diff options
Diffstat (limited to 'source/ucli/elf.cc')
| -rw-r--r-- | source/ucli/elf.cc | 208 |
1 files changed, 96 insertions, 112 deletions
diff --git a/source/ucli/elf.cc b/source/ucli/elf.cc index 3f64a99..4bce21d 100644 --- a/source/ucli/elf.cc +++ b/source/ucli/elf.cc @@ -1,8 +1,8 @@ #include "elf.h" #include <elf.h> -#include <fcntl.h> // for open -#include <gelf.h> // for GElf_Ehdr +#include <fcntl.h> // for open +#include <gelf.h> // for GElf_Ehdr #include <libelf.h> #include <string.h> #include <sys/utsname.h> @@ -88,7 +88,8 @@ static int get_symbols_in_section(sym_section_ctx *sym, Elf *elf, Elf_Scn *sec, return -1; } - sym->sym_count = shdr->sh_size / shdr->sh_entsize; // 获取section中的symbol数量 + sym->sym_count = + shdr->sh_size / shdr->sh_entsize; // 获取section中的symbol数量 sym->is_plt = 0; sym->is_reloc = is_reloc; // 是否是可重定位文件 @@ -120,7 +121,8 @@ static int get_plt_symbols_in_section(sym_section_ctx *sym, Elf *elf, sym->is_plt = 1; sym->plt_entsize = plt->plt.hdr->sh_type; sym->plt_offset = plt->plt.hdr->sh_offset; - sym->sym_count = plt->plt_rel.hdr->sh_size / plt->plt_rel.hdr->sh_entsize; // 获取section中的symbol数量 + sym->sym_count = plt->plt_rel.hdr->sh_size / + plt->plt_rel.hdr->sh_entsize; // 获取section中的symbol数量 sym->plt_rel_type = plt->plt_rel.hdr->sh_type; return 0; @@ -163,7 +165,8 @@ 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: 0x%lx, end: 0x%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 +223,8 @@ 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("plt name: %s, start: 0x%lx, end: 0x%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); } } @@ -235,7 +239,8 @@ static void get_all_symbols(std::set<symbol> &ss, symbol_sections_ctx *si, // Dwarf_Off die_offset = 0, next_offset; // size_t header_size; // printf("1\n"); -// while (dwarf_nextcu(dw, die_offset, &next_offset, &header_size, NULL, NULL, NULL) == 0) { +// while (dwarf_nextcu(dw, die_offset, &next_offset, &header_size, NULL, NULL, +// NULL) == 0) { // printf("2\n"); // Dwarf_Die cudie; // printf("3\n"); @@ -280,11 +285,11 @@ static void get_all_symbols(std::set<symbol> &ss, symbol_sections_ctx *si, // } // } -bool is_stripped(const char* path) { +bool is_stripped(const char *path) { char command[256]; // snprintf(command, sizeof(command), "file %s", path); - FILE* fp = popen(command, "r"); + FILE *fp = popen(command, "r"); if (fp == NULL) { // handle error return false; @@ -298,92 +303,87 @@ bool is_stripped(const char* path) { } #define MAX_LINE_LENGTH 1024 -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); - - // 执行 GDB 命令并获取输出 - fp = popen(cmd, "r"); - if (fp == NULL) - { - perror("popen"); - return; - } +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); + + // 执行 GDB 命令并获取输出 + fp = popen(cmd, "r"); + if (fp == NULL) { + perror("popen"); + return; + } - 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); - // } + 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; } - 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); + 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); } - // 关闭 GDB 进程 - pclose(fp); - // + // 解析函数名和地址 + // 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); + // } + } + + 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, size_t file_base_addr) { +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) { @@ -450,7 +450,7 @@ bool get_symbol_from_elf(std::set<symbol> &ss, const char *path, size_t file_bas if (str && strcmp(".symtab", str) == 0) { // .symtab section symtab_sec = sec; - memcpy(&symtab_shdr, &shdr, sizeof(dynsym_shdr)); + memcpy(&symtab_shdr, &shdr, sizeof(dynsym_shdr)); } if (str && strcmp(".dynsym", str) == 0) { // .dynsym section dynsym_sec = sec; @@ -480,22 +480,13 @@ bool get_symbol_from_elf(std::set<symbol> &ss, const char *path, size_t file_bas 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 (hdr.e_type != ET_DYN) { // no shared object + // printf("stripped, path: %s\n", path); + get_symbol_from_elf_gdb(ss, path, file_base_addr); + return true; + } } if (dynsym_sec) { get_symbols_in_section(&si.symtab_in_dynsym, elf, dynsym_sec, &dynsym_shdr, @@ -508,13 +499,6 @@ bool get_symbol_from_elf(std::set<symbol> &ss, const char *path, size_t file_bas get_all_symbols(ss, &si, elf); elf_end(elf); - // After getting all symbols from .symtab and .dynsym - // Dwarf *dw = dwarf_begin(fd, DWARF_C_READ); - // if (dw) { - // get_debug_symbols(ss, dw); - // dwarf_end(dw); - // } - close(fd); return true; }
\ No newline at end of file |
