Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12:GA
ltrace
ltrace-ppc64le_git15.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File ltrace-ppc64le_git15.patch of Package ltrace
--- sysdeps/linux-gnu/ppc/arch.h.ori +++ sysdeps/linux-gnu/ppc/arch.h @@ -39,6 +39,7 @@ #define ARCH_HAVE_ATOMIC_SINGLESTEP #define ARCH_HAVE_ADD_PLT_ENTRY +#define ARCH_HAVE_ADD_FUNC_ENTRY #define ARCH_HAVE_TRANSLATE_ADDRESS #define ARCH_HAVE_DYNLINK_DONE #define ARCH_HAVE_FETCH_ARG --- sysdeps/linux-gnu/ppc/plt.c.ori +++ sysdeps/linux-gnu/ppc/plt.c @@ -120,9 +120,12 @@ * catch the point where the slot is resolved, would hit the return * breakpoint and that's not currently handled well. * - * On PPC32 with secure PLT, IFUNC symbols in main binary actually - * don't refer to the resolver itself. Instead they refer to a PLT - * slot. + * On PPC32 with secure PLT, the address of IFUNC symbols in main + * binary actually isn't of the resolver, but of a PLT slot. We + * therefore have to locate the corresponding PLT relocation (which is + * of type R_PPC_IRELATIVE) and request that it be traced. The addend + * of that relocation is an address of resolver, and we request + * tracing of the xyz.IFUNC symbol there. * * XXX TODO If we have hardware watch point, we might put a read watch * on .plt slot, and discover the offenders this way. I don't know @@ -653,6 +656,59 @@ unresolve_plt_slot(struct Process *proc, GElf_Addr addr, GElf_Addr value) } enum plt_status +arch_elf_add_func_entry(struct Process *proc, struct ltelf *lte, + const GElf_Sym *sym, + arch_addr_t addr, const char *name, + struct library_symbol **ret) +{ + if (lte->ehdr.e_machine != EM_PPC || lte->ehdr.e_type == ET_DYN) + return plt_default; + + bool ifunc = false; +#ifdef STT_GNU_IFUNC + ifunc = GELF_ST_TYPE(sym->st_info) == STT_GNU_IFUNC; +#endif + if (! ifunc) + return plt_default; + + size_t len = vect_size(<e->plt_relocs); + size_t i; + for (i = 0; i < len; ++i) { + GElf_Rela *rela = VECT_ELEMENT(<e->plt_relocs, GElf_Rela, i); + if (sym->st_value == arch_plt_sym_val(lte, i, rela)) { + + struct library_symbol *libsym = malloc(sizeof *libsym); + + /* XXX double cast. */ + arch_addr_t resolver_addr + = (arch_addr_t) (uintptr_t) rela->r_addend; + + if (name == NULL || libsym == NULL + || library_symbol_init(libsym, resolver_addr, + name, 1, + LS_TOPLT_EXEC) < 0) { + fail: + free(libsym); + return plt_fail; + } + + if (elf_add_plt_entry(proc, lte, name, rela, + i, ret) < 0) { + library_symbol_destroy(libsym); + goto fail; + } + + libsym->next = *ret; + *ret = libsym; + return plt_ok; + } + } + + *ret = NULL; + return plt_ok; +} + +enum plt_status arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, const char *a_name, GElf_Rela *rela, size_t ndx, struct library_symbol **ret)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor