diff options
author | Petr Machata <pmachata@redhat.com> | 2012-03-21 05:15:44 +0100 |
---|---|---|
committer | Petr Machata <pmachata@redhat.com> | 2012-04-19 01:17:09 +0200 |
commit | 4e2073f64f9db2974d89064dcdc49b2ed7aa9006 (patch) | |
tree | 4a21c31fc15e222222a296e32e644c2b28363123 /sysdeps | |
parent | b120fdfda45e49d082ab2aa5caadf030f50cb4ed (diff) | |
download | ltrace-4e2073f64f9db2974d89064dcdc49b2ed7aa9006.tar.gz |
Support tracing PPC32 processes with both BSS and secure PLTs
- only entry breakpoint is realized at the beginning
- when it's hit, it's deleted, and all enabled breakpoints are realized
- all PLTs are LS_TOPLT_EXEC. The difference is in the way the PLT entry
address is computed
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/linux-gnu/ppc/arch.h | 1 | ||||
-rw-r--r-- | sysdeps/linux-gnu/ppc/plt.c | 31 |
2 files changed, 18 insertions, 14 deletions
diff --git a/sysdeps/linux-gnu/ppc/arch.h b/sysdeps/linux-gnu/ppc/arch.h index 15673e0..609a6b9 100644 --- a/sysdeps/linux-gnu/ppc/arch.h +++ b/sysdeps/linux-gnu/ppc/arch.h @@ -29,5 +29,6 @@ struct arch_ltelf_data { GElf_Addr ppcgot; GElf_Addr plt_stub_vma; + int secure_plt; }; #endif diff --git a/sysdeps/linux-gnu/ppc/plt.c b/sysdeps/linux-gnu/ppc/plt.c index 94a500b..a0701eb 100644 --- a/sysdeps/linux-gnu/ppc/plt.c +++ b/sysdeps/linux-gnu/ppc/plt.c @@ -12,7 +12,7 @@ #define PPC_PLT_STUB_SIZE 16 static inline int -is_ppc64() +host_powerpc64() { #ifdef __powerpc64__ return 1; @@ -21,27 +21,29 @@ is_ppc64() #endif } -static inline int -is_ppc32() -{ - return !is_ppc64(); -} - GElf_Addr -arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { - if (lte->arch.plt_stub_vma != 0) +arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela *rela) +{ + if (lte->ehdr.e_machine == EM_PPC && lte->arch.secure_plt) { + assert(lte->arch.plt_stub_vma != 0); return lte->arch.plt_stub_vma + PPC_PLT_STUB_SIZE * ndx; - else + + } else if (lte->ehdr.e_machine == EM_PPC) { return rela->r_offset; + + } else { + assert(lte->ehdr.e_machine == EM_PPC64); + fprintf(stderr, "PPC64\n"); + abort(); + return rela->r_offset; + } } int arch_translate_address(struct Process *proc, target_address_t addr, target_address_t *ret) { - if (is_ppc64() && proc->e_machine == EM_PPC64) { - fprintf (stderr, "32-bit\n"); - + if (host_powerpc64() && proc->e_machine == EM_PPC64) { long l = ptrace(PTRACE_PEEKTEXT, proc->pid, addr, 0); fprintf(stderr, "arch_translate_address %p->%#lx\n", addr, l); @@ -178,7 +180,8 @@ arch_elf_dynamic_tag(struct ltelf *lte, GElf_Dyn dyn) int arch_elf_init(struct ltelf *lte) { - if (lte->ehdr.e_machine == EM_PPC) { + 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); |