Commit 55c085b893

Jakub Konka <kubkon@jakubkonka.com>
2024-03-12 13:25:29
elf: re-use output buffer for emitting thunks
1 parent faa4bdb
Changed files (1)
src
link
src/link/Elf.zig
@@ -4565,14 +4565,20 @@ fn writeAtoms(self: *Elf) !void {
         try self.base.file.?.pwriteAll(buffer, sh_offset);
     }
 
-    for (self.thunks.items) |th| {
-        const shdr = self.shdrs.items[th.output_section_index];
-        const offset = th.value + shdr.sh_offset;
-        const buffer = try gpa.alloc(u8, th.size(self));
-        defer gpa.free(buffer);
-        var stream = std.io.fixedBufferStream(buffer);
-        try th.write(self, stream.writer());
-        try self.base.file.?.pwriteAll(buffer, offset);
+    if (self.requiresThunks()) {
+        var buffer = std.ArrayList(u8).init(gpa);
+        defer buffer.deinit();
+
+        for (self.thunks.items) |th| {
+            const thunk_size = th.size(self);
+            try buffer.ensureUnusedCapacity(thunk_size);
+            const shdr = self.shdrs.items[th.output_section_index];
+            const offset = th.value + shdr.sh_offset;
+            try th.write(self, buffer.writer());
+            assert(buffer.items.len == thunk_size);
+            try self.base.file.?.pwriteAll(buffer.items, offset);
+            buffer.clearRetainingCapacity();
+        }
     }
 
     try self.reportUndefinedSymbols(&undefs);
@@ -4603,12 +4609,12 @@ pub fn updateSymtabSize(self: *Elf) !void {
         nlocals += 1;
     }
 
-    for (self.thunks.items) |*th| {
+    if (self.requiresThunks()) for (self.thunks.items) |*th| {
         th.output_symtab_ctx.ilocal = nlocals + 1;
         th.calcSymtabSize(self);
         nlocals += th.output_symtab_ctx.nlocals;
         strsize += th.output_symtab_ctx.strsize;
-    }
+    };
 
     for (files.items) |index| {
         const file_ptr = self.file(index).?;
@@ -4840,9 +4846,9 @@ pub fn writeSymtab(self: *Elf) !void {
 
     self.writeSectionSymbols();
 
-    for (self.thunks.items) |th| {
+    if (self.requiresThunks()) for (self.thunks.items) |th| {
         th.writeSymtab(self);
-    }
+    };
 
     if (self.zigObjectPtr()) |zig_object| {
         zig_object.asFile().writeSymtab(self);
@@ -6007,10 +6013,14 @@ fn fmtDumpState(
         try writer.print("linker_defined({d}) : (linker defined)\n", .{index});
         try writer.print("{}\n", .{linker_defined.fmtSymtab(self)});
     }
-    try writer.writeAll("thunks\n");
-    for (self.thunks.items, 0..) |th, index| {
-        try writer.print("thunk({d}) : {}\n", .{ index, th.fmt(self) });
+
+    if (self.requiresThunks()) {
+        try writer.writeAll("thunks\n");
+        for (self.thunks.items, 0..) |th, index| {
+            try writer.print("thunk({d}) : {}\n", .{ index, th.fmt(self) });
+        }
     }
+
     try writer.print("{}\n", .{self.zig_got.fmt(self)});
     try writer.print("{}\n", .{self.got.fmt(self)});
     try writer.print("{}\n", .{self.plt.fmt(self)});