summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-12-07 11:36:02 +0800
committerruki <[email protected]>2025-12-07 17:15:59 +0800
commit1ef6dddad4c6a3a2e3b3b79667e7f4568f7cfda0 (patch)
tree7dd959bba3f618f2cc32e229e46b65d4cee4c2da
parentcae5b0a17dc7d0eb5599c0d5a92fab69d39983d5 (diff)
improve minos and sdkver
-rw-r--r--core/src/xmake/utils/bin2macho.c72
-rw-r--r--xmake/core/sandbox/modules/utils.lua4
-rw-r--r--xmake/modules/private/utils/bin2obj.lua18
-rw-r--r--xmake/rules/utils/bin2obj/xmake.lua20
4 files changed, 94 insertions, 20 deletions
diff --git a/core/src/xmake/utils/bin2macho.c b/core/src/xmake/utils/bin2macho.c
index b5a97c21f..5499ee103 100644
--- a/core/src/xmake/utils/bin2macho.c
+++ b/core/src/xmake/utils/bin2macho.c
@@ -67,6 +67,10 @@
#define XM_MACHO_N_TYPE_SECT 0x0e
#define XM_MACHO_N_EXT 0x01
+#define XM_MACHO_VM_PROT_READ 1
+#define XM_MACHO_VM_PROT_WRITE 2
+#define XM_MACHO_VM_PROT_EXECUTE 4
+
/* //////////////////////////////////////////////////////////////////////////////////////
* types
*/
@@ -255,12 +259,48 @@ static tb_uint32_t xm_utils_bin2macho_get_platform(tb_char_t const *platform) {
return XM_MACHO_PLATFORM_MACOS;
}
+// parse version string (e.g., "10.0" or "18.2") to Mach-O format (0x000a0000)
+// format: (major << 16) | (minor << 8) | patch
+static tb_uint32_t xm_utils_bin2macho_parse_version(tb_char_t const *version_str) {
+ if (!version_str || !version_str[0]) {
+ return 0x000a0000; // default: 10.0.0
+ }
+ tb_uint32_t major = 0;
+ tb_uint32_t minor = 0;
+ tb_uint32_t patch = 0;
+ tb_char_t const *p = version_str;
+ // parse major
+ while (*p && tb_isdigit(*p)) {
+ major = major * 10 + (*p - '0');
+ p++;
+ }
+ if (*p == '.') {
+ p++;
+ // parse minor
+ while (*p && tb_isdigit(*p)) {
+ minor = minor * 10 + (*p - '0');
+ p++;
+ }
+ if (*p == '.') {
+ p++;
+ // parse patch
+ while (*p && tb_isdigit(*p)) {
+ patch = patch * 10 + (*p - '0');
+ p++;
+ }
+ }
+ }
+ return (major << 16) | (minor << 8) | patch;
+}
+
static tb_bool_t xm_utils_bin2macho_dump_64(tb_stream_ref_t istream,
tb_stream_ref_t ostream,
tb_char_t const *symbol_prefix,
tb_char_t const *plat,
tb_char_t const *arch,
- tb_char_t const *basename) {
+ tb_char_t const *basename,
+ tb_uint32_t minos,
+ tb_uint32_t sdk) {
tb_assert_and_check_return_val(istream && ostream, tb_false);
// get file size
@@ -339,13 +379,13 @@ static tb_bool_t xm_utils_bin2macho_dump_64(tb_stream_ref_t istream,
tb_memset(&segment, 0, sizeof(segment));
segment.cmd = XM_MACHO_LC_SEGMENT_64;
segment.cmdsize = segment_cmd_total_size;
- tb_strncpy(segment.segname, "__DATA", 16);
+ tb_strncpy(segment.segname, "__TEXT", 16);
segment.vmaddr = 0;
segment.vmsize = data_size;
segment.fileoff = data_offset;
segment.filesize = data_size;
- segment.maxprot = 1; // VM_PROT_READ
- segment.initprot = 1; // VM_PROT_READ
+ segment.maxprot = XM_MACHO_VM_PROT_READ; // VM_PROT_READ (read-only)
+ segment.initprot = XM_MACHO_VM_PROT_READ; // VM_PROT_READ (read-only)
segment.nsects = 1;
segment.flags = 0;
if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&segment, sizeof(segment))) {
@@ -355,8 +395,8 @@ static tb_bool_t xm_utils_bin2macho_dump_64(tb_stream_ref_t istream,
// write section
xm_macho_section_64_t section;
tb_memset(&section, 0, sizeof(section));
- tb_strncpy(section.sectname, "__data", 16);
- tb_strncpy(section.segname, "__DATA", 16);
+ tb_strncpy(section.sectname, "__const", 16);
+ tb_strncpy(section.segname, "__TEXT", 16);
section.addr = 0;
section.size = data_size;
section.offset = data_offset;
@@ -387,8 +427,8 @@ static tb_bool_t xm_utils_bin2macho_dump_64(tb_stream_ref_t istream,
build_version.cmd = XM_MACHO_LC_BUILD_VERSION;
build_version.cmdsize = build_version_cmd_size;
build_version.platform = xm_utils_bin2macho_get_platform(plat);
- build_version.minos = 0x000a0000; // 10.0.0
- build_version.sdk = 0x000a0000; // 10.0.0
+ build_version.minos = minos;
+ build_version.sdk = sdk;
build_version.ntools = 0;
if (!tb_stream_bwrit(ostream, (tb_byte_t const *)&build_version, sizeof(build_version))) {
return tb_false;
@@ -497,9 +537,11 @@ static tb_bool_t xm_utils_bin2macho_dump(tb_stream_ref_t istream,
tb_char_t const *symbol_prefix,
tb_char_t const *plat,
tb_char_t const *arch,
- tb_char_t const *basename) {
+ tb_char_t const *basename,
+ tb_uint32_t minos,
+ tb_uint32_t sdk) {
if (xm_utils_bin2macho_is_64bit(arch)) {
- return xm_utils_bin2macho_dump_64(istream, ostream, symbol_prefix, plat, arch, basename);
+ return xm_utils_bin2macho_dump_64(istream, ostream, symbol_prefix, plat, arch, basename, minos, sdk);
} else {
// 32-bit not implemented yet
return tb_false;
@@ -537,6 +579,14 @@ tb_int_t xm_utils_bin2macho(lua_State *lua) {
// get basename (optional)
tb_char_t const *basename = lua_isstring(lua, 6) ? lua_tostring(lua, 6) : tb_null;
+ // get minos version string (optional)
+ tb_char_t const *minos_str = lua_isstring(lua, 7) ? lua_tostring(lua, 7) : tb_null;
+ tb_uint32_t minos = xm_utils_bin2macho_parse_version(minos_str);
+
+ // get sdk version string (optional)
+ tb_char_t const *sdk_str = lua_isstring(lua, 8) ? lua_tostring(lua, 8) : tb_null;
+ tb_uint32_t sdk = xm_utils_bin2macho_parse_version(sdk_str);
+
// do dump
tb_bool_t ok = tb_false;
tb_stream_ref_t istream = tb_stream_init_from_file(binaryfile, TB_FILE_MODE_RO);
@@ -555,7 +605,7 @@ tb_int_t xm_utils_bin2macho(lua_State *lua) {
break;
}
- if (!xm_utils_bin2macho_dump(istream, ostream, symbol_prefix, plat, arch, basename)) {
+ if (!xm_utils_bin2macho_dump(istream, ostream, symbol_prefix, plat, arch, basename, minos, sdk)) {
lua_pushboolean(lua, tb_false);
lua_pushfstring(lua, "bin2macho: dump data failed");
break;
diff --git a/xmake/core/sandbox/modules/utils.lua b/xmake/core/sandbox/modules/utils.lua
index b6dfedd45..b3453cb92 100644
--- a/xmake/core/sandbox/modules/utils.lua
+++ b/xmake/core/sandbox/modules/utils.lua
@@ -170,8 +170,8 @@ end
-- generate Mach-O object file from the binary file
if utils.bin2macho then
- function sandbox_utils.bin2macho(binaryfile, outputfile, symbol_prefix, plat, arch, basename)
- local ok, errors = utils.bin2macho(binaryfile, outputfile, symbol_prefix, plat, arch, basename)
+ function sandbox_utils.bin2macho(binaryfile, outputfile, symbol_prefix, plat, arch, basename, target_minver, xcode_sdkver)
+ local ok, errors = utils.bin2macho(binaryfile, outputfile, symbol_prefix, plat, arch, basename, target_minver, xcode_sdkver)
if not ok then
os.raise(errors)
end
diff --git a/xmake/modules/private/utils/bin2obj.lua b/xmake/modules/private/utils/bin2obj.lua
index a27f5c5dc..a41c919fe 100644
--- a/xmake/modules/private/utils/bin2obj.lua
+++ b/xmake/modules/private/utils/bin2obj.lua
@@ -25,14 +25,16 @@ local options = {
{'i', "binarypath", "kv", nil, "Set the binary file path."},
{'o', "outputpath", "kv", nil, "Set the output object file path."},
{'f', "format", "kv", nil, "Set the object file format (coff, elf, macho)."},
- {nil, "symbol-prefix", "kv", nil, "Set the symbol prefix (default: _binary_)."},
+ {nil, "symbol_prefix", "kv", nil, "Set the symbol prefix (default: _binary_)."},
{'a', "arch", "kv", nil, "Set the target architecture."},
- {'p', "plat", "kv", nil, "Set the target platform (macosx, iphoneos, etc.)."}
+ {'p', "plat", "kv", nil, "Set the target platform (macosx, iphoneos, etc.)."},
+ {nil, "target_minver", "kv", nil, "Set the target minimum version (e.g., 10.0, 18.2)."},
+ {nil, "xcode_sdkver", "kv", nil, "Set the Xcode SDK version (e.g., 10.0, 18.2)."}
}
function _do_bin2obj_coff(binarypath, outputpath, opt)
-- get symbol prefix
- local symbol_prefix = opt["symbol-prefix"] or "_binary_"
+ local symbol_prefix = opt.symbol_prefix or "_binary_"
-- get architecture (default: x86_64)
local arch = opt.arch or "x86_64"
@@ -65,7 +67,7 @@ end
function _do_bin2obj_macho(binarypath, outputpath, opt)
-- get symbol prefix
- local symbol_prefix = opt["symbol-prefix"] or "_binary_"
+ local symbol_prefix = opt.symbol_prefix or "_binary_"
-- get platform (default: macosx)
local plat = opt.plat or "macosx"
@@ -73,6 +75,12 @@ function _do_bin2obj_macho(binarypath, outputpath, opt)
-- get architecture (default: x86_64)
local arch = opt.arch or "x86_64"
+ -- get target minimum version (default: nil, will use default 10.0.0 in C)
+ local target_minver = opt.target_minver
+
+ -- get xcode sdk version (default: nil, will use default 10.0.0 in C)
+ local xcode_sdkver = opt.xcode_sdkver
+
-- get filename from binary path (with extension, dots replaced with underscores)
local filename = path.filename(binarypath)
-- replace dots with underscores for symbol name (e.g., data.bin -> data_bin)
@@ -83,7 +91,7 @@ function _do_bin2obj_macho(binarypath, outputpath, opt)
-- do dump
if utils.bin2macho then
- utils.bin2macho(binarypath, outputpath, symbol_prefix, plat, arch, basename)
+ utils.bin2macho(binarypath, outputpath, symbol_prefix, plat, arch, basename, target_minver, xcode_sdkver)
else
raise("bin2obj: utils.bin2macho not available (C implementation not compiled)")
end
diff --git a/xmake/rules/utils/bin2obj/xmake.lua b/xmake/rules/utils/bin2obj/xmake.lua
index def3f56e8..1f8e6e0b2 100644
--- a/xmake/rules/utils/bin2obj/xmake.lua
+++ b/xmake/rules/utils/bin2obj/xmake.lua
@@ -53,6 +53,17 @@ rule("utils.bin2obj")
-- get platform
local plat = target:plat()
+ -- get target_minver and xcode_sdkver from xcode toolchain (if available)
+ local target_minver = nil
+ local xcode_sdkver = nil
+ if format == "macho" then
+ local toolchain = target:toolchain("xcode")
+ if toolchain then
+ target_minver = toolchain:config("target_minver")
+ xcode_sdkver = toolchain:config("xcode_sdkver")
+ end
+ end
+
-- convert binary file to object file
local argv = {
"-i", path(sourcefile_bin),
@@ -62,8 +73,13 @@ rule("utils.bin2obj")
"-p", plat
}
if symbol_prefix ~= "_binary_" then
- table.insert(argv, "--symbol-prefix")
- table.insert(argv, symbol_prefix)
+ table.insert(argv, "--symbol_prefix=" .. symbol_prefix)
+ end
+ if target_minver then
+ table.insert(argv, "--target_minver=" .. target_minver)
+ end
+ if xcode_sdkver then
+ table.insert(argv, "--xcode_sdkver=" .. xcode_sdkver)
end
batchcmds:vlua("private.utils.bin2obj", argv)