uclibc_0.9.28: fix thumb support to allow thumb uclibc
authorJohn Bowler <jbowler@nslu2-linux.org>
Thu, 22 Sep 2005 19:44:38 +0000 (19:44 +0000)
committerOpenEmbedded Project <openembedded-devel@lists.openembedded.org>
Thu, 22 Sep 2005 19:44:38 +0000 (19:44 +0000)
This, together with the fixes in gcc and binutils, allows a system to
be build with thumb libgcc and libuClibc (etc).  ucslugc is changed to
release 2 and to use thumb compilation of these modules.

conf/distro/ucslugc.conf
packages/uclibc/uclibc-0.9.28/thumb-asm-swi.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/thumb-call-via-rx.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/thumb-mov-pc-bx.patch
packages/uclibc/uclibc-0.9.28/thumb-resolve.patch
packages/uclibc/uclibc-0.9.28/thumb-swi-r7.patch [new file with mode: 0644]
packages/uclibc/uclibc-0.9.28/thumb-sysnum-h.patch [new file with mode: 0644]
packages/uclibc/uclibc_0.9.28.bb

index 1ce5493..550c26d 100644 (file)
@@ -6,7 +6,7 @@
 # STANDARD UcSlugC DEFINITIONS
 #----------------------------------------------------------------------------------
 DISTRO_NAME = "UcSlugC"
-DISTRO_VERSION = "1.1-beta"
+DISTRO_VERSION = "2-beta"
 DISTRO_FEED = "unstable"
 DISTRO_TYPE ?= "beta"
 
