diff options
Diffstat (limited to 'source/ucli/elf.cc')
| -rw-r--r-- | source/ucli/elf.cc | 123 |
1 files changed, 93 insertions, 30 deletions
diff --git a/source/ucli/elf.cc b/source/ucli/elf.cc index af4f801..3f64a99 100644 --- a/source/ucli/elf.cc +++ b/source/ucli/elf.cc @@ -163,7 +163,7 @@ static void __get_symbol_without_plt(std::set<symbol> &ss, sym_section_ctx *tab, s.end = s.start + sym.st_size; s.ip = s.start; s.name = sym_name; - printf("name: %s, start: %lx, end: %lx\n", s.name.c_str(), s.start, s.end); + // printf("name: %s, start: 0x%lx, end: 0x%lx\n", s.name.c_str(), s.start, s.end); ss.insert(s); } } @@ -220,7 +220,7 @@ static void __get_plt_symbol(std::set<symbol> &ss, symbol_sections_ctx *si, s.end = s.start + si->dynsymtab.plt_entsize; s.ip = s.start; s.name = sym_name; - printf("name: %s, start: %lx, end: %lx\n", s.name.c_str(), s.start, s.end); + // printf("plt name: %s, start: 0x%lx, end: 0x%lx\n", s.name.c_str(), s.start, s.end); ss.insert(s); } } @@ -282,7 +282,7 @@ static void get_all_symbols(std::set<symbol> &ss, symbol_sections_ctx *si, bool is_stripped(const char* path) { char command[256]; - snprintf(command, sizeof(command), "file %s", path); + // snprintf(command, sizeof(command), "file %s", path); FILE* fp = popen(command, "r"); if (fp == NULL) { @@ -298,38 +298,92 @@ bool is_stripped(const char* path) { } #define MAX_LINE_LENGTH 1024 -void get_symbol_from_elf_gdb(std::set<symbol> &ss, const char *path) { +void get_symbol_from_elf_gdb(std::set<symbol> &ss, const char *path, size_t file_base_addr = 0) +{ FILE *fp; char cmd[MAX_LINE_LENGTH]; char line[MAX_LINE_LENGTH]; // 构建 GDB 命令 - snprintf(cmd, sizeof(cmd), - "gdb -batch -ex \"file %s\" -ex \"info functions\"", path); + snprintf(cmd, sizeof(cmd), "gdb -batch -ex \"file %s\" -ex \"info functions\"", path); // 执行 GDB 命令并获取输出 fp = popen(cmd, "r"); - if (fp == NULL) { - perror("popen"); - return ; - } - - // 读取并解析 GDB 的输出 - while (fgets(line, sizeof(line), fp) != NULL) { - unsigned long address; - char name[MAX_LINE_LENGTH]; + if (fp == NULL) + { + perror("popen"); + return; + } - // 解析函数名和地址 - if (sscanf(line, "%lx %s", &address, name) == 2) { - printf("Name: %s, Address: %lx\n", name, address); + bool non_debugging_symbols = false; + std::map<unsigned long long, std::string> symbol_map; + + // 读取并解析 GDB 的输出 + while (fgets(line, sizeof(line), fp) != NULL) + { + unsigned long long address; + char name[MAX_LINE_LENGTH]; + // printf("line: %s", line); + if (!non_debugging_symbols) + { + if (strstr(line, "Non-debugging symbols:") != NULL) + { + non_debugging_symbols = true; + } + continue; + } + + char *token = strtok(line, " "); + if (token != NULL) + { + sscanf(token, "%llx", &address); + token = strtok(NULL, "\n"); + if (token != NULL) + { + strcpy(name, token); + } + // if name == ":", 跳过 + if (name[0] == ':') + { + continue; + } + symbol_map[address] = std::string(name); + } + // 解析函数名和地址 + // if (sscanf(line, "%llx %s", &address, name) == 2) + // { + // // if name == ":", 跳过 + // if (name[0] == ':') + // { + // continue; + // } + // // printf("Name %s, Address %llx\n", name, address); + // // name -> std::string + // symbol_map[address] = std::string(name); + // } } - } - // 关闭 GDB 进程 - pclose(fp); - // + symbol s; + + // 插入范围到新的map + auto it = symbol_map.begin(); + auto next_it = it; + ++next_it; + + for (; next_it != symbol_map.end(); ++it, ++next_it) + { + s.start = it->first - file_base_addr; + s.end = next_it->first - file_base_addr; + s.ip = s.start; + s.name = it->second; + // printf("gdb name: %s, start: 0x%lx, end: 0x%lx\n", s.name.c_str(), s.start, s.end); + ss.insert(s); + } + // 关闭 GDB 进程 + pclose(fp); + // } -bool get_symbol_from_elf(std::set<symbol> &ss, const char *path) { +bool get_symbol_from_elf(std::set<symbol> &ss, const char *path, size_t file_base_addr) { static int first_init = 0; if (!first_init) { @@ -340,12 +394,6 @@ bool get_symbol_from_elf(std::set<symbol> &ss, const char *path) { int is_reloc = 0; elf_version(EV_CURRENT); - // Check if the file attribute contains "stripped" - if (is_stripped(path)){ - get_symbol_from_elf_gdb(ss, path); - return true; - } - int fd = open(path, O_RDONLY); Elf *elf = elf_begin(fd, ELF_C_READ, NULL); // 指向elf文件的指针 @@ -432,7 +480,22 @@ bool get_symbol_from_elf(std::set<symbol> &ss, const char *path) { symbol_sections_ctx si; memset(&si, 0, sizeof(si)); if (symtab_sec) { - get_symbols_in_section(&si.symtab, elf, symtab_sec, &symtab_shdr, is_reloc); + get_symbols_in_section(&si.symtab, elf, symtab_sec, &symtab_shdr, is_reloc); + } else { + if (hdr.e_type != ET_DYN) { // no shared object + // is_reloc = 1; + // printf("stripped, path: %s\n", path); + get_symbol_from_elf_gdb(ss, path, file_base_addr); + return true; + } + + // Check if the file attribute contains "stripped" + // if (is_stripped(path)) + // { + // printf("stripped, path: %s\n", path); + // get_symbol_from_elf_gdb(ss, path); + // return true; + // } } if (dynsym_sec) { get_symbols_in_section(&si.symtab_in_dynsym, elf, dynsym_sec, &dynsym_shdr, |
