authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-12 23:12:15+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-24 12:34:39+01:00
log11524e4d0c1e924d49dccc03eb8b0beb71872792
tree559bb7293683324bf65117d5dbdbb0bb8389fc69
parent0a60e4448d27639a4dadccb48c00d22fab7bb790

test/link/macho: migrate entry_in_dylib test to new test format


5 files changed, 63 insertions(+), 77 deletions(-)

test/link.zig-4
......@@ -131,10 +131,6 @@ pub const cases = [_]Case{
131131 .build_root = "test/link/macho/entry_in_archive",
132132 .import = @import("link/macho/entry_in_archive/build.zig"),
133133 },
134 .{
135 .build_root = "test/link/macho/entry_in_dylib",
136 .import = @import("link/macho/entry_in_dylib/build.zig"),
137 },
138134 .{
139135 .build_root = "test/link/macho/headerpad",
140136 .import = @import("link/macho/headerpad/build.zig"),
test/link/macho.zig+63-3
......@@ -4,13 +4,70 @@
44pub fn testAll(b: *std.Build) *Step {
55 const macho_step = b.step("test-macho", "Run MachO tests");
66
7 macho_step.dependOn(testSectionBoundarySymbols(b, .{
8 .target = b.resolveTargetQuery(.{ .os_tag = .macos }),
9 }));
7 const default_target = b.resolveTargetQuery(.{
8 .os_tag = .macos,
9 });
10
11 macho_step.dependOn(testEntryPointDylib(b, .{ .target = default_target }));
12 macho_step.dependOn(testSectionBoundarySymbols(b, .{ .target = default_target }));
1013
1114 return macho_step;
1215}
1316
17fn testEntryPointDylib(b: *std.Build, opts: Options) *Step {
18 const test_step = addTestStep(b, "macho-entry-point-dylib", opts);
19
20 const dylib = addSharedLibrary(b, opts, .{ .name = "liba.dylib" });
21 addCSourceBytes(dylib,
22 \\extern int my_main();
23 \\int bootstrap() {
24 \\ return my_main();
25 \\}
26 , &.{});
27 dylib.linker_allow_shlib_undefined = true;
28
29 const exe = addExecutable(b, opts, .{ .name = "main" });
30 addCSourceBytes(dylib,
31 \\#include<stdio.h>
32 \\int my_main() {
33 \\ fprintf(stdout, "Hello!\n");
34 \\ return 0;
35 \\}
36 , &.{});
37 exe.linkLibrary(dylib);
38 exe.entry = .{ .symbol_name = "_bootstrap" };
39 exe.forceUndefinedSymbol("_my_main");
40
41 const check = exe.checkObject();
42 check.checkInHeaders();
43 check.checkExact("segname __TEXT");
44 check.checkExtract("vmaddr {text_vmaddr}");
45 check.checkInHeaders();
46 check.checkExact("sectname __stubs");
47 check.checkExtract("addr {stubs_vmaddr}");
48 check.checkInHeaders();
49 check.checkExact("sectname __stubs");
50 check.checkExtract("size {stubs_vmsize}");
51 check.checkInHeaders();
52 check.checkExact("cmd MAIN");
53 check.checkExtract("entryoff {entryoff}");
54 check.checkComputeCompare("text_vmaddr entryoff +", .{
55 .op = .gte,
56 .value = .{ .variable = "stubs_vmaddr" }, // The entrypoint should be a synthetic stub
57 });
58 check.checkComputeCompare("text_vmaddr entryoff + stubs_vmaddr -", .{
59 .op = .lt,
60 .value = .{ .variable = "stubs_vmsize" }, // The entrypoint should be a synthetic stub
61 });
62 test_step.dependOn(&check.step);
63
64 const run = addRunArtifact(exe);
65 run.expectStdOutEqual("Hello!\n");
66 test_step.dependOn(&run.step);
67
68 return test_step;
69}
70
1471fn testSectionBoundarySymbols(b: *std.Build, opts: Options) *Step {
1572 const test_step = addTestStep(b, "macho-section-boundary-symbols", opts);
1673
......@@ -95,8 +152,11 @@ fn addTestStep(b: *std.Build, comptime prefix: []const u8, opts: Options) *Step
95152 return link.addTestStep(b, "macho-" ++ prefix, opts);
96153}
97154
155const addCSourceBytes = link.addCSourceBytes;
156const addRunArtifact = link.addRunArtifact;
98157const addObject = link.addObject;
99158const addExecutable = link.addExecutable;
159const addSharedLibrary = link.addSharedLibrary;
100160const expectLinkErrors = link.expectLinkErrors;
101161const link = @import("link.zig");
102162const std = @import("std");
test/link/macho/entry_in_dylib/bootstrap.c deleted-5
......@@ -1,5 +0,0 @@
1extern int my_main();
2
3int bootstrap() {
4 return my_main();
5}
test/link/macho/entry_in_dylib/build.zig deleted-59
......@@ -1,59 +0,0 @@
1const std = @import("std");
2
3pub const requires_symlinks = true;
4
5pub fn build(b: *std.Build) void {
6 const test_step = b.step("test", "Test it");
7 b.default_step = test_step;
8
9 add(b, test_step, .Debug);
10 add(b, test_step, .ReleaseFast);
11 add(b, test_step, .ReleaseSmall);
12 add(b, test_step, .ReleaseSafe);
13}
14
15fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.OptimizeMode) void {
16 const lib = b.addSharedLibrary(.{
17 .name = "bootstrap",
18 .optimize = optimize,
19 .target = b.resolveTargetQuery(.{ .os_tag = .macos }),
20 });
21 lib.addCSourceFile(.{ .file = .{ .path = "bootstrap.c" }, .flags = &.{} });
22 lib.linkLibC();
23 lib.linker_allow_shlib_undefined = true;
24
25 const exe = b.addExecutable(.{
26 .name = "main",
27 .optimize = optimize,
28 .target = b.resolveTargetQuery(.{ .os_tag = .macos }),
29 });
30 exe.addCSourceFile(.{ .file = .{ .path = "main.c" }, .flags = &.{} });
31 exe.linkLibrary(lib);
32 exe.linkLibC();
33 exe.entry = .{ .symbol_name = "_bootstrap" };
34 exe.forceUndefinedSymbol("_my_main");
35
36 const check_exe = exe.checkObject();
37 check_exe.checkInHeaders();
38 check_exe.checkExact("segname __TEXT");
39 check_exe.checkExtract("vmaddr {text_vmaddr}");
40
41 check_exe.checkInHeaders();
42 check_exe.checkExact("sectname __stubs");
43 check_exe.checkExtract("addr {stubs_vmaddr}");
44
45 check_exe.checkInHeaders();
46 check_exe.checkExact("cmd MAIN");
47 check_exe.checkExtract("entryoff {entryoff}");
48
49 check_exe.checkComputeCompare("text_vmaddr entryoff +", .{
50 .op = .eq,
51 .value = .{ .variable = "stubs_vmaddr" }, // The entrypoint should be a synthetic stub
52 });
53 test_step.dependOn(&check_exe.step);
54
55 const run = b.addRunArtifact(exe);
56 run.skip_foreign_checks = true;
57 run.expectStdOutEqual("Hello!\n");
58 test_step.dependOn(&run.step);
59}
test/link/macho/entry_in_dylib/main.c deleted-6
......@@ -1,6 +0,0 @@
1#include <stdio.h>
2
3int my_main() {
4 fprintf(stdout, "Hello!\n");
5 return 0;
6}