Skip to content

Commit

Permalink
elf: handle text relocations
Browse files Browse the repository at this point in the history
  • Loading branch information
kubkon committed Jul 21, 2023
1 parent ef349de commit 8672fba
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/Elf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ comdat_groups_owners: std.ArrayListUnmanaged(ComdatGroupOwner) = .{},
comdat_groups_table: std.AutoHashMapUnmanaged(u32, ComdatGroupOwner.Index) = .{},

needs_tlsld: bool = false,
has_text_reloc: bool = false,
num_ifunc_dynrelocs: usize = 0,
default_sym_version: elf.Elf64_Versym,

Expand Down
6 changes: 1 addition & 5 deletions src/Elf/Atom.zig
Original file line number Diff line number Diff line change
Expand Up @@ -349,11 +349,7 @@ inline fn checkTextReloc(self: Atom, symbol: *const Symbol, elf_file: *Elf) void
symbol.getName(elf_file),
});
} else {
// TODO
elf_file.base.fatal("{s}: {s}: TODO handle relocations in read-only section", .{
self.getObject(elf_file).fmtPath(),
self.getName(elf_file),
});
elf_file.has_text_reloc = true;
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Elf/Options.zig
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const usage =
\\ nodlopen Mark DSO not available to dlopen
\\ now Disable lazy function resolution
\\ stack-size=[value] Override default stack size
\\ text Do not allow relocations against read-only segments (default)
\\ text Do not allow relocations against read-only segments
\\ notext
\\ relro Make some sections read-only after dynamic relocations
\\ norelro
Expand Down Expand Up @@ -115,7 +115,7 @@ z_nocopyreloc: bool = false,
/// Mark DSO not available for dlopen.
z_nodlopen: bool = false,
/// Do not allow relocations against read-only segments.
z_text: bool = true,
z_text: bool = false,
/// Make some sections read-only after dynamic relocations.
/// TODO make this default to true.
z_relro: bool = false,
Expand Down
9 changes: 9 additions & 0 deletions src/Elf/synthetic.zig
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ pub const DynamicSection = struct {
},
else => {},
};
if (elf_file.has_text_reloc) {
flags |= elf.DF_TEXTREL;
}
return if (flags > 0) flags else null;
}

Expand Down Expand Up @@ -75,6 +78,7 @@ pub const DynamicSection = struct {
if (elf_file.got_plt_sect_index != null) nentries += 1; // PLTGOT
nentries += 1; // HASH
if (elf_file.gnu_hash_sect_index != null) nentries += 1; // GNU_HASH
if (elf_file.has_text_reloc) nentries += 1; // TEXTREL
nentries += 1; // SYMTAB
nentries += 1; // SYMENT
nentries += 1; // STRTAB
Expand Down Expand Up @@ -165,6 +169,11 @@ pub const DynamicSection = struct {
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_GNU_HASH, .d_val = addr });
}

// TEXTREL
if (elf_file.has_text_reloc) {
try writer.writeStruct(elf.Elf64_Dyn{ .d_tag = elf.DT_TEXTREL, .d_val = 0 });
}

// SYMTAB + SYMENT
{
assert(elf_file.dynsymtab_sect_index != null);
Expand Down
48 changes: 48 additions & 0 deletions test/elf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ pub fn addElfTests(b: *Build, opts: Options) *Step {
elf_step.dependOn(testWeakExportExe(b, opts));
elf_step.dependOn(testWeakUndefDso(b, opts));
elf_step.dependOn(testZNow(b, opts));
elf_step.dependOn(testZText(b, opts));
}

return elf_step;
Expand Down Expand Up @@ -3007,6 +3008,53 @@ fn testZNow(b: *Build, opts: Options) *Step {
return test_step;
}

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

const a_o = cc(b, opts);
a_o.addAsmSource(
\\.globl fn1
\\fn1:
\\ sub $8, %rsp
\\ movabs ptr, %rax
\\ call *%rax
\\ add $8, %rsp
\\ ret
);
a_o.addArg("-c");

const b_o = cc(b, opts);
b_o.addCSource(
\\#include <stdio.h>
\\int fn1();
\\int fn2() {
\\ return 3;
\\}
\\void *ptr = fn2;
\\int main() {
\\ printf("%d\n", fn1());
\\}
);
b_o.addArgs(&.{ "-fPIC", "-c" });

const exe = cc(b, opts);
exe.addFileSource(a_o.out);
exe.addFileSource(b_o.out);
exe.addArg("-pie");

const run = exe.run();
run.expectStdOutEqual("3\n");
test_step.dependOn(run.step());

const check = exe.check();
check.checkInDynamicSection();
// check.checkExact("TEXTREL 0"); // TODO fix in CheckObject parser
check.checkExact("FLAGS TEXTREL");
test_step.dependOn(&check.step);

return test_step;
}

fn cc(b: *Build, opts: Options) SysCmd {
const cmd = Run.create(b, "cc");
cmd.addArgs(&.{ "cc", "-fno-lto" });
Expand Down

0 comments on commit 8672fba

Please sign in to comment.