diff options
author | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2012-07-12 13:04:55 +0200 |
---|---|---|
committer | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2012-07-19 15:46:34 +0200 |
commit | 08f43f9bbf97c03ec4d2754c69fd9d7efce6ef96 (patch) | |
tree | 17318764c9e7b5e6c151def3bdab1fc30af377ed /sysdeps/s390/s390-64/dl-machine.h | |
parent | a98430587c57da2832fa9abe336c5a8f8137e89c (diff) | |
download | glibc-08f43f9bbf97c03ec4d2754c69fd9d7efce6ef96.tar.gz glibc-08f43f9bbf97c03ec4d2754c69fd9d7efce6ef96.tar.xz glibc-08f43f9bbf97c03ec4d2754c69fd9d7efce6ef96.zip |
S/390: Add support for STT_GNU_IFUNC symbols.
Add support for STT_GNU_IFUNC symbols and the new R_390_IRELATIVE relocation. Provide optimized version of memcpy, memset, and memcmp for z10 and z196.
Diffstat (limited to 'sysdeps/s390/s390-64/dl-machine.h')
-rw-r--r-- | sysdeps/s390/s390-64/dl-machine.h | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h index 908c024763..067336e2a6 100644 --- a/sysdeps/s390/s390-64/dl-machine.h +++ b/sysdeps/s390/s390-64/dl-machine.h @@ -1,6 +1,6 @@ /* Machine-dependent ELF dynamic relocation inline functions. 64 bit S/390 Version. - Copyright (C) 2001-2005, 2006, 2011 Free Software Foundation, Inc. + Copyright (C) 2001-2012 Free Software Foundation, Inc. Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). This file is part of the GNU C Library. @@ -26,6 +26,9 @@ #include <sys/param.h> #include <string.h> #include <link.h> +#include <dl-irel.h> + +#define ELF_MACHINE_IRELATIVE R_390_IRELATIVE /* This is an older, now obsolete value. */ #define EM_S390_OLD 0xA390 @@ -280,8 +283,21 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); Elf64_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value; + if (sym != NULL + && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, + 0) + && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1) + && __builtin_expect (!skip_ifunc, 1)) + value = elf_ifunc_invoke (value); + switch (r_type) { + case R_390_IRELATIVE: + value = map->l_addr + reloc->r_addend; + if (__builtin_expect (!skip_ifunc, 1)) + value = elf_ifunc_invoke (value); + *reloc_addr = value; + break; case R_390_GLOB_DAT: case R_390_JMP_SLOT: *reloc_addr = value + reloc->r_addend; @@ -426,6 +442,13 @@ elf_machine_lazy_rel (struct link_map *map, map->l_mach.plt + (((Elf64_Addr) reloc_addr) - map->l_mach.gotplt) * 4; } + else if (__builtin_expect (r_type == R_390_IRELATIVE, 1)) + { + Elf64_Addr value = map->l_addr + reloc->r_addend; + if (__builtin_expect (!skip_ifunc, 1)) + value = elf_ifunc_invoke (value); + *reloc_addr = value; + } else _dl_reloc_bad_type (map, r_type, 1); } |