test/link/macho: upgrade and migrate headerpad test

This commit is contained in:
Jakub Konka 2024-01-14 00:17:23 +01:00
parent 9533628ca0
commit 2c0c86944e
4 changed files with 109 additions and 144 deletions

View File

@ -127,10 +127,6 @@ pub const cases = [_]Case{
.build_root = "test/link/macho/entry_in_archive",
.import = @import("link/macho/entry_in_archive/build.zig"),
},
.{
.build_root = "test/link/macho/headerpad",
.import = @import("link/macho/headerpad/build.zig"),
},
.{
.build_root = "test/link/macho/linksection",
.import = @import("link/macho/linksection/build.zig"),

View File

@ -24,6 +24,7 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
// Tests requiring presence of macOS SDK in system path
if (build_opts.has_macos_sdk) {
macho_step.dependOn(testHeaderpad(b, .{ .target = b.host }));
macho_step.dependOn(testNeededFramework(b, .{ .target = b.host }));
}
}
@ -166,6 +167,113 @@ fn testEntryPointDylib(b: *Build, opts: Options) *Step {
return test_step;
}
fn testHeaderpad(b: *Build, opts: Options) *Step {
const test_step = addTestStep(b, "macho-headerpad", opts);
const addExe = struct {
fn addExe(bb: *Build, o: Options, name: []const u8) *Compile {
const exe = addExecutable(bb, o, .{
.name = name,
.c_source_bytes = "int main() { return 0; }",
});
exe.linkFramework("CoreFoundation");
exe.linkFramework("Foundation");
exe.linkFramework("Cocoa");
exe.linkFramework("CoreGraphics");
exe.linkFramework("CoreHaptics");
exe.linkFramework("CoreAudio");
exe.linkFramework("AVFoundation");
exe.linkFramework("CoreImage");
exe.linkFramework("CoreLocation");
exe.linkFramework("CoreML");
exe.linkFramework("CoreVideo");
exe.linkFramework("CoreText");
exe.linkFramework("CryptoKit");
exe.linkFramework("GameKit");
exe.linkFramework("SwiftUI");
exe.linkFramework("StoreKit");
exe.linkFramework("SpriteKit");
return exe;
}
}.addExe;
{
const exe = addExe(b, opts, "main1");
exe.headerpad_max_install_names = true;
const check = exe.checkObject();
check.checkInHeaders();
check.checkExact("sectname __text");
check.checkExtract("offset {offset}");
switch (opts.target.result.cpu.arch) {
.aarch64 => check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x4000 } }),
.x86_64 => check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x1000 } }),
else => unreachable,
}
test_step.dependOn(&check.step);
const run = addRunArtifact(exe);
run.expectExitCode(0);
test_step.dependOn(&run.step);
}
{
const exe = addExe(b, opts, "main2");
exe.headerpad_size = 0x10000;
const check = exe.checkObject();
check.checkInHeaders();
check.checkExact("sectname __text");
check.checkExtract("offset {offset}");
check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x10000 } });
test_step.dependOn(&check.step);
const run = addRunArtifact(exe);
run.expectExitCode(0);
test_step.dependOn(&run.step);
}
{
const exe = addExe(b, opts, "main3");
exe.headerpad_max_install_names = true;
exe.headerpad_size = 0x10000;
const check = exe.checkObject();
check.checkInHeaders();
check.checkExact("sectname __text");
check.checkExtract("offset {offset}");
check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x10000 } });
test_step.dependOn(&check.step);
const run = addRunArtifact(exe);
run.expectExitCode(0);
test_step.dependOn(&run.step);
}
{
const exe = addExe(b, opts, "main4");
exe.headerpad_max_install_names = true;
exe.headerpad_size = 0x1000;
const check = exe.checkObject();
check.checkInHeaders();
check.checkExact("sectname __text");
check.checkExtract("offset {offset}");
switch (opts.target.result.cpu.arch) {
.aarch64 => check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x4000 } }),
.x86_64 => check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x1000 } }),
else => unreachable,
}
test_step.dependOn(&check.step);
const run = addRunArtifact(exe);
run.expectExitCode(0);
test_step.dependOn(&run.step);
}
return test_step;
}
// Adapted from https://github.com/llvm/llvm-project/blob/main/lld/test/MachO/weak-header-flags.s
fn testHeaderWeakFlags(b: *Build, opts: Options) *Step {
const test_step = addTestStep(b, "macho-header-weak-flags", opts);
@ -537,5 +645,6 @@ const std = @import("std");
const Build = std.Build;
const BuildOptions = link.BuildOptions;
const Compile = Step.Compile;
const Options = link.Options;
const Step = Build.Step;

View File

@ -1,137 +0,0 @@
const std = @import("std");
const builtin = @import("builtin");
pub const requires_symlinks = true;
pub const requires_macos_sdk = true;
pub fn build(b: *std.Build) void {
const test_step = b.step("test", "Test it");
b.default_step = test_step;
add(b, test_step, .Debug);
add(b, test_step, .ReleaseFast);
add(b, test_step, .ReleaseSmall);
add(b, test_step, .ReleaseSafe);
}
fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
{
// Test -headerpad_max_install_names
const exe = simpleExe(b, optimize, "headerpad_max_install_names");
exe.headerpad_max_install_names = true;
const check = exe.checkObject();
check.checkInHeaders();
check.checkExact("sectname __text");
check.checkExtract("offset {offset}");
switch (builtin.cpu.arch) {
.aarch64 => {
check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x4000 } });
},
.x86_64 => {
check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x1000 } });
},
else => unreachable,
}
test_step.dependOn(&check.step);
const run = b.addRunArtifact(exe);
test_step.dependOn(&run.step);
}
{
// Test -headerpad
const exe = simpleExe(b, optimize, "headerpad");
exe.headerpad_size = 0x10000;
const check = exe.checkObject();
check.checkInHeaders();
check.checkExact("sectname __text");
check.checkExtract("offset {offset}");
check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x10000 } });
test_step.dependOn(&check.step);
const run = b.addRunArtifact(exe);
test_step.dependOn(&run.step);
}
{
// Test both flags with -headerpad overriding -headerpad_max_install_names
const exe = simpleExe(b, optimize, "headerpad_overriding");
exe.headerpad_max_install_names = true;
exe.headerpad_size = 0x10000;
const check = exe.checkObject();
check.checkInHeaders();
check.checkExact("sectname __text");
check.checkExtract("offset {offset}");
check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x10000 } });
test_step.dependOn(&check.step);
const run = b.addRunArtifact(exe);
test_step.dependOn(&run.step);
}
{
// Test both flags with -headerpad_max_install_names overriding -headerpad
const exe = simpleExe(b, optimize, "headerpad_max_install_names_overriding");
exe.headerpad_size = 0x1000;
exe.headerpad_max_install_names = true;
const check = exe.checkObject();
check.checkInHeaders();
check.checkExact("sectname __text");
check.checkExtract("offset {offset}");
switch (builtin.cpu.arch) {
.aarch64 => {
check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x4000 } });
},
.x86_64 => {
check.checkComputeCompare("offset", .{ .op = .gte, .value = .{ .literal = 0x1000 } });
},
else => unreachable,
}
test_step.dependOn(&check.step);
const run = b.addRunArtifact(exe);
test_step.dependOn(&run.step);
}
}
fn simpleExe(
b: *std.Build,
optimize: std.builtin.OptimizeMode,
name: []const u8,
) *std.Build.Step.Compile {
const exe = b.addExecutable(.{
.name = name,
.optimize = optimize,
.target = b.host,
});
exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
exe.linkLibC();
exe.linkFramework("CoreFoundation");
exe.linkFramework("Foundation");
exe.linkFramework("Cocoa");
exe.linkFramework("CoreGraphics");
exe.linkFramework("CoreHaptics");
exe.linkFramework("CoreAudio");
exe.linkFramework("AVFoundation");
exe.linkFramework("CoreImage");
exe.linkFramework("CoreLocation");
exe.linkFramework("CoreML");
exe.linkFramework("CoreVideo");
exe.linkFramework("CoreText");
exe.linkFramework("CryptoKit");
exe.linkFramework("GameKit");
exe.linkFramework("SwiftUI");
exe.linkFramework("StoreKit");
exe.linkFramework("SpriteKit");
return exe;
}

View File

@ -1,3 +0,0 @@
int main(int argc, char* argv[]) {
return 0;
}