aboutsummaryrefslogtreecommitdiff
path: root/src/link/MachO.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/link/MachO.zig')
-rw-r--r--src/link/MachO.zig134
1 files changed, 111 insertions, 23 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index 00b456eb12..aac0536816 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -103,6 +103,14 @@ zig_const_sect_index: ?u8 = null,
zig_data_sect_index: ?u8 = null,
zig_bss_sect_index: ?u8 = null,
+/// Tracked DWARF section headers that apply only when we emit relocatable.
+/// For executable and loadable images, DWARF is tracked directly by dSYM bundle object.
+debug_info_sect_index: ?u8 = null,
+debug_abbrev_sect_index: ?u8 = null,
+debug_str_sect_index: ?u8 = null,
+debug_aranges_sect_index: ?u8 = null,
+debug_line_sect_index: ?u8 = null,
+
has_tlv: bool = false,
binds_to_weak: bool = false,
weak_defines: bool = false,
@@ -259,32 +267,11 @@ pub fn createEmpty(
try zo.init(self);
try self.initMetadata(.{
+ .emit = emit,
+ .zo = zo,
.symbol_count_hint = options.symbol_count_hint,
.program_code_size_hint = options.program_code_size_hint,
});
-
- if (zo.dwarf != null and !self.base.isRelocatable()) {
- // Create dSYM bundle.
- log.debug("creating {s}.dSYM bundle", .{emit.sub_path});
-
- const sep = fs.path.sep_str;
- const d_sym_path = try std.fmt.allocPrint(
- arena,
- "{s}.dSYM" ++ sep ++ "Contents" ++ sep ++ "Resources" ++ sep ++ "DWARF",
- .{emit.sub_path},
- );
-
- var d_sym_bundle = try emit.directory.handle.makeOpenPath(d_sym_path, .{});
- defer d_sym_bundle.close();
-
- const d_sym_file = try d_sym_bundle.createFile(emit.sub_path, .{
- .truncate = false,
- .read = true,
- });
-
- self.d_sym = .{ .allocator = gpa, .file = d_sym_file };
- try self.d_sym.?.initMetadata(self);
- }
}
}
@@ -2007,6 +1994,11 @@ pub fn sortSections(self: *MachO) !void {
&self.eh_frame_sect_index,
&self.unwind_info_sect_index,
&self.objc_stubs_sect_index,
+ &self.debug_info_sect_index,
+ &self.debug_str_sect_index,
+ &self.debug_line_sect_index,
+ &self.debug_abbrev_sect_index,
+ &self.debug_info_sect_index,
}) |maybe_index| {
if (maybe_index.*) |*index| {
index.* = backlinks[index.*];
@@ -3317,6 +3309,8 @@ fn copyRangeAllZeroOut(self: *MachO, old_offset: u64, new_offset: u64, size: u64
}
const InitMetadataOptions = struct {
+ emit: Compilation.Emit,
+ zo: *ZigObject,
symbol_count_hint: u64,
program_code_size_hint: u64,
};
@@ -3385,6 +3379,31 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void {
.prot = macho.PROT.READ | macho.PROT.WRITE,
});
}
+
+ if (options.zo.dwarf) |_| {
+ // Create dSYM bundle.
+ log.debug("creating {s}.dSYM bundle", .{options.emit.sub_path});
+
+ const gpa = self.base.comp.gpa;
+ const sep = fs.path.sep_str;
+ const d_sym_path = try std.fmt.allocPrint(
+ gpa,
+ "{s}.dSYM" ++ sep ++ "Contents" ++ sep ++ "Resources" ++ sep ++ "DWARF",
+ .{options.emit.sub_path},
+ );
+ defer gpa.free(d_sym_path);
+
+ var d_sym_bundle = try options.emit.directory.handle.makeOpenPath(d_sym_path, .{});
+ defer d_sym_bundle.close();
+
+ const d_sym_file = try d_sym_bundle.createFile(options.emit.sub_path, .{
+ .truncate = false,
+ .read = true,
+ });
+
+ self.d_sym = .{ .allocator = gpa, .file = d_sym_file };
+ try self.d_sym.?.initMetadata(self);
+ }
}
const appendSect = struct {
@@ -3462,6 +3481,44 @@ fn initMetadata(self: *MachO, options: InitMetadataOptions) !void {
appendSect(self, self.zig_bss_sect_index.?, self.zig_bss_seg_index.?);
}
}
+
+ if (self.base.isRelocatable()) {
+ {
+ self.debug_str_sect_index = try self.addSection("__DWARF", "__debug_str", .{
+ .flags = macho.S_ATTR_DEBUG,
+ });
+ try allocSect(self, self.debug_str_sect_index.?, 200);
+ }
+
+ {
+ self.debug_info_sect_index = try self.addSection("__DWARF", "__debug_info", .{
+ .flags = macho.S_ATTR_DEBUG,
+ });
+ try allocSect(self, self.debug_info_sect_index.?, 200);
+ }
+
+ {
+ self.debug_abbrev_sect_index = try self.addSection("__DWARF", "__debug_abbrev", .{
+ .flags = macho.S_ATTR_DEBUG,
+ });
+ try allocSect(self, self.debug_abbrev_sect_index.?, 128);
+ }
+
+ {
+ self.debug_aranges_sect_index = try self.addSection("__DWARF", "__debug_aranges", .{
+ .alignment = 4,
+ .flags = macho.S_ATTR_DEBUG,
+ });
+ try allocSect(self, self.debug_aranges_sect_index.?, 160);
+ }
+
+ {
+ self.debug_line_sect_index = try self.addSection("__DWARF", "__debug_line", .{
+ .flags = macho.S_ATTR_DEBUG,
+ });
+ try allocSect(self, self.debug_line_sect_index.?, 250);
+ }
+ }
}
pub fn growSection(self: *MachO, sect_index: u8, needed_size: u64) !void {
@@ -3549,6 +3606,22 @@ fn growSectionRelocatable(self: *MachO, sect_index: u8, needed_size: u64) !void
sect.size = needed_size;
}
+pub fn markDirty(self: *MachO, sect_index: u8) void {
+ if (self.getZigObject()) |zo| {
+ if (self.debug_info_sect_index.? == sect_index) {
+ zo.debug_info_header_dirty = true;
+ } else if (self.debug_line_sect_index.? == sect_index) {
+ zo.debug_line_header_dirty = true;
+ } else if (self.debug_abbrev_sect_index.? == sect_index) {
+ zo.debug_abbrev_dirty = true;
+ } else if (self.debug_str_sect_index.? == sect_index) {
+ zo.debug_strtab_dirty = true;
+ } else if (self.debug_aranges_sect_index.? == sect_index) {
+ zo.debug_aranges_dirty = true;
+ }
+ }
+}
+
pub fn getTarget(self: MachO) std.Target {
return self.base.comp.root_mod.resolved_target.result;
}
@@ -3624,6 +3697,21 @@ pub fn isZigSection(self: MachO, sect_id: u8) bool {
return false;
}
+pub fn isDebugSection(self: MachO, sect_id: u8) bool {
+ inline for (&[_]?u8{
+ self.debug_info_sect_index,
+ self.debug_abbrev_sect_index,
+ self.debug_str_sect_index,
+ self.debug_aranges_sect_index,
+ self.debug_line_sect_index,
+ }) |maybe_index| {
+ if (maybe_index) |index| {
+ if (index == sect_id) return true;
+ }
+ }
+ return false;
+}
+
pub fn addSegment(self: *MachO, name: []const u8, opts: struct {
vmaddr: u64 = 0,
vmsize: u64 = 0,