github.com/afumu/libc@v0.0.6/musl/src/ldso/arm/find_exidx.c (about) 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_memsz; 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 }