mirror of
https://github.com/ziglang/zig.git
synced 2025-12-22 14:13:08 +00:00
elf: write out contents of .rela sections
This commit is contained in:
parent
3606b5df3f
commit
5698be3ef0
@ -4400,6 +4400,10 @@ fn updateSymtabSize(self: *Elf) !void {
|
|||||||
fn writeSyntheticSections(self: *Elf) !void {
|
fn writeSyntheticSections(self: *Elf) !void {
|
||||||
const gpa = self.base.allocator;
|
const gpa = self.base.allocator;
|
||||||
|
|
||||||
|
if (self.zigObjectPtr()) |zig_object| {
|
||||||
|
try zig_object.writeRelaSections(self);
|
||||||
|
}
|
||||||
|
|
||||||
if (self.interp_section_index) |shndx| {
|
if (self.interp_section_index) |shndx| {
|
||||||
const shdr = self.shdrs.items[shndx];
|
const shdr = self.shdrs.items[shndx];
|
||||||
const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
|
const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
|
||||||
|
|||||||
@ -432,6 +432,60 @@ pub fn updateRelaSectionSizes(self: ZigObject, elf_file: *Elf) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void {
|
||||||
|
_ = self;
|
||||||
|
const gpa = elf_file.base.allocator;
|
||||||
|
|
||||||
|
for (&[_]?u16{
|
||||||
|
elf_file.zig_text_rela_section_index,
|
||||||
|
elf_file.zig_data_rel_ro_rela_section_index,
|
||||||
|
elf_file.zig_data_rela_section_index,
|
||||||
|
}) |maybe_index| {
|
||||||
|
const index = maybe_index orelse continue;
|
||||||
|
const shdr = elf_file.shdrs.items[index];
|
||||||
|
const meta = elf_file.last_atom_and_free_list_table.get(@intCast(shdr.sh_info)).?;
|
||||||
|
const last_atom_index = meta.last_atom_index;
|
||||||
|
|
||||||
|
var atom = elf_file.atom(last_atom_index) orelse continue;
|
||||||
|
|
||||||
|
var relocs = std.ArrayList(elf.Elf64_Rela).init(gpa);
|
||||||
|
defer relocs.deinit();
|
||||||
|
try relocs.ensureTotalCapacityPrecise(@divExact(shdr.sh_size, shdr.sh_entsize));
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
for (atom.relocs(elf_file)) |rel| {
|
||||||
|
relocs.appendAssumeCapacity(switch (rel.r_type()) {
|
||||||
|
Elf.R_X86_64_ZIG_GOT32 => .{
|
||||||
|
.r_offset = rel.r_offset,
|
||||||
|
.r_addend = rel.r_addend,
|
||||||
|
.r_info = (@as(u64, @intCast(rel.r_sym())) << 32) | elf.R_X86_64_32,
|
||||||
|
},
|
||||||
|
Elf.R_X86_64_ZIG_GOTPCREL => .{
|
||||||
|
.r_offset = rel.r_offset,
|
||||||
|
.r_addend = rel.r_addend,
|
||||||
|
.r_info = (@as(u64, @intCast(rel.r_sym())) << 32) | elf.R_X86_64_PC32,
|
||||||
|
},
|
||||||
|
else => rel,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (elf_file.atom(atom.prev_index)) |prev| {
|
||||||
|
atom = prev;
|
||||||
|
} else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SortRelocs = struct {
|
||||||
|
pub fn lessThan(ctx: void, lhs: elf.Elf64_Rela, rhs: elf.Elf64_Rela) bool {
|
||||||
|
_ = ctx;
|
||||||
|
return lhs.r_offset < rhs.r_offset;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mem.sort(elf.Elf64_Rela, relocs.items, {}, SortRelocs.lessThan);
|
||||||
|
|
||||||
|
try elf_file.base.file.?.pwriteAll(mem.sliceAsBytes(relocs.items), shdr.sh_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn symbol(self: *ZigObject, index: Symbol.Index) Symbol.Index {
|
pub fn symbol(self: *ZigObject, index: Symbol.Index) Symbol.Index {
|
||||||
const is_global = index & global_symbol_bit != 0;
|
const is_global = index & global_symbol_bit != 0;
|
||||||
const actual_index = index & symbol_mask;
|
const actual_index = index & symbol_mask;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user