diff options
| author | ruki <[email protected]> | 2025-12-09 00:42:30 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2025-12-09 00:42:30 +0800 |
| commit | d48b2fcf37ed5c323d8e2d2d407bda9679dc01dc (patch) | |
| tree | ba79c8181226f0d2d7bd73154443fd58f64a4550 /core/src | |
| parent | 2ce4dfa1c8029498cfa6b99ed28daca6c2e350d4 (diff) | |
improve symbol dump
Diffstat (limited to 'core/src')
| -rw-r--r-- | core/src/xmake/binutils/coff/prefix.h | 60 | ||||
| -rw-r--r-- | core/src/xmake/binutils/coff/readsyms.c | 59 | ||||
| -rw-r--r-- | core/src/xmake/binutils/elf/readsyms.c | 40 | ||||
| -rw-r--r-- | core/src/xmake/binutils/macho/readsyms.c | 30 |
4 files changed, 87 insertions, 102 deletions
diff --git a/core/src/xmake/binutils/coff/prefix.h b/core/src/xmake/binutils/coff/prefix.h index ccc7f6292..1b1c2298e 100644 --- a/core/src/xmake/binutils/coff/prefix.h +++ b/core/src/xmake/binutils/coff/prefix.h @@ -34,6 +34,11 @@ #define XM_COFF_MACHINE_ARM 0x01c0 #define XM_COFF_MACHINE_ARM64 0xaa64 +// COFF section flags +#define XM_COFF_SCN_CNT_CODE 0x20 // IMAGE_SCN_CNT_CODE +#define XM_COFF_SCN_CNT_INITIALIZED_DATA 0x40 // IMAGE_SCN_CNT_INITIALIZED_DATA +#define XM_COFF_SCN_CNT_UNINITIALIZED_DATA 0x80 // IMAGE_SCN_CNT_UNINITIALIZED_DATA + #define XM_COFF_SECTION_RDATA 0x40000040 // IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ /* ////////////////////////////////////////////////////////////////////////////////////// @@ -178,14 +183,18 @@ static __tb_inline__ tb_void_t xm_binutils_coff_write_symbol_name(tb_stream_ref_ /* read string from COFF string table * * @param istream the input stream - * @param strtab_offset the string table offset - * @param offset the string offset (relative to string table content, after size field) + * @param strtab_offset the string table offset (including 4-byte size field) + * @param offset the string offset (from start of string table content, after size field) * @return the string (static buffer, valid until next call) */ static __tb_inline__ tb_bool_t xm_binutils_coff_read_string(tb_stream_ref_t istream, tb_uint32_t strtab_offset, tb_uint32_t offset, tb_char_t *name, tb_size_t name_size) { tb_assert_and_check_return_val(istream && name && name_size > 0, tb_false); - // read string table size + // In COFF format, the offset in symbol table is from the start of string table + // (including the 4-byte size field). So offset=4 points to the first string after + // the size field, offset=74 points to a string at position 74 from the start. + + // read string table size first to validate offset tb_uint32_t strtab_size = 0; tb_hize_t saved_pos = tb_stream_offset(istream); if (!tb_stream_seek(istream, strtab_offset)) { @@ -196,14 +205,17 @@ static __tb_inline__ tb_bool_t xm_binutils_coff_read_string(tb_stream_ref_t istr return tb_false; } - // check offset (offset is relative to start of string table, after the 4-byte size field) - if (offset >= strtab_size - 4) { + // check offset (must be >= 4 to skip the size field, and < strtab_size) + if (offset < 4 || offset >= strtab_size) { tb_stream_seek(istream, saved_pos); return tb_false; } - // seek to string position (offset is from start of string table content, after size field) - if (!tb_stream_seek(istream, strtab_offset + 4 + offset)) { + // seek to string position (offset is from start of string table, including size field) + // strtab_offset points to the start of string table (including 4-byte size field) + // offset is from the start of string table (including size field) + // So we use strtab_offset + offset directly + if (!tb_stream_seek(istream, strtab_offset + offset)) { tb_stream_seek(istream, saved_pos); return tb_false; } @@ -260,11 +272,13 @@ static __tb_inline__ tb_bool_t xm_binutils_coff_get_symbol_name(tb_stream_ref_t /* get symbol type character (nm-style) from COFF symbol * - * @param scl the storage class - * @param sect the section number (0 = undefined) - * @return the type character (T/t/D/d/B/b/U) + * @param scl the storage class + * @param sect the section number (0 = undefined, 1-based) + * @param sections the section headers array + * @param nsects the number of sections + * @return the type character (T/t/D/d/B/b/U) */ -static __tb_inline__ tb_char_t xm_binutils_coff_get_symbol_type_char(tb_uint8_t scl, tb_int16_t sect) { +static __tb_inline__ tb_char_t xm_binutils_coff_get_symbol_type_char(tb_uint8_t scl, tb_int16_t sect, xm_coff_section_t const *sections, tb_uint16_t nsects) { // undefined symbol if (sect == 0) { return 'U'; @@ -273,17 +287,33 @@ static __tb_inline__ tb_char_t xm_binutils_coff_get_symbol_type_char(tb_uint8_t // check if external tb_bool_t is_external = (scl == 2); // IMAGE_SYM_CLASS_EXTERNAL - // For COFF, section 1 is usually .text, section 2 is .data, section 3 is .bss - // This is a heuristic and may not be 100% accurate + // check section flags to determine type + if (sections && sect > 0 && sect <= nsects) { + tb_uint32_t flags = sections[sect - 1].flags; // section numbers are 1-based + // IMAGE_SCN_CNT_CODE (0x20) - code section + if (flags & XM_COFF_SCN_CNT_CODE) { + return is_external ? 'T' : 't'; // text section + } + // IMAGE_SCN_CNT_UNINITIALIZED_DATA (0x80) - bss section + if (flags & XM_COFF_SCN_CNT_UNINITIALIZED_DATA) { + return is_external ? 'B' : 'b'; // bss section + } + // IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) - data section + if (flags & XM_COFF_SCN_CNT_INITIALIZED_DATA) { + return is_external ? 'D' : 'd'; // data section + } + } + + // fallback: use section number heuristic if (sect == 1) { return is_external ? 'T' : 't'; // text section } else if (sect == 2) { return is_external ? 'D' : 'd'; // data section } else if (sect == 3) { return is_external ? 'B' : 'b'; // bss section - } else { - return is_external ? 'S' : 's'; // other section } + + return is_external ? 'S' : 's'; // other section } #endif diff --git a/core/src/xmake/binutils/coff/readsyms.c b/core/src/xmake/binutils/coff/readsyms.c index abe374367..9a10eba9d 100644 --- a/core/src/xmake/binutils/coff/readsyms.c +++ b/core/src/xmake/binutils/coff/readsyms.c @@ -58,8 +58,30 @@ tb_bool_t xm_binutils_coff_read_symbols(tb_stream_ref_t istream, lua_State *lua) // read string table offset (after symbol table) tb_uint32_t strtab_offset = header.symtabofs + header.nsyms * 18; // each symbol is 18 bytes + // read section headers to determine section types + xm_coff_section_t *sections = tb_null; + if (header.nsects > 0) { + sections = (xm_coff_section_t*)tb_malloc(header.nsects * sizeof(xm_coff_section_t)); + if (sections) { + tb_hize_t saved_pos = tb_stream_offset(istream); + // section headers are after COFF header and optional header + tb_uint32_t section_offset = sizeof(xm_coff_header_t) + (header.opthdr > 0 ? header.opthdr : 0); + if (tb_stream_seek(istream, section_offset)) { + for (tb_uint16_t i = 0; i < header.nsects; i++) { + if (!tb_stream_bread(istream, (tb_byte_t*)§ions[i], sizeof(xm_coff_section_t))) { + break; + } + } + } + tb_stream_seek(istream, saved_pos); + } + } + // read symbols if (!tb_stream_seek(istream, header.symtabofs)) { + if (sections) { + tb_free(sections); + } return tb_false; } @@ -84,7 +106,7 @@ tb_bool_t xm_binutils_coff_read_symbols(tb_stream_ref_t istream, lua_State *lua) } continue; } - + // skip internal symbols (starting with .) if (name[0] == '.') { sym_index++; @@ -96,6 +118,20 @@ tb_bool_t xm_binutils_coff_read_symbols(tb_stream_ref_t istream, lua_State *lua) continue; } + // skip compiler-generated symbols (containing $ or .constprop or .startup, etc.) + if (tb_strchr(name, '$') != tb_null || + tb_strstr(name, ".constprop") != tb_null || + tb_strstr(name, ".startup") != tb_null || + tb_strstr(name, "ta$") != tb_null) { + sym_index++; + if (sym.naux > 0) { + sym_index += sym.naux; // skip auxiliary entries + // skip auxiliary data + tb_stream_seek(istream, tb_stream_offset(istream) + sym.naux * 18); + } + continue; + } + // create symbol table entry lua_pushinteger(lua, sym_count + 1); lua_newtable(lua); @@ -105,28 +141,13 @@ tb_bool_t xm_binutils_coff_read_symbols(tb_stream_ref_t istream, lua_State *lua) lua_pushstring(lua, name); lua_settable(lua, -3); - // value - lua_pushstring(lua, "value"); - lua_pushinteger(lua, sym.value); - lua_settable(lua, -3); - - // section - lua_pushstring(lua, "section"); - lua_pushinteger(lua, sym.sect); - lua_settable(lua, -3); - // type (nm-style: T/t/D/d/B/b/U) - tb_char_t type_char = xm_binutils_coff_get_symbol_type_char(sym.scl, sym.sect); + tb_char_t type_char = xm_binutils_coff_get_symbol_type_char(sym.scl, sym.sect, sections, header.nsects); tb_char_t type_str[2] = {type_char, '\0'}; lua_pushstring(lua, "type"); lua_pushstring(lua, type_str); lua_settable(lua, -3); - // storage class - lua_pushstring(lua, "storage_class"); - lua_pushinteger(lua, sym.scl); - lua_settable(lua, -3); - lua_settable(lua, -3); sym_count++; @@ -142,5 +163,9 @@ tb_bool_t xm_binutils_coff_read_symbols(tb_stream_ref_t istream, lua_State *lua) } } + if (sections) { + tb_free(sections); + } + return tb_true; } diff --git a/core/src/xmake/binutils/elf/readsyms.c b/core/src/xmake/binutils/elf/readsyms.c index 1afc80fc6..6a9f333c7 100644 --- a/core/src/xmake/binutils/elf/readsyms.c +++ b/core/src/xmake/binutils/elf/readsyms.c @@ -143,21 +143,6 @@ tb_bool_t xm_binutils_elf_read_symbols_32(tb_stream_ref_t istream, lua_State *lu lua_pushstring(lua, name); lua_settable(lua, -3); - // value - lua_pushstring(lua, "value"); - lua_pushinteger(lua, sym.st_value); - lua_settable(lua, -3); - - // size - lua_pushstring(lua, "size"); - lua_pushinteger(lua, sym.st_size); - lua_settable(lua, -3); - - // section - lua_pushstring(lua, "section"); - lua_pushinteger(lua, sym.st_shndx); - lua_settable(lua, -3); - // type (nm-style: T/t/D/d/B/b/U) tb_char_t type_char = xm_binutils_elf_get_symbol_type_char(sym.st_info, sym.st_shndx); tb_char_t type_str[2] = {type_char, '\0'}; @@ -165,11 +150,6 @@ tb_bool_t xm_binutils_elf_read_symbols_32(tb_stream_ref_t istream, lua_State *lu lua_pushstring(lua, type_str); lua_settable(lua, -3); - // bind - lua_pushstring(lua, "bind"); - lua_pushstring(lua, xm_binutils_elf_get_symbol_bind(sym.st_info)); - lua_settable(lua, -3); - lua_settable(lua, -3); result_count++; } @@ -284,21 +264,6 @@ tb_bool_t xm_binutils_elf_read_symbols_64(tb_stream_ref_t istream, lua_State *lu lua_pushstring(lua, name); lua_settable(lua, -3); - // value - lua_pushstring(lua, "value"); - lua_pushinteger(lua, sym.st_value); - lua_settable(lua, -3); - - // size - lua_pushstring(lua, "size"); - lua_pushinteger(lua, sym.st_size); - lua_settable(lua, -3); - - // section - lua_pushstring(lua, "section"); - lua_pushinteger(lua, sym.st_shndx); - lua_settable(lua, -3); - // type (nm-style: T/t/D/d/B/b/U) tb_char_t type_char = xm_binutils_elf_get_symbol_type_char(sym.st_info, sym.st_shndx); tb_char_t type_str[2] = {type_char, '\0'}; @@ -306,11 +271,6 @@ tb_bool_t xm_binutils_elf_read_symbols_64(tb_stream_ref_t istream, lua_State *lu lua_pushstring(lua, type_str); lua_settable(lua, -3); - // bind - lua_pushstring(lua, "bind"); - lua_pushstring(lua, xm_binutils_elf_get_symbol_bind(sym.st_info)); - lua_settable(lua, -3); - lua_settable(lua, -3); result_count++; } diff --git a/core/src/xmake/binutils/macho/readsyms.c b/core/src/xmake/binutils/macho/readsyms.c index 62596c45e..dbe7925a4 100644 --- a/core/src/xmake/binutils/macho/readsyms.c +++ b/core/src/xmake/binutils/macho/readsyms.c @@ -124,16 +124,6 @@ tb_bool_t xm_binutils_macho_read_symbols_32(tb_stream_ref_t istream, lua_State * lua_pushstring(lua, name); lua_settable(lua, -3); - // value - lua_pushstring(lua, "value"); - lua_pushinteger(lua, nlist.value); - lua_settable(lua, -3); - - // section - lua_pushstring(lua, "section"); - lua_pushinteger(lua, nlist.sect); - lua_settable(lua, -3); - // type (nm-style: T/t/D/d/B/b/U) tb_char_t type_char = xm_binutils_macho_get_symbol_type_char(nlist.type, nlist.sect); tb_char_t type_str[2] = {type_char, '\0'}; @@ -141,11 +131,6 @@ tb_bool_t xm_binutils_macho_read_symbols_32(tb_stream_ref_t istream, lua_State * lua_pushstring(lua, type_str); lua_settable(lua, -3); - // bind - lua_pushstring(lua, "bind"); - lua_pushstring(lua, xm_binutils_macho_get_symbol_bind(nlist.type)); - lua_settable(lua, -3); - lua_settable(lua, -3); result_count++; } @@ -243,16 +228,6 @@ tb_bool_t xm_binutils_macho_read_symbols_64(tb_stream_ref_t istream, lua_State * lua_pushstring(lua, name); lua_settable(lua, -3); - // value - lua_pushstring(lua, "value"); - lua_pushinteger(lua, nlist.value); - lua_settable(lua, -3); - - // section - lua_pushstring(lua, "section"); - lua_pushinteger(lua, nlist.sect); - lua_settable(lua, -3); - // type (nm-style: T/t/D/d/B/b/U) tb_char_t type_char = xm_binutils_macho_get_symbol_type_char(nlist.type, nlist.sect); tb_char_t type_str[2] = {type_char, '\0'}; @@ -260,11 +235,6 @@ tb_bool_t xm_binutils_macho_read_symbols_64(tb_stream_ref_t istream, lua_State * lua_pushstring(lua, type_str); lua_settable(lua, -3); - // bind - lua_pushstring(lua, "bind"); - lua_pushstring(lua, xm_binutils_macho_get_symbol_bind(nlist.type)); - lua_settable(lua, -3); - lua_settable(lua, -3); result_count++; } |
