authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-22 00:34:58+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-22 00:34:58+02:00
logcbb80934554776eb8d4d016640572e0c7962f2be
tree84aa0ba5d7dae5e7f40e0d35a29dd7ed029a6b40
parentca417e1e32571b87b4a198a3f6faf1e63e7833b2

macho: emit local symbols for thunks


2 files changed, 41 insertions(+), 1 deletions(-)

src/link/MachO.zig+12-1
......@@ -1909,7 +1909,7 @@ fn calcSectionSizes(self: *MachO) !void {
19091909 }
19101910 }
19111911
1912 // At this point, we can also calculate symtab and data-in-code linkedit section sizes
1912 // At this point, we can also calculate most of the symtab and data-in-code linkedit section sizes
19131913 if (self.getZigObject()) |zo| {
19141914 tp.spawnWg(&wg, File.calcSymtabSize, .{ zo.asFile(), self });
19151915 }
......@@ -2463,6 +2463,9 @@ fn writeSectionsAndUpdateLinkeditSizes(self: *MachO) !void {
24632463 if (self.getInternalObject()) |obj| {
24642464 tp.spawnWg(&wg, File.writeSymtab, .{ obj.asFile(), self, self });
24652465 }
2466 if (self.requiresThunks()) for (self.thunks.items) |th| {
2467 tp.spawnWg(&wg, Thunk.writeSymtab, .{ th, self, self });
2468 };
24662469 }
24672470
24682471 if (self.has_errors.swap(false, .seq_cst)) return error.FlushFailure;
......@@ -2725,6 +2728,14 @@ fn calcSymtabSize(self: *MachO) !void {
27252728 var nimports: u32 = 0;
27262729 var strsize: u32 = 1;
27272730
2731 if (self.requiresThunks()) for (self.thunks.items) |*th| {
2732 th.output_symtab_ctx.ilocal = nlocals;
2733 th.output_symtab_ctx.stroff = strsize;
2734 th.calcSymtabSize(self);
2735 nlocals += th.output_symtab_ctx.nlocals;
2736 strsize += th.output_symtab_ctx.strsize;
2737 };
2738
27282739 for (files.items) |index| {
27292740 const file = self.getFile(index).?;
27302741 const ctx = switch (file) {
src/link/MachO/thunks.zig+29
......@@ -85,6 +85,7 @@ pub const Thunk = struct {
8585 value: u64 = 0,
8686 out_n_sect: u8 = 0,
8787 symbols: std.AutoArrayHashMapUnmanaged(MachO.Ref, void) = .{},
88 output_symtab_ctx: MachO.SymtabCtx = .{},
8889
8990 pub fn deinit(thunk: *Thunk, allocator: Allocator) void {
9091 thunk.symbols.deinit(allocator);
......@@ -116,6 +117,34 @@ pub const Thunk = struct {
116117 }
117118 }
118119
120 pub fn calcSymtabSize(thunk: *Thunk, macho_file: *MachO) void {
121 thunk.output_symtab_ctx.nlocals = @as(u32, @intCast(thunk.symbols.keys().len));
122 for (thunk.symbols.keys()) |ref| {
123 const sym = ref.getSymbol(macho_file).?;
124 thunk.output_symtab_ctx.strsize += @as(u32, @intCast(sym.getName(macho_file).len + "__thunk".len + 1));
125 }
126 }
127
128 pub fn writeSymtab(thunk: Thunk, macho_file: *MachO, ctx: anytype) void {
129 var n_strx = thunk.output_symtab_ctx.stroff;
130 for (thunk.symbols.keys(), thunk.output_symtab_ctx.ilocal..) |ref, ilocal| {
131 const sym = ref.getSymbol(macho_file).?;
132 const name = sym.getName(macho_file);
133 const out_sym = &ctx.symtab.items[ilocal];
134 out_sym.n_strx = n_strx;
135 @memcpy(ctx.strtab.items[n_strx..][0..name.len], name);
136 n_strx += @intCast(name.len);
137 @memcpy(ctx.strtab.items[n_strx..][0.."__thunk".len], "__thunk");
138 n_strx += @intCast("__thunk".len);
139 ctx.strtab.items[n_strx] = 0;
140 n_strx += 1;
141 out_sym.n_type = macho.N_SECT;
142 out_sym.n_sect = @intCast(thunk.out_n_sect + 1);
143 out_sym.n_value = @intCast(thunk.getTargetAddress(ref, macho_file));
144 out_sym.n_desc = 0;
145 }
146 }
147
119148 pub fn format(
120149 thunk: Thunk,
121150 comptime unused_fmt_string: []const u8,