OLD | NEW |
(Empty) | |
| 1 #define _GNU_SOURCE |
| 2 #include <link.h> |
| 3 #include <stdint.h> |
| 4 |
| 5 struct find_exidx_data { |
| 6 uintptr_t pc, exidx_start; |
| 7 int exidx_len; |
| 8 }; |
| 9 |
| 10 static int find_exidx(struct dl_phdr_info *info, size_t size, void *ptr) |
| 11 { |
| 12 struct find_exidx_data *data = ptr; |
| 13 const ElfW(Phdr) *phdr = info->dlpi_phdr; |
| 14 uintptr_t addr, exidx_start = 0; |
| 15 int i, match = 0, exidx_len = 0; |
| 16 |
| 17 for (i = info->dlpi_phnum; i > 0; i--, phdr++) { |
| 18 addr = info->dlpi_addr + phdr->p_vaddr; |
| 19 switch (phdr->p_type) { |
| 20 case PT_LOAD: |
| 21 match |= data->pc >= addr && data->pc < addr + phdr->p_m
emsz; |
| 22 break; |
| 23 case PT_ARM_EXIDX: |
| 24 exidx_start = addr; |
| 25 exidx_len = phdr->p_memsz; |
| 26 break; |
| 27 } |
| 28 } |
| 29 data->exidx_start = exidx_start; |
| 30 data->exidx_len = exidx_len; |
| 31 return match; |
| 32 } |
| 33 |
| 34 uintptr_t __gnu_Unwind_Find_exidx(uintptr_t pc, int *pcount) |
| 35 { |
| 36 struct find_exidx_data data; |
| 37 data.pc = pc; |
| 38 if (dl_iterate_phdr(find_exidx, &data) <= 0) |
| 39 return 0; |
| 40 *pcount = data.exidx_len / 8; |
| 41 return data.exidx_start; |
| 42 } |
OLD | NEW |