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