add symbol lookup
This commit is contained in:
parent
b9978801a3
commit
f284304dd6
|
@ -232,4 +232,98 @@ static int parse_elf_symbols(const char* filepath){
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// symbol lookup
|
||||||
|
const char* rvprof_symbols_lookup(void* addr){
|
||||||
|
if (!g_rvprof.symbols_loaded || g_rvprof.symbols.size == 0){
|
||||||
|
snprintf(g_tmp_func_name, sizeof(g_tmp_func_name), "func_%p", addr);
|
||||||
|
return g_tmp_func_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t target_addr = (uintptr_t)addr;
|
||||||
|
|
||||||
|
// try to calculate base address offset using known symbols
|
||||||
|
if (!g_base_address_calculated && g_rvprof.symbols.size > 0){
|
||||||
|
// use our own profiling functions as reference points since we know their addresses
|
||||||
|
for (int i = 0; i < g_rvprof.symbols.size; i++){
|
||||||
|
symbol_entry_t* sym = &g_rvprof.symbols.data[i];
|
||||||
|
|
||||||
|
// use rvprof functions as reference points
|
||||||
|
if (strcmp(sym->name, "__cyg_profile_func_enter") == 0){
|
||||||
|
calculate_base_address_offset((void*)__cyg_profile_func_enter, sym->addr);
|
||||||
|
break;
|
||||||
|
} else if (strcmp(sym->name, "rvprof_init") == 0){
|
||||||
|
calculate_base_address_offset((void*)rvprof_init, sym->addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we still haven't calculated it, try to infer from the lookup addresses
|
||||||
|
if (!g_base_address_calculated && g_rvprof.symbols.size > 0){
|
||||||
|
// find the closest symbol and use it to estimate base offset
|
||||||
|
uintptr_t highest_elf_addr = 0;
|
||||||
|
for (int i = 0; i < g_rvprof.symbols.size; i++) {
|
||||||
|
if (g_rvprof.symbols.data[i].addr > highest_elf_addr) {
|
||||||
|
highest_elf_addr = g_rvprof.symbols.data[i].addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the target address is much higher than any ELF address, calculate offset
|
||||||
|
if (target_addr > highest_elf_addr && (target_addr - highest_elf_addr) > 0x100000){
|
||||||
|
// estimate base offset
|
||||||
|
uintptr_t estimated_offset = target_addr - highest_elf_addr;
|
||||||
|
// round down to page boundary (typically 4KB)
|
||||||
|
g_base_address_offset = (estimated_offset & ~0xFFF);
|
||||||
|
g_base_address_calculated = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// adjust target address by base offset
|
||||||
|
uintptr_t adjusted_addr = target_addr;
|
||||||
|
if (g_base_address_calculated && g_base_address_offset > 0){
|
||||||
|
adjusted_addr = target_addr - g_base_address_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// binary search for closest symbol
|
||||||
|
int left = 0;
|
||||||
|
int right = g_rvprof.symbols.size - 1;
|
||||||
|
int best_match = -1;
|
||||||
|
|
||||||
|
while (left <= right){
|
||||||
|
int mid = (left + right) / 2;
|
||||||
|
|
||||||
|
if (g_rvprof.symbols.data[mid].addr <= adjusted_addr){
|
||||||
|
best_match = mid;
|
||||||
|
left = mid + 1;
|
||||||
|
} else {
|
||||||
|
right = mid - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// match?
|
||||||
|
if (best_match >= 0) {
|
||||||
|
symbol_entry_t* sym = &g_rvprof.symbols.data[best_match];
|
||||||
|
|
||||||
|
// if symbol has size info, check if address is within range
|
||||||
|
if (sym->size > 0) {
|
||||||
|
if (adjusted_addr >= sym->addr && adjusted_addr < sym->addr + sym->size){
|
||||||
|
strncpy(g_temp_func_name, sym->name, sizeof(g_temp_func_name) - 1);
|
||||||
|
g_temp_func_name[sizeof(g_temp_func_name) - 1] = '\0';
|
||||||
|
return g_temp_func_name;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// no size info, use 64 KB heuristic: must be within reasonable range
|
||||||
|
if (adjusted_addr >= sym->addr && (adjusted_addr - sym->addr) < 0x10000){
|
||||||
|
strncpy(g_temp_func_name, sym->name, sizeof(g_temp_func_name) - 1);
|
||||||
|
g_temp_func_name[sizeof(g_temp_func_name) - 1] = '\0';
|
||||||
|
return g_temp_func_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback to addresses if we cannot resolve symbols
|
||||||
|
snprintf(g_temp_func_name, sizeof(g_temp_func_name), "func_%p", addr);
|
||||||
|
return g_temp_func_name;
|
||||||
}
|
}
|
Loading…
Reference in New Issue