authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-25 14:19:20+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-09-26 21:07:47+02:00
logaac04b4a5a70fc45f88d7b005e20c2cde271ff89
tree87849c43cdb05d88a1b5b72a4b4f9fa919a26a25
parentf4c884617f499b52eaecc0ef674609c774052f8f

elf: port some of zld's test harness


2 files changed, 95 insertions(+), 0 deletions(-)

test/link.zig+6
......@@ -29,6 +29,12 @@ pub const cases = [_]Case{
2929 .import = @import("link/glibc_compat/build.zig"),
3030 },
3131
32 // Elf Cases
33 .{
34 .build_root = "test/link",
35 .import = @import("link/elf.zig"),
36 },
37
3238 // WASM Cases
3339 // https://github.com/ziglang/zig/issues/16938
3440 //.{
test/link/elf.zig created+89
......@@ -0,0 +1,89 @@
1//! Here we test our ELF linker for correctness and functionality.
2//! Currently, we support linking x86_64 Linux, but in the future we
3//! will progressively relax those to exercise more combinations.
4
5pub fn build(b: *Build) void {
6 const elf_step = b.step("test-elf", "Run ELF tests");
7 b.default_step = elf_step;
8
9 const target: CrossTarget = .{
10 .cpu_arch = .x86_64, // TODO relax this once ELF linker is able to handle other archs
11 .os_tag = .linux,
12 };
13
14 elf_step.dependOn(testHelloStatic(b, .{ .target = target, .use_llvm = true }));
15 elf_step.dependOn(testHelloStatic(b, .{ .target = target, .use_llvm = false }));
16}
17
18fn testHelloStatic(b: *Build, opts: Options) *Step {
19 const test_step = addTestStep(b, "hello-static", opts);
20
21 const exe = addExecutable(b, opts);
22 addZigSourceBytes(exe,
23 \\pub fn main() void {
24 \\ @import("std").debug.print("Hello World!\n", .{});
25 \\}
26 );
27 exe.linkage = .static;
28
29 const run = b.addRunArtifact(exe);
30 run.expectStdErrEqual("Hello World!\n");
31 test_step.dependOn(&run.step);
32
33 const check = exe.checkObject();
34 check.checkStart();
35 check.checkExact("header");
36 check.checkExact("type EXEC");
37 check.checkStart();
38 check.checkExact("section headers");
39 check.checkNotPresent("name .dynamic");
40 test_step.dependOn(&check.step);
41
42 return test_step;
43}
44
45const Options = struct {
46 target: CrossTarget = .{ .os_tag = .linux },
47 optimize: std.builtin.OptimizeMode = .Debug,
48 use_llvm: bool = true,
49};
50
51fn addTestStep(b: *Build, comptime prefix: []const u8, opts: Options) *Step {
52 const target = opts.target.zigTriple(b.allocator) catch @panic("OOM");
53 const optimize = @tagName(opts.optimize);
54 const use_llvm = if (opts.use_llvm) "llvm" else "no-llvm";
55 const name = std.fmt.allocPrint(b.allocator, "test-elf-" ++ prefix ++ "-{s}-{s}-{s}", .{
56 target,
57 optimize,
58 use_llvm,
59 }) catch @panic("OOM");
60 return b.step(name, "");
61}
62
63fn addExecutable(b: *Build, opts: Options) *Compile {
64 return b.addExecutable(.{
65 .name = "test",
66 .target = opts.target,
67 .optimize = opts.optimize,
68 .single_threaded = true, // TODO temp until we teach linker how to handle TLS
69 .use_llvm = opts.use_llvm,
70 .use_lld = false,
71 });
72}
73
74fn addZigSourceBytes(comp: *Compile, bytes: []const u8) void {
75 const b = comp.step.owner;
76 const file = WriteFile.create(b).add("a.zig", bytes);
77 file.addStepDependencies(&comp.step);
78 comp.root_src = file;
79}
80
81const std = @import("std");
82
83const Build = std.Build;
84const Compile = Step.Compile;
85const CrossTarget = std.zig.CrossTarget;
86const LazyPath = Build.LazyPath;
87const Run = Step.Run;
88const Step = Build.Step;
89const WriteFile = Step.WriteFile;