Skip to content

Commit

Permalink
Merge pull request #125 from kubkon/elf-aarch64-thunks
Browse files Browse the repository at this point in the history
elf: thunks algorithm fixes
  • Loading branch information
kubkon authored Mar 11, 2024
2 parents 19cd7ed + 1bb8134 commit 60afc8a
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 3 deletions.
12 changes: 12 additions & 0 deletions src/Elf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2236,6 +2236,8 @@ fn writeAtoms(self: *Elf) !void {
const tracy = trace(@src());
defer tracy.end();

const gpa = self.base.allocator;

const slice = self.sections.slice();
for (slice.items(.shdr), slice.items(.atoms)) |shdr, atoms| {
if (atoms.items.len == 0) continue;
Expand Down Expand Up @@ -2274,6 +2276,16 @@ fn writeAtoms(self: *Elf) !void {
try self.base.file.pwriteAll(buffer, shdr.sh_offset);
}

for (self.thunks.items) |thunk| {
const shdr = slice.items(.shdr)[thunk.out_shndx];
const offset = thunk.value + shdr.sh_offset;
const buffer = try gpa.alloc(u8, thunk.size(self));
defer gpa.free(buffer);
var stream = std.io.fixedBufferStream(buffer);
try thunk.write(self, stream.writer());
try self.base.file.pwriteAll(buffer, offset);
}

try self.reportUndefs();
}

Expand Down
6 changes: 3 additions & 3 deletions src/Elf/thunks.zig
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ 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.getAtom(atom_index).?;
assert(atom.flags.alive);
const alignment = try math.powi(u32, 2, atom.alignment);
if (mem.alignForward(u64, shdr.sh_size, alignment) - start_atom.value >= maxAllowedDistance(cpu_arch)) break;
atom.value = try advance(shdr, atom.size, atom.alignment);
}

Expand Down
60 changes: 60 additions & 0 deletions test/elf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ pub fn addElfTests(b: *Build, options: common.Options) *Step {
elf_step.dependOn(testSharedAbsSymbol(b, opts));
elf_step.dependOn(testStrip(b, opts));
elf_step.dependOn(testThunks(b, opts));
elf_step.dependOn(testThunks2(b, opts));
elf_step.dependOn(testTlsCommon(b, opts));
elf_step.dependOn(testTlsDesc(b, opts));
elf_step.dependOn(testTlsDescImport(b, opts));
Expand Down Expand Up @@ -2165,6 +2166,65 @@ fn testThunks(b: *Build, opts: Options) *Step {
return test_step;
}

fn testThunks2(b: *Build, opts: Options) *Step {
const test_step = b.step("test-elf-thunks2", "");

if (builtin.target.cpu.arch != .aarch64) return skipTestStep(test_step);

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 exe = cc(b, "a.out", opts);
exe.addCSource(src);
exe.addArg("-ffunction-sections");

const run = exe.run();
run.expectStdOutEqual("bar=42, foo=0, foobar=42");
run.expectExitCode(0);
test_step.dependOn(run.step());

const check = exe.check();
check.max_bytes = std.math.maxInt(u32);
check.checkInSymtab();
check.checkContains("_libc_start_main$thunk");
test_step.dependOn(&check.step);
}

{
const exe = cc(b, "a.out", opts);
exe.addCSource(src);

const run = exe.run();
run.expectStdOutEqual("bar=42, foo=0, foobar=42");
run.expectExitCode(0);
test_step.dependOn(run.step());

const check = exe.check();
check.max_bytes = std.math.maxInt(u32);
check.checkInSymtab();
check.checkContains("_libc_start_main$thunk");
test_step.dependOn(&check.step);
}

return test_step;
}

fn testTlsCommon(b: *Build, opts: Options) *Step {
const test_step = b.step("test-elf-tls-common", "");

Expand Down

0 comments on commit 60afc8a

Please sign in to comment.