summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
Diffstat (limited to 'core/src')
-rw-r--r--core/src/xmake/binutils/elf/bin2elf.c81
-rw-r--r--core/src/xmake/binutils/elf/prefix.h135
-rw-r--r--core/src/xmake/binutils/prefix.h32
3 files changed, 221 insertions, 27 deletions
diff --git a/core/src/xmake/binutils/elf/bin2elf.c b/core/src/xmake/binutils/elf/bin2elf.c
index 76a75f8fe..ff3f941f1 100644
--- a/core/src/xmake/binutils/elf/bin2elf.c
+++ b/core/src/xmake/binutils/elf/bin2elf.c
@@ -34,11 +34,38 @@
* private implementation
*/
+// write an ELF struct out in the target endianness (the struct is converted in place)
+static tb_bool_t xm_binutils_bin2elf_bwrit_header_32(tb_stream_ref_t ostream, xm_elf32_header_t* h, tb_bool_t be) {
+ xm_binutils_elf32_header_conv(h, be);
+ return tb_stream_bwrit(ostream, (tb_byte_t const *)h, sizeof(*h));
+}
+static tb_bool_t xm_binutils_bin2elf_bwrit_section_32(tb_stream_ref_t ostream, xm_elf32_section_t* s, tb_bool_t be) {
+ xm_binutils_elf32_section_conv(s, be);
+ return tb_stream_bwrit(ostream, (tb_byte_t const *)s, sizeof(*s));
+}
+static tb_bool_t xm_binutils_bin2elf_bwrit_symbol_32(tb_stream_ref_t ostream, xm_elf32_symbol_t* s, tb_bool_t be) {
+ xm_binutils_elf32_symbol_conv(s, be);
+ return tb_stream_bwrit(ostream, (tb_byte_t const *)s, sizeof(*s));
+}
+static tb_bool_t xm_binutils_bin2elf_bwrit_header_64(tb_stream_ref_t ostream, xm_elf64_header_t* h, tb_bool_t be) {
+ xm_binutils_elf64_header_conv(h, be);
+ return tb_stream_bwrit(ostream, (tb_byte_t const *)h, sizeof(*h));
+}
+static tb_bool_t xm_binutils_bin2elf_bwrit_section_64(tb_stream_ref_t ostream, xm_elf64_section_t* s, tb_bool_t be) {
+ xm_binutils_elf64_section_conv(s, be);
+ return tb_stream_bwrit(ostream, (tb_byte_t const *)s, sizeof(*s));
+}
+static tb_bool_t xm_binutils_bin2elf_bwrit_symbol_64(tb_stream_ref_t ostream, xm_elf64_symbol_t* s, tb_bool_t be) {
+ xm_binutils_elf64_symbol_conv(s, be);
+ return tb_stream_bwrit(ostream, (tb_byte_t const *)s, sizeof(*s));
+}
+
static tb_bool_t xm_binutils_bin2elf_dump_32(tb_stream_ref_t istream,
tb_stream_ref_t ostream,
tb_char_t const *symbol_prefix,
tb_char_t const *arch,
tb_char_t const *basename,
+ tb_bool_t bigendian,
tb_bool_t zeroend) {
tb_assert_and_check_return_val(istream && ostream, tb_false);
@@ -117,25 +144,26 @@ static tb_bool_t xm_binutils_bin2elf_dump_32(tb_stream_ref_t istream,
header.e_ident[2] = 'L';
header.e_ident[3] = 'F';
header.e_ident[XM_ELF_EI_CLASS] = XM_ELF_CLASS32;
- header.e_ident[5] = 1; // ELFDATA2LSB
+ header.e_ident[5] = bigendian? XM_ELF_DATA2MSB : XM_ELF_DATA2LSB;
header.e_ident[6] = 1; // EV_CURRENT
header.e_ident[7] = 0; // ELFOSABI_SYSV
header.e_type = 1; // ET_REL
header.e_machine = xm_binutils_elf_get_machine(arch);
header.e_version = 1;
+ header.e_flags = xm_binutils_elf_get_flags(arch);
header.e_shoff = section_headers_ofs;
header.e_ehsize = header_size;
header.e_shentsize = section_header_size;
header.e_shnum = section_count;
header.e_shstrndx = 4; // .shstrtab section index
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&header, sizeof(header))) {
+ if (!xm_binutils_bin2elf_bwrit_header_32(ostream, &header, bigendian)) {
return tb_false;
}
// write section headers
xm_elf32_section_t section_null;
tb_memset(&section_null, 0, sizeof(section_null));
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&section_null, sizeof(section_null))) {
+ if (!xm_binutils_bin2elf_bwrit_section_32(ostream, &section_null, bigendian)) {
return tb_false;
}
@@ -148,7 +176,7 @@ static tb_bool_t xm_binutils_bin2elf_dump_32(tb_stream_ref_t istream,
section_rodata.sh_offset = rodata_ofs;
section_rodata.sh_size = rodata_size;
section_rodata.sh_addralign = 4;
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&section_rodata, sizeof(section_rodata))) {
+ if (!xm_binutils_bin2elf_bwrit_section_32(ostream, &section_rodata, bigendian)) {
return tb_false;
}
@@ -163,7 +191,7 @@ static tb_bool_t xm_binutils_bin2elf_dump_32(tb_stream_ref_t istream,
section_symtab.sh_info = 1; // first global symbol index
section_symtab.sh_addralign = 4;
section_symtab.sh_entsize = sizeof(xm_elf32_symbol_t);
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&section_symtab, sizeof(section_symtab))) {
+ if (!xm_binutils_bin2elf_bwrit_section_32(ostream, &section_symtab, bigendian)) {
return tb_false;
}
@@ -175,7 +203,7 @@ static tb_bool_t xm_binutils_bin2elf_dump_32(tb_stream_ref_t istream,
section_strtab.sh_offset = strtab_ofs;
section_strtab.sh_size = strtab_size;
section_strtab.sh_addralign = 1;
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&section_strtab, sizeof(section_strtab))) {
+ if (!xm_binutils_bin2elf_bwrit_section_32(ostream, &section_strtab, bigendian)) {
return tb_false;
}
@@ -187,7 +215,7 @@ static tb_bool_t xm_binutils_bin2elf_dump_32(tb_stream_ref_t istream,
section_shstrtab.sh_offset = shstrtab_ofs;
section_shstrtab.sh_size = shstrtab_size;
section_shstrtab.sh_addralign = 1;
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&section_shstrtab, sizeof(section_shstrtab))) {
+ if (!xm_binutils_bin2elf_bwrit_section_32(ostream, &section_shstrtab, bigendian)) {
return tb_false;
}
@@ -200,7 +228,7 @@ static tb_bool_t xm_binutils_bin2elf_dump_32(tb_stream_ref_t istream,
section_note_gnu_stack.sh_offset = shstrtab_ofs + shstrtab_size; // after .shstrtab
section_note_gnu_stack.sh_size = 0; // empty section
section_note_gnu_stack.sh_addralign = 1;
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&section_note_gnu_stack, sizeof(section_note_gnu_stack))) {
+ if (!xm_binutils_bin2elf_bwrit_section_32(ostream, &section_note_gnu_stack, bigendian)) {
return tb_false;
}
@@ -230,7 +258,7 @@ static tb_bool_t xm_binutils_bin2elf_dump_32(tb_stream_ref_t istream,
// symbol 0: NULL symbol
xm_elf32_symbol_t sym_null;
tb_memset(&sym_null, 0, sizeof(sym_null));
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&sym_null, sizeof(sym_null))) {
+ if (!xm_binutils_bin2elf_bwrit_symbol_32(ostream, &sym_null, bigendian)) {
return tb_false;
}
@@ -242,7 +270,7 @@ static tb_bool_t xm_binutils_bin2elf_dump_32(tb_stream_ref_t istream,
sym_start.st_shndx = 1; // .rodata section index
sym_start.st_value = 0;
sym_start.st_size = 0;
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&sym_start, sizeof(sym_start))) {
+ if (!xm_binutils_bin2elf_bwrit_symbol_32(ostream, &sym_start, bigendian)) {
return tb_false;
}
@@ -254,7 +282,7 @@ static tb_bool_t xm_binutils_bin2elf_dump_32(tb_stream_ref_t istream,
sym_end.st_shndx = 1; // .rodata section index
sym_end.st_value = rodata_size;
sym_end.st_size = 0;
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&sym_end, sizeof(sym_end))) {
+ if (!xm_binutils_bin2elf_bwrit_symbol_32(ostream, &sym_end, bigendian)) {
return tb_false;
}
@@ -339,6 +367,7 @@ static tb_bool_t xm_binutils_bin2elf_dump_64(tb_stream_ref_t istream,
tb_char_t const *symbol_prefix,
tb_char_t const *arch,
tb_char_t const *basename,
+ tb_bool_t bigendian,
tb_bool_t zeroend) {
tb_assert_and_check_return_val(istream && ostream, tb_false);
@@ -417,25 +446,26 @@ static tb_bool_t xm_binutils_bin2elf_dump_64(tb_stream_ref_t istream,
header.e_ident[2] = 'L';
header.e_ident[3] = 'F';
header.e_ident[XM_ELF_EI_CLASS] = XM_ELF_CLASS64;
- header.e_ident[5] = 1; // ELFDATA2LSB
+ header.e_ident[5] = bigendian? XM_ELF_DATA2MSB : XM_ELF_DATA2LSB;
header.e_ident[6] = 1; // EV_CURRENT
header.e_ident[7] = 0; // ELFOSABI_SYSV
header.e_type = 1; // ET_REL
header.e_machine = xm_binutils_elf_get_machine(arch);
header.e_version = 1;
+ header.e_flags = xm_binutils_elf_get_flags(arch);
header.e_shoff = section_headers_ofs;
header.e_ehsize = header_size;
header.e_shentsize = section_header_size;
header.e_shnum = section_count;
header.e_shstrndx = 4; // .shstrtab section index
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&header, sizeof(header))) {
+ if (!xm_binutils_bin2elf_bwrit_header_64(ostream, &header, bigendian)) {
return tb_false;
}
// write section headers
xm_elf64_section_t section_null;
tb_memset(&section_null, 0, sizeof(section_null));
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&section_null, sizeof(section_null))) {
+ if (!xm_binutils_bin2elf_bwrit_section_64(ostream, &section_null, bigendian)) {
return tb_false;
}
@@ -448,7 +478,7 @@ static tb_bool_t xm_binutils_bin2elf_dump_64(tb_stream_ref_t istream,
section_rodata.sh_offset = rodata_ofs;
section_rodata.sh_size = rodata_size;
section_rodata.sh_addralign = 8;
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&section_rodata, sizeof(section_rodata))) {
+ if (!xm_binutils_bin2elf_bwrit_section_64(ostream, &section_rodata, bigendian)) {
return tb_false;
}
@@ -463,7 +493,7 @@ static tb_bool_t xm_binutils_bin2elf_dump_64(tb_stream_ref_t istream,
section_symtab.sh_info = 1; // first global symbol index
section_symtab.sh_addralign = 8;
section_symtab.sh_entsize = sizeof(xm_elf64_symbol_t);
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&section_symtab, sizeof(section_symtab))) {
+ if (!xm_binutils_bin2elf_bwrit_section_64(ostream, &section_symtab, bigendian)) {
return tb_false;
}
@@ -475,7 +505,7 @@ static tb_bool_t xm_binutils_bin2elf_dump_64(tb_stream_ref_t istream,
section_strtab.sh_offset = strtab_ofs;
section_strtab.sh_size = strtab_size;
section_strtab.sh_addralign = 1;
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&section_strtab, sizeof(section_strtab))) {
+ if (!xm_binutils_bin2elf_bwrit_section_64(ostream, &section_strtab, bigendian)) {
return tb_false;
}
@@ -487,7 +517,7 @@ static tb_bool_t xm_binutils_bin2elf_dump_64(tb_stream_ref_t istream,
section_shstrtab.sh_offset = shstrtab_ofs; // points to initial null byte
section_shstrtab.sh_size = shstrtab_size; // size includes initial null and all strings
section_shstrtab.sh_addralign = 1;
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&section_shstrtab, sizeof(section_shstrtab))) {
+ if (!xm_binutils_bin2elf_bwrit_section_64(ostream, &section_shstrtab, bigendian)) {
return tb_false;
}
@@ -500,7 +530,7 @@ static tb_bool_t xm_binutils_bin2elf_dump_64(tb_stream_ref_t istream,
section_note_gnu_stack.sh_offset = shstrtab_ofs + shstrtab_size; // after .shstrtab
section_note_gnu_stack.sh_size = 0; // empty section
section_note_gnu_stack.sh_addralign = 1;
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&section_note_gnu_stack, sizeof(section_note_gnu_stack))) {
+ if (!xm_binutils_bin2elf_bwrit_section_64(ostream, &section_note_gnu_stack, bigendian)) {
return tb_false;
}
@@ -530,7 +560,7 @@ static tb_bool_t xm_binutils_bin2elf_dump_64(tb_stream_ref_t istream,
// symbol 0: NULL symbol
xm_elf64_symbol_t sym_null;
tb_memset(&sym_null, 0, sizeof(sym_null));
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&sym_null, sizeof(sym_null))) {
+ if (!xm_binutils_bin2elf_bwrit_symbol_64(ostream, &sym_null, bigendian)) {
return tb_false;
}
@@ -542,7 +572,7 @@ static tb_bool_t xm_binutils_bin2elf_dump_64(tb_stream_ref_t istream,
sym_start.st_shndx = 1; // .rodata section index
sym_start.st_value = 0;
sym_start.st_size = 0;
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&sym_start, sizeof(sym_start))) {
+ if (!xm_binutils_bin2elf_bwrit_symbol_64(ostream, &sym_start, bigendian)) {
return tb_false;
}
@@ -554,7 +584,7 @@ static tb_bool_t xm_binutils_bin2elf_dump_64(tb_stream_ref_t istream,
sym_end.st_shndx = 1; // .rodata section index
sym_end.st_value = rodata_size;
sym_end.st_size = 0;
- if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&sym_end, sizeof(sym_end))) {
+ if (!xm_binutils_bin2elf_bwrit_symbol_64(ostream, &sym_end, bigendian)) {
return tb_false;
}
@@ -683,16 +713,17 @@ tb_int_t xm_binutils_bin2elf(lua_State *lua) {
break;
}
- // choose 32-bit or 64-bit ELF based on architecture
+ // choose 32-bit or 64-bit ELF based on architecture, and little/big endian
tb_bool_t is_64bit = xm_binutils_elf_is_64bit(arch);
+ tb_bool_t is_bigendian = xm_binutils_elf_is_bigendian(arch);
if (is_64bit) {
- if (!xm_binutils_bin2elf_dump_64(istream, ostream, symbol_prefix, arch, basename, zeroend)) {
+ if (!xm_binutils_bin2elf_dump_64(istream, ostream, symbol_prefix, arch, basename, is_bigendian, zeroend)) {
lua_pushboolean(lua, tb_false);
lua_pushfstring(lua, "bin2elf: dump data failed");
break;
}
} else {
- if (!xm_binutils_bin2elf_dump_32(istream, ostream, symbol_prefix, arch, basename, zeroend)) {
+ if (!xm_binutils_bin2elf_dump_32(istream, ostream, symbol_prefix, arch, basename, is_bigendian, zeroend)) {
lua_pushboolean(lua, tb_false);
lua_pushfstring(lua, "bin2elf: dump data failed");
break;
diff --git a/core/src/xmake/binutils/elf/prefix.h b/core/src/xmake/binutils/elf/prefix.h
index 2072ee879..49c53c6c7 100644
--- a/core/src/xmake/binutils/elf/prefix.h
+++ b/core/src/xmake/binutils/elf/prefix.h
@@ -56,6 +56,19 @@
#define XM_ELF_MACHINE_WASM 0xe7
#define XM_ELF_MACHINE_LOONGARCH 0x102
+// ELF data encoding (e_ident[EI_DATA])
+#define XM_ELF_DATA2LSB 1
+#define XM_ELF_DATA2MSB 2
+
+// RISC-V e_flags (arch/riscv/include/uapi/asm/elf.h)
+#define XM_EF_RISCV_RVC 0x0001
+#define XM_EF_RISCV_FLOAT_ABI_SINGLE 0x0002
+#define XM_EF_RISCV_FLOAT_ABI_DOUBLE 0x0004
+
+// LoongArch e_flags (LoongArch ELF psABI)
+#define XM_EF_LOONGARCH_ABI_DOUBLE_FLOAT 0x3
+#define XM_EF_LOONGARCH_OBJABI_V1 0x40
+
#define XM_ELF_SHT_PROGBITS 0x1
#define XM_ELF_SHT_SYMTAB 0x2
#define XM_ELF_SHT_STRTAB 0x3
@@ -297,6 +310,128 @@ static __tb_inline__ tb_bool_t xm_binutils_elf_is_64bit(tb_char_t const *arch) {
return xm_binutils_arch_is_64bit(arch);
}
+/* check if architecture is big-endian
+ *
+ * @param arch the architecture string
+ * @return tb_true if big-endian, tb_false otherwise
+ */
+static __tb_inline__ tb_bool_t xm_binutils_elf_is_bigendian(tb_char_t const *arch) {
+ return xm_binutils_arch_is_bigendian(arch);
+}
+
+/* get the default e_flags for the given architecture
+ *
+ * Some architectures (RISC-V, LoongArch) encode the ABI (e.g. float ABI) in e_flags.
+ * The linker refuses to merge objects whose ABI flags are incompatible, so a data-only
+ * object generated with e_flags == 0 (soft-float) would fail to link against a normal
+ * double-float toolchain. We default to the flags used by the common GNU toolchains.
+ *
+ * @param arch the architecture string
+ * @return the e_flags value
+ */
+static __tb_inline__ tb_uint32_t xm_binutils_elf_get_flags(tb_char_t const *arch) {
+ if (!arch) {
+ return 0;
+ }
+ // RISC-V: default to RVC + double-float ABI to match the common rv32/rv64 "gc" toolchains
+ if (tb_strncmp(arch, "riscv", 5) == 0) {
+ return XM_EF_RISCV_RVC | XM_EF_RISCV_FLOAT_ABI_DOUBLE;
+ }
+ // LoongArch: default to double-float ABI (lp64d/ilp32d) + object ABI v1
+ else if (tb_strncmp(arch, "loongarch", 9) == 0 || tb_strncmp(arch, "loong64", 7) == 0) {
+ return XM_EF_LOONGARCH_ABI_DOUBLE_FLOAT | XM_EF_LOONGARCH_OBJABI_V1;
+ }
+ return 0;
+}
+
+/* //////////////////////////////////////////////////////////////////////////////////////
+ * endianness-aware serialization
+ *
+ * The dump code fills the ELF structs in the host's native byte order. Before writing them
+ * out, each multi-byte field must be converted to the *target* endianness (which may differ
+ * from the host, e.g. generating a big-endian s390x object on a little-endian host).
+ */
+
+static __tb_inline__ tb_uint16_t xm_binutils_elf_conv_u16(tb_uint16_t x, tb_bool_t bigendian) {
+ return bigendian? tb_bits_ne_to_be_u16(x) : tb_bits_ne_to_le_u16(x);
+}
+static __tb_inline__ tb_uint32_t xm_binutils_elf_conv_u32(tb_uint32_t x, tb_bool_t bigendian) {
+ return bigendian? tb_bits_ne_to_be_u32(x) : tb_bits_ne_to_le_u32(x);
+}
+static __tb_inline__ tb_uint64_t xm_binutils_elf_conv_u64(tb_uint64_t x, tb_bool_t bigendian) {
+ return bigendian? tb_bits_ne_to_be_u64(x) : tb_bits_ne_to_le_u64(x);
+}
+
+// convert a 32-bit ELF header to the target endianness in place (e_ident is byte data, untouched)
+static __tb_inline__ void xm_binutils_elf32_header_conv(xm_elf32_header_t* h, tb_bool_t be) {
+ h->e_type = xm_binutils_elf_conv_u16(h->e_type, be);
+ h->e_machine = xm_binutils_elf_conv_u16(h->e_machine, be);
+ h->e_version = xm_binutils_elf_conv_u32(h->e_version, be);
+ h->e_entry = xm_binutils_elf_conv_u32(h->e_entry, be);
+ h->e_phoff = xm_binutils_elf_conv_u32(h->e_phoff, be);
+ h->e_shoff = xm_binutils_elf_conv_u32(h->e_shoff, be);
+ h->e_flags = xm_binutils_elf_conv_u32(h->e_flags, be);
+ h->e_ehsize = xm_binutils_elf_conv_u16(h->e_ehsize, be);
+ h->e_phentsize = xm_binutils_elf_conv_u16(h->e_phentsize, be);
+ h->e_phnum = xm_binutils_elf_conv_u16(h->e_phnum, be);
+ h->e_shentsize = xm_binutils_elf_conv_u16(h->e_shentsize, be);
+ h->e_shnum = xm_binutils_elf_conv_u16(h->e_shnum, be);
+ h->e_shstrndx = xm_binutils_elf_conv_u16(h->e_shstrndx, be);
+}
+static __tb_inline__ void xm_binutils_elf32_section_conv(xm_elf32_section_t* s, tb_bool_t be) {
+ s->sh_name = xm_binutils_elf_conv_u32(s->sh_name, be);
+ s->sh_type = xm_binutils_elf_conv_u32(s->sh_type, be);
+ s->sh_flags = xm_binutils_elf_conv_u32(s->sh_flags, be);
+ s->sh_addr = xm_binutils_elf_conv_u32(s->sh_addr, be);
+ s->sh_offset = xm_binutils_elf_conv_u32(s->sh_offset, be);
+ s->sh_size = xm_binutils_elf_conv_u32(s->sh_size, be);
+ s->sh_link = xm_binutils_elf_conv_u32(s->sh_link, be);
+ s->sh_info = xm_binutils_elf_conv_u32(s->sh_info, be);
+ s->sh_addralign = xm_binutils_elf_conv_u32(s->sh_addralign, be);
+ s->sh_entsize = xm_binutils_elf_conv_u32(s->sh_entsize, be);
+}
+static __tb_inline__ void xm_binutils_elf32_symbol_conv(xm_elf32_symbol_t* s, tb_bool_t be) {
+ s->st_name = xm_binutils_elf_conv_u32(s->st_name, be);
+ s->st_value = xm_binutils_elf_conv_u32(s->st_value, be);
+ s->st_size = xm_binutils_elf_conv_u32(s->st_size, be);
+ s->st_shndx = xm_binutils_elf_conv_u16(s->st_shndx, be);
+ // st_info and st_other are single bytes, untouched
+}
+static __tb_inline__ void xm_binutils_elf64_header_conv(xm_elf64_header_t* h, tb_bool_t be) {
+ h->e_type = xm_binutils_elf_conv_u16(h->e_type, be);
+ h->e_machine = xm_binutils_elf_conv_u16(h->e_machine, be);
+ h->e_version = xm_binutils_elf_conv_u32(h->e_version, be);
+ h->e_entry = xm_binutils_elf_conv_u64(h->e_entry, be);
+ h->e_phoff = xm_binutils_elf_conv_u64(h->e_phoff, be);
+ h->e_shoff = xm_binutils_elf_conv_u64(h->e_shoff, be);
+ h->e_flags = xm_binutils_elf_conv_u32(h->e_flags, be);
+ h->e_ehsize = xm_binutils_elf_conv_u16(h->e_ehsize, be);
+ h->e_phentsize = xm_binutils_elf_conv_u16(h->e_phentsize, be);
+ h->e_phnum = xm_binutils_elf_conv_u16(h->e_phnum, be);
+ h->e_shentsize = xm_binutils_elf_conv_u16(h->e_shentsize, be);
+ h->e_shnum = xm_binutils_elf_conv_u16(h->e_shnum, be);
+ h->e_shstrndx = xm_binutils_elf_conv_u16(h->e_shstrndx, be);
+}
+static __tb_inline__ void xm_binutils_elf64_section_conv(xm_elf64_section_t* s, tb_bool_t be) {
+ s->sh_name = xm_binutils_elf_conv_u32(s->sh_name, be);
+ s->sh_type = xm_binutils_elf_conv_u32(s->sh_type, be);
+ s->sh_flags = xm_binutils_elf_conv_u64(s->sh_flags, be);
+ s->sh_addr = xm_binutils_elf_conv_u64(s->sh_addr, be);
+ s->sh_offset = xm_binutils_elf_conv_u64(s->sh_offset, be);
+ s->sh_size = xm_binutils_elf_conv_u64(s->sh_size, be);
+ s->sh_link = xm_binutils_elf_conv_u32(s->sh_link, be);
+ s->sh_info = xm_binutils_elf_conv_u32(s->sh_info, be);
+ s->sh_addralign = xm_binutils_elf_conv_u64(s->sh_addralign, be);
+ s->sh_entsize = xm_binutils_elf_conv_u64(s->sh_entsize, be);
+}
+static __tb_inline__ void xm_binutils_elf64_symbol_conv(xm_elf64_symbol_t* s, tb_bool_t be) {
+ s->st_name = xm_binutils_elf_conv_u32(s->st_name, be);
+ s->st_shndx = xm_binutils_elf_conv_u16(s->st_shndx, be);
+ s->st_value = xm_binutils_elf_conv_u64(s->st_value, be);
+ s->st_size = xm_binutils_elf_conv_u64(s->st_size, be);
+ // st_info and st_other are single bytes, untouched
+}
+
/* //////////////////////////////////////////////////////////////////////////////////////
* readsyms inline implementation
*/
diff --git a/core/src/xmake/binutils/prefix.h b/core/src/xmake/binutils/prefix.h
index 608424958..bef683209 100644
--- a/core/src/xmake/binutils/prefix.h
+++ b/core/src/xmake/binutils/prefix.h
@@ -205,8 +205,8 @@ static __tb_inline__ tb_bool_t xm_binutils_arch_is_64bit(tb_char_t const *arch)
else if (tb_strcmp(arch, "s390x") == 0) {
return tb_true;
}
- // LoongArch64
- else if (tb_strncmp(arch, "loongarch64", 11) == 0) {
+ // LoongArch64 (xmake uses "loong64" as the canonical arch name)
+ else if (tb_strncmp(arch, "loongarch64", 11) == 0 || tb_strcmp(arch, "loong64") == 0) {
return tb_true;
}
// WebAssembly 64
@@ -220,5 +220,33 @@ static __tb_inline__ tb_bool_t xm_binutils_arch_is_64bit(tb_char_t const *arch)
return tb_false;
}
+/* check if architecture is big-endian
+ *
+ * @param arch the architecture string
+ * @return tb_true if big-endian, tb_false otherwise
+ */
+static __tb_inline__ tb_bool_t xm_binutils_arch_is_bigendian(tb_char_t const *arch) {
+ if (!arch) {
+ return tb_false;
+ }
+ // s390/s390x are always big-endian
+ if (tb_strcmp(arch, "s390x") == 0 || tb_strcmp(arch, "s390") == 0) {
+ return tb_true;
+ }
+ // SPARC is big-endian
+ else if (tb_strncmp(arch, "sparc", 5) == 0) {
+ return tb_true;
+ }
+ // MIPS big-endian variants (mips, mips64), the little-endian ones end with "el" (mipsel, mips64el)
+ else if (tb_strncmp(arch, "mips", 4) == 0) {
+ return tb_strstr(arch, "el") == tb_null;
+ }
+ // PowerPC big-endian variants (ppc, ppc64), the little-endian ones end with "le" (ppc64le, powerpc64le)
+ else if (tb_strncmp(arch, "ppc", 3) == 0 || tb_strncmp(arch, "powerpc", 7) == 0) {
+ return tb_strstr(arch, "le") == tb_null;
+ }
+ return tb_false;
+}
+
#endif