aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2020-12-27 10:59:54 +0100
committerJakub Konka <kubkon@jakubkonka.com>2020-12-31 10:19:04 +0100
commitd9ce7a021bfeca7ba4b4e478617b4da590264a99 (patch)
tree4b4bc5715ed1524a82846e1d087f4cb5a5464c22 /src
parenta7bae1b8579475eaf4a25907405d85b98d29977d (diff)
downloadzig-d9ce7a021bfeca7ba4b4e478617b4da590264a99.tar.gz
zig-d9ce7a021bfeca7ba4b4e478617b4da590264a99.zip
macho: copy snapshots of segment commands
Diffstat (limited to 'src')
-rw-r--r--src/link/MachO.zig10
-rw-r--r--src/link/MachO/DebugSymbols.zig70
2 files changed, 76 insertions, 4 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index 510d7b74fb..90c4757979 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -1427,7 +1427,7 @@ pub fn populateMissingMetadata(self: *MachO) !void {
.addr = text_segment.inner.vmaddr + off,
.size = needed_size,
.offset = @intCast(u32, off),
- .@"align" = @sizeOf(u64),
+ .@"align" = 3, // 2^@sizeOf(u64)
.reloff = 0,
.nreloc = 0,
.flags = flags,
@@ -1749,8 +1749,14 @@ fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64,
self.last_text_block = text_block;
text_section.size = needed_size;
-
self.load_commands_dirty = true; // TODO Make more granular.
+
+ if (self.d_sym) |*ds| {
+ const debug_text_seg = &ds.load_commands.items[ds.text_segment_cmd_index.?].Segment;
+ const debug_text_sect = &debug_text_seg.sections.items[ds.text_section_index.?];
+ debug_text_sect.size = needed_size;
+ ds.load_commands_dirty = true;
+ }
}
text_block.size = new_block_size;
diff --git a/src/link/MachO/DebugSymbols.zig b/src/link/MachO/DebugSymbols.zig
index 3882eaca69..22d7e04fef 100644
--- a/src/link/MachO/DebugSymbols.zig
+++ b/src/link/MachO/DebugSymbols.zig
@@ -26,17 +26,20 @@ load_commands: std.ArrayListUnmanaged(LoadCommand) = .{},
pagezero_segment_cmd_index: ?u16 = null,
/// __TEXT segment
text_segment_cmd_index: ?u16 = null,
-/// __DWARF segment
-dwarf_segment_cmd_index: ?u16 = null,
/// __DATA segment
data_segment_cmd_index: ?u16 = null,
/// __LINKEDIT segment
linkedit_segment_cmd_index: ?u16 = null,
+/// __DWARF segment
+dwarf_segment_cmd_index: ?u16 = null,
/// Symbol table
symtab_cmd_index: ?u16 = null,
/// UUID load command
uuid_cmd_index: ?u16 = null,
+/// Index into __TEXT,__text section.
+text_section_index: ?u16 = null,
+
header_dirty: bool = false,
load_commands_dirty: bool = false,
@@ -58,6 +61,22 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
self.header = header;
self.header_dirty = true;
}
+ if (self.pagezero_segment_cmd_index == null) {
+ self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
+ const base_cmd = self.base.load_commands.items[self.base.pagezero_segment_cmd_index.?].Segment;
+ try self.copySegmentCommand(allocator, base_cmd);
+ }
+ if (self.text_segment_cmd_index == null) {
+ self.text_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
+ const base_cmd = self.base.load_commands.items[self.base.text_segment_cmd_index.?].Segment;
+ try self.copySegmentCommand(allocator, base_cmd);
+ }
+ if (self.data_segment_cmd_index == null) outer: {
+ if (self.base.data_segment_cmd_index == null) break :outer; // __DATA is optional
+ self.data_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
+ const base_cmd = self.base.load_commands.items[self.base.data_segment_cmd_index.?].Segment;
+ try self.copySegmentCommand(allocator, base_cmd);
+ }
if (self.uuid_cmd_index == null) {
const base_cmd = self.base.load_commands.items[self.base.uuid_cmd_index.?];
self.uuid_cmd_index = @intCast(u16, self.load_commands.items.len);
@@ -81,6 +100,53 @@ pub fn deinit(self: *DebugSymbols, allocator: *Allocator) void {
self.file.close();
}
+fn copySegmentCommand(self: *DebugSymbols, allocator: *Allocator, base_cmd: SegmentCommand) !void {
+ var cmd = SegmentCommand.empty(.{
+ .cmd = macho.LC_SEGMENT_64,
+ .cmdsize = base_cmd.inner.cmdsize,
+ .segname = undefined,
+ .vmaddr = base_cmd.inner.vmaddr,
+ .vmsize = base_cmd.inner.vmsize,
+ .fileoff = 0,
+ .filesize = 0,
+ .maxprot = base_cmd.inner.maxprot,
+ .initprot = base_cmd.inner.initprot,
+ .nsects = base_cmd.inner.nsects,
+ .flags = base_cmd.inner.flags,
+ });
+ mem.copy(u8, &cmd.inner.segname, &base_cmd.inner.segname);
+
+ try cmd.sections.ensureCapacity(allocator, cmd.inner.nsects);
+ for (base_cmd.sections.items) |base_sect, i| {
+ var sect = macho.section_64{
+ .sectname = undefined,
+ .segname = undefined,
+ .addr = base_sect.addr,
+ .size = base_sect.size,
+ .offset = 0,
+ .@"align" = base_sect.@"align",
+ .reloff = 0,
+ .nreloc = 0,
+ .flags = base_sect.flags,
+ .reserved1 = base_sect.reserved1,
+ .reserved2 = base_sect.reserved2,
+ .reserved3 = base_sect.reserved3,
+ };
+ mem.copy(u8, &sect.sectname, &base_sect.sectname);
+ mem.copy(u8, &sect.segname, &base_sect.segname);
+
+ if (self.base.text_section_index.? == i) {
+ self.text_section_index = @intCast(u16, i);
+ }
+
+ cmd.sections.appendAssumeCapacity(sect);
+ }
+
+ try self.load_commands.append(allocator, .{ .Segment = cmd });
+ self.header_dirty = true;
+ self.load_commands_dirty = true;
+}
+
/// Writes all load commands and section headers.
fn writeLoadCommands(self: *DebugSymbols, allocator: *Allocator) !void {
if (!self.load_commands_dirty) return;