summaryrefslogtreecommitdiff
path: root/core/src/xmake/binutils/coff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-12-11 23:29:42 +0800
committerruki <[email protected]>2025-12-12 09:00:44 +0800
commit0b8a0363ed4c21be9795e0b6256d4f1dcd52d722 (patch)
tree2b392230511fe671dcdf8f9c583d1b1ae8bda167 /core/src/xmake/binutils/coff
parent2821dc7bf3ccee9b725697836ac97b4036e6eb24 (diff)
improve readsyms
Diffstat (limited to 'core/src/xmake/binutils/coff')
-rw-r--r--core/src/xmake/binutils/coff/prefix.h23
-rw-r--r--core/src/xmake/binutils/coff/readsyms.c64
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);