plt.c revision 2a61d19bd244dadcde5009f1632cf14b95623e3d
1#include <gelf.h> 2#include "common.h" 3 4GElf_Addr 5arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { 6 return rela->r_offset; 7} 8 9void * 10sym2addr(Process *proc, struct library_symbol *sym) { 11 void *addr = sym->enter_addr; 12 long pt_ret; 13 14 debug(3, 0); 15 16 if (sym->plt_type != LS_TOPLT_POINT) { 17 return addr; 18 } 19 20 if (proc->pid == 0) { 21 return 0; 22 } 23 24 if (options.debug >= 3) { 25 xinfdump(proc->pid, (void *)(((long)addr-32)&0xfffffff0), 26 sizeof(void*)*8); 27 } 28 29 // On a PowerPC-64 system, a plt is three 64-bit words: the first is the 30 // 64-bit address of the routine. Before the PLT has been initialized, 31 // this will be 0x0. In fact, the symbol table won't have the plt's 32 // address even. Ater the PLT has been initialized, but before it has 33 // been resolved, the first word will be the address of the function in 34 // the dynamic linker that will reslove the PLT. After the PLT is 35 // resolved, this will will be the address of the routine whose symbol 36 // is in the symbol table. 37 38 // On a PowerPC-32 system, there are two types of PLTs: secure (new) and 39 // non-secure (old). For the secure case, the PLT is simply a pointer 40 // and we can treat it much as we do for the PowerPC-64 case. For the 41 // non-secure case, the PLT is executable code and we can put the 42 // break-point right in the PLT. 43 44 pt_ret = ptrace(PTRACE_PEEKTEXT, proc->pid, addr, 0); 45 46 if (proc->mask_32bit) { 47 // Assume big-endian. 48 addr = (void *)((pt_ret >> 32) & 0xffffffff); 49 } else { 50 addr = (void *)pt_ret; 51 } 52 53 return addr; 54} 55