| Index: fusl/arch/arm/src/find_exidx.c
|
| diff --git a/fusl/arch/arm/src/find_exidx.c b/fusl/arch/arm/src/find_exidx.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..77c4472bf60f8690d46ab81284168aa178c29482
|
| --- /dev/null
|
| +++ b/fusl/arch/arm/src/find_exidx.c
|
| @@ -0,0 +1,42 @@
|
| +#define _GNU_SOURCE
|
| +#include <link.h>
|
| +#include <stdint.h>
|
| +
|
| +struct find_exidx_data {
|
| + uintptr_t pc, exidx_start;
|
| + int exidx_len;
|
| +};
|
| +
|
| +static int find_exidx(struct dl_phdr_info *info, size_t size, void *ptr)
|
| +{
|
| + struct find_exidx_data *data = ptr;
|
| + const ElfW(Phdr) *phdr = info->dlpi_phdr;
|
| + uintptr_t addr, exidx_start = 0;
|
| + int i, match = 0, exidx_len = 0;
|
| +
|
| + for (i = info->dlpi_phnum; i > 0; i--, phdr++) {
|
| + addr = info->dlpi_addr + phdr->p_vaddr;
|
| + switch (phdr->p_type) {
|
| + case PT_LOAD:
|
| + match |= data->pc >= addr && data->pc < addr + phdr->p_memsz;
|
| + break;
|
| + case PT_ARM_EXIDX:
|
| + exidx_start = addr;
|
| + exidx_len = phdr->p_memsz;
|
| + break;
|
| + }
|
| + }
|
| + data->exidx_start = exidx_start;
|
| + data->exidx_len = exidx_len;
|
| + return match;
|
| +}
|
| +
|
| +uintptr_t __gnu_Unwind_Find_exidx(uintptr_t pc, int *pcount)
|
| +{
|
| + struct find_exidx_data data;
|
| + data.pc = pc;
|
| + if (dl_iterate_phdr(find_exidx, &data) <= 0)
|
| + return 0;
|
| + *pcount = data.exidx_len / 8;
|
| + return data.exidx_start;
|
| +}
|
|
|