This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] HPPA/IA64 : Don't use broken DL_AUTO_FUNCTION_ADDRESS()
- From: Guy Martin <gmsoft at tuxicoman dot be>
- To: Andreas Schwab <schwab at suse dot de>
- Cc: Carlos O'Donell <carlos at redhat dot com>, Mike Frysinger <vapier at gentoo dot org>, libc-alpha at sourceware dot org
- Date: Wed, 06 Nov 2013 13:53:42 +0100
- Subject: Re: [PATCH] HPPA/IA64 : Don't use broken DL_AUTO_FUNCTION_ADDRESS()
- Authentication-results: sourceware.org; auth=none
- References: <20131017214754 dot 00555bf3 at dellete> <871u3ina5t dot fsf at igel dot home> <b42704e5527fa00f6e69cacd0d62c19d at tuxicoman dot be> <201310190206 dot 07506 dot vapier at gentoo dot org> <52631FA0 dot 5090403 at redhat dot com> <78728c2956beea68522df0d0e5f8d649 at tuxicoman dot be> <80a141633592ef9ba33d3217af3e9cef at tuxicoman dot be> <mvmy559wode dot fsf at hawking dot suse dot de>
On 2013-10-31 14:39, Andreas Schwab wrote:
Guy Martin <gmsoft@tuxicoman.be> writes:
diff --git a/elf/dl-close.c b/elf/dl-close.c
index fe3014c..3735527 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -274,9 +274,8 @@ _dl_close_worker (struct link_map *map)
/* Next try the old-style destructor. */
if (imap->l_info[DT_FINI] != NULL)
- (*(void (*) (void)) DL_DT_FINI_ADDRESS
- (imap, ((void *) imap->l_addr
- + imap->l_info[DT_FINI]->d_un.d_ptr))) ();
+ DL_DT_FINI (imap, ((void *) imap->l_addr
+ + imap->l_info[DT_FINI]->d_un.d_ptr));
The macro should have CALL in its name.
diff --git a/ports/sysdeps/hppa/dl-machine.h
b/ports/sysdeps/hppa/dl-machine.h
index d2411a6..b8587a5 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; \
+ static DL_DT_FUNCTION_ADDRESS(map, start, addr) \
Please make static an argument of the macro.
The attached patch addresses the above issues. I also fixed warnings at
compile time.
Tested on amd64 and hppa. Untested on ia64.
Regards,
Guy
Main ChangeLog :
2013-11-06 Guy Martin <gmsoft@tuxicoman.be>
* sysdeps/generic/ldsodefs.h: Replace DL_DT_INIT_ADDRESS() and
DL_DT_FINI_ADDRESS() macro with DL_DT_CALL_INIT() and
DL_DT_CALL_FINI() that call the functions directly.
* elf/dl-init.c: Use the new DL_DT_CALL_INIT() macro.
* elf/dl-close.c: Use the new DL_DT_CALL_FINI() macro.
* elf/dl-fini.c: Likewise.
Ports ChangeLog :
2013-11-06 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_DT_CALL_INIT() as well as DL_DT_CALL_FINI().
Define DL_DT_FUNCTION_ADDRESS().
* sysdeps/ia64/dl-lookupcfg.h: Likewise.
* sysdeps/hppa/dl-machine.h: Update ELF_MACHINE_START_ADDRESS()
to use DL_DT_FUNCTION_ADDRESS().
* sysdeps/ia64/dl-machine.h: Likewise.
diff --git a/elf/dl-close.c b/elf/dl-close.c
index fe3014c..78c6dcc 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -274,9 +274,8 @@ _dl_close_worker (struct link_map *map)
/* Next try the old-style destructor. */
if (imap->l_info[DT_FINI] != NULL)
- (*(void (*) (void)) DL_DT_FINI_ADDRESS
- (imap, ((void *) imap->l_addr
- + imap->l_info[DT_FINI]->d_un.d_ptr))) ();
+ DL_DT_CALL_FINI (imap, ((void *) imap->l_addr
+ + imap->l_info[DT_FINI]->d_un.d_ptr));
}
#ifdef SHARED
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
index 6b245f0..58ade6c 100644
--- a/elf/dl-fini.c
+++ b/elf/dl-fini.c
@@ -254,7 +254,7 @@ _dl_fini (void)
/* Next try the old-style destructor. */
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_DT_CALL_FINI(l, l->l_addr + l->l_info[DT_FINI]->d_un.d_ptr);
}
#ifdef SHARED
diff --git a/elf/dl-init.c b/elf/dl-init.c
index a657eb6..41a12dd 100644
--- a/elf/dl-init.c
+++ b/elf/dl-init.c
@@ -61,13 +61,7 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
- the others in the DT_INIT_ARRAY.
*/
if (l->l_info[DT_INIT] != NULL)
- {
- 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);
- }
+ DL_DT_CALL_INIT(l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr, argc, argv, env);
/* Next see whether there is an array with initialization functions. */
ElfW(Dyn) *init_array = l->l_info[DT_INIT_ARRAY];
diff --git a/ports/sysdeps/hppa/dl-lookupcfg.h b/ports/sysdeps/hppa/dl-lookupcfg.h
index f3125e5..e918511 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_DT_CALL_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_DT_CALL_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 d2411a6..e47e947 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. */
diff --git a/ports/sysdeps/ia64/dl-lookupcfg.h b/ports/sysdeps/ia64/dl-lookupcfg.h
index 4da1263..323623d 100644
--- a/ports/sysdeps/ia64/dl-lookupcfg.h
+++ b/ports/sysdeps/ia64/dl-lookupcfg.h
@@ -39,24 +39,29 @@ extern void _dl_unmap (struct link_map *map);
#define DL_UNMAP(map) _dl_unmap (map)
-#define DL_AUTO_FUNCTION_ADDRESS(map, addr) \
-({ \
- unsigned long int fptr[2]; \
- fptr[0] = (unsigned long int) (addr); \
- fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \
- (Elf64_Addr) fptr; \
-})
-
-#define DL_STATIC_FUNCTION_ADDRESS(map, addr) \
-({ \
- static unsigned long int fptr[2]; \
- fptr[0] = (unsigned long int) (addr); \
- fptr[1] = (map)->l_info[DT_PLTGOT]->d_un.d_ptr; \
- (Elf64_Addr) fptr; \
-})
-
-#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)
+#define DL_DT_FUNCTION_ADDRESS(map, start, attr, addr) \
+ attr volatile unsigned int fptr[2]; \
+ 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_DT_CALL_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_DT_CALL_FINI(map, start) \
+{ \
+ ElfW(Addr) addr; \
+ DL_DT_FUNCTION_ADDRESS(map, start, , addr) \
+ fini_t fini = (finit_t) addr; \
+ fini (); \
+}
+
/* The type of the return value of fixup/profile_fixup. */
#define DL_FIXUP_VALUE_TYPE struct fdesc
/* Construct a value of type DL_FIXUP_VALUE_TYPE from a code address
diff --git a/ports/sysdeps/ia64/dl-machine.h b/ports/sysdeps/ia64/dl-machine.h
index dd469d7..d469b86 100644
--- a/ports/sysdeps/ia64/dl-machine.h
+++ b/ports/sysdeps/ia64/dl-machine.h
@@ -322,8 +322,12 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
#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;
+})
/* Fixup a PLT entry to bounce directly to the function at VALUE. */
static inline struct fdesc __attribute__ ((always_inline))
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index e7b0516..edce07f 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -76,8 +76,8 @@ typedef struct link_map *lookup_t;
# define DL_SYMBOL_ADDRESS(map, ref) \
(void *) (LOOKUP_VALUE_ADDRESS (map) + ref->st_value)
# define DL_LOOKUP_ADDRESS(addr) ((ElfW(Addr)) (addr))
-# define DL_DT_INIT_ADDRESS(map, start) (start)
-# define DL_DT_FINI_ADDRESS(map, start) (start)
+# define DL_DT_CALL_INIT(map, start, argc, argv, env) ((init_t) (start)) (argc, argv, env)
+# define DL_DT_CALL_FINI(map, start) ((fini_t) (start)) ()
#endif
/* On some architectures dladdr can't use st_size of all symbols this way. */