authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-09 20:26:34+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-07-18 09:13:08+02:00
logf8b5466aef4131821b259aa5f0d6b9654a5595ce
treea0b037225a7a256913ed861c61cd152b480bd513
parent882ff3ae31a39edf23db00b558db60ee574d9859

macho: migrate UnwindInfo


3 files changed, 64 insertions(+), 37 deletions(-)

src/link/MachO.zig+2-2
......@@ -354,8 +354,8 @@ pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
354354 if (comp.verbose_link) try self.dumpArgv(comp);
355355
356356 if (self.getZigObject()) |zo| try zo.flushModule(self, tid);
357 if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path);
358 if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path);
357 // if (self.base.isStaticLib()) return relocatable.flushStaticLib(self, comp, module_obj_path);
358 // if (self.base.isObject()) return relocatable.flushObject(self, comp, module_obj_path);
359359
360360 var positionals = std.ArrayList(Compilation.LinkObject).init(gpa);
361361 defer positionals.deinit();
src/link/MachO/UnwindInfo.zig+22-11
......@@ -4,7 +4,7 @@ records: std.ArrayListUnmanaged(Record.Ref) = .{},
44
55/// List of all personalities referenced by either unwind info entries
66/// or __eh_frame entries.
7personalities: [max_personalities]Symbol.Index = undefined,
7personalities: [max_personalities]MachO.Ref = undefined,
88personalities_count: u2 = 0,
99
1010/// 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 {
4242}
4343
4444pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void {
45 const tracy = trace(@src());
46 defer tracy.end();
47
4548 const gpa = macho_file.base.comp.gpa;
4649
4750 log.debug("generating unwind info", .{});
4851
4952 // Collect all unwind records
5053 for (macho_file.sections.items(.atoms)) |atoms| {
51 for (atoms.items) |atom_index| {
52 const atom = macho_file.getAtom(atom_index) orelse continue;
54 for (atoms.items) |ref| {
55 const atom = ref.getAtom(macho_file) orelse continue;
5356 if (!atom.flags.alive) continue;
5457 const recs = atom.getUnwindRecords(macho_file);
5558 const file = atom.getFile(macho_file);
......@@ -73,11 +76,15 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void {
7376 }
7477 const cie = fde.getCie(macho_file);
7578 if (cie.getPersonality(macho_file)) |_| {
76 const personality_index = try info.getOrPutPersonalityFunction(cie.personality.?.index); // TODO handle error
79 const object = cie.getObject(macho_file);
80 const sym_ref = object.getSymbolRef(cie.personality.?.index, macho_file);
81 const personality_index = try info.getOrPutPersonalityFunction(sym_ref); // TODO handle error
7782 rec.enc.setPersonalityIndex(personality_index + 1);
7883 }
7984 } else if (rec.getPersonality(macho_file)) |_| {
80 const personality_index = try info.getOrPutPersonalityFunction(rec.personality.?); // TODO handle error
85 const object = rec.getObject(macho_file);
86 const sym_ref = object.getSymbolRef(rec.personality.?, macho_file);
87 const personality_index = try info.getOrPutPersonalityFunction(sym_ref); // TODO handle error
8188 rec.enc.setPersonalityIndex(personality_index + 1);
8289 }
8390 }
......@@ -257,6 +264,9 @@ pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void {
257264}
258265
259266pub fn calcSize(info: UnwindInfo) usize {
267 const tracy = trace(@src());
268 defer tracy.end();
269
260270 var total_size: usize = 0;
261271 total_size += @sizeOf(macho.unwind_info_section_header);
262272 total_size +=
......@@ -293,8 +303,8 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void {
293303
294304 try writer.writeAll(mem.sliceAsBytes(info.common_encodings[0..info.common_encodings_count]));
295305
296 for (info.personalities[0..info.personalities_count]) |sym_index| {
297 const sym = macho_file.getSymbol(sym_index);
306 for (info.personalities[0..info.personalities_count]) |ref| {
307 const sym = ref.getSymbol(macho_file).?;
298308 try writer.writeInt(u32, @intCast(sym.getGotAddress(macho_file) - seg.vmaddr), .little);
299309 }
300310
......@@ -342,13 +352,13 @@ pub fn write(info: UnwindInfo, macho_file: *MachO, buffer: []u8) !void {
342352 @memset(buffer[stream.pos..], 0);
343353}
344354
345fn getOrPutPersonalityFunction(info: *UnwindInfo, sym_index: Symbol.Index) error{TooManyPersonalities}!u2 {
355fn getOrPutPersonalityFunction(info: *UnwindInfo, ref: MachO.Ref) error{TooManyPersonalities}!u2 {
346356 comptime var index: u2 = 0;
347357 inline while (index < max_personalities) : (index += 1) {
348 if (info.personalities[index] == sym_index) {
358 if (info.personalities[index].eql(ref)) {
349359 return index;
350360 } else if (index == info.personalities_count) {
351 info.personalities[index] = sym_index;
361 info.personalities[index] = ref;
352362 info.personalities_count += 1;
353363 return index;
354364 }
......@@ -472,7 +482,8 @@ pub const Record = struct {
472482
473483 pub fn getPersonality(rec: Record, macho_file: *MachO) ?*Symbol {
474484 const personality = rec.personality orelse return null;
475 return macho_file.getSymbol(personality);
485 const object = rec.getObject(macho_file);
486 return object.getSymbolRef(personality, macho_file).getSymbol(macho_file);
476487 }
477488
478489 pub fn getFde(rec: Record, macho_file: *MachO) ?Fde {
src/link/MachO/dead_strip.zig+40-24
......@@ -17,16 +17,16 @@ pub fn gcAtoms(macho_file: *MachO) !void {
1717fn collectRoots(roots: *std.ArrayList(*Atom), objects: []const File.Index, macho_file: *MachO) !void {
1818 for (objects) |index| {
1919 const object = macho_file.getFile(index).?;
20 for (object.getSymbols()) |sym_index| {
21 const sym = macho_file.getSymbol(sym_index);
22 const file = sym.getFile(macho_file) orelse continue;
20 for (object.getSymbols(), 0..) |*sym, i| {
21 const ref = object.getSymbolRef(@intCast(i), macho_file);
22 const file = ref.getFile(macho_file) orelse continue;
2323 if (file.getIndex() != index) continue;
2424 if (sym.flags.no_dead_strip or (macho_file.base.isDynLib() and sym.visibility == .global))
2525 try markSymbol(sym, roots, macho_file);
2626 }
2727
2828 for (object.getAtoms()) |atom_index| {
29 const atom = macho_file.getAtom(atom_index).?;
29 const atom = object.getAtom(atom_index) orelse continue;
3030 const isec = atom.getInputSection(macho_file);
3131 switch (isec.type()) {
3232 macho.S_MOD_INIT_FUNC_POINTERS,
......@@ -51,19 +51,27 @@ fn collectRoots(roots: *std.ArrayList(*Atom), objects: []const File.Index, macho
5151 }
5252 }
5353
54 for (macho_file.undefined_symbols.items) |sym_index| {
55 const sym = macho_file.getSymbol(sym_index);
56 try markSymbol(sym, roots, macho_file);
57 }
54 if (macho_file.getInternalObject()) |obj| {
55 for (obj.force_undefined.items) |sym_index| {
56 const ref = obj.getSymbolRef(sym_index, macho_file);
57 if (ref.getFile(macho_file) != null) {
58 const sym = ref.getSymbol(macho_file).?;
59 try markSymbol(sym, roots, macho_file);
60 }
61 }
5862
59 for (&[_]?Symbol.Index{
60 macho_file.entry_index,
61 macho_file.dyld_stub_binder_index,
62 macho_file.objc_msg_send_index,
63 }) |index| {
64 if (index) |idx| {
65 const sym = macho_file.getSymbol(idx);
66 try markSymbol(sym, roots, macho_file);
63 for (&[_]?Symbol.Index{
64 obj.entry_index,
65 obj.dyld_stub_binder_index,
66 obj.objc_msg_send_index,
67 }) |index| {
68 if (index) |idx| {
69 const ref = obj.getSymbolRef(idx, macho_file);
70 if (ref.getFile(macho_file) != null) {
71 const sym = ref.getSymbol(macho_file).?;
72 try markSymbol(sym, roots, macho_file);
73 }
74 }
6775 }
6876 }
6977}
......@@ -89,8 +97,9 @@ fn mark(roots: []*Atom, objects: []const File.Index, macho_file: *MachO) void {
8997 loop = false;
9098
9199 for (objects) |index| {
92 for (macho_file.getFile(index).?.getAtoms()) |atom_index| {
93 const atom = macho_file.getAtom(atom_index).?;
100 const file = macho_file.getFile(index).?;
101 for (file.getAtoms()) |atom_index| {
102 const atom = file.getAtom(atom_index) orelse continue;
94103 const isec = atom.getInputSection(macho_file);
95104 if (isec.isDontDeadStripIfReferencesLive() and
96105 !(mem.eql(u8, isec.sectName(), "__eh_frame") or
......@@ -120,8 +129,11 @@ fn markLive(atom: *Atom, macho_file: *MachO) void {
120129
121130 for (atom.getRelocs(macho_file)) |rel| {
122131 const target_atom = switch (rel.tag) {
123 .local => rel.getTargetAtom(macho_file),
124 .@"extern" => rel.getTargetSymbol(macho_file).getAtom(macho_file),
132 .local => rel.getTargetAtom(atom.*, macho_file),
133 .@"extern" => blk: {
134 const ref = rel.getTargetSymbolRef(atom.*, macho_file);
135 break :blk if (ref.getSymbol(macho_file)) |sym| sym.getAtom(macho_file) else null;
136 },
125137 };
126138 if (target_atom) |ta| {
127139 if (markAtom(ta)) markLive(ta, macho_file);
......@@ -151,8 +163,11 @@ fn markLive(atom: *Atom, macho_file: *MachO) void {
151163fn refersLive(atom: *Atom, macho_file: *MachO) bool {
152164 for (atom.getRelocs(macho_file)) |rel| {
153165 const target_atom = switch (rel.tag) {
154 .local => rel.getTargetAtom(macho_file),
155 .@"extern" => rel.getTargetSymbol(macho_file).getAtom(macho_file),
166 .local => rel.getTargetAtom(atom.*, macho_file),
167 .@"extern" => blk: {
168 const ref = rel.getTargetSymbolRef(atom.*, macho_file);
169 break :blk if (ref.getSymbol(macho_file)) |sym| sym.getAtom(macho_file) else null;
170 },
156171 };
157172 if (target_atom) |ta| {
158173 if (ta.flags.alive) return true;
......@@ -163,8 +178,9 @@ fn refersLive(atom: *Atom, macho_file: *MachO) bool {
163178
164179fn prune(objects: []const File.Index, macho_file: *MachO) void {
165180 for (objects) |index| {
166 for (macho_file.getFile(index).?.getAtoms()) |atom_index| {
167 const atom = macho_file.getAtom(atom_index).?;
181 const file = macho_file.getFile(index).?;
182 for (file.getAtoms()) |atom_index| {
183 const atom = file.getAtom(atom_index) orelse continue;
168184 if (atom.flags.alive and !atom.flags.visited) {
169185 atom.flags.alive = false;
170186 atom.markUnwindRecordsDead(macho_file);