From d551a039ad443e1ba1c29461b43ca865785fbb68 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Tue, 23 Jun 2015 21:18:49 +0200 Subject: add patch from ldso-future branch Fixes segfaults when gcc 5.1 is used for x86. http://git.uclibc.org/uClibc/commit/ldso/ldso/i386/dl-sysdep.h?h=ldso-future&id=7de778389d0040be4a21ffc326310e0eb361570a Mentioned in #uclibc. --- ldso/ldso/i386/dl-sysdep.h | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/ldso/ldso/i386/dl-sysdep.h b/ldso/ldso/i386/dl-sysdep.h index a66c80212..8efa1a832 100644 --- a/ldso/ldso/i386/dl-sysdep.h +++ b/ldso/ldso/i386/dl-sysdep.h @@ -37,31 +37,27 @@ extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_ent | (((type) == R_386_COPY) * ELF_RTYPE_CLASS_COPY)) /* Return the link-time address of _DYNAMIC. Conveniently, this is the - first element of the GOT. This must be inlined in a function which - uses global data. */ -static __always_inline Elf32_Addr elf_machine_dynamic (void) attribute_unused; -static __always_inline Elf32_Addr + first element of the GOT, a special entry that is never relocated. */ +extern const Elf32_Addr _GLOBAL_OFFSET_TABLE_[] attribute_hidden; +static __always_inline Elf32_Addr __attribute__ ((unused, const)) elf_machine_dynamic (void) { - register Elf32_Addr *got __asm__ ("%ebx"); - return *got; + /* This produces a GOTOFF reloc that resolves to zero at link time, so in + fact just loads from the GOT register directly. By doing it without + an asm we can let the compiler choose any register. */ + return _GLOBAL_OFFSET_TABLE_[0]; } +extern Elf32_Dyn bygotoff[] __asm__ ("_DYNAMIC") attribute_hidden; /* Return the run-time load address of the shared object. */ -static __always_inline Elf32_Addr elf_machine_load_address (void) attribute_unused; -static __always_inline Elf32_Addr +static __always_inline Elf32_Addr attribute_unused elf_machine_load_address (void) { - /* It doesn't matter what variable this is, the reference never makes - it to assembly. We need a dummy reference to some global variable - via the GOT to make sure the compiler initialized %ebx in time. */ - Elf32_Addr addr; - int tmp; - __asm__ ("leal _dl_start@GOTOFF(%%ebx), %0\n" - "subl _dl_start@GOT(%%ebx), %0" - : "=r" (addr) : "m" (tmp) : "cc"); - return addr; + /* Compute the difference between the runtime address of _DYNAMIC as seen + by a GOTOFF reference, and the link-time address found in the special + unrelocated first GOT entry. */ + return (Elf32_Addr) &bygotoff - elf_machine_dynamic (); } static __always_inline void -- cgit v1.2.3