From: "Edgar E. Iglesias" <[email protected]> No functional change. Will be used by the MIPS backend.
Signed-off-by: Edgar E. Iglesias <[email protected]> --- backend.h | 15 +++++++++++++++ ltrace-elf.c | 56 ++++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 51 insertions(+), 20 deletions(-) diff --git a/backend.h b/backend.h index bae53bd..60d682d 100644 --- a/backend.h +++ b/backend.h @@ -266,6 +266,21 @@ void arch_process_destroy(struct Process *proc); int arch_process_clone(struct Process *retp, struct Process *proc); int arch_process_exec(struct Process *proc); +/* The following callback has to be implemented in backend if arch.h + * defines ARCH_HAVE_GET_SYM_INFO. + * + * This is called for every PLT relocation R in ELF file LTE, that + * ltrace is about to add to it's internal representation of the + * program under trace. + * The corresponding PLT entry is for sym_index-th relocation in the file. + * + * If this function returns plt_default, PLT address is obtained by + * 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. */ +int arch_get_sym_info(struct ltelf *lte, const char *filename, + GElf_Rela *rela, GElf_Sym *sym, size_t sym_index); + enum plt_status { plt_fail, plt_ok, diff --git a/ltrace-elf.c b/ltrace-elf.c index bc99c6a..d9af076 100644 --- a/ltrace-elf.c +++ b/ltrace-elf.c @@ -510,35 +510,51 @@ do_close_elf(struct ltelf *lte) { close(lte->fd); } +#ifndef ARCH_HAVE_GET_SYMINFO +int +arch_get_sym_info(struct ltelf *lte, const char *filename, + GElf_Rela *rela, GElf_Sym *sym, size_t sym_index) +{ + int i = sym_index; + GElf_Rel rel; + void *ret; + + if (lte->relplt->d_type == ELF_T_REL) { + ret = gelf_getrel(lte->relplt, i, &rel); + rela->r_offset = rel.r_offset; + rela->r_info = rel.r_info; + rela->r_addend = 0; + } else { + ret = gelf_getrela(lte->relplt, i, rela); + } + + if (ret == NULL + || ELF64_R_SYM(rela->r_info) >= lte->dynsym_count + || gelf_getsym(lte->dynsym, ELF64_R_SYM(rela->r_info), + sym) == NULL) { + fprintf(stderr, + "Couldn't get relocation from \"%s\": %s\n", + filename, elf_errmsg(-1)); + exit(EXIT_FAILURE); + } + + return 0; +} +#endif + static int populate_plt(struct Process *proc, const char *filename, struct ltelf *lte, struct library *lib) { size_t i; for (i = 0; i < lte->relplt_count; ++i) { - GElf_Rel rel; GElf_Rela rela; GElf_Sym sym; - void *ret; - - if (lte->relplt->d_type == ELF_T_REL) { - ret = gelf_getrel(lte->relplt, i, &rel); - rela.r_offset = rel.r_offset; - rela.r_info = rel.r_info; - rela.r_addend = 0; - } else { - ret = gelf_getrela(lte->relplt, i, &rela); - } + int err; - if (ret == NULL - || ELF64_R_SYM(rela.r_info) >= lte->dynsym_count - || gelf_getsym(lte->dynsym, ELF64_R_SYM(rela.r_info), - &sym) == NULL) { - fprintf(stderr, - "Couldn't get relocation from \"%s\": %s\n", - filename, elf_errmsg(-1)); - exit(EXIT_FAILURE); - } + err = arch_get_sym_info(lte, filename, &rela, &sym, i); + if (err) + continue; /* Skip this entry. */ char const *name = lte->dynstr + sym.st_name; -- 1.7.8.6 _______________________________________________ Ltrace-devel mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/ltrace-devel
