summaryrefslogtreecommitdiff
path: root/packages/uclibc/uclibc-0.9.28/thumb-resolve.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packages/uclibc/uclibc-0.9.28/thumb-resolve.patch')
-rw-r--r--packages/uclibc/uclibc-0.9.28/thumb-resolve.patch130
1 files changed, 102 insertions, 28 deletions
diff --git a/packages/uclibc/uclibc-0.9.28/thumb-resolve.patch b/packages/uclibc/uclibc-0.9.28/thumb-resolve.patch
index 9d1db384ab..0a99a7d9bc 100644
--- a/packages/uclibc/uclibc-0.9.28/thumb-resolve.patch
+++ b/packages/uclibc/uclibc-0.9.28/thumb-resolve.patch
@@ -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];
@@ -15,9 +15,19 @@
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
@@ -127,16 +137,19 @@
+ * 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}
@@ -169,18 +182,59 @@
+#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
@@ -190,26 +244,46 @@
+ && 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;
}