diff options
| author | ruki <[email protected]> | 2025-12-12 23:43:40 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2025-12-12 23:43:40 +0800 |
| commit | 0865857ff1d5635bcf9f7e40409493b2f1e4837a (patch) | |
| tree | c7f09e937c7ea8e5a209d6e0b136b4d2f11d7acd /core/src | |
| parent | 9d8252cafb476466b9192562326b7a6ea9987b7c (diff) | |
format codes
Diffstat (limited to 'core/src')
| -rw-r--r-- | core/src/xmake/binutils/coff/deplibs.c | 118 | ||||
| -rw-r--r-- | core/src/xmake/binutils/coff/prefix.h | 28 | ||||
| -rw-r--r-- | core/src/xmake/binutils/elf/prefix.h | 71 | ||||
| -rw-r--r-- | core/src/xmake/binutils/prefix.h | 89 |
4 files changed, 150 insertions, 156 deletions
diff --git a/core/src/xmake/binutils/coff/deplibs.c b/core/src/xmake/binutils/coff/deplibs.c index 6ff0f742d..44809a535 100644 --- a/core/src/xmake/binutils/coff/deplibs.c +++ b/core/src/xmake/binutils/coff/deplibs.c @@ -60,27 +60,29 @@ tb_bool_t xm_binutils_coff_deplibs(tb_stream_ref_t istream, tb_hize_t base_offse if (header.opthdr > 0) { // save pos tb_hize_t saved_pos = tb_stream_offset(istream); - + // seek to optional header if (tb_stream_seek(istream, base_offset + sizeof(xm_coff_header_t))) { tb_uint16_t magic = 0; if (tb_stream_bread(istream, (tb_byte_t*)&magic, 2)) { // magic is little endian magic = tb_bits_le_to_ne_u16(magic); - + tb_uint32_t data_dir_offset = 0; if (magic == XM_PE32_MAGIC) { data_dir_offset = 96; } else if (magic == XM_PE32P_MAGIC) { data_dir_offset = 112; } - - // check if optional header is large enough to contain import directory entry (index 1) - // export(0) + import(1) -> 2 entries -> 16 bytes + + /* check if optional header is large enough to contain import directory entry (index 1) + * export(0) + import(1) -> 2 entries -> 16 bytes + */ if (data_dir_offset != 0 && header.opthdr >= data_dir_offset + 16) { - // seek to Import Directory (Index 1) - // Data Directory Array starts at optional_header_start + data_dir_offset - // Index 1 is at + 8 bytes (sizeof(IMAGE_DATA_DIRECTORY) * 1) + /* seek to Import Directory (Index 1) + * Data Directory Array starts at optional_header_start + data_dir_offset + * Index 1 is at + 8 bytes (sizeof(IMAGE_DATA_DIRECTORY) * 1) + */ if (tb_stream_seek(istream, base_offset + sizeof(xm_coff_header_t) + data_dir_offset + 8)) { if (tb_stream_bread(istream, (tb_byte_t*)&import_rva, 4)) { import_rva = tb_bits_le_to_ne_u32(import_rva); @@ -118,20 +120,22 @@ tb_bool_t xm_binutils_coff_deplibs(tb_stream_ref_t istream, tb_hize_t base_offse } if (found_idt) { - // read import directory table - // The .idata section contains the Import Directory Table. - // Each entry is 20 bytes (IMAGE_IMPORT_DESCRIPTOR). - // The table ends with a null entry. - - // We need to iterate over IMAGE_IMPORT_DESCRIPTOR entries. - // struct IMAGE_IMPORT_DESCRIPTOR { - // DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA) - // DWORD TimeDateStamp; // 0 if not bound, - // DWORD ForwarderChain; // -1 if no forwarders - // DWORD Name; // RVA to DLL name - // DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses) - // }; - + /* read import directory table + * The .idata section contains the Import Directory Table. + * Each entry is 20 bytes (IMAGE_IMPORT_DESCRIPTOR). + * The table ends with a null entry. + */ + + /* We need to iterate over IMAGE_IMPORT_DESCRIPTOR entries. + * struct IMAGE_IMPORT_DESCRIPTOR { + * DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA) + * DWORD TimeDateStamp; // 0 if not bound, + * DWORD ForwarderChain; // -1 if no forwarders + * DWORD Name; // RVA to DLL name + * DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses) + * }; + */ + if (!tb_stream_seek(istream, idt_offset)) { return tb_false; } @@ -143,36 +147,38 @@ tb_bool_t xm_binutils_coff_deplibs(tb_stream_ref_t istream, tb_hize_t base_offse tb_uint32_t name_rva; tb_uint32_t first_thunk; - if (!tb_stream_bread(istream, (tb_byte_t*)&original_first_thunk, 4)) break; - if (!tb_stream_bread(istream, (tb_byte_t*)&time_date_stamp, 4)) break; - if (!tb_stream_bread(istream, (tb_byte_t*)&forwarder_chain, 4)) break; - if (!tb_stream_bread(istream, (tb_byte_t*)&name_rva, 4)) break; - if (!tb_stream_bread(istream, (tb_byte_t*)&first_thunk, 4)) break; + if (!tb_stream_bread(istream, (tb_byte_t*)&original_first_thunk, 4)) { break; } + if (!tb_stream_bread(istream, (tb_byte_t*)&time_date_stamp, 4)) { break; } + if (!tb_stream_bread(istream, (tb_byte_t*)&forwarder_chain, 4)) { break; } + if (!tb_stream_bread(istream, (tb_byte_t*)&name_rva, 4)) { break; } + if (!tb_stream_bread(istream, (tb_byte_t*)&first_thunk, 4)) { break; } // check for null entry (end of table) if (original_first_thunk == 0 && name_rva == 0) { break; } - + name_rva = tb_bits_le_to_ne_u32(name_rva); if (name_rva != 0) { - // map RVA to file offset to read the name - // We need to find the section that contains this RVA. - // Since we are iterating sections, we might need to seek back to read section headers again or cache them. - // For simplicity, we assume the name string is within the same .idata section or we can find it by scanning sections. - - // To do this correctly, we should scan all sections to find which one contains the RVA. - // But here we are inside a loop iterating sections. - // We can save current position and iterate sections from the beginning (or cached) to find the RVA. - + /* map RVA to file offset to read the name + * We need to find the section that contains this RVA. + * Since we are iterating sections, we might need to seek back to read section headers again or cache them. + * For simplicity, we assume the name string is within the same .idata section or we can find it by scanning sections. + */ + + /* To do this correctly, we should scan all sections to find which one contains the RVA. + * But here we are inside a loop iterating sections. + * We can save current position and iterate sections from the beginning (or cached) to find the RVA. + */ + // Optimization: usually the name is in the same .idata section or a nearby .rdata section. - + tb_hize_t saved_pos_inner = tb_stream_offset(istream); - + // Find the section containing name_rva tb_uint32_t name_file_offset = 0; - + // check current section first if (name_rva >= section.vaddr && name_rva < section.vaddr + section.vsize) { name_file_offset = section.ofs + (name_rva - section.vaddr); @@ -195,32 +201,22 @@ tb_bool_t xm_binutils_coff_deplibs(tb_stream_ref_t istream, tb_hize_t base_offse } if (name_file_offset != 0) { - if (tb_stream_seek(istream, name_file_offset)) { - tb_char_t dll_name[256]; - tb_size_t pos = 0; - tb_byte_t c; - while (pos < sizeof(dll_name) - 1) { - if (!tb_stream_bread(istream, &c, 1)) break; - if (c == 0) break; - dll_name[pos++] = (tb_char_t)c; - } - dll_name[pos] = '\0'; - - if (pos > 0) { - lua_pushinteger(lua, result_count + 1); - lua_pushstring(lua, dll_name); - lua_settable(lua, -3); - result_count++; - } + tb_char_t dll_name[256]; + if (xm_binutils_read_string(istream, name_file_offset, dll_name, sizeof(dll_name)) && dll_name[0]) { + lua_pushinteger(lua, result_count + 1); + lua_pushstring(lua, dll_name); + lua_settable(lua, -3); + result_count++; } } - + tb_stream_seek(istream, saved_pos_inner); } } - // We found .idata and processed it. Usually there is only one import table. - // But we should continue just in case or break? - // Typically break is enough after processing the import table. + /* We found .idata and processed it. Usually there is only one import table. + * But we should continue just in case or break? + * Typically break is enough after processing the import table. + */ break; } } diff --git a/core/src/xmake/binutils/coff/prefix.h b/core/src/xmake/binutils/coff/prefix.h index f62ff547d..f991ac26d 100644 --- a/core/src/xmake/binutils/coff/prefix.h +++ b/core/src/xmake/binutils/coff/prefix.h @@ -237,33 +237,9 @@ static __tb_inline__ tb_bool_t xm_binutils_coff_read_string(tb_stream_ref_t istr return tb_false; } - // 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; - } - - // read string - tb_size_t pos = 0; - tb_byte_t c; - while (pos < name_size - 1) { - if (!tb_stream_bread(istream, &c, 1)) { - tb_stream_seek(istream, saved_pos); - return tb_false; - } - if (c == 0) { - break; - } - name[pos++] = (tb_char_t)c; - } - name[pos] = '\0'; - - // restore position + // restore position and use common implementation tb_stream_seek(istream, saved_pos); - return tb_true; + return xm_binutils_read_string(istream, strtab_offset + offset, name, name_size); } /* get symbol name from COFF symbol entry diff --git a/core/src/xmake/binutils/elf/prefix.h b/core/src/xmake/binutils/elf/prefix.h index ed22d3963..f69f4ee3a 100644 --- a/core/src/xmake/binutils/elf/prefix.h +++ b/core/src/xmake/binutils/elf/prefix.h @@ -241,52 +241,7 @@ static __tb_inline__ tb_uint16_t xm_binutils_elf_get_machine(tb_char_t const *ar * @return tb_true if 64-bit, tb_false otherwise */ static __tb_inline__ tb_bool_t xm_binutils_elf_is_64bit(tb_char_t const *arch) { - if (!arch) { - return tb_true; - } - // x86_64 - if (tb_strcmp(arch, "x86_64") == 0 || tb_strcmp(arch, "x64") == 0) { - return tb_true; - } - // ARM64 - else if (tb_strcmp(arch, "arm64") == 0 || tb_strcmp(arch, "aarch64") == 0 || - tb_strcmp(arch, "arm64-v8a") == 0) { - return tb_true; - } - // MIPS64 - else if (tb_strncmp(arch, "mips64", 6) == 0) { - return tb_true; - } - // PowerPC64 - else if (tb_strncmp(arch, "ppc64", 5) == 0 || tb_strncmp(arch, "powerpc64", 9) == 0) { - return tb_true; - } - // RISC-V 64 - else if (tb_strncmp(arch, "riscv64", 7) == 0 || - (tb_strncmp(arch, "riscv", 5) == 0 && tb_strstr(arch, "64"))) { - return tb_true; - } - // SPARC64 - else if (tb_strncmp(arch, "sparc64", 7) == 0) { - return tb_true; - } - // s390x - else if (tb_strcmp(arch, "s390x") == 0) { - return tb_true; - } - // LoongArch64 - else if (tb_strncmp(arch, "loongarch64", 11) == 0) { - return tb_true; - } - // WebAssembly 64 - else if (tb_strcmp(arch, "wasm64") == 0) { - return tb_true; - } - // IA-64 - else if (tb_strcmp(arch, "ia64") == 0 || tb_strcmp(arch, "itanium") == 0) { - return tb_true; - } - return tb_false; + return xm_binutils_arch_is_64bit(arch); } /* ////////////////////////////////////////////////////////////////////////////////////// @@ -301,29 +256,7 @@ static __tb_inline__ tb_bool_t xm_binutils_elf_is_64bit(tb_char_t const *arch) { * @return the string (static buffer, valid until next call) */ static __tb_inline__ tb_bool_t xm_binutils_elf_read_string(tb_stream_ref_t istream, tb_uint64_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); - - tb_hize_t saved_pos = tb_stream_offset(istream); - if (!tb_stream_seek(istream, strtab_offset + offset)) { - return tb_false; - } - - tb_size_t pos = 0; - tb_byte_t c; - while (pos < name_size - 1) { - if (!tb_stream_bread(istream, &c, 1)) { - tb_stream_seek(istream, saved_pos); - return tb_false; - } - if (c == 0) { - break; - } - name[pos++] = (tb_char_t)c; - } - name[pos] = '\0'; - - tb_stream_seek(istream, saved_pos); - return tb_true; + return xm_binutils_read_string(istream, strtab_offset + offset, name, name_size); } /* get symbol type character (nm-style) from ELF symbol diff --git a/core/src/xmake/binutils/prefix.h b/core/src/xmake/binutils/prefix.h index 64c7cd80f..68408eea5 100644 --- a/core/src/xmake/binutils/prefix.h +++ b/core/src/xmake/binutils/prefix.h @@ -189,6 +189,95 @@ static __tb_inline__ void xm_binutils_sanitize_symbol_name(tb_char_t* name) { } } +/* read string from stream at specified offset + * + * @param istream the input stream + * @param offset the offset to read from + * @param name the buffer to store the string + * @param name_size the size of the buffer + * + * @return tb_true on success, tb_false on failure + */ +static __tb_inline__ tb_bool_t xm_binutils_read_string(tb_stream_ref_t istream, tb_hize_t offset, tb_char_t *name, tb_size_t name_size) { + tb_assert_and_check_return_val(istream && name && name_size > 0, tb_false); + + tb_hize_t saved_pos = tb_stream_offset(istream); + if (!tb_stream_seek(istream, offset)) { + return tb_false; + } + + tb_size_t pos = 0; + tb_byte_t c; + while (pos < name_size - 1) { + if (!tb_stream_bread(istream, &c, 1)) { + tb_stream_seek(istream, saved_pos); + return tb_false; + } + if (c == 0) { + break; + } + name[pos++] = (tb_char_t)c; + } + name[pos] = '\0'; + + tb_stream_seek(istream, saved_pos); + return tb_true; +} + +/* check if architecture is 64-bit + * + * @param arch the architecture string + * @return tb_true if 64-bit, tb_false otherwise + */ +static __tb_inline__ tb_bool_t xm_binutils_arch_is_64bit(tb_char_t const *arch) { + if (!arch) { + return tb_true; + } + // x86_64 + if (tb_strcmp(arch, "x86_64") == 0 || tb_strcmp(arch, "x64") == 0) { + return tb_true; + } + // ARM64 + else if (tb_strcmp(arch, "arm64") == 0 || tb_strcmp(arch, "aarch64") == 0 || + tb_strcmp(arch, "arm64-v8a") == 0) { + return tb_true; + } + // MIPS64 + else if (tb_strncmp(arch, "mips64", 6) == 0) { + return tb_true; + } + // PowerPC64 + else if (tb_strncmp(arch, "ppc64", 5) == 0 || tb_strncmp(arch, "powerpc64", 9) == 0) { + return tb_true; + } + // RISC-V 64 + else if (tb_strncmp(arch, "riscv64", 7) == 0 || + (tb_strncmp(arch, "riscv", 5) == 0 && tb_strstr(arch, "64"))) { + return tb_true; + } + // SPARC64 + else if (tb_strncmp(arch, "sparc64", 7) == 0) { + return tb_true; + } + // s390x + else if (tb_strcmp(arch, "s390x") == 0) { + return tb_true; + } + // LoongArch64 + else if (tb_strncmp(arch, "loongarch64", 11) == 0) { + return tb_true; + } + // WebAssembly 64 + else if (tb_strcmp(arch, "wasm64") == 0) { + return tb_true; + } + // IA-64 + else if (tb_strcmp(arch, "ia64") == 0 || tb_strcmp(arch, "itanium") == 0) { + return tb_true; + } + return tb_false; +} + #endif |
