Commit 82628dd151
Changed files (3)
src
link
src/link/MachO/Object.zig
@@ -164,6 +164,10 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {
try self.initUnwindRecords(index, macho_file);
}
+ if (self.hasUnwindRecords() or self.hasEhFrameRecords()) {
+ try self.parseUnwindRecords(macho_file);
+ }
+
self.initPlatform();
if (self.platform) |platform| {
@@ -816,36 +820,9 @@ fn initUnwindRecords(self: *Object, sect_id: u8, macho_file: *MachO) !void {
}
}
}
-
- if (!macho_file.base.isObject()) try self.synthesiseNullUnwindRecords(macho_file);
-
- const sortFn = struct {
- fn sortFn(ctx: *MachO, lhs_index: UnwindInfo.Record.Index, rhs_index: UnwindInfo.Record.Index) bool {
- const lhs = ctx.getUnwindRecord(lhs_index);
- const rhs = ctx.getUnwindRecord(rhs_index);
- const lhsa = lhs.getAtom(ctx);
- const rhsa = rhs.getAtom(ctx);
- return lhsa.getInputAddress(ctx) + lhs.atom_offset < rhsa.getInputAddress(ctx) + rhs.atom_offset;
- }
- }.sortFn;
- mem.sort(UnwindInfo.Record.Index, self.unwind_records.items, macho_file, sortFn);
-
- // Associate unwind records to atoms
- var next_cu: u32 = 0;
- while (next_cu < self.unwind_records.items.len) {
- const start = next_cu;
- const rec_index = self.unwind_records.items[start];
- const rec = macho_file.getUnwindRecord(rec_index);
- while (next_cu < self.unwind_records.items.len and
- macho_file.getUnwindRecord(self.unwind_records.items[next_cu]).atom == rec.atom) : (next_cu += 1)
- {}
-
- const atom = rec.getAtom(macho_file);
- atom.unwind_records = .{ .pos = start, .len = next_cu - start };
- }
}
-fn synthesiseNullUnwindRecords(self: *Object, macho_file: *MachO) !void {
+fn parseUnwindRecords(self: *Object, macho_file: *MachO) !void {
// Synthesise missing unwind records.
// The logic here is as follows:
// 1. if an atom has unwind info record that is not DWARF, FDE is marked dead
@@ -902,12 +879,10 @@ fn synthesiseNullUnwindRecords(self: *Object, macho_file: *MachO) !void {
}
} else {
// Synthesise new unwind info record
- const fde_data = fde.getData(macho_file);
- const atom_size = mem.readInt(u64, fde_data[16..][0..8], .little);
const rec_index = try macho_file.addUnwindRecord();
const rec = macho_file.getUnwindRecord(rec_index);
try self.unwind_records.append(gpa, rec_index);
- rec.length = @intCast(atom_size);
+ rec.length = @intCast(meta.size);
rec.atom = fde.atom;
rec.atom_offset = fde.atom_offset;
rec.fde = fde_index;
@@ -930,6 +905,31 @@ fn synthesiseNullUnwindRecords(self: *Object, macho_file: *MachO) !void {
rec.file = self.index;
}
}
+
+ const sortFn = struct {
+ fn sortFn(ctx: *MachO, lhs_index: UnwindInfo.Record.Index, rhs_index: UnwindInfo.Record.Index) bool {
+ const lhs = ctx.getUnwindRecord(lhs_index);
+ const rhs = ctx.getUnwindRecord(rhs_index);
+ const lhsa = lhs.getAtom(ctx);
+ const rhsa = rhs.getAtom(ctx);
+ return lhsa.getInputAddress(ctx) + lhs.atom_offset < rhsa.getInputAddress(ctx) + rhs.atom_offset;
+ }
+ }.sortFn;
+ mem.sort(UnwindInfo.Record.Index, self.unwind_records.items, macho_file, sortFn);
+
+ // Associate unwind records to atoms
+ var next_cu: u32 = 0;
+ while (next_cu < self.unwind_records.items.len) {
+ const start = next_cu;
+ const rec_index = self.unwind_records.items[start];
+ const rec = macho_file.getUnwindRecord(rec_index);
+ while (next_cu < self.unwind_records.items.len and
+ macho_file.getUnwindRecord(self.unwind_records.items[next_cu]).atom == rec.atom) : (next_cu += 1)
+ {}
+
+ const atom = rec.getAtom(macho_file);
+ atom.unwind_records = .{ .pos = start, .len = next_cu - start };
+ }
}
fn initPlatform(self: *Object) void {
@@ -1566,6 +1566,14 @@ fn getString(self: Object, off: u32) [:0]const u8 {
return mem.sliceTo(@as([*:0]const u8, @ptrCast(self.strtab.ptr + off)), 0);
}
+pub fn hasUnwindRecords(self: Object) bool {
+ return self.unwind_records.items.len > 0;
+}
+
+pub fn hasEhFrameRecords(self: Object) bool {
+ return self.cies.items.len > 0;
+}
+
/// TODO handle multiple CUs
pub fn hasDebugInfo(self: Object) bool {
if (self.dwarf_info) |dw| {
src/link/MachO/relocatable.zig
@@ -143,7 +143,7 @@ fn initOutputSections(macho_file: *MachO) !void {
}
const needs_unwind_info = for (macho_file.objects.items) |index| {
- if (macho_file.getFile(index).?.object.compact_unwind_sect_index != null) break true;
+ if (macho_file.getFile(index).?.object.hasUnwindRecords()) break true;
} else false;
if (needs_unwind_info) {
macho_file.unwind_info_sect_index = try macho_file.addSection("__LD", "__compact_unwind", .{
@@ -152,7 +152,7 @@ fn initOutputSections(macho_file: *MachO) !void {
}
const needs_eh_frame = for (macho_file.objects.items) |index| {
- if (macho_file.getFile(index).?.object.eh_frame_sect_index != null) break true;
+ if (macho_file.getFile(index).?.object.hasEhFrameRecords()) break true;
} else false;
if (needs_eh_frame) {
assert(needs_unwind_info);
src/link/MachO.zig
@@ -1862,14 +1862,14 @@ fn initSyntheticSections(self: *MachO) !void {
}
const needs_unwind_info = for (self.objects.items) |index| {
- if (self.getFile(index).?.object.compact_unwind_sect_index != null) break true;
+ if (self.getFile(index).?.object.hasUnwindRecords()) break true;
} else false;
if (needs_unwind_info) {
self.unwind_info_sect_index = try self.addSection("__TEXT", "__unwind_info", .{});
}
const needs_eh_frame = for (self.objects.items) |index| {
- if (self.getFile(index).?.object.eh_frame_sect_index != null) break true;
+ if (self.getFile(index).?.object.hasEhFrameRecords()) break true;
} else false;
if (needs_eh_frame) {
assert(needs_unwind_info);