diff --git a/packages/uclibc/uclibc-0.9.28/thumb-asm-swi.patch b/packages/uclibc/uclibc-0.9.28/thumb-asm-swi.patch
new file mode 100644 (file)
index 0000000..35e53ca
--- /dev/null
@@ -0,0 +1,153 @@
+# WARNING: nasty hack.  Because sysnum.h produces thumb syscall
+# numbers when compiled in thumb mode the arm assembler (which is arm
+# even in thumb mode) needs to write the OS syscall base back into
+# the swi calls.  This is done here just by orring in the correct
+# value.  This is a hack - it might be better to add a define to
+# sysnum.h to force it to output arm (not thumb) values on demand -
+# but this hack is fairly safe (rmk would have to change the syscall
+# base, this seems unlikely).
+#
+# The patch also fixes up the .align directives to '2' (i.e. a multiple
+# of 4) not '4' (a multiple of 16 - apparently an error since it seems
+# to be unnecessary, there is no advantage here in cache line alignment).
+diff -u uClibc-0.9.28/libc/sysdeps/linux/arm/orig/__longjmp.S uClibc-0.9.28/libc/sysdeps/linux/arm/__longjmp.S
+--- uClibc-0.9.28/libc/sysdeps/linux/arm/orig/__longjmp.S      2005-09-18 18:41:36.870986621 -0700
++++ uClibc-0.9.28/libc/sysdeps/linux/arm/__longjmp.S   2005-09-18 19:01:26.741860474 -0700
+@@ -25,7 +25,7 @@
+ .global __longjmp
+ .type __longjmp,%function
+-.align 4
++.align 2
+ __longjmp:
+       mov     ip, r0          /* save jmp_buf pointer */
+       
+diff -u uClibc-0.9.28/libc/sysdeps/linux/arm/orig/bsd-_setjmp.S uClibc-0.9.28/libc/sysdeps/linux/arm/bsd-_setjmp.S
+--- uClibc-0.9.28/libc/sysdeps/linux/arm/orig/bsd-_setjmp.S    2005-09-18 18:41:36.870986621 -0700
++++ uClibc-0.9.28/libc/sysdeps/linux/arm/bsd-_setjmp.S 2005-09-18 19:01:31.982190228 -0700
+@@ -27,7 +27,7 @@
+ .global _setjmp
+ .type _setjmp,%function
+-.align 4
++.align 2
+ _setjmp:
+       mov     r1, #0
+ #ifdef __PIC__
+diff -u uClibc-0.9.28/libc/sysdeps/linux/arm/orig/bsd-setjmp.S uClibc-0.9.28/libc/sysdeps/linux/arm/bsd-setjmp.S
+--- uClibc-0.9.28/libc/sysdeps/linux/arm/orig/bsd-setjmp.S     2005-09-18 18:41:36.870986621 -0700
++++ uClibc-0.9.28/libc/sysdeps/linux/arm/bsd-setjmp.S  2005-09-18 19:01:40.166705247 -0700
+@@ -27,7 +27,7 @@
+ .global setjmp
+ .type setjmp,%function
+-.align 4
++.align 2
+ setjmp:
+       mov     r1, #1
+ #ifdef __PIC__
+diff -u uClibc-0.9.28/libc/sysdeps/linux/arm/orig/clone.S uClibc-0.9.28/libc/sysdeps/linux/arm/clone.S
+--- uClibc-0.9.28/libc/sysdeps/linux/arm/orig/clone.S  2005-09-18 18:41:36.870986621 -0700
++++ uClibc-0.9.28/libc/sysdeps/linux/arm/clone.S       2005-09-18 19:01:45.427036258 -0700
+@@ -30,7 +30,7 @@
+ .text
+ .global __clone
+ .type __clone,%function
+-.align 4
++.align 2
+ __clone:
+       @ sanity check args
+       cmp     r0, #0
+@@ -48,7 +48,7 @@
+       @ get flags
+       mov     r0, r2
+       @ new sp is already in r1
+-      swi     __NR_clone
++      swi     (__NR_clone | 0x900000)
+       movs    a1, a1
+       blt     __error
+ #if defined(__THUMB_INTERWORK__)
+diff -u uClibc-0.9.28/libc/sysdeps/linux/arm/orig/mmap64.S uClibc-0.9.28/libc/sysdeps/linux/arm/mmap64.S
+--- uClibc-0.9.28/libc/sysdeps/linux/arm/orig/mmap64.S 2005-09-18 18:41:36.874986873 -0700
++++ uClibc-0.9.28/libc/sysdeps/linux/arm/mmap64.S      2005-09-18 19:02:03.692185612 -0700
+@@ -27,7 +27,7 @@
+ .text
+ .global mmap64
+ .type mmap64,%function
+-.align 4
++.align 2
+ mmap64:
+       stmfd   sp!, {r4, r5, lr}
+       ldr     r5, [sp, $16]
+@@ -40,7 +40,7 @@
+       movs    ip, ip, lsr $12
+       bne     .Linval                 @ check for overflow
+       mov     ip, r0
+-      swi     __NR_mmap2
++      swi     (__NR_mmap2 | 0x900000)
+       cmn     r0, $4096
+       ldmccfd sp!, {r4, r5, pc}
+       cmn     r0, $ENOSYS
+diff -u uClibc-0.9.28/libc/sysdeps/linux/arm/orig/setjmp.S uClibc-0.9.28/libc/sysdeps/linux/arm/setjmp.S
+--- uClibc-0.9.28/libc/sysdeps/linux/arm/orig/setjmp.S 2005-09-18 18:41:36.874986873 -0700
++++ uClibc-0.9.28/libc/sysdeps/linux/arm/setjmp.S      2005-09-18 19:02:08.956516875 -0700
+@@ -24,7 +24,7 @@
+ .global __sigsetjmp
+ .type __sigsetjmp,%function
+-.align 4
++.align 2
+ __sigsetjmp:
+       /* Save registers */
+ #if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__
+diff -u uClibc-0.9.28/libc/sysdeps/linux/arm/orig/sigrestorer.S uClibc-0.9.28/libc/sysdeps/linux/arm/sigrestorer.S
+--- uClibc-0.9.28/libc/sysdeps/linux/arm/orig/sigrestorer.S    2005-09-18 18:41:36.874986873 -0700
++++ uClibc-0.9.28/libc/sysdeps/linux/arm/sigrestorer.S 2005-09-18 19:02:18.041088531 -0700
+@@ -24,17 +24,17 @@
+ .global __default_sa_restorer
+ .type __default_sa_restorer,%function
+-.align 4
++.align 2
+ __default_sa_restorer:
+-      swi     __NR_sigreturn
++      swi     (__NR_sigreturn | 0x900000)
+ #ifdef __NR_rt_sigreturn
+ .global __default_rt_sa_restorer
+ .type __default_rt_sa_restorer,%function
+-.align 4
++.align 2
+ __default_rt_sa_restorer:
+-      swi     __NR_rt_sigreturn
++      swi     (__NR_rt_sigreturn | 0x900000)
+ #endif
+diff -u uClibc-0.9.28/libc/sysdeps/linux/arm/orig/vfork.S uClibc-0.9.28/libc/sysdeps/linux/arm/vfork.S
+--- uClibc-0.9.28/libc/sysdeps/linux/arm/orig/vfork.S  2005-09-18 18:41:36.874986873 -0700
++++ uClibc-0.9.28/libc/sysdeps/linux/arm/vfork.S       2005-09-18 19:02:23.561435905 -0700
+@@ -28,11 +28,11 @@
+ .text
+ .global vfork
+ .type vfork,%function
+-.align 4
++.align 2
+ vfork:
+ #ifdef __NR_vfork
+-      swi     __NR_vfork
++      swi     (__NR_vfork | 0x900000)
+       cmn     r0, #4096
+ #if defined(__THUMB_INTERWORK__)
+       bxcc    lr
+@@ -47,7 +47,7 @@
+ #endif
+       /* If we don't have vfork, use fork.  */
+-      swi     __NR_fork
++      swi     (__NR_fork | 0x900000)
+       cmn     r0, #4096
+       /* Syscal worked.  Return to child/parent */
diff --git a/packages/uclibc/uclibc-0.9.28/thumb-call-via-rx.patch b/packages/uclibc/uclibc-0.9.28/thumb-call-via-rx.patch
new file mode 100644 (file)
index 0000000..eae54f3
--- /dev/null
@@ -0,0 +1,207 @@
+# Put the call_via_rx code into each executable - call_via_ip cannot
+# possibly work if called through the PLT!  ldso requires this code
+# too as it is not linked with the crt stuff and thumb ldso does
+# make calls via a register.
+#
+# The patch puts the code into crti.S so that it is linked into
+# every normally built application (if thumb or interworking is
+# selected).  This is only 30 extra bytes and it works - the previous
+# code did not because nothing both implemented and exported the
+# APIs (they were in libgcc, but not in the version script).
+#
+# crti.S and crtn.S is also brought up to date with GCC 3.4.4 - this
+# is essential for thumb support because the .init and .fini sections
+# must use arm or thumb code to match the compilation of the libraries.
+#
+# Note that code which pushes stuff into .init or .fini must be
+# compiled with or without -mthumb to match the uclibc compilation -
+# and gcc itself (which does do this) must therefore be compiled to
+# match.
+#
+--- uClibc-0.9.28/.pc/thumb-call-via-rx.patch/libc/sysdeps/linux/arm/crti.S    2005-08-17 15:49:41.000000000 -0700
++++ uClibc-0.9.28/libc/sysdeps/linux/arm/crti.S        2005-09-21 19:15:19.996721584 -0700
+@@ -1,26 +1,86 @@
+       .file   "initfini.c"
+       
+       .section .init
+-      .align  2
+       .global _init
+       .type   _init, %function
++#if defined __thumb__
++      .align  1
++      .thumb
++      .thumb_func
+ _init:
+-      @ args = 0, pretend = 0, frame = 0
+-      @ frame_needed = 0, uses_anonymous_args = 0
+-      str     lr, [sp, #-4]!
+-      
+-      .align 2
+-      
+-      
+-      .section .fini
++      push    {r4-r7, lr}
++#else
+       .align  2
++      .arm
++_init:
++      @ gcc 3.3.2 didn't create a stack frame, gcc 3.4.4 does -
++      @ presumably 3.4.4 can put stuff into .init which requires
++      @ the arguments to be saved.  This code is copied from 3.4.4
++      mov     ip, sp
++      stmdb   sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
++      sub     fp, ip, #4
++#endif
++
++
++      .section .fini
+       .global _fini
+       .type   _fini, %function
++#if defined __thumb__
++      .align  1
++      .thumb
++      .thumb_func
+ _fini:
+-      @ args = 0, pretend = 0, frame = 0
+-      @ frame_needed = 0, uses_anonymous_args = 0
+-      str     lr, [sp, #-4]!
+-      .align 2
+-      
+-      
++      push    {r4-r7, lr}
++#else
++      .align  2
++      .arm
++_fini:
++      mov     ip, sp
++      stmdb   sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
++      sub     fp, ip, #4
++#endif
++
++
++#if (defined __thumb__ || defined __THUMB_INTERWORK__) && (defined __ARM_ARCH_4T__ || defined __ARM_ARCH_5T__ || defined __ARM_ARCH_5TE__)
++      @ To support thumb code it is currently necessary to have the _call_via_rX
++      @ functions exposed to the linker for any program or shared library.  PLT
++      @ references are inadequate - the PLT zaps ip and therefore breaks _call_via_ip
++      @ (and the compiler does generate this).  It is simpler to put all the
++      @ required code in here - it only amounts to 60 bytes overhead.
++      @NOTE: it would be better to have the compiler generate this stuff as
++      @ required...
++      .section        ".text"
++      .align 0
++      .force_thumb
++
++.macro call_via register
++      .global _call_via_\register
++      .type   _call_via_\register, %function
++      .weak   _call_via_\register
++      .hidden _call_via_\register
++      .thumb_func
++_call_via_\register:
++      bx      \register
++      nop
++      .size   _call_via_\register, . - _call_via_\register
++.endm
++
++      @ and calls for the 15 general purpose registers (2 bytes each).
++      call_via r0
++      call_via r1
++      call_via r2
++      call_via r3
++      call_via r4
++      call_via r5
++      call_via r6
++      call_via r7
++      call_via r8
++      call_via r9
++      call_via sl
++      call_via fp
++      call_via ip
++      call_via sp
++      call_via lr
++#endif
++
+       .ident  "GCC: (GNU) 3.3.2 20031005 (Debian prerelease)"
+--- uClibc-0.9.28/libc/sysdeps/linux/arm/crtn.S.orig   2005-09-20 16:39:20.010925582 -0700
++++ uClibc-0.9.28/libc/sysdeps/linux/arm/crtn.S        2005-09-20 17:00:51.700206464 -0700
+@@ -1,17 +1,34 @@
+       .file   "initfini.c"
+       
+       .section .init
+-      .align  2
+       .global _init
+       .type   _init, %function
+-      ldr     pc, [sp], #4
++#if defined __thumb__
++      .align  1
++      .thumb
++      @ this will not work on ARMv4T, but lots of stuff
++      @ in here won't work there anyway...
++      pop     {r4-r7, pc}
++#else
++      .align  2
++      .arm
++      ldmdb   fp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}
++#endif
+       .size   _init, .-_init
+       
+       .section .fini
+-      .align  2
+       .global _fini
+       .type   _fini, %function
+-      ldr     pc, [sp], #4
++#if defined __thumb__
++      .align  1
++      .thumb
++      pop     {r4-r7, pc}
++#else
++      .align  2
++      .arm
++      ldmdb   fp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, pc}
++#endif
+       .size   _fini, .-_fini
+       
++      @ In fact this is modified to 3.4.4
+       .ident  "GCC: (GNU) 3.3.2 20031005 (Debian prerelease)"
+--- uClibc-0.9.28/.pc/thumb-call-via-rx.patch/ldso/ldso/arm/dl-syscalls.h      2005-08-17 15:49:41.000000000 -0700
++++ uClibc-0.9.28/ldso/ldso/arm/dl-syscalls.h  2005-09-21 19:17:01.143086323 -0700
+@@ -4,3 +4,39 @@
+ #define __set_errno(X) {(_dl_errno) = (X);}
+ #include "sys/syscall.h"
++/* _call_via_rX calls are used in thumb ldso because of calls via
++ * function pointers, but ldso is not linked with anything which
++ * provides them, so define them here (only required for thumb).
++ */
++#if defined(__thumb__)
++asm(
++      ".macro call_via register\n"
++      "       .global _call_via_\\register\n"
++      "       .hidden _call_via_\\register\n"
++      "       .type   _call_via_\\register, %function\n"
++      "       .thumb_func\n"
++      "_call_via_\\register:\n"
++      "       bx      \\register\n"
++      "       .size   _call_via_\\register, . - _call_via_\\register\n"
++      ".endm\n"
++
++      ".text\n"
++      ".thumb\n"
++      ".align 1\n"
++      "       call_via r0\n"
++      "       call_via r1\n"
++      "       call_via r2\n"
++      "       call_via r3\n"
++      "       call_via r4\n"
++      "       call_via r5\n"
++      "       call_via r6\n"
++      "       call_via r7\n"
++      "       call_via r8\n"
++      "       call_via r9\n"
++      "       call_via r10\n"
++      "       call_via r11\n"
++      "       call_via r12\n"
++      "       call_via r13\n"
++      "       call_via r14\n"
++);
++#endif
index 86713a7..4419169 100644 (file)
 # so this is safe.  See gcc lib1asmfuncs for a more exact test.
 #
 --- uClibc-0.9.28/.pc/thumb-mov-pc-bx.patch/ldso/ldso/arm/dl-startup.h 2005-08-17 15:49:41.000000000 -0700
