From: "Edgar E. Iglesias" <[email protected]> Add support for CPIC (Calls PIC) only binaries. These ELF files are not PIC themselves (as ordinary o32 binaries).
External calls via function pointers don't work yet. Signed-off-by: Edgar E. Iglesias <[email protected]> --- sysdeps/linux-gnu/mipsel/arch.h | 2 ++ sysdeps/linux-gnu/mipsel/plt.c | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletions(-) diff --git a/sysdeps/linux-gnu/mipsel/arch.h b/sysdeps/linux-gnu/mipsel/arch.h index 4fa3a93..684b546 100644 --- a/sysdeps/linux-gnu/mipsel/arch.h +++ b/sysdeps/linux-gnu/mipsel/arch.h @@ -60,6 +60,8 @@ struct arch_library_symbol_data { /* Set for FUNCs that have GOT entries but not PLT entries. */ int gotonly : 1; + /* Set for FUNCs that have PLT entries that are always used. */ + int pltalways : 1; }; #endif /* LTRACE_MIPS_ARCH_H */ diff --git a/sysdeps/linux-gnu/mipsel/plt.c b/sysdeps/linux-gnu/mipsel/plt.c index f49f04f..09abf26 100644 --- a/sysdeps/linux-gnu/mipsel/plt.c +++ b/sysdeps/linux-gnu/mipsel/plt.c @@ -16,6 +16,12 @@ @{ */ +/* Are we in pure CPIC mode (the non-PIC ABI extension)? */ +static inline int mips_elf_is_cpic(unsigned int elf_flags) +{ + return (elf_flags & (EF_MIPS_PIC | EF_MIPS_CPIC)) == EF_MIPS_CPIC; +} + /** \param lte Structure containing link table entry information \param ndx Index into .dynsym @@ -43,6 +49,13 @@ GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela) { debug(1,"plt_addr %zx ndx %#zx",lte->arch.pltgot_addr, ndx); + + if (mips_elf_is_cpic(lte->ehdr.e_flags)) { + /* Return a pointer into the PLT. */ + return lte->plt_addr + 16 * 2 + (ndx * 16); + } + + /* Return a pointer to a GOT entry. */ return lte->arch.pltgot_addr + sizeof(void *) * (lte->arch.mips_local_gotno + (ndx - lte->arch.mips_gotsym)); @@ -70,7 +83,8 @@ void * sym2addr(Process *proc, struct library_symbol *sym) { long ret; - if (!sym->arch.gotonly && sym->plt_type == LS_TOPLT_NONE) { + if (sym->arch.pltalways + || (!sym->arch.gotonly && sym->plt_type == LS_TOPLT_NONE)) { return sym->enter_addr; } @@ -120,6 +134,10 @@ arch_get_sym_info(struct ltelf *lte, const char *filename, { const char *name; + if (mips_elf_is_cpic(lte->ehdr.e_flags)) { + return elf_get_sym_info(lte, filename, sym_index, rela, sym); + } + /* Fixup the offset. */ sym_index += lte->arch.mips_gotsym; @@ -158,6 +176,15 @@ arch_elf_init(struct ltelf *lte, struct library *lib) { Elf_Scn *scn; GElf_Shdr shdr; + + /* FIXME: for CPIC we should really scan both GOT tables + * to pick up relocations to external functions. Right now + * function pointers from the main binary to external functions + * can't be traced in CPIC mode. */ + if (mips_elf_is_cpic(lte->ehdr.e_flags)) { + return 0; /* We are already done. */ + } + if (elf_get_section_type(lte, SHT_DYNAMIC, &scn, &shdr) < 0 || scn == NULL) { fail: @@ -210,6 +237,10 @@ void arch_symbol_ret(struct Process *proc, struct library_symbol *libsym) if (libsym->arch.type != MIPS_PLT_UNRESOLVED) return; + /* Get out if we are always using the PLT. */ + if (libsym->arch.pltalways) + return; + resolved_addr = sym2addr(proc, libsym); libsym->arch.resolved_addr = (uintptr_t) resolved_addr; libsym->arch.type = MIPS_PLT_RESOLVED; @@ -329,6 +360,8 @@ arch_elf_add_plt_entry(struct Process *proc, struct ltelf *lte, /* Delay breakpoint activation until the symbol gets * resolved. */ libsym->delayed = 1; + } else if (mips_elf_is_cpic(lte->ehdr.e_flags)) { + libsym->arch.pltalways = 1; } *ret = libsym; @@ -343,6 +376,7 @@ fail: int arch_library_symbol_init(struct library_symbol *libsym) { + libsym->arch.pltalways = 0; libsym->arch.gotonly = 0; libsym->arch.type = MIPS_PLT_UNRESOLVED; if (libsym->plt_type == LS_TOPLT_NONE) { -- 1.7.8.6 _______________________________________________ Ltrace-devel mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/ltrace-devel
