From c5abd7ce01539dc5224f7533c9d1048900992317 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 10 Mar 2013 11:49:29 +0000 Subject: 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 --- ports/ChangeLog.ia64 | 12 ++++++++++++ ports/sysdeps/ia64/dl-fptr.h | 10 ++++++++++ ports/sysdeps/ia64/dl-machine.h | 4 ++-- ports/sysdeps/ia64/entry.h | 5 ++++- ports/sysdeps/unix/sysv/linux/ia64/makecontext.c | 16 ++++++---------- 5 files changed, 34 insertions(+), 13 deletions(-) diff --git a/ports/ChangeLog.ia64 b/ports/ChangeLog.ia64 index c0cf5c9dc6..82ae703593 100644 --- a/ports/ChangeLog.ia64 +++ b/ports/ChangeLog.ia64 @@ -1,3 +1,15 @@ +2013-03-12 Mike Frysinger + + * 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 * 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 c2bef6c288..447c098aff 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 2eb80d752f..dd469d7a73 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 b93e1b6a57..e11b49fc53 100644 --- a/ports/sysdeps/ia64/entry.h +++ b/ports/sysdeps/ia64/entry.h @@ -1,10 +1,13 @@ +#include +#include + #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 a512c94097..c3bb5de197 100644 --- a/ports/sysdeps/unix/sysv/linux/ia64/makecontext.c +++ b/ports/sysdeps/unix/sysv/linux/ia64/makecontext.c @@ -22,14 +22,10 @@ #include #include #include +#include +#include -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)); -- cgit v1.2.3