authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-03-12 00:07:07+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-03-12 13:16:11+01:00
logfaa4bdb0175ee142834be320326063ae99dac1e4
treee81281d52055a3671aab168d31dc4d46bc7c2cf1
parentb1bd3825f84edc7a8f1195b0c842fbbf8346c1cb

elf+aarch64: fix off-by-one in converging on groups interleaved with thunks


2 files changed, 51 insertions(+), 31 deletions(-)

src/link/Elf/thunks.zig+3-3
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1pub fn createThunks(shndx: u32, elf_file: *Elf) !void {1pub fn createThunks(shndx: u32, elf_file: *Elf) !void {
2 const gpa = elf_file.base.comp.gpa;2 const gpa = elf_file.base.comp.gpa;
3 const cpu_arch = elf_file.getTarget().cpu.arch;3 const cpu_arch = elf_file.getTarget().cpu.arch;
4 const max_distance = maxAllowedDistance(cpu_arch);
4 const shdr = &elf_file.shdrs.items[shndx];5 const shdr = &elf_file.shdrs.items[shndx];
5 const atoms = elf_file.output_sections.get(shndx).?.items;6 const atoms = elf_file.output_sections.get(shndx).?.items;
6 assert(atoms.len > 0);7 assert(atoms.len > 0);
...@@ -17,12 +18,11 @@ pub fn createThunks(shndx: u32, elf_file: *Elf) !void {...@@ -17,12 +18,11 @@ pub fn createThunks(shndx: u32, elf_file: *Elf) !void {
17 start_atom.value = try advance(shdr, start_atom.size, start_atom.alignment);18 start_atom.value = try advance(shdr, start_atom.size, start_atom.alignment);
18 i += 1;19 i += 1;
1920
20 while (i < atoms.len and21 while (i < atoms.len) : (i += 1) {
21 shdr.sh_size - start_atom.value < maxAllowedDistance(cpu_arch)) : (i += 1)
22 {
23 const atom_index = atoms[i];22 const atom_index = atoms[i];
24 const atom = elf_file.atom(atom_index).?;23 const atom = elf_file.atom(atom_index).?;
25 assert(atom.flags.alive);24 assert(atom.flags.alive);
25 if (atom.alignment.forward(shdr.sh_size) - start_atom.value >= max_distance) break;
26 atom.value = try advance(shdr, atom.size, atom.alignment);26 atom.value = try advance(shdr, atom.size, atom.alignment);
27 }27 }
2828
test/link/elf.zig+48-28
...@@ -2671,36 +2671,56 @@ fn testStrip(b: *Build, opts: Options) *Step {...@@ -2671,36 +2671,56 @@ fn testStrip(b: *Build, opts: Options) *Step {
2671fn testThunks(b: *Build, opts: Options) *Step {2671fn testThunks(b: *Build, opts: Options) *Step {
2672 const test_step = addTestStep(b, "thunks", opts);2672 const test_step = addTestStep(b, "thunks", opts);
26732673
2674 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = 2674 const src =
2675 \\#include <stdio.h>2675 \\#include <stdio.h>
2676 \\__attribute__((aligned(0x8000000))) int bar() {2676 \\__attribute__((aligned(0x8000000))) int bar() {
2677 \\ return 42;2677 \\ return 42;
2678 \\}2678 \\}
2679 \\int foobar();2679 \\int foobar();
2680 \\int foo() {2680 \\int foo() {
2681 \\ return bar() - foobar();2681 \\ return bar() - foobar();
2682 \\}2682 \\}
2683 \\__attribute__((aligned(0x8000000))) int foobar() {2683 \\__attribute__((aligned(0x8000000))) int foobar() {
2684 \\ return 42;2684 \\ return 42;
2685 \\}2685 \\}
2686 \\int main() {2686 \\int main() {
2687 \\ printf("bar=%d, foo=%d, foobar=%d", bar(), foo(), foobar());2687 \\ printf("bar=%d, foo=%d, foobar=%d", bar(), foo(), foobar());
2688 \\ return foo();2688 \\ return foo();
2689 \\}2689 \\}
2690 });2690 ;
2691 exe.link_function_sections = true;
2692 exe.linkLibC();
26932691
2694 const run = addRunArtifact(exe);2692 {
2695 run.expectStdOutEqual("bar=42, foo=0, foobar=42");2693 const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = src });
2696 run.expectExitCode(0);2694 exe.link_function_sections = true;
2697 test_step.dependOn(&run.step);2695 exe.linkLibC();
26982696
2699 const check = exe.checkObject();2697 const run = addRunArtifact(exe);
2700 check.max_bytes = std.math.maxInt(u32);2698 run.expectStdOutEqual("bar=42, foo=0, foobar=42");
2701 check.checkInSymtab();2699 run.expectExitCode(0);
2702 check.checkContains("_libc_start_main$thunk");2700 test_step.dependOn(&run.step);
2703 test_step.dependOn(&check.step);2701
2702 const check = exe.checkObject();
2703 check.max_bytes = std.math.maxInt(u32);
2704 check.checkInSymtab();
2705 check.checkContains("__libc_start_main$thunk");
2706 test_step.dependOn(&check.step);
2707 }
2708
2709 {
2710 const exe = addExecutable(b, opts, .{ .name = "main2", .c_source_bytes = src });
2711 exe.linkLibC();
2712
2713 const run = addRunArtifact(exe);
2714 run.expectStdOutEqual("bar=42, foo=0, foobar=42");
2715 run.expectExitCode(0);
2716 test_step.dependOn(&run.step);
2717
2718 const check = exe.checkObject();
2719 check.max_bytes = std.math.maxInt(u32);
2720 check.checkInSymtab();
2721 check.checkContains("__libc_start_main$thunk");
2722 test_step.dependOn(&check.step);
2723 }
27042724
2705 return test_step;2725 return test_step;
2706}2726}