From 08f43f9bbf97c03ec4d2754c69fd9d7efce6ef96 Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Thu, 12 Jul 2012 13:04:55 +0200 Subject: 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. --- sysdeps/s390/s390-32/dl-machine.h | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'sysdeps/s390/s390-32/dl-machine.h') diff --git a/sysdeps/s390/s390-32/dl-machine.h b/sysdeps/s390/s390-32/dl-machine.h index 3eb7e41..e56ad67 100644 --- a/sysdeps/s390/s390-32/dl-machine.h +++ b/sysdeps/s390/s390-32/dl-machine.h @@ -1,6 +1,5 @@ /* Machine-dependent ELF dynamic relocation inline functions. S390 Version. - Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2011 - Free Software Foundation, Inc. + Copyright (C) 2000-2012 Free Software Foundation, Inc. Contributed by Carl Pederson & Martin Schwidefsky. This file is part of the GNU C Library. @@ -27,6 +26,7 @@ #include #include #include +#include /* This is an older, now obsolete value. */ #define EM_S390_OLD 0xA390 @@ -305,8 +305,21 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); Elf32_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; @@ -444,6 +457,13 @@ elf_machine_lazy_rel (struct link_map *map, map->l_mach.plt + (((Elf32_Addr) reloc_addr) - map->l_mach.gotplt) * 8; } + else if (__builtin_expect (r_type == R_390_IRELATIVE, 1)) + { + Elf32_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); } -- cgit v1.1