Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12:GA
ltrace
ltrace-ppc64le_git14.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File ltrace-ppc64le_git14.patch of Package ltrace
--- backend.h.ori +++ backend.h @@ -294,8 +294,8 @@ enum plt_status { plt_default, }; -/* The following callback has to be implemented in backend if arch.h - * defines ARCH_HAVE_ADD_PLT_ENTRY. +/* The following callback has to be implemented in OS backend if os.h + * defines OS_HAVE_ADD_PLT_ENTRY. * * This is called for every PLT relocation R in ELF file LTE, that * ltrace is about to add to a library constructed in process PROC. @@ -306,11 +306,18 @@ enum plt_status { * calling arch_plt_sym_val, and symbol is allocated. If plt_ok or * plt_default are returned, the chain of symbols passed back in RET * is added to library under construction. */ +enum plt_status os_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, + const char *name, GElf_Rela *rela, + size_t i, struct library_symbol **ret); + +/* Like os_elf_add_plt_entry, but tied to ARCH_HAVE_ADD_PLT_ENTRY in + * arch.h. The arch callback is called first. If it returns + * plt_default, the os callback is called next. */ enum plt_status arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, const char *name, GElf_Rela *rela, size_t i, struct library_symbol **ret); -/* The following callback has to be implemented in backend if arch.h +/* The following callback has to be implemented in OS backend if os.h * defines OS_HAVE_ADD_FUNC_ENTRY. * * This is called for every symbol in ltrace is about to add to the @@ -327,6 +334,14 @@ enum plt_status os_elf_add_func_entry(struct Process *proc, struct ltelf *lte, arch_addr_t addr, const char *name, struct library_symbol **ret); +/* Like os_elf_add_func_entry, but tied to ARCH_HAVE_ADD_FUNC_ENTRY in + * arch.h. The arch callback is called first. If it returns + * plt_default, the os callback is called next. */ +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); + /* This callback needs to be implemented if arch.h defines * ARCH_HAVE_DYNLINK_DONE. It is called after the dynamic linker is * done with the process startup. */ --- ltrace-elf.c.ori +++ ltrace-elf.c @@ -36,6 +36,7 @@ #include <gelf.h> #include <inttypes.h> #include <search.h> +#include <stdbool.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -63,41 +64,15 @@ arch_elf_destroy(struct ltelf *lte) } #endif -int -default_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, - const char *a_name, GElf_Rela *rela, size_t ndx, - struct library_symbol **ret) +#ifndef OS_HAVE_ADD_PLT_ENTRY +enum plt_status +os_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, + const char *a_name, GElf_Rela *rela, size_t ndx, + struct library_symbol **ret) { - char *name = strdup(a_name); - if (name == NULL) { - fail_message: - fprintf(stderr, "Couldn't create symbol for PLT entry: %s\n", - strerror(errno)); - fail: - free(name); - return -1; - } - - GElf_Addr addr = arch_plt_sym_val(lte, ndx, rela); - - struct library_symbol *libsym = malloc(sizeof(*libsym)); - if (libsym == NULL) - goto fail_message; - - /* XXX The double cast should be removed when - * arch_addr_t becomes integral type. */ - arch_addr_t taddr = (arch_addr_t) - (uintptr_t)(addr + lte->bias); - - if (library_symbol_init(libsym, taddr, name, 1, LS_TOPLT_EXEC) < 0) { - free(libsym); - goto fail; - } - - libsym->next = *ret; - *ret = libsym; - return 0; + return plt_default; } +#endif #ifndef ARCH_HAVE_ADD_PLT_ENTRY enum plt_status @@ -125,6 +100,17 @@ os_elf_add_func_entry(struct Process *proc, struct ltelf *lte, } #endif +#ifndef ARCH_HAVE_ADD_FUNC_ENTRY +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) +{ + return plt_default; +} +#endif + Elf_Data * elf_loaddata(Elf_Scn *scn, GElf_Shdr *shdr) { @@ -645,6 +631,67 @@ arch_get_sym_info(struct ltelf *lte, const char *filename, } #endif +int +default_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, + const char *a_name, GElf_Rela *rela, size_t ndx, + struct library_symbol **ret) +{ + char *name = strdup(a_name); + if (name == NULL) { + fail_message: + fprintf(stderr, "Couldn't create symbol for PLT entry: %s\n", + strerror(errno)); + fail: + free(name); + return -1; + } + + GElf_Addr addr = arch_plt_sym_val(lte, ndx, rela); + + struct library_symbol *libsym = malloc(sizeof(*libsym)); + if (libsym == NULL) + goto fail_message; + + /* XXX The double cast should be removed when + * arch_addr_t becomes integral type. */ + arch_addr_t taddr = (arch_addr_t) + (uintptr_t)(addr + lte->bias); + + if (library_symbol_init(libsym, taddr, name, 1, LS_TOPLT_EXEC) < 0) { + free(libsym); + goto fail; + } + + libsym->next = *ret; + *ret = libsym; + return 0; +} + +int +elf_add_plt_entry(struct Process *proc, struct ltelf *lte, + const char *name, GElf_Rela *rela, size_t idx, + struct library_symbol **ret) +{ + enum plt_status plts + = arch_elf_add_plt_entry(proc, lte, name, rela, idx, ret); + + if (plts == plt_default) + plts = os_elf_add_plt_entry(proc, lte, name, rela, idx, ret); + + switch (plts) { + case plt_default: + return default_elf_add_plt_entry(proc, lte, name, + rela, idx, ret); + case plt_fail: + return -1; + case plt_ok: + return 0; + } + + assert(! "Invalid return from X_elf_add_plt_entry!"); + abort(); +} + static void mark_chain_latent(struct library_symbol *libsym) { @@ -672,23 +719,13 @@ filter_symbol_chain(struct filter *filter, } } -static void -delete_symbol_chain(struct library_symbol *libsym) -{ - while (libsym != NULL) { - struct library_symbol *tmp = libsym->next; - library_symbol_destroy(libsym); - free(libsym); - libsym = tmp; - } -} - static int populate_plt(struct Process *proc, const char *filename, - struct ltelf *lte, struct library *lib, - int latent_plts) + struct ltelf *lte, struct library *lib) { - size_t count = vect_size(<e->plt_relocs); + const bool latent_plts = options.export_filter != NULL; + const size_t count = vect_size(<e->plt_relocs); + size_t i; for (i = 0; i < count; ++i) { GElf_Rela *rela = VECT_ELEMENT(<e->plt_relocs, GElf_Rela, i); @@ -698,45 +735,43 @@ populate_plt(struct Process *proc, const char *filename, continue; /* Skip this entry. */ char const *name = lte->dynstr + sym.st_name; - int matched = filter_matches_symbol(options.plt_filter, name, lib); struct library_symbol *libsym = NULL; - switch (arch_elf_add_plt_entry(proc, lte, name, - rela, i, &libsym)) { - case plt_fail: + if (elf_add_plt_entry(proc, lte, name, rela, i, &libsym) < 0) return -1; - case plt_default: - /* Add default entry to the beginning of LIBSYM. */ - if (default_elf_add_plt_entry(proc, lte, name, - rela, i, &libsym) < 0) - return -1; - /* fall-through */ - case plt_ok: - /* If we didn't match the PLT entry up there, - * filter the chain to only include the - * matching symbols (but include all if we are - * adding latent symbols). This is to allow - * arch_elf_add_plt_entry to override the PLT - * symbol's name. */ - if (!matched && !latent_plts) - filter_symbol_chain(options.plt_filter, - &libsym, lib); - if (libsym != NULL) { - /* If we are adding those symbols just - * for tracing exports, mark them all - * latent. */ - if (!matched && latent_plts) - mark_chain_latent(libsym); - library_add_symbol(lib, libsym); - } + /* If we didn't match the PLT entry, filter the chain + * to only include the matching symbols (but include + * all if we are adding latent symbols) to allow + * backends to override the PLT symbol's name. */ + + if (! matched && ! latent_plts) + filter_symbol_chain(options.plt_filter, &libsym, lib); + + if (libsym != NULL) { + /* If we are adding those symbols just for + * tracing exports, mark them all latent. */ + if (! matched && latent_plts) + mark_chain_latent(libsym); + library_add_symbol(lib, libsym); } } return 0; } +static void +delete_symbol_chain(struct library_symbol *libsym) +{ + while (libsym != NULL) { + struct library_symbol *tmp = libsym->next; + library_symbol_destroy(libsym); + free(libsym); + libsym = tmp; + } +} + /* When -x rules result in request to trace several aliases, we only * want to add such symbol once. The only way that those symbols * differ in is their name, e.g. in glibc you have __GI___libc_free, @@ -872,8 +909,14 @@ populate_this_symtab(struct Process *proc, const char *filename, } struct library_symbol *libsym = NULL; - switch (os_elf_add_func_entry(proc, lte, &sym, - naddr, full_name, &libsym)) { + enum plt_status plts + = arch_elf_add_func_entry(proc, lte, &sym, + naddr, full_name, &libsym); + if (plts == plt_default) + plts = os_elf_add_func_entry(proc, lte, &sym, + naddr, full_name, &libsym); + + switch (plts) { case plt_default:; /* Put the default symbol to the chain. */ struct library_symbol *tmp = malloc(sizeof *tmp); @@ -924,6 +967,7 @@ populate_this_symtab(struct Process *proc, const char *filename, unique->libsym = tmp; unique->addr = tmp->enter_addr; tmp = tmp->next; + unique->libsym->next = NULL; } else { if (strlen(tmp->name) < strlen(unique->libsym->name)) { @@ -1108,8 +1152,7 @@ read_module(struct library *lib, struct Process *proc, int plts = filter_matches_library(options.plt_filter, lib); if ((plts || options.export_filter != NULL) - && populate_plt(proc, filename, <e, lib, - options.export_filter != NULL) < 0) + && populate_plt(proc, filename, <e, lib) < 0) goto fail; int exports = filter_matches_library(options.export_filter, lib); --- ltrace-elf.h.ori +++ ltrace-elf.h @@ -83,6 +83,22 @@ int ltelf_read_library(struct library *lib, struct Process *proc, * point address is stored to *ENTRYP. */ struct library *ltelf_read_main_binary(struct Process *proc, const char *path); +/* This is called for every PLT relocation R in ELF file LTE, that + * ltrace is about to add to a library constructed in process PROC. + * The corresponding PLT entry is for symbol called NAME, and it's + * I-th relocation in the file. *RET shall be initialized and + * symbol(s) corresponding to the given PLT entry will be added to the + * front. Returns 0 for success, or a negative value for failures. + * + * This calls os_elf_add_plt_entry and arch_elf_add_plt_entry in the + * background (see backend.h for documentation). The arch callback is + * called first. If it returns plt_default, the os callback is called + * next. If that returns plt_default, default_elf_add_plt_entry is + * called. */ +int elf_add_plt_entry(struct Process *proc, struct ltelf *lte, + const char *name, GElf_Rela *rela, size_t idx, + struct library_symbol **ret); + /* Create a default PLT entry. This can be used instead (or in * addition to) returning plt_default from arch_elf_add_plt_entry. * RET shall be initialized, the created symbol will be added to the
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