diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2022-12-23 13:55:58 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-12-23 14:02:52 +0100 |
| commit | 2cb6db22193acc802ff38f1cc4576ac1ee3f94fa (patch) | |
| tree | ea09230231a0fe10760b342537f46b024f607d0a /test | |
| parent | 550ebcce9abe9db9453509b38820756a1fff8391 (diff) | |
| download | zig-2cb6db22193acc802ff38f1cc4576ac1ee3f94fa.tar.gz zig-2cb6db22193acc802ff38f1cc4576ac1ee3f94fa.zip | |
link-tests: add macho strict validation test
Support more operators when running simple arithmetic tests, and
allow for int literals in the program spec.
Diffstat (limited to 'test')
| -rw-r--r-- | test/link.zig | 5 | ||||
| -rw-r--r-- | test/link/macho/strict_validation/build.zig | 100 | ||||
| -rw-r--r-- | test/link/macho/strict_validation/main.zig | 6 |
3 files changed, 111 insertions, 0 deletions
diff --git a/test/link.zig b/test/link.zig index 5620ac95a0..ff18d65be5 100644 --- a/test/link.zig +++ b/test/link.zig @@ -165,6 +165,11 @@ fn addMachOCases(cases: *tests.StandaloneContext) void { .requires_symlinks = true, }); + cases.addBuildFile("test/link/macho/strict_validation/build.zig", .{ + .build_modes = true, + .requires_symlinks = true, + }); + cases.addBuildFile("test/link/macho/tls/build.zig", .{ .build_modes = true, .requires_symlinks = true, diff --git a/test/link/macho/strict_validation/build.zig b/test/link/macho/strict_validation/build.zig new file mode 100644 index 0000000000..d5c00bffee --- /dev/null +++ b/test/link/macho/strict_validation/build.zig @@ -0,0 +1,100 @@ +const std = @import("std"); +const builtin = @import("builtin"); +const Builder = std.build.Builder; +const LibExeObjectStep = std.build.LibExeObjStep; + +pub fn build(b: *Builder) void { + const mode = b.standardReleaseOptions(); + const target: std.zig.CrossTarget = .{ .os_tag = .macos }; + + const test_step = b.step("test", "Test"); + test_step.dependOn(b.getInstallStep()); + + const exe = b.addExecutable("main", "main.zig"); + exe.setBuildMode(mode); + exe.setTarget(target); + exe.linkLibC(); + + const check_exe = exe.checkObject(.macho); + + check_exe.checkStart("cmd SEGMENT_64"); + check_exe.checkNext("segname __LINKEDIT"); + check_exe.checkNext("fileoff {fileoff}"); + check_exe.checkNext("filesz {filesz}"); + + check_exe.checkStart("cmd DYLD_INFO_ONLY"); + check_exe.checkNext("rebaseoff {rebaseoff}"); + check_exe.checkNext("rebasesize {rebasesize}"); + check_exe.checkNext("bindoff {bindoff}"); + check_exe.checkNext("bindsize {bindsize}"); + check_exe.checkNext("lazybindoff {lazybindoff}"); + check_exe.checkNext("lazybindsize {lazybindsize}"); + check_exe.checkNext("exportoff {exportoff}"); + check_exe.checkNext("exportsize {exportsize}"); + + check_exe.checkStart("cmd SYMTAB"); + check_exe.checkNext("symoff {symoff}"); + check_exe.checkNext("stroff {stroff}"); + check_exe.checkNext("strsize {strsize}"); + + check_exe.checkStart("cmd DYSYMTAB"); + check_exe.checkNext("indirectsymoff {dysymoff}"); + + switch (builtin.cpu.arch) { + .aarch64 => { + check_exe.checkStart("cmd CODE_SIGNATURE"); + check_exe.checkNext("dataoff {codesigoff}"); + check_exe.checkNext("datasize {codesigsize}"); + }, + .x86_64 => {}, + else => unreachable, + } + + // Next check: DYLD_INFO_ONLY subsections are in order: rebase < bind < lazy < export + check_exe.checkComputeCompare("rebaseoff ", .{ .op = .lt, .value = .{ .variable = "bindoff" } }); + check_exe.checkComputeCompare("bindoff", .{ .op = .lt, .value = .{ .variable = "lazybindoff" } }); + check_exe.checkComputeCompare("lazybindoff", .{ .op = .lt, .value = .{ .variable = "exportoff" } }); + + // Next check: DYLD_INFO_ONLY subsections do not overlap + check_exe.checkComputeCompare("rebaseoff rebasesize +", .{ .op = .lte, .value = .{ .variable = "bindoff" } }); + check_exe.checkComputeCompare("bindoff bindsize +", .{ .op = .lte, .value = .{ .variable = "lazybindoff" } }); + check_exe.checkComputeCompare("lazybindoff lazybindsize +", .{ .op = .lte, .value = .{ .variable = "exportoff" } }); + + // Next check: we maintain order: symtab < dysymtab < strtab + check_exe.checkComputeCompare("symoff", .{ .op = .lt, .value = .{ .variable = "dysymoff" } }); + check_exe.checkComputeCompare("dysymoff", .{ .op = .lt, .value = .{ .variable = "stroff" } }); + + // Next check: all LINKEDIT sections apart from CODE_SIGNATURE are 8-bytes aligned + check_exe.checkComputeCompare("rebaseoff 8 %", .{ .op = .eq, .value = .{ .literal = 0 } }); + check_exe.checkComputeCompare("bindoff 8 %", .{ .op = .eq, .value = .{ .literal = 0 } }); + check_exe.checkComputeCompare("lazybindoff 8 %", .{ .op = .eq, .value = .{ .literal = 0 } }); + check_exe.checkComputeCompare("exportoff 8 %", .{ .op = .eq, .value = .{ .literal = 0 } }); + check_exe.checkComputeCompare("symoff 8 %", .{ .op = .eq, .value = .{ .literal = 0 } }); + check_exe.checkComputeCompare("stroff 8 %", .{ .op = .eq, .value = .{ .literal = 0 } }); + check_exe.checkComputeCompare("dysymoff 8 %", .{ .op = .eq, .value = .{ .literal = 0 } }); + + switch (builtin.cpu.arch) { + .aarch64 => { + // Next check: LINKEDIT segment does not extend beyond, or does not include, CODE_SIGNATURE data + check_exe.checkComputeCompare("fileoff filesz codesigoff codesigsize + - -", .{ + .op = .eq, + .value = .{ .literal = 0 }, + }); + + // Next check: CODE_SIGNATURE data offset is 16-bytes aligned + check_exe.checkComputeCompare("codesigoff 16 %", .{ .op = .eq, .value = .{ .literal = 0 } }); + }, + .x86_64 => { + // Next check: LINKEDIT segment does not extend beyond, or does not include, strtab data + check_exe.checkComputeCompare("fileoff filesz stroff strsize + - -", .{ + .op = .eq, + .value = .{ .literal = 0 }, + }); + }, + else => unreachable, + } + + const run = check_exe.runAndCompare(); + run.expectStdOutEqual("Hello!\n"); + test_step.dependOn(&run.step); +} diff --git a/test/link/macho/strict_validation/main.zig b/test/link/macho/strict_validation/main.zig new file mode 100644 index 0000000000..6510e13fd7 --- /dev/null +++ b/test/link/macho/strict_validation/main.zig @@ -0,0 +1,6 @@ +const std = @import("std"); + +pub fn main() !void { + const stdout = std.io.getStdOut().writer(); + try stdout.writeAll("Hello!\n"); +} |
