summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorruki <[email protected]>2025-12-09 00:42:30 +0800
committerruki <[email protected]>2025-12-09 00:42:30 +0800
commitd48b2fcf37ed5c323d8e2d2d407bda9679dc01dc (patch)
treeba79c8181226f0d2d7bd73154443fd58f64a4550 /core
parent2ce4dfa1c8029498cfa6b99ed28daca6c2e350d4 (diff)
improve symbol dump
Diffstat (limited to 'core')
-rw-r--r--core/src/xmake/binutils/coff/prefix.h60
-rw-r--r--core/src/xmake/binutils/coff/readsyms.c59
-rw-r--r--core/src/xmake/binutils/elf/readsyms.c40
-rw-r--r--core/src/xmake/binutils/macho/readsyms.c30
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*)&sections[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++;
}