diff options
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/generic/dl-fptr.h | 2 | ||||
-rw-r--r-- | sysdeps/generic/dl-lookupcfg.h | 11 | ||||
-rw-r--r-- | sysdeps/ia64/dl-lookupcfg.h | 14 | ||||
-rw-r--r-- | sysdeps/ia64/dl-machine.h | 24 |
4 files changed, 36 insertions, 15 deletions
diff --git a/sysdeps/generic/dl-fptr.h b/sysdeps/generic/dl-fptr.h index 8156981e6e..d47fb7b635 100644 --- a/sysdeps/generic/dl-fptr.h +++ b/sysdeps/generic/dl-fptr.h @@ -36,6 +36,8 @@ struct fdesc_table struct fdesc fdesc[0]; }; +struct link_map; + extern ElfW(Addr) _dl_boot_fptr_table []; extern ElfW(Addr) _dl_make_fptr (struct link_map *, const ElfW(Sym) *, diff --git a/sysdeps/generic/dl-lookupcfg.h b/sysdeps/generic/dl-lookupcfg.h index 39c430b41e..2b29989600 100644 --- a/sysdeps/generic/dl-lookupcfg.h +++ b/sysdeps/generic/dl-lookupcfg.h @@ -17,4 +17,13 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -/* Nothing special. */ +/* The type of the return value of fixup/profile_fixup. */ +#define DL_FIXUP_VALUE_TYPE ElfW(Addr) +/* Construct a value of type DL_FIXUP_VALUE_TYPE from a code address + and a link map. */ +#define DL_FIXUP_MAKE_VALUE(map, addr) (addr) +/* Extract the code address from a value of type DL_FIXUP_MAKE_VALUE. + */ +#define DL_FIXUP_VALUE_CODE_ADDR(value) (value) +#define DL_FIXUP_VALUE_ADDR(value) (value) +#define DL_FIXUP_ADDR_VALUE(addr) (addr) diff --git a/sysdeps/ia64/dl-lookupcfg.h b/sysdeps/ia64/dl-lookupcfg.h index ddf405b551..b50030ebd2 100644 --- a/sysdeps/ia64/dl-lookupcfg.h +++ b/sysdeps/ia64/dl-lookupcfg.h @@ -20,6 +20,8 @@ #define ELF_FUNCTION_PTR_IS_SPECIAL #define DL_UNMAP_IS_SPECIAL +#include <dl-fptr.h> + /* We do not support copy relocations for IA-64. */ #define DL_NO_COPY_RELOCS @@ -56,3 +58,15 @@ extern void _dl_unmap (struct link_map *map); #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. */ +#define DL_FIXUP_VALUE_TYPE struct fdesc +/* Construct a value of type DL_FIXUP_VALUE_TYPE from a code address + and a link map. */ +#define DL_FIXUP_MAKE_VALUE(map, addr) \ + ((struct fdesc) { (addr), (map)->l_info[DT_PLTGOT]->d_un.d_ptr }) +/* Extract the code address from a value of type DL_FIXUP_MAKE_VALUE. + */ +#define DL_FIXUP_VALUE_CODE_ADDR(value) (value).ip + +#define DL_FIXUP_VALUE_ADDR(value) ((uintptr_t) &(value)) +#define DL_FIXUP_ADDR_VALUE(addr) (*(struct fdesc *) (addr)) diff --git a/sysdeps/ia64/dl-machine.h b/sysdeps/ia64/dl-machine.h index 2864315cca..55349690e3 100644 --- a/sysdeps/ia64/dl-machine.h +++ b/sysdeps/ia64/dl-machine.h @@ -331,34 +331,29 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) #define ELF_MACHINE_START_ADDRESS(map, start) \ DL_STATIC_FUNCTION_ADDRESS (map, start) -#define elf_machine_profile_fixup_plt(l, reloc, rel_addr, value) \ - elf_machine_fixup_plt (l, reloc, rel_addr, value) - -#define elf_machine_profile_plt(reloc_addr) ((Elf64_Addr) (reloc_addr)) - /* Fixup a PLT entry to bounce directly to the function at VALUE. */ -static inline Elf64_Addr __attribute__ ((always_inline)) +static inline struct fdesc __attribute__ ((always_inline)) elf_machine_fixup_plt (struct link_map *l, lookup_t t, const Elf64_Rela *reloc, - Elf64_Addr *reloc_addr, Elf64_Addr value) + Elf64_Addr *reloc_addr, struct fdesc value) { /* l is the link_map for the caller, t is the link_map for the object * being called */ /* got has already been relocated in elf_get_dynamic_info() */ - reloc_addr[1] = t->l_info[DT_PLTGOT]->d_un.d_ptr; + reloc_addr[1] = value.gp; /* we need a "release" here to ensure that the gp is visible before the code entry point is updated: */ - ((volatile Elf64_Addr *) reloc_addr)[0] = value; - return (Elf64_Addr) reloc_addr; + ((volatile Elf64_Addr *) reloc_addr)[0] = value.ip; + return value; } /* Return the final value of a plt relocation. */ -static inline Elf64_Addr +static inline struct fdesc elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, - Elf64_Addr value) + struct fdesc value) { /* No need to handle rel vs rela since IA64 is rela only */ - return value + reloc->r_addend; + return (struct fdesc) { value.ip + reloc->r_addend, value.gp }; } #endif /* !dl_machine_h */ @@ -429,7 +424,8 @@ elf_machine_rela (struct link_map *map, ;/* No adjustment. */ else if (r_type == R_IA64_IPLTLSB) { - elf_machine_fixup_plt (NULL, sym_map, reloc, reloc_addr, value); + elf_machine_fixup_plt (NULL, NULL, reloc, reloc_addr, + DL_FIXUP_MAKE_VALUE (sym_map, value)); return; } else if (R_IA64_TYPE (r_type) == R_IA64_TYPE (R_IA64_FPTR64LSB)) |