authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-10 16:36:32+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-18 09:13:08+02:00
log174de37cefde3b22b02fee5982e7bacead4d200f
treede8e99729e11de1b9116ebd3da5077ad722d9993
parent5b4c0cc1f9c4cb047064cffb70bc649b83681814

macho: fix compile errors


17 files changed, 352 insertions(+), 281 deletions(-)

src/arch/x86_64/CodeGen.zig+6-4
...@@ -12362,8 +12362,9 @@ fn genCall(self: *Self, info: union(enum) {...@@ -12362,8 +12362,9 @@ fn genCall(self: *Self, info: union(enum) {
12362 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }, .{});12362 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }, .{});
12363 try self.asmRegister(.{ ._, .call }, .rax);12363 try self.asmRegister(.{ ._, .call }, .rax);
12364 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {12364 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
12365 const sym_index = try macho_file.getZigObject().?.getOrCreateMetadataForDecl(macho_file, func.owner_decl);12365 const zo = macho_file.getZigObject().?;
12366 const sym = macho_file.getSymbol(sym_index);12366 const sym_index = try zo.getOrCreateMetadataForDecl(macho_file, func.owner_decl);
12367 const sym = zo.symbols.items[sym_index];
12367 try self.genSetReg(12368 try self.genSetReg(
12368 .rax,12369 .rax,
12369 Type.usize,12370 Type.usize,
...@@ -15396,9 +15397,10 @@ fn genLazySymbolRef(...@@ -15396,9 +15397,10 @@ fn genLazySymbolRef(
15396 else => unreachable,15397 else => unreachable,
15397 }15398 }
15398 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {15399 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
15399 const sym_index = macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, pt, lazy_sym) catch |err|15400 const zo = macho_file.getZigObject().?;
15401 const sym_index = zo.getOrCreateMetadataForLazySymbol(macho_file, pt, lazy_sym) catch |err|
15400 return self.fail("{s} creating lazy symbol", .{@errorName(err)});15402 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
15401 const sym = macho_file.getSymbol(sym_index);15403 const sym = zo.symbols.items[sym_index];
15402 switch (tag) {15404 switch (tag) {
15403 .lea, .call => try self.genSetReg(15405 .lea, .call => try self.genSetReg(
15404 reg,15406 reg,
src/arch/x86_64/Emit.zig+1-1
...@@ -162,7 +162,7 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -162,7 +162,7 @@ pub fn emitMir(emit: *Emit) Error!void {
162 };162 };
163 const zo = macho_file.getZigObject().?;163 const zo = macho_file.getZigObject().?;
164 const atom = zo.symbols.items[data.atom_index].getAtom(macho_file).?;164 const atom = zo.symbols.items[data.atom_index].getAtom(macho_file).?;
165 const sym = zo.symbols.items[data.sym_index];165 const sym = &zo.symbols.items[data.sym_index];
166 if (sym.flags.needs_zig_got and !is_obj_or_static_lib) {166 if (sym.flags.needs_zig_got and !is_obj_or_static_lib) {
167 _ = try sym.getOrCreateZigGotEntry(data.sym_index, macho_file);167 _ = try sym.getOrCreateZigGotEntry(data.sym_index, macho_file);
168 }168 }
src/link/MachO.zig+36-29
...@@ -529,7 +529,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_n...@@ -529,7 +529,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
529 dylib.ordinal = @intCast(ord);529 dylib.ordinal = @intCast(ord);
530 }530 }
531531
532 try self.claimUnresolved();532 self.claimUnresolved();
533533
534 self.scanRelocs() catch |err| switch (err) {534 self.scanRelocs() catch |err| switch (err) {
535 error.HasUndefinedSymbols => return error.FlushFailure,535 error.HasUndefinedSymbols => return error.FlushFailure,
...@@ -603,7 +603,12 @@ pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_n...@@ -603,7 +603,12 @@ pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
603603
604 if (has_resolve_error) return error.FlushFailure;604 if (has_resolve_error) return error.FlushFailure;
605 }605 }
606 try self.writeSectionsAndUpdateLinkeditSizes();606 self.writeSectionsAndUpdateLinkeditSizes() catch |err| {
607 switch (err) {
608 error.ResolveFailed => return error.FlushFailure,
609 else => |e| return e,
610 }
611 };
607612
608 try self.writeSectionsToFile();613 try self.writeSectionsToFile();
609 try self.allocateLinkeditSegment();614 try self.allocateLinkeditSegment();
...@@ -1450,12 +1455,12 @@ pub fn dedupLiterals(self: *MachO) !void {...@@ -1450,12 +1455,12 @@ pub fn dedupLiterals(self: *MachO) !void {
1450 }1455 }
1451}1456}
14521457
1453fn claimUnresolved(self: *MachO) error{OutOfMemory}!void {1458fn claimUnresolved(self: *MachO) void {
1454 if (self.getZigObject()) |zo| {1459 if (self.getZigObject()) |zo| {
1455 try zo.asFile().claimUnresolved(self);1460 zo.claimUnresolved(self);
1456 }1461 }
1457 for (self.objects.items) |index| {1462 for (self.objects.items) |index| {
1458 try self.getFile(index).?.claimUnresolved(self);1463 self.getFile(index).?.object.claimUnresolved(self);
1459 }1464 }
1460}1465}
14611466
...@@ -2402,7 +2407,7 @@ fn writeSectionsAndUpdateLinkeditSizes(self: *MachO) !void {...@@ -2402,7 +2407,7 @@ fn writeSectionsAndUpdateLinkeditSizes(self: *MachO) !void {
2402 }2407 }
24032408
2404 if (self.la_symbol_ptr_sect_index) |_| {2409 if (self.la_symbol_ptr_sect_index) |_| {
2405 try self.updatelazyBindSize();2410 try self.updateLazyBindSize();
2406 }2411 }
24072412
2408 try self.rebase.updateSize(self);2413 try self.rebase.updateSize(self);
...@@ -2412,16 +2417,16 @@ fn writeSectionsAndUpdateLinkeditSizes(self: *MachO) !void {...@@ -2412,16 +2417,16 @@ fn writeSectionsAndUpdateLinkeditSizes(self: *MachO) !void {
2412 try self.data_in_code.updateSize(self);2417 try self.data_in_code.updateSize(self);
24132418
2414 if (self.getZigObject()) |zo| {2419 if (self.getZigObject()) |zo| {
2415 zo.asFile().writeSymtab(self);2420 zo.asFile().writeSymtab(self, self);
2416 }2421 }
2417 for (self.objects.items) |index| {2422 for (self.objects.items) |index| {
2418 self.getFile(index).?.writeSymtab(self);2423 self.getFile(index).?.writeSymtab(self, self);
2419 }2424 }
2420 for (self.dylibs.items) |index| {2425 for (self.dylibs.items) |index| {
2421 self.getFile(index).?.writeSymtab(self);2426 self.getFile(index).?.writeSymtab(self, self);
2422 }2427 }
2423 if (self.getInternalObject()) |obj| {2428 if (self.getInternalObject()) |obj| {
2424 obj.asFile().writeSymtab(self);2429 obj.asFile().writeSymtab(self, self);
2425 }2430 }
2426}2431}
24272432
...@@ -2484,7 +2489,7 @@ fn writeSectionsToFile(self: *MachO) !void {...@@ -2484,7 +2489,7 @@ fn writeSectionsToFile(self: *MachO) !void {
24842489
2485 const slice = self.sections.slice();2490 const slice = self.sections.slice();
2486 for (slice.items(.header), slice.items(.out)) |header, out| {2491 for (slice.items(.header), slice.items(.out)) |header, out| {
2487 try self.base.file.pwriteAll(out.items, header.offset);2492 try self.base.file.?.pwriteAll(out.items, header.offset);
2488 }2493 }
2489}2494}
24902495
...@@ -2501,7 +2506,7 @@ fn writeDyldInfo(self: *MachO) !void {...@@ -2501,7 +2506,7 @@ fn writeDyldInfo(self: *MachO) !void {
2501 const tracy = trace(@src());2506 const tracy = trace(@src());
2502 defer tracy.end();2507 defer tracy.end();
25032508
2504 const gpa = self.base.allocator;2509 const gpa = self.base.comp.gpa;
2505 const base_off = self.getLinkeditSegment().fileoff;2510 const base_off = self.getLinkeditSegment().fileoff;
2506 const cmd = self.dyld_info_cmd;2511 const cmd = self.dyld_info_cmd;
2507 var needed_size: u32 = 0;2512 var needed_size: u32 = 0;
...@@ -2527,14 +2532,14 @@ fn writeDyldInfo(self: *MachO) !void {...@@ -2527,14 +2532,14 @@ fn writeDyldInfo(self: *MachO) !void {
2527 try self.lazy_bind.write(writer);2532 try self.lazy_bind.write(writer);
2528 try stream.seekTo(cmd.export_off - base_off);2533 try stream.seekTo(cmd.export_off - base_off);
2529 try self.export_trie.write(writer);2534 try self.export_trie.write(writer);
2530 try self.base.file.pwriteAll(buffer, cmd.rebase_off);2535 try self.base.file.?.pwriteAll(buffer, cmd.rebase_off);
2531}2536}
25322537
2533pub fn writeDataInCode(self: *MachO) !void {2538pub fn writeDataInCode(self: *MachO) !void {
2534 const tracy = trace(@src());2539 const tracy = trace(@src());
2535 defer tracy.end();2540 defer tracy.end();
2536 const cmd = self.data_in_code_cmd;2541 const cmd = self.data_in_code_cmd;
2537 try self.base.file.pwriteAll(mem.sliceAsBytes(self.data_in_code.entries.items), cmd.dataoff);2542 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.data_in_code.entries.items), cmd.dataoff);
2538}2543}
25392544
2540fn writeIndsymtab(self: *MachO) !void {2545fn writeIndsymtab(self: *MachO) !void {
...@@ -2546,15 +2551,15 @@ fn writeIndsymtab(self: *MachO) !void {...@@ -2546,15 +2551,15 @@ fn writeIndsymtab(self: *MachO) !void {
2546 var buffer = try std.ArrayList(u8).initCapacity(gpa, needed_size);2551 var buffer = try std.ArrayList(u8).initCapacity(gpa, needed_size);
2547 defer buffer.deinit();2552 defer buffer.deinit();
2548 try self.indsymtab.write(self, buffer.writer());2553 try self.indsymtab.write(self, buffer.writer());
2549 try self.base.file.pwriteAll(buffer.items, cmd.indirectsymoff);2554 try self.base.file.?.pwriteAll(buffer.items, cmd.indirectsymoff);
2550}2555}
25512556
2552pub fn writeSymtabToFile(self: *MachO) !void {2557pub fn writeSymtabToFile(self: *MachO) !void {
2553 const tracy = trace(@src());2558 const tracy = trace(@src());
2554 defer tracy.end();2559 defer tracy.end();
2555 const cmd = self.symtab_cmd;2560 const cmd = self.symtab_cmd;
2556 try self.base.file.pwriteAll(mem.sliceAsBytes(self.symtab.items), cmd.symoff);2561 try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.symtab.items), cmd.symoff);
2557 try self.base.file.pwriteAll(self.strtab.items, cmd.stroff);2562 try self.base.file.?.pwriteAll(self.strtab.items, cmd.stroff);
2558}2563}
25592564
2560fn writeUnwindInfo(self: *MachO) !void {2565fn writeUnwindInfo(self: *MachO) !void {
...@@ -2687,18 +2692,20 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } {...@@ -2687,18 +2692,20 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } {
2687 try load_commands.writeDylinkerLC(writer);2692 try load_commands.writeDylinkerLC(writer);
2688 ncmds += 1;2693 ncmds += 1;
26892694
2690 if (self.entry_index) |global_index| {2695 if (self.getInternalObject()) |obj| {
2691 const sym = self.getSymbol(global_index);2696 if (obj.getEntryRef(self)) |ref| {
2692 const seg = self.getTextSegment();2697 const sym = ref.getSymbol(self).?;
2693 const entryoff: u32 = if (sym.getFile(self) == null)2698 const seg = self.getTextSegment();
2694 02699 const entryoff: u32 = if (sym.getFile(self) == null)
2695 else2700 0
2696 @as(u32, @intCast(sym.getAddress(.{ .stubs = true }, self) - seg.vmaddr));2701 else
2697 try writer.writeStruct(macho.entry_point_command{2702 @as(u32, @intCast(sym.getAddress(.{ .stubs = true }, self) - seg.vmaddr));
2698 .entryoff = entryoff,2703 try writer.writeStruct(macho.entry_point_command{
2699 .stacksize = self.base.stack_size,2704 .entryoff = entryoff,
2700 });2705 .stacksize = self.base.stack_size,
2701 ncmds += 1;2706 });
2707 ncmds += 1;
2708 }
2702 }2709 }
27032710
2704 if (self.base.isDynLib()) {2711 if (self.base.isDynLib()) {
src/link/MachO/Atom.zig+19-15
...@@ -213,7 +213,8 @@ pub fn initOutputSection(sect: macho.section_64, macho_file: *MachO) !u8 {...@@ -213,7 +213,8 @@ pub fn initOutputSection(sect: macho.section_64, macho_file: *MachO) !u8 {
213/// File offset relocation happens transparently, so it is not included in213/// File offset relocation happens transparently, so it is not included in
214/// this calculation.214/// this calculation.
215pub fn capacity(self: Atom, macho_file: *MachO) u64 {215pub fn capacity(self: Atom, macho_file: *MachO) u64 {
216 const next_addr = if (macho_file.getAtom(self.next_index)) |next|216 const zo = macho_file.getZigObject().?;
217 const next_addr = if (zo.getAtom(self.next_index)) |next|
217 next.getAddress(macho_file)218 next.getAddress(macho_file)
218 else219 else
219 std.math.maxInt(u32);220 std.math.maxInt(u32);
...@@ -222,7 +223,8 @@ pub fn capacity(self: Atom, macho_file: *MachO) u64 {...@@ -222,7 +223,8 @@ pub fn capacity(self: Atom, macho_file: *MachO) u64 {
222223
223pub fn freeListEligible(self: Atom, macho_file: *MachO) bool {224pub fn freeListEligible(self: Atom, macho_file: *MachO) bool {
224 // No need to keep a free list node for the last block.225 // No need to keep a free list node for the last block.
225 const next = macho_file.getAtom(self.next_index) orelse return false;226 const zo = macho_file.getZigObject().?;
227 const next = zo.getAtom(self.next_index) orelse return false;
226 const cap = next.getAddress(macho_file) - self.getAddress(macho_file);228 const cap = next.getAddress(macho_file) - self.getAddress(macho_file);
227 const ideal_cap = MachO.padToIdeal(self.size);229 const ideal_cap = MachO.padToIdeal(self.size);
228 if (cap <= ideal_cap) return false;230 if (cap <= ideal_cap) return false;
...@@ -231,6 +233,7 @@ pub fn freeListEligible(self: Atom, macho_file: *MachO) bool {...@@ -231,6 +233,7 @@ pub fn freeListEligible(self: Atom, macho_file: *MachO) bool {
231}233}
232234
233pub fn allocate(self: *Atom, macho_file: *MachO) !void {235pub fn allocate(self: *Atom, macho_file: *MachO) !void {
236 const zo = macho_file.getZigObject().?;
234 const sect = &macho_file.sections.items(.header)[self.out_n_sect];237 const sect = &macho_file.sections.items(.header)[self.out_n_sect];
235 const free_list = &macho_file.sections.items(.free_list)[self.out_n_sect];238 const free_list = &macho_file.sections.items(.free_list)[self.out_n_sect];
236 const last_atom_index = &macho_file.sections.items(.last_atom_index)[self.out_n_sect];239 const last_atom_index = &macho_file.sections.items(.last_atom_index)[self.out_n_sect];
...@@ -250,7 +253,7 @@ pub fn allocate(self: *Atom, macho_file: *MachO) !void {...@@ -250,7 +253,7 @@ pub fn allocate(self: *Atom, macho_file: *MachO) !void {
250 var i: usize = free_list.items.len;253 var i: usize = free_list.items.len;
251 while (i < free_list.items.len) {254 while (i < free_list.items.len) {
252 const big_atom_index = free_list.items[i];255 const big_atom_index = free_list.items[i];
253 const big_atom = macho_file.getAtom(big_atom_index).?;256 const big_atom = zo.getAtom(big_atom_index).?;
254 // We now have a pointer to a live atom that has too much capacity.257 // We now have a pointer to a live atom that has too much capacity.
255 // Is it enough that we could fit this new atom?258 // Is it enough that we could fit this new atom?
256 const cap = big_atom.capacity(macho_file);259 const cap = big_atom.capacity(macho_file);
...@@ -282,7 +285,7 @@ pub fn allocate(self: *Atom, macho_file: *MachO) !void {...@@ -282,7 +285,7 @@ pub fn allocate(self: *Atom, macho_file: *MachO) !void {
282 free_list_removal = i;285 free_list_removal = i;
283 }286 }
284 break :blk new_start_vaddr;287 break :blk new_start_vaddr;
285 } else if (macho_file.getAtom(last_atom_index.*)) |last| {288 } else if (zo.getAtom(last_atom_index.*)) |last| {
286 const ideal_capacity = MachO.padToIdeal(last.size);289 const ideal_capacity = MachO.padToIdeal(last.size);
287 const ideal_capacity_end_vaddr = last.value + ideal_capacity;290 const ideal_capacity_end_vaddr = last.value + ideal_capacity;
288 const new_start_vaddr = self.alignment.forward(ideal_capacity_end_vaddr);291 const new_start_vaddr = self.alignment.forward(ideal_capacity_end_vaddr);
...@@ -302,7 +305,7 @@ pub fn allocate(self: *Atom, macho_file: *MachO) !void {...@@ -302,7 +305,7 @@ pub fn allocate(self: *Atom, macho_file: *MachO) !void {
302 });305 });
303306
304 const expand_section = if (atom_placement) |placement_index|307 const expand_section = if (atom_placement) |placement_index|
305 macho_file.getAtom(placement_index).?.next_index == 0308 zo.getAtom(placement_index).?.next_index == 0
306 else309 else
307 true;310 true;
308 if (expand_section) {311 if (expand_section) {
...@@ -327,15 +330,15 @@ pub fn allocate(self: *Atom, macho_file: *MachO) !void {...@@ -327,15 +330,15 @@ pub fn allocate(self: *Atom, macho_file: *MachO) !void {
327 // This function can also reallocate an atom.330 // This function can also reallocate an atom.
328 // In this case we need to "unplug" it from its previous location before331 // In this case we need to "unplug" it from its previous location before
329 // plugging it in to its new location.332 // plugging it in to its new location.
330 if (macho_file.getAtom(self.prev_index)) |prev| {333 if (zo.getAtom(self.prev_index)) |prev| {
331 prev.next_index = self.next_index;334 prev.next_index = self.next_index;
332 }335 }
333 if (macho_file.getAtom(self.next_index)) |next| {336 if (zo.getAtom(self.next_index)) |next| {
334 next.prev_index = self.prev_index;337 next.prev_index = self.prev_index;
335 }338 }
336339
337 if (atom_placement) |big_atom_index| {340 if (atom_placement) |big_atom_index| {
338 const big_atom = macho_file.getAtom(big_atom_index).?;341 const big_atom = zo.getAtom(big_atom_index).?;
339 self.prev_index = big_atom_index;342 self.prev_index = big_atom_index;
340 self.next_index = big_atom.next_index;343 self.next_index = big_atom.next_index;
341 big_atom.next_index = self.atom_index;344 big_atom.next_index = self.atom_index;
...@@ -365,6 +368,7 @@ pub fn free(self: *Atom, macho_file: *MachO) void {...@@ -365,6 +368,7 @@ pub fn free(self: *Atom, macho_file: *MachO) void {
365368
366 const comp = macho_file.base.comp;369 const comp = macho_file.base.comp;
367 const gpa = comp.gpa;370 const gpa = comp.gpa;
371 const zo = macho_file.getZigObject().?;
368 const free_list = &macho_file.sections.items(.free_list)[self.out_n_sect];372 const free_list = &macho_file.sections.items(.free_list)[self.out_n_sect];
369 const last_atom_index = &macho_file.sections.items(.last_atom_index)[self.out_n_sect];373 const last_atom_index = &macho_file.sections.items(.last_atom_index)[self.out_n_sect];
370 var already_have_free_list_node = false;374 var already_have_free_list_node = false;
...@@ -383,9 +387,9 @@ pub fn free(self: *Atom, macho_file: *MachO) void {...@@ -383,9 +387,9 @@ pub fn free(self: *Atom, macho_file: *MachO) void {
383 }387 }
384 }388 }
385389
386 if (macho_file.getAtom(last_atom_index.*)) |last_atom| {390 if (zo.getAtom(last_atom_index.*)) |last_atom| {
387 if (last_atom.atom_index == self.atom_index) {391 if (last_atom.atom_index == self.atom_index) {
388 if (macho_file.getAtom(self.prev_index)) |_| {392 if (zo.getAtom(self.prev_index)) |_| {
389 // TODO shrink the section size here393 // TODO shrink the section size here
390 last_atom_index.* = self.prev_index;394 last_atom_index.* = self.prev_index;
391 } else {395 } else {
...@@ -394,7 +398,7 @@ pub fn free(self: *Atom, macho_file: *MachO) void {...@@ -394,7 +398,7 @@ pub fn free(self: *Atom, macho_file: *MachO) void {
394 }398 }
395 }399 }
396400
397 if (macho_file.getAtom(self.prev_index)) |prev| {401 if (zo.getAtom(self.prev_index)) |prev| {
398 prev.next_index = self.next_index;402 prev.next_index = self.next_index;
399 if (!already_have_free_list_node and prev.*.freeListEligible(macho_file)) {403 if (!already_have_free_list_node and prev.*.freeListEligible(macho_file)) {
400 // The free list is heuristics, it doesn't have to be perfect, so we can404 // The free list is heuristics, it doesn't have to be perfect, so we can
...@@ -405,7 +409,7 @@ pub fn free(self: *Atom, macho_file: *MachO) void {...@@ -405,7 +409,7 @@ pub fn free(self: *Atom, macho_file: *MachO) void {
405 self.prev_index = 0;409 self.prev_index = 0;
406 }410 }
407411
408 if (macho_file.getAtom(self.next_index)) |next| {412 if (zo.getAtom(self.next_index)) |next| {
409 next.prev_index = self.prev_index;413 next.prev_index = self.prev_index;
410 } else {414 } else {
411 self.next_index = 0;415 self.next_index = 0;
...@@ -423,7 +427,7 @@ pub fn addReloc(self: *Atom, macho_file: *MachO, reloc: Relocation) !void {...@@ -423,7 +427,7 @@ pub fn addReloc(self: *Atom, macho_file: *MachO, reloc: Relocation) !void {
423 const gpa = macho_file.base.comp.gpa;427 const gpa = macho_file.base.comp.gpa;
424 const file = self.getFile(macho_file);428 const file = self.getFile(macho_file);
425 assert(file == .zig_object);429 assert(file == .zig_object);
426 var extra = self.getExtra(macho_file).?;430 var extra = self.getExtra(macho_file);
427 const rels = &file.zig_object.relocs.items[extra.rel_index];431 const rels = &file.zig_object.relocs.items[extra.rel_index];
428 try rels.append(gpa, reloc);432 try rels.append(gpa, reloc);
429 extra.rel_count += 1;433 extra.rel_count += 1;
...@@ -432,7 +436,7 @@ pub fn addReloc(self: *Atom, macho_file: *MachO, reloc: Relocation) !void {...@@ -432,7 +436,7 @@ pub fn addReloc(self: *Atom, macho_file: *MachO, reloc: Relocation) !void {
432436
433pub fn freeRelocs(self: *Atom, macho_file: *MachO) void {437pub fn freeRelocs(self: *Atom, macho_file: *MachO) void {
434 self.getFile(macho_file).zig_object.freeAtomRelocs(self.*, macho_file);438 self.getFile(macho_file).zig_object.freeAtomRelocs(self.*, macho_file);
435 var extra = self.getExtra(macho_file).?;439 var extra = self.getExtra(macho_file);
436 extra.rel_count = 0;440 extra.rel_count = 0;
437 self.setExtra(extra, macho_file);441 self.setExtra(extra, macho_file);
438}442}
...@@ -630,7 +634,7 @@ fn resolveRelocInner(...@@ -630,7 +634,7 @@ fn resolveRelocInner(
630 const TLS = @as(i64, @intCast(macho_file.getTlsAddress()));634 const TLS = @as(i64, @intCast(macho_file.getTlsAddress()));
631 const SUB = if (subtractor) |sub| @as(i64, @intCast(sub.getTargetAddress(self, macho_file))) else 0;635 const SUB = if (subtractor) |sub| @as(i64, @intCast(sub.getTargetAddress(self, macho_file))) else 0;
632 // Address of the __got_zig table entry if any.636 // Address of the __got_zig table entry if any.
633 const ZIG_GOT = @as(i64, @intCast(rel.getZigGotTargetAddress(self, macho_file)));637 const ZIG_GOT = @as(i64, @intCast(rel.getZigGotTargetAddress(macho_file)));
634638
635 const divExact = struct {639 const divExact = struct {
636 fn divExact(atom: Atom, r: Relocation, num: u12, den: u12, ctx: *MachO) !u12 {640 fn divExact(atom: Atom, r: Relocation, num: u12, den: u12, ctx: *MachO) !u12 {
src/link/MachO/DebugSymbols.zig+6-6
...@@ -175,8 +175,9 @@ fn findFreeSpace(self: *DebugSymbols, object_size: u64, min_alignment: u64) u64...@@ -175,8 +175,9 @@ fn findFreeSpace(self: *DebugSymbols, object_size: u64, min_alignment: u64) u64
175}175}
176176
177pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {177pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {
178 const zo = macho_file.getZigObject().?;
178 for (self.relocs.items) |*reloc| {179 for (self.relocs.items) |*reloc| {
179 const sym = macho_file.getSymbol(reloc.target);180 const sym = zo.symbols.items[reloc.target];
180 const sym_name = sym.getName(macho_file);181 const sym_name = sym.getName(macho_file);
181 const addr = switch (reloc.type) {182 const addr = switch (reloc.type) {
182 .direct_load => sym.getAddress(.{}, macho_file),183 .direct_load => sym.getAddress(.{}, macho_file),
...@@ -382,23 +383,22 @@ pub fn writeSymtab(self: *DebugSymbols, off: u32, macho_file: *MachO) !u32 {...@@ -382,23 +383,22 @@ pub fn writeSymtab(self: *DebugSymbols, off: u32, macho_file: *MachO) !u32 {
382 cmd.symoff = off;383 cmd.symoff = off;
383384
384 try self.symtab.resize(gpa, cmd.nsyms);385 try self.symtab.resize(gpa, cmd.nsyms);
385 try self.strtab.ensureUnusedCapacity(gpa, cmd.strsize - 1);386 try self.strtab.resize(gpa, cmd.strsize);
387 self.strtab.items[0] = 0;
386388
387 if (macho_file.getZigObject()) |zo| {389 if (macho_file.getZigObject()) |zo| {
388 zo.writeSymtab(macho_file, self);390 zo.writeSymtab(macho_file, self);
389 }391 }
390 for (macho_file.objects.items) |index| {392 for (macho_file.objects.items) |index| {
391 try macho_file.getFile(index).?.writeSymtab(macho_file, self);393 macho_file.getFile(index).?.writeSymtab(macho_file, self);
392 }394 }
393 for (macho_file.dylibs.items) |index| {395 for (macho_file.dylibs.items) |index| {
394 try macho_file.getFile(index).?.writeSymtab(macho_file, self);396 macho_file.getFile(index).?.writeSymtab(macho_file, self);
395 }397 }
396 if (macho_file.getInternalObject()) |internal| {398 if (macho_file.getInternalObject()) |internal| {
397 internal.writeSymtab(macho_file, self);399 internal.writeSymtab(macho_file, self);
398 }400 }
399401
400 assert(self.strtab.items.len == cmd.strsize);
401
402 try self.file.pwriteAll(mem.sliceAsBytes(self.symtab.items), cmd.symoff);402 try self.file.pwriteAll(mem.sliceAsBytes(self.symtab.items), cmd.symoff);
403403
404 return off + cmd.nsyms * @sizeOf(macho.nlist_64);404 return off + cmd.nsyms * @sizeOf(macho.nlist_64);
src/link/MachO/Dylib.zig+15-9
...@@ -6,7 +6,7 @@ strtab: std.ArrayListUnmanaged(u8) = .{},...@@ -6,7 +6,7 @@ strtab: std.ArrayListUnmanaged(u8) = .{},
6id: ?Id = null,6id: ?Id = null,
7ordinal: u16 = 0,7ordinal: u16 = 0,
88
9symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},9symbols: std.ArrayListUnmanaged(Symbol) = .{},
10symbols_extra: std.ArrayListUnmanaged(u32) = .{},10symbols_extra: std.ArrayListUnmanaged(u32) = .{},
11globals: std.ArrayListUnmanaged(MachO.SymbolResolver.Index) = .{},11globals: std.ArrayListUnmanaged(MachO.SymbolResolver.Index) = .{},
12dependents: std.ArrayListUnmanaged(Id) = .{},12dependents: std.ArrayListUnmanaged(Id) = .{},
...@@ -516,7 +516,7 @@ pub fn initSymbols(self: *Dylib, macho_file: *MachO) !void {...@@ -516,7 +516,7 @@ pub fn initSymbols(self: *Dylib, macho_file: *MachO) !void {
516 }516 }
517}517}
518518
519pub fn resolveSymbols(self: *Dylib, macho_file: *MachO) void {519pub fn resolveSymbols(self: *Dylib, macho_file: *MachO) !void {
520 const tracy = trace(@src());520 const tracy = trace(@src());
521 defer tracy.end();521 defer tracy.end();
522522
...@@ -584,7 +584,7 @@ pub fn calcSymtabSize(self: *Dylib, macho_file: *MachO) void {...@@ -584,7 +584,7 @@ pub fn calcSymtabSize(self: *Dylib, macho_file: *MachO) void {
584 }584 }
585}585}
586586
587pub fn writeSymtab(self: Dylib, macho_file: *MachO) void {587pub fn writeSymtab(self: Dylib, macho_file: *MachO, ctx: anytype) void {
588 const tracy = trace(@src());588 const tracy = trace(@src());
589 defer tracy.end();589 defer tracy.end();
590590
...@@ -594,13 +594,13 @@ pub fn writeSymtab(self: Dylib, macho_file: *MachO) void {...@@ -594,13 +594,13 @@ pub fn writeSymtab(self: Dylib, macho_file: *MachO) void {
594 const file = ref.getFile(macho_file) orelse continue;594 const file = ref.getFile(macho_file) orelse continue;
595 if (file.getIndex() != self.index) continue;595 if (file.getIndex() != self.index) continue;
596 const idx = sym.getOutputSymtabIndex(macho_file) orelse continue;596 const idx = sym.getOutputSymtabIndex(macho_file) orelse continue;
597 const out_sym = &macho_file.symtab.items[idx];597 const out_sym = &ctx.symtab.items[idx];
598 out_sym.n_strx = n_strx;598 out_sym.n_strx = n_strx;
599 sym.setOutputSym(macho_file, out_sym);599 sym.setOutputSym(macho_file, out_sym);
600 const name = sym.getName(macho_file);600 const name = sym.getName(macho_file);
601 @memcpy(macho_file.strtab.items[n_strx..][0..name.len], name);601 @memcpy(ctx.strtab.items[n_strx..][0..name.len], name);
602 n_strx += @intCast(name.len);602 n_strx += @intCast(name.len);
603 macho_file.strtab.items[n_strx] = 0;603 ctx.strtab.items[n_strx] = 0;
604 n_strx += 1;604 n_strx += 1;
605 }605 }
606}606}
...@@ -718,10 +718,16 @@ fn formatSymtab(...@@ -718,10 +718,16 @@ fn formatSymtab(
718 _ = unused_fmt_string;718 _ = unused_fmt_string;
719 _ = options;719 _ = options;
720 const dylib = ctx.dylib;720 const dylib = ctx.dylib;
721 const macho_file = ctx.macho_file;
721 try writer.writeAll(" globals\n");722 try writer.writeAll(" globals\n");
722 for (dylib.symbols.items) |index| {723 for (dylib.symbols.items, 0..) |sym, i| {
723 const global = ctx.macho_file.getSymbol(index);724 const ref = dylib.getSymbolRef(@intCast(i), macho_file);
724 try writer.print(" {}\n", .{global.fmt(ctx.macho_file)});725 if (ref.getFile(macho_file) == null) {
726 // TODO any better way of handling this?
727 try writer.print(" {s} : unclaimed\n", .{sym.getName(macho_file)});
728 } else {
729 try writer.print(" {}\n", .{ref.getSymbol(macho_file).?.fmt(macho_file)});
730 }
725 }731 }
726}732}
727733
src/link/MachO/InternalObject.zig+19-19
...@@ -16,7 +16,7 @@ objc_selrefs: [@sizeOf(u64)]u8 = [_]u8{0} ** @sizeOf(u64),...@@ -16,7 +16,7 @@ objc_selrefs: [@sizeOf(u64)]u8 = [_]u8{0} ** @sizeOf(u64),
16force_undefined: std.ArrayListUnmanaged(Symbol.Index) = .{},16force_undefined: std.ArrayListUnmanaged(Symbol.Index) = .{},
17entry_index: ?Symbol.Index = null,17entry_index: ?Symbol.Index = null,
18dyld_stub_binder_index: ?Symbol.Index = null,18dyld_stub_binder_index: ?Symbol.Index = null,
19dyld_private: ?Symbol.Index = null,19dyld_private_index: ?Symbol.Index = null,
20objc_msg_send_index: ?Symbol.Index = null,20objc_msg_send_index: ?Symbol.Index = null,
21mh_execute_header_index: ?Symbol.Index = null,21mh_execute_header_index: ?Symbol.Index = null,
22mh_dylib_header_index: ?Symbol.Index = null,22mh_dylib_header_index: ?Symbol.Index = null,
...@@ -206,7 +206,7 @@ pub fn resolveBoundarySymbols(self: *InternalObject, macho_file: *MachO) !void {...@@ -206,7 +206,7 @@ pub fn resolveBoundarySymbols(self: *InternalObject, macho_file: *MachO) !void {
206 const nlist_idx: u32 = @intCast(self.symtab.items.len);206 const nlist_idx: u32 = @intCast(self.symtab.items.len);
207 const nlist = self.symtab.addOneAssumeCapacity();207 const nlist = self.symtab.addOneAssumeCapacity();
208 nlist.* = .{208 nlist.* = .{
209 .n_strx = name_off.pos,209 .n_strx = name_off,
210 .n_type = macho.N_SECT,210 .n_type = macho.N_SECT,
211 .n_sect = 0,211 .n_sect = 0,
212 .n_desc = 0,212 .n_desc = 0,
...@@ -273,7 +273,7 @@ fn addObjcMethnameSection(self: *InternalObject, methname: []const u8, macho_fil...@@ -273,7 +273,7 @@ fn addObjcMethnameSection(self: *InternalObject, methname: []const u8, macho_fil
273 const nlist_idx: u32 = @intCast(self.symtab.items.len);273 const nlist_idx: u32 = @intCast(self.symtab.items.len);
274 const nlist = try self.symtab.addOne(gpa);274 const nlist = try self.symtab.addOne(gpa);
275 nlist.* = .{275 nlist.* = .{
276 .n_strx = name_str.pos,276 .n_strx = name_str,
277 .n_type = macho.N_SECT,277 .n_type = macho.N_SECT,
278 .n_sect = @intCast(n_sect + 1),278 .n_sect = @intCast(n_sect + 1),
279 .n_desc = 0,279 .n_desc = 0,
...@@ -286,12 +286,12 @@ fn addObjcMethnameSection(self: *InternalObject, methname: []const u8, macho_fil...@@ -286,12 +286,12 @@ fn addObjcMethnameSection(self: *InternalObject, methname: []const u8, macho_fil
286}286}
287287
288fn addObjcSelrefsSection(self: *InternalObject, methname_sym_index: Symbol.Index, macho_file: *MachO) !Symbol.Index {288fn addObjcSelrefsSection(self: *InternalObject, methname_sym_index: Symbol.Index, macho_file: *MachO) !Symbol.Index {
289 const gpa = macho_file.base.allocator;289 const gpa = macho_file.base.comp.gpa;
290 const atom_index = try self.addAtom(gpa);290 const atom_index = try self.addAtom(gpa);
291 try self.atoms_indexes.append(gpa, atom_index);291 try self.atoms_indexes.append(gpa, atom_index);
292 const atom = self.getAtom(atom_index).?;292 const atom = self.getAtom(atom_index).?;
293 atom.size = @sizeOf(u64);293 atom.size = @sizeOf(u64);
294 atom.alignment = 3;294 atom.alignment = .@"8";
295295
296 const n_sect = try self.addSection(gpa, "__DATA", "__objc_selrefs");296 const n_sect = try self.addSection(gpa, "__DATA", "__objc_selrefs");
297 const sect = &self.sections.items(.header)[n_sect];297 const sect = &self.sections.items(.header)[n_sect];
...@@ -389,7 +389,7 @@ pub fn resolveObjcMsgSendSymbols(self: *InternalObject, macho_file: *MachO) !voi...@@ -389,7 +389,7 @@ pub fn resolveObjcMsgSendSymbols(self: *InternalObject, macho_file: *MachO) !voi
389 };389 };
390 sym.nlist_idx = nlist_idx;390 sym.nlist_idx = nlist_idx;
391 sym.extra = try self.addSymbolExtra(gpa, .{ .objc_selrefs = selrefs_index });391 sym.extra = try self.addSymbolExtra(gpa, .{ .objc_selrefs = selrefs_index });
392 sym.setSectionFlags(.{ .objc_stubs = true });392 sym.flags.objc_stubs = true;
393393
394 const idx = ref.getFile(macho_file).?.object.globals.items[ref.index];394 const idx = ref.getFile(macho_file).?.object.globals.items[ref.index];
395 try self.globals.append(gpa, idx);395 try self.globals.append(gpa, idx);
...@@ -417,7 +417,7 @@ pub fn resolveLiterals(self: *InternalObject, lp: *MachO.LiteralPool, macho_file...@@ -417,7 +417,7 @@ pub fn resolveLiterals(self: *InternalObject, lp: *MachO.LiteralPool, macho_file
417 const target = rel.getTargetSymbol(atom.*, macho_file).getAtom(macho_file).?;417 const target = rel.getTargetSymbol(atom.*, macho_file).getAtom(macho_file).?;
418 try buffer.ensureUnusedCapacity(target.size);418 try buffer.ensureUnusedCapacity(target.size);
419 buffer.resize(target.size) catch unreachable;419 buffer.resize(target.size) catch unreachable;
420 @memcpy(buffer.items, self.getSectionData(target.n_sect));420 @memcpy(buffer.items, try self.getSectionData(target.n_sect));
421 const res = try lp.insert(gpa, header.type(), buffer.items);421 const res = try lp.insert(gpa, header.type(), buffer.items);
422 buffer.clearRetainingCapacity();422 buffer.clearRetainingCapacity();
423 if (!res.found_existing) {423 if (!res.found_existing) {
...@@ -425,7 +425,7 @@ pub fn resolveLiterals(self: *InternalObject, lp: *MachO.LiteralPool, macho_file...@@ -425,7 +425,7 @@ pub fn resolveLiterals(self: *InternalObject, lp: *MachO.LiteralPool, macho_file
425 } else {425 } else {
426 const lp_sym = lp.getSymbol(res.index, macho_file);426 const lp_sym = lp.getSymbol(res.index, macho_file);
427 const lp_atom = lp_sym.getAtom(macho_file).?;427 const lp_atom = lp_sym.getAtom(macho_file).?;
428 lp_atom.alignment = @max(lp_atom.alignment, atom.alignment);428 lp_atom.alignment = lp_atom.alignment.max(atom.alignment);
429 atom.flags.alive = false;429 atom.flags.alive = false;
430 }430 }
431 atom.addExtra(.{ .literal_pool_index = res.index }, macho_file);431 atom.addExtra(.{ .literal_pool_index = res.index }, macho_file);
...@@ -438,7 +438,7 @@ pub fn dedupLiterals(self: *InternalObject, lp: MachO.LiteralPool, macho_file: *...@@ -438,7 +438,7 @@ pub fn dedupLiterals(self: *InternalObject, lp: MachO.LiteralPool, macho_file: *
438438
439 for (self.getAtoms()) |atom_index| {439 for (self.getAtoms()) |atom_index| {
440 const atom = self.getAtom(atom_index) orelse continue;440 const atom = self.getAtom(atom_index) orelse continue;
441 if (!atom.alive.load(.seq_cst)) continue;441 if (!atom.flags.alive) continue;
442442
443 const relocs = blk: {443 const relocs = blk: {
444 const extra = atom.getExtra(macho_file);444 const extra = atom.getExtra(macho_file);
...@@ -463,7 +463,7 @@ pub fn dedupLiterals(self: *InternalObject, lp: MachO.LiteralPool, macho_file: *...@@ -463,7 +463,7 @@ pub fn dedupLiterals(self: *InternalObject, lp: MachO.LiteralPool, macho_file: *
463 }463 }
464464
465 for (self.symbols.items) |*sym| {465 for (self.symbols.items) |*sym| {
466 if (!sym.getSectionFlags().objc_stubs) continue;466 if (!sym.flags.objc_stubs) continue;
467 const extra = sym.getExtra(macho_file);467 const extra = sym.getExtra(macho_file);
468 const file = sym.getFile(macho_file).?;468 const file = sym.getFile(macho_file).?;
469 if (file.getIndex() != self.index) continue;469 if (file.getIndex() != self.index) continue;
...@@ -495,14 +495,14 @@ pub fn scanRelocs(self: *InternalObject, macho_file: *MachO) void {...@@ -495,14 +495,14 @@ pub fn scanRelocs(self: *InternalObject, macho_file: *MachO) void {
495 if (self.getDyldStubBinderRef(macho_file)) |ref| {495 if (self.getDyldStubBinderRef(macho_file)) |ref| {
496 if (ref.getFile(macho_file) != null) {496 if (ref.getFile(macho_file) != null) {
497 const sym = ref.getSymbol(macho_file).?;497 const sym = ref.getSymbol(macho_file).?;
498 sym.flags.got = true;498 sym.flags.needs_got = true;
499 }499 }
500 }500 }
501 if (self.getObjcMsgSendRef(macho_file)) |ref| {501 if (self.getObjcMsgSendRef(macho_file)) |ref| {
502 if (ref.getFile(macho_file) != null) {502 if (ref.getFile(macho_file) != null) {
503 const sym = ref.getSymbol(macho_file).?;503 const sym = ref.getSymbol(macho_file).?;
504 // TODO is it always needed, or only if we are synthesising fast stubs504 // TODO is it always needed, or only if we are synthesising fast stubs
505 sym.flags.got = true;505 sym.flags.needs_got = true;
506 }506 }
507 }507 }
508}508}
...@@ -569,30 +569,30 @@ pub fn writeAtoms(self: *InternalObject, macho_file: *MachO) !void {...@@ -569,30 +569,30 @@ pub fn writeAtoms(self: *InternalObject, macho_file: *MachO) !void {
569569
570 for (self.getAtoms()) |atom_index| {570 for (self.getAtoms()) |atom_index| {
571 const atom = self.getAtom(atom_index) orelse continue;571 const atom = self.getAtom(atom_index) orelse continue;
572 if (!atom.alive.load(.seq_cst)) continue;572 if (!atom.flags.alive) continue;
573 const sect = atom.getInputSection(macho_file);573 const sect = atom.getInputSection(macho_file);
574 if (sect.isZerofill()) continue;574 if (sect.isZerofill()) continue;
575 const off = atom.value;575 const off = atom.value;
576 const buffer = macho_file.sections.items(.out)[atom.out_n_sect].items[off..][0..atom.size];576 const buffer = macho_file.sections.items(.out)[atom.out_n_sect].items[off..][0..atom.size];
577 @memcpy(buffer, self.getSectionData(atom.n_sect));577 @memcpy(buffer, try self.getSectionData(atom.n_sect));
578 try atom.resolveRelocs(macho_file, buffer);578 try atom.resolveRelocs(macho_file, buffer);
579 }579 }
580}580}
581581
582pub fn writeSymtab(self: InternalObject, macho_file: *MachO) void {582pub fn writeSymtab(self: InternalObject, macho_file: *MachO, ctx: anytype) void {
583 var n_strx = self.output_symtab_ctx.stroff;583 var n_strx = self.output_symtab_ctx.stroff;
584 for (self.symbols.items, 0..) |sym, i| {584 for (self.symbols.items, 0..) |sym, i| {
585 const ref = self.getSymbolRef(@intCast(i), macho_file);585 const ref = self.getSymbolRef(@intCast(i), macho_file);
586 const file = ref.getFile(macho_file) orelse continue;586 const file = ref.getFile(macho_file) orelse continue;
587 if (file.getIndex() != self.index) continue;587 if (file.getIndex() != self.index) continue;
588 const idx = sym.getOutputSymtabIndex(macho_file) orelse continue;588 const idx = sym.getOutputSymtabIndex(macho_file) orelse continue;
589 const out_sym = &macho_file.symtab.items[idx];589 const out_sym = &ctx.symtab.items[idx];
590 out_sym.n_strx = n_strx;590 out_sym.n_strx = n_strx;
591 sym.setOutputSym(macho_file, out_sym);591 sym.setOutputSym(macho_file, out_sym);
592 const name = sym.getName(macho_file);592 const name = sym.getName(macho_file);
593 @memcpy(macho_file.strtab.items[n_strx..][0..name.len], name);593 @memcpy(ctx.strtab.items[n_strx..][0..name.len], name);
594 n_strx += @intCast(name.len);594 n_strx += @intCast(name.len);
595 macho_file.strtab.items[n_strx] = 0;595 ctx.strtab.items[n_strx] = 0;
596 n_strx += 1;596 n_strx += 1;
597 }597 }
598}598}
...@@ -640,7 +640,7 @@ pub fn asFile(self: *InternalObject) File {...@@ -640,7 +640,7 @@ pub fn asFile(self: *InternalObject) File {
640}640}
641641
642pub fn getAtomRelocs(self: *const InternalObject, atom: Atom, macho_file: *MachO) []const Relocation {642pub fn getAtomRelocs(self: *const InternalObject, atom: Atom, macho_file: *MachO) []const Relocation {
643 const extra = atom.getExtra(macho_file).?;643 const extra = atom.getExtra(macho_file);
644 const relocs = self.sections.items(.relocs)[atom.n_sect];644 const relocs = self.sections.items(.relocs)[atom.n_sect];
645 return relocs.items[extra.rel_index..][0..extra.rel_count];645 return relocs.items[extra.rel_index..][0..extra.rel_count];
646}646}
src/link/MachO/Object.zig+138-116
...@@ -11,10 +11,10 @@ sections: std.MultiArrayList(Section) = .{},...@@ -11,10 +11,10 @@ sections: std.MultiArrayList(Section) = .{},
11symtab: std.MultiArrayList(Nlist) = .{},11symtab: std.MultiArrayList(Nlist) = .{},
12strtab: std.ArrayListUnmanaged(u8) = .{},12strtab: std.ArrayListUnmanaged(u8) = .{},
1313
14symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},14symbols: std.ArrayListUnmanaged(Symbol) = .{},
15symbols_extra: std.ArrayListUnmanaged(u32) = .{},15symbols_extra: std.ArrayListUnmanaged(u32) = .{},
16globals: std.ArrayListUnmanaged(MachO.SymbolResolver.Index) = .{},16globals: std.ArrayListUnmanaged(MachO.SymbolResolver.Index) = .{},
17atoms: std.ArrayListUnmanaged(Atom.Index) = .{},17atoms: std.ArrayListUnmanaged(Atom) = .{},
18atoms_indexes: std.ArrayListUnmanaged(Atom.Index) = .{},18atoms_indexes: std.ArrayListUnmanaged(Atom.Index) = .{},
19atoms_extra: std.ArrayListUnmanaged(u32) = .{},19atoms_extra: std.ArrayListUnmanaged(u32) = .{},
2020
...@@ -228,7 +228,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {...@@ -228,7 +228,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {
228228
229 // Parse DWARF __TEXT,__eh_frame section229 // Parse DWARF __TEXT,__eh_frame section
230 if (self.eh_frame_sect_index) |index| {230 if (self.eh_frame_sect_index) |index| {
231 try self.initEhFrameRecords(index, macho_file);231 try self.initEhFrameRecords(gpa, index, handle, macho_file);
232 }232 }
233233
234 // Parse Apple's __LD,__compact_unwind section234 // Parse Apple's __LD,__compact_unwind section
...@@ -261,7 +261,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {...@@ -261,7 +261,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {
261261
262 try self.parseDebugInfo(macho_file);262 try self.parseDebugInfo(macho_file);
263263
264 for (self.atoms.items) |atom_index| {264 for (self.getAtoms()) |atom_index| {
265 const atom = self.getAtom(atom_index) orelse continue;265 const atom = self.getAtom(atom_index) orelse continue;
266 const isec = atom.getInputSection(macho_file);266 const isec = atom.getInputSection(macho_file);
267 if (mem.eql(u8, isec.sectName(), "__eh_frame") or267 if (mem.eql(u8, isec.sectName(), "__eh_frame") or
...@@ -606,7 +606,7 @@ fn initPointerLiterals(self: *Object, allocator: Allocator, macho_file: *MachO)...@@ -606,7 +606,7 @@ fn initPointerLiterals(self: *Object, allocator: Allocator, macho_file: *MachO)
606 }606 }
607}607}
608608
609pub fn resolveLiterals(self: Object, lp: *MachO.LiteralPool, macho_file: *MachO) !void {609pub fn resolveLiterals(self: *Object, lp: *MachO.LiteralPool, macho_file: *MachO) !void {
610 const tracy = trace(@src());610 const tracy = trace(@src());
611 defer tracy.end();611 defer tracy.end();
612612
...@@ -646,7 +646,7 @@ pub fn resolveLiterals(self: Object, lp: *MachO.LiteralPool, macho_file: *MachO)...@@ -646,7 +646,7 @@ pub fn resolveLiterals(self: Object, lp: *MachO.LiteralPool, macho_file: *MachO)
646 } else {646 } else {
647 const lp_sym = lp.getSymbol(res.index, macho_file);647 const lp_sym = lp.getSymbol(res.index, macho_file);
648 const lp_atom = lp_sym.getAtom(macho_file).?;648 const lp_atom = lp_sym.getAtom(macho_file).?;
649 lp_atom.alignment = @max(lp_atom.alignment, atom.alignment);649 lp_atom.alignment = lp_atom.alignment.max(atom.alignment);
650 atom.flags.alive = false;650 atom.flags.alive = false;
651 }651 }
652 atom.addExtra(.{ .literal_pool_index = res.index }, macho_file);652 atom.addExtra(.{ .literal_pool_index = res.index }, macho_file);
...@@ -684,7 +684,7 @@ pub fn resolveLiterals(self: Object, lp: *MachO.LiteralPool, macho_file: *MachO)...@@ -684,7 +684,7 @@ pub fn resolveLiterals(self: Object, lp: *MachO.LiteralPool, macho_file: *MachO)
684 } else {684 } else {
685 const lp_sym = lp.getSymbol(res.index, macho_file);685 const lp_sym = lp.getSymbol(res.index, macho_file);
686 const lp_atom = lp_sym.getAtom(macho_file).?;686 const lp_atom = lp_sym.getAtom(macho_file).?;
687 lp_atom.alignment = @max(lp_atom.alignment, atom.alignment);687 lp_atom.alignment = lp_atom.alignment.max(atom.alignment);
688 atom.flags.alive = false;688 atom.flags.alive = false;
689 }689 }
690 atom.addExtra(.{ .literal_pool_index = res.index }, macho_file);690 atom.addExtra(.{ .literal_pool_index = res.index }, macho_file);
...@@ -823,7 +823,7 @@ fn initSymbols(self: *Object, allocator: Allocator, macho_file: *MachO) !void {...@@ -823,7 +823,7 @@ fn initSymbols(self: *Object, allocator: Allocator, macho_file: *MachO) !void {
823 const index = self.addSymbolAssumeCapacity();823 const index = self.addSymbolAssumeCapacity();
824 const symbol = &self.symbols.items[index];824 const symbol = &self.symbols.items[index];
825 symbol.value = nlist.n_value;825 symbol.value = nlist.n_value;
826 symbol.name = .{ .pos = nlist.n_strx, .len = @intCast(self.getNStrx(nlist.n_strx).len + 1) };826 symbol.name = nlist.n_strx;
827 symbol.nlist_idx = @intCast(i);827 symbol.nlist_idx = @intCast(i);
828 symbol.extra = self.addSymbolExtraAssumeCapacity(.{});828 symbol.extra = self.addSymbolExtraAssumeCapacity(.{});
829829
...@@ -838,7 +838,9 @@ fn initSymbols(self: *Object, allocator: Allocator, macho_file: *MachO) !void {...@@ -838,7 +838,9 @@ fn initSymbols(self: *Object, allocator: Allocator, macho_file: *MachO) !void {
838 symbol.flags.tentative = nlist.tentative();838 symbol.flags.tentative = nlist.tentative();
839 symbol.flags.no_dead_strip = symbol.flags.no_dead_strip or nlist.noDeadStrip();839 symbol.flags.no_dead_strip = symbol.flags.no_dead_strip or nlist.noDeadStrip();
840 symbol.flags.dyn_ref = nlist.n_desc & macho.REFERENCED_DYNAMICALLY != 0;840 symbol.flags.dyn_ref = nlist.n_desc & macho.REFERENCED_DYNAMICALLY != 0;
841 symbol.flags.interposable = nlist.ext() and (nlist.sect() or nlist.abs()) and macho_file.options.dylib and macho_file.options.namespace == .flat and !nlist.pext();841 symbol.flags.interposable = nlist.ext() and (nlist.sect() or nlist.abs()) and macho_file.base.isDynLib() and !nlist.pext();
842 // TODO
843 // symbol.flags.interposable = nlist.ext() and (nlist.sect() or nlist.abs()) and macho_file.base.isDynLib() and macho_file.options.namespace == .flat and !nlist.pext();
842844
843 if (nlist.sect() and845 if (nlist.sect() and
844 self.sections.items(.header)[nlist.n_sect - 1].type() == macho.S_THREAD_LOCAL_VARIABLES)846 self.sections.items(.header)[nlist.n_sect - 1].type() == macho.S_THREAD_LOCAL_VARIABLES)
...@@ -869,7 +871,7 @@ fn initSymbolStabs(self: *Object, allocator: Allocator, nlists: anytype, macho_f...@@ -869,7 +871,7 @@ fn initSymbolStabs(self: *Object, allocator: Allocator, nlists: anytype, macho_f
869 fn find(fs: @This(), addr: u64) ?Symbol.Index {871 fn find(fs: @This(), addr: u64) ?Symbol.Index {
870 // TODO binary search since we have the list sorted872 // TODO binary search since we have the list sorted
871 for (fs.entries) |nlist| {873 for (fs.entries) |nlist| {
872 if (nlist.nlist.n_value == addr) return fs.ctx.symbols.items[nlist.idx];874 if (nlist.nlist.n_value == addr) return @intCast(nlist.idx);
873 }875 }
874 return null;876 return null;
875 }877 }
...@@ -920,17 +922,17 @@ fn initSymbolStabs(self: *Object, allocator: Allocator, nlists: anytype, macho_f...@@ -920,17 +922,17 @@ fn initSymbolStabs(self: *Object, allocator: Allocator, nlists: anytype, macho_f
920 switch (nlist.n_type) {922 switch (nlist.n_type) {
921 macho.N_BNSYM => {923 macho.N_BNSYM => {
922 stab.is_func = true;924 stab.is_func = true;
923 stab.symbol = sym_lookup.find(nlist.n_value);925 stab.index = sym_lookup.find(nlist.n_value);
924 // TODO validate926 // TODO validate
925 i += 3;927 i += 3;
926 },928 },
927 macho.N_GSYM => {929 macho.N_GSYM => {
928 stab.is_func = false;930 stab.is_func = false;
929 stab.symbol = sym_lookup.find(addr_lookup.get(self.getString(nlist.n_strx)).?);931 stab.index = sym_lookup.find(addr_lookup.get(self.getString(nlist.n_strx)).?);
930 },932 },
931 macho.N_STSYM => {933 macho.N_STSYM => {
932 stab.is_func = false;934 stab.is_func = false;
933 stab.symbol = sym_lookup.find(nlist.n_value);935 stab.index = sym_lookup.find(nlist.n_value);
934 },936 },
935 else => {937 else => {
936 try macho_file.reportParseError2(self.index, "unhandled symbol stab type 0x{x}", .{938 try macho_file.reportParseError2(self.index, "unhandled symbol stab type 0x{x}", .{
...@@ -1103,9 +1105,9 @@ fn initUnwindRecords(self: *Object, allocator: Allocator, sect_id: u8, file: Fil...@@ -1103,9 +1105,9 @@ fn initUnwindRecords(self: *Object, allocator: Allocator, sect_id: u8, file: Fil
1103 ctx: *const Object,1105 ctx: *const Object,
11041106
1105 fn find(fs: @This(), addr: u64) ?Symbol.Index {1107 fn find(fs: @This(), addr: u64) ?Symbol.Index {
1106 for (fs.ctx.symbols.items, 0..) |sym_index, i| {1108 for (0..fs.ctx.symbols.items.len) |i| {
1107 const nlist = fs.ctx.symtab.items(.nlist)[i];1109 const nlist = fs.ctx.symtab.items(.nlist)[i];
1108 if (nlist.ext() and nlist.n_value == addr) return sym_index;1110 if (nlist.ext() and nlist.n_value == addr) return @intCast(i);
1109 }1111 }
1110 return null;1112 return null;
1111 }1113 }
...@@ -1274,7 +1276,7 @@ fn parseUnwindRecords(self: *Object, allocator: Allocator, cpu_arch: std.Target....@@ -1274,7 +1276,7 @@ fn parseUnwindRecords(self: *Object, allocator: Allocator, cpu_arch: std.Target.
1274 // Create a null record1276 // Create a null record
1275 const rec_index = try self.addUnwindRecord(allocator);1277 const rec_index = try self.addUnwindRecord(allocator);
1276 const rec = self.getUnwindRecord(rec_index);1278 const rec = self.getUnwindRecord(rec_index);
1277 const atom = macho_file.getAtom(meta.atom).?;1279 const atom = self.getAtom(meta.atom).?;
1278 try self.unwind_records_indexes.append(allocator, rec_index);1280 try self.unwind_records_indexes.append(allocator, rec_index);
1279 rec.length = @intCast(meta.size);1281 rec.length = @intCast(meta.size);
1280 rec.atom = meta.atom;1282 rec.atom = meta.atom;
...@@ -1468,17 +1470,17 @@ fn findCompileUnit(self: *Object, args: struct {...@@ -1468,17 +1470,17 @@ fn findCompileUnit(self: *Object, args: struct {
1468 };1470 };
1469}1471}
14701472
1471pub fn resolveSymbols(self: *Object, macho_file: *MachO) void {1473pub fn resolveSymbols(self: *Object, macho_file: *MachO) !void {
1472 const tracy = trace(@src());1474 const tracy = trace(@src());
1473 defer tracy.end();1475 defer tracy.end();
14741476
1475 const gpa = macho_file.base.allocator;1477 const gpa = macho_file.base.comp.gpa;
14761478
1477 for (self.symtab.items(.nlist), self.symtab.items(.atom), self.globals.items, 0..) |nlist, atom_index, *global, i| {1479 for (self.symtab.items(.nlist), self.symtab.items(.atom), self.globals.items, 0..) |nlist, atom_index, *global, i| {
1478 if (!nlist.ext()) continue;1480 if (!nlist.ext()) continue;
1479 if (nlist.sect()) {1481 if (nlist.sect()) {
1480 const atom = self.getAtom(atom_index).?;1482 const atom = self.getAtom(atom_index).?;
1481 if (!atom.alive.load(.seq_cst)) continue;1483 if (!atom.flags.alive) continue;
1482 }1484 }
14831485
1484 const gop = try macho_file.resolver.getOrPut(gpa, .{1486 const gop = try macho_file.resolver.getOrPut(gpa, .{
...@@ -1643,7 +1645,7 @@ pub fn claimUnresolved(self: *Object, macho_file: *MachO) void {...@@ -1643,7 +1645,7 @@ pub fn claimUnresolved(self: *Object, macho_file: *MachO) void {
16431645
1644 if (self.getSymbolRef(@intCast(i), macho_file).getFile(macho_file) != null) continue;1646 if (self.getSymbolRef(@intCast(i), macho_file).getFile(macho_file) != null) continue;
16451647
1646 const is_import = switch (macho_file.options.undefined_treatment) {1648 const is_import = switch (macho_file.undefined_treatment) {
1647 .@"error" => false,1649 .@"error" => false,
1648 .warn, .suppress => nlist.weakRef(),1650 .warn, .suppress => nlist.weakRef(),
1649 .dynamic_lookup => true,1651 .dynamic_lookup => true,
...@@ -1682,8 +1684,8 @@ pub fn claimUnresolvedRelocatable(self: *Object, macho_file: *MachO) void {...@@ -1682,8 +1684,8 @@ pub fn claimUnresolvedRelocatable(self: *Object, macho_file: *MachO) void {
1682 }1684 }
1683}1685}
16841686
1685fn addSection(self: *Object, allocator: Allocator, segname: []const u8, sectname: []const u8) !u32 {1687fn addSection(self: *Object, allocator: Allocator, segname: []const u8, sectname: []const u8) !u8 {
1686 const n_sect = @as(u32, @intCast(try self.sections.addOne(allocator)));1688 const n_sect = @as(u8, @intCast(try self.sections.addOne(allocator)));
1687 self.sections.set(n_sect, .{1689 self.sections.set(n_sect, .{
1688 .header = .{1690 .header = .{
1689 .sectname = MachO.makeStaticString(sectname),1691 .sectname = MachO.makeStaticString(sectname),
...@@ -1799,7 +1801,7 @@ pub fn writeAr(self: Object, ar_format: Archive.Format, macho_file: *MachO, writ...@@ -1799,7 +1801,7 @@ pub fn writeAr(self: Object, ar_format: Archive.Format, macho_file: *MachO, writ
1799 try writer.writeAll(data);1801 try writer.writeAll(data);
1800}1802}
18011803
1802pub fn calcSymtabSize(self: *Object, macho_file: *MachO) !void {1804pub fn calcSymtabSize(self: *Object, macho_file: *MachO) void {
1803 const tracy = trace(@src());1805 const tracy = trace(@src());
1804 defer tracy.end();1806 defer tracy.end();
18051807
...@@ -1821,27 +1823,27 @@ pub fn calcSymtabSize(self: *Object, macho_file: *MachO) !void {...@@ -1821,27 +1823,27 @@ pub fn calcSymtabSize(self: *Object, macho_file: *MachO) !void {
1821 continue;1823 continue;
1822 sym.flags.output_symtab = true;1824 sym.flags.output_symtab = true;
1823 if (sym.isLocal()) {1825 if (sym.isLocal()) {
1824 try sym.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, macho_file);1826 sym.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, macho_file);
1825 self.output_symtab_ctx.nlocals += 1;1827 self.output_symtab_ctx.nlocals += 1;
1826 } else if (sym.flags.@"export") {1828 } else if (sym.flags.@"export") {
1827 try sym.addExtra(.{ .symtab = self.output_symtab_ctx.nexports }, macho_file);1829 sym.addExtra(.{ .symtab = self.output_symtab_ctx.nexports }, macho_file);
1828 self.output_symtab_ctx.nexports += 1;1830 self.output_symtab_ctx.nexports += 1;
1829 } else {1831 } else {
1830 assert(sym.flags.import);1832 assert(sym.flags.import);
1831 try sym.addExtra(.{ .symtab = self.output_symtab_ctx.nimports }, macho_file);1833 sym.addExtra(.{ .symtab = self.output_symtab_ctx.nimports }, macho_file);
1832 self.output_symtab_ctx.nimports += 1;1834 self.output_symtab_ctx.nimports += 1;
1833 }1835 }
1834 self.output_symtab_ctx.strsize += @as(u32, @intCast(sym.getName(macho_file).len + 1));1836 self.output_symtab_ctx.strsize += @as(u32, @intCast(sym.getName(macho_file).len + 1));
1835 }1837 }
18361838
1837 if (macho_file.base.comp.config.debug_format != .strip and self.hasDebugInfo())1839 if (macho_file.base.comp.config.debug_format != .strip and self.hasDebugInfo())
1838 try self.calcStabsSize(macho_file);1840 self.calcStabsSize(macho_file);
1839}1841}
18401842
1841pub fn calcStabsSize(self: *Object, macho_file: *MachO) error{Overflow}!void {1843pub fn calcStabsSize(self: *Object, macho_file: *MachO) void {
1842 if (self.compile_unit) |cu| {1844 if (self.compile_unit) |cu| {
1843 const comp_dir = cu.getCompDir(self);1845 const comp_dir = cu.getCompDir(self.*);
1844 const tu_name = cu.getTuName(self);1846 const tu_name = cu.getTuName(self.*);
18451847
1846 self.output_symtab_ctx.nstabs += 4; // N_SO, N_SO, N_OSO, N_SO1848 self.output_symtab_ctx.nstabs += 4; // N_SO, N_SO, N_OSO, N_SO
1847 self.output_symtab_ctx.strsize += @as(u32, @intCast(comp_dir.len + 1)); // comp_dir1849 self.output_symtab_ctx.strsize += @as(u32, @intCast(comp_dir.len + 1)); // comp_dir
...@@ -1876,12 +1878,12 @@ pub fn calcStabsSize(self: *Object, macho_file: *MachO) error{Overflow}!void {...@@ -1876,12 +1878,12 @@ pub fn calcStabsSize(self: *Object, macho_file: *MachO) error{Overflow}!void {
18761878
1877 for (self.stab_files.items) |sf| {1879 for (self.stab_files.items) |sf| {
1878 self.output_symtab_ctx.nstabs += 4; // N_SO, N_SO, N_OSO, N_SO1880 self.output_symtab_ctx.nstabs += 4; // N_SO, N_SO, N_OSO, N_SO
1879 self.output_symtab_ctx.strsize += @as(u32, @intCast(sf.getCompDir(self).len + 1)); // comp_dir1881 self.output_symtab_ctx.strsize += @as(u32, @intCast(sf.getCompDir(self.*).len + 1)); // comp_dir
1880 self.output_symtab_ctx.strsize += @as(u32, @intCast(sf.getTuName(self).len + 1)); // tu_name1882 self.output_symtab_ctx.strsize += @as(u32, @intCast(sf.getTuName(self.*).len + 1)); // tu_name
1881 self.output_symtab_ctx.strsize += @as(u32, @intCast(sf.getOsoPath(self).len + 1)); // path1883 self.output_symtab_ctx.strsize += @as(u32, @intCast(sf.getOsoPath(self.*).len + 1)); // path
18821884
1883 for (sf.stabs.items) |stab| {1885 for (sf.stabs.items) |stab| {
1884 const sym = stab.getSymbol(macho_file) orelse continue;1886 const sym = stab.getSymbol(self.*) orelse continue;
1885 const file = sym.getFile(macho_file).?;1887 const file = sym.getFile(macho_file).?;
1886 if (file.getIndex() != self.index) continue;1888 if (file.getIndex() != self.index) continue;
1887 if (!sym.flags.output_symtab) continue;1889 if (!sym.flags.output_symtab) continue;
...@@ -2065,7 +2067,7 @@ pub fn writeCompactUnwindRelocatable(self: *Object, macho_file: *MachO) !void {...@@ -2065,7 +2067,7 @@ pub fn writeCompactUnwindRelocatable(self: *Object, macho_file: *MachO) !void {
2065 }2067 }
2066}2068}
20672069
2068pub fn writeSymtab(self: Object, macho_file: *MachO) void {2070pub fn writeSymtab(self: Object, macho_file: *MachO, ctx: anytype) void {
2069 const tracy = trace(@src());2071 const tracy = trace(@src());
2070 defer tracy.end();2072 defer tracy.end();
20712073
...@@ -2075,21 +2077,21 @@ pub fn writeSymtab(self: Object, macho_file: *MachO) void {...@@ -2075,21 +2077,21 @@ pub fn writeSymtab(self: Object, macho_file: *MachO) void {
2075 const file = ref.getFile(macho_file) orelse continue;2077 const file = ref.getFile(macho_file) orelse continue;
2076 if (file.getIndex() != self.index) continue;2078 if (file.getIndex() != self.index) continue;
2077 const idx = sym.getOutputSymtabIndex(macho_file) orelse continue;2079 const idx = sym.getOutputSymtabIndex(macho_file) orelse continue;
2078 const out_sym = &macho_file.symtab.items[idx];2080 const out_sym = &ctx.symtab.items[idx];
2079 out_sym.n_strx = n_strx;2081 out_sym.n_strx = n_strx;
2080 sym.setOutputSym(macho_file, out_sym);2082 sym.setOutputSym(macho_file, out_sym);
2081 const name = sym.getName(macho_file);2083 const name = sym.getName(macho_file);
2082 @memcpy(macho_file.strtab.items[n_strx..][0..name.len], name);2084 @memcpy(ctx.strtab.items[n_strx..][0..name.len], name);
2083 n_strx += @intCast(name.len);2085 n_strx += @intCast(name.len);
2084 macho_file.strtab.items[n_strx] = 0;2086 ctx.strtab.items[n_strx] = 0;
2085 n_strx += 1;2087 n_strx += 1;
2086 }2088 }
20872089
2088 if (macho_file.base.comp.config.debug_format != .strip and self.hasDebugInfo())2090 if (macho_file.base.comp.config.debug_format != .strip and self.hasDebugInfo())
2089 try self.writeStabs(n_strx, macho_file);2091 self.writeStabs(n_strx, macho_file, ctx);
2090}2092}
20912093
2092pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {2094pub fn writeStabs(self: Object, stroff: u32, macho_file: *MachO, ctx: anytype) void {
2093 const writeFuncStab = struct {2095 const writeFuncStab = struct {
2094 inline fn writeFuncStab(2096 inline fn writeFuncStab(
2095 n_strx: u32,2097 n_strx: u32,
...@@ -2097,7 +2099,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {...@@ -2097,7 +2099,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
2097 n_value: u64,2099 n_value: u64,
2098 size: u64,2100 size: u64,
2099 index: u32,2101 index: u32,
2100 context: *MachO,2102 context: anytype,
2101 ) void {2103 ) void {
2102 context.symtab.items[index] = .{2104 context.symtab.items[index] = .{
2103 .n_strx = 0,2105 .n_strx = 0,
...@@ -2139,7 +2141,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {...@@ -2139,7 +2141,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
21392141
2140 // Open scope2142 // Open scope
2141 // N_SO comp_dir2143 // N_SO comp_dir
2142 macho_file.symtab.items[index] = .{2144 ctx.symtab.items[index] = .{
2143 .n_strx = n_strx,2145 .n_strx = n_strx,
2144 .n_type = macho.N_SO,2146 .n_type = macho.N_SO,
2145 .n_sect = 0,2147 .n_sect = 0,
...@@ -2147,9 +2149,9 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {...@@ -2147,9 +2149,9 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
2147 .n_value = 0,2149 .n_value = 0,
2148 };2150 };
2149 index += 1;2151 index += 1;
2150 @memcpy(macho_file.strtab.items[n_strx..][0..comp_dir.len], comp_dir);2152 @memcpy(ctx.strtab.items[n_strx..][0..comp_dir.len], comp_dir);
2151 n_strx += @intCast(comp_dir.len);2153 n_strx += @intCast(comp_dir.len);
2152 macho_file.strtab.items[n_strx] = 0;2154 ctx.strtab.items[n_strx] = 0;
2153 n_strx += 1;2155 n_strx += 1;
2154 // N_SO tu_name2156 // N_SO tu_name
2155 macho_file.symtab.items[index] = .{2157 macho_file.symtab.items[index] = .{
...@@ -2160,12 +2162,12 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {...@@ -2160,12 +2162,12 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
2160 .n_value = 0,2162 .n_value = 0,
2161 };2163 };
2162 index += 1;2164 index += 1;
2163 @memcpy(macho_file.strtab.items[n_strx..][0..tu_name.len], tu_name);2165 @memcpy(ctx.strtab.items[n_strx..][0..tu_name.len], tu_name);
2164 n_strx += @intCast(tu_name.len);2166 n_strx += @intCast(tu_name.len);
2165 macho_file.strtab.items[n_strx] = 0;2167 ctx.strtab.items[n_strx] = 0;
2166 n_strx += 1;2168 n_strx += 1;
2167 // N_OSO path2169 // N_OSO path
2168 macho_file.symtab.items[index] = .{2170 ctx.symtab.items[index] = .{
2169 .n_strx = n_strx,2171 .n_strx = n_strx,
2170 .n_type = macho.N_OSO,2172 .n_type = macho.N_OSO,
2171 .n_sect = 0,2173 .n_sect = 0,
...@@ -2174,20 +2176,20 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {...@@ -2174,20 +2176,20 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
2174 };2176 };
2175 index += 1;2177 index += 1;
2176 if (self.in_archive) |ar| {2178 if (self.in_archive) |ar| {
2177 @memcpy(macho_file.strtab.items[n_strx..][0..ar.path.len], ar.path);2179 @memcpy(ctx.strtab.items[n_strx..][0..ar.path.len], ar.path);
2178 n_strx += @intCast(ar.path.len);2180 n_strx += @intCast(ar.path.len);
2179 macho_file.strtab.items[n_strx] = '(';2181 ctx.strtab.items[n_strx] = '(';
2180 n_strx += 1;2182 n_strx += 1;
2181 @memcpy(macho_file.strtab.items[n_strx..][0..self.path.len], self.path);2183 @memcpy(ctx.strtab.items[n_strx..][0..self.path.len], self.path);
2182 n_strx += @intCast(self.path.len);2184 n_strx += @intCast(self.path.len);
2183 macho_file.strtab.items[n_strx] = ')';2185 ctx.strtab.items[n_strx] = ')';
2184 n_strx += 1;2186 n_strx += 1;
2185 macho_file.strtab.items[n_strx] = 0;2187 ctx.strtab.items[n_strx] = 0;
2186 n_strx += 1;2188 n_strx += 1;
2187 } else {2189 } else {
2188 @memcpy(macho_file.strtab.items[n_strx..][0..self.path.len], self.path);2190 @memcpy(ctx.strtab.items[n_strx..][0..self.path.len], self.path);
2189 n_strx += @intCast(self.path.len);2191 n_strx += @intCast(self.path.len);
2190 macho_file.strtab.items[n_strx] = 0;2192 ctx.strtab.items[n_strx] = 0;
2191 n_strx += 1;2193 n_strx += 1;
2192 }2194 }
21932195
...@@ -2203,17 +2205,17 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {...@@ -2203,17 +2205,17 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
2203 const sect = macho_file.sections.items(.header)[sym.getOutputSectionIndex(macho_file)];2205 const sect = macho_file.sections.items(.header)[sym.getOutputSectionIndex(macho_file)];
2204 const sym_n_strx = n_strx: {2206 const sym_n_strx = n_strx: {
2205 const symtab_index = sym.getOutputSymtabIndex(macho_file).?;2207 const symtab_index = sym.getOutputSymtabIndex(macho_file).?;
2206 const osym = macho_file.symtab.items[symtab_index];2208 const osym = ctx.symtab.items[symtab_index];
2207 break :n_strx osym.n_strx;2209 break :n_strx osym.n_strx;
2208 };2210 };
2209 const sym_n_sect: u8 = if (!sym.flags.abs) @intCast(sym.getOutputSectionIndex(macho_file) + 1) else 0;2211 const sym_n_sect: u8 = if (!sym.flags.abs) @intCast(sym.getOutputSectionIndex(macho_file) + 1) else 0;
2210 const sym_n_value = sym.getAddress(.{}, macho_file);2212 const sym_n_value = sym.getAddress(.{}, macho_file);
2211 const sym_size = sym.getSize(macho_file);2213 const sym_size = sym.getSize(macho_file);
2212 if (sect.isCode()) {2214 if (sect.isCode()) {
2213 writeFuncStab(sym_n_strx, sym_n_sect, sym_n_value, sym_size, index, macho_file);2215 writeFuncStab(sym_n_strx, sym_n_sect, sym_n_value, sym_size, index, ctx);
2214 index += 4;2216 index += 4;
2215 } else if (sym.visibility == .global) {2217 } else if (sym.visibility == .global) {
2216 macho_file.symtab.items[index] = .{2218 ctx.symtab.items[index] = .{
2217 .n_strx = sym_n_strx,2219 .n_strx = sym_n_strx,
2218 .n_type = macho.N_GSYM,2220 .n_type = macho.N_GSYM,
2219 .n_sect = sym_n_sect,2221 .n_sect = sym_n_sect,
...@@ -2222,7 +2224,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {...@@ -2222,7 +2224,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
2222 };2224 };
2223 index += 1;2225 index += 1;
2224 } else {2226 } else {
2225 macho_file.symtab.items[index] = .{2227 ctx.symtab.items[index] = .{
2226 .n_strx = sym_n_strx,2228 .n_strx = sym_n_strx,
2227 .n_type = macho.N_STSYM,2229 .n_type = macho.N_STSYM,
2228 .n_sect = sym_n_sect,2230 .n_sect = sym_n_sect,
...@@ -2235,7 +2237,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {...@@ -2235,7 +2237,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
22352237
2236 // Close scope2238 // Close scope
2237 // N_SO2239 // N_SO
2238 macho_file.symtab.items[index] = .{2240 ctx.symtab.items[index] = .{
2239 .n_strx = 0,2241 .n_strx = 0,
2240 .n_type = macho.N_SO,2242 .n_type = macho.N_SO,
2241 .n_sect = 0,2243 .n_sect = 0,
...@@ -2246,13 +2248,13 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {...@@ -2246,13 +2248,13 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
2246 assert(self.hasSymbolStabs());2248 assert(self.hasSymbolStabs());
22472249
2248 for (self.stab_files.items) |sf| {2250 for (self.stab_files.items) |sf| {
2249 const comp_dir = sf.getCombDir(self);2251 const comp_dir = sf.getCompDir(self);
2250 const tu_name = sf.getTuName(self);2252 const tu_name = sf.getTuName(self);
2251 const oso_path = sf.getOsoPath(self);2253 const oso_path = sf.getOsoPath(self);
22522254
2253 // Open scope2255 // Open scope
2254 // N_SO comp_dir2256 // N_SO comp_dir
2255 macho_file.symtab.items[index] = .{2257 ctx.symtab.items[index] = .{
2256 .n_strx = n_strx,2258 .n_strx = n_strx,
2257 .n_type = macho.N_SO,2259 .n_type = macho.N_SO,
2258 .n_sect = 0,2260 .n_sect = 0,
...@@ -2260,12 +2262,12 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {...@@ -2260,12 +2262,12 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
2260 .n_value = 0,2262 .n_value = 0,
2261 };2263 };
2262 index += 1;2264 index += 1;
2263 @memcpy(macho_file.strtab.items[n_strx..][0..comp_dir.len], comp_dir);2265 @memcpy(ctx.strtab.items[n_strx..][0..comp_dir.len], comp_dir);
2264 n_strx += @intCast(comp_dir.len);2266 n_strx += @intCast(comp_dir.len);
2265 macho_file.strtab.items[n_strx] = 0;2267 ctx.strtab.items[n_strx] = 0;
2266 n_strx += 1;2268 n_strx += 1;
2267 // N_SO tu_name2269 // N_SO tu_name
2268 macho_file.symtab.items[index] = .{2270 ctx.symtab.items[index] = .{
2269 .n_strx = n_strx,2271 .n_strx = n_strx,
2270 .n_type = macho.N_SO,2272 .n_type = macho.N_SO,
2271 .n_sect = 0,2273 .n_sect = 0,
...@@ -2273,12 +2275,12 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {...@@ -2273,12 +2275,12 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
2273 .n_value = 0,2275 .n_value = 0,
2274 };2276 };
2275 index += 1;2277 index += 1;
2276 @memcpy(macho_file.strtab.items[n_strx..][0..tu_name.len], tu_name);2278 @memcpy(ctx.strtab.items[n_strx..][0..tu_name.len], tu_name);
2277 n_strx += @intCast(tu_name.len);2279 n_strx += @intCast(tu_name.len);
2278 macho_file.strtab.items[n_strx] = 0;2280 ctx.strtab.items[n_strx] = 0;
2279 n_strx += 1;2281 n_strx += 1;
2280 // N_OSO path2282 // N_OSO path
2281 macho_file.symtab.items[index] = .{2283 ctx.symtab.items[index] = .{
2282 .n_strx = n_strx,2284 .n_strx = n_strx,
2283 .n_type = macho.N_OSO,2285 .n_type = macho.N_OSO,
2284 .n_sect = 0,2286 .n_sect = 0,
...@@ -2286,29 +2288,29 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {...@@ -2286,29 +2288,29 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
2286 .n_value = sf.getOsoModTime(self),2288 .n_value = sf.getOsoModTime(self),
2287 };2289 };
2288 index += 1;2290 index += 1;
2289 @memcpy(macho_file.strtab.items[n_strx..][0..oso_path.len], oso_path);2291 @memcpy(ctx.strtab.items[n_strx..][0..oso_path.len], oso_path);
2290 n_strx += @intCast(oso_path.len);2292 n_strx += @intCast(oso_path.len);
2291 macho_file.strtab.items[n_strx] = 0;2293 ctx.strtab.items[n_strx] = 0;
2292 n_strx += 1;2294 n_strx += 1;
22932295
2294 for (sf.stabs.items) |stab| {2296 for (sf.stabs.items) |stab| {
2295 const sym = stab.getSymbol(macho_file) orelse continue;2297 const sym = stab.getSymbol(self) orelse continue;
2296 const file = sym.getFile(macho_file).?;2298 const file = sym.getFile(macho_file).?;
2297 if (file.getIndex() != self.index) continue;2299 if (file.getIndex() != self.index) continue;
2298 if (!sym.flags.output_symtab) continue;2300 if (!sym.flags.output_symtab) continue;
2299 const sym_n_strx = n_strx: {2301 const sym_n_strx = n_strx: {
2300 const symtab_index = sym.getOutputSymtabIndex(macho_file).?;2302 const symtab_index = sym.getOutputSymtabIndex(macho_file).?;
2301 const osym = macho_file.symtab.items[symtab_index];2303 const osym = ctx.symtab.items[symtab_index];
2302 break :n_strx osym.n_strx;2304 break :n_strx osym.n_strx;
2303 };2305 };
2304 const sym_n_sect: u8 = if (!sym.flags.abs) @intCast(sym.getOutputSectionIndex(macho_file) + 1) else 0;2306 const sym_n_sect: u8 = if (!sym.flags.abs) @intCast(sym.getOutputSectionIndex(macho_file) + 1) else 0;
2305 const sym_n_value = sym.getAddress(.{}, macho_file);2307 const sym_n_value = sym.getAddress(.{}, macho_file);
2306 const sym_size = sym.getSize(macho_file);2308 const sym_size = sym.getSize(macho_file);
2307 if (stab.is_func) {2309 if (stab.is_func) {
2308 writeFuncStab(sym_n_strx, sym_n_sect, sym_n_value, sym_size, index, macho_file);2310 writeFuncStab(sym_n_strx, sym_n_sect, sym_n_value, sym_size, index, ctx);
2309 index += 4;2311 index += 4;
2310 } else if (sym.visibility == .global) {2312 } else if (sym.visibility == .global) {
2311 macho_file.symtab.items[index] = .{2313 ctx.symtab.items[index] = .{
2312 .n_strx = sym_n_strx,2314 .n_strx = sym_n_strx,
2313 .n_type = macho.N_GSYM,2315 .n_type = macho.N_GSYM,
2314 .n_sect = sym_n_sect,2316 .n_sect = sym_n_sect,
...@@ -2317,7 +2319,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {...@@ -2317,7 +2319,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
2317 };2319 };
2318 index += 1;2320 index += 1;
2319 } else {2321 } else {
2320 macho_file.symtab.items[index] = .{2322 ctx.symtab.items[index] = .{
2321 .n_strx = sym_n_strx,2323 .n_strx = sym_n_strx,
2322 .n_type = macho.N_STSYM,2324 .n_type = macho.N_STSYM,
2323 .n_sect = sym_n_sect,2325 .n_sect = sym_n_sect,
...@@ -2330,7 +2332,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {...@@ -2330,7 +2332,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
23302332
2331 // Close scope2333 // Close scope
2332 // N_SO2334 // N_SO
2333 macho_file.symtab.items[index] = .{2335 ctx.symtab.items[index] = .{
2334 .n_strx = 0,2336 .n_strx = 0,
2335 .n_type = macho.N_SO,2337 .n_type = macho.N_SO,
2336 .n_sect = 0,2338 .n_sect = 0,
...@@ -2343,7 +2345,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {...@@ -2343,7 +2345,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
2343}2345}
23442346
2345pub fn getAtomRelocs(self: *const Object, atom: Atom, macho_file: *MachO) []const Relocation {2347pub fn getAtomRelocs(self: *const Object, atom: Atom, macho_file: *MachO) []const Relocation {
2346 const extra = atom.getExtra(macho_file).?;2348 const extra = atom.getExtra(macho_file);
2347 const relocs = self.sections.items(.relocs)[atom.n_sect];2349 const relocs = self.sections.items(.relocs)[atom.n_sect];
2348 return relocs.items[extra.rel_index..][0..extra.rel_count];2350 return relocs.items[extra.rel_index..][0..extra.rel_count];
2349}2351}
...@@ -2402,7 +2404,7 @@ pub fn asFile(self: *Object) File {...@@ -2402,7 +2404,7 @@ pub fn asFile(self: *Object) File {
2402}2404}
24032405
2404const AddAtomArgs = struct {2406const AddAtomArgs = struct {
2405 name: MachO.String,2407 name: u32,
2406 n_sect: u8,2408 n_sect: u8,
2407 off: u64,2409 off: u64,
2408 size: u64,2410 size: u64,
...@@ -2420,7 +2422,7 @@ fn addAtom(self: *Object, allocator: Allocator, args: AddAtomArgs) !Atom.Index {...@@ -2420,7 +2422,7 @@ fn addAtom(self: *Object, allocator: Allocator, args: AddAtomArgs) !Atom.Index {
2420 .size = args.size,2422 .size = args.size,
2421 .off = args.off,2423 .off = args.off,
2422 .extra = try self.addAtomExtra(allocator, .{}),2424 .extra = try self.addAtomExtra(allocator, .{}),
2423 .alignment = args.alignment,2425 .alignment = Atom.Alignment.fromLog2Units(args.alignment),
2424 };2426 };
2425 return atom_index;2427 return atom_index;
2426}2428}
...@@ -2693,12 +2695,12 @@ fn formatSymtab(...@@ -2693,12 +2695,12 @@ fn formatSymtab(
2693 }2695 }
2694 for (object.stab_files.items) |sf| {2696 for (object.stab_files.items) |sf| {
2695 try writer.print(" stabs({s},{s},{s})\n", .{2697 try writer.print(" stabs({s},{s},{s})\n", .{
2696 sf.getCompDir(object),2698 sf.getCompDir(object.*),
2697 sf.getTuName(object),2699 sf.getTuName(object.*),
2698 sf.getOsoPath(object),2700 sf.getOsoPath(object.*),
2699 });2701 });
2700 for (sf.stabs.items) |stab| {2702 for (sf.stabs.items) |stab| {
2701 try writer.print(" {}", .{stab.fmt(object)});2703 try writer.print(" {}", .{stab.fmt(object.*)});
2702 }2704 }
2703 }2705 }
2704}2706}
...@@ -2744,33 +2746,33 @@ const StabFile = struct {...@@ -2744,33 +2746,33 @@ const StabFile = struct {
2744 comp_dir: u32,2746 comp_dir: u32,
2745 stabs: std.ArrayListUnmanaged(Stab) = .{},2747 stabs: std.ArrayListUnmanaged(Stab) = .{},
27462748
2747 fn getCompDir(sf: StabFile, object: *const Object) [:0]const u8 {2749 fn getCompDir(sf: StabFile, object: Object) [:0]const u8 {
2748 const nlist = object.symtab.items(.nlist)[sf.comp_dir];2750 const nlist = object.symtab.items(.nlist)[sf.comp_dir];
2749 return object.getString(nlist.n_strx);2751 return object.getString(nlist.n_strx);
2750 }2752 }
27512753
2752 fn getTuName(sf: StabFile, object: *const Object) [:0]const u8 {2754 fn getTuName(sf: StabFile, object: Object) [:0]const u8 {
2753 const nlist = object.symtab.items(.nlist)[sf.comp_dir + 1];2755 const nlist = object.symtab.items(.nlist)[sf.comp_dir + 1];
2754 return object.getString(nlist.n_strx);2756 return object.getString(nlist.n_strx);
2755 }2757 }
27562758
2757 fn getOsoPath(sf: StabFile, object: *const Object) [:0]const u8 {2759 fn getOsoPath(sf: StabFile, object: Object) [:0]const u8 {
2758 const nlist = object.symtab.items(.nlist)[sf.comp_dir + 2];2760 const nlist = object.symtab.items(.nlist)[sf.comp_dir + 2];
2759 return object.getString(nlist.n_strx);2761 return object.getString(nlist.n_strx);
2760 }2762 }
27612763
2762 fn getOsoModTime(sf: StabFile, object: *const Object) u64 {2764 fn getOsoModTime(sf: StabFile, object: Object) u64 {
2763 const nlist = object.symtab.items(.nlist)[sf.comp_dir + 2];2765 const nlist = object.symtab.items(.nlist)[sf.comp_dir + 2];
2764 return nlist.n_value;2766 return nlist.n_value;
2765 }2767 }
27662768
2767 const Stab = struct {2769 const Stab = struct {
2768 is_func: bool = true,2770 is_func: bool = true,
2769 symbol: ?Symbol.Index = null,2771 index: ?Symbol.Index = null,
27702772
2771 fn getSymbol(stab: Stab, object: *const Object) ?*Symbol {2773 fn getSymbol(stab: Stab, object: Object) ?Symbol {
2772 const index = stab.index orelse return null;2774 const index = stab.index orelse return null;
2773 return &object.symbols.items[index];2775 return object.symbols.items[index];
2774 }2776 }
27752777
2776 pub fn format(2778 pub fn format(
...@@ -2786,9 +2788,9 @@ const StabFile = struct {...@@ -2786,9 +2788,9 @@ const StabFile = struct {
2786 @compileError("do not format stabs directly");2788 @compileError("do not format stabs directly");
2787 }2789 }
27882790
2789 const StabFormatContext = struct { Stab, *const Object };2791 const StabFormatContext = struct { Stab, Object };
27902792
2791 pub fn fmt(stab: Stab, object: *const Object) std.fmt.Formatter(format2) {2793 pub fn fmt(stab: Stab, object: Object) std.fmt.Formatter(format2) {
2792 return .{ .data = .{ stab, object } };2794 return .{ .data = .{ stab, object } };
2793 }2795 }
27942796
...@@ -2817,11 +2819,11 @@ const CompileUnit = struct {...@@ -2817,11 +2819,11 @@ const CompileUnit = struct {
2817 comp_dir: u32,2819 comp_dir: u32,
2818 tu_name: u32,2820 tu_name: u32,
28192821
2820 fn getCompDir(cu: CompileUnit, object: *const Object) [:0]const u8 {2822 fn getCompDir(cu: CompileUnit, object: Object) [:0]const u8 {
2821 return object.getString(cu.comp_dir);2823 return object.getString(cu.comp_dir);
2822 }2824 }
28232825
2824 fn getTuName(cu: CompileUnit, object: *const Object) [:0]const u8 {2826 fn getTuName(cu: CompileUnit, object: Object) [:0]const u8 {
2825 return object.getString(cu.tu_name);2827 return object.getString(cu.tu_name);
2826 }2828 }
2827};2829};
...@@ -2840,15 +2842,14 @@ const CompactUnwindCtx = struct {...@@ -2840,15 +2842,14 @@ const CompactUnwindCtx = struct {
28402842
2841const x86_64 = struct {2843const x86_64 = struct {
2842 fn parseRelocs(2844 fn parseRelocs(
2843 self: *const Object,2845 self: *Object,
2844 n_sect: u8,
2845 sect: macho.section_64,2846 sect: macho.section_64,
2846 out: *std.ArrayListUnmanaged(Relocation),2847 out: *std.ArrayListUnmanaged(Relocation),
2848 handle: File.Handle,
2847 macho_file: *MachO,2849 macho_file: *MachO,
2848 ) !void {2850 ) !void {
2849 const gpa = macho_file.base.comp.gpa;2851 const gpa = macho_file.base.comp.gpa;
28502852
2851 const handle = macho_file.getFileHandle(self.file_handle);
2852 const relocs_buffer = try gpa.alloc(u8, sect.nreloc * @sizeOf(macho.relocation_info));2853 const relocs_buffer = try gpa.alloc(u8, sect.nreloc * @sizeOf(macho.relocation_info));
2853 defer gpa.free(relocs_buffer);2854 defer gpa.free(relocs_buffer);
2854 {2855 {
...@@ -2857,8 +2858,12 @@ const x86_64 = struct {...@@ -2857,8 +2858,12 @@ const x86_64 = struct {
2857 }2858 }
2858 const relocs = @as([*]align(1) const macho.relocation_info, @ptrCast(relocs_buffer.ptr))[0..sect.nreloc];2859 const relocs = @as([*]align(1) const macho.relocation_info, @ptrCast(relocs_buffer.ptr))[0..sect.nreloc];
28592860
2860 const code = try self.getSectionData(@intCast(n_sect), macho_file);2861 const code = try gpa.alloc(u8, sect.size);
2861 defer gpa.free(code);2862 defer gpa.free(code);
2863 {
2864 const amt = try handle.preadAll(code, sect.offset + self.offset);
2865 if (amt != code.len) return error.InputOutput;
2866 }
28622867
2863 try out.ensureTotalCapacityPrecise(gpa, relocs.len);2868 try out.ensureTotalCapacityPrecise(gpa, relocs.len);
28642869
...@@ -2880,8 +2885,9 @@ const x86_64 = struct {...@@ -2880,8 +2885,9 @@ const x86_64 = struct {
2880 .X86_64_RELOC_SIGNED_4 => 4,2885 .X86_64_RELOC_SIGNED_4 => 4,
2881 else => 0,2886 else => 0,
2882 };2887 };
2888 var is_extern = rel.r_extern == 1;
28832889
2884 const target = if (rel.r_extern == 0) blk: {2890 const target = if (!is_extern) blk: {
2885 const nsect = rel.r_symbolnum - 1;2891 const nsect = rel.r_symbolnum - 1;
2886 const taddr: i64 = if (rel.r_pcrel == 1)2892 const taddr: i64 = if (rel.r_pcrel == 1)
2887 @as(i64, @intCast(sect.addr)) + rel.r_address + addend + 42893 @as(i64, @intCast(sect.addr)) + rel.r_address + addend + 4
...@@ -2893,9 +2899,15 @@ const x86_64 = struct {...@@ -2893,9 +2899,15 @@ const x86_64 = struct {
2893 });2899 });
2894 return error.MalformedObject;2900 return error.MalformedObject;
2895 };2901 };
2896 addend = taddr - @as(i64, @intCast(macho_file.getAtom(target).?.getInputAddress(macho_file)));2902 const target_atom = self.getAtom(target).?;
2903 addend = taddr - @as(i64, @intCast(target_atom.getInputAddress(macho_file)));
2904 const isec = target_atom.getInputSection(macho_file);
2905 if (isCstringLiteral(isec) or isFixedSizeLiteral(isec) or isPtrLiteral(isec)) {
2906 is_extern = true;
2907 break :blk target_atom.getExtra(macho_file).literal_symbol_index;
2908 }
2897 break :blk target;2909 break :blk target;
2898 } else self.symbols.items[rel.r_symbolnum];2910 } else rel.r_symbolnum;
28992911
2900 const has_subtractor = if (i > 0 and2912 const has_subtractor = if (i > 0 and
2901 @as(macho.reloc_type_x86_64, @enumFromInt(relocs[i - 1].r_type)) == .X86_64_RELOC_SUBTRACTOR)2913 @as(macho.reloc_type_x86_64, @enumFromInt(relocs[i - 1].r_type)) == .X86_64_RELOC_SUBTRACTOR)
...@@ -2909,7 +2921,7 @@ const x86_64 = struct {...@@ -2909,7 +2921,7 @@ const x86_64 = struct {
2909 break :blk true;2921 break :blk true;
2910 } else false;2922 } else false;
29112923
2912 const @"type": Relocation.Type = validateRelocType(rel, rel_type) catch |err| {2924 const @"type": Relocation.Type = validateRelocType(rel, rel_type, is_extern) catch |err| {
2913 switch (err) {2925 switch (err) {
2914 error.Pcrel => try macho_file.reportParseError2(2926 error.Pcrel => try macho_file.reportParseError2(
2915 self.index,2927 self.index,
...@@ -2936,7 +2948,7 @@ const x86_64 = struct {...@@ -2936,7 +2948,7 @@ const x86_64 = struct {
2936 };2948 };
29372949
2938 out.appendAssumeCapacity(.{2950 out.appendAssumeCapacity(.{
2939 .tag = if (rel.r_extern == 1) .@"extern" else .local,2951 .tag = if (is_extern) .@"extern" else .local,
2940 .offset = @as(u32, @intCast(rel.r_address)),2952 .offset = @as(u32, @intCast(rel.r_address)),
2941 .target = target,2953 .target = target,
2942 .addend = addend,2954 .addend = addend,
...@@ -2951,7 +2963,7 @@ const x86_64 = struct {...@@ -2951,7 +2963,7 @@ const x86_64 = struct {
2951 }2963 }
2952 }2964 }
29532965
2954 fn validateRelocType(rel: macho.relocation_info, rel_type: macho.reloc_type_x86_64) !Relocation.Type {2966 fn validateRelocType(rel: macho.relocation_info, rel_type: macho.reloc_type_x86_64, is_extern: bool) !Relocation.Type {
2955 switch (rel_type) {2967 switch (rel_type) {
2956 .X86_64_RELOC_UNSIGNED => {2968 .X86_64_RELOC_UNSIGNED => {
2957 if (rel.r_pcrel == 1) return error.Pcrel;2969 if (rel.r_pcrel == 1) return error.Pcrel;
...@@ -2971,7 +2983,7 @@ const x86_64 = struct {...@@ -2971,7 +2983,7 @@ const x86_64 = struct {
2971 => {2983 => {
2972 if (rel.r_pcrel == 0) return error.NonPcrel;2984 if (rel.r_pcrel == 0) return error.NonPcrel;
2973 if (rel.r_length != 2) return error.InvalidLength;2985 if (rel.r_length != 2) return error.InvalidLength;
2974 if (rel.r_extern == 0) return error.NonExtern;2986 if (!is_extern) return error.NonExtern;
2975 return switch (rel_type) {2987 return switch (rel_type) {
2976 .X86_64_RELOC_BRANCH => .branch,2988 .X86_64_RELOC_BRANCH => .branch,
2977 .X86_64_RELOC_GOT_LOAD => .got_load,2989 .X86_64_RELOC_GOT_LOAD => .got_load,
...@@ -3002,15 +3014,14 @@ const x86_64 = struct {...@@ -3002,15 +3014,14 @@ const x86_64 = struct {
30023014
3003const aarch64 = struct {3015const aarch64 = struct {
3004 fn parseRelocs(3016 fn parseRelocs(
3005 self: *const Object,3017 self: *Object,
3006 n_sect: u8,
3007 sect: macho.section_64,3018 sect: macho.section_64,
3008 out: *std.ArrayListUnmanaged(Relocation),3019 out: *std.ArrayListUnmanaged(Relocation),
3020 handle: File.Handle,
3009 macho_file: *MachO,3021 macho_file: *MachO,
3010 ) !void {3022 ) !void {
3011 const gpa = macho_file.base.comp.gpa;3023 const gpa = macho_file.base.comp.gpa;
30123024
3013 const handle = macho_file.getFileHandle(self.file_handle);
3014 const relocs_buffer = try gpa.alloc(u8, sect.nreloc * @sizeOf(macho.relocation_info));3025 const relocs_buffer = try gpa.alloc(u8, sect.nreloc * @sizeOf(macho.relocation_info));
3015 defer gpa.free(relocs_buffer);3026 defer gpa.free(relocs_buffer);
3016 {3027 {
...@@ -3019,8 +3030,12 @@ const aarch64 = struct {...@@ -3019,8 +3030,12 @@ const aarch64 = struct {
3019 }3030 }
3020 const relocs = @as([*]align(1) const macho.relocation_info, @ptrCast(relocs_buffer.ptr))[0..sect.nreloc];3031 const relocs = @as([*]align(1) const macho.relocation_info, @ptrCast(relocs_buffer.ptr))[0..sect.nreloc];
30213032
3022 const code = try self.getSectionData(@intCast(n_sect), macho_file);3033 const code = try gpa.alloc(u8, sect.size);
3023 defer gpa.free(code);3034 defer gpa.free(code);
3035 {
3036 const amt = try handle.preadAll(code, sect.offset + self.offset);
3037 if (amt != code.len) return error.InputOutput;
3038 }
30243039
3025 try out.ensureTotalCapacityPrecise(gpa, relocs.len);3040 try out.ensureTotalCapacityPrecise(gpa, relocs.len);
30263041
...@@ -3066,8 +3081,9 @@ const aarch64 = struct {...@@ -3066,8 +3081,9 @@ const aarch64 = struct {
3066 }3081 }
30673082
3068 const rel_type: macho.reloc_type_arm64 = @enumFromInt(rel.r_type);3083 const rel_type: macho.reloc_type_arm64 = @enumFromInt(rel.r_type);
3084 var is_extern = rel.r_extern == 1;
30693085
3070 const target = if (rel.r_extern == 0) blk: {3086 const target = if (!is_extern) blk: {
3071 const nsect = rel.r_symbolnum - 1;3087 const nsect = rel.r_symbolnum - 1;
3072 const taddr: i64 = if (rel.r_pcrel == 1)3088 const taddr: i64 = if (rel.r_pcrel == 1)
3073 @as(i64, @intCast(sect.addr)) + rel.r_address + addend3089 @as(i64, @intCast(sect.addr)) + rel.r_address + addend
...@@ -3079,9 +3095,15 @@ const aarch64 = struct {...@@ -3079,9 +3095,15 @@ const aarch64 = struct {
3079 });3095 });
3080 return error.MalformedObject;3096 return error.MalformedObject;
3081 };3097 };
3082 addend = taddr - @as(i64, @intCast(macho_file.getAtom(target).?.getInputAddress(macho_file)));3098 const target_atom = self.getAtom(target).?;
3099 addend = taddr - @as(i64, @intCast(target_atom.getInputAddress(macho_file)));
3100 const isec = target_atom.getInputSection(macho_file);
3101 if (isCstringLiteral(isec) or isFixedSizeLiteral(isec) or isPtrLiteral(isec)) {
3102 is_extern = true;
3103 break :blk target_atom.getExtra(macho_file).literal_symbol_index;
3104 }
3083 break :blk target;3105 break :blk target;
3084 } else self.symbols.items[rel.r_symbolnum];3106 } else rel.r_symbolnum;
30853107
3086 const has_subtractor = if (i > 0 and3108 const has_subtractor = if (i > 0 and
3087 @as(macho.reloc_type_arm64, @enumFromInt(relocs[i - 1].r_type)) == .ARM64_RELOC_SUBTRACTOR)3109 @as(macho.reloc_type_arm64, @enumFromInt(relocs[i - 1].r_type)) == .ARM64_RELOC_SUBTRACTOR)
...@@ -3095,7 +3117,7 @@ const aarch64 = struct {...@@ -3095,7 +3117,7 @@ const aarch64 = struct {
3095 break :blk true;3117 break :blk true;
3096 } else false;3118 } else false;
30973119
3098 const @"type": Relocation.Type = validateRelocType(rel, rel_type) catch |err| {3120 const @"type": Relocation.Type = validateRelocType(rel, rel_type, is_extern) catch |err| {
3099 switch (err) {3121 switch (err) {
3100 error.Pcrel => try macho_file.reportParseError2(3122 error.Pcrel => try macho_file.reportParseError2(
3101 self.index,3123 self.index,
...@@ -3122,7 +3144,7 @@ const aarch64 = struct {...@@ -3122,7 +3144,7 @@ const aarch64 = struct {
3122 };3144 };
31233145
3124 out.appendAssumeCapacity(.{3146 out.appendAssumeCapacity(.{
3125 .tag = if (rel.r_extern == 1) .@"extern" else .local,3147 .tag = if (is_extern) .@"extern" else .local,
3126 .offset = @as(u32, @intCast(rel.r_address)),3148 .offset = @as(u32, @intCast(rel.r_address)),
3127 .target = target,3149 .target = target,
3128 .addend = addend,3150 .addend = addend,
...@@ -3137,7 +3159,7 @@ const aarch64 = struct {...@@ -3137,7 +3159,7 @@ const aarch64 = struct {
3137 }3159 }
3138 }3160 }
31393161
3140 fn validateRelocType(rel: macho.relocation_info, rel_type: macho.reloc_type_arm64) !Relocation.Type {3162 fn validateRelocType(rel: macho.relocation_info, rel_type: macho.reloc_type_arm64, is_extern: bool) !Relocation.Type {
3141 switch (rel_type) {3163 switch (rel_type) {
3142 .ARM64_RELOC_UNSIGNED => {3164 .ARM64_RELOC_UNSIGNED => {
3143 if (rel.r_pcrel == 1) return error.Pcrel;3165 if (rel.r_pcrel == 1) return error.Pcrel;
...@@ -3158,7 +3180,7 @@ const aarch64 = struct {...@@ -3158,7 +3180,7 @@ const aarch64 = struct {
3158 => {3180 => {
3159 if (rel.r_pcrel == 0) return error.NonPcrel;3181 if (rel.r_pcrel == 0) return error.NonPcrel;
3160 if (rel.r_length != 2) return error.InvalidLength;3182 if (rel.r_length != 2) return error.InvalidLength;
3161 if (rel.r_extern == 0) return error.NonExtern;3183 if (!is_extern) return error.NonExtern;
3162 return switch (rel_type) {3184 return switch (rel_type) {
3163 .ARM64_RELOC_BRANCH26 => .branch,3185 .ARM64_RELOC_BRANCH26 => .branch,
3164 .ARM64_RELOC_PAGE21 => .page,3186 .ARM64_RELOC_PAGE21 => .page,
...@@ -3175,7 +3197,7 @@ const aarch64 = struct {...@@ -3175,7 +3197,7 @@ const aarch64 = struct {
3175 => {3197 => {
3176 if (rel.r_pcrel == 1) return error.Pcrel;3198 if (rel.r_pcrel == 1) return error.Pcrel;
3177 if (rel.r_length != 2) return error.InvalidLength;3199 if (rel.r_length != 2) return error.InvalidLength;
3178 if (rel.r_extern == 0) return error.NonExtern;3200 if (!is_extern) return error.NonExtern;
3179 return switch (rel_type) {3201 return switch (rel_type) {
3180 .ARM64_RELOC_PAGEOFF12 => .pageoff,3202 .ARM64_RELOC_PAGEOFF12 => .pageoff,
3181 .ARM64_RELOC_GOT_LOAD_PAGEOFF12 => .got_load_pageoff,3203 .ARM64_RELOC_GOT_LOAD_PAGEOFF12 => .got_load_pageoff,
src/link/MachO/Symbol.zig+2-2
...@@ -150,7 +150,7 @@ pub fn getObjcSelrefsAddress(symbol: Symbol, macho_file: *MachO) u64 {...@@ -150,7 +150,7 @@ pub fn getObjcSelrefsAddress(symbol: Symbol, macho_file: *MachO) u64 {
150 const file = symbol.getFile(macho_file).?;150 const file = symbol.getFile(macho_file).?;
151 return switch (file) {151 return switch (file) {
152 .dylib, .zig_object => unreachable,152 .dylib, .zig_object => unreachable,
153 .object, .internal => |x| x.symbols.items[extra.objc_selrefs].getAddress(.{}, macho_file),153 inline else => |x| x.symbols.items[extra.objc_selrefs].getAddress(.{}, macho_file),
154 };154 };
155}155}
156156
...@@ -186,7 +186,7 @@ pub fn getOutputSymtabIndex(symbol: Symbol, macho_file: *MachO) ?u32 {...@@ -186,7 +186,7 @@ pub fn getOutputSymtabIndex(symbol: Symbol, macho_file: *MachO) ?u32 {
186 const symtab_ctx = switch (file) {186 const symtab_ctx = switch (file) {
187 inline else => |x| x.output_symtab_ctx,187 inline else => |x| x.output_symtab_ctx,
188 };188 };
189 var idx = symbol.getExtra(macho_file).?.symtab;189 var idx = symbol.getExtra(macho_file).symtab;
190 if (symbol.isLocal()) {190 if (symbol.isLocal()) {
191 idx += symtab_ctx.ilocal;191 idx += symtab_ctx.ilocal;
192 } else if (symbol.flags.@"export") {192 } else if (symbol.flags.@"export") {
src/link/MachO/UnwindInfo.zig+2-2
...@@ -473,11 +473,11 @@ pub const Record = struct {...@@ -473,11 +473,11 @@ pub const Record = struct {
473 }473 }
474474
475 pub fn getAtom(rec: Record, macho_file: *MachO) *Atom {475 pub fn getAtom(rec: Record, macho_file: *MachO) *Atom {
476 return macho_file.getAtom(rec.atom).?;476 return rec.getObject(macho_file).getAtom(rec.atom).?;
477 }477 }
478478
479 pub fn getLsdaAtom(rec: Record, macho_file: *MachO) ?*Atom {479 pub fn getLsdaAtom(rec: Record, macho_file: *MachO) ?*Atom {
480 return macho_file.getAtom(rec.lsda);480 return rec.getObject(macho_file).getAtom(rec.lsda);
481 }481 }
482482
483 pub fn getPersonality(rec: Record, macho_file: *MachO) ?*Symbol {483 pub fn getPersonality(rec: Record, macho_file: *MachO) ?*Symbol {
src/link/MachO/ZigObject.zig+35-5
...@@ -343,6 +343,36 @@ pub fn writeAr(self: ZigObject, ar_format: Archive.Format, writer: anytype) !voi...@@ -343,6 +343,36 @@ pub fn writeAr(self: ZigObject, ar_format: Archive.Format, writer: anytype) !voi
343 try writer.writeAll(self.data.items);343 try writer.writeAll(self.data.items);
344}344}
345345
346pub fn claimUnresolved(self: *ZigObject, macho_file: *MachO) void {
347 const tracy = trace(@src());
348 defer tracy.end();
349
350 for (self.symbols.items, 0..) |*sym, i| {
351 const nlist = self.symtab.items(.nlist)[i];
352 if (!nlist.ext()) continue;
353 if (!nlist.undf()) continue;
354
355 if (self.getSymbolRef(@intCast(i), macho_file).getFile(macho_file) != null) continue;
356
357 const is_import = switch (macho_file.undefined_treatment) {
358 .@"error" => false,
359 .warn, .suppress => nlist.weakRef(),
360 .dynamic_lookup => true,
361 };
362 if (is_import) {
363 sym.value = 0;
364 sym.atom_ref = .{ .index = 0, .file = 0 };
365 sym.flags.weak = false;
366 sym.flags.weak_ref = nlist.weakRef();
367 sym.flags.import = is_import;
368 sym.visibility = .global;
369
370 const idx = self.globals.items[i];
371 macho_file.resolver.values.items[idx - 1] = .{ .index = @intCast(i), .file = self.index };
372 }
373 }
374}
375
346pub fn scanRelocs(self: *ZigObject, macho_file: *MachO) !void {376pub fn scanRelocs(self: *ZigObject, macho_file: *MachO) !void {
347 for (self.getAtoms()) |atom_index| {377 for (self.getAtoms()) |atom_index| {
348 const atom = self.getAtom(atom_index) orelse continue;378 const atom = self.getAtom(atom_index) orelse continue;
...@@ -378,7 +408,7 @@ pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) void {...@@ -378,7 +408,7 @@ pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) void {
378 }408 }
379}409}
380410
381pub fn writeSymtab(self: ZigObject, macho_file: *MachO) void {411pub fn writeSymtab(self: ZigObject, macho_file: *MachO, ctx: anytype) void {
382 const tracy = trace(@src());412 const tracy = trace(@src());
383 defer tracy.end();413 defer tracy.end();
384414
...@@ -388,13 +418,13 @@ pub fn writeSymtab(self: ZigObject, macho_file: *MachO) void {...@@ -388,13 +418,13 @@ pub fn writeSymtab(self: ZigObject, macho_file: *MachO) void {
388 const file = ref.getFile(macho_file) orelse continue;418 const file = ref.getFile(macho_file) orelse continue;
389 if (file.getIndex() != self.index) continue;419 if (file.getIndex() != self.index) continue;
390 const idx = sym.getOutputSymtabIndex(macho_file) orelse continue;420 const idx = sym.getOutputSymtabIndex(macho_file) orelse continue;
391 const out_sym = &macho_file.symtab.items[idx];421 const out_sym = &ctx.symtab.items[idx];
392 out_sym.n_strx = n_strx;422 out_sym.n_strx = n_strx;
393 sym.setOutputSym(macho_file, out_sym);423 sym.setOutputSym(macho_file, out_sym);
394 const name = sym.getName(macho_file);424 const name = sym.getName(macho_file);
395 @memcpy(macho_file.strtab.items[n_strx..][0..name.len], name);425 @memcpy(ctx.strtab.items[n_strx..][0..name.len], name);
396 n_strx += @intCast(name.len);426 n_strx += @intCast(name.len);
397 macho_file.strtab.items[n_strx] = 0;427 ctx.strtab.items[n_strx] = 0;
398 n_strx += 1;428 n_strx += 1;
399 }429 }
400}430}
...@@ -1098,7 +1128,7 @@ pub fn lowerUnnamedConst(...@@ -1098,7 +1128,7 @@ pub fn lowerUnnamedConst(
1098 },1128 },
1099 };1129 };
1100 const sym = self.symbols.items[sym_index];1130 const sym = self.symbols.items[sym_index];
1101 try unnamed_consts.append(gpa, sym.atom);1131 try unnamed_consts.append(gpa, sym.atom_ref.index);
1102 return sym_index;1132 return sym_index;
1103}1133}
11041134
src/link/MachO/dyld_info/Rebase.zig+5-5
...@@ -34,7 +34,7 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void {...@@ -34,7 +34,7 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void {
34 for (objects.items) |index| {34 for (objects.items) |index| {
35 const file = macho_file.getFile(index).?;35 const file = macho_file.getFile(index).?;
36 for (file.getAtoms()) |atom_index| {36 for (file.getAtoms()) |atom_index| {
37 const atom = macho_file.getAtom(atom_index) orelse continue;37 const atom = file.getAtom(atom_index) orelse continue;
38 if (!atom.flags.alive) continue;38 if (!atom.flags.alive) continue;
39 if (atom.getInputSection(macho_file).isZerofill()) continue;39 if (atom.getInputSection(macho_file).isZerofill()) continue;
40 const atom_addr = atom.getAddress(macho_file);40 const atom_addr = atom.getAddress(macho_file);
...@@ -43,7 +43,7 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void {...@@ -43,7 +43,7 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void {
43 for (atom.getRelocs(macho_file)) |rel| {43 for (atom.getRelocs(macho_file)) |rel| {
44 if (rel.type != .unsigned or rel.meta.length != 3) continue;44 if (rel.type != .unsigned or rel.meta.length != 3) continue;
45 if (rel.tag == .@"extern") {45 if (rel.tag == .@"extern") {
46 const sym = rel.getTargetSymbol(macho_file);46 const sym = rel.getTargetSymbol(atom.*, macho_file);
47 if (sym.isTlvInit(macho_file)) continue;47 if (sym.isTlvInit(macho_file)) continue;
48 if (sym.flags.import) continue;48 if (sym.flags.import) continue;
49 }49 }
...@@ -72,7 +72,7 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void {...@@ -72,7 +72,7 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void {
72 const seg_id = macho_file.sections.items(.segment_id)[sid];72 const seg_id = macho_file.sections.items(.segment_id)[sid];
73 const seg = macho_file.segments.items[seg_id];73 const seg = macho_file.segments.items[seg_id];
74 for (macho_file.got.symbols.items, 0..) |ref, idx| {74 for (macho_file.got.symbols.items, 0..) |ref, idx| {
75 const sym = macho_file.getSymbol(ref);75 const sym = ref.getSymbol(macho_file).?;
76 const addr = macho_file.got.getAddress(@intCast(idx), macho_file);76 const addr = macho_file.got.getAddress(@intCast(idx), macho_file);
77 if (!sym.flags.import) {77 if (!sym.flags.import) {
78 try rebase.entries.append(gpa, .{78 try rebase.entries.append(gpa, .{
...@@ -88,7 +88,7 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void {...@@ -88,7 +88,7 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void {
88 const seg_id = macho_file.sections.items(.segment_id)[sid];88 const seg_id = macho_file.sections.items(.segment_id)[sid];
89 const seg = macho_file.segments.items[seg_id];89 const seg = macho_file.segments.items[seg_id];
90 for (macho_file.stubs.symbols.items, 0..) |ref, idx| {90 for (macho_file.stubs.symbols.items, 0..) |ref, idx| {
91 const sym = macho_file.getSymbol(ref);91 const sym = ref.getSymbol(macho_file).?;
92 const addr = sect.addr + idx * @sizeOf(u64);92 const addr = sect.addr + idx * @sizeOf(u64);
93 const rebase_entry = Rebase.Entry{93 const rebase_entry = Rebase.Entry{
94 .offset = addr - seg.vmaddr,94 .offset = addr - seg.vmaddr,
...@@ -104,7 +104,7 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void {...@@ -104,7 +104,7 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void {
104 const seg_id = macho_file.sections.items(.segment_id)[sid];104 const seg_id = macho_file.sections.items(.segment_id)[sid];
105 const seg = macho_file.segments.items[seg_id];105 const seg = macho_file.segments.items[seg_id];
106 for (macho_file.tlv_ptr.symbols.items, 0..) |ref, idx| {106 for (macho_file.tlv_ptr.symbols.items, 0..) |ref, idx| {
107 const sym = macho_file.getSymbol(ref);107 const sym = ref.getSymbol(macho_file).?;
108 const addr = macho_file.tlv_ptr.getAddress(@intCast(idx), macho_file);108 const addr = macho_file.tlv_ptr.getAddress(@intCast(idx), macho_file);
109 if (!sym.flags.import) {109 if (!sym.flags.import) {
110 try rebase.entries.append(gpa, .{110 try rebase.entries.append(gpa, .{
src/link/MachO/dyld_info/Trie.zig+22-24
...@@ -94,33 +94,31 @@ pub fn updateSize(self: *Trie, macho_file: *MachO) !void {...@@ -94,33 +94,31 @@ pub fn updateSize(self: *Trie, macho_file: *MachO) !void {
94 const gpa = macho_file.base.comp.gpa;94 const gpa = macho_file.base.comp.gpa;
9595
96 try self.init(gpa);96 try self.init(gpa);
97 // TODO97 try self.nodes.ensureUnusedCapacity(gpa, macho_file.resolver.values.items.len * 2);
98 // try self.nodes.ensureUnusedCapacity(gpa, macho_file.resolver.values.items.len * 2);98 try self.edges.ensureUnusedCapacity(gpa, macho_file.resolver.values.items.len * 2);
99 // try self.edges.ensureUnusedCapacity(gpa, macho_file.resolver.values.items.len * 2);
10099
101 const seg = macho_file.getTextSegment();100 const seg = macho_file.getTextSegment();
102 for (macho_file.objects.items) |index| {101 for (macho_file.resolver.values.items) |ref| {
103 for (macho_file.getFile(index).?.getSymbols()) |ref| {102 if (ref.getFile(macho_file) == null) continue;
104 const sym = macho_file.getSymbol(ref);103 const sym = ref.getSymbol(macho_file).?;
105 if (!sym.flags.@"export") continue;104 if (!sym.flags.@"export") continue;
106 if (sym.getAtom(macho_file)) |atom| if (!atom.flags.alive) continue;105 if (sym.getAtom(macho_file)) |atom| if (!atom.flags.alive) continue;
107 var flags: u64 = if (sym.flags.abs)106 var flags: u64 = if (sym.flags.abs)
108 macho.EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE107 macho.EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE
109 else if (sym.flags.tlv)108 else if (sym.flags.tlv)
110 macho.EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL109 macho.EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL
111 else110 else
112 macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR;111 macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR;
113 if (sym.flags.weak) {112 if (sym.flags.weak) {
114 flags |= macho.EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION;113 flags |= macho.EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION;
115 macho_file.weak_defines = true;114 macho_file.weak_defines = true;
116 macho_file.binds_to_weak = true;115 macho_file.binds_to_weak = true;
117 }
118 try self.put(gpa, .{
119 .name = sym.getName(macho_file),
120 .vmaddr_offset = sym.getAddress(.{ .stubs = false }, macho_file) - seg.vmaddr,
121 .export_flags = flags,
122 });
123 }116 }
117 try self.put(gpa, .{
118 .name = sym.getName(macho_file),
119 .vmaddr_offset = sym.getAddress(.{ .stubs = false }, macho_file) - seg.vmaddr,
120 .export_flags = flags,
121 });
124 }122 }
125123
126 try self.finalize(gpa);124 try self.finalize(gpa);
src/link/MachO/dyld_info/bind.zig+27-25
...@@ -1,17 +1,19 @@...@@ -1,17 +1,19 @@
1pub const Entry = struct {1pub const Entry = struct {
2 target: Symbol.Index,2 target: MachO.Ref,
3 offset: u64,3 offset: u64,
4 segment_id: u8,4 segment_id: u8,
5 addend: i64,5 addend: i64,
66
7 pub fn lessThan(ctx: *MachO, entry: Entry, other: Entry) bool {7 pub fn lessThan(ctx: *MachO, entry: Entry, other: Entry) bool {
8 _ = ctx;
8 if (entry.segment_id == other.segment_id) {9 if (entry.segment_id == other.segment_id) {
9 if (entry.target == other.target) {10 if (entry.target.eql(other.target)) {
10 return entry.offset < other.offset;11 return entry.offset < other.offset;
11 }12 }
12 const entry_name = ctx.getSymbol(entry.target).getName(ctx);13 if (entry.target.file == other.target.file) {
13 const other_name = ctx.getSymbol(other.target).getName(ctx);14 return entry.target.index < other.target.index;
14 return std.mem.lessThan(u8, entry_name, other_name);15 }
16 return entry.target.file < other.target.file;
15 }17 }
16 return entry.segment_id < other.segment_id;18 return entry.segment_id < other.segment_id;
17 }19 }
...@@ -44,7 +46,7 @@ pub const Bind = struct {...@@ -44,7 +46,7 @@ pub const Bind = struct {
44 for (objects.items) |index| {46 for (objects.items) |index| {
45 const file = macho_file.getFile(index).?;47 const file = macho_file.getFile(index).?;
46 for (file.getAtoms()) |atom_index| {48 for (file.getAtoms()) |atom_index| {
47 const atom = macho_file.getAtom(atom_index) orelse continue;49 const atom = file.getAtom(atom_index) orelse continue;
48 if (!atom.flags.alive) continue;50 if (!atom.flags.alive) continue;
49 if (atom.getInputSection(macho_file).isZerofill()) continue;51 if (atom.getInputSection(macho_file).isZerofill()) continue;
50 const atom_addr = atom.getAddress(macho_file);52 const atom_addr = atom.getAddress(macho_file);
...@@ -55,10 +57,10 @@ pub const Bind = struct {...@@ -55,10 +57,10 @@ pub const Bind = struct {
55 if (rel.type != .unsigned or rel.meta.length != 3 or rel.tag != .@"extern") continue;57 if (rel.type != .unsigned or rel.meta.length != 3 or rel.tag != .@"extern") continue;
56 const rel_offset = rel.offset - atom.off;58 const rel_offset = rel.offset - atom.off;
57 const addend = rel.addend + rel.getRelocAddend(cpu_arch);59 const addend = rel.addend + rel.getRelocAddend(cpu_arch);
58 const sym = rel.getTargetSymbol(macho_file);60 const sym = rel.getTargetSymbol(atom.*, macho_file);
59 if (sym.isTlvInit(macho_file)) continue;61 if (sym.isTlvInit(macho_file)) continue;
60 const entry = Entry{62 const entry = Entry{
61 .target = rel.target,63 .target = rel.getTargetSymbolRef(atom.*, macho_file),
62 .offset = atom_addr + rel_offset - seg.vmaddr,64 .offset = atom_addr + rel_offset - seg.vmaddr,
63 .segment_id = seg_id,65 .segment_id = seg_id,
64 .addend = addend,66 .addend = addend,
...@@ -74,7 +76,7 @@ pub const Bind = struct {...@@ -74,7 +76,7 @@ pub const Bind = struct {
74 const seg_id = macho_file.sections.items(.segment_id)[sid];76 const seg_id = macho_file.sections.items(.segment_id)[sid];
75 const seg = macho_file.segments.items[seg_id];77 const seg = macho_file.segments.items[seg_id];
76 for (macho_file.got.symbols.items, 0..) |ref, idx| {78 for (macho_file.got.symbols.items, 0..) |ref, idx| {
77 const sym = macho_file.getSymbol(ref);79 const sym = ref.getSymbol(macho_file).?;
78 const addr = macho_file.got.getAddress(@intCast(idx), macho_file);80 const addr = macho_file.got.getAddress(@intCast(idx), macho_file);
79 const entry = Entry{81 const entry = Entry{
80 .target = ref,82 .target = ref,
...@@ -93,7 +95,7 @@ pub const Bind = struct {...@@ -93,7 +95,7 @@ pub const Bind = struct {
93 const seg_id = macho_file.sections.items(.segment_id)[sid];95 const seg_id = macho_file.sections.items(.segment_id)[sid];
94 const seg = macho_file.segments.items[seg_id];96 const seg = macho_file.segments.items[seg_id];
95 for (macho_file.stubs.symbols.items, 0..) |ref, idx| {97 for (macho_file.stubs.symbols.items, 0..) |ref, idx| {
96 const sym = macho_file.getSymbol(ref);98 const sym = ref.getSymbol(macho_file).?;
97 const addr = sect.addr + idx * @sizeOf(u64);99 const addr = sect.addr + idx * @sizeOf(u64);
98 const bind_entry = Entry{100 const bind_entry = Entry{
99 .target = ref,101 .target = ref,
...@@ -112,7 +114,7 @@ pub const Bind = struct {...@@ -112,7 +114,7 @@ pub const Bind = struct {
112 const seg = macho_file.segments.items[seg_id];114 const seg = macho_file.segments.items[seg_id];
113115
114 for (macho_file.tlv_ptr.symbols.items, 0..) |ref, idx| {116 for (macho_file.tlv_ptr.symbols.items, 0..) |ref, idx| {
115 const sym = macho_file.getSymbol(ref);117 const sym = ref.getSymbol(macho_file).?;
116 const addr = macho_file.tlv_ptr.getAddress(@intCast(idx), macho_file);118 const addr = macho_file.tlv_ptr.getAddress(@intCast(idx), macho_file);
117 const entry = Entry{119 const entry = Entry{
118 .target = ref,120 .target = ref,
...@@ -162,7 +164,7 @@ pub const Bind = struct {...@@ -162,7 +164,7 @@ pub const Bind = struct {
162 var addend: i64 = 0;164 var addend: i64 = 0;
163 var count: usize = 0;165 var count: usize = 0;
164 var skip: u64 = 0;166 var skip: u64 = 0;
165 var target: ?Symbol.Index = null;167 var target: ?MachO.Ref = null;
166168
167 var state: enum {169 var state: enum {
168 start,170 start,
...@@ -173,7 +175,7 @@ pub const Bind = struct {...@@ -173,7 +175,7 @@ pub const Bind = struct {
173 var i: usize = 0;175 var i: usize = 0;
174 while (i < entries.len) : (i += 1) {176 while (i < entries.len) : (i += 1) {
175 const current = entries[i];177 const current = entries[i];
176 if (target == null or target.? != current.target) {178 if (target == null or !target.?.eql(current.target)) {
177 switch (state) {179 switch (state) {
178 .start => {},180 .start => {},
179 .bind_single => try doBind(writer),181 .bind_single => try doBind(writer),
...@@ -182,7 +184,7 @@ pub const Bind = struct {...@@ -182,7 +184,7 @@ pub const Bind = struct {
182 state = .start;184 state = .start;
183 target = current.target;185 target = current.target;
184186
185 const sym = ctx.getSymbol(current.target);187 const sym = current.target.getSymbol(ctx).?;
186 const name = sym.getName(ctx);188 const name = sym.getName(ctx);
187 const flags: u8 = if (sym.weakRef(ctx)) macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT else 0;189 const flags: u8 = if (sym.weakRef(ctx)) macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT else 0;
188 const ordinal: i16 = ord: {190 const ordinal: i16 = ord: {
...@@ -296,7 +298,7 @@ pub const WeakBind = struct {...@@ -296,7 +298,7 @@ pub const WeakBind = struct {
296 for (objects.items) |index| {298 for (objects.items) |index| {
297 const file = macho_file.getFile(index).?;299 const file = macho_file.getFile(index).?;
298 for (file.getAtoms()) |atom_index| {300 for (file.getAtoms()) |atom_index| {
299 const atom = macho_file.getAtom(atom_index) orelse continue;301 const atom = file.getAtom(atom_index) orelse continue;
300 if (!atom.flags.alive) continue;302 if (!atom.flags.alive) continue;
301 if (atom.getInputSection(macho_file).isZerofill()) continue;303 if (atom.getInputSection(macho_file).isZerofill()) continue;
302 const atom_addr = atom.getAddress(macho_file);304 const atom_addr = atom.getAddress(macho_file);
...@@ -307,10 +309,10 @@ pub const WeakBind = struct {...@@ -307,10 +309,10 @@ pub const WeakBind = struct {
307 if (rel.type != .unsigned or rel.meta.length != 3 or rel.tag != .@"extern") continue;309 if (rel.type != .unsigned or rel.meta.length != 3 or rel.tag != .@"extern") continue;
308 const rel_offset = rel.offset - atom.off;310 const rel_offset = rel.offset - atom.off;
309 const addend = rel.addend + rel.getRelocAddend(cpu_arch);311 const addend = rel.addend + rel.getRelocAddend(cpu_arch);
310 const sym = rel.getTargetSymbol(macho_file);312 const sym = rel.getTargetSymbol(atom.*, macho_file);
311 if (sym.isTlvInit(macho_file)) continue;313 if (sym.isTlvInit(macho_file)) continue;
312 const entry = Entry{314 const entry = Entry{
313 .target = rel.target,315 .target = rel.getTargetSymbolRef(atom.*, macho_file),
314 .offset = atom_addr + rel_offset - seg.vmaddr,316 .offset = atom_addr + rel_offset - seg.vmaddr,
315 .segment_id = seg_id,317 .segment_id = seg_id,
316 .addend = addend,318 .addend = addend,
...@@ -326,7 +328,7 @@ pub const WeakBind = struct {...@@ -326,7 +328,7 @@ pub const WeakBind = struct {
326 const seg_id = macho_file.sections.items(.segment_id)[sid];328 const seg_id = macho_file.sections.items(.segment_id)[sid];
327 const seg = macho_file.segments.items[seg_id];329 const seg = macho_file.segments.items[seg_id];
328 for (macho_file.got.symbols.items, 0..) |ref, idx| {330 for (macho_file.got.symbols.items, 0..) |ref, idx| {
329 const sym = macho_file.getSymbol(ref);331 const sym = ref.getSymbol(macho_file).?;
330 const addr = macho_file.got.getAddress(@intCast(idx), macho_file);332 const addr = macho_file.got.getAddress(@intCast(idx), macho_file);
331 const entry = Entry{333 const entry = Entry{
332 .target = ref,334 .target = ref,
...@@ -346,7 +348,7 @@ pub const WeakBind = struct {...@@ -346,7 +348,7 @@ pub const WeakBind = struct {
346 const seg = macho_file.segments.items[seg_id];348 const seg = macho_file.segments.items[seg_id];
347349
348 for (macho_file.stubs.symbols.items, 0..) |ref, idx| {350 for (macho_file.stubs.symbols.items, 0..) |ref, idx| {
349 const sym = macho_file.getSymbol(ref);351 const sym = ref.getSymbol(macho_file).?;
350 const addr = sect.addr + idx * @sizeOf(u64);352 const addr = sect.addr + idx * @sizeOf(u64);
351 const bind_entry = Entry{353 const bind_entry = Entry{
352 .target = ref,354 .target = ref,
...@@ -365,7 +367,7 @@ pub const WeakBind = struct {...@@ -365,7 +367,7 @@ pub const WeakBind = struct {
365 const seg = macho_file.segments.items[seg_id];367 const seg = macho_file.segments.items[seg_id];
366368
367 for (macho_file.tlv_ptr.symbols.items, 0..) |ref, idx| {369 for (macho_file.tlv_ptr.symbols.items, 0..) |ref, idx| {
368 const sym = macho_file.getSymbol(ref);370 const sym = ref.getSymbol(macho_file).?;
369 const addr = macho_file.tlv_ptr.getAddress(@intCast(idx), macho_file);371 const addr = macho_file.tlv_ptr.getAddress(@intCast(idx), macho_file);
370 const entry = Entry{372 const entry = Entry{
371 .target = ref,373 .target = ref,
...@@ -415,7 +417,7 @@ pub const WeakBind = struct {...@@ -415,7 +417,7 @@ pub const WeakBind = struct {
415 var addend: i64 = 0;417 var addend: i64 = 0;
416 var count: usize = 0;418 var count: usize = 0;
417 var skip: u64 = 0;419 var skip: u64 = 0;
418 var target: ?Symbol.Index = null;420 var target: ?MachO.Ref = null;
419421
420 var state: enum {422 var state: enum {
421 start,423 start,
...@@ -426,7 +428,7 @@ pub const WeakBind = struct {...@@ -426,7 +428,7 @@ pub const WeakBind = struct {
426 var i: usize = 0;428 var i: usize = 0;
427 while (i < entries.len) : (i += 1) {429 while (i < entries.len) : (i += 1) {
428 const current = entries[i];430 const current = entries[i];
429 if (target == null or target.? != current.target) {431 if (target == null or !target.?.eql(current.target)) {
430 switch (state) {432 switch (state) {
431 .start => {},433 .start => {},
432 .bind_single => try doBind(writer),434 .bind_single => try doBind(writer),
...@@ -435,7 +437,7 @@ pub const WeakBind = struct {...@@ -435,7 +437,7 @@ pub const WeakBind = struct {
435 state = .start;437 state = .start;
436 target = current.target;438 target = current.target;
437439
438 const sym = ctx.getSymbol(current.target);440 const sym = current.target.getSymbol(ctx).?;
439 const name = sym.getName(ctx);441 const name = sym.getName(ctx);
440 const flags: u8 = 0; // TODO NON_WEAK_DEFINITION442 const flags: u8 = 0; // TODO NON_WEAK_DEFINITION
441443
...@@ -536,7 +538,7 @@ pub const LazyBind = struct {...@@ -536,7 +538,7 @@ pub const LazyBind = struct {
536 const seg = macho_file.segments.items[seg_id];538 const seg = macho_file.segments.items[seg_id];
537539
538 for (macho_file.stubs.symbols.items, 0..) |ref, idx| {540 for (macho_file.stubs.symbols.items, 0..) |ref, idx| {
539 const sym = macho_file.getSymbol(ref);541 const sym = ref.getSymbol(macho_file).?;
540 const addr = sect.addr + idx * @sizeOf(u64);542 const addr = sect.addr + idx * @sizeOf(u64);
541 const bind_entry = Entry{543 const bind_entry = Entry{
542 .target = ref,544 .target = ref,
...@@ -565,7 +567,7 @@ pub const LazyBind = struct {...@@ -565,7 +567,7 @@ pub const LazyBind = struct {
565 for (self.entries.items) |entry| {567 for (self.entries.items) |entry| {
566 self.offsets.appendAssumeCapacity(@intCast(self.buffer.items.len));568 self.offsets.appendAssumeCapacity(@intCast(self.buffer.items.len));
567569
568 const sym = ctx.getSymbol(entry.target);570 const sym = entry.target.getSymbol(ctx).?;
569 const name = sym.getName(ctx);571 const name = sym.getName(ctx);
570 const flags: u8 = if (sym.weakRef(ctx)) macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT else 0;572 const flags: u8 = if (sym.weakRef(ctx)) macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT else 0;
571 const ordinal: i16 = ord: {573 const ordinal: i16 = ord: {
src/link/MachO/file.zig+11-11
...@@ -30,10 +30,10 @@ pub const File = union(enum) {...@@ -30,10 +30,10 @@ pub const File = union(enum) {
30 }30 }
31 }31 }
3232
33 pub fn resolveSymbols(file: File, macho_file: *MachO) void {33 pub fn resolveSymbols(file: File, macho_file: *MachO) !void {
34 switch (file) {34 return switch (file) {
35 inline else => |x| x.resolveSymbols(macho_file),35 inline else => |x| x.resolveSymbols(macho_file),
36 }36 };
37 }37 }
3838
39 pub fn scanRelocs(file: File, macho_file: *MachO) !void {39 pub fn scanRelocs(file: File, macho_file: *MachO) !void {
...@@ -147,19 +147,19 @@ pub const File = union(enum) {...@@ -147,19 +147,19 @@ pub const File = union(enum) {
147 if (ref.getFile(macho_file) == null) continue;147 if (ref.getFile(macho_file) == null) continue;
148 if (ref.file != file.getIndex()) continue;148 if (ref.file != file.getIndex()) continue;
149 const sym = ref.getSymbol(macho_file).?;149 const sym = ref.getSymbol(macho_file).?;
150 if (sym.getSectionFlags().got) {150 if (sym.flags.needs_got) {
151 log.debug("'{s}' needs GOT", .{sym.getName(macho_file)});151 log.debug("'{s}' needs GOT", .{sym.getName(macho_file)});
152 try macho_file.got.addSymbol(ref, macho_file);152 try macho_file.got.addSymbol(ref, macho_file);
153 }153 }
154 if (sym.getSectionFlags().stubs) {154 if (sym.flags.stubs) {
155 log.debug("'{s}' needs STUBS", .{sym.getName(macho_file)});155 log.debug("'{s}' needs STUBS", .{sym.getName(macho_file)});
156 try macho_file.stubs.addSymbol(ref, macho_file);156 try macho_file.stubs.addSymbol(ref, macho_file);
157 }157 }
158 if (sym.getSectionFlags().tlv_ptr) {158 if (sym.flags.tlv_ptr) {
159 log.debug("'{s}' needs TLV pointer", .{sym.getName(macho_file)});159 log.debug("'{s}' needs TLV pointer", .{sym.getName(macho_file)});
160 try macho_file.tlv_ptr.addSymbol(ref, macho_file);160 try macho_file.tlv_ptr.addSymbol(ref, macho_file);
161 }161 }
162 if (sym.getSectionFlags().objc_stubs) {162 if (sym.flags.objc_stubs) {
163 log.debug("'{s}' needs OBJC STUBS", .{sym.getName(macho_file)});163 log.debug("'{s}' needs OBJC STUBS", .{sym.getName(macho_file)});
164 try macho_file.objc_stubs.addSymbol(ref, macho_file);164 try macho_file.objc_stubs.addSymbol(ref, macho_file);
165 }165 }
...@@ -171,7 +171,7 @@ pub const File = union(enum) {...@@ -171,7 +171,7 @@ pub const File = union(enum) {
171 defer tracy.end();171 defer tracy.end();
172 for (file.getAtoms()) |atom_index| {172 for (file.getAtoms()) |atom_index| {
173 const atom = file.getAtom(atom_index) orelse continue;173 const atom = file.getAtom(atom_index) orelse continue;
174 if (!atom.alive.load(.seq_cst)) continue;174 if (!atom.flags.alive) continue;
175 atom.out_n_sect = try Atom.initOutputSection(atom.getInputSection(macho_file), macho_file);175 atom.out_n_sect = try Atom.initOutputSection(atom.getInputSection(macho_file), macho_file);
176 }176 }
177 }177 }
...@@ -185,18 +185,18 @@ pub const File = union(enum) {...@@ -185,18 +185,18 @@ pub const File = union(enum) {
185185
186 pub fn writeAtoms(file: File, macho_file: *MachO) !void {186 pub fn writeAtoms(file: File, macho_file: *MachO) !void {
187 return switch (file) {187 return switch (file) {
188 .dylib => unreachable,188 .dylib, .zig_object => unreachable,
189 inline else => |x| x.writeAtoms(macho_file),189 inline else => |x| x.writeAtoms(macho_file),
190 };190 };
191 }191 }
192192
193 pub fn calcSymtabSize(file: File, macho_file: *MachO) !void {193 pub fn calcSymtabSize(file: File, macho_file: *MachO) void {
194 return switch (file) {194 return switch (file) {
195 inline else => |x| x.calcSymtabSize(macho_file),195 inline else => |x| x.calcSymtabSize(macho_file),
196 };196 };
197 }197 }
198198
199 pub fn writeSymtab(file: File, macho_file: *MachO, ctx: anytype) !void {199 pub fn writeSymtab(file: File, macho_file: *MachO, ctx: anytype) void {
200 return switch (file) {200 return switch (file) {
201 inline else => |x| x.writeSymtab(macho_file, ctx),201 inline else => |x| x.writeSymtab(macho_file, ctx),
202 };202 };
src/link/MachO/synthetic.zig+5-5
...@@ -23,7 +23,7 @@ pub const ZigGotSection = struct {...@@ -23,7 +23,7 @@ pub const ZigGotSection = struct {
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 = zo.getSymbol(sym_index);26 const symbol = &zo.symbols.items[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 symbol.addExtra(.{ .zig_got = index }, macho_file);29 symbol.addExtra(.{ .zig_got = index }, macho_file);
...@@ -56,7 +56,7 @@ pub const ZigGotSection = struct {...@@ -56,7 +56,7 @@ pub const ZigGotSection = struct {
56 const zo = macho_file.getZigObject().?;56 const zo = macho_file.getZigObject().?;
57 const off = zig_got.entryOffset(index, macho_file);57 const off = zig_got.entryOffset(index, macho_file);
58 const entry = zig_got.entries.items[index];58 const entry = zig_got.entries.items[index];
59 const value = zo.getSymbol(entry).getAddress(.{ .stubs = false }, macho_file);59 const value = zo.symbols.items[entry].getAddress(.{ .stubs = false }, macho_file);
6060
61 var buf: [8]u8 = undefined;61 var buf: [8]u8 = undefined;
62 std.mem.writeInt(u64, &buf, value, .little);62 std.mem.writeInt(u64, &buf, value, .little);
...@@ -66,7 +66,7 @@ pub const ZigGotSection = struct {...@@ -66,7 +66,7 @@ pub const ZigGotSection = struct {
66 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().?;67 const zo = macho_file.getZigObject().?;
68 for (zig_got.entries.items) |entry| {68 for (zig_got.entries.items) |entry| {
69 const symbol = zo.getSymbol(entry);69 const symbol = zo.symbols.items[entry];
70 const value = symbol.address(.{ .stubs = false }, macho_file);70 const value = symbol.address(.{ .stubs = false }, macho_file);
71 try writer.writeInt(u64, value, .little);71 try writer.writeInt(u64, value, .little);
72 }72 }
...@@ -94,7 +94,7 @@ pub const ZigGotSection = struct {...@@ -94,7 +94,7 @@ pub const ZigGotSection = struct {
94 const zo = macho_file.getZigObject().?;94 const zo = macho_file.getZigObject().?;
95 try writer.writeAll("__zig_got\n");95 try writer.writeAll("__zig_got\n");
96 for (zig_got.entries.items, 0..) |entry, index| {96 for (zig_got.entries.items, 0..) |entry, index| {
97 const symbol = zo.getSymbol(entry);97 const symbol = zo.symbols.items[entry];
98 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{98 try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{
99 index,99 index,
100 zig_got.entryAddress(@intCast(index), macho_file),100 zig_got.entryAddress(@intCast(index), macho_file),
...@@ -694,7 +694,7 @@ pub const DataInCode = struct {...@@ -694,7 +694,7 @@ pub const DataInCode = struct {
694 dices[next_dice].offset < end_off) : (next_dice += 1)694 dices[next_dice].offset < end_off) : (next_dice += 1)
695 {}695 {}
696696
697 if (atom.alive.load(.seq_cst)) for (dices[start_dice..next_dice]) |d| {697 if (atom.flags.alive) for (dices[start_dice..next_dice]) |d| {
698 dice.entries.appendAssumeCapacity(.{698 dice.entries.appendAssumeCapacity(.{
699 .offset = @intCast(atom.getAddress(macho_file) + d.offset - start_off - base_address),699 .offset = @intCast(atom.getAddress(macho_file) + d.offset - start_off - base_address),
700 .length = d.length,700 .length = d.length,
src/link/MachO/thunks.zig+3-3
...@@ -37,7 +37,7 @@ pub fn createThunks(sect_id: u8, macho_file: *MachO) !void {...@@ -37,7 +37,7 @@ pub fn createThunks(sect_id: u8, macho_file: *MachO) !void {
3737
38 // Scan relocs in the group and create trampolines for any unreachable callsite38 // Scan relocs in the group and create trampolines for any unreachable callsite
39 try scanRelocs(thunk_index, gpa, atoms[start..i], macho_file);39 try scanRelocs(thunk_index, gpa, atoms[start..i], macho_file);
40 thunk.value = try advance(header, thunk.size(), .@"4");40 thunk.value = advance(header, thunk.size(), .@"4");
4141
42 log.debug("thunk({d}) : {}", .{ thunk_index, thunk.fmt(macho_file) });42 log.debug("thunk({d}) : {}", .{ thunk_index, thunk.fmt(macho_file) });
43 }43 }
...@@ -99,8 +99,8 @@ pub const Thunk = struct {...@@ -99,8 +99,8 @@ pub const Thunk = struct {
99 return header.addr + thunk.value;99 return header.addr + thunk.value;
100 }100 }
101101
102 pub fn getTargetAddress(thunk: Thunk, sym_index: Symbol.Index, macho_file: *MachO) u64 {102 pub fn getTargetAddress(thunk: Thunk, ref: MachO.Ref, macho_file: *MachO) u64 {
103 return thunk.getAddress(macho_file) + thunk.symbols.getIndex(sym_index).? * trampoline_size;103 return thunk.getAddress(macho_file) + thunk.symbols.getIndex(ref).? * trampoline_size;
104 }104 }
105105
106 pub fn write(thunk: Thunk, macho_file: *MachO, writer: anytype) !void {106 pub fn write(thunk: Thunk, macho_file: *MachO, writer: anytype) !void {