diff options
author | Ulrich Drepper <drepper@redhat.com> | 2009-05-31 23:45:33 -0700 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2009-05-31 23:45:33 -0700 |
commit | 74414708355a922a514d5c76183eca6931c4488a (patch) | |
tree | 60dd084df2e9f02464f66b0da2068f4561856458 /sysdeps/i386/dl-machine.h | |
parent | 963cb6fcb47ca212c0c57cc57bd7510f6549579c (diff) | |
download | glibc-74414708355a922a514d5c76183eca6931c4488a.tar.gz glibc-74414708355a922a514d5c76183eca6931c4488a.tar.xz glibc-74414708355a922a514d5c76183eca6931c4488a.zip |
Finish IFUNC support for x86 and x86-64.
Add support for the IRELAIVE relocation and IFUNC in static executables.
Diffstat (limited to 'sysdeps/i386/dl-machine.h')
-rw-r--r-- | sysdeps/i386/dl-machine.h | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h index 0e15878d4e..efa929e57f 100644 --- a/sysdeps/i386/dl-machine.h +++ b/sysdeps/i386/dl-machine.h @@ -345,6 +345,7 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, Elf32_Addr value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value; if (sym != NULL + && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1) && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)) value = ((Elf32_Addr (*) (void)) value) (); @@ -471,6 +472,11 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, memcpy (reloc_addr_arg, (void *) value, MIN (sym->st_size, refsym->st_size)); break; + case R_386_IRELATIVE: + value = map->l_addr + *reloc_addr; + value = ((Elf32_Addr (*) (void)) value) (); + *reloc_addr = value; + break; default: _dl_reloc_bad_type (map, r_type, 0); break; @@ -500,6 +506,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, Elf32_Addr value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value; if (sym != NULL + && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1) && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0)) value = ((Elf32_Addr (*) (void)) value) (); @@ -609,6 +616,11 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, MIN (sym->st_size, refsym->st_size)); break; # endif /* !RESOLVE_CONFLICT_FIND_MAP */ + case R_386_IRELATIVE: + value = map->l_addr + reloc->r_addend; + value = ((Elf32_Addr (*) (void)) value) (); + *reloc_addr = value; + break; default: /* We add these checks in the version to relocate ld.so only if we are still debugging. */ @@ -703,6 +715,12 @@ elf_machine_lazy_rel (struct link_map *map, # endif } } + else if (__builtin_expect (r_type == R_386_IRELATIVE, 0)) + { + Elf32_Addr value = map->l_addr + *reloc_addr; + value = ((Elf32_Addr (*) (void)) value) (); + *reloc_addr = value; + } else _dl_reloc_bad_type (map, r_type, 1); } @@ -726,6 +744,12 @@ elf_machine_lazy_rela (struct link_map *map, td->arg = (void*)reloc; td->entry = _dl_tlsdesc_resolve_rela; } + else if (__builtin_expect (r_type == R_386_IRELATIVE, 0)) + { + Elf32_Addr value = map->l_addr + reloc->r_addend; + value = ((Elf32_Addr (*) (void)) value) (); + *reloc_addr = value; + } else _dl_reloc_bad_type (map, r_type, 1); } |