aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/linux-gnu/ppc/plt.c
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/linux-gnu/ppc/plt.c')
-rw-r--r--sysdeps/linux-gnu/ppc/plt.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/sysdeps/linux-gnu/ppc/plt.c b/sysdeps/linux-gnu/ppc/plt.c
index 19991b5..c85ea92 100644
--- a/sysdeps/linux-gnu/ppc/plt.c
+++ b/sysdeps/linux-gnu/ppc/plt.c
@@ -1,8 +1,42 @@
#include <gelf.h>
#include "ltrace.h"
#include "elf.h"
+#include "debug.h"
+#include "ptrace.h"
+#include "options.h"
-GElf_Addr arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela)
+GElf_Addr
+arch_plt_sym_val (struct ltelf *lte, size_t ndx, GElf_Rela *rela)
{
- return rela->r_offset;
+ return rela->r_offset;
}
+
+void * plt2addr(struct process *proc, void ** plt)
+{
+ long addr;
+
+ debug(3, 0);
+
+ if (proc->e_machine == EM_PPC || plt == 0)
+ return (void *)plt;
+
+ if (proc->pid == 0)
+ return (void *)0;
+
+ // 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.
+
+ addr = ptrace(PTRACE_PEEKTEXT, proc->pid, plt);
+
+ if (opt_d >= 3) {
+ xinfdump(proc->pid, plt, sizeof(void*)*3);
+ }
+
+ return (void *)addr;
+}
+