authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-03-10 23:45:29+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-03-12 13:16:11+01:00
logb1eba5a996ed862aefae49a1a7d1480a788095ff
tree2debf6d50e93317831634489ce135d31d45cae2e
parentda5b16f9e2b76534b1cab9093566693482084360

elf+aarch64: actually write out thunks, and add a proper link test


3 files changed, 56 insertions(+), 11 deletions(-)

src/link/Elf.zig+10
......@@ -4565,6 +4565,16 @@ fn writeAtoms(self: *Elf) !void {
45654565 try self.base.file.?.pwriteAll(buffer, sh_offset);
45664566 }
45674567
4568 for (self.thunks.items) |th| {
4569 const shdr = self.shdrs.items[th.output_section_index];
4570 const offset = th.value + shdr.sh_offset;
4571 const buffer = try gpa.alloc(u8, th.size(self));
4572 defer gpa.free(buffer);
4573 var stream = std.io.fixedBufferStream(buffer);
4574 try th.write(self, stream.writer());
4575 try self.base.file.?.pwriteAll(buffer, offset);
4576 }
4577
45684578 try self.reportUndefinedSymbols(&undefs);
45694579
45704580 if (has_reloc_errors) return error.FlushFailure;
src/link/Elf/thunks.zig+1-1
......@@ -103,7 +103,7 @@ pub const Thunk = struct {
103103 }
104104
105105 pub fn write(thunk: Thunk, elf_file: *Elf, writer: anytype) !void {
106 switch (elf_file.options.cpu_arch.?) {
106 switch (elf_file.getTarget().cpu.arch) {
107107 .aarch64 => try aarch64.write(thunk, elf_file, writer),
108108 .x86_64, .riscv64 => unreachable,
109109 else => @panic("unhandled arch"),
test/link/elf.zig+45-10
......@@ -20,16 +20,11 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
2020 .os_tag = .linux,
2121 .abi = .gnu,
2222 });
23 // const aarch64_musl = b.resolveTargetQuery(.{
24 // .cpu_arch = .aarch64,
25 // .os_tag = .linux,
26 // .abi = .musl,
27 // });
28 // const aarch64_gnu = b.resolveTargetQuery(.{
29 // .cpu_arch = .aarch64,
30 // .os_tag = .linux,
31 // .abi = .gnu,
32 // });
23 const aarch64_musl = b.resolveTargetQuery(.{
24 .cpu_arch = .aarch64,
25 .os_tag = .linux,
26 .abi = .musl,
27 });
3328 const riscv64_musl = b.resolveTargetQuery(.{
3429 .cpu_arch = .riscv64,
3530 .os_tag = .linux,
......@@ -153,6 +148,9 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
153148 elf_step.dependOn(testMismatchedCpuArchitectureError(b, .{ .target = x86_64_musl }));
154149 elf_step.dependOn(testZText(b, .{ .target = x86_64_gnu }));
155150
151 // aarch64 specific tests
152 elf_step.dependOn(testThunks(b, .{ .target = aarch64_musl }));
153
156154 // x86_64 self-hosted backend
157155 elf_step.dependOn(testEmitRelocatable(b, .{ .use_llvm = false, .target = x86_64_musl }));
158156 elf_step.dependOn(testEmitStaticLibZig(b, .{ .use_llvm = false, .target = x86_64_musl }));
......@@ -2670,6 +2668,43 @@ fn testStrip(b: *Build, opts: Options) *Step {
26702668 return test_step;
26712669}
26722670
2671fn testThunks(b: *Build, opts: Options) *Step {
2672 const test_step = addTestStep(b, "thunks", opts);
2673
2674 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes =
2675 \\#include <stdio.h>
2676 \\__attribute__((aligned(0x8000000))) int bar() {
2677 \\ return 42;
2678 \\}
2679 \\int foobar();
2680 \\int foo() {
2681 \\ return bar() - foobar();
2682 \\}
2683 \\__attribute__((aligned(0x8000000))) int foobar() {
2684 \\ return 42;
2685 \\}
2686 \\int main() {
2687 \\ printf("bar=%d, foo=%d, foobar=%d", bar(), foo(), foobar());
2688 \\ return foo();
2689 \\}
2690 });
2691 exe.link_function_sections = true;
2692 exe.linkLibC();
2693
2694 const run = addRunArtifact(exe);
2695 run.expectStdOutEqual("bar=42, foo=0, foobar=42");
2696 run.expectExitCode(0);
2697 test_step.dependOn(&run.step);
2698
2699 const check = exe.checkObject();
2700 check.max_bytes = std.math.maxInt(u32);
2701 check.checkInSymtab();
2702 check.checkContains("_libc_start_main$thunk");
2703 test_step.dependOn(&check.step);
2704
2705 return test_step;
2706}
2707
26732708fn testTlsDfStaticTls(b: *Build, opts: Options) *Step {
26742709 const test_step = addTestStep(b, "tls-df-static-tls", opts);
26752710