Commit 88e0d49feb

Jakub Konka <kubkon@jakubkonka.com>
2024-09-03 13:49:14
elf: init rela sections in a separate pass for ZigObject
1 parent 2ef3e30
Changed files (2)
src/link/Elf/relocatable.zig
@@ -288,6 +288,9 @@ fn claimUnresolved(elf_file: *Elf) void {
 }
 
 fn initSections(elf_file: *Elf) !void {
+    if (elf_file.zigObjectPtr()) |zo| {
+        try zo.initRelaSections(elf_file);
+    }
     for (elf_file.objects.items) |index| {
         const object = elf_file.file(index).?.object;
         try object.initOutputSections(elf_file);
src/link/Elf/ZigObject.zig
@@ -803,7 +803,7 @@ pub fn writeAr(self: ZigObject, writer: anytype) !void {
     try writer.writeAll(self.data.items);
 }
 
-pub fn addAtomsToRelaSections(self: *ZigObject, elf_file: *Elf) !void {
+pub fn initRelaSections(self: *ZigObject, elf_file: *Elf) !void {
     const gpa = elf_file.base.comp.gpa;
     for (self.atoms_indexes.items) |atom_index| {
         const atom_ptr = self.atom(atom_index) orelse continue;
@@ -819,10 +819,28 @@ pub fn addAtomsToRelaSections(self: *ZigObject, elf_file: *Elf) !void {
             elf_file.getShString(out_shdr.sh_name),
         });
         defer gpa.free(rela_sect_name);
-        const out_rela_shndx = if (elf_file.sectionByName(rela_sect_name)) |out_rela_shndx|
-            out_rela_shndx
-        else
+        _ = elf_file.sectionByName(rela_sect_name) orelse
             try elf_file.addRelaShdr(try elf_file.insertShString(rela_sect_name), out_shndx);
+    }
+}
+
+pub fn addAtomsToRelaSections(self: *ZigObject, elf_file: *Elf) !void {
+    const gpa = elf_file.base.comp.gpa;
+    for (self.atoms_indexes.items) |atom_index| {
+        const atom_ptr = self.atom(atom_index) orelse continue;
+        if (!atom_ptr.alive) continue;
+        if (atom_ptr.output_section_index == elf_file.eh_frame_section_index) continue;
+        const rela_shndx = atom_ptr.relocsShndx() orelse continue;
+        // TODO this check will become obsolete when we rework our relocs mechanism at the ZigObject level
+        if (self.relocs.items[rela_shndx].items.len == 0) continue;
+        const out_shndx = atom_ptr.output_section_index;
+        const out_shdr = elf_file.sections.items(.shdr)[out_shndx];
+        if (out_shdr.sh_type == elf.SHT_NOBITS) continue;
+        const rela_sect_name = try std.fmt.allocPrintZ(gpa, ".rela{s}", .{
+            elf_file.getShString(out_shdr.sh_name),
+        });
+        defer gpa.free(rela_sect_name);
+        const out_rela_shndx = elf_file.sectionByName(rela_sect_name).?;
         const out_rela_shdr = &elf_file.sections.items(.shdr)[out_rela_shndx];
         out_rela_shdr.sh_info = out_shndx;
         out_rela_shdr.sh_link = elf_file.symtab_section_index.?;