mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
elf+aarch64: fix off-by-one in converging on groups interleaved with thunks
This commit is contained in:
parent
b1bd3825f8
commit
faa4bdb017
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user