authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-09 19:30:58+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-18 09:13:08+02:00
logf86a38564f5d8eb903b940ddf9b9f5685a3ca932
tree0681926bedfcbe95136ba485da7eab960943dbac
parent2e87883be85956b2a5be682423256e9ba700c13f

macho: migrate synthetic sections


2 files changed, 136 insertions(+), 67 deletions(-)

src/link/MachO.zig+3
...@@ -68,6 +68,7 @@ weak_bind: WeakBind = .{},...@@ -68,6 +68,7 @@ weak_bind: WeakBind = .{},
68lazy_bind: LazyBind = .{},68lazy_bind: LazyBind = .{},
69export_trie: ExportTrie = .{},69export_trie: ExportTrie = .{},
70unwind_info: UnwindInfo = .{},70unwind_info: UnwindInfo = .{},
71data_in_code: DataInCode = .{},
7172
72/// Tracked loadable segments during incremental linking.73/// Tracked loadable segments during incremental linking.
73zig_text_seg_index: ?u8 = null,74zig_text_seg_index: ?u8 = null,
...@@ -316,6 +317,7 @@ pub fn deinit(self: *MachO) void {...@@ -316,6 +317,7 @@ pub fn deinit(self: *MachO) void {
316 self.lazy_bind.deinit(gpa);317 self.lazy_bind.deinit(gpa);
317 self.export_trie.deinit(gpa);318 self.export_trie.deinit(gpa);
318 self.unwind_info.deinit(gpa);319 self.unwind_info.deinit(gpa);
320 self.data_in_code.deinit(gpa);
319321
320 self.thunks.deinit(gpa);322 self.thunks.deinit(gpa);
321}323}
...@@ -4524,6 +4526,7 @@ const Bind = bind.Bind;...@@ -4524,6 +4526,7 @@ const Bind = bind.Bind;
4524const Cache = std.Build.Cache;4526const Cache = std.Build.Cache;
4525const CodeSignature = @import("MachO/CodeSignature.zig");4527const CodeSignature = @import("MachO/CodeSignature.zig");
4526const Compilation = @import("../Compilation.zig");4528const Compilation = @import("../Compilation.zig");
4529const DataInCode = synthetic.DataInCode;
4527pub const DebugSymbols = @import("MachO/DebugSymbols.zig");4530pub const DebugSymbols = @import("MachO/DebugSymbols.zig");
4528const Dylib = @import("MachO/Dylib.zig");4531const Dylib = @import("MachO/Dylib.zig");
4529const ExportTrie = @import("MachO/dyld_info/Trie.zig");4532const ExportTrie = @import("MachO/dyld_info/Trie.zig");
src/link/MachO/synthetic.zig+133-67
...@@ -18,15 +18,15 @@ pub const ZigGotSection = struct {...@@ -18,15 +18,15 @@ pub const ZigGotSection = struct {
18 }18 }
1919
20 pub fn addSymbol(zig_got: *ZigGotSection, sym_index: Symbol.Index, macho_file: *MachO) !Index {20 pub fn addSymbol(zig_got: *ZigGotSection, sym_index: Symbol.Index, macho_file: *MachO) !Index {
21 const comp = macho_file.base.comp;21 const gpa = macho_file.base.comp.gpa;
22 const gpa = comp.gpa;22 const zo = macho_file.getZigObject().?;
23 const index = try zig_got.allocateEntry(gpa);23 const index = try zig_got.allocateEntry(gpa);
24 const entry = &zig_got.entries.items[index];24 const entry = &zig_got.entries.items[index];
25 entry.* = sym_index;25 entry.* = sym_index;
26 const symbol = macho_file.getSymbol(sym_index);26 const symbol = zo.getSymbol(sym_index);
27 assert(symbol.flags.needs_zig_got);27 assert(symbol.flags.needs_zig_got);
28 symbol.flags.has_zig_got = true;28 symbol.flags.has_zig_got = true;
29 try symbol.addExtra(.{ .zig_got = index }, macho_file);29 symbol.addExtra(.{ .zig_got = index }, macho_file);
30 return index;30 return index;
31 }31 }
3232
...@@ -53,9 +53,10 @@ pub const ZigGotSection = struct {...@@ -53,9 +53,10 @@ pub const ZigGotSection = struct {
53 try macho_file.growSection(macho_file.zig_got_sect_index.?, needed_size);53 try macho_file.growSection(macho_file.zig_got_sect_index.?, needed_size);
54 zig_got.dirty = false;54 zig_got.dirty = false;
55 }55 }
56 const zo = macho_file.getZigObject().?;
56 const off = zig_got.entryOffset(index, macho_file);57 const off = zig_got.entryOffset(index, macho_file);
57 const entry = zig_got.entries.items[index];58 const entry = zig_got.entries.items[index];
58 const value = macho_file.getSymbol(entry).getAddress(.{ .stubs = false }, macho_file);59 const value = zo.getSymbol(entry).getAddress(.{ .stubs = false }, macho_file);
5960
60 var buf: [8]u8 = undefined;61 var buf: [8]u8 = undefined;
61 std.mem.writeInt(u64, &buf, value, .little);62 std.mem.writeInt(u64, &buf, value, .little);
...@@ -63,8 +64,9 @@ pub const ZigGotSection = struct {...@@ -63,8 +64,9 @@ pub const ZigGotSection = struct {
63 }64 }
6465
65 pub fn writeAll(zig_got: ZigGotSection, macho_file: *MachO, writer: anytype) !void {66 pub fn writeAll(zig_got: ZigGotSection, macho_file: *MachO, writer: anytype) !void {
67 const zo = macho_file.getZigObject().?;
66 for (zig_got.entries.items) |entry| {68 for (zig_got.entries.items) |entry| {
67 const symbol = macho_file.getSymbol(entry);69 const symbol = zo.getSymbol(entry);
68 const value = symbol.address(.{ .stubs = false }, macho_file);70 const value = symbol.address(.{ .stubs = false }, macho_file);
69 try writer.writeInt(u64, value, .little);71 try writer.writeInt(u64, value, .little);
70 }72 }
...@@ -87,22 +89,25 @@ pub const ZigGotSection = struct {...@@ -87,22 +89,25 @@ pub const ZigGotSection = struct {
87 ) !void {89 ) !void {
88 _ = options;90 _ = options;
89 _ = unused_fmt_string;91 _ = unused_fmt_string;
92 const zig_got = ctx.zig_got;
93 const macho_file = ctx.macho_file;
94 const zo = macho_file.getZigObject().?;
90 try writer.writeAll("__zig_got\n");95 try writer.writeAll("__zig_got\n");
91 for (ctx.zig_got.entries.items, 0..) |entry, index| {96 for (zig_got.entries.items, 0..) |entry, index| {
92 const symbol = ctx.macho_file.getSymbol(entry);97 const symbol = zo.getSymbol(entry);
93 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{98 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{
94 index,99 index,
95 ctx.zig_got.entryAddress(@intCast(index), ctx.macho_file),100 zig_got.entryAddress(@intCast(index), macho_file),
96 entry,101 entry,
97 symbol.getAddress(.{}, ctx.macho_file),102 symbol.getAddress(.{}, macho_file),
98 symbol.getName(ctx.macho_file),103 symbol.getName(macho_file),
99 });104 });
100 }105 }
101 }106 }
102};107};
103108
104pub const GotSection = struct {109pub const GotSection = struct {
105 symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},110 symbols: std.ArrayListUnmanaged(MachO.Ref) = .{},
106111
107 pub const Index = u32;112 pub const Index = u32;
108113
...@@ -110,14 +115,14 @@ pub const GotSection = struct {...@@ -110,14 +115,14 @@ pub const GotSection = struct {
110 got.symbols.deinit(allocator);115 got.symbols.deinit(allocator);
111 }116 }
112117
113 pub fn addSymbol(got: *GotSection, sym_index: Symbol.Index, macho_file: *MachO) !void {118 pub fn addSymbol(got: *GotSection, ref: MachO.Ref, macho_file: *MachO) !void {
114 const gpa = macho_file.base.comp.gpa;119 const gpa = macho_file.base.comp.gpa;
115 const index = @as(Index, @intCast(got.symbols.items.len));120 const index = @as(Index, @intCast(got.symbols.items.len));
116 const entry = try got.symbols.addOne(gpa);121 const entry = try got.symbols.addOne(gpa);
117 entry.* = sym_index;122 entry.* = ref;
118 const symbol = macho_file.getSymbol(sym_index);123 const symbol = ref.getSymbol(macho_file).?;
119 symbol.flags.has_got = true;124 symbol.flags.has_got = true;
120 try symbol.addExtra(.{ .got = index }, macho_file);125 symbol.addExtra(.{ .got = index }, macho_file);
121 }126 }
122127
123 pub fn getAddress(got: GotSection, index: Index, macho_file: *MachO) u64 {128 pub fn getAddress(got: GotSection, index: Index, macho_file: *MachO) u64 {
...@@ -133,8 +138,8 @@ pub const GotSection = struct {...@@ -133,8 +138,8 @@ pub const GotSection = struct {
133 pub fn write(got: GotSection, macho_file: *MachO, writer: anytype) !void {138 pub fn write(got: GotSection, macho_file: *MachO, writer: anytype) !void {
134 const tracy = trace(@src());139 const tracy = trace(@src());
135 defer tracy.end();140 defer tracy.end();
136 for (got.symbols.items) |sym_index| {141 for (got.symbols.items) |ref| {
137 const sym = macho_file.getSymbol(sym_index);142 const sym = ref.getSymbol(macho_file).?;
138 const value = if (sym.flags.import) @as(u64, 0) else sym.getAddress(.{}, macho_file);143 const value = if (sym.flags.import) @as(u64, 0) else sym.getAddress(.{}, macho_file);
139 try writer.writeInt(u64, value, .little);144 try writer.writeInt(u64, value, .little);
140 }145 }
...@@ -157,12 +162,12 @@ pub const GotSection = struct {...@@ -157,12 +162,12 @@ pub const GotSection = struct {
157 ) !void {162 ) !void {
158 _ = options;163 _ = options;
159 _ = unused_fmt_string;164 _ = unused_fmt_string;
160 for (ctx.got.symbols.items, 0..) |entry, i| {165 for (ctx.got.symbols.items, 0..) |ref, i| {
161 const symbol = ctx.macho_file.getSymbol(entry);166 const symbol = ref.getSymbol(ctx.macho_file).?;
162 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{167 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{
163 i,168 i,
164 symbol.getGotAddress(ctx.macho_file),169 symbol.getGotAddress(ctx.macho_file),
165 entry,170 ref,
166 symbol.getAddress(.{}, ctx.macho_file),171 symbol.getAddress(.{}, ctx.macho_file),
167 symbol.getName(ctx.macho_file),172 symbol.getName(ctx.macho_file),
168 });173 });
...@@ -171,7 +176,7 @@ pub const GotSection = struct {...@@ -171,7 +176,7 @@ pub const GotSection = struct {
171};176};
172177
173pub const StubsSection = struct {178pub const StubsSection = struct {
174 symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},179 symbols: std.ArrayListUnmanaged(MachO.Ref) = .{},
175180
176 pub const Index = u32;181 pub const Index = u32;
177182
...@@ -179,13 +184,13 @@ pub const StubsSection = struct {...@@ -179,13 +184,13 @@ pub const StubsSection = struct {
179 stubs.symbols.deinit(allocator);184 stubs.symbols.deinit(allocator);
180 }185 }
181186
182 pub fn addSymbol(stubs: *StubsSection, sym_index: Symbol.Index, macho_file: *MachO) !void {187 pub fn addSymbol(stubs: *StubsSection, ref: MachO.Ref, macho_file: *MachO) !void {
183 const gpa = macho_file.base.comp.gpa;188 const gpa = macho_file.base.comp.gpa;
184 const index = @as(Index, @intCast(stubs.symbols.items.len));189 const index = @as(Index, @intCast(stubs.symbols.items.len));
185 const entry = try stubs.symbols.addOne(gpa);190 const entry = try stubs.symbols.addOne(gpa);
186 entry.* = sym_index;191 entry.* = ref;
187 const symbol = macho_file.getSymbol(sym_index);192 const symbol = ref.getSymbol(macho_file).?;
188 try symbol.addExtra(.{ .stubs = index }, macho_file);193 symbol.addExtra(.{ .stubs = index }, macho_file);
189 }194 }
190195
191 pub fn getAddress(stubs: StubsSection, index: Index, macho_file: *MachO) u64 {196 pub fn getAddress(stubs: StubsSection, index: Index, macho_file: *MachO) u64 {
...@@ -205,8 +210,8 @@ pub const StubsSection = struct {...@@ -205,8 +210,8 @@ pub const StubsSection = struct {
205 const cpu_arch = macho_file.getTarget().cpu.arch;210 const cpu_arch = macho_file.getTarget().cpu.arch;
206 const laptr_sect = macho_file.sections.items(.header)[macho_file.la_symbol_ptr_sect_index.?];211 const laptr_sect = macho_file.sections.items(.header)[macho_file.la_symbol_ptr_sect_index.?];
207212
208 for (stubs.symbols.items, 0..) |sym_index, idx| {213 for (stubs.symbols.items, 0..) |ref, idx| {
209 const sym = macho_file.getSymbol(sym_index);214 const sym = ref.getSymbol(macho_file).?;
210 const source = sym.getAddress(.{ .stubs = true }, macho_file);215 const source = sym.getAddress(.{ .stubs = true }, macho_file);
211 const target = laptr_sect.addr + idx * @sizeOf(u64);216 const target = laptr_sect.addr + idx * @sizeOf(u64);
212 switch (cpu_arch) {217 switch (cpu_arch) {
...@@ -248,12 +253,12 @@ pub const StubsSection = struct {...@@ -248,12 +253,12 @@ pub const StubsSection = struct {
248 ) !void {253 ) !void {
249 _ = options;254 _ = options;
250 _ = unused_fmt_string;255 _ = unused_fmt_string;
251 for (ctx.stubs.symbols.items, 0..) |entry, i| {256 for (ctx.stubs.symbols.items, 0..) |ref, i| {
252 const symbol = ctx.macho_file.getSymbol(entry);257 const symbol = ref.getSymbol(ctx.macho_file).?;
253 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{258 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{
254 i,259 i,
255 symbol.getStubsAddress(ctx.macho_file),260 symbol.getStubsAddress(ctx.macho_file),
256 entry,261 ref,
257 symbol.getAddress(.{}, ctx.macho_file),262 symbol.getAddress(.{}, ctx.macho_file),
258 symbol.getName(ctx.macho_file),263 symbol.getName(ctx.macho_file),
259 });264 });
...@@ -284,8 +289,8 @@ pub const StubsHelperSection = struct {...@@ -284,8 +289,8 @@ pub const StubsHelperSection = struct {
284 _ = stubs_helper;289 _ = stubs_helper;
285 const cpu_arch = macho_file.getTarget().cpu.arch;290 const cpu_arch = macho_file.getTarget().cpu.arch;
286 var s: usize = preambleSize(cpu_arch);291 var s: usize = preambleSize(cpu_arch);
287 for (macho_file.stubs.symbols.items) |sym_index| {292 for (macho_file.stubs.symbols.items) |ref| {
288 const sym = macho_file.getSymbol(sym_index);293 const sym = ref.getSymbol(macho_file).?;
289 if (sym.flags.weak) continue;294 if (sym.flags.weak) continue;
290 s += entrySize(cpu_arch);295 s += entrySize(cpu_arch);
291 }296 }
...@@ -304,8 +309,8 @@ pub const StubsHelperSection = struct {...@@ -304,8 +309,8 @@ pub const StubsHelperSection = struct {
304 const entry_size = entrySize(cpu_arch);309 const entry_size = entrySize(cpu_arch);
305310
306 var idx: usize = 0;311 var idx: usize = 0;
307 for (macho_file.stubs.symbols.items) |sym_index| {312 for (macho_file.stubs.symbols.items) |ref| {
308 const sym = macho_file.getSymbol(sym_index);313 const sym = ref.getSymbol(macho_file).?;
309 if (sym.flags.weak) continue;314 if (sym.flags.weak) continue;
310 const offset = macho_file.lazy_bind.offsets.items[idx];315 const offset = macho_file.lazy_bind.offsets.items[idx];
311 const source: i64 = @intCast(sect.addr + preamble_size + entry_size * idx);316 const source: i64 = @intCast(sect.addr + preamble_size + entry_size * idx);
...@@ -339,14 +344,15 @@ pub const StubsHelperSection = struct {...@@ -339,14 +344,15 @@ pub const StubsHelperSection = struct {
339344
340 fn writePreamble(stubs_helper: StubsHelperSection, macho_file: *MachO, writer: anytype) !void {345 fn writePreamble(stubs_helper: StubsHelperSection, macho_file: *MachO, writer: anytype) !void {
341 _ = stubs_helper;346 _ = stubs_helper;
347 const obj = macho_file.getInternalObject().?;
342 const cpu_arch = macho_file.getTarget().cpu.arch;348 const cpu_arch = macho_file.getTarget().cpu.arch;
343 const sect = macho_file.sections.items(.header)[macho_file.stubs_helper_sect_index.?];349 const sect = macho_file.sections.items(.header)[macho_file.stubs_helper_sect_index.?];
344 const dyld_private_addr = target: {350 const dyld_private_addr = target: {
345 const sym = macho_file.getSymbol(macho_file.dyld_private_index.?);351 const sym = obj.getDyldPrivateRef(macho_file).?.getSymbol(macho_file).?;
346 break :target sym.getAddress(.{}, macho_file);352 break :target sym.getAddress(.{}, macho_file);
347 };353 };
348 const dyld_stub_binder_addr = target: {354 const dyld_stub_binder_addr = target: {
349 const sym = macho_file.getSymbol(macho_file.dyld_stub_binder_index.?);355 const sym = obj.getDyldStubBinderRef(macho_file).?.getSymbol(macho_file).?;
350 break :target sym.getGotAddress(macho_file);356 break :target sym.getGotAddress(macho_file);
351 };357 };
352 switch (cpu_arch) {358 switch (cpu_arch) {
...@@ -402,8 +408,8 @@ pub const LaSymbolPtrSection = struct {...@@ -402,8 +408,8 @@ pub const LaSymbolPtrSection = struct {
402 const cpu_arch = macho_file.getTarget().cpu.arch;408 const cpu_arch = macho_file.getTarget().cpu.arch;
403 const sect = macho_file.sections.items(.header)[macho_file.stubs_helper_sect_index.?];409 const sect = macho_file.sections.items(.header)[macho_file.stubs_helper_sect_index.?];
404 var stub_helper_idx: u32 = 0;410 var stub_helper_idx: u32 = 0;
405 for (macho_file.stubs.symbols.items) |sym_index| {411 for (macho_file.stubs.symbols.items) |ref| {
406 const sym = macho_file.getSymbol(sym_index);412 const sym = ref.getSymbol(macho_file).?;
407 if (sym.flags.weak) {413 if (sym.flags.weak) {
408 const value = sym.getAddress(.{ .stubs = false }, macho_file);414 const value = sym.getAddress(.{ .stubs = false }, macho_file);
409 try writer.writeInt(u64, @intCast(value), .little);415 try writer.writeInt(u64, @intCast(value), .little);
...@@ -418,7 +424,7 @@ pub const LaSymbolPtrSection = struct {...@@ -418,7 +424,7 @@ pub const LaSymbolPtrSection = struct {
418};424};
419425
420pub const TlvPtrSection = struct {426pub const TlvPtrSection = struct {
421 symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},427 symbols: std.ArrayListUnmanaged(MachO.Ref) = .{},
422428
423 pub const Index = u32;429 pub const Index = u32;
424430
...@@ -426,13 +432,13 @@ pub const TlvPtrSection = struct {...@@ -426,13 +432,13 @@ pub const TlvPtrSection = struct {
426 tlv.symbols.deinit(allocator);432 tlv.symbols.deinit(allocator);
427 }433 }
428434
429 pub fn addSymbol(tlv: *TlvPtrSection, sym_index: Symbol.Index, macho_file: *MachO) !void {435 pub fn addSymbol(tlv: *TlvPtrSection, ref: MachO.Ref, macho_file: *MachO) !void {
430 const gpa = macho_file.base.comp.gpa;436 const gpa = macho_file.base.comp.gpa;
431 const index = @as(Index, @intCast(tlv.symbols.items.len));437 const index = @as(Index, @intCast(tlv.symbols.items.len));
432 const entry = try tlv.symbols.addOne(gpa);438 const entry = try tlv.symbols.addOne(gpa);
433 entry.* = sym_index;439 entry.* = ref;
434 const symbol = macho_file.getSymbol(sym_index);440 const symbol = ref.getSymbol(macho_file).?;
435 try symbol.addExtra(.{ .tlv_ptr = index }, macho_file);441 symbol.addExtra(.{ .tlv_ptr = index }, macho_file);
436 }442 }
437443
438 pub fn getAddress(tlv: TlvPtrSection, index: Index, macho_file: *MachO) u64 {444 pub fn getAddress(tlv: TlvPtrSection, index: Index, macho_file: *MachO) u64 {
...@@ -449,8 +455,8 @@ pub const TlvPtrSection = struct {...@@ -449,8 +455,8 @@ pub const TlvPtrSection = struct {
449 const tracy = trace(@src());455 const tracy = trace(@src());
450 defer tracy.end();456 defer tracy.end();
451457
452 for (tlv.symbols.items) |sym_index| {458 for (tlv.symbols.items) |ref| {
453 const sym = macho_file.getSymbol(sym_index);459 const sym = ref.getSymbol(macho_file).?;
454 if (sym.flags.import) {460 if (sym.flags.import) {
455 try writer.writeInt(u64, 0, .little);461 try writer.writeInt(u64, 0, .little);
456 } else {462 } else {
...@@ -476,12 +482,12 @@ pub const TlvPtrSection = struct {...@@ -476,12 +482,12 @@ pub const TlvPtrSection = struct {
476 ) !void {482 ) !void {
477 _ = options;483 _ = options;
478 _ = unused_fmt_string;484 _ = unused_fmt_string;
479 for (ctx.tlv.symbols.items, 0..) |entry, i| {485 for (ctx.tlv.symbols.items, 0..) |ref, i| {
480 const symbol = ctx.macho_file.getSymbol(entry);486 const symbol = ref.getSymbol(ctx.macho_file).?;
481 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{487 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{
482 i,488 i,
483 symbol.getTlvPtrAddress(ctx.macho_file),489 symbol.getTlvPtrAddress(ctx.macho_file),
484 entry,490 ref,
485 symbol.getAddress(.{}, ctx.macho_file),491 symbol.getAddress(.{}, ctx.macho_file),
486 symbol.getName(ctx.macho_file),492 symbol.getName(ctx.macho_file),
487 });493 });
...@@ -490,7 +496,7 @@ pub const TlvPtrSection = struct {...@@ -490,7 +496,7 @@ pub const TlvPtrSection = struct {
490};496};
491497
492pub const ObjcStubsSection = struct {498pub const ObjcStubsSection = struct {
493 symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},499 symbols: std.ArrayListUnmanaged(MachO.Ref) = .{},
494500
495 pub fn deinit(objc: *ObjcStubsSection, allocator: Allocator) void {501 pub fn deinit(objc: *ObjcStubsSection, allocator: Allocator) void {
496 objc.symbols.deinit(allocator);502 objc.symbols.deinit(allocator);
...@@ -504,13 +510,13 @@ pub const ObjcStubsSection = struct {...@@ -504,13 +510,13 @@ pub const ObjcStubsSection = struct {
504 };510 };
505 }511 }
506512
507 pub fn addSymbol(objc: *ObjcStubsSection, sym_index: Symbol.Index, macho_file: *MachO) !void {513 pub fn addSymbol(objc: *ObjcStubsSection, ref: MachO.Ref, macho_file: *MachO) !void {
508 const gpa = macho_file.base.comp.gpa;514 const gpa = macho_file.base.comp.gpa;
509 const index = @as(Index, @intCast(objc.symbols.items.len));515 const index = @as(Index, @intCast(objc.symbols.items.len));
510 const entry = try objc.symbols.addOne(gpa);516 const entry = try objc.symbols.addOne(gpa);
511 entry.* = sym_index;517 entry.* = ref;
512 const symbol = macho_file.getSymbol(sym_index);518 const symbol = ref.getSymbol(macho_file).?;
513 try symbol.addExtra(.{ .objc_stubs = index }, macho_file);519 symbol.addExtra(.{ .objc_stubs = index }, macho_file);
514 }520 }
515521
516 pub fn getAddress(objc: ObjcStubsSection, index: Index, macho_file: *MachO) u64 {522 pub fn getAddress(objc: ObjcStubsSection, index: Index, macho_file: *MachO) u64 {
...@@ -527,8 +533,10 @@ pub const ObjcStubsSection = struct {...@@ -527,8 +533,10 @@ pub const ObjcStubsSection = struct {
527 const tracy = trace(@src());533 const tracy = trace(@src());
528 defer tracy.end();534 defer tracy.end();
529535
530 for (objc.symbols.items, 0..) |sym_index, idx| {536 const obj = macho_file.getInternalObject().?;
531 const sym = macho_file.getSymbol(sym_index);537
538 for (objc.symbols.items, 0..) |ref, idx| {
539 const sym = ref.getSymbol(macho_file).?;
532 const addr = objc.getAddress(@intCast(idx), macho_file);540 const addr = objc.getAddress(@intCast(idx), macho_file);
533 switch (macho_file.getTarget().cpu.arch) {541 switch (macho_file.getTarget().cpu.arch) {
534 .x86_64 => {542 .x86_64 => {
...@@ -540,7 +548,7 @@ pub const ObjcStubsSection = struct {...@@ -540,7 +548,7 @@ pub const ObjcStubsSection = struct {
540 }548 }
541 try writer.writeAll(&.{ 0xff, 0x25 });549 try writer.writeAll(&.{ 0xff, 0x25 });
542 {550 {
543 const target_sym = macho_file.getSymbol(macho_file.objc_msg_send_index.?);551 const target_sym = obj.getObjcMsgSendRef(macho_file).?.getSymbol(macho_file).?;
544 const target = target_sym.getGotAddress(macho_file);552 const target = target_sym.getGotAddress(macho_file);
545 const source = addr + 7;553 const source = addr + 7;
546 try writer.writeInt(i32, @intCast(target - source - 2 - 4), .little);554 try writer.writeInt(i32, @intCast(target - source - 2 - 4), .little);
...@@ -560,7 +568,7 @@ pub const ObjcStubsSection = struct {...@@ -560,7 +568,7 @@ pub const ObjcStubsSection = struct {
560 );568 );
561 }569 }
562 {570 {
563 const target_sym = macho_file.getSymbol(macho_file.objc_msg_send_index.?);571 const target_sym = obj.getObjcMsgSendRef(macho_file).?.getSymbol(macho_file).?;
564 const target = target_sym.getGotAddress(macho_file);572 const target = target_sym.getGotAddress(macho_file);
565 const source = addr + 2 * @sizeOf(u32);573 const source = addr + 2 * @sizeOf(u32);
566 const pages = try aarch64.calcNumberOfPages(@intCast(source), @intCast(target));574 const pages = try aarch64.calcNumberOfPages(@intCast(source), @intCast(target));
...@@ -599,12 +607,12 @@ pub const ObjcStubsSection = struct {...@@ -599,12 +607,12 @@ pub const ObjcStubsSection = struct {
599 ) !void {607 ) !void {
600 _ = options;608 _ = options;
601 _ = unused_fmt_string;609 _ = unused_fmt_string;
602 for (ctx.objc.symbols.items, 0..) |entry, i| {610 for (ctx.objc.symbols.items, 0..) |ref, i| {
603 const symbol = ctx.macho_file.getSymbol(entry);611 const symbol = ref.getSymbol(ctx.macho_file).?;
604 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{612 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{
605 i,613 i,
606 symbol.getObjcStubsAddress(ctx.macho_file),614 symbol.getObjcStubsAddress(ctx.macho_file),
607 entry,615 ref,
608 symbol.getAddress(.{}, ctx.macho_file),616 symbol.getAddress(.{}, ctx.macho_file),
609 symbol.getName(ctx.macho_file),617 symbol.getName(ctx.macho_file),
610 });618 });
...@@ -620,31 +628,89 @@ pub const Indsymtab = struct {...@@ -620,31 +628,89 @@ pub const Indsymtab = struct {
620 return @intCast(macho_file.stubs.symbols.items.len * 2 + macho_file.got.symbols.items.len);628 return @intCast(macho_file.stubs.symbols.items.len * 2 + macho_file.got.symbols.items.len);
621 }629 }
622630
631 pub fn updateSize(ind: *Indsymtab, macho_file: *MachO) !void {
632 macho_file.dysymtab_cmd.nindirectsyms = ind.nsyms(macho_file);
633 }
634
623 pub fn write(ind: Indsymtab, macho_file: *MachO, writer: anytype) !void {635 pub fn write(ind: Indsymtab, macho_file: *MachO, writer: anytype) !void {
624 const tracy = trace(@src());636 const tracy = trace(@src());
625 defer tracy.end();637 defer tracy.end();
626638
627 _ = ind;639 _ = ind;
628640
629 for (macho_file.stubs.symbols.items) |sym_index| {641 for (macho_file.stubs.symbols.items) |ref| {
630 const sym = macho_file.getSymbol(sym_index);642 const sym = ref.getSymbol(macho_file).?;
631 try writer.writeInt(u32, sym.getOutputSymtabIndex(macho_file).?, .little);643 try writer.writeInt(u32, sym.getOutputSymtabIndex(macho_file).?, .little);
632 }644 }
633645
634 for (macho_file.got.symbols.items) |sym_index| {646 for (macho_file.got.symbols.items) |ref| {
635 const sym = macho_file.getSymbol(sym_index);647 const sym = ref.getSymbol(macho_file).?;
636 try writer.writeInt(u32, sym.getOutputSymtabIndex(macho_file).?, .little);648 try writer.writeInt(u32, sym.getOutputSymtabIndex(macho_file).?, .little);
637 }649 }
638650
639 for (macho_file.stubs.symbols.items) |sym_index| {651 for (macho_file.stubs.symbols.items) |ref| {
640 const sym = macho_file.getSymbol(sym_index);652 const sym = ref.getSymbol(macho_file).?;
641 try writer.writeInt(u32, sym.getOutputSymtabIndex(macho_file).?, .little);653 try writer.writeInt(u32, sym.getOutputSymtabIndex(macho_file).?, .little);
642 }654 }
643 }655 }
644};656};
645657
658pub const DataInCode = struct {
659 entries: std.ArrayListUnmanaged(macho.data_in_code_entry) = .{},
660
661 pub fn deinit(dice: *DataInCode, allocator: Allocator) void {
662 dice.entries.deinit(allocator);
663 }
664
665 pub fn size(dice: DataInCode) usize {
666 return dice.entries.items.len * @sizeOf(macho.data_in_code_entry);
667 }
668
669 pub fn updateSize(dice: *DataInCode, macho_file: *MachO) !void {
670 const gpa = macho_file.base.comp.gpa;
671 const base_address = if (!macho_file.base.isRelocatable())
672 macho_file.getTextSegment().vmaddr
673 else
674 0;
675
676 for (macho_file.objects.items) |index| {
677 const object = macho_file.getFile(index).?.object;
678 const dices = object.getDataInCode();
679
680 try dice.entries.ensureUnusedCapacity(gpa, dices.len);
681
682 var next_dice: usize = 0;
683 for (object.getAtoms()) |atom_index| {
684 if (next_dice >= dices.len) break;
685 const atom = object.getAtom(atom_index) orelse continue;
686 if (!atom.flags.alive) continue;
687 const start_off = atom.getInputAddress(macho_file);
688 const end_off = start_off + atom.size;
689 const start_dice = next_dice;
690
691 if (end_off < dices[next_dice].offset) continue;
692
693 while (next_dice < dices.len and
694 dices[next_dice].offset < end_off) : (next_dice += 1)
695 {}
696
697 if (atom.alive.load(.seq_cst)) for (dices[start_dice..next_dice]) |d| {
698 dice.entries.appendAssumeCapacity(.{
699 .offset = @intCast(atom.getAddress(macho_file) + d.offset - start_off - base_address),
700 .length = d.length,
701 .kind = d.kind,
702 });
703 };
704 }
705 }
706
707 macho_file.data_in_code_cmd.datasize = math.cast(u32, dice.size()) orelse return error.Overflow;
708 }
709};
710
646const aarch64 = @import("../aarch64.zig");711const aarch64 = @import("../aarch64.zig");
647const assert = std.debug.assert;712const assert = std.debug.assert;
713const macho = std.macho;
648const math = std.math;714const math = std.math;
649const std = @import("std");715const std = @import("std");
650const trace = @import("../../tracy.zig").trace;716const trace = @import("../../tracy.zig").trace;