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