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;
|
||||
}
|
||||
|
||||
// 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