| author | |
| committer | |
| log | cbb80934554776eb8d4d016640572e0c7962f2be |
| tree | 84aa0ba5d7dae5e7f40e0d35a29dd7ed029a6b40 |
| parent | ca417e1e32571b87b4a198a3f6faf1e63e7833b2 |
2 files changed, 41 insertions(+), 1 deletions(-)
src/link/MachO.zig+12-1| ... | @@ -1909,7 +1909,7 @@ fn calcSectionSizes(self: *MachO) !void { | ... | @@ -1909,7 +1909,7 @@ fn calcSectionSizes(self: *MachO) !void { |
| 1909 | } | 1909 | } |
| 1910 | } | 1910 | } |
| 1911 | 1911 | ||
| 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 |
| 1913 | if (self.getZigObject()) |zo| { | 1913 | if (self.getZigObject()) |zo| { |
| 1914 | tp.spawnWg(&wg, File.calcSymtabSize, .{ zo.asFile(), self }); | 1914 | tp.spawnWg(&wg, File.calcSymtabSize, .{ zo.asFile(), self }); |
| 1915 | } | 1915 | } |
| ... | @@ -2463,6 +2463,9 @@ fn writeSectionsAndUpdateLinkeditSizes(self: *MachO) !void { | ... | @@ -2463,6 +2463,9 @@ fn writeSectionsAndUpdateLinkeditSizes(self: *MachO) !void { |
| 2463 | if (self.getInternalObject()) |obj| { | 2463 | if (self.getInternalObject()) |obj| { |
| 2464 | tp.spawnWg(&wg, File.writeSymtab, .{ obj.asFile(), self, self }); | 2464 | tp.spawnWg(&wg, File.writeSymtab, .{ obj.asFile(), self, self }); |
| 2465 | } | 2465 | } |
| 2466 | if (self.requiresThunks()) for (self.thunks.items) |th| { | ||
| 2467 | tp.spawnWg(&wg, Thunk.writeSymtab, .{ th, self, self }); | ||
| 2468 | }; | ||
| 2466 | } | 2469 | } |
| 2467 | 2470 | ||
| 2468 | if (self.has_errors.swap(false, .seq_cst)) return error.FlushFailure; | 2471 | if (self.has_errors.swap(false, .seq_cst)) return error.FlushFailure; |
| ... | @@ -2725,6 +2728,14 @@ fn calcSymtabSize(self: *MachO) !void { | ... | @@ -2725,6 +2728,14 @@ fn calcSymtabSize(self: *MachO) !void { |
| 2725 | var nimports: u32 = 0; | 2728 | var nimports: u32 = 0; |
| 2726 | var strsize: u32 = 1; | 2729 | var strsize: u32 = 1; |
| 2727 | 2730 | ||
| 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 | |||
| 2728 | for (files.items) |index| { | 2739 | for (files.items) |index| { |
| 2729 | const file = self.getFile(index).?; | 2740 | const file = self.getFile(index).?; |
| 2730 | const ctx = switch (file) { | 2741 | const ctx = switch (file) { |
src/link/MachO/thunks.zig+29| ... | @@ -85,6 +85,7 @@ pub const Thunk = struct { | ... | @@ -85,6 +85,7 @@ pub const Thunk = struct { |
| 85 | value: u64 = 0, | 85 | value: u64 = 0, |
| 86 | out_n_sect: u8 = 0, | 86 | out_n_sect: u8 = 0, |
| 87 | symbols: std.AutoArrayHashMapUnmanaged(MachO.Ref, void) = .{}, | 87 | symbols: std.AutoArrayHashMapUnmanaged(MachO.Ref, void) = .{}, |
| 88 | output_symtab_ctx: MachO.SymtabCtx = .{}, | ||
| 88 | 89 | ||
| 89 | pub fn deinit(thunk: *Thunk, allocator: Allocator) void { | 90 | pub fn deinit(thunk: *Thunk, allocator: Allocator) void { |
| 90 | thunk.symbols.deinit(allocator); | 91 | thunk.symbols.deinit(allocator); |
| ... | @@ -116,6 +117,34 @@ pub const Thunk = struct { | ... | @@ -116,6 +117,34 @@ pub const Thunk = struct { |
| 116 | } | 117 | } |
| 117 | } | 118 | } |
| 118 | 119 | ||
| 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 | |||
| 119 | pub fn format( | 148 | pub fn format( |
| 120 | thunk: Thunk, | 149 | thunk: Thunk, |
| 121 | comptime unused_fmt_string: []const u8, | 150 | comptime unused_fmt_string: []const u8, |