diff options
author | Guy Martin <gmsoft@tuxicoman.be> | 2013-11-21 13:23:16 -0500 |
---|---|---|
committer | Carlos O'Donell <carlos@redhat.com> | 2013-11-21 15:52:31 -0500 |
commit | daf75146de07303ea0c5ad700ec5ef703ec114a1 (patch) | |
tree | ed307e39a90288cbcdf727a7c07addb9f38f65d8 /ports/sysdeps/hppa | |
parent | Add lang_name to Arabic locales. (diff) | |
download | glibc-daf75146de07303ea0c5ad700ec5ef703ec114a1.tar.gz glibc-daf75146de07303ea0c5ad700ec5ef703ec114a1.tar.bz2 glibc-daf75146de07303ea0c5ad700ec5ef703ec114a1.zip |
Don't use broken DL_AUTO_FUNCTION_ADDRESS()
On hppa and ia64, the macro DL_AUTO_FUNCTION_ADDRESS() uses the
variable fptr[2] in it's own scope.
The content of fptr[] is thus undefined right after the macro exits.
Newer gcc's (>= 4.7) reuse the stack space of this variable triggering
a segmentation fault in dl-init.c:69.
To fix this we rewrite the macros to make the call directly to init
and fini without needing to pass back a constructed function pointer.
Diffstat (limited to 'ports/sysdeps/hppa')
-rw-r--r-- | ports/sysdeps/hppa/dl-lookupcfg.h | 56 | ||||
-rw-r--r-- | ports/sysdeps/hppa/dl-machine.h | 8 |
2 files changed, 36 insertions, 28 deletions
diff --git a/ports/sysdeps/hppa/dl-lookupcfg.h b/ports/sysdeps/hppa/dl-lookupcfg.h index f3125e5ec6..feea320789 100644 --- a/ports/sysdeps/hppa/dl-lookupcfg.h +++ b/ports/sysdeps/hppa/dl-lookupcfg.h @@ -38,32 +38,36 @@ void _dl_unmap (struct link_map *map); #define DL_UNMAP(map) _dl_unmap (map) -#define DL_AUTO_FUNCTION_ADDRESS(map, addr) \ -({ \ - unsigned int fptr[2]; \ - fptr[0] = (unsigned int) (addr); \ - fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \ - /* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */ \ - (ElfW(Addr))((unsigned int)fptr | 2); \ -}) - -#define DL_STATIC_FUNCTION_ADDRESS(map, addr) \ -({ \ - static unsigned int fptr[2]; \ - fptr[0] = (unsigned int) (addr); \ - fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \ - /* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */ \ - (ElfW(Addr))((unsigned int)fptr | 2); \ -}) - - -/* The test for "addr & 2" below is to accommodate old binaries which - violated the ELF ABI by pointing DT_INIT and DT_FINI at a function - descriptor. */ -#define DL_DT_INIT_ADDRESS(map, addr) \ - ((Elf32_Addr)(addr) & 2 ? (addr) : DL_AUTO_FUNCTION_ADDRESS (map, addr)) -#define DL_DT_FINI_ADDRESS(map, addr) \ - ((Elf32_Addr)(addr) & 2 ? (addr) : DL_AUTO_FUNCTION_ADDRESS (map, addr)) +#define DL_DT_FUNCTION_ADDRESS(map, start, attr, addr) \ + attr volatile unsigned int fptr[2]; \ + /* The test for "start & 2" below is to accommodate old binaries which \ + violated the ELF ABI by pointing DT_INIT and DT_FINI at a function \ + descriptor. */ \ + if ((ElfW(Addr)) (start) & 2) \ + addr = (ElfW(Addr)) start; \ + else \ + { \ + fptr[0] = (unsigned int) (start); \ + fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \ + /* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */ \ + addr = (ElfW(Addr))((unsigned int)fptr | 2); \ + } \ + +#define DL_CALL_DT_INIT(map, start, argc, argv, env) \ +{ \ + ElfW(Addr) addr; \ + DL_DT_FUNCTION_ADDRESS(map, start, , addr) \ + init_t init = (init_t) addr; \ + init (argc, argv, env); \ +} + +#define DL_CALL_DT_FINI(map, start) \ +{ \ + ElfW(Addr) addr; \ + DL_DT_FUNCTION_ADDRESS(map, start, , addr) \ + fini_t fini = (fini_t) addr; \ + fini (); \ +} /* The type of the return value of fixup/profile_fixup */ #define DL_FIXUP_VALUE_TYPE struct fdesc diff --git a/ports/sysdeps/hppa/dl-machine.h b/ports/sysdeps/hppa/dl-machine.h index d2411a654a..e47e9473e1 100644 --- a/ports/sysdeps/hppa/dl-machine.h +++ b/ports/sysdeps/hppa/dl-machine.h @@ -490,8 +490,12 @@ asm ( \ #define ELF_MACHINE_NO_REL 1 /* Return the address of the entry point. */ -#define ELF_MACHINE_START_ADDRESS(map, start) \ - DL_STATIC_FUNCTION_ADDRESS (map, start) +#define ELF_MACHINE_START_ADDRESS(map, start) \ +({ \ + ElfW(Addr) addr; \ + DL_DT_FUNCTION_ADDRESS(map, start, static, addr) \ + addr; \ +}) /* We define an initialization functions. This is called very early in * _dl_sysdep_start. */ |