-+++ uClibc-0.9.28/ldso/ldso/arm/dl-startup.h   2005-09-08 09:34:22.918316874 -0700
-@@ -8,6 +8,7 @@
++++ uClibc-0.9.28/ldso/ldso/arm/dl-startup.h   2005-09-16 23:38:34.266546180 -0700
+@@ -4,6 +4,7 @@
+  * Copyright (C) 2000-2004 by Erik Andersen <andersen@codepoet.org>
+  */
++#if defined(__arm__)
+ asm(
      " .text\n"
      " .globl  _start\n"
-     " .type   _start,%function\n"
-+    " .arm\n"
-       "_start:\n"
-       "       @ at start time, all the args are on the stack\n"
-       "       mov     r0, sp\n"
 @@ -40,7 +41,11 @@
        "       ldr     r0, .L_FINI_PROC\n"
        "       ldr     r0, [sl, r0]\n"
        ".L_GET_GOT:\n"
        "       .word   _GLOBAL_OFFSET_TABLE_ - .L_GOT_GOT - 4\n"
        ".L_SKIP_ARGS:\n"
+@@ -51,6 +56,70 @@
+     " .size   _start,.-_start\n"
+       ".previous\n"
+ );
++#else
++asm(
++    " .text\n"
++    " .arm\n"
++    " .globl  _start\n"
++    " .type   _start,%function\n"
++      "_start:\n"
++      "       @ dumb: can't persuade the linker to make the start address\n"
++      "       @ odd, so use an arm function and change to thumb (_dl_start\n"
++      "       @ is thumb)\n"
++      "       adr     r0, __dl_thumb_start+1\n"
++      "       bx      r0\n"
++      "\n\n"
++    " .thumb\n"
++    " .globl  __dl_thumb_start\n"
++    " .thumb_func\n"
++    " .type   __dl_thumb_start,%function\n"
++      "__dl_thumb_start:\n"
++      "       @ at start time, all the args are on the stack\n"
++      "       mov     r0, sp\n"
++      "       bl      _dl_start\n"
++      "       @ returns user entry point in r0\n"
++      "       mov     r6, r0\n"
++      "       @ we are PIC code, so get global offset table\n"
++      "       ldr     r7, .L_GET_GOT\n"
++      ".L_GOT_GOT:\n"
++      "       add     r7, pc\n"
++      "       @ See if we were run as a command with the executable file\n"
++      "       @ name as an extra leading argument.\n"
++      "       ldr     r4, .L_SKIP_ARGS\n"
++      "       ldr     r4, [r7, r4]\n"
++      "       @ get the original arg count\n"
++      "       ldr     r1, [sp]\n"
++      "       @ subtract _dl_skip_args from it\n"
++      "       sub     r1, r1, r4\n"
++      "       @ adjust the stack pointer to skip them\n"
++      "       lsl     r4, r4, #2\n"
++      "       add     sp, r4\n"
++      "       @ get the argv address\n"
++      "       add     r2, sp, #4\n"
++      "       @ store the new argc in the new stack location\n"
++      "       str     r1, [sp]\n"
++      "       @ compute envp\n"
++      "       lsl     r3, r1, #2\n"
++      "       add     r3, r3, r2\n"
++      "       add     r3, #4\n"
++      "\n\n"
++      "       @ load the finalizer function\n"
++      "       ldr     r0, .L_FINI_PROC\n"
++      "       ldr     r0, [r7, r0]\n"
++      "       @ jump to the user_s entry point\n"
++      "       bx      r6\n"
++      "\n\n"
++      ".L_GET_GOT:\n"
++      "       .word   _GLOBAL_OFFSET_TABLE_ - .L_GOT_GOT - 4\n"
++      ".L_SKIP_ARGS:\n"
++      "       .word   _dl_skip_args(GOTOFF)\n"
++      ".L_FINI_PROC:\n"
++      "       .word   _dl_fini(GOT)\n"
++      "\n\n"
++    " .size   _start,.-_start\n"
++      ".previous\n"
++);
++#endif
+ /* Get a pointer to the argv array.  On many platforms this can be just
 --- uClibc-0.9.28/.pc/thumb-mov-pc-bx.patch/ldso/ldso/arm/dl-sysdep.h  2005-08-17 15:49:41.000000000 -0700
 +++ uClibc-0.9.28/ldso/ldso/arm/dl-sysdep.h    2005-09-07 20:10:35.923583424 -0700
 @@ -85,7 +85,19 @@
index 9d1db38..0a99a7d 100644 (file)
@@ -5,7 +5,7 @@
 # count (faster in caller and callee, and slightly easier to understand).
 #
 --- uClibc-0.9.28/.pc/thumb-resolve.patch/ldso/ldso/arm/elfinterp.c    2005-08-17 15:49:41.000000000 -0700
-+++ uClibc-0.9.28/ldso/ldso/arm/elfinterp.c    2005-09-07 20:10:36.231602806 -0700
++++ uClibc-0.9.28/ldso/ldso/arm/elfinterp.c    2005-09-17 12:55:26.379172744 -0700
 @@ -55,7 +55,7 @@
  
        rel_addr = (ELF_RELOC *) tpnt->dynamic_info[DT_JMPREL];
        reloc_type = ELF32_R_TYPE(this_reloc->r_info);
        symtab_index = ELF32_R_SYM(this_reloc->r_info);
  
+@@ -84,7 +84,9 @@
+               _dl_exit(1);
+       };
+ #if defined (__SUPPORT_LD_DEBUG__)
++#if !defined __SUPPORT_LD_DEBUG_EARLY__
+       if ((unsigned long) got_addr < 0x40000000)
++#endif
+       {
+               if (_dl_debug_bindings)
+               {
 --- uClibc-0.9.28/.pc/thumb-resolve.patch/ldso/ldso/arm/resolve.S      2005-08-17 15:49:41.000000000 -0700
-+++ uClibc-0.9.28/ldso/ldso/arm/resolve.S      2005-09-08 09:54:03.536608499 -0700
-@@ -1,43 +1,121 @@
++++ uClibc-0.9.28/ldso/ldso/arm/resolve.S      2005-09-17 11:02:27.860627464 -0700
+@@ -1,43 +1,163 @@
  /*
 - * This function is _not_ called directly.  It is jumped to (so no return
 - * address is on the stack) when attempting to use a symbol that has not yet
 + * that linux/uclibc seems to be using r10 - sl - as a PIC base register - see
 + * dl-startup.c).
   */
