| Juan Cespedes | d914a20 | 2004-11-10 00:15:33 +0100 | [diff] [blame] | 1 | #include <gelf.h> |
| Petr Machata | c0ab286 | 2012-05-05 00:06:17 +0200 | [diff] [blame] | 2 | |
| Petr Machata | 366c2f4 | 2012-02-09 19:34:36 +0100 | [diff] [blame] | 3 | #include "proc.h" |
| Petr Machata | c0ab286 | 2012-05-05 00:06:17 +0200 | [diff] [blame] | 4 | #include "library.h" |
| 5 | #include "ltrace-elf.h" |
| Juan Cespedes | d914a20 | 2004-11-10 00:15:33 +0100 | [diff] [blame] | 6 | |
| Zach Welch | d568f51 | 2010-10-08 14:44:16 -0700 | [diff] [blame] | 7 | static int |
| 8 | arch_plt_entry_has_stub(struct ltelf *lte, size_t off) { |
| 9 | uint16_t op = *(uint16_t *)((char *)lte->relplt->d_buf + off); |
| 10 | return op == 0x4778; |
| 11 | } |
| 12 | |
| Juan Cespedes | f135052 | 2008-12-16 18:19:58 +0100 | [diff] [blame] | 13 | GElf_Addr |
| 14 | arch_plt_sym_val(struct ltelf *lte, size_t ndx, GElf_Rela * rela) { |
| Zach Welch | d568f51 | 2010-10-08 14:44:16 -0700 | [diff] [blame] | 15 | size_t start = lte->relplt->d_size + 12; |
| 16 | size_t off = start + 20, i; |
| 17 | for (i = 0; i < ndx; i++) |
| 18 | off += arch_plt_entry_has_stub(lte, off) ? 16 : 12; |
| 19 | if (arch_plt_entry_has_stub(lte, off)) |
| 20 | off += 4; |
| 21 | return lte->plt_addr + off - start; |
| Ian Wienand | 9a2ad35 | 2006-02-20 22:44:45 +0100 | [diff] [blame] | 22 | } |
| 23 | |
| Juan Cespedes | f135052 | 2008-12-16 18:19:58 +0100 | [diff] [blame] | 24 | void * |
| Juan Cespedes | a8909f7 | 2009-04-28 20:02:41 +0200 | [diff] [blame] | 25 | sym2addr(Process *proc, struct library_symbol *sym) { |
| Paul Gilliam | 76c61f1 | 2006-06-14 06:55:21 +0200 | [diff] [blame] | 26 | return sym->enter_addr; |
| Juan Cespedes | d914a20 | 2004-11-10 00:15:33 +0100 | [diff] [blame] | 27 | } |