diff options
| author | ruki <[email protected]> | 2025-12-11 23:29:42 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2025-12-12 09:00:44 +0800 |
| commit | 0b8a0363ed4c21be9795e0b6256d4f1dcd52d722 (patch) | |
| tree | 2b392230511fe671dcdf8f9c583d1b1ae8bda167 /core/src/xmake/binutils/coff | |
| parent | 2821dc7bf3ccee9b725697836ac97b4036e6eb24 (diff) | |
improve readsyms
Diffstat (limited to 'core/src/xmake/binutils/coff')
| -rw-r--r-- | core/src/xmake/binutils/coff/prefix.h | 23 | ||||
| -rw-r--r-- | core/src/xmake/binutils/coff/readsyms.c | 64 |
2 files changed, 87 insertions, 0 deletions
diff --git a/core/src/xmake/binutils/coff/prefix.h b/core/src/xmake/binutils/coff/prefix.h index 587d724df..19ae9bc7b 100644 --- a/core/src/xmake/binutils/coff/prefix.h +++ b/core/src/xmake/binutils/coff/prefix.h @@ -55,6 +55,29 @@ typedef struct __xm_coff_header_t { tb_uint16_t flags; } __tb_packed__ xm_coff_header_t; +typedef struct __xm_coff_import_header_t { + tb_uint16_t sig1; // 0 + tb_uint16_t sig2; // 0xffff + tb_uint16_t version; + tb_uint16_t machine; + tb_uint32_t time; + tb_uint32_t size; // size of data + tb_uint16_t ordinal; // ordinal or hint + tb_uint16_t type; // type +} __tb_packed__ xm_coff_import_header_t; + +typedef struct __xm_coff_anon_header_t { + tb_uint16_t sig1; // 0 + tb_uint16_t sig2; // 0xffff + tb_uint16_t version; + tb_uint16_t machine; + tb_uint32_t time; + tb_uint8_t clsid[16]; + tb_uint32_t size; // size of data +} __tb_packed__ xm_coff_anon_header_t; + + + typedef struct __xm_coff_section_t { tb_char_t name[8]; tb_uint32_t vsize; diff --git a/core/src/xmake/binutils/coff/readsyms.c b/core/src/xmake/binutils/coff/readsyms.c index 41ca5ee47..5fac470e2 100644 --- a/core/src/xmake/binutils/coff/readsyms.c +++ b/core/src/xmake/binutils/coff/readsyms.c @@ -46,6 +46,70 @@ tb_bool_t xm_binutils_coff_read_symbols(tb_stream_ref_t istream, lua_State *lua) return tb_false; } + // check if it is an import object + if (header.machine == 0 && header.nsects == 0xffff) { + // create result table + lua_newtable(lua); + + // check version + // version is the low 16 bits of the time field (offset 4) + // xm_coff_header_t: machine(2), nsects(2), time(4) + // xm_coff_import_header_t: sig1(2), sig2(2), version(2), machine(2) + tb_uint16_t version = header.time & 0xffff; + if (version == 1) { + // anonymous object header (used for CLSID) + xm_coff_anon_header_t anon_header; + if (!tb_stream_seek(istream, 0)) { + return tb_false; + } + if (!tb_stream_bread(istream, (tb_byte_t*)&anon_header, sizeof(anon_header))) { + return tb_false; + } + } else { + // import header + xm_coff_import_header_t import_header; + if (!tb_stream_seek(istream, 0)) { + return tb_false; + } + if (!tb_stream_bread(istream, (tb_byte_t*)&import_header, sizeof(import_header))) { + return tb_false; + } + } + + // read symbol name (it follows the header) + tb_char_t name[256] = {0}; + tb_size_t pos = 0; + tb_byte_t c; + while (pos < sizeof(name) - 1) { + if (!tb_stream_bread(istream, &c, 1)) { + break; + } + if (c == 0) { + break; + } + name[pos++] = (tb_char_t)c; + } + name[pos] = '\0'; + + if (name[0]) { + lua_pushinteger(lua, 1); + lua_newtable(lua); + + // name + lua_pushstring(lua, "name"); + lua_pushstring(lua, name); + lua_settable(lua, -3); + + // type + lua_pushstring(lua, "type"); + lua_pushstring(lua, "I"); + lua_settable(lua, -3); + + lua_settable(lua, -3); + } + return tb_true; + } + // check if there are symbols if (header.nsyms == 0 || header.symtabofs == 0) { lua_newtable(lua); |