+-
 -#define sl r10
 -#define fp r11
 -#define ip r12
--
++#include <sys/syscall.h>
  .text
++.align 4      @ 16 byte boundary and there are 32 bytes below (arm case)
++#if !defined(__thumb__)
++.arm
  .globl _dl_linux_resolve
  .type _dl_linux_resolve,%function
 -.align 4;
-+.align 4      @ 16 byte boundary and there are 32 bytes below
  
  _dl_linux_resolve:
 -      stmdb sp!, {r0, r1, r2, r3, sl, fp}
 +#else
 +      mov   pc, ip
 +#endif
++.size _dl_linux_resolve, .-_dl_linux_resolve
++#else
++      @ In the thumb case _dl_linux_resolver is thumb.  If a bl is used
++      @ from arm code the linker will insert a stub call which, with
++      @ binutils 2.16, is not PIC.  Since this code is accessed by an
++      @ ldr pc the reasonable fix is to make _dl_linux_resolve thumb too.
++.thumb
++.globl _dl_linux_resolve
++.thumb_func
++.type _dl_linux_resolve,%function
++
++_dl_linux_resolve:
++      @ _dl_linux_resolver is a standard subroutine call, therefore it
++      @ preserves everything except r0-r3 (a1-a4), ip and lr.  This
++      @ function must branch to the real function, and that expects
++      @ r0-r3 and lr to be as they were before the whole PLT stuff -
++      @ ip can be trashed.
++      push    {r0-r3}
++      mov     r1, lr          @ &GOT_TABLE[2]
++      sub     r0, r1, #4
++      mov     r2, ip          @ &GOT[n]
++      ldr     r0, [r0]        @ r0 := GOT_TABLE[1]
++      @ for the function call r1 := n-3
++      sub     r1, r2
++      asr     r1, r1, #2
++      mvn     r1, r1          @ exactly as in the arm code above
++
++      bl      _dl_linux_resolver
++
++      @ r0 contains the branch address, the return address is above
++      @ the saved r0..r3
++      mov     ip, r0
++      ldr     r1, [sp, #16]
++      mov     lr, r1
++      pop     {r0-r3}
++      add     sp, #4
++      bx      ip
++
  .size _dl_linux_resolve, .-_dl_linux_resolve
---- uClibc/ldso/ldso/dl-hash.c 2005-09-08 13:54:30.124416436 -0700
-+++ uClibc/ldso/ldso/dl-hash.c 2005-09-08 14:17:44.828179610 -0700
-@@ -186,11 +186,19 @@
++#endif
+--- uClibc-0.9.28/.pc/thumb-resolve.patch/ldso/ldso/dl-hash.c  2005-08-17 15:49:41.000000000 -0700
++++ uClibc-0.9.28/ldso/ldso/dl-hash.c  2005-09-21 18:56:31.181689732 -0700
+@@ -182,28 +182,52 @@
+               strtab = (char *) (tpnt->dynamic_info[DT_STRTAB]);
+               for (si = tpnt->elf_buckets[hn]; si != STN_UNDEF; si = tpnt->chains[si]) {
++                      char *result;
+                       sym = &symtab[si];
  
-                       if (type_class & (sym->st_shndx == SHN_UNDEF))
+-                      if (type_class & (sym->st_shndx == SHN_UNDEF))
++                      if (sym->st_shndx == SHN_UNDEF)
                                continue;
 -                      if (_dl_strcmp(strtab + sym->st_name, name) != 0)
--                              continue;
-                       if (sym->st_value == 0)
-                               continue;
--                      if (ELF_ST_TYPE(sym->st_info) > STT_FUNC)
 +                      if (ELF_ST_TYPE(sym->st_info) > STT_FUNC
 +#if defined(__arm__) || defined(__thumb__)
 +                              /* On ARM (only) STT_ARM_TFUNC is a function
 +                              && ELF_ST_TYPE(sym->st_info) != STT_ARM_TFUNC
 +#endif
 +                         )
-+                              continue;
+                               continue;
+-                      if (sym->st_value == 0)
 +                      if (_dl_strcmp(strtab + sym->st_name, name) != 0)
                                continue;
+-                      if (ELF_ST_TYPE(sym->st_info) > STT_FUNC)
++#if 0
++                      /* I don't know how to write this test - need to test shndx
++                       * to see if it is the PLT for this module.
++                       */
++                      if ((type_class & ELF_RTYPE_CLASS_PLT) && some test)
+                               continue;
++#endif
  
-                       switch (ELF_ST_BIND(sym->st_info)) {
-@@ -203,7 +211,17 @@
-                               break;
- #endif
-                       case STB_GLOBAL:
 +#if defined(__arm__) || defined(__thumb__)
-+                              /* On ARM the caller needs to know that STT_ARM_TFUNC
-+                               * is a thumb function call, this is now indicated by
-+                               * setting the low bit of the value (and newer binutils
-+                               * will do this and record STT_FUNC).
-+                               */
-+                              return (char*)tpnt->loadaddr + (sym->st_value |
-+                                      (ELF_ST_TYPE(sym->st_info) == STT_ARM_TFUNC));
++                      /* On ARM the caller needs to know that STT_ARM_TFUNC
++                       * is a thumb function call, this is now indicated by
++                       * setting the low bit of the value (and newer binutils
++                       * will do this and record STT_FUNC).
++                       */
++                      result = (char*)tpnt->loadaddr + (sym->st_value |
++                              (ELF_ST_TYPE(sym->st_info) == STT_ARM_TFUNC));
 +#else
-                               return (char*)tpnt->loadaddr + sym->st_value;
++                      result = (char*)tpnt->loadaddr + sym->st_value;
 +#endif
+                       switch (ELF_ST_BIND(sym->st_info)) {
+                       case STB_WEAK:
+-#if 0
+-/* Perhaps we should support old style weak symbol handling
+- * per what glibc does when you export LD_DYNAMIC_WEAK */
++                              /* Record for use later if we can't find a global. */
+                               if (!weak_result)
+-                                      weak_result = (char *)tpnt->loadaddr + sym->st_value;
++                                      weak_result = result;
+                               break;
+-#endif
++
+                       case STB_GLOBAL:
+-                              return (char*)tpnt->loadaddr + sym->st_value;
++                              return result;
++
                        default:        /* Local symbols not handled here */
                                break;
                        }
diff --git a/packages/uclibc/uclibc-0.9.28/thumb-swi-r7.patch b/packages/uclibc/uclibc-0.9.28/thumb-swi-r7.patch
new file mode 100644 (file)
index 0000000..330ceb6
--- /dev/null
@@ -0,0 +1,48 @@
+# This is a work round for a fairly serious GCC compiler bug - when
+# the syscall assembler overwrites r7 (required on thumb) the
+# compiler fails to protect the register when it is using it as a
+# frame pointer.
+#
+--- uClibc-0.9.28/libc/sysdeps/linux/arm/bits/syscalls.h       2005-09-12 17:51:26.062205918 -0700
++++ uClibc-0.9.28/libc/sysdeps/linux/arm/bits/syscalls.h       2005-09-12 18:16:15.507930828 -0700
+@@ -111,6 +111,11 @@
+      }                                                                \
+      (int) _sys_result; })
+ #else
++#if 0
++/* This doesn't work because GCC uses r7 as a frame pointer in
++ * some cases and doesn't notice that the _r7 value changes
++ * it, resulting in mysterious crashes after the SWI.
++ */
+ #define INTERNAL_SYSCALL(name, err, nr, args...)              \
+   ({ unsigned int _sys_result;                                        \
+      {                                                                \
+@@ -124,6 +129,28 @@
+        _sys_result = _a1;                                     \
+      }                                                                \
+      (int) _sys_result; })
++#else
++/* So hide the use of r7 from the compiler, this would be a lot
++ * easier but for the fact that the syscalls can exceed 255.
++ * For the moment the LOAD_ARG_7 is sacrificed.
++ */
++#define INTERNAL_SYSCALL(name, err, nr, args...)              \
++  ({ unsigned int _sys_result;                                        \
++     {                                                                \
++       register int _a1 asm ("a1");                           \
++       LOAD_ARGS_##nr (args)                                  \
++       register int _v3 asm ("v3") = (int) (SYS_ify(name));   \
++       asm volatile ("push    {r7}\n"                         \
++                   "\tmov     r7, v3\n"                       \
++                   "\tswi     0       @ syscall " #name "\n"  \
++                   "\tpop     {r7}"                           \
++                   : "=r" (_a1)                               \
++                   : "r" (_v3) ASM_ARGS_##nr                  \
++                   : "memory");                               \
++       _sys_result = _a1;                                     \
++     }                                                                \
++     (int) _sys_result; })
++#endif
+ #endif
+ #undef INTERNAL_SYSCALL_ERROR_P
diff --git a/packages/uclibc/uclibc-0.9.28/thumb-sysnum-h.patch b/packages/uclibc/uclibc-0.9.28/thumb-sysnum-h.patch
new file mode 100644 (file)
index 0000000..599691e
--- /dev/null
@@ -0,0 +1,45 @@
+--- uClibc-0.9.28/extra/scripts/gen_bits_syscall_h.sh.orig     2005-09-18 02:20:04.441119651 -0700
++++ uClibc-0.9.28/extra/scripts/gen_bits_syscall_h.sh  2005-09-18 03:17:58.287715035 -0700
+@@ -11,6 +11,37 @@
+ UNISTD_H_PATH=$TOPDIR/include/asm/unistd.h
+ INCLUDE_OPTS="-I$TOPDIR/include"
++# This test is added to avoid mangling the (variable) syscall base value on
++# ARM
++if echo "#if defined __arm__ || defined __thumb__
++xyzzy
++#endif" | $CC -E $INCLUDE_OPTS - | grep xyzzy >/dev/null
++then
++      echo '/* WARNING!!! AUTO-GENERATED FILE!!! DO NOT EDIT!!! */
++#ifndef _BITS_SYSNUM_H
++#define _BITS_SYSNUM_H
++
++#ifndef _SYSCALL_H
++# error "Never use <bits/sysnum.h> directly; include <sys/syscall.h> instead."
++#endif'
++      # arm case, assume unistd.h conforms to the one in 2.6.x, if not
++      # go into a corner and sulk (fix this script)  The sed rune below
++      # expects items of the form UCLIBC_foo at the start of the line
++      # for each syscall number, the arm syscalls all start with lower
++      # case alpha and the all-important __NR_SYSCALL_BASE does not...
++      sed -n -e '/__sys2/Q' -e '/^[   ]*#include/,${
++              s/^[    ]*#include.*$//
++              h
++              s/^[    ]*#define[      ]*__NR_\([a-z][A-Za-z0-9_]*\)[  ]*\(.*\)[       ]*$/#undef __NR_\1\
++#define SYS_\1 __NR_\1/p
++              g
++              p
++              }' $UNISTD_H_PATH
++      # i.e. this relies on the __sys2 definition coming after the last
++      # sys number define (and #include preceding all useful definitions)
++      echo '#endif'
++else
++# non-arm case
+ ( echo "#include \"$UNISTD_H_PATH\"" ;
+   $CC -E -dN $INCLUDE_OPTS $UNISTD_H_PATH | # needed to strip out any kernel-internal defines
+   sed -ne 's/^[ ]*#define[ ]*__NR_\([A-Za-z0-9_]*\).*/UCLIBC_\1 __NR_\1/gp'
+@@ -29,3 +60,4 @@
+   echo ;
+   echo "#endif" ;
+ )
++fi
index 8805f9f..9214b64 100644 (file)
@@ -1,5 +1,5 @@
 DEFAULT_PREFERENCE = "1"
