From 47f2d8e46f6d2fdfdcadda2892c32eced2d022fd28a284038e21da912516d12a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristian=20Rodr=C3=ADguez?= Date: Mon, 10 Oct 2011 21:11:45 +0000 Subject: [PATCH] Accepting request 87299 from home:a_jaeger:branches:openSUSE:Factory Fix tracing with ifuncs, e.g. ldd -u -r some-lib OBS-URL: https://build.opensuse.org/request/show/87299 OBS-URL: https://build.opensuse.org/package/show/Base:System/glibc?expand=0&rev=116 --- glibc-2.15-ifunc-trace.patch | 716 +++++++++++++++++++++++++++++++++++ glibc.changes | 5 + glibc.spec | 6 +- 3 files changed, 726 insertions(+), 1 deletion(-) create mode 100644 glibc-2.15-ifunc-trace.patch diff --git a/glibc-2.15-ifunc-trace.patch b/glibc-2.15-ifunc-trace.patch new file mode 100644 index 0000000..6a6409d --- /dev/null +++ b/glibc-2.15-ifunc-trace.patch @@ -0,0 +1,716 @@ +commit 3a62d00d408e9ec19479b6c7d39e89021061f9cd +Author: Andreas Schwab +Date: Tue Oct 4 16:10:16 2011 +0200 + + Don't call ifunc functions in trace mode + +2011-10-04 Andreas Schwab + + * include/dlfcn.h (__RTLD_NOIFUNC): Define. + * elf/do-rel.h (elf_dynamic_do_rel): Add parameter skip_ifunc and + pass it down. + * elf/dynamic-link.h: Adjust prototypes of elf_machine_rel, + elf_machine_rela, elf_machine_lazy_rel. + (_ELF_DYNAMIC_DO_RELOC): Add parameter skip_ifunc and pass it down. + (ELF_DYNAMIC_DO_REL): Likewise. + (ELF_DYNAMIC_DO_RELA): Likewise. + (ELF_DYNAMIC_RELOCATE): Likewise. + * elf/dl-reloc.c (_dl_relocate_object): Pass __RTLD_NOIFUNC down + to ELF_DYNAMIC_DO_REL. + * elf/rtld.c (_dl_start): Adjust use of ELF_DYNAMIC_RELOCATE. + (dl_main): In trace mode always set __RTLD_NOIFUNC. + * elf/dl-conflict.c (_dl_resolve_conflicts): Adjust call to + elf_machine_rela. + * sysdeps/i386/dl-machine.h (elf_machine_rel): Add parameter + skip_ifunc, don't call ifunc function if non-zero. + (elf_machine_rela): Likewise. + (elf_machine_lazy_rel): Likewise. + (elf_machine_lazy_rela): Likewise. + * sysdeps/ia64/dl-machine.h (elf_machine_rela): Likewise. + (elf_machine_lazy_rel): Likewise. + * sysdeps/powerpc/powerpc32/dl-machine.h (elf_machine_rela): + Likewise. + (elf_machine_lazy_rel): Likewise. + * sysdeps/powerpc/powerpc64/dl-machine.h (elf_machine_rela): + Likewise. + (elf_machine_lazy_rel): Likewise. + * sysdeps/s390/s390-32/dl-machine.h (elf_machine_rela): Likewise. + (elf_machine_lazy_rel): Likewise. + * sysdeps/s390/s390-64/dl-machine.h (elf_machine_rela): Likewise. + (elf_machine_lazy_rel): Likewise. + * sysdeps/sh/dl-machine.h (elf_machine_rela): Likewise. + (elf_machine_lazy_rel): Likewise. + * sysdeps/sparc/sparc32/dl-machine.h (elf_machine_rela): Likewise. + (elf_machine_lazy_rel): Likewise. + * sysdeps/sparc/sparc64/dl-machine.h (elf_machine_rela): Likewise. + (elf_machine_lazy_rel): Likewise. + * sysdeps/x86_64/dl-machine.h (elf_machine_rela): Likewise. + (elf_machine_lazy_rel): Likewise. + +Index: glibc-2.14/elf/dl-conflict.c +=================================================================== +--- glibc-2.14.orig/elf/dl-conflict.c ++++ glibc-2.14/elf/dl-conflict.c +@@ -1,5 +1,5 @@ + /* Resolve conflicts against already prelinked libraries. +- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2008 Free Software Foundation, Inc. ++ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2008, 2011 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek , 2001. + +@@ -69,7 +69,8 @@ _dl_resolve_conflicts (struct link_map * + GL(dl_num_cache_relocations) += conflictend - conflict; + + for (; conflict < conflictend; ++conflict) +- elf_machine_rela (l, conflict, NULL, NULL, (void *) conflict->r_offset); ++ elf_machine_rela (l, conflict, NULL, NULL, (void *) conflict->r_offset, ++ 0); + } + #endif + } +Index: glibc-2.14/elf/dl-reloc.c +=================================================================== +--- glibc-2.14.orig/elf/dl-reloc.c ++++ glibc-2.14/elf/dl-reloc.c +@@ -162,6 +162,7 @@ _dl_relocate_object (struct link_map *l, + /* Initialize it to make the compiler happy. */ + const char *errstring = NULL; + int lazy = reloc_mode & RTLD_LAZY; ++ int skip_ifunc = reloc_mode & __RTLD_NOIFUNC; + + #ifdef SHARED + /* If we are auditing, install the same handlers we need for profiling. */ +@@ -261,7 +262,7 @@ _dl_relocate_object (struct link_map *l, + + #include "dynamic-link.h" + +- ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling); ++ ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc); + + #ifndef PROF + if (__builtin_expect (consider_profiling, 0)) +Index: glibc-2.14/elf/do-rel.h +=================================================================== +--- glibc-2.14.orig/elf/do-rel.h ++++ glibc-2.14/elf/do-rel.h +@@ -1,5 +1,5 @@ + /* Do relocations for ELF dynamic linking. +- Copyright (C) 1995-2003, 2004 Free Software Foundation, Inc. ++ Copyright (C) 1995-2003, 2004, 2011 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or +@@ -52,7 +52,7 @@ + auto inline void __attribute__ ((always_inline)) + elf_dynamic_do_rel (struct link_map *map, + ElfW(Addr) reladdr, ElfW(Addr) relsize, +- int lazy) ++ int lazy, int skip_ifunc) + { + const ElfW(Rel) *r = (const void *) reladdr; + const ElfW(Rel) *end = (const void *) (reladdr + relsize); +@@ -66,7 +66,7 @@ elf_dynamic_do_rel (struct link_map *map + { + /* Doing lazy PLT relocations; they need very little info. */ + for (; r < end; ++r) +- elf_machine_lazy_rel (map, l_addr, r); ++ elf_machine_lazy_rel (map, l_addr, r, skip_ifunc); + } + else + #endif +@@ -119,14 +119,14 @@ elf_dynamic_do_rel (struct link_map *map + ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; + elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], + &map->l_versions[ndx], +- (void *) (l_addr + r->r_offset)); ++ (void *) (l_addr + r->r_offset), skip_ifunc); + } + } + #ifndef RTLD_BOOTSTRAP + else + for (; r < end; ++r) + elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, +- (void *) (l_addr + r->r_offset)); ++ (void *) (l_addr + r->r_offset), skip_ifunc); + #endif + } + } +Index: glibc-2.14/elf/dynamic-link.h +=================================================================== +--- glibc-2.14.orig/elf/dynamic-link.h ++++ glibc-2.14/elf/dynamic-link.h +@@ -60,7 +60,7 @@ int internal_function _dl_try_allocate_s + auto inline void __attribute__((always_inline)) + elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc, + const ElfW(Sym) *sym, const struct r_found_version *version, +- void *const reloc_addr); ++ void *const reloc_addr, int skip_ifunc); + auto inline void __attribute__((always_inline)) + elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc, + void *const reloc_addr); +@@ -69,7 +69,7 @@ elf_machine_rel_relative (ElfW(Addr) l_a + auto inline void __attribute__((always_inline)) + elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, + const ElfW(Sym) *sym, const struct r_found_version *version, +- void *const reloc_addr); ++ void *const reloc_addr, int skip_ifunc); + auto inline void __attribute__((always_inline)) + elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, + void *const reloc_addr); +@@ -77,11 +77,13 @@ elf_machine_rela_relative (ElfW(Addr) l_ + # if ELF_MACHINE_NO_RELA || defined ELF_MACHINE_PLT_REL + auto inline void __attribute__((always_inline)) + elf_machine_lazy_rel (struct link_map *map, +- ElfW(Addr) l_addr, const ElfW(Rel) *reloc); ++ ElfW(Addr) l_addr, const ElfW(Rel) *reloc, ++ int skip_ifunc); + # else + auto inline void __attribute__((always_inline)) + elf_machine_lazy_rel (struct link_map *map, +- ElfW(Addr) l_addr, const ElfW(Rela) *reloc); ++ ElfW(Addr) l_addr, const ElfW(Rela) *reloc, ++ int skip_ifunc); + # endif + #endif + +@@ -254,7 +256,7 @@ elf_get_dynamic_info (struct link_map *l + not happen we do something more optimal. */ + + # ifdef ELF_MACHINE_PLTREL_OVERLAP +-# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, test_rel) \ ++# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \ + do { \ + struct { ElfW(Addr) start, size; int lazy; } ranges[3]; \ + int ranges_index; \ +@@ -284,10 +286,11 @@ elf_get_dynamic_info (struct link_map *l + elf_dynamic_do_##reloc ((map), \ + ranges[ranges_index].start, \ + ranges[ranges_index].size, \ +- ranges[ranges_index].lazy); \ ++ ranges[ranges_index].lazy, \ ++ skip_ifunc); \ + } while (0) + # else +-# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, test_rel) \ ++# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \ + do { \ + struct { ElfW(Addr) start, size; int lazy; } ranges[2]; \ + ranges[0].lazy = 0; \ +@@ -324,7 +327,8 @@ elf_get_dynamic_info (struct link_map *l + } \ + \ + if (ELF_DURING_STARTUP) \ +- elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size, 0); \ ++ elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size, 0, \ ++ skip_ifunc); \ + else \ + { \ + int ranges_index; \ +@@ -332,7 +336,8 @@ elf_get_dynamic_info (struct link_map *l + elf_dynamic_do_##reloc ((map), \ + ranges[ranges_index].start, \ + ranges[ranges_index].size, \ +- ranges[ranges_index].lazy); \ ++ ranges[ranges_index].lazy, \ ++ skip_ifunc); \ + } \ + } while (0) + # endif +@@ -345,29 +350,29 @@ elf_get_dynamic_info (struct link_map *l + + # if ! ELF_MACHINE_NO_REL + # include "do-rel.h" +-# define ELF_DYNAMIC_DO_REL(map, lazy) \ +- _ELF_DYNAMIC_DO_RELOC (REL, rel, map, lazy, _ELF_CHECK_REL) ++# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) \ ++ _ELF_DYNAMIC_DO_RELOC (REL, rel, map, lazy, skip_ifunc, _ELF_CHECK_REL) + # else +-# define ELF_DYNAMIC_DO_REL(map, lazy) /* Nothing to do. */ ++# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) /* Nothing to do. */ + # endif + + # if ! ELF_MACHINE_NO_RELA + # define DO_RELA + # include "do-rel.h" +-# define ELF_DYNAMIC_DO_RELA(map, lazy) \ +- _ELF_DYNAMIC_DO_RELOC (RELA, rela, map, lazy, _ELF_CHECK_REL) ++# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) \ ++ _ELF_DYNAMIC_DO_RELOC (RELA, rela, map, lazy, skip_ifunc, _ELF_CHECK_REL) + # else +-# define ELF_DYNAMIC_DO_RELA(map, lazy) /* Nothing to do. */ ++# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) /* Nothing to do. */ + # endif + + /* This can't just be an inline function because GCC is too dumb + to inline functions containing inlines themselves. */ +-# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile) \ ++# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile, skip_ifunc) \ + do { \ + int edr_lazy = elf_machine_runtime_setup ((map), (lazy), \ + (consider_profile)); \ +- ELF_DYNAMIC_DO_REL ((map), edr_lazy); \ +- ELF_DYNAMIC_DO_RELA ((map), edr_lazy); \ ++ ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc); \ ++ ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc); \ + } while (0) + + #endif +Index: glibc-2.14/elf/rtld.c +=================================================================== +--- glibc-2.14.orig/elf/rtld.c ++++ glibc-2.14/elf/rtld.c +@@ -543,7 +543,7 @@ _dl_start (void *arg) + /* Relocate ourselves so we can do normal function calls and + data access using the global offset table. */ + +- ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0); ++ ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0, 0); + } + bootstrap_map.l_relocated = 1; + +@@ -1992,8 +1992,9 @@ ERROR: ld.so: object '%s' cannot be load + + /* Relocate the main executable. */ + struct relocate_args args = { .l = l, +- .reloc_mode = (GLRO(dl_lazy) +- ? RTLD_LAZY : 0) }; ++ .reloc_mode = ((GLRO(dl_lazy) ++ ? RTLD_LAZY : 0) ++ | __RTLD_NOIFUNC) }; + _dl_receive_error (print_unresolved, relocate_doit, &args); + + /* This loop depends on the dependencies of the executable to +@@ -2070,7 +2071,8 @@ ERROR: ld.so: object '%s' cannot be load + struct relocate_args args; + struct link_map *l; + +- args.reloc_mode = GLRO(dl_lazy) ? RTLD_LAZY : 0; ++ args.reloc_mode = ((GLRO(dl_lazy) ? RTLD_LAZY : 0) ++ | __RTLD_NOIFUNC); + + l = main_map; + while (l->l_next != NULL) +@@ -2093,7 +2095,7 @@ ERROR: ld.so: object '%s' cannot be load + /* Mark the link map as not yet relocated again. */ + GL(dl_rtld_map).l_relocated = 0; + _dl_relocate_object (&GL(dl_rtld_map), +- main_map->l_scope, 0, 0); ++ main_map->l_scope, __RTLD_NOIFUNC, 0); + } + } + #define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED)) +Index: glibc-2.14/include/dlfcn.h +=================================================================== +--- glibc-2.14.orig/include/dlfcn.h ++++ glibc-2.14/include/dlfcn.h +@@ -10,6 +10,7 @@ + #define __RTLD_CALLMAP 0x10000000 + #define __RTLD_AUDIT 0x08000000 + #define __RTLD_SECURE 0x04000000 /* Apply additional security checks. */ ++#define __RTLD_NOIFUNC 0x02000000 /* Suppress calling ifunc functions. */ + + #define __LM_ID_CALLER -2 + +Index: glibc-2.14/sysdeps/i386/dl-machine.h +=================================================================== +--- glibc-2.14.orig/sysdeps/i386/dl-machine.h ++++ glibc-2.14/sysdeps/i386/dl-machine.h +@@ -311,7 +311,7 @@ auto inline void + __attribute ((always_inline)) + elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, + const Elf32_Sym *sym, const struct r_found_version *version, +- void *const reloc_addr_arg) ++ void *const reloc_addr_arg, int skip_ifunc) + { + Elf32_Addr *const reloc_addr = reloc_addr_arg; + const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); +@@ -347,7 +347,8 @@ elf_machine_rel (struct link_map *map, c + 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 (sym->st_shndx != SHN_UNDEF, 1) ++ && __builtin_expect (!skip_ifunc, 1)) + value = ((Elf32_Addr (*) (void)) value) (); + + switch (r_type) +@@ -490,7 +491,7 @@ auto inline void + __attribute__ ((always_inline)) + elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + const Elf32_Sym *sym, const struct r_found_version *version, +- void *const reloc_addr_arg) ++ void *const reloc_addr_arg, int skip_ifunc) + { + Elf32_Addr *const reloc_addr = reloc_addr_arg; + const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); +@@ -507,8 +508,8 @@ elf_machine_rela (struct link_map *map, + + if (sym != NULL + && __builtin_expect (sym->st_shndx != SHN_UNDEF, 1) +- && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, +- 0)) ++ && __builtin_expect (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC, 0) ++ && __builtin_expect (!skip_ifunc, 1)) + value = ((Elf32_Addr (*) (void)) value) (); + + switch (ELF32_R_TYPE (reloc->r_info)) +@@ -655,7 +656,8 @@ elf_machine_rela_relative (Elf32_Addr l_ + auto inline void + __attribute__ ((always_inline)) + elf_machine_lazy_rel (struct link_map *map, +- Elf32_Addr l_addr, const Elf32_Rel *reloc) ++ Elf32_Addr l_addr, const Elf32_Rel *reloc, ++ int skip_ifunc) + { + Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); + const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); +@@ -706,19 +708,20 @@ elf_machine_lazy_rel (struct link_map *m + ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; + elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], + &map->l_versions[ndx], +- (void *) (l_addr + r->r_offset)); ++ (void *) (l_addr + r->r_offset), skip_ifunc); + } + # ifndef RTLD_BOOTSTRAP + else + elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, +- (void *) (l_addr + r->r_offset)); ++ (void *) (l_addr + r->r_offset), skip_ifunc); + # endif + } + } + else if (__builtin_expect (r_type == R_386_IRELATIVE, 0)) + { + Elf32_Addr value = map->l_addr + *reloc_addr; +- value = ((Elf32_Addr (*) (void)) value) (); ++ if (__builtin_expect (!skip_ifunc, 1)) ++ value = ((Elf32_Addr (*) (void)) value) (); + *reloc_addr = value; + } + else +@@ -730,7 +733,8 @@ elf_machine_lazy_rel (struct link_map *m + auto inline void + __attribute__ ((always_inline)) + elf_machine_lazy_rela (struct link_map *map, +- Elf32_Addr l_addr, const Elf32_Rela *reloc) ++ Elf32_Addr l_addr, const Elf32_Rela *reloc, ++ int skip_ifunc) + { + Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); + const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); +@@ -747,7 +751,8 @@ elf_machine_lazy_rela (struct link_map * + else if (__builtin_expect (r_type == R_386_IRELATIVE, 0)) + { + Elf32_Addr value = map->l_addr + reloc->r_addend; +- value = ((Elf32_Addr (*) (void)) value) (); ++ if (__builtin_expect (!skip_ifunc, 1)) ++ value = ((Elf32_Addr (*) (void)) value) (); + *reloc_addr = value; + } + else +Index: glibc-2.14/sysdeps/ia64/dl-machine.h +=================================================================== +--- glibc-2.14.orig/sysdeps/ia64/dl-machine.h ++++ glibc-2.14/sysdeps/ia64/dl-machine.h +@@ -377,7 +377,8 @@ elf_machine_rela (struct link_map *map, + const Elf64_Rela *reloc, + const Elf64_Sym *sym, + const struct r_found_version *version, +- void *const reloc_addr_arg) ++ void *const reloc_addr_arg, ++ int skip_ifunc) + { + Elf64_Addr *const reloc_addr = reloc_addr_arg; + const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info); +@@ -493,7 +494,8 @@ elf_machine_rela_relative (Elf64_Addr l_ + auto inline void + __attribute ((always_inline)) + elf_machine_lazy_rel (struct link_map *map, +- Elf64_Addr l_addr, const Elf64_Rela *reloc) ++ Elf64_Addr l_addr, const Elf64_Rela *reloc, ++ int skip_ifunc) + { + Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); + const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info); +Index: glibc-2.14/sysdeps/powerpc/powerpc32/dl-machine.h +=================================================================== +--- glibc-2.14.orig/sysdeps/powerpc/powerpc32/dl-machine.h ++++ glibc-2.14/sysdeps/powerpc/powerpc32/dl-machine.h +@@ -280,7 +280,7 @@ extern void _dl_reloc_overflow (struct l + auto inline void __attribute__ ((always_inline)) + elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + const Elf32_Sym *sym, const struct r_found_version *version, +- void *const reloc_addr_arg) ++ void *const reloc_addr_arg, int skip_ifunc) + { + Elf32_Addr *const reloc_addr = reloc_addr_arg; + const Elf32_Sym *const refsym = sym; +@@ -315,7 +315,8 @@ elf_machine_rela (struct link_map *map, + + 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 (sym->st_shndx != SHN_UNDEF, 1) ++ && __builtin_expect (!skip_ifunc, 1)) + value = ((Elf32_Addr (*) (void)) value) (); + + /* A small amount of code is duplicated here for speed. In libc, +@@ -391,7 +392,8 @@ elf_machine_rela_relative (Elf32_Addr l_ + + auto inline void __attribute__ ((always_inline)) + elf_machine_lazy_rel (struct link_map *map, +- Elf32_Addr l_addr, const Elf32_Rela *reloc) ++ Elf32_Addr l_addr, const Elf32_Rela *reloc, ++ int skip_ifunc) + { + /* elf_machine_runtime_setup handles this. */ + } +Index: glibc-2.14/sysdeps/powerpc/powerpc64/dl-machine.h +=================================================================== +--- glibc-2.14.orig/sysdeps/powerpc/powerpc64/dl-machine.h ++++ glibc-2.14/sysdeps/powerpc/powerpc64/dl-machine.h +@@ -558,7 +558,8 @@ elf_machine_rela (struct link_map *map, + const Elf64_Rela *reloc, + const Elf64_Sym *sym, + const struct r_found_version *version, +- void *const reloc_addr_arg) ++ void *const reloc_addr_arg, ++ int skip_ifunc) + { + Elf64_Addr *const reloc_addr = reloc_addr_arg; + const int r_type = ELF64_R_TYPE (reloc->r_info); +@@ -583,7 +584,8 @@ elf_machine_rela (struct link_map *map, + + 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 (sym->st_shndx != SHN_UNDEF, 1) ++ && __builtin_expect (!skip_ifunc, 1)) + value = resolve_ifunc (value, map, sym_map); + + /* For relocs that don't edit code, return. +@@ -596,12 +598,14 @@ elf_machine_rela (struct link_map *map, + return; + + case R_PPC64_IRELATIVE: +- value = resolve_ifunc (value, map, sym_map); ++ if (__builtin_expect (!skip_ifunc, 1)) ++ value = resolve_ifunc (value, map, sym_map); + *reloc_addr = value; + return; + + case R_PPC64_JMP_IREL: +- value = resolve_ifunc (value, map, sym_map); ++ if (__builtin_expect (!skip_ifunc, 1)) ++ value = resolve_ifunc (value, map, sym_map); + /* Fall thru */ + case R_PPC64_JMP_SLOT: + #ifdef RESOLVE_CONFLICT_FIND_MAP +@@ -852,7 +856,8 @@ elf_machine_rela (struct link_map *map, + + auto inline void __attribute__ ((always_inline)) + elf_machine_lazy_rel (struct link_map *map, +- Elf64_Addr l_addr, const Elf64_Rela *reloc) ++ Elf64_Addr l_addr, const Elf64_Rela *reloc, ++ int skip_ifunc) + { + /* elf_machine_runtime_setup handles this. */ + } +Index: glibc-2.14/sysdeps/s390/s390-32/dl-machine.h +=================================================================== +--- glibc-2.14.orig/sysdeps/s390/s390-32/dl-machine.h ++++ glibc-2.14/sysdeps/s390/s390-32/dl-machine.h +@@ -275,7 +275,7 @@ auto inline void + __attribute__ ((always_inline)) + elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + const Elf32_Sym *sym, const struct r_found_version *version, +- void *const reloc_addr_arg) ++ void *const reloc_addr_arg, int skip_ifunc) + { + Elf32_Addr *const reloc_addr = reloc_addr_arg; + const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); +@@ -434,7 +434,8 @@ elf_machine_rela_relative (Elf32_Addr l_ + auto inline void + __attribute__ ((always_inline)) + elf_machine_lazy_rel (struct link_map *map, +- Elf32_Addr l_addr, const Elf32_Rela *reloc) ++ Elf32_Addr l_addr, const Elf32_Rela *reloc, ++ int skip_ifunc) + { + Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); + const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); +Index: glibc-2.14/sysdeps/s390/s390-64/dl-machine.h +=================================================================== +--- glibc-2.14.orig/sysdeps/s390/s390-64/dl-machine.h ++++ glibc-2.14/sysdeps/s390/s390-64/dl-machine.h +@@ -247,7 +247,7 @@ auto inline void + __attribute__ ((always_inline)) + elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, + const Elf64_Sym *sym, const struct r_found_version *version, +- void *const reloc_addr_arg) ++ void *const reloc_addr_arg, int skip_ifunc) + { + Elf64_Addr *const reloc_addr = reloc_addr_arg; + const unsigned int r_type = ELF64_R_TYPE (reloc->r_info); +@@ -413,7 +413,8 @@ elf_machine_rela_relative (Elf64_Addr l_ + auto inline void + __attribute__ ((always_inline)) + elf_machine_lazy_rel (struct link_map *map, +- Elf64_Addr l_addr, const Elf64_Rela *reloc) ++ Elf64_Addr l_addr, const Elf64_Rela *reloc, ++ int skip_ifunc) + { + Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); + const unsigned int r_type = ELF64_R_TYPE (reloc->r_info); +Index: glibc-2.14/sysdeps/sh/dl-machine.h +=================================================================== +--- glibc-2.14.orig/sysdeps/sh/dl-machine.h ++++ glibc-2.14/sysdeps/sh/dl-machine.h +@@ -268,7 +268,7 @@ auto inline void + __attribute ((always_inline)) + elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + const Elf32_Sym *sym, const struct r_found_version *version, +- void *const reloc_addr_arg) ++ void *const reloc_addr_arg, int skip_ifunc) + { + Elf32_Addr *const reloc_addr = reloc_addr_arg; + const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); +@@ -454,7 +454,8 @@ elf_machine_rela_relative (Elf32_Addr l_ + auto inline void + __attribute__ ((always_inline)) + elf_machine_lazy_rel (struct link_map *map, +- Elf32_Addr l_addr, const Elf32_Rela *reloc) ++ Elf32_Addr l_addr, const Elf32_Rela *reloc, ++ int skip_ifunc) + { + Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); + /* Check for unexpected PLT reloc type. */ +Index: glibc-2.14/sysdeps/sparc/sparc32/dl-machine.h +=================================================================== +--- glibc-2.14.orig/sysdeps/sparc/sparc32/dl-machine.h ++++ glibc-2.14/sysdeps/sparc/sparc32/dl-machine.h +@@ -347,7 +347,7 @@ auto inline void + __attribute__ ((always_inline)) + elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, + const Elf32_Sym *sym, const struct r_found_version *version, +- void *const reloc_addr_arg) ++ void *const reloc_addr_arg, int skip_ifunc) + { + Elf32_Addr *const reloc_addr = reloc_addr_arg; + const Elf32_Sym *const refsym = sym; +@@ -397,7 +397,8 @@ elf_machine_rela (struct link_map *map, + + 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 (sym->st_shndx != SHN_UNDEF, 1) ++ && __builtin_expect (!skip_ifunc, 1)) + { + value = ((Elf32_Addr (*) (int)) value) (GLRO(dl_hwcap)); + } +@@ -552,7 +553,8 @@ elf_machine_rela_relative (Elf32_Addr l_ + auto inline void + __attribute__ ((always_inline)) + elf_machine_lazy_rel (struct link_map *map, +- Elf32_Addr l_addr, const Elf32_Rela *reloc) ++ Elf32_Addr l_addr, const Elf32_Rela *reloc, ++ int skip_ifunc) + { + Elf32_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); + const unsigned int r_type = ELF32_R_TYPE (reloc->r_info); +@@ -562,7 +564,8 @@ elf_machine_lazy_rel (struct link_map *m + else if (r_type == R_SPARC_JMP_IREL) + { + Elf32_Addr value = map->l_addr + reloc->r_addend; +- value = ((Elf32_Addr (*) (int)) value) (GLRO(dl_hwcap)); ++ if (__builtin_expect (!skip_ifunc, 1)) ++ value = ((Elf32_Addr (*) (int)) value) (GLRO(dl_hwcap)); + sparc_fixup_plt (reloc, reloc_addr, value, 1, 1); + } + else if (r_type == R_SPARC_NONE) +Index: glibc-2.14/sysdeps/sparc/sparc64/dl-machine.h +=================================================================== +--- glibc-2.14.orig/sysdeps/sparc/sparc64/dl-machine.h ++++ glibc-2.14/sysdeps/sparc/sparc64/dl-machine.h +@@ -375,7 +375,7 @@ auto inline void + __attribute__ ((always_inline)) + elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, + const Elf64_Sym *sym, const struct r_found_version *version, +- void *const reloc_addr_arg) ++ void *const reloc_addr_arg, int skip_ifunc) + { + Elf64_Addr *const reloc_addr = reloc_addr_arg; + #if !defined RTLD_BOOTSTRAP && !defined RESOLVE_CONFLICT_FIND_MAP +@@ -429,7 +429,8 @@ elf_machine_rela (struct link_map *map, + + 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 (sym->st_shndx != SHN_UNDEF, 1) ++ && __builtin_expect (!skip_ifunc, 1)) + value = ((Elf64_Addr (*) (int)) value) (GLRO(dl_hwcap)); + + switch (r_type) +@@ -647,7 +648,8 @@ elf_machine_rela_relative (Elf64_Addr l_ + auto inline void + __attribute__ ((always_inline)) + elf_machine_lazy_rel (struct link_map *map, +- Elf64_Addr l_addr, const Elf64_Rela *reloc) ++ Elf64_Addr l_addr, const Elf64_Rela *reloc, ++ int skip_ifunc) + { + Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); + const unsigned int r_type = ELF64_R_TYPE (reloc->r_info); +@@ -658,7 +660,8 @@ elf_machine_lazy_rel (struct link_map *m + || r_type == R_SPARC_IRELATIVE) + { + Elf64_Addr value = map->l_addr + reloc->r_addend; +- value = ((Elf64_Addr (*) (int)) value) (GLRO(dl_hwcap)); ++ if (__builtin_expect (!skip_ifunc, 1)) ++ value = ((Elf64_Addr (*) (int)) value) (GLRO(dl_hwcap)); + if (r_type == R_SPARC_JMP_IREL) + { + /* 'high' is always zero, for large PLT entries the linker +Index: glibc-2.14/sysdeps/x86_64/dl-machine.h +=================================================================== +--- glibc-2.14.orig/sysdeps/x86_64/dl-machine.h ++++ glibc-2.14/sysdeps/x86_64/dl-machine.h +@@ -261,7 +261,7 @@ auto inline void + __attribute__ ((always_inline)) + elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, + const Elf64_Sym *sym, const struct r_found_version *version, +- void *const reloc_addr_arg) ++ void *const reloc_addr_arg, int skip_ifunc) + { + Elf64_Addr *const reloc_addr = reloc_addr_arg; + const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info); +@@ -299,7 +299,8 @@ elf_machine_rela (struct link_map *map, + 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 (sym->st_shndx != SHN_UNDEF, 1) ++ && __builtin_expect (!skip_ifunc, 1)) + value = ((Elf64_Addr (*) (void)) value) (); + + # if defined RTLD_BOOTSTRAP && !USE___THREAD +@@ -470,7 +471,8 @@ elf_machine_rela_relative (Elf64_Addr l_ + auto inline void + __attribute ((always_inline)) + elf_machine_lazy_rel (struct link_map *map, +- Elf64_Addr l_addr, const Elf64_Rela *reloc) ++ Elf64_Addr l_addr, const Elf64_Rela *reloc, ++ int skip_ifunc) + { + Elf64_Addr *const reloc_addr = (void *) (l_addr + reloc->r_offset); + const unsigned long int r_type = ELF64_R_TYPE (reloc->r_info); +@@ -497,7 +499,8 @@ elf_machine_lazy_rel (struct link_map *m + else if (__builtin_expect (r_type == R_X86_64_IRELATIVE, 0)) + { + Elf64_Addr value = map->l_addr + reloc->r_addend; +- value = ((Elf64_Addr (*) (void)) value) (); ++ if (__builtin_expect (!skip_ifunc, 1)) ++ value = ((Elf64_Addr (*) (void)) value) (); + *reloc_addr = value; + } + else diff --git a/glibc.changes b/glibc.changes index 04389d2..a88af3e 100644 --- a/glibc.changes +++ b/glibc.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Mon Oct 10 14:07:44 UTC 2011 - aj@suse.de + +- Fix tracing with ifuncs. + ------------------------------------------------------------------- Tue Oct 4 14:10:13 UTC 2011 - uli@suse.com diff --git a/glibc.spec b/glibc.spec index 8beb0f6..ba249e1 100644 --- a/glibc.spec +++ b/glibc.spec @@ -79,9 +79,10 @@ Obsoletes: glibc-32bit %endif Version: 2.14 Release: 11 +%define git_id 8bd683657e8a Url: http://www.gnu.org/software/libc/libc.html BuildRoot: %{_tmppath}/%{name}-%{version}-build -Source: glibc-%{version}-8bd683657e8a.tar.bz2 +Source: glibc-%{version}-%{git_id}.tar.bz2 Source2: http://ftp.gnu.org/gnu/glibc/glibc-ports-2.14.tar.bz2 Source3: noversion.tar.bz2 Source4: manpages.tar.bz2 @@ -206,6 +207,8 @@ Patch72: glibc-2.15-avoid-vsyscall.patch Patch73: glibc-resolv-assert.diff # PATCH-FIX-OPENSUSE Run ctors (bnc#717671) aj@suse.de Patch74: glibc-2.14-fix-ctors.patch +# PATCH-FIX-UPSTREAM Fix trace and ifuncs aj@suse.de +Patch75: glibc-2.15-ifunc-trace.patch # PATCH-FEATURE-OPENSUSE -- add sha support to crypt_blowfish lnussel@suse.de Patch80: crypt_blowfish-1.2-sha.diff # PATCH-FEATURE-OPENSUSE -- use separate symbol version for Owl extensions - lnussel@suse.de @@ -448,6 +451,7 @@ rm nscd/s-stamp %patch72 -p1 %patch73 -p1 %patch74 -p1 +%patch75 -p1 # # Inconsistency detected by ld.so: dl-close.c: 719: _dl_close: Assertion `map->l_init_called' failed!