authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-01 23:34:24+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-11-04 09:10:06+01:00
log5698be3ef042eb8c17d75f51fd15d73eebd64a7b
tree07ef9c7285c1351340a8514a17b945fadc244df1
parent3606b5df3f185edd69af823d3cae213e4b93ff39

elf: write out contents of .rela sections


2 files changed, 58 insertions(+), 0 deletions(-)

src/link/Elf.zig+4
......@@ -4400,6 +4400,10 @@ fn updateSymtabSize(self: *Elf) !void {
44004400fn writeSyntheticSections(self: *Elf) !void {
44014401 const gpa = self.base.allocator;
44024402
4403 if (self.zigObjectPtr()) |zig_object| {
4404 try zig_object.writeRelaSections(self);
4405 }
4406
44034407 if (self.interp_section_index) |shndx| {
44044408 const shdr = self.shdrs.items[shndx];
44054409 const sh_size = math.cast(usize, shdr.sh_size) orelse return error.Overflow;
src/link/Elf/ZigObject.zig+54
......@@ -432,6 +432,60 @@ pub fn updateRelaSectionSizes(self: ZigObject, elf_file: *Elf) void {
432432 }
433433}
434434
435pub fn writeRelaSections(self: ZigObject, elf_file: *Elf) !void {
436 _ = self;
437 const gpa = elf_file.base.allocator;
438
439 for (&[_]?u16{
440 elf_file.zig_text_rela_section_index,
441 elf_file.zig_data_rel_ro_rela_section_index,
442 elf_file.zig_data_rela_section_index,
443 }) |maybe_index| {
444 const index = maybe_index orelse continue;
445 const shdr = elf_file.shdrs.items[index];
446 const meta = elf_file.last_atom_and_free_list_table.get(@intCast(shdr.sh_info)).?;
447 const last_atom_index = meta.last_atom_index;
448
449 var atom = elf_file.atom(last_atom_index) orelse continue;
450
451 var relocs = std.ArrayList(elf.Elf64_Rela).init(gpa);
452 defer relocs.deinit();
453 try relocs.ensureTotalCapacityPrecise(@divExact(shdr.sh_size, shdr.sh_entsize));
454
455 while (true) {
456 for (atom.relocs(elf_file)) |rel| {
457 relocs.appendAssumeCapacity(switch (rel.r_type()) {
458 Elf.R_X86_64_ZIG_GOT32 => .{
459 .r_offset = rel.r_offset,
460 .r_addend = rel.r_addend,
461 .r_info = (@as(u64, @intCast(rel.r_sym())) << 32) | elf.R_X86_64_32,
462 },
463 Elf.R_X86_64_ZIG_GOTPCREL => .{
464 .r_offset = rel.r_offset,
465 .r_addend = rel.r_addend,
466 .r_info = (@as(u64, @intCast(rel.r_sym())) << 32) | elf.R_X86_64_PC32,
467 },
468 else => rel,
469 });
470 }
471 if (elf_file.atom(atom.prev_index)) |prev| {
472 atom = prev;
473 } else break;
474 }
475
476 const SortRelocs = struct {
477 pub fn lessThan(ctx: void, lhs: elf.Elf64_Rela, rhs: elf.Elf64_Rela) bool {
478 _ = ctx;
479 return lhs.r_offset < rhs.r_offset;
480 }
481 };
482
483 mem.sort(elf.Elf64_Rela, relocs.items, {}, SortRelocs.lessThan);
484
485 try elf_file.base.file.?.pwriteAll(mem.sliceAsBytes(relocs.items), shdr.sh_offset);
486 }
487}
488
435489pub fn symbol(self: *ZigObject, index: Symbol.Index) Symbol.Index {
436490 const is_global = index & global_symbol_bit != 0;
437491 const actual_index = index & symbol_mask;