srctree

Jakub Konka parent b1bd3825 faa4bdb0
elf+aarch64: fix off-by-one in converging on groups interleaved with thunks

inlinesplit
src/link/Elf/thunks.zig added: 53, removed: 33, total 20
@@ -1,6 +1,7 @@
pub fn createThunks(shndx: u32, elf_file: *Elf) !void {
const gpa = elf_file.base.comp.gpa;
const cpu_arch = elf_file.getTarget().cpu.arch;
const max_distance = maxAllowedDistance(cpu_arch);
const shdr = &elf_file.shdrs.items[shndx];
const atoms = elf_file.output_sections.get(shndx).?.items;
assert(atoms.len > 0);
@@ -17,12 +18,11 @@ pub fn createThunks(shndx: u32, elf_file: *Elf) !void {
start_atom.value = try advance(shdr, start_atom.size, start_atom.alignment);
i += 1;
 
while (i < atoms.len and
shdr.sh_size - start_atom.value < maxAllowedDistance(cpu_arch)) : (i += 1)
{
while (i < atoms.len) : (i += 1) {
const atom_index = atoms[i];
const atom = elf_file.atom(atom_index).?;
assert(atom.flags.alive);
if (atom.alignment.forward(shdr.sh_size) - start_atom.value >= max_distance) break;
atom.value = try advance(shdr, atom.size, atom.alignment);
}
 
 
test/link/elf.zig added: 53, removed: 33, total 20
@@ -2671,36 +2671,56 @@ fn testStrip(b: *Build, opts: Options) *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 src =
\\#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();
\\}
;
 
const run = addRunArtifact(exe);
run.expectStdOutEqual("bar=42, foo=0, foobar=42");
run.expectExitCode(0);
test_step.dependOn(&run.step);
{
const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes = src });
exe.link_function_sections = true;
exe.linkLibC();
 
const check = exe.checkObject();
check.max_bytes = std.math.maxInt(u32);
check.checkInSymtab();
check.checkContains("_libc_start_main$thunk");
test_step.dependOn(&check.step);
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);
}
 
{
const exe = addExecutable(b, opts, .{ .name = "main2", .c_source_bytes = src });
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;
}