Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12:GA
ltrace
ltrace-ppc64le_git8.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File ltrace-ppc64le_git8.patch of Package ltrace
--- backend.h.ori +++ backend.h @@ -310,6 +310,23 @@ 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 + * defines OS_HAVE_ADD_FUNC_ENTRY. + * + * This is called for every symbol in ltrace is about to add to the + * library constructed for LTE in process PROC. + * + * If this function returns plt_default, then if there is a + * pre-existing symbol, its name may be updated if the newly-found + * name is shorter. Otherwise a new symbol is created. + * + * 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_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 @@ -109,6 +109,22 @@ arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, } #endif +#ifndef OS_HAVE_ADD_FUNC_ENTRY +enum plt_status +os_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 (GELF_ST_TYPE(sym->st_info) != STT_FUNC) { + *ret = NULL; + return plt_ok; + } else { + return plt_default; + } +} +#endif + Elf_Data * elf_loaddata(Elf_Scn *scn, GElf_Shdr *shdr) { @@ -617,6 +633,17 @@ 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, @@ -639,7 +666,7 @@ populate_plt(struct Process *proc, const char *filename, switch (arch_elf_add_plt_entry(proc, lte, name, &rela, i, &libsym)) { case plt_fail: - return -1; + return -1; case plt_default: /* Add default entry to the beginning of LIBSYM. */ @@ -734,16 +751,16 @@ populate_this_symtab(struct Process *proc, const char *filename, for (i = 0; i < size; ++i) { GElf_Sym sym; if (gelf_getsym(symtab, i, &sym) == NULL) { - fail: fprintf(stderr, "couldn't get symbol #%zd from %s: %s\n", i, filename, elf_errmsg(-1)); continue; } - if (GELF_ST_TYPE(sym.st_info) != STT_FUNC - || sym.st_value == 0 - || sym.st_shndx == STN_UNDEF) + if (sym.st_value == 0 || sym.st_shndx == STN_UNDEF + /* Also ignore any special values besides direct + * section references. */ + || sym.st_shndx >= lte->ehdr.e_shnum) continue; /* Find symbol name and snip version. */ @@ -757,14 +784,14 @@ populate_this_symtab(struct Process *proc, const char *filename, name[len] = 0; /* If we are interested in exports, store this name. */ - char *name_copy = NULL; if (names != NULL) { - struct library_exported_name *export = NULL; - name_copy = strdup(name); + struct library_exported_name *export + = malloc(sizeof *export); + char *name_copy = strdup(name); - if (name_copy == NULL - || (export = malloc(sizeof(*export))) == NULL) { + if (name_copy == NULL || export == NULL) { free(name_copy); + free(export); fprintf(stderr, "Couldn't store symbol %s. " "Tracing may be incomplete.\n", name); } else { @@ -797,42 +824,78 @@ populate_this_symtab(struct Process *proc, const char *filename, continue; } - char *full_name; - int own_full_name = 1; - if (name_copy == NULL) { - full_name = strdup(name); - if (full_name == NULL) - goto fail; - } else { - full_name = name_copy; - own_full_name = 0; + char *full_name = strdup(name); + if (full_name == NULL) { + fprintf(stderr, "couldn't copy name of %s@%s: %s\n", + name, lib->soname, strerror(errno)); + continue; } - /* Look whether we already have a symbol for this - * address. If not, add this one. */ - struct unique_symbol key = { naddr, NULL }; - struct unique_symbol *unique - = lsearch(&key, symbols, &num_symbols, - sizeof(*symbols), &unique_symbol_cmp); - - if (unique->libsym == NULL) { - struct library_symbol *libsym = malloc(sizeof(*libsym)); - if (libsym == NULL - || library_symbol_init(libsym, naddr, - full_name, own_full_name, + struct library_symbol *libsym = NULL; + switch (os_elf_add_func_entry(proc, lte, &sym, + naddr, full_name, &libsym)) { + case plt_default:; + /* Put the default symbol to the chain. */ + struct library_symbol *tmp = malloc(sizeof *tmp); + if (tmp == NULL + || library_symbol_init(tmp, naddr, full_name, 1, LS_TOPLT_NONE) < 0) { - --num_symbols; - goto fail; + free(tmp); + + /* Either add the whole bunch, or none + * of it. Note that for plt_fail we + * don't do this--it's the callee's + * job to clean up after itself before + * it bails out. */ + delete_symbol_chain(libsym); + libsym = NULL; + + case plt_fail: + fprintf(stderr, "Couldn't add symbol %s@%s " + "for tracing.\n", name, lib->soname); + + break; } - unique->libsym = libsym; - unique->addr = naddr; - } else if (strlen(full_name) < strlen(unique->libsym->name)) { - library_symbol_set_name(unique->libsym, - full_name, own_full_name); + full_name = NULL; + tmp->next = libsym; + libsym = tmp; + break; - } else if (own_full_name) { - free(full_name); + case plt_ok: + break; + } + + free(full_name); + + struct library_symbol *tmp; + for (tmp = libsym; tmp != NULL; ) { + /* Look whether we already have a symbol for + * this address. If not, add this one. If + * yes, look if we should pick the new symbol + * name. */ + + struct unique_symbol key = { tmp->enter_addr, NULL }; + struct unique_symbol *unique + = lsearch(&key, symbols, &num_symbols, + sizeof *symbols, &unique_symbol_cmp); + + if (unique->libsym == NULL) { + unique->libsym = tmp; + unique->addr = tmp->enter_addr; + tmp = tmp->next; + } else { + if (strlen(tmp->name) + < strlen(unique->libsym->name)) { + library_symbol_set_name + (unique->libsym, tmp->name, 1); + tmp->name = NULL; + } + struct library_symbol *next = tmp->next; + library_symbol_destroy(tmp); + free(tmp); + tmp = next; + } } }
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