diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-03-12 13:25:29 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-03-12 13:25:29 +0100 |
| commit | 55c085b893892f89e7d9930f3ec6c22537ebb54f (patch) | |
| tree | 11a7c25fa278531bc5c557f7eeda56901b670f1e /src/link/Elf.zig | |
| parent | faa4bdb0175ee142834be320326063ae99dac1e4 (diff) | |
| download | zig-55c085b893892f89e7d9930f3ec6c22537ebb54f.tar.gz zig-55c085b893892f89e7d9930f3ec6c22537ebb54f.zip | |
elf: re-use output buffer for emitting thunks
Diffstat (limited to 'src/link/Elf.zig')
| -rw-r--r-- | src/link/Elf.zig | 40 |
1 files changed, 25 insertions, 15 deletions
diff --git a/src/link/Elf.zig b/src/link/Elf.zig index ed6ffbcd08..e6182b4333 100644 --- a/src/link/Elf.zig +++ b/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)}); |
