diff options
author | Petr Machata <pmachata@redhat.com> | 2012-03-24 02:06:48 +0100 |
---|---|---|
committer | Petr Machata <pmachata@redhat.com> | 2012-04-19 01:18:47 +0200 |
commit | 644d669f96c0fe261fe938cecda41938e804c7d9 (patch) | |
tree | 495db755f69b6e8b1acf5b26f0dbefd5017e4c7b /sysdeps | |
parent | ffd5aab0bddbbb7c650c2f5c12a48e0298f82516 (diff) | |
download | ltrace-644d669f96c0fe261fe938cecda41938e804c7d9.tar.gz |
Drop recently introduced arch_elf_dynamic_tag
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/linux-gnu/mipsel/arch.h | 2 | ||||
-rw-r--r-- | sysdeps/linux-gnu/mipsel/plt.c | 43 | ||||
-rw-r--r-- | sysdeps/linux-gnu/ppc/arch.h | 3 | ||||
-rw-r--r-- | sysdeps/linux-gnu/ppc/plt.c | 42 |
4 files changed, 66 insertions, 24 deletions
diff --git a/sysdeps/linux-gnu/mipsel/arch.h b/sysdeps/linux-gnu/mipsel/arch.h index e2fdbf8..a447edb 100644 --- a/sysdeps/linux-gnu/mipsel/arch.h +++ b/sysdeps/linux-gnu/mipsel/arch.h @@ -8,8 +8,8 @@ #define PLTs_INIT_BY_HERE "_start" #define E_ENTRY_NAME "_start" +#define ARCH_HAVE_LTELF_DATA #ifdef DEFINING_LTELF -# define ARCH_HAVE_LTELF_DATA struct arch_ltelf_data { size_t pltgot_addr; size_t mips_local_gotno; diff --git a/sysdeps/linux-gnu/mipsel/plt.c b/sysdeps/linux-gnu/mipsel/plt.c index 77807b1..5eec221 100644 --- a/sysdeps/linux-gnu/mipsel/plt.c +++ b/sysdeps/linux-gnu/mipsel/plt.c @@ -1,6 +1,7 @@ #include "debug.h" #include <gelf.h> #include <sys/ptrace.h> +#include <error.h> #include "proc.h" #include "common.h" @@ -87,23 +88,39 @@ sym2addr(Process *proc, struct library_symbol *sym) { */ int -arch_elf_dynamic_tag(struct ltelf *lte, GElf_Dyn dyn) +arch_elf_init(struct ltelf *lte) { - if(dyn.d_tag == DT_PLTGOT) { - lte->arch.pltgot_addr = dyn.d_un.d_ptr; - } - if(dyn.d_tag == DT_MIPS_LOCAL_GOTNO){ - lte->arch.mips_local_gotno = dyn.d_un.d_val; + Elf_Scn *scn; + GElf_Shdr shdr; + if (elf_get_section_type(lte, SHT_DYNAMIC, &scn, &shdr) < 0 + || scn == NULL) { + fail: + error(0, 0, "Couldn't get SHT_DYNAMIC: %s", + elf_errmsg(-1)); + return -1; } - if(dyn.d_tag == DT_MIPS_GOTSYM){ - lte->arch.mips_gotsym = dyn.d_un.d_val; + + Elf_Data *data = elf_loaddata(scn, &shdr); + if (data == NULL) + goto fail; + + size_t j; + for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) { + GElf_Dyn dyn; + if (gelf_getdyn(data, j, &dyn) == NULL) + goto fail; + + if(dyn.d_tag == DT_PLTGOT) { + lte->arch.pltgot_addr = dyn.d_un.d_ptr; + } + if(dyn.d_tag == DT_MIPS_LOCAL_GOTNO){ + lte->arch.mips_local_gotno = dyn.d_un.d_val; + } + if(dyn.d_tag == DT_MIPS_GOTSYM){ + lte->arch.mips_gotsym = dyn.d_un.d_val; + } } - return 0; -} -int -arch_elf_init(struct ltelf *lte) -{ return 0; } diff --git a/sysdeps/linux-gnu/ppc/arch.h b/sysdeps/linux-gnu/ppc/arch.h index 609a6b9..6fd4714 100644 --- a/sysdeps/linux-gnu/ppc/arch.h +++ b/sysdeps/linux-gnu/ppc/arch.h @@ -24,10 +24,9 @@ #error "Length of the breakpoint value not equal to the length of a nop instruction" #endif +#define ARCH_HAVE_LTELF_DATA #ifdef DEFINING_LTELF -# define ARCH_HAVE_LTELF_DATA struct arch_ltelf_data { - GElf_Addr ppcgot; GElf_Addr plt_stub_vma; int secure_plt; }; diff --git a/sysdeps/linux-gnu/ppc/plt.c b/sysdeps/linux-gnu/ppc/plt.c index a0701eb..6075d7d 100644 --- a/sysdeps/linux-gnu/ppc/plt.c +++ b/sysdeps/linux-gnu/ppc/plt.c @@ -167,14 +167,36 @@ get_glink_vma(struct ltelf *lte, GElf_Addr ppcgot, Elf_Data *plt_data) return 0; } -int -arch_elf_dynamic_tag(struct ltelf *lte, GElf_Dyn dyn) +static int +load_ppcgot(struct ltelf *lte, GElf_Addr *ppcgotp) { - if (dyn.d_tag == DT_PPC_GOT) { - lte->arch.ppcgot = dyn.d_un.d_val; - debug(1, "ppcgot %#" PRIx64, lte->arch.ppcgot); + Elf_Scn *scn; + GElf_Shdr shdr; + if (elf_get_section_type(lte, SHT_DYNAMIC, &scn, &shdr) < 0 + || scn == NULL) { + fail: + error(0, 0, "Couldn't get SHT_DYNAMIC: %s", + elf_errmsg(-1)); + return -1; } - return 0; + + Elf_Data *data = elf_loaddata(scn, &shdr); + if (data == NULL) + goto fail; + + size_t j; + for (j = 0; j < shdr.sh_size / shdr.sh_entsize; ++j) { + GElf_Dyn dyn; + if (gelf_getdyn(data, j, &dyn) == NULL) + goto fail; + + if(dyn.d_tag == DT_PPC_GOT) { + *ppcgotp = dyn.d_un.d_ptr; + return 0; + } + } + + return -1; } int @@ -182,8 +204,12 @@ arch_elf_init(struct ltelf *lte) { lte->arch.secure_plt = !(lte->lte_flags & LTE_PLT_EXECUTABLE); if (lte->ehdr.e_machine == EM_PPC && lte->arch.secure_plt) { - GElf_Addr glink_vma - = get_glink_vma(lte, lte->arch.ppcgot, lte->plt_data); + GElf_Addr ppcgot; + if (load_ppcgot(lte, &ppcgot) < 0) { + fprintf(stderr, "Couldn't find DT_PPC_GOT.\n"); + return -1; + } + GElf_Addr glink_vma = get_glink_vma(lte, ppcgot, lte->plt_data); assert (lte->relplt_size % 12 == 0); size_t count = lte->relplt_size / 12; // size of RELA entry |