diff options
-rw-r--r-- | linuxthreads/ChangeLog | 3 | ||||
-rw-r--r-- | linuxthreads/sysdeps/i386/Makefile | 13 | ||||
-rw-r--r-- | sysdeps/sparc/sparc64/dl-machine.h | 42 |
3 files changed, 46 insertions, 12 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index 3dfc5c7417..d51bcd42b3 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,5 +1,8 @@ 2001-04-12 Ulrich Drepper <drepper@redhat.com> + * sysdeps/i386/Makefile: Make sure gcc uses a frame pointer for + all the files which use CURRENT_STACK_FRAME. + * sysdeps/i386/pt-machine.h (CURRENT_STACK_FRAME): Define using __builtin_frame_address. * sysdeps/i386/i686/pt-machine.h: Likewise. diff --git a/linuxthreads/sysdeps/i386/Makefile b/linuxthreads/sysdeps/i386/Makefile index 811a799ad8..854eacbd32 100644 --- a/linuxthreads/sysdeps/i386/Makefile +++ b/linuxthreads/sysdeps/i386/Makefile @@ -2,4 +2,17 @@ ifeq ($(subdir),linuxthreads) # On i686 we must avoid generating the trampoline functions generated # to get the GOT pointer. CFLAGS-pt-initfini.s += -march=i386 -mcpu=i386 + +# Most files must not be compiled without frame pointer since we need +# the frame base address which is stored in %ebp unless the frame pointer +# is optimized out. +CFLAGS-cancel.c += -fno-omit-frame-pointer +CFLAGS-condvar.c += -fno-omit-frame-pointer +CFLAGS-join.c += -fno-omit-frame-pointer +CFLAGS-manager.c += -fno-omit-frame-pointer +CFLAGS-oldsemaphore.c += -fno-omit-frame-pointer +CFLAGS-pthreads.c += -fno-omit-frame-pointer +CFLAGS-ptlongjmp.c += -fno-omit-frame-pointer +CFLAGS-semaphore.c += -fno-omit-frame-pointer +CFLAGS-signals.c += -fno-omit-frame-pointer endif diff --git a/sysdeps/sparc/sparc64/dl-machine.h b/sysdeps/sparc/sparc64/dl-machine.h index b4785c74cc..c420bbdf86 100644 --- a/sysdeps/sparc/sparc64/dl-machine.h +++ b/sysdeps/sparc/sparc64/dl-machine.h @@ -49,19 +49,37 @@ elf_machine_dynamic (void) static inline Elf64_Addr elf_machine_load_address (void) { - register Elf64_Addr elf_pic_register __asm__("%l7"); - Elf64_Addr pc, la; - - /* Utilize the fact that a local .got entry will be partially - initialized at startup awaiting its RELATIVE fixup. */ - - __asm("sethi %%hi(.Load_address), %1\n" - ".Load_address:\n\t" - "rd %%pc, %0\n\t" - "or %1, %%lo(.Load_address), %1\n\t" - : "=r"(pc), "=r"(la)); + register Elf64_Addr *elf_pic_register __asm__("%l7"); - return pc - *(Elf64_Addr *)(elf_pic_register + la); + /* We used to utilize the fact that a local .got entry will + be partially initialized at startup awaiting its RELATIVE + fixup: + + Elf64_Addr pc, la; + + __asm("sethi %%hi(.Load_address), %1\n" + ".Load_address:\n\t" + "rd %%pc, %0\n\t" + "or %1, %%lo(.Load_address), %1\n\t" + : "=r"(pc), "=r"(la)); + + return pc - *(Elf64_Addr *)(elf_pic_register + la); + + Unfortunately as binutils tries to work around Solaris + dynamic linker bug which resolves R_SPARC_RELATIVE as X += B + A + instead of X = B + A this does not work any longer, since ld + clears it. + + The following method relies on the fact that sparcv9 ABI maximal + page length is 1MB and all ELF segments on sparc64 are aligned + to 1MB. Also, it relies on _DYNAMIC coming after _GLOBAL_OFFSET_TABLE_ + and assumes that they both fit into the first 1MB of the RW segment. + This should be true for some time unless ld.so grows too much, at the + moment the whole stripped ld.so is 128KB and only smaller part of that + is in the RW segment. */ + + return ((Elf64_Addr)elf_pic_register - *elf_pic_register + 0xfffff) + & ~0xfffffUL; } /* We have 4 cases to handle. And we code different code sequences |