diff options
| author | ruki <[email protected]> | 2026-02-12 00:55:56 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2026-02-12 00:55:56 +0800 |
| commit | b445dc4e25b5acceacaabcea627fba3703050e15 (patch) | |
| tree | a91b74bd762e157bf9566faa783154655f9563fe | |
| parent | af7720f0b49e91bae20648f49133c6eef8f9e003 (diff) | |
improve readsyms for wasm/.a
| -rw-r--r-- | core/src/xmake/binutils/ar/prefix.h | 14 | ||||
| -rw-r--r-- | core/src/xmake/binutils/ar/readsyms.c | 28 | ||||
| -rw-r--r-- | tests/modules/binutils/test.lua | 34 |
3 files changed, 75 insertions, 1 deletions
diff --git a/core/src/xmake/binutils/ar/prefix.h b/core/src/xmake/binutils/ar/prefix.h index 53df74e5d..c474eefa6 100644 --- a/core/src/xmake/binutils/ar/prefix.h +++ b/core/src/xmake/binutils/ar/prefix.h @@ -28,6 +28,7 @@ #include "../coff/prefix.h" #include "../elf/prefix.h" #include "../macho/prefix.h" +#include "../wasm/prefix.h" /* ////////////////////////////////////////////////////////////////////////////////////// * forward declarations @@ -35,6 +36,7 @@ extern tb_bool_t xm_binutils_coff_read_symbols(tb_stream_ref_t istream, tb_hize_t base_offset, lua_State *lua); extern tb_bool_t xm_binutils_elf_read_symbols(tb_stream_ref_t istream, tb_hize_t base_offset, lua_State *lua); extern tb_bool_t xm_binutils_macho_read_symbols(tb_stream_ref_t istream, tb_hize_t base_offset, lua_State *lua); +extern tb_bool_t xm_binutils_wasm_read_symbols(tb_stream_ref_t istream, tb_hize_t base_offset, lua_State *lua); /* ////////////////////////////////////////////////////////////////////////////////////// * types @@ -157,6 +159,18 @@ static __tb_inline__ tb_bool_t xm_binutils_ar_get_member_name(tb_stream_ref_t is } } + if (header->name[0] == '/') { + if (header->name[1] == '/') { + tb_strlcpy(name, "//", name_size); + *name_len = 2; + } else { + tb_strlcpy(name, "/", name_size); + *name_len = 1; + } + *bytes_read = 0; + return tb_true; + } + // regular name (null-terminated or space-padded) tb_size_t i = 0; for (i = 0; i < 16 && i < name_size - 1; i++) { diff --git a/core/src/xmake/binutils/ar/readsyms.c b/core/src/xmake/binutils/ar/readsyms.c index 1a0d3b540..3af3f8a62 100644 --- a/core/src/xmake/binutils/ar/readsyms.c +++ b/core/src/xmake/binutils/ar/readsyms.c @@ -30,6 +30,30 @@ /* ////////////////////////////////////////////////////////////////////////////////////// * implementation */ +static tb_int_t xm_binutils_ar_detect_member_format(tb_stream_ref_t istream, tb_hize_t base_offset) { + tb_uint8_t magic[8] = {0}; + if (!tb_stream_seek(istream, base_offset)) { + return -1; + } + if (!tb_stream_bread(istream, magic, 8)) { + tb_stream_seek(istream, base_offset); + return -1; + } + tb_stream_seek(istream, base_offset); + + if (magic[0] == 0x00 && magic[1] == 0x61 && magic[2] == 0x73 && magic[3] == 0x6d) { + return XM_BINUTILS_FORMAT_WASM; + } + if (magic[0] == 0x7f && magic[1] == 'E' && magic[2] == 'L' && magic[3] == 'F') { + return XM_BINUTILS_FORMAT_ELF; + } + if ((magic[0] == 0xfe && magic[1] == 0xed && magic[2] == 0xfa && (magic[3] == 0xce || magic[3] == 0xcf)) || + (magic[0] == 0xce && magic[1] == 0xfa && magic[2] == 0xed && magic[3] == 0xfe) || + (magic[0] == 0xcf && magic[1] == 0xfa && magic[2] == 0xed && magic[3] == 0xfe)) { + return XM_BINUTILS_FORMAT_MACHO; + } + return XM_BINUTILS_FORMAT_UNKNOWN; +} /* parse BSD symbol table (__.SYMDEF or __.SYMDEF SORTED) * @@ -346,7 +370,7 @@ tb_bool_t xm_binutils_ar_read_symbols(tb_stream_ref_t istream, tb_hize_t base_of tb_hize_t current_pos = tb_stream_offset(istream); // detect format - tb_int_t format = xm_binutils_format_detect(istream); + tb_int_t format = xm_binutils_ar_detect_member_format(istream, current_pos); if (format != XM_BINUTILS_FORMAT_AR) { // create entry table lua_newtable(lua); @@ -365,6 +389,8 @@ tb_bool_t xm_binutils_ar_read_symbols(tb_stream_ref_t istream, tb_hize_t base_of read_ok = xm_binutils_elf_read_symbols(istream, current_pos, lua); } else if (format == XM_BINUTILS_FORMAT_MACHO) { read_ok = xm_binutils_macho_read_symbols(istream, current_pos, lua); + } else if (format == XM_BINUTILS_FORMAT_WASM) { + read_ok = xm_binutils_wasm_read_symbols(istream, current_pos, lua); } if (!read_ok) { diff --git a/tests/modules/binutils/test.lua b/tests/modules/binutils/test.lua index 319a197e6..964e84ed2 100644 --- a/tests/modules/binutils/test.lua +++ b/tests/modules/binutils/test.lua @@ -141,5 +141,39 @@ function test_readsyms(t) t:are_equal(resultslink[1].symbols[1].name, "add") t:are_equal(resultslink[1].symbols[1].type, "T") + local wasmar = path.join(tempdir, "libbar.a") + local function _pad(str, n) + if #str < n then + return str .. string.rep(" ", n - #str) + end + return str:sub(1, n) + end + local function _ar_header(name, size) + return _pad(name, 16) .. + _pad("0", 12) .. + _pad("0", 6) .. + _pad("0", 6) .. + _pad("644", 8) .. + _pad(tostring(size), 10) .. + "`\n" + end + local wasmobj = string.char( + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x04, 0x01, 0x60, 0x00, 0x00, + 0x03, 0x02, 0x01, 0x00, + 0x0a, 0x04, 0x01, 0x02, 0x00, 0x0b, + 0x00, 0x13, 0x07, 0x6c, 0x69, 0x6e, 0x6b, 0x69, 0x6e, 0x67, 0x02, 0x08, 0x08, 0x01, 0x00, 0x00, 0x00, 0x03, 0x61, 0x64, 0x64) + local symtab = string.char(0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50) .. "add\0" + local ardata = "!<arch>\n" .. + _ar_header("/", #symtab) .. symtab .. ((#symtab % 2 == 1) and "\n" or "") .. + _ar_header("foo.cpp.o/", #wasmobj) .. wasmobj .. ((#wasmobj % 2 == 1) and "\n" or "") + io.writefile(wasmar, ardata) + local resultsar = binutils.readsyms(wasmar) + t:are_equal(#resultsar, 1) + t:are_equal(resultsar[1].objectfile, "foo.cpp.o") + t:are_equal(#resultsar[1].symbols, 1) + t:are_equal(resultsar[1].symbols[1].name, "add") + t:are_equal(resultsar[1].symbols[1].type, "T") + os.tryrm(tempdir) end |
