diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-08-22 00:34:58 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-08-22 00:34:58 +0200 |
| commit | cbb80934554776eb8d4d016640572e0c7962f2be (patch) | |
| tree | 84aa0ba5d7dae5e7f40e0d35a29dd7ed029a6b40 /src | |
| parent | ca417e1e32571b87b4a198a3f6faf1e63e7833b2 (diff) | |
| download | zig-cbb80934554776eb8d4d016640572e0c7962f2be.tar.gz zig-cbb80934554776eb8d4d016640572e0c7962f2be.zip | |
macho: emit local symbols for thunks
Diffstat (limited to 'src')
| -rw-r--r-- | src/link/MachO.zig | 13 | ||||
| -rw-r--r-- | src/link/MachO/thunks.zig | 29 |
2 files changed, 41 insertions, 1 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 65f31ae5dc..d99fc2185e 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -1909,7 +1909,7 @@ fn calcSectionSizes(self: *MachO) !void { } } - // At this point, we can also calculate symtab and data-in-code linkedit section sizes + // At this point, we can also calculate most of the symtab and data-in-code linkedit section sizes if (self.getZigObject()) |zo| { tp.spawnWg(&wg, File.calcSymtabSize, .{ zo.asFile(), self }); } @@ -2463,6 +2463,9 @@ fn writeSectionsAndUpdateLinkeditSizes(self: *MachO) !void { if (self.getInternalObject()) |obj| { tp.spawnWg(&wg, File.writeSymtab, .{ obj.asFile(), self, self }); } + if (self.requiresThunks()) for (self.thunks.items) |th| { + tp.spawnWg(&wg, Thunk.writeSymtab, .{ th, self, self }); + }; } if (self.has_errors.swap(false, .seq_cst)) return error.FlushFailure; @@ -2725,6 +2728,14 @@ fn calcSymtabSize(self: *MachO) !void { var nimports: u32 = 0; var strsize: u32 = 1; + if (self.requiresThunks()) for (self.thunks.items) |*th| { + th.output_symtab_ctx.ilocal = nlocals; + th.output_symtab_ctx.stroff = strsize; + th.calcSymtabSize(self); + nlocals += th.output_symtab_ctx.nlocals; + strsize += th.output_symtab_ctx.strsize; + }; + for (files.items) |index| { const file = self.getFile(index).?; const ctx = switch (file) { diff --git a/src/link/MachO/thunks.zig b/src/link/MachO/thunks.zig index 37013c54c4..4248785c54 100644 --- a/src/link/MachO/thunks.zig +++ b/src/link/MachO/thunks.zig @@ -85,6 +85,7 @@ pub const Thunk = struct { value: u64 = 0, out_n_sect: u8 = 0, symbols: std.AutoArrayHashMapUnmanaged(MachO.Ref, void) = .{}, + output_symtab_ctx: MachO.SymtabCtx = .{}, pub fn deinit(thunk: *Thunk, allocator: Allocator) void { thunk.symbols.deinit(allocator); @@ -116,6 +117,34 @@ pub const Thunk = struct { } } + pub fn calcSymtabSize(thunk: *Thunk, macho_file: *MachO) void { + thunk.output_symtab_ctx.nlocals = @as(u32, @intCast(thunk.symbols.keys().len)); + for (thunk.symbols.keys()) |ref| { + const sym = ref.getSymbol(macho_file).?; + thunk.output_symtab_ctx.strsize += @as(u32, @intCast(sym.getName(macho_file).len + "__thunk".len + 1)); + } + } + + pub fn writeSymtab(thunk: Thunk, macho_file: *MachO, ctx: anytype) void { + var n_strx = thunk.output_symtab_ctx.stroff; + for (thunk.symbols.keys(), thunk.output_symtab_ctx.ilocal..) |ref, ilocal| { + const sym = ref.getSymbol(macho_file).?; + const name = sym.getName(macho_file); + const out_sym = &ctx.symtab.items[ilocal]; + out_sym.n_strx = n_strx; + @memcpy(ctx.strtab.items[n_strx..][0..name.len], name); + n_strx += @intCast(name.len); + @memcpy(ctx.strtab.items[n_strx..][0.."__thunk".len], "__thunk"); + n_strx += @intCast("__thunk".len); + ctx.strtab.items[n_strx] = 0; + n_strx += 1; + out_sym.n_type = macho.N_SECT; + out_sym.n_sect = @intCast(thunk.out_n_sect + 1); + out_sym.n_value = @intCast(thunk.getTargetAddress(ref, macho_file)); + out_sym.n_desc = 0; + } + } + pub fn format( thunk: Thunk, comptime unused_fmt_string: []const u8, |
