diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-03-10 23:45:29 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-03-12 13:16:11 +0100 |
| commit | b1eba5a996ed862aefae49a1a7d1480a788095ff (patch) | |
| tree | 2debf6d50e93317831634489ce135d31d45cae2e | |
| parent | da5b16f9e2b76534b1cab9093566693482084360 (diff) | |
| download | zig-b1eba5a996ed862aefae49a1a7d1480a788095ff.tar.gz zig-b1eba5a996ed862aefae49a1a7d1480a788095ff.zip | |
elf+aarch64: actually write out thunks, and add a proper link test
| -rw-r--r-- | src/link/Elf.zig | 10 | ||||
| -rw-r--r-- | src/link/Elf/thunks.zig | 2 | ||||
| -rw-r--r-- | test/link/elf.zig | 55 |
3 files changed, 56 insertions, 11 deletions
diff --git a/src/link/Elf.zig b/src/link/Elf.zig index d26f49ca09..ed6ffbcd08 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -4565,6 +4565,16 @@ fn writeAtoms(self: *Elf) !void { try self.base.file.?.pwriteAll(buffer, sh_offset); } + for (self.thunks.items) |th| { + const shdr = self.shdrs.items[th.output_section_index]; + const offset = th.value + shdr.sh_offset; + const buffer = try gpa.alloc(u8, th.size(self)); + defer gpa.free(buffer); + var stream = std.io.fixedBufferStream(buffer); + try th.write(self, stream.writer()); + try self.base.file.?.pwriteAll(buffer, offset); + } + try self.reportUndefinedSymbols(&undefs); if (has_reloc_errors) return error.FlushFailure; diff --git a/src/link/Elf/thunks.zig b/src/link/Elf/thunks.zig index 398a2acd93..586cbed236 100644 --- a/src/link/Elf/thunks.zig +++ b/src/link/Elf/thunks.zig @@ -103,7 +103,7 @@ pub const Thunk = struct { } pub fn write(thunk: Thunk, elf_file: *Elf, writer: anytype) !void { - switch (elf_file.options.cpu_arch.?) { + switch (elf_file.getTarget().cpu.arch) { .aarch64 => try aarch64.write(thunk, elf_file, writer), .x86_64, .riscv64 => unreachable, else => @panic("unhandled arch"), diff --git a/test/link/elf.zig b/test/link/elf.zig index d872796cd4..1920feb30c 100644 --- a/test/link/elf.zig +++ b/test/link/elf.zig @@ -20,16 +20,11 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step { .os_tag = .linux, .abi = .gnu, }); - // const aarch64_musl = b.resolveTargetQuery(.{ - // .cpu_arch = .aarch64, - // .os_tag = .linux, - // .abi = .musl, - // }); - // const aarch64_gnu = b.resolveTargetQuery(.{ - // .cpu_arch = .aarch64, - // .os_tag = .linux, - // .abi = .gnu, - // }); + const aarch64_musl = b.resolveTargetQuery(.{ + .cpu_arch = .aarch64, + .os_tag = .linux, + .abi = .musl, + }); const riscv64_musl = b.resolveTargetQuery(.{ .cpu_arch = .riscv64, .os_tag = .linux, @@ -153,6 +148,9 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step { elf_step.dependOn(testMismatchedCpuArchitectureError(b, .{ .target = x86_64_musl })); elf_step.dependOn(testZText(b, .{ .target = x86_64_gnu })); + // aarch64 specific tests + elf_step.dependOn(testThunks(b, .{ .target = aarch64_musl })); + // x86_64 self-hosted backend elf_step.dependOn(testEmitRelocatable(b, .{ .use_llvm = false, .target = x86_64_musl })); elf_step.dependOn(testEmitStaticLibZig(b, .{ .use_llvm = false, .target = x86_64_musl })); @@ -2670,6 +2668,43 @@ fn testStrip(b: *Build, opts: Options) *Step { return test_step; } +fn testThunks(b: *Build, opts: Options) *Step { + const test_step = addTestStep(b, "thunks", opts); + + const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = + \\#include <stdio.h> + \\__attribute__((aligned(0x8000000))) int bar() { + \\ return 42; + \\} + \\int foobar(); + \\int foo() { + \\ return bar() - foobar(); + \\} + \\__attribute__((aligned(0x8000000))) int foobar() { + \\ return 42; + \\} + \\int main() { + \\ printf("bar=%d, foo=%d, foobar=%d", bar(), foo(), foobar()); + \\ return foo(); + \\} + }); + exe.link_function_sections = true; + exe.linkLibC(); + + const run = addRunArtifact(exe); + run.expectStdOutEqual("bar=42, foo=0, foobar=42"); + run.expectExitCode(0); + test_step.dependOn(&run.step); + + const check = exe.checkObject(); + check.max_bytes = std.math.maxInt(u32); + check.checkInSymtab(); + check.checkContains("_libc_start_main$thunk"); + test_step.dependOn(&check.step); + + return test_step; +} + fn testTlsDfStaticTls(b: *Build, opts: Options) *Step { const test_step = addTestStep(b, "tls-df-static-tls", opts); |
