diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 5d95838f30..9703890985 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -354,8 +354,8 @@ pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_n if (comp.verbose_link) try self.dumpArgv(comp); if (self.getZigObject()) |zo| try zo.flushModule(self, tid); - if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path); - if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path); + // if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path); + // if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path); var positionals = std.ArrayList(Compilation.LinkObject).init(gpa); defer positionals.deinit(); diff --git a/src/link/MachO/UnwindInfo.zig b/src/link/MachO/UnwindInfo.zig index 252333d5bb..f06db2f842 100644 --- a/src/link/MachO/UnwindInfo.zig +++ b/src/link/MachO/UnwindInfo.zig @@ -4,7 +4,7 @@ records: std.ArrayListUnmanaged(Record.Ref) = .{}, /// List of all personalities referenced by either unwind info entries /// or __eh_frame entries. -personalities: [max_personalities]Symbol.Index = undefined, +personalities: [max_personalities]MachO.Ref = undefined, personalities_count: u2 = 0, /// List of common encodings sorted in descending order with the most common first. @@ -42,14 +42,17 @@ fn canFold(macho_file: *MachO, lhs_ref: Record.Ref, rhs_ref: Record.Ref) bool { } pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void { + const tracy = trace(@src()); + defer tracy.end(); + const gpa = macho_file.base.comp.gpa; log.debug("generating unwind info", .{}); // Collect all unwind records for (macho_file.sections.items(.atoms)) |atoms| { - for (atoms.items) |atom_index| { - const atom = macho_file.getAtom(atom_index) orelse continue; + for (atoms.items) |ref| { + const atom = ref.getAtom(macho_file) orelse continue; if (!atom.flags.alive) continue; const recs = atom.getUnwindRecords(macho_file); const file = atom.getFile(macho_file); @@ -73,11 +76,15 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void { } const cie = fde.getCie(macho_file); if (cie.getPersonality(macho_file)) |_| { - const personality_index = try info.getOrPutPersonalityFunction(cie.personality.?.index); // TODO handle error + const object = cie.getObject(macho_file); + const sym_ref = object.getSymbolRef(cie.personality.?.index, macho_file); + const personality_index = try info.getOrPutPersonalityFunction(sym_ref); // TODO handle error rec.enc.setPersonalityIndex(personality_index + 1); } } else if (rec.getPersonality(macho_file)) |_| { - const personality_index = try info.getOrPutPersonalityFunction(rec.personality.?); // TODO handle error + const object = rec.getObject(macho_file); + const sym_ref = object.getSymbolRef(rec.personality.?, macho_file); + const personality_index = try info.getOrPutPersonalityFunction(sym_ref); // TODO handle error rec.enc.setPersonalityIndex(personality_index + 1); } } @@ -257,6 +264,9 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void { } pub fn calcSize(info: UnwindInfo) usize { + const tracy = trace(@src()); + defer tracy.end(); + var total_size: usize = 0; total_size += @sizeOf(macho.unwind_info_section_header); total_size += @@ -293,8 +303,8 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void { try writer.writeAll(mem.sliceAsBytes(info.common_encodings[0..info.common_encodings_count])); - for (info.personalities[0..info.personalities_count]) |sym_index| { - const sym = macho_file.getSymbol(sym_index); + for (info.personalities[0..info.personalities_count]) |ref| { + const sym = ref.getSymbol(macho_file).?; try writer.writeInt(u32, @intCast(sym.getGotAddress(macho_file) - seg.vmaddr), .little); } @@ -342,13 +352,13 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void { @memset(buffer[stream.pos..], 0); } -fn getOrPutPersonalityFunction(info: *UnwindInfo, sym_index: Symbol.Index) error{TooManyPersonalities}!u2 { +fn getOrPutPersonalityFunction(info: *UnwindInfo, ref: MachO.Ref) error{TooManyPersonalities}!u2 { comptime var index: u2 = 0; inline while (index < max_personalities) : (index += 1) { - if (info.personalities[index] == sym_index) { + if (info.personalities[index].eql(ref)) { return index; } else if (index == info.personalities_count) { - info.personalities[index] = sym_index; + info.personalities[index] = ref; info.personalities_count += 1; return index; } @@ -472,7 +482,8 @@ pub const Record = struct { pub fn getPersonality(rec: Record, macho_file: *MachO) ?*Symbol { const personality = rec.personality orelse return null; - return macho_file.getSymbol(personality); + const object = rec.getObject(macho_file); + return object.getSymbolRef(personality, macho_file).getSymbol(macho_file); } pub fn getFde(rec: Record, macho_file: *MachO) ?Fde { diff --git a/src/link/MachO/dead_strip.zig b/src/link/MachO/dead_strip.zig index 84e56c9249..eb27109a82 100644 --- a/src/link/MachO/dead_strip.zig +++ b/src/link/MachO/dead_strip.zig @@ -17,16 +17,16 @@ pub fn gcAtoms(macho_file: *MachO) !void { fn collectRoots(roots: *std.ArrayList(*Atom), objects: []const File.Index, macho_file: *MachO) !void { for (objects) |index| { const object = macho_file.getFile(index).?; - for (object.getSymbols()) |sym_index| { - const sym = macho_file.getSymbol(sym_index); - const file = sym.getFile(macho_file) orelse continue; + for (object.getSymbols(), 0..) |*sym, i| { + const ref = object.getSymbolRef(@intCast(i), macho_file); + const file = ref.getFile(macho_file) orelse continue; if (file.getIndex() != index) continue; if (sym.flags.no_dead_strip or (macho_file.base.isDynLib() and sym.visibility == .global)) try markSymbol(sym, roots, macho_file); } for (object.getAtoms()) |atom_index| { - const atom = macho_file.getAtom(atom_index).?; + const atom = object.getAtom(atom_index) orelse continue; const isec = atom.getInputSection(macho_file); switch (isec.type()) { macho.S_MOD_INIT_FUNC_POINTERS, @@ -51,19 +51,27 @@ fn collectRoots(roots: *std.ArrayList(*Atom), objects: []const File.Index, macho } } - for (macho_file.undefined_symbols.items) |sym_index| { - const sym = macho_file.getSymbol(sym_index); - try markSymbol(sym, roots, macho_file); - } + if (macho_file.getInternalObject()) |obj| { + for (obj.force_undefined.items) |sym_index| { + const ref = obj.getSymbolRef(sym_index, macho_file); + if (ref.getFile(macho_file) != null) { + const sym = ref.getSymbol(macho_file).?; + try markSymbol(sym, roots, macho_file); + } + } - for (&[_]?Symbol.Index{ - macho_file.entry_index, - macho_file.dyld_stub_binder_index, - macho_file.objc_msg_send_index, - }) |index| { - if (index) |idx| { - const sym = macho_file.getSymbol(idx); - try markSymbol(sym, roots, macho_file); + for (&[_]?Symbol.Index{ + obj.entry_index, + obj.dyld_stub_binder_index, + obj.objc_msg_send_index, + }) |index| { + if (index) |idx| { + const ref = obj.getSymbolRef(idx, macho_file); + if (ref.getFile(macho_file) != null) { + const sym = ref.getSymbol(macho_file).?; + try markSymbol(sym, roots, macho_file); + } + } } } } @@ -89,8 +97,9 @@ fn mark(roots: []*Atom, objects: []const File.Index, macho_file: *MachO) void { loop = false; for (objects) |index| { - for (macho_file.getFile(index).?.getAtoms()) |atom_index| { - const atom = macho_file.getAtom(atom_index).?; + const file = macho_file.getFile(index).?; + for (file.getAtoms()) |atom_index| { + const atom = file.getAtom(atom_index) orelse continue; const isec = atom.getInputSection(macho_file); if (isec.isDontDeadStripIfReferencesLive() and !(mem.eql(u8, isec.sectName(), "__eh_frame") or @@ -120,8 +129,11 @@ fn markLive(atom: *Atom, macho_file: *MachO) void { for (atom.getRelocs(macho_file)) |rel| { const target_atom = switch (rel.tag) { - .local => rel.getTargetAtom(macho_file), - .@"extern" => rel.getTargetSymbol(macho_file).getAtom(macho_file), + .local => rel.getTargetAtom(atom.*, macho_file), + .@"extern" => blk: { + const ref = rel.getTargetSymbolRef(atom.*, macho_file); + break :blk if (ref.getSymbol(macho_file)) |sym| sym.getAtom(macho_file) else null; + }, }; if (target_atom) |ta| { if (markAtom(ta)) markLive(ta, macho_file); @@ -151,8 +163,11 @@ fn markLive(atom: *Atom, macho_file: *MachO) void { fn refersLive(atom: *Atom, macho_file: *MachO) bool { for (atom.getRelocs(macho_file)) |rel| { const target_atom = switch (rel.tag) { - .local => rel.getTargetAtom(macho_file), - .@"extern" => rel.getTargetSymbol(macho_file).getAtom(macho_file), + .local => rel.getTargetAtom(atom.*, macho_file), + .@"extern" => blk: { + const ref = rel.getTargetSymbolRef(atom.*, macho_file); + break :blk if (ref.getSymbol(macho_file)) |sym| sym.getAtom(macho_file) else null; + }, }; if (target_atom) |ta| { if (ta.flags.alive) return true; @@ -163,8 +178,9 @@ fn refersLive(atom: *Atom, macho_file: *MachO) bool { fn prune(objects: []const File.Index, macho_file: *MachO) void { for (objects) |index| { - for (macho_file.getFile(index).?.getAtoms()) |atom_index| { - const atom = macho_file.getAtom(atom_index).?; + const file = macho_file.getFile(index).?; + for (file.getAtoms()) |atom_index| { + const atom = file.getAtom(atom_index) orelse continue; if (atom.flags.alive and !atom.flags.visited) { atom.flags.alive = false; atom.markUnwindRecordsDead(macho_file);