mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
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.
This commit is contained in:
committed by
Carlos O'Donell
parent
d33cafadfe
commit
daf75146de
@ -1,3 +1,12 @@
|
|||||||
|
2013-11-21 Guy Martin <gmsoft@tuxicoman.be>
|
||||||
|
|
||||||
|
* sysdeps/generic/ldsodefs.h: Replace DL_DT_INIT_ADDRESS() and
|
||||||
|
DL_DT_FINI_ADDRESS() macro with DL_CALL_DT_INIT() and
|
||||||
|
DL_CALL_DT_FINI() that call the functions directly.
|
||||||
|
* elf/dl-init.c: Use the new DL_CALL_DT_INIT() macro.
|
||||||
|
* elf/dl-close.c: Use the new DL_CALL_DT_FINI() macro.
|
||||||
|
* elf/dl-fini.c: Likewise.
|
||||||
|
|
||||||
2013-11-20 Ondřej Bílka <neleai@seznam.cz>
|
2013-11-20 Ondřej Bílka <neleai@seznam.cz>
|
||||||
|
|
||||||
* malloc/hooks.c (memalign_check): Add alignment rounding.
|
* malloc/hooks.c (memalign_check): Add alignment rounding.
|
||||||
|
@ -274,9 +274,8 @@ _dl_close_worker (struct link_map *map)
|
|||||||
|
|
||||||
/* Next try the old-style destructor. */
|
/* Next try the old-style destructor. */
|
||||||
if (imap->l_info[DT_FINI] != NULL)
|
if (imap->l_info[DT_FINI] != NULL)
|
||||||
(*(void (*) (void)) DL_DT_FINI_ADDRESS
|
DL_CALL_DT_FINI (imap, ((void *) imap->l_addr
|
||||||
(imap, ((void *) imap->l_addr
|
+ imap->l_info[DT_FINI]->d_un.d_ptr));
|
||||||
+ imap->l_info[DT_FINI]->d_un.d_ptr))) ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SHARED
|
#ifdef SHARED
|
||||||
|
@ -254,7 +254,7 @@ _dl_fini (void)
|
|||||||
|
|
||||||
/* Next try the old-style destructor. */
|
/* Next try the old-style destructor. */
|
||||||
if (l->l_info[DT_FINI] != NULL)
|
if (l->l_info[DT_FINI] != NULL)
|
||||||
((fini_t) DL_DT_FINI_ADDRESS (l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr)) ();
|
DL_CALL_DT_FINI(l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SHARED
|
#ifdef SHARED
|
||||||
|
@ -61,13 +61,7 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
|
|||||||
- the others in the DT_INIT_ARRAY.
|
- the others in the DT_INIT_ARRAY.
|
||||||
*/
|
*/
|
||||||
if (l->l_info[DT_INIT] != NULL)
|
if (l->l_info[DT_INIT] != NULL)
|
||||||
{
|
DL_CALL_DT_INIT(l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr, argc, argv, env);
|
||||||
init_t init = (init_t) DL_DT_INIT_ADDRESS
|
|
||||||
(l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr);
|
|
||||||
|
|
||||||
/* Call the function. */
|
|
||||||
init (argc, argv, env);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Next see whether there is an array with initialization functions. */
|
/* Next see whether there is an array with initialization functions. */
|
||||||
ElfW(Dyn) *init_array = l->l_info[DT_INIT_ARRAY];
|
ElfW(Dyn) *init_array = l->l_info[DT_INIT_ARRAY];
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
2013-11-21 Guy Martin <gmsoft@tuxicoman.be>
|
||||||
|
|
||||||
|
* sysdeps/hppa/dl-lookupcfg.h: Remove obsolete
|
||||||
|
DL_DT_INIT_ADDRESS() and DL_DT_FINI_ADDRESS() macro and implement
|
||||||
|
DL_CALL_DT_INIT() as well as DL_CALL_DT_FINI().
|
||||||
|
Define DL_DT_FUNCTION_ADDRESS().
|
||||||
|
* sysdeps/hppa/dl-machine.h: Update ELF_MACHINE_START_ADDRESS()
|
||||||
|
to use DL_DT_FUNCTION_ADDRESS().
|
||||||
|
|
||||||
2013-10-30 Mike Frysinger <vapier@gentoo.org>
|
2013-10-30 Mike Frysinger <vapier@gentoo.org>
|
||||||
|
|
||||||
* sysdeps/hppa/configure.in: Moved to ...
|
* sysdeps/hppa/configure.in: Moved to ...
|
||||||
|
@ -1,3 +1,12 @@
|
|||||||
|
2013-11-21 Guy Martin <gmsoft@tuxicoman.be>
|
||||||
|
|
||||||
|
* sysdeps/ia64/dl-lookupcfg.h: Remove obsolete
|
||||||
|
DL_DT_INIT_ADDRESS() and DL_DT_FINI_ADDRESS() macro and implement
|
||||||
|
DL_CALL_DT_INIT() as well as DL_CALL_DT_FINI().
|
||||||
|
Define DL_DT_FUNCTION_ADDRESS().
|
||||||
|
* sysdeps/ia64/dl-machine.h: Update ELF_MACHINE_START_ADDRESS()
|
||||||
|
to use DL_DT_FUNCTION_ADDRESS().
|
||||||
|
|
||||||
2013-10-30 Mike Frysinger <vapier@gentoo.org>
|
2013-10-30 Mike Frysinger <vapier@gentoo.org>
|
||||||
|
|
||||||
* sysdeps/ia64/configure.in: Moved to ...
|
* sysdeps/ia64/configure.in: Moved to ...
|
||||||
|
@ -38,32 +38,36 @@ void _dl_unmap (struct link_map *map);
|
|||||||
|
|
||||||
#define DL_UNMAP(map) _dl_unmap (map)
|
#define DL_UNMAP(map) _dl_unmap (map)
|
||||||
|
|
||||||
#define DL_AUTO_FUNCTION_ADDRESS(map, addr) \
|
#define DL_DT_FUNCTION_ADDRESS(map, start, attr, addr) \
|
||||||
({ \
|
attr volatile unsigned int fptr[2]; \
|
||||||
unsigned int fptr[2]; \
|
/* The test for "start & 2" below is to accommodate old binaries which \
|
||||||
fptr[0] = (unsigned int) (addr); \
|
violated the ELF ABI by pointing DT_INIT and DT_FINI at a function \
|
||||||
fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \
|
descriptor. */ \
|
||||||
/* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */ \
|
if ((ElfW(Addr)) (start) & 2) \
|
||||||
(ElfW(Addr))((unsigned int)fptr | 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_STATIC_FUNCTION_ADDRESS(map, addr) \
|
#define DL_CALL_DT_INIT(map, start, argc, argv, env) \
|
||||||
({ \
|
{ \
|
||||||
static unsigned int fptr[2]; \
|
ElfW(Addr) addr; \
|
||||||
fptr[0] = (unsigned int) (addr); \
|
DL_DT_FUNCTION_ADDRESS(map, start, , addr) \
|
||||||
fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \
|
init_t init = (init_t) addr; \
|
||||||
/* Set bit 30 to indicate to $$dyncall that this is a PLABEL. */ \
|
init (argc, argv, env); \
|
||||||
(ElfW(Addr))((unsigned int)fptr | 2); \
|
}
|
||||||
})
|
|
||||||
|
|
||||||
|
#define DL_CALL_DT_FINI(map, start) \
|
||||||
/* 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
|
ElfW(Addr) addr; \
|
||||||
descriptor. */
|
DL_DT_FUNCTION_ADDRESS(map, start, , addr) \
|
||||||
#define DL_DT_INIT_ADDRESS(map, addr) \
|
fini_t fini = (fini_t) addr; \
|
||||||
((Elf32_Addr)(addr) & 2 ? (addr) : DL_AUTO_FUNCTION_ADDRESS (map, addr))
|
fini (); \
|
||||||
#define DL_DT_FINI_ADDRESS(map, addr) \
|
}
|
||||||
((Elf32_Addr)(addr) & 2 ? (addr) : DL_AUTO_FUNCTION_ADDRESS (map, addr))
|
|
||||||
|
|
||||||
/* The type of the return value of fixup/profile_fixup */
|
/* The type of the return value of fixup/profile_fixup */
|
||||||
#define DL_FIXUP_VALUE_TYPE struct fdesc
|
#define DL_FIXUP_VALUE_TYPE struct fdesc
|
||||||
|
@ -490,8 +490,12 @@ asm ( \
|
|||||||
#define ELF_MACHINE_NO_REL 1
|
#define ELF_MACHINE_NO_REL 1
|
||||||
|
|
||||||
/* Return the address of the entry point. */
|
/* Return the address of the entry point. */
|
||||||
#define ELF_MACHINE_START_ADDRESS(map, start) \
|
#define ELF_MACHINE_START_ADDRESS(map, start) \
|
||||||
DL_STATIC_FUNCTION_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
|
/* We define an initialization functions. This is called very early in
|
||||||
* _dl_sysdep_start. */
|
* _dl_sysdep_start. */
|
||||||
|
@ -39,24 +39,28 @@ extern void _dl_unmap (struct link_map *map);
|
|||||||
|
|
||||||
#define DL_UNMAP(map) _dl_unmap (map)
|
#define DL_UNMAP(map) _dl_unmap (map)
|
||||||
|
|
||||||
#define DL_AUTO_FUNCTION_ADDRESS(map, addr) \
|
#define DL_DT_FUNCTION_ADDRESS(map, start, attr, addr) \
|
||||||
({ \
|
attr volatile unsigned long int fptr[2]; \
|
||||||
unsigned long int fptr[2]; \
|
fptr[0] = (unsigned long int) (start); \
|
||||||
fptr[0] = (unsigned long int) (addr); \
|
fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \
|
||||||
fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \
|
addr = (ElfW(Addr)) fptr; \
|
||||||
(Elf64_Addr) fptr; \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define DL_STATIC_FUNCTION_ADDRESS(map, addr) \
|
#define DL_CALL_DT_INIT(map, start, argc, argv, env) \
|
||||||
({ \
|
{ \
|
||||||
static unsigned long int fptr[2]; \
|
ElfW(Addr) addr; \
|
||||||
fptr[0] = (unsigned long int) (addr); \
|
DL_DT_FUNCTION_ADDRESS(map, start, , addr) \
|
||||||
fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \
|
init_t init = (init_t) addr; \
|
||||||
(Elf64_Addr) fptr; \
|
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 (); \
|
||||||
|
}
|
||||||
|
|
||||||
#define DL_DT_INIT_ADDRESS(map, addr) DL_AUTO_FUNCTION_ADDRESS (map, addr)
|
|
||||||
#define DL_DT_FINI_ADDRESS(map, addr) DL_AUTO_FUNCTION_ADDRESS (map, addr)
|
|
||||||
/* The type of the return value of fixup/profile_fixup. */
|
/* The type of the return value of fixup/profile_fixup. */
|
||||||
#define DL_FIXUP_VALUE_TYPE struct fdesc
|
#define DL_FIXUP_VALUE_TYPE struct fdesc
|
||||||
/* Construct a value of type DL_FIXUP_VALUE_TYPE from a code address
|
/* Construct a value of type DL_FIXUP_VALUE_TYPE from a code address
|
||||||
|
@ -322,8 +322,12 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
|
|||||||
#define ELF_MACHINE_NO_REL 1
|
#define ELF_MACHINE_NO_REL 1
|
||||||
|
|
||||||
/* Return the address of the entry point. */
|
/* Return the address of the entry point. */
|
||||||
#define ELF_MACHINE_START_ADDRESS(map, start) \
|
#define ELF_MACHINE_START_ADDRESS(map, start) \
|
||||||
DL_STATIC_FUNCTION_ADDRESS (map, start)
|
({ \
|
||||||
|
ElfW(Addr) addr; \
|
||||||
|
DL_DT_FUNCTION_ADDRESS(map, start, static, addr) \
|
||||||
|
addr; \
|
||||||
|
})
|
||||||
|
|
||||||
/* Fixup a PLT entry to bounce directly to the function at VALUE. */
|
/* Fixup a PLT entry to bounce directly to the function at VALUE. */
|
||||||
static inline struct fdesc __attribute__ ((always_inline))
|
static inline struct fdesc __attribute__ ((always_inline))
|
||||||
|
@ -76,8 +76,9 @@ typedef struct link_map *lookup_t;
|
|||||||
# define DL_SYMBOL_ADDRESS(map, ref) \
|
# define DL_SYMBOL_ADDRESS(map, ref) \
|
||||||
(void *) (LOOKUP_VALUE_ADDRESS (map) + ref->st_value)
|
(void *) (LOOKUP_VALUE_ADDRESS (map) + ref->st_value)
|
||||||
# define DL_LOOKUP_ADDRESS(addr) ((ElfW(Addr)) (addr))
|
# define DL_LOOKUP_ADDRESS(addr) ((ElfW(Addr)) (addr))
|
||||||
# define DL_DT_INIT_ADDRESS(map, start) (start)
|
# define DL_CALL_DT_INIT(map, start, argc, argv, env) \
|
||||||
# define DL_DT_FINI_ADDRESS(map, start) (start)
|
((init_t) (start)) (argc, argv, env)
|
||||||
|
# define DL_CALL_DT_FINI(map, start) ((fini_t) (start)) ()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* On some architectures dladdr can't use st_size of all symbols this way. */
|
/* On some architectures dladdr can't use st_size of all symbols this way. */
|
||||||
|
Reference in New Issue
Block a user