aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetr Machata <pmachata@redhat.com>2012-04-07 01:24:08 +0200
committerPetr Machata <pmachata@redhat.com>2012-04-19 01:38:02 +0200
commit18c801c3f29081d9de517815df89bc1bbf8e2188 (patch)
treef26fb9c35397438497832e7fb07ec075da2ec7c1
parent0092820afcd45fe045ccc294b061bce8da00a1f2 (diff)
downloadltrace-18c801c3f29081d9de517815df89bc1bbf8e2188.tar.gz
Drop the rest of LS_TOPLT_POINT support
If any other architecture needs it, we'll add it back in some form. But now that we have callbacks on breakpoints, it might be possible to do it differently, without explicit support.
-rw-r--r--library.h1
-rw-r--r--ltrace-elf.c19
-rw-r--r--ltrace-elf.h6
-rw-r--r--sysdeps/linux-gnu/ppc/plt.c62
4 files changed, 7 insertions, 81 deletions
diff --git a/library.h b/library.h
index 4f925d1..5cafaf5 100644
--- a/library.h
+++ b/library.h
@@ -31,7 +31,6 @@ struct library;
enum toplt {
LS_TOPLT_NONE = 0, /* PLT not used for this symbol. */
LS_TOPLT_EXEC, /* PLT for this symbol is executable. */
- LS_TOPLT_POINT /* PLT for this symbol is a non-executable. */
};
/* We should in general be able to trace 64-bit processes with 32-bit
diff --git a/ltrace-elf.c b/ltrace-elf.c
index 60d3851..97207da 100644
--- a/ltrace-elf.c
+++ b/ltrace-elf.c
@@ -52,8 +52,6 @@ default_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
return -1;
}
- enum toplt pltt = PLTS_ARE_EXECUTABLE(lte)
- ? LS_TOPLT_EXEC : LS_TOPLT_POINT;
GElf_Addr addr = arch_plt_sym_val(lte, ndx, rela);
struct library_symbol *libsym = malloc(sizeof(*libsym));
@@ -62,19 +60,7 @@ default_elf_add_plt_entry(struct Process *proc, struct ltelf *lte,
target_address_t taddr = (target_address_t)(addr + lte->bias);
- /* The logic behind this conditional translation is as
- * follows. PLT entries do not typically need custom TOC
- * pointer, and therefore aren't redirected via OPD. POINT
- * PLT, on the other hand, most likely contains addresses of
- * target functions, not PLT entries themselves, and would
- * need the OPD redirection. */
- if (pltt == LS_TOPLT_POINT
- && arch_translate_address(proc, taddr, &taddr) < 0) {
- free(libsym);
- goto fail;
- }
-
- library_symbol_init(libsym, taddr, name, 1, pltt);
+ library_symbol_init(libsym, taddr, name, 1, LS_TOPLT_EXEC);
*ret = libsym;
return 0;
}
@@ -375,8 +361,7 @@ do_init_elf(struct ltelf *lte, const char *filename, GElf_Addr bias)
if (lte->plt_data == NULL)
fprintf(stderr,
"Can't load .plt data\n");
- if (shdr.sh_flags & SHF_EXECINSTR)
- lte->lte_flags |= LTE_PLT_EXECUTABLE;
+ lte->plt_flags = shdr.sh_flags;
}
#ifdef ARCH_SUPPORTS_OPD
else if (strcmp(name, ".opd") == 0) {
diff --git a/ltrace-elf.h b/ltrace-elf.h
index 4a27598..758c1d0 100644
--- a/ltrace-elf.h
+++ b/ltrace-elf.h
@@ -22,6 +22,7 @@ struct ltelf {
size_t dynsym_count;
const char *dynstr;
GElf_Addr plt_addr;
+ GElf_Word plt_flags;
size_t plt_size;
Elf_Data *relplt;
Elf_Data *plt_data;
@@ -33,7 +34,6 @@ struct ltelf {
Elf_Data *opd;
GElf_Addr *opd_addr;
size_t opd_size;
- int lte_flags;
GElf_Addr dyn_addr;
size_t dyn_sz;
size_t relplt_size;
@@ -43,10 +43,6 @@ struct ltelf {
struct arch_ltelf_data arch;
};
-#define LTE_PLT_EXECUTABLE 2
-
-#define PLTS_ARE_EXECUTABLE(lte) (((lte)->lte_flags & LTE_PLT_EXECUTABLE) != 0)
-
int open_elf(struct ltelf *lte, const char *filename);
/* XXX is it possible to put breakpoints in VDSO and VSYSCALL
diff --git a/sysdeps/linux-gnu/ppc/plt.c b/sysdeps/linux-gnu/ppc/plt.c
index de304d3..4aff818 100644
--- a/sysdeps/linux-gnu/ppc/plt.c
+++ b/sysdeps/linux-gnu/ppc/plt.c
@@ -135,58 +135,10 @@ arch_translate_address(struct Process *proc,
return 0;
}
-/* XXX Apparently PPC64 doesn't support PLT breakpoints. */
void *
-sym2addr(Process *proc, struct library_symbol *sym) {
- void *addr = sym->enter_addr;
- long pt_ret;
-
- debug(3, 0);
-
- if (sym->plt_type != LS_TOPLT_POINT) {
- return addr;
- }
-
- if (proc->pid == 0) {
- return 0;
- }
-
- if (options.debug >= 3) {
- xinfdump(proc->pid, (void *)(((long)addr-32)&0xfffffff0),
- sizeof(void*)*8);
- }
-
- // On a PowerPC-64 system, a plt is three 64-bit words: the first is the
- // 64-bit address of the routine. Before the PLT has been initialized,
- // this will be 0x0. In fact, the symbol table won't have the plt's
- // address even. Ater the PLT has been initialized, but before it has
- // been resolved, the first word will be the address of the function in
- // the dynamic linker that will reslove the PLT. After the PLT is
- // resolved, this will will be the address of the routine whose symbol
- // is in the symbol table.
-
- // On a PowerPC-32 system, there are two types of PLTs: secure (new) and
- // non-secure (old). For the secure case, the PLT is simply a pointer
- // and we can treat it much as we do for the PowerPC-64 case. For the
- // non-secure case, the PLT is executable code and we can put the
- // break-point right in the PLT.
-
- pt_ret = ptrace(PTRACE_PEEKTEXT, proc->pid, addr, 0);
-
-#if SIZEOF_LONG == 8
- if (proc->mask_32bit) {
- // Assume big-endian.
- addr = (void *)((pt_ret >> 32) & 0xffffffff);
- } else {
- addr = (void *)pt_ret;
- }
-#else
- /* XXX Um, so where exactly are we dealing with the non-secure
- PLT thing? */
- addr = (void *)pt_ret;
-#endif
-
- return addr;
+sym2addr(struct Process *proc, struct library_symbol *sym)
+{
+ return sym->enter_addr;
}
static GElf_Addr
@@ -282,7 +234,7 @@ load_ppc64_glink(struct ltelf *lte, GElf_Addr *glinkp)
int
arch_elf_init(struct ltelf *lte)
{
- lte->arch.secure_plt = !(lte->lte_flags & LTE_PLT_EXECUTABLE);
+ lte->arch.secure_plt = !(lte->plt_flags & SHF_EXECINSTR);
if (lte->ehdr.e_machine == EM_PPC && lte->arch.secure_plt) {
GElf_Addr ppcgot;
if (load_ppcgot(lte, &ppcgot) < 0) {
@@ -308,11 +260,6 @@ arch_elf_init(struct ltelf *lte)
lte->arch.plt_stub_vma = glink_vma + 32;
}
- /* Override the value that we gleaned from flags on the .plt
- * section. The PLT entries are in fact executable, they are
- * just not in .plt. */
- lte->lte_flags |= LTE_PLT_EXECUTABLE;
-
/* On PPC64, look for stub symbols in symbol table. These are
* called: xxxxxxxx.plt_call.callee_name@version+addend. */
if (lte->ehdr.e_machine == EM_PPC64
@@ -586,7 +533,6 @@ arch_breakpoint_init(struct Process *proc, struct breakpoint *bp)
/* We could see LS_TOPLT_EXEC or LS_TOPLT_NONE (the latter
* when we trace entry points), but not LS_TOPLT_POINT
* anywhere on PPC. */
- assert(bp->libsym->plt_type != LS_TOPLT_POINT);
if (bp->libsym->plt_type != LS_TOPLT_EXEC
|| bp->libsym->arch.type == PPC64PLT_STUB)
return 0;