diff options
| author | ruki <[email protected]> | 2025-12-09 00:36:15 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2025-12-09 00:36:15 +0800 |
| commit | 2ce4dfa1c8029498cfa6b99ed28daca6c2e350d4 (patch) | |
| tree | f9039bb89eb1fcc98924d495e2dc1e6e305ef0ee /core/src | |
| parent | 333af0b66dfe73fabb2c900bce00ba2d50bfe622 (diff) | |
improve symbol type
Diffstat (limited to 'core/src')
| -rw-r--r-- | core/src/xmake/binutils/coff/prefix.h | 35 | ||||
| -rw-r--r-- | core/src/xmake/binutils/coff/readsyms.c | 17 | ||||
| -rw-r--r-- | core/src/xmake/binutils/elf/prefix.h | 36 | ||||
| -rw-r--r-- | core/src/xmake/binutils/elf/readsyms.c | 34 | ||||
| -rw-r--r-- | core/src/xmake/binutils/macho/prefix.h | 38 | ||||
| -rw-r--r-- | core/src/xmake/binutils/macho/readsyms.c | 22 |
6 files changed, 142 insertions, 40 deletions
diff --git a/core/src/xmake/binutils/coff/prefix.h b/core/src/xmake/binutils/coff/prefix.h index 95737dc20..ccc7f6292 100644 --- a/core/src/xmake/binutils/coff/prefix.h +++ b/core/src/xmake/binutils/coff/prefix.h @@ -258,20 +258,31 @@ static __tb_inline__ tb_bool_t xm_binutils_coff_get_symbol_name(tb_stream_ref_t } } -/* get symbol type string from storage class +/* get symbol type character (nm-style) from COFF symbol * - * @param scl the storage class - * @return the type string + * @param scl the storage class + * @param sect the section number (0 = undefined) + * @return the type character (T/t/D/d/B/b/U) */ -static __tb_inline__ tb_char_t const *xm_binutils_coff_get_symbol_type(tb_uint8_t scl) { - // IMAGE_SYM_CLASS_EXTERNAL = 2 - // IMAGE_SYM_CLASS_STATIC = 3 - // IMAGE_SYM_CLASS_LABEL = 6 - switch (scl) { - case 2: return "external"; - case 3: return "static"; - case 6: return "label"; - default: return "unknown"; +static __tb_inline__ tb_char_t xm_binutils_coff_get_symbol_type_char(tb_uint8_t scl, tb_int16_t sect) { + // undefined symbol + if (sect == 0) { + return 'U'; + } + + // 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 + 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 } } diff --git a/core/src/xmake/binutils/coff/readsyms.c b/core/src/xmake/binutils/coff/readsyms.c index d863c2fdf..abe374367 100644 --- a/core/src/xmake/binutils/coff/readsyms.c +++ b/core/src/xmake/binutils/coff/readsyms.c @@ -84,6 +84,17 @@ 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++; + 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); @@ -104,9 +115,11 @@ tb_bool_t xm_binutils_coff_read_symbols(tb_stream_ref_t istream, lua_State *lua) lua_pushinteger(lua, sym.sect); lua_settable(lua, -3); - // type + // 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_str[2] = {type_char, '\0'}; lua_pushstring(lua, "type"); - lua_pushstring(lua, xm_binutils_coff_get_symbol_type(sym.scl)); + lua_pushstring(lua, type_str); lua_settable(lua, -3); // storage class diff --git a/core/src/xmake/binutils/elf/prefix.h b/core/src/xmake/binutils/elf/prefix.h index 97d05a661..7ddc0ef85 100644 --- a/core/src/xmake/binutils/elf/prefix.h +++ b/core/src/xmake/binutils/elf/prefix.h @@ -303,21 +303,35 @@ static __tb_inline__ tb_bool_t xm_binutils_elf_read_string(tb_stream_ref_t istre return tb_true; } -/* get symbol type string from ELF symbol info +/* get symbol type character (nm-style) from ELF symbol * - * @param st_info the symbol info byte - * @return the type string + * @param st_info the symbol info byte + * @param st_shndx the section index (0 = undefined) + * @return the type character (T/t/D/d/B/b/U) */ -static __tb_inline__ tb_char_t const *xm_binutils_elf_get_symbol_type(tb_uint8_t st_info) { +static __tb_inline__ tb_char_t xm_binutils_elf_get_symbol_type_char(tb_uint8_t st_info, tb_uint16_t st_shndx) { + // undefined symbol + if (st_shndx == 0) { + return 'U'; + } + + // check bind (global = uppercase, local = lowercase) + tb_uint8_t bind = (st_info >> 4) & 0xf; + tb_bool_t is_global = (bind == 1); // STB_GLOBAL + + // check type tb_uint8_t type = st_info & 0xf; - switch (type) { - case 0: return "notype"; - case 1: return "object"; - case 2: return "func"; - case 3: return "section"; - case 4: return "file"; - default: return "unknown"; + if (type == 2) { // STT_FUNC + return is_global ? 'T' : 't'; // text (function) + } else if (type == 1) { // STT_OBJECT + // For object symbols, we need section info to determine data/bss + // For simplicity, we'll use 'D' for data, 'B' for bss + // This is a heuristic - in practice, we'd need to check section flags + return is_global ? 'D' : 'd'; // data (assume data section) } + + // other types + return is_global ? 'S' : 's'; // other section } /* get symbol bind string from ELF symbol info diff --git a/core/src/xmake/binutils/elf/readsyms.c b/core/src/xmake/binutils/elf/readsyms.c index 06c17a697..1afc80fc6 100644 --- a/core/src/xmake/binutils/elf/readsyms.c +++ b/core/src/xmake/binutils/elf/readsyms.c @@ -117,11 +117,22 @@ tb_bool_t xm_binutils_elf_read_symbols_32(tb_stream_ref_t istream, lua_State *lu continue; } + // skip section and file symbols + tb_uint8_t type = sym.st_info & 0xf; + if (type == 3 || type == 4) { // STT_SECTION or STT_FILE + continue; + } + // get symbol name tb_char_t name[256]; if (!xm_binutils_elf_read_string(istream, strtab_section.sh_offset, sym.st_name, name, sizeof(name)) || !name[0]) { continue; } + + // skip internal symbols (starting with .) + if (name[0] == '.') { + continue; + } // create symbol table entry lua_pushinteger(lua, result_count + 1); @@ -147,9 +158,11 @@ tb_bool_t xm_binutils_elf_read_symbols_32(tb_stream_ref_t istream, lua_State *lu lua_pushinteger(lua, sym.st_shndx); lua_settable(lua, -3); - // type + // 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'}; lua_pushstring(lua, "type"); - lua_pushstring(lua, xm_binutils_elf_get_symbol_type(sym.st_info)); + lua_pushstring(lua, type_str); lua_settable(lua, -3); // bind @@ -245,11 +258,22 @@ tb_bool_t xm_binutils_elf_read_symbols_64(tb_stream_ref_t istream, lua_State *lu continue; } + // skip section and file symbols + tb_uint8_t type = sym.st_info & 0xf; + if (type == 3 || type == 4) { // STT_SECTION or STT_FILE + continue; + } + // get symbol name tb_char_t name[256]; if (!xm_binutils_elf_read_string(istream, strtab_section.sh_offset, sym.st_name, name, sizeof(name)) || !name[0]) { continue; } + + // skip internal symbols (starting with .) + if (name[0] == '.') { + continue; + } // create symbol table entry lua_pushinteger(lua, result_count + 1); @@ -275,9 +299,11 @@ tb_bool_t xm_binutils_elf_read_symbols_64(tb_stream_ref_t istream, lua_State *lu lua_pushinteger(lua, sym.st_shndx); lua_settable(lua, -3); - // type + // 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'}; lua_pushstring(lua, "type"); - lua_pushstring(lua, xm_binutils_elf_get_symbol_type(sym.st_info)); + lua_pushstring(lua, type_str); lua_settable(lua, -3); // bind diff --git a/core/src/xmake/binutils/macho/prefix.h b/core/src/xmake/binutils/macho/prefix.h index 39ac857f1..7664940b1 100644 --- a/core/src/xmake/binutils/macho/prefix.h +++ b/core/src/xmake/binutils/macho/prefix.h @@ -358,17 +358,41 @@ static __tb_inline__ tb_bool_t xm_binutils_macho_read_string(tb_stream_ref_t ist return tb_true; } -/* get symbol type string from Mach-O symbol type +/* get symbol type character (nm-style) from Mach-O symbol * - * @param type the symbol type byte - * @return the type string + * @param type the symbol type byte + * @param sect the section number (0 = undefined) + * @return the type character (T/t/D/d/B/b/U) */ -static __tb_inline__ tb_char_t const *xm_binutils_macho_get_symbol_type(tb_uint8_t type) { +static __tb_inline__ tb_char_t xm_binutils_macho_get_symbol_type_char(tb_uint8_t type, tb_uint8_t sect) { + // undefined symbol + if (sect == 0) { + return 'U'; + } + + // check if external + tb_bool_t is_external = (type & XM_MACHO_N_EXT) != 0; + + // check if in section tb_uint8_t n_type = type & XM_MACHO_N_TYPE_MASK; - switch (n_type) { - case XM_MACHO_N_TYPE_SECT: return "section"; - default: return "unknown"; + if (n_type == XM_MACHO_N_TYPE_SECT) { + // section 1 is usually __TEXT,__text (text) + // section 2 is usually __DATA,__data (data) + // section 3 is usually __DATA,__bss (bss) + // For simplicity, we'll use section number to determine type + // This is a heuristic and may not be 100% accurate + 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 '?'; // unknown } /* get symbol bind string from Mach-O symbol type diff --git a/core/src/xmake/binutils/macho/readsyms.c b/core/src/xmake/binutils/macho/readsyms.c index a78daaa5a..62596c45e 100644 --- a/core/src/xmake/binutils/macho/readsyms.c +++ b/core/src/xmake/binutils/macho/readsyms.c @@ -110,6 +110,11 @@ tb_bool_t xm_binutils_macho_read_symbols_32(tb_stream_ref_t istream, lua_State * continue; } + // skip internal symbols (starting with .) + if (name[0] == '.') { + continue; + } + // create symbol table entry lua_pushinteger(lua, result_count + 1); lua_newtable(lua); @@ -129,9 +134,11 @@ tb_bool_t xm_binutils_macho_read_symbols_32(tb_stream_ref_t istream, lua_State * lua_pushinteger(lua, nlist.sect); lua_settable(lua, -3); - // type + // 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'}; lua_pushstring(lua, "type"); - lua_pushstring(lua, xm_binutils_macho_get_symbol_type(nlist.type)); + lua_pushstring(lua, type_str); lua_settable(lua, -3); // bind @@ -222,6 +229,11 @@ tb_bool_t xm_binutils_macho_read_symbols_64(tb_stream_ref_t istream, lua_State * continue; } + // skip internal symbols (starting with .) + if (name[0] == '.') { + continue; + } + // create symbol table entry lua_pushinteger(lua, result_count + 1); lua_newtable(lua); @@ -241,9 +253,11 @@ tb_bool_t xm_binutils_macho_read_symbols_64(tb_stream_ref_t istream, lua_State * lua_pushinteger(lua, nlist.sect); lua_settable(lua, -3); - // type + // 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'}; lua_pushstring(lua, "type"); - lua_pushstring(lua, xm_binutils_macho_get_symbol_type(nlist.type)); + lua_pushstring(lua, type_str); lua_settable(lua, -3); // bind |
