aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2013-03-10 11:49:29 +0000
committerMike Frysinger <vapier@gentoo.org>2013-03-12 06:00:05 -0400
commitc5abd7ce01539dc5224f7533c9d1048900992317 (patch)
treecca3fe48d201c7078fd530f55913ce9ce01eec83
parentb7845b638818f32401070f00a61d3b42595ab223 (diff)
downloadglibc-c5abd7ce01539dc5224f7533c9d1048900992317.zip
glibc-c5abd7ce01539dc5224f7533c9d1048900992317.tar.gz
glibc-c5abd7ce01539dc5224f7533c9d1048900992317.tar.bz2
ia64: fix strict aliasing warnings with func descriptors
Function pointers on ia64 are like parisc -- they're plabels. While the parisc port enjoys a gcc builtin for extracting the address here, ia64 has no such luck. Casting & dereferencing in one go triggers a strict aliasing warning. Use a union to fix that. Signed-off-by: Mike Frysinger <vapier@gentoo.org>
-rw-r--r--ports/ChangeLog.ia6412
-rw-r--r--ports/sysdeps/ia64/dl-fptr.h10
-rw-r--r--ports/sysdeps/ia64/dl-machine.h4
-rw-r--r--ports/sysdeps/ia64/entry.h5
-rw-r--r--ports/sysdeps/unix/sysv/linux/ia64/makecontext.c16
5 files changed, 34 insertions, 13 deletions
diff --git a/ports/ChangeLog.ia64 b/ports/ChangeLog.ia64
index c0cf5c9..82ae703 100644
--- a/ports/ChangeLog.ia64
+++ b/ports/ChangeLog.ia64
@@ -1,3 +1,15 @@
+2013-03-12 Mike Frysinger <vapier@gentoo.org>
+
+ * sysdeps/ia64/dl-fptr.h (ELF_PTR_TO_FDESC): New definition.
+ * sysdeps/ia64/dl-machine.h (elf_machine_runtime_setup): Change
+ struct fdesc * casts to use new ELF_PTR_TO_FDESC helper.
+ * sysdeps/ia64/entry.h: Include link.h and dl-fptr.h.
+ (ENTRY_POINT): Change cast to use new ELF_PTR_TO_FDESC helper.
+ * sysdeps/unix/sysv/linux/ia64/makecontext.c: Include link.h and
+ dl-fptr.h.
+ (struct fdesc): Remove structure, now redundant.
+ (makecontext): Change casts to use new ELF_PTR_TO_FDESC helper.
+
2013-03-11 Andreas Jaeger <aj@suse.de>
* sysdeps/unix/sysv/linux/ia64/bits/mman.h: Remove all defines
diff --git a/ports/sysdeps/ia64/dl-fptr.h b/ports/sysdeps/ia64/dl-fptr.h
index c2bef6c..447c098 100644
--- a/ports/sysdeps/ia64/dl-fptr.h
+++ b/ports/sysdeps/ia64/dl-fptr.h
@@ -32,4 +32,14 @@
#define ELF_MACHINE_LOAD_ADDRESS(var, symbol) \
asm ("movl %0 = @gprel (" #symbol ");; add %0 = %0, gp" : "=&r" (var));
+/* We don't have a gcc helper to extract the plabel info. */
+#define ELF_PTR_TO_FDESC(ptr) \
+ ({ union { \
+ void *_ptr; \
+ struct fdesc *_fdesc; \
+ } _u; \
+ _u._ptr = ptr; \
+ _u._fdesc; \
+ })
+
#endif /* !dl_ia64_fptr_h */
diff --git a/ports/sysdeps/ia64/dl-machine.h b/ports/sysdeps/ia64/dl-machine.h
index 2eb80d7..dd469d7 100644
--- a/ports/sysdeps/ia64/dl-machine.h
+++ b/ports/sysdeps/ia64/dl-machine.h
@@ -119,7 +119,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
/* This function will be called to perform the relocation. */
if (!profile)
- doit = (Elf64_Addr) ((struct fdesc *) &_dl_runtime_resolve)->ip;
+ doit = (Elf64_Addr) ELF_PTR_TO_FDESC (&_dl_runtime_resolve)->ip;
else
{
if (GLRO(dl_profile) != NULL
@@ -129,7 +129,7 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
want profiling and the timers are started. */
GL(dl_profile_map) = l;
}
- doit = (Elf64_Addr) ((struct fdesc *) &_dl_runtime_profile)->ip;
+ doit = (Elf64_Addr) ELF_PTR_TO_FDESC (&_dl_runtime_profile)->ip;
}
reserve[1] = doit;
diff --git a/ports/sysdeps/ia64/entry.h b/ports/sysdeps/ia64/entry.h
index b93e1b6..e11b49f 100644
--- a/ports/sysdeps/ia64/entry.h
+++ b/ports/sysdeps/ia64/entry.h
@@ -1,10 +1,13 @@
+#include <link.h>
+#include <dl-fptr.h>
+
#ifndef __ASSEMBLY__
extern void _start (void);
#endif
/* The function's entry point is stored in the first word of the
function descriptor (plabel) of _start(). */
-#define ENTRY_POINT (((long int *) _start)[0])
+#define ENTRY_POINT ELF_PTR_TO_FDESC (_start)->ip
/* We have to provide a special declaration. */
#define ENTRY_POINT_DECL(class) class void _start (void);
diff --git a/ports/sysdeps/unix/sysv/linux/ia64/makecontext.c b/ports/sysdeps/unix/sysv/linux/ia64/makecontext.c
index a512c94..c3bb5de 100644
--- a/ports/sysdeps/unix/sysv/linux/ia64/makecontext.c
+++ b/ports/sysdeps/unix/sysv/linux/ia64/makecontext.c
@@ -22,14 +22,10 @@
#include <stdlib.h>
#include <ucontext.h>
#include <sys/rse.h>
+#include <link.h>
+#include <dl-fptr.h>
-struct fdesc
- {
- unsigned long ip;
- unsigned long gp;
- };
-
#define PUSH(val) \
do { \
if (ia64_rse_is_rnat_slot (rbs)) \
@@ -65,16 +61,16 @@ makecontext: does not know how to handle more than 8 arguments\n"));
}
/* set the entry point and global pointer: */
- sc->sc_br[0] = ((struct fdesc *) &__start_context)->ip;
- sc->sc_br[1] = ((struct fdesc *) func)->ip;
- sc->sc_gr[1] = ((struct fdesc *) func)->gp;
+ sc->sc_br[0] = ELF_PTR_TO_FDESC (&__start_context)->ip;
+ sc->sc_br[1] = ELF_PTR_TO_FDESC (func)->ip;
+ sc->sc_gr[1] = ELF_PTR_TO_FDESC (func)->gp;
/* set up the call frame: */
sc->sc_ar_pfs = ((sc->sc_ar_pfs & ~0x3fffffffffUL)
| (argc + 2) | ((argc + 2) << 7));
rbs = (unsigned long *) stack_start;
PUSH((long) ucp->uc_link);
- PUSH(((struct fdesc *) &__start_context)->gp);
+ PUSH(ELF_PTR_TO_FDESC (&__start_context)->gp);
va_start (ap, argc);
for (i = 0; i < argc; ++i)
PUSH(va_arg (ap, long));