| author | |
| committer | |
| log | 589bf67635a9fe9c3e6df4b63c09e0cc4954d29a |
| tree | c8e26db7d4f8d83facb6b4a91514bbbff496ed78 |
| parent | a6fbdfabb9b60262594da012b8d877a43d8d8e99 |
13 files changed, 180 insertions(+), 61 deletions(-)
lib/std/build.zig+2-2| ... | ... | @@ -1595,7 +1595,7 @@ pub const LibExeObjStep = struct { |
| 1595 | 1595 | |
| 1596 | 1596 | /// (Darwin) Set size of the padding between the end of load commands |
| 1597 | 1597 | /// and start of `__TEXT,__text` section. |
| 1598 | headerpad_size: ?u64 = null, | |
| 1598 | headerpad_size: ?u32 = null, | |
| 1599 | 1599 | |
| 1600 | 1600 | /// (Darwin) Automatically Set size of the padding between the end of load commands |
| 1601 | 1601 | /// and start of `__TEXT,__text` section to a value fitting all paths expanded to MAXPATHLEN. |
| ... | ... | @@ -2671,7 +2671,7 @@ pub const LibExeObjStep = struct { |
| 2671 | 2671 | }; |
| 2672 | 2672 | if (self.headerpad_size) |headerpad_size| { |
| 2673 | 2673 | const size = try std.fmt.allocPrint(builder.allocator, "{x}", .{headerpad_size}); |
| 2674 | try zig_args.appendSlice(&[_][]const u8{ "-headerpad_size", size }); | |
| 2674 | try zig_args.appendSlice(&[_][]const u8{ "-headerpad", size }); | |
| 2675 | 2675 | } |
| 2676 | 2676 | if (self.headerpad_max_install_names) { |
| 2677 | 2677 | try zig_args.append("-headerpad_max_install_names"); |
src/Compilation.zig+5-3| ... | ... | @@ -908,7 +908,7 @@ pub const InitOptions = struct { |
| 908 | 908 | /// (Darwin) search strategy for system libraries |
| 909 | 909 | search_strategy: ?link.File.MachO.SearchStrategy = null, |
| 910 | 910 | /// (Darwin) set minimum space for future expansion of the load commands |
| 911 | headerpad_size: ?u64 = null, | |
| 911 | headerpad_size: ?u32 = null, | |
| 912 | 912 | /// (Darwin) set enough space as if all paths were MATPATHLEN |
| 913 | 913 | headerpad_max_install_names: bool = false, |
| 914 | 914 | }; |
| ... | ... | @@ -2369,7 +2369,7 @@ fn prepareWholeEmitSubPath(arena: Allocator, opt_emit: ?EmitLoc) error{OutOfMemo |
| 2369 | 2369 | /// to remind the programmer to update multiple related pieces of code that |
| 2370 | 2370 | /// are in different locations. Bump this number when adding or deleting |
| 2371 | 2371 | /// anything from the link cache manifest. |
| 2372 | pub const link_hash_implementation_version = 5; | |
| 2372 | pub const link_hash_implementation_version = 6; | |
| 2373 | 2373 | |
| 2374 | 2374 | fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifest) !void { |
| 2375 | 2375 | const gpa = comp.gpa; |
| ... | ... | @@ -2379,7 +2379,7 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2379 | 2379 | defer arena_allocator.deinit(); |
| 2380 | 2380 | const arena = arena_allocator.allocator(); |
| 2381 | 2381 | |
| 2382 | comptime assert(link_hash_implementation_version == 5); | |
| 2382 | comptime assert(link_hash_implementation_version == 6); | |
| 2383 | 2383 | |
| 2384 | 2384 | if (comp.bin_file.options.module) |mod| { |
| 2385 | 2385 | const main_zig_file = try mod.main_pkg.root_src_directory.join(arena, &[_][]const u8{ |
| ... | ... | @@ -2486,6 +2486,8 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2486 | 2486 | try man.addOptionalFile(comp.bin_file.options.entitlements); |
| 2487 | 2487 | man.hash.addOptional(comp.bin_file.options.pagezero_size); |
| 2488 | 2488 | man.hash.addOptional(comp.bin_file.options.search_strategy); |
| 2489 | man.hash.addOptional(comp.bin_file.options.headerpad_size); | |
| 2490 | man.hash.add(comp.bin_file.options.headerpad_max_install_names); | |
| 2489 | 2491 | |
| 2490 | 2492 | // COFF specific stuff |
| 2491 | 2493 | man.hash.addOptional(comp.bin_file.options.subsystem); |
src/link.zig+1-1| ... | ... | @@ -194,7 +194,7 @@ pub const Options = struct { |
| 194 | 194 | search_strategy: ?File.MachO.SearchStrategy = null, |
| 195 | 195 | |
| 196 | 196 | /// (Darwin) set minimum space for future expansion of the load commands |
| 197 | headerpad_size: ?u64 = null, | |
| 197 | headerpad_size: ?u32 = null, | |
| 198 | 198 | |
| 199 | 199 | /// (Darwin) set enough space as if all paths were MATPATHLEN |
| 200 | 200 | headerpad_max_install_names: bool = false, |
src/link/Coff.zig+1-1| ... | ... | @@ -969,7 +969,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 969 | 969 | man = comp.cache_parent.obtain(); |
| 970 | 970 | self.base.releaseLock(); |
| 971 | 971 | |
| 972 | comptime assert(Compilation.link_hash_implementation_version == 5); | |
| 972 | comptime assert(Compilation.link_hash_implementation_version == 6); | |
| 973 | 973 | |
| 974 | 974 | for (self.base.options.objects) |obj| { |
| 975 | 975 | _ = try man.addFile(obj.path, null); |
src/link/Elf.zig+1-1| ... | ... | @@ -1298,7 +1298,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node) !v |
| 1298 | 1298 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 1299 | 1299 | self.base.releaseLock(); |
| 1300 | 1300 | |
| 1301 | comptime assert(Compilation.link_hash_implementation_version == 5); | |
| 1301 | comptime assert(Compilation.link_hash_implementation_version == 6); | |
| 1302 | 1302 | |
| 1303 | 1303 | try man.addOptionalFile(self.base.options.linker_script); |
| 1304 | 1304 | try man.addOptionalFile(self.base.options.version_script); |
src/link/MachO.zig+35-18| ... | ... | @@ -69,9 +69,6 @@ page_size: u16, |
| 69 | 69 | /// and potentially stage2 release builds in the future. |
| 70 | 70 | needs_prealloc: bool = true, |
| 71 | 71 | |
| 72 | /// Size of the padding between the end of load commands and start of the '__TEXT,__text' section. | |
| 73 | headerpad_size: u64, | |
| 74 | ||
| 75 | 72 | /// The absolute address of the entry point. |
| 76 | 73 | entry_addr: ?u64 = null, |
| 77 | 74 | |
| ... | ... | @@ -296,7 +293,7 @@ const default_pagezero_vmsize: u64 = 0x100000000; |
| 296 | 293 | /// We commit 0x1000 = 4096 bytes of space to the header and |
| 297 | 294 | /// the table of load commands. This should be plenty for any |
| 298 | 295 | /// potential future extensions. |
| 299 | const default_headerpad_size: u64 = 0x1000; | |
| 296 | const default_headerpad_size: u32 = 0x1000; | |
| 300 | 297 | |
| 301 | 298 | pub const Export = struct { |
| 302 | 299 | sym_index: ?u32 = null, |
| ... | ... | @@ -403,12 +400,6 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO { |
| 403 | 400 | const use_llvm = build_options.have_llvm and options.use_llvm; |
| 404 | 401 | const use_stage1 = build_options.is_stage1 and options.use_stage1; |
| 405 | 402 | const needs_prealloc = !(use_stage1 or use_llvm or options.cache_mode == .whole); |
| 406 | // TODO handle `headerpad_max_install_names` in incremental context | |
| 407 | const explicit_headerpad_size = options.headerpad_size orelse 0; | |
| 408 | const headerpad_size = if (needs_prealloc) | |
| 409 | @maximum(explicit_headerpad_size, default_headerpad_size) | |
| 410 | else | |
| 411 | explicit_headerpad_size; | |
| 412 | 403 | |
| 413 | 404 | const self = try gpa.create(MachO); |
| 414 | 405 | errdefer gpa.destroy(self); |
| ... | ... | @@ -421,7 +412,6 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*MachO { |
| 421 | 412 | .file = null, |
| 422 | 413 | }, |
| 423 | 414 | .page_size = page_size, |
| 424 | .headerpad_size = headerpad_size, | |
| 425 | 415 | .code_signature = if (requires_adhoc_codesig) CodeSignature.init(page_size) else null, |
| 426 | 416 | .needs_prealloc = needs_prealloc, |
| 427 | 417 | }; |
| ... | ... | @@ -551,7 +541,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 551 | 541 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 552 | 542 | self.base.releaseLock(); |
| 553 | 543 | |
| 554 | comptime assert(Compilation.link_hash_implementation_version == 5); | |
| 544 | comptime assert(Compilation.link_hash_implementation_version == 6); | |
| 555 | 545 | |
| 556 | 546 | for (self.base.options.objects) |obj| { |
| 557 | 547 | _ = try man.addFile(obj.path, null); |
| ... | ... | @@ -566,6 +556,8 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 566 | 556 | man.hash.add(stack_size); |
| 567 | 557 | man.hash.addOptional(self.base.options.pagezero_size); |
| 568 | 558 | man.hash.addOptional(self.base.options.search_strategy); |
| 559 | man.hash.addOptional(self.base.options.headerpad_size); | |
| 560 | man.hash.add(self.base.options.headerpad_max_install_names); | |
| 569 | 561 | man.hash.addListOfBytes(self.base.options.lib_dirs); |
| 570 | 562 | man.hash.addListOfBytes(self.base.options.framework_dirs); |
| 571 | 563 | man.hash.addListOfBytes(self.base.options.frameworks); |
| ... | ... | @@ -4470,9 +4462,10 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 4470 | 4462 | if (self.text_segment_cmd_index == null) { |
| 4471 | 4463 | self.text_segment_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 4472 | 4464 | const needed_size = if (self.needs_prealloc) blk: { |
| 4465 | const headerpad_size = @maximum(self.base.options.headerpad_size orelse 0, default_headerpad_size); | |
| 4473 | 4466 | const program_code_size_hint = self.base.options.program_code_size_hint; |
| 4474 | 4467 | const got_size_hint = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4475 | const ideal_size = self.headerpad_size + program_code_size_hint + got_size_hint; | |
| 4468 | const ideal_size = headerpad_size + program_code_size_hint + got_size_hint; | |
| 4476 | 4469 | const needed_size = mem.alignForwardGeneric(u64, padToIdeal(ideal_size), self.page_size); |
| 4477 | 4470 | log.debug("found __TEXT segment free space 0x{x} to 0x{x}", .{ 0, needed_size }); |
| 4478 | 4471 | break :blk needed_size; |
| ... | ... | @@ -4975,13 +4968,34 @@ fn allocateTextSegment(self: *MachO) !void { |
| 4975 | 4968 | seg.inner.fileoff = 0; |
| 4976 | 4969 | seg.inner.vmaddr = base_vmaddr; |
| 4977 | 4970 | |
| 4978 | var sizeofcmds: u64 = 0; | |
| 4971 | var sizeofcmds: u32 = 0; | |
| 4979 | 4972 | for (self.load_commands.items) |lc| { |
| 4980 | 4973 | sizeofcmds += lc.cmdsize(); |
| 4981 | 4974 | } |
| 4982 | 4975 | |
| 4983 | // TODO verify if `headerpad_max_install_names` leads to larger padding size | |
| 4984 | const offset = @sizeOf(macho.mach_header_64) + sizeofcmds + self.headerpad_size; | |
| 4976 | var padding: u32 = sizeofcmds + (self.base.options.headerpad_size orelse 0); | |
| 4977 | log.debug("minimum requested headerpad size 0x{x}", .{padding + @sizeOf(macho.mach_header_64)}); | |
| 4978 | ||
| 4979 | if (self.base.options.headerpad_max_install_names) { | |
| 4980 | var min_headerpad_size: u32 = 0; | |
| 4981 | for (self.load_commands.items) |lc| switch (lc.cmd()) { | |
| 4982 | .ID_DYLIB, | |
| 4983 | .LOAD_WEAK_DYLIB, | |
| 4984 | .LOAD_DYLIB, | |
| 4985 | .REEXPORT_DYLIB, | |
| 4986 | => { | |
| 4987 | min_headerpad_size += @sizeOf(macho.dylib_command) + std.os.PATH_MAX + 1; | |
| 4988 | }, | |
| 4989 | ||
| 4990 | else => {}, | |
| 4991 | }; | |
| 4992 | log.debug("headerpad_max_install_names minimum headerpad size 0x{x}", .{ | |
| 4993 | min_headerpad_size + @sizeOf(macho.mach_header_64), | |
| 4994 | }); | |
| 4995 | padding = @maximum(padding, min_headerpad_size); | |
| 4996 | } | |
| 4997 | const offset = @sizeOf(macho.mach_header_64) + padding; | |
| 4998 | log.debug("actual headerpad size 0x{x}", .{offset}); | |
| 4985 | 4999 | try self.allocateSegment(self.text_segment_cmd_index.?, offset); |
| 4986 | 5000 | |
| 4987 | 5001 | // Shift all sections to the back to minimize jump size between __TEXT and __DATA segments. |
| ... | ... | @@ -5109,7 +5123,10 @@ fn initSection( |
| 5109 | 5123 | |
| 5110 | 5124 | if (self.needs_prealloc) { |
| 5111 | 5125 | const alignment_pow_2 = try math.powi(u32, 2, alignment); |
| 5112 | const padding: ?u64 = if (segment_id == self.text_segment_cmd_index.?) self.headerpad_size else null; | |
| 5126 | const padding: ?u32 = if (segment_id == self.text_segment_cmd_index.?) | |
| 5127 | @maximum(self.base.options.headerpad_size orelse 0, default_headerpad_size) | |
| 5128 | else | |
| 5129 | null; | |
| 5113 | 5130 | const off = self.findFreeSpace(segment_id, alignment_pow_2, padding); |
| 5114 | 5131 | log.debug("allocating {s},{s} section from 0x{x} to 0x{x}", .{ |
| 5115 | 5132 | sect.segName(), |
| ... | ... | @@ -5148,7 +5165,7 @@ fn initSection( |
| 5148 | 5165 | return index; |
| 5149 | 5166 | } |
| 5150 | 5167 | |
| 5151 | fn findFreeSpace(self: MachO, segment_id: u16, alignment: u64, start: ?u64) u64 { | |
| 5168 | fn findFreeSpace(self: MachO, segment_id: u16, alignment: u64, start: ?u32) u64 { | |
| 5152 | 5169 | const seg = self.load_commands.items[segment_id].segment; |
| 5153 | 5170 | if (seg.sections.items.len == 0) { |
| 5154 | 5171 | return if (start) |v| v else seg.inner.fileoff; |
src/link/Wasm.zig+1-1| ... | ... | @@ -2481,7 +2481,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) ! |
| 2481 | 2481 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 2482 | 2482 | self.base.releaseLock(); |
| 2483 | 2483 | |
| 2484 | comptime assert(Compilation.link_hash_implementation_version == 5); | |
| 2484 | comptime assert(Compilation.link_hash_implementation_version == 6); | |
| 2485 | 2485 | |
| 2486 | 2486 | for (self.base.options.objects) |obj| { |
| 2487 | 2487 | _ = try man.addFile(obj.path, null); |
src/main.zig+6-6| ... | ... | @@ -450,7 +450,7 @@ const usage_build_generic = |
| 450 | 450 | \\ -pagezero_size [value] (Darwin) size of the __PAGEZERO segment in hexadecimal notation |
| 451 | 451 | \\ -search_paths_first (Darwin) search each dir in library search paths for `libx.dylib` then `libx.a` |
| 452 | 452 | \\ -search_dylibs_first (Darwin) search `libx.dylib` in each dir in library search paths, then `libx.a` |
| 453 | \\ -headerpad_size [value] (Darwin) set minimum space for future expansion of the load commands in hexadecimal notation | |
| 453 | \\ -headerpad [value] (Darwin) set minimum space for future expansion of the load commands in hexadecimal notation | |
| 454 | 454 | \\ -headerpad_max_install_names (Darwin) set enough space as if all paths were MAXPATHLEN |
| 455 | 455 | \\ --import-memory (WebAssembly) import memory from the environment |
| 456 | 456 | \\ --import-table (WebAssembly) import function table from the host environment |
| ... | ... | @@ -701,7 +701,7 @@ fn buildOutputType( |
| 701 | 701 | var entitlements: ?[]const u8 = null; |
| 702 | 702 | var pagezero_size: ?u64 = null; |
| 703 | 703 | var search_strategy: ?link.File.MachO.SearchStrategy = null; |
| 704 | var headerpad_size: ?u64 = null; | |
| 704 | var headerpad_size: ?u32 = null; | |
| 705 | 705 | var headerpad_max_install_names: bool = false; |
| 706 | 706 | |
| 707 | 707 | // e.g. -m3dnow or -mno-outline-atomics. They correspond to std.Target llvm cpu feature names. |
| ... | ... | @@ -928,11 +928,11 @@ fn buildOutputType( |
| 928 | 928 | search_strategy = .paths_first; |
| 929 | 929 | } else if (mem.eql(u8, arg, "-search_dylibs_first")) { |
| 930 | 930 | search_strategy = .dylibs_first; |
| 931 | } else if (mem.eql(u8, arg, "-headerpad_size")) { | |
| 931 | } else if (mem.eql(u8, arg, "-headerpad")) { | |
| 932 | 932 | const next_arg = args_iter.next() orelse { |
| 933 | 933 | fatal("expected parameter after {s}", .{arg}); |
| 934 | 934 | }; |
| 935 | headerpad_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| { | |
| 935 | headerpad_size = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| { | |
| 936 | 936 | fatal("unable to parser '{s}': {s}", .{ arg, @errorName(err) }); |
| 937 | 937 | }; |
| 938 | 938 | } else if (mem.eql(u8, arg, "-headerpad_max_install_names")) { |
| ... | ... | @@ -1689,13 +1689,13 @@ fn buildOutputType( |
| 1689 | 1689 | pagezero_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| { |
| 1690 | 1690 | fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); |
| 1691 | 1691 | }; |
| 1692 | } else if (mem.eql(u8, arg, "-headerpad_size")) { | |
| 1692 | } else if (mem.eql(u8, arg, "-headerpad")) { | |
| 1693 | 1693 | i += 1; |
| 1694 | 1694 | if (i >= linker_args.items.len) { |
| 1695 | 1695 | fatal("expected linker arg after '{s}'", .{arg}); |
| 1696 | 1696 | } |
| 1697 | 1697 | const next_arg = linker_args.items[i]; |
| 1698 | headerpad_size = std.fmt.parseUnsigned(u64, eatIntPrefix(next_arg, 16), 16) catch |err| { | |
| 1698 | headerpad_size = std.fmt.parseUnsigned(u32, eatIntPrefix(next_arg, 16), 16) catch |err| { | |
| 1699 | 1699 | fatal("unable to parse '{s}': {s}", .{ arg, @errorName(err) }); |
| 1700 | 1700 | }; |
| 1701 | 1701 | } else if (mem.eql(u8, arg, "-headerpad_max_install_names")) { |
test/link.zig+5| ... | ... | @@ -64,5 +64,10 @@ pub fn addCases(cases: *tests.StandaloneContext) void { |
| 64 | 64 | cases.addBuildFile("test/link/macho/search_strategy/build.zig", .{ |
| 65 | 65 | .build_modes = true, |
| 66 | 66 | }); |
| 67 | ||
| 68 | cases.addBuildFile("test/link/macho/headerpad/build.zig", .{ | |
| 69 | .build_modes = true, | |
| 70 | .requires_macos_sdk = true, | |
| 71 | }); | |
| 67 | 72 | } |
| 68 | 73 | } |
test/link/macho/headerpad/build.zig created+120| ... | ... | @@ -0,0 +1,120 @@ |
| 1 | const std = @import("std"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const Builder = std.build.Builder; | |
| 4 | const LibExeObjectStep = std.build.LibExeObjStep; | |
| 5 | ||
| 6 | pub fn build(b: *Builder) void { | |
| 7 | const mode = b.standardReleaseOptions(); | |
| 8 | ||
| 9 | const test_step = b.step("test", "Test"); | |
| 10 | test_step.dependOn(b.getInstallStep()); | |
| 11 | ||
| 12 | { | |
| 13 | // Test -headerpad_max_install_names | |
| 14 | const exe = simpleExe(b, mode); | |
| 15 | exe.headerpad_max_install_names = true; | |
| 16 | ||
| 17 | const check = exe.checkObject(.macho); | |
| 18 | check.checkStart("sectname __text"); | |
| 19 | check.checkNext("offset {offset}"); | |
| 20 | ||
| 21 | switch (builtin.cpu.arch) { | |
| 22 | .aarch64 => { | |
| 23 | check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x4000 } }); | |
| 24 | }, | |
| 25 | .x86_64 => { | |
| 26 | check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x1000 } }); | |
| 27 | }, | |
| 28 | else => unreachable, | |
| 29 | } | |
| 30 | ||
| 31 | test_step.dependOn(&check.step); | |
| 32 | ||
| 33 | const run = exe.run(); | |
| 34 | test_step.dependOn(&run.step); | |
| 35 | } | |
| 36 | ||
| 37 | { | |
| 38 | // Test -headerpad | |
| 39 | const exe = simpleExe(b, mode); | |
| 40 | exe.headerpad_size = 0x10000; | |
| 41 | ||
| 42 | const check = exe.checkObject(.macho); | |
| 43 | check.checkStart("sectname __text"); | |
| 44 | check.checkNext("offset {offset}"); | |
| 45 | check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x10000 } }); | |
| 46 | ||
| 47 | test_step.dependOn(&check.step); | |
| 48 | ||
| 49 | const run = exe.run(); | |
| 50 | test_step.dependOn(&run.step); | |
| 51 | } | |
| 52 | ||
| 53 | { | |
| 54 | // Test both flags with -headerpad overriding -headerpad_max_install_names | |
| 55 | const exe = simpleExe(b, mode); | |
| 56 | exe.headerpad_max_install_names = true; | |
| 57 | exe.headerpad_size = 0x10000; | |
| 58 | ||
| 59 | const check = exe.checkObject(.macho); | |
| 60 | check.checkStart("sectname __text"); | |
| 61 | check.checkNext("offset {offset}"); | |
| 62 | check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x10000 } }); | |
| 63 | ||
| 64 | test_step.dependOn(&check.step); | |
| 65 | ||
| 66 | const run = exe.run(); | |
| 67 | test_step.dependOn(&run.step); | |
| 68 | } | |
| 69 | ||
| 70 | { | |
| 71 | // Test both flags with -headerpad_max_install_names overriding -headerpad | |
| 72 | const exe = simpleExe(b, mode); | |
| 73 | exe.headerpad_size = 0x1000; | |
| 74 | exe.headerpad_max_install_names = true; | |
| 75 | ||
| 76 | const check = exe.checkObject(.macho); | |
| 77 | check.checkStart("sectname __text"); | |
| 78 | check.checkNext("offset {offset}"); | |
| 79 | ||
| 80 | switch (builtin.cpu.arch) { | |
| 81 | .aarch64 => { | |
| 82 | check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x4000 } }); | |
| 83 | }, | |
| 84 | .x86_64 => { | |
| 85 | check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x1000 } }); | |
| 86 | }, | |
| 87 | else => unreachable, | |
| 88 | } | |
| 89 | ||
| 90 | test_step.dependOn(&check.step); | |
| 91 | ||
| 92 | const run = exe.run(); | |
| 93 | test_step.dependOn(&run.step); | |
| 94 | } | |
| 95 | } | |
| 96 | ||
| 97 | fn simpleExe(b: *Builder, mode: std.builtin.Mode) *LibExeObjectStep { | |
| 98 | const exe = b.addExecutable("main", null); | |
| 99 | exe.setBuildMode(mode); | |
| 100 | exe.addCSourceFile("main.c", &.{}); | |
| 101 | exe.linkLibC(); | |
| 102 | exe.linkFramework("CoreFoundation"); | |
| 103 | exe.linkFramework("Foundation"); | |
| 104 | exe.linkFramework("Cocoa"); | |
| 105 | exe.linkFramework("CoreGraphics"); | |
| 106 | exe.linkFramework("CoreHaptics"); | |
| 107 | exe.linkFramework("CoreAudio"); | |
| 108 | exe.linkFramework("AVFoundation"); | |
| 109 | exe.linkFramework("CoreImage"); | |
| 110 | exe.linkFramework("CoreLocation"); | |
| 111 | exe.linkFramework("CoreML"); | |
| 112 | exe.linkFramework("CoreVideo"); | |
| 113 | exe.linkFramework("CoreText"); | |
| 114 | exe.linkFramework("CryptoKit"); | |
| 115 | exe.linkFramework("GameKit"); | |
| 116 | exe.linkFramework("SwiftUI"); | |
| 117 | exe.linkFramework("StoreKit"); | |
| 118 | exe.linkFramework("SpriteKit"); | |
| 119 | return exe; | |
| 120 | } |
test/link/macho/headerpad/main.c created+3| ... | ... | @@ -0,0 +1,3 @@ |
| 1 | int main(int argc, char* argv[]) { | |
| 2 | return 0; | |
| 3 | } |
test/link/macho/headerpad_size/build.zig deleted-25| ... | ... | @@ -1,25 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const Builder = std.build.Builder; | |
| 3 | ||
| 4 | pub fn build(b: *Builder) void { | |
| 5 | const mode = b.standardReleaseOptions(); | |
| 6 | ||
| 7 | const test_step = b.step("test", "Test"); | |
| 8 | test_step.dependOn(b.getInstallStep()); | |
| 9 | ||
| 10 | const exe = b.addExecutable("main", null); | |
| 11 | exe.setBuildMode(mode); | |
| 12 | exe.addCSourceFile("main.c", &.{}); | |
| 13 | exe.linkLibC(); | |
| 14 | exe.headerpad_size = 0x10000; | |
| 15 | ||
| 16 | const check = exe.checkObject(.macho); | |
| 17 | check.checkStart("sectname __text"); | |
| 18 | check.checkNext("offset {offset}"); | |
| 19 | check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x10000 } }); | |
| 20 | ||
| 21 | test_step.dependOn(&check.step); | |
| 22 | ||
| 23 | const run = exe.run(); | |
| 24 | test_step.dependOn(&run.step); | |
| 25 | } |
test/link/macho/headerpad_size/main.c deleted-3| ... | ... | @@ -1,3 +0,0 @@ |
| 1 | int main(int argc, char* argv[]) { | |
| 2 | return 0; | |
| 3 | } |