-PR = "r2"
+PR = "r3"
 
 include uclibc.inc
 
@@ -12,9 +12,6 @@ SRC_URI += "http://www.uclibc.org/downloads/uClibc-${PV}.tar.bz2"
 
 S = "${WORKDIR}/uClibc-${PV}"
 
-# At present the thumb implementation is non-functional
-ARM_INSTRUCTION_SET = ""
-
 #*** PATCHES ***
 #
 # The nokernelheadercheck patch removes the check on the include
@@ -29,4 +26,13 @@ SRC_URI += " file://thumb-defined-arm-or-thumb.patch;patch=1"
 #
 # Thumb interworking support
 SRC_URI += " file://thumb-mov-pc-bx.patch;patch=1"
-SRC_URI += " file://thumb-resolve.patch;patch=1"
+SRC_URI += " file://thumb-swi-r7.patch;patch=1"
+SRC_URI += " file://thumb-sysnum-h.patch;patch=1"
+SRC_URI += " file://thumb-asm-swi.patch;patch=1"
+SRC_URI += " file://thumb-call-via-rx.patch;patch=1"
+#
+# This is a core change and is controversial, maybe even wrong
+# on some architectures
+THUMB_INTERWORK_RESOLVE_PATCH = ""
+THUMB_INTERWORK_RESOLVE_PATCH_thumb-interwork = " file://thumb-resolve.patch;patch=1"
+SRC_URI += " ${THUMB_INTERWORK_RESOLVE_PATCH}"