Juan Cespedes | 1cd999a | 2001-07-03 00:46:04 +0200 | [diff] [blame] | 1 | #ifndef LTRACE_ELF_H |
| 2 | #define LTRACE_ELF_H |
| 3 | |
Juan Cespedes | d914a20 | 2004-11-10 00:15:33 +0100 | [diff] [blame] | 4 | #include <gelf.h> |
| 5 | #include <stdlib.h> |
| 6 | |
Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 7 | struct Process; |
| 8 | struct library; |
| 9 | |
| 10 | /* XXX Ok, the original idea was to separate the low-level ELF data |
| 11 | * from the abstract "struct library" object, but we use some of the |
| 12 | * following extensively in the back end. Not all though. So what we |
| 13 | * use should be move to struct library, and the rest of this |
| 14 | * structure maybe could be safely hidden in .c. How to integrate the |
| 15 | * arch-specific bits into struct library is unclear as of now. */ |
Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 16 | struct ltelf { |
| 17 | int fd; |
| 18 | Elf *elf; |
| 19 | GElf_Ehdr ehdr; |
| 20 | Elf_Data *dynsym; |
| 21 | size_t dynsym_count; |
| 22 | const char *dynstr; |
| 23 | GElf_Addr plt_addr; |
| 24 | size_t plt_size; |
| 25 | Elf_Data *relplt; |
| 26 | size_t relplt_count; |
| 27 | Elf_Data *symtab; |
| 28 | const char *strtab; |
Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 29 | const char *soname; |
Ian Wienand | 2d45b1a | 2006-02-20 22:48:07 +0100 | [diff] [blame] | 30 | size_t symtab_count; |
| 31 | Elf_Data *opd; |
| 32 | GElf_Addr *opd_addr; |
| 33 | size_t opd_size; |
Paul Gilliam | 76c61f1 | 2006-06-14 06:55:21 +0200 | [diff] [blame] | 34 | int lte_flags; |
Joe Damato | 87f4f58 | 2010-11-08 15:47:36 -0800 | [diff] [blame] | 35 | GElf_Addr dyn_addr; |
| 36 | size_t dyn_sz; |
Petr Machata | 29add4f | 2012-02-18 16:38:05 +0100 | [diff] [blame^] | 37 | GElf_Addr bias; |
Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 38 | GElf_Addr entry_addr; |
Petr Machata | 29add4f | 2012-02-18 16:38:05 +0100 | [diff] [blame^] | 39 | GElf_Addr base_addr; |
Eric Vaitl | 1228a91 | 2006-12-28 16:16:56 +0100 | [diff] [blame] | 40 | #ifdef __mips__ |
Juan Cespedes | a413e5b | 2007-09-04 17:34:53 +0200 | [diff] [blame] | 41 | size_t pltgot_addr; |
| 42 | size_t mips_local_gotno; |
| 43 | size_t mips_gotsym; |
Eric Vaitl | 1228a91 | 2006-12-28 16:16:56 +0100 | [diff] [blame] | 44 | #endif // __mips__ |
Petr Machata | fe1c171 | 2010-10-27 16:57:34 +0200 | [diff] [blame] | 45 | GElf_Addr plt_stub_vma; |
Juan Cespedes | 1cd999a | 2001-07-03 00:46:04 +0200 | [diff] [blame] | 46 | }; |
| 47 | |
Joe Damato | 47cae1e | 2010-11-08 15:47:39 -0800 | [diff] [blame] | 48 | #define ELF_MAX_SEGMENTS 50 |
Paul Gilliam | 76c61f1 | 2006-06-14 06:55:21 +0200 | [diff] [blame] | 49 | #define LTE_PLT_EXECUTABLE 2 |
| 50 | |
Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 51 | #define PLTS_ARE_EXECUTABLE(lte) (((lte)->lte_flags & LTE_PLT_EXECUTABLE) != 0) |
Paul Gilliam | 76c61f1 | 2006-06-14 06:55:21 +0200 | [diff] [blame] | 52 | |
Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 53 | int open_elf(struct ltelf *lte, const char *filename); |
Juan Cespedes | 1cd999a | 2001-07-03 00:46:04 +0200 | [diff] [blame] | 54 | |
Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 55 | /* XXX is it possible to put breakpoints in VDSO and VSYSCALL |
| 56 | * pseudo-libraries? For now we assume that all libraries can be |
| 57 | * opened via a filesystem. BASE is ignored for ET_EXEC files. */ |
| 58 | struct library *ltelf_read_library(const char *filename, GElf_Addr base); |
Juan Cespedes | d914a20 | 2004-11-10 00:15:33 +0100 | [diff] [blame] | 59 | |
Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 60 | /* Create a library object representing the main binary. The entry |
| 61 | * point address is stored to *ENTRYP. */ |
| 62 | struct library *ltelf_read_main_binary(struct Process *proc, const char *path); |
Juan Cespedes | 96935a9 | 1997-08-09 23:45:39 +0200 | [diff] [blame] | 63 | |
Petr Machata | 2b46cfc | 2012-02-18 11:17:29 +0100 | [diff] [blame] | 64 | GElf_Addr arch_plt_sym_val(struct ltelf *, size_t, GElf_Rela *); |
Zachary T Welch | 3ba522f | 2010-12-14 15:12:47 -0800 | [diff] [blame] | 65 | |
| 66 | #if __WORDSIZE == 32 |
| 67 | #define PRI_ELF_ADDR PRIx32 |
| 68 | #define GELF_ADDR_CAST(x) (void *)(uint32_t)(x) |
| 69 | #else |
| 70 | #define PRI_ELF_ADDR PRIx64 |
| 71 | #define GELF_ADDR_CAST(x) (void *)(x) |
| 72 | #endif |
| 73 | |
Juan Cespedes | 1cd999a | 2001-07-03 00:46:04 +0200 | [diff] [blame] | 74 | #endif |