Commit 0e5cd112ef

Jakub Konka <kubkon@jakubkonka.com>
2024-10-02 13:32:13
elf: clear dynamic relocs before resolving relocs in atoms
When resolving and writing atoms to file, we may add dynamic relocs to the output buffer so clear the buffers before that happens.
1 parent cf2e462
Changed files (1)
src
link
src/link/Elf.zig
@@ -987,6 +987,9 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod
     for (self.objects.items) |index| {
         self.file(index).?.object.dirty = false;
     }
+    // TODO: would state tracking be more appropriate here? perhaps even custom relocation type?
+    self.rela_dyn.clearRetainingCapacity();
+    self.rela_plt.clearRetainingCapacity();
 
     if (self.zigObjectPtr()) |zo| {
         var has_reloc_errors = false;
@@ -1017,6 +1020,7 @@ pub fn flushModule(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_nod
     try self.writeShdrTable();
     try self.writeAtoms();
     try self.writeMergeSections();
+
     self.writeSyntheticSections() catch |err| switch (err) {
         error.RelocFailure => return error.FlushFailure,
         error.UnsupportedCpuArch => {
@@ -4236,8 +4240,6 @@ fn writeSyntheticSections(self: *Elf) !void {
     }
 
     if (self.rela_dyn_section_index) |shndx| {
-        // TODO: would state tracking be more appropriate here? perhaps even custom relocation type?
-        self.rela_dyn.clearRetainingCapacity();
         const shdr = slice.items(.shdr)[shndx];
         try self.got.addRela(self);
         try self.copy_rel.addRela(self);
@@ -4270,8 +4272,6 @@ fn writeSyntheticSections(self: *Elf) !void {
     }
 
     if (self.rela_plt_section_index) |shndx| {
-        // TODO: would state tracking be more appropriate here? perhaps even custom relocation type?
-        self.rela_plt.clearRetainingCapacity();
         const shdr = slice.items(.shdr)[shndx];
         try self.plt.addRela(self);
         try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.rela_plt.items), shdr.sh_offset);