authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-12-27 10:59:54+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-12-31 10:19:04+01:00
logd9ce7a021bfeca7ba4b4e478617b4da590264a99
tree4b4bc5715ed1524a82846e1d087f4cb5a5464c22
parenta7bae1b8579475eaf4a25907405d85b98d29977d

macho: copy snapshots of segment commands


2 files changed, 76 insertions(+), 4 deletions(-)

src/link/MachO.zig+8-2
......@@ -1427,7 +1427,7 @@ pub fn populateMissingMetadata(self: *MachO) !void {
14271427 .addr = text_segment.inner.vmaddr + off,
14281428 .size = needed_size,
14291429 .offset = @intCast(u32, off),
1430 .@"align" = @sizeOf(u64),
1430 .@"align" = 3, // 2^@sizeOf(u64)
14311431 .reloff = 0,
14321432 .nreloc = 0,
14331433 .flags = flags,
......@@ -1749,8 +1749,14 @@ fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64,
17491749
17501750 self.last_text_block = text_block;
17511751 text_section.size = needed_size;
1752
17531752 self.load_commands_dirty = true; // TODO Make more granular.
1753
1754 if (self.d_sym) |*ds| {
1755 const debug_text_seg = &ds.load_commands.items[ds.text_segment_cmd_index.?].Segment;
1756 const debug_text_sect = &debug_text_seg.sections.items[ds.text_section_index.?];
1757 debug_text_sect.size = needed_size;
1758 ds.load_commands_dirty = true;
1759 }
17541760 }
17551761 text_block.size = new_block_size;
17561762
src/link/MachO/DebugSymbols.zig+68-2
......@@ -26,17 +26,20 @@ load_commands: std.ArrayListUnmanaged(LoadCommand) = .{},
2626pagezero_segment_cmd_index: ?u16 = null,
2727/// __TEXT segment
2828text_segment_cmd_index: ?u16 = null,
29/// __DWARF segment
30dwarf_segment_cmd_index: ?u16 = null,
3129/// __DATA segment
3230data_segment_cmd_index: ?u16 = null,
3331/// __LINKEDIT segment
3432linkedit_segment_cmd_index: ?u16 = null,
33/// __DWARF segment
34dwarf_segment_cmd_index: ?u16 = null,
3535/// Symbol table
3636symtab_cmd_index: ?u16 = null,
3737/// UUID load command
3838uuid_cmd_index: ?u16 = null,
3939
40/// Index into __TEXT,__text section.
41text_section_index: ?u16 = null,
42
4043header_dirty: bool = false,
4144load_commands_dirty: bool = false,
4245
......@@ -58,6 +61,22 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
5861 self.header = header;
5962 self.header_dirty = true;
6063 }
64 if (self.pagezero_segment_cmd_index == null) {
65 self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
66 const base_cmd = self.base.load_commands.items[self.base.pagezero_segment_cmd_index.?].Segment;
67 try self.copySegmentCommand(allocator, base_cmd);
68 }
69 if (self.text_segment_cmd_index == null) {
70 self.text_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
71 const base_cmd = self.base.load_commands.items[self.base.text_segment_cmd_index.?].Segment;
72 try self.copySegmentCommand(allocator, base_cmd);
73 }
74 if (self.data_segment_cmd_index == null) outer: {
75 if (self.base.data_segment_cmd_index == null) break :outer; // __DATA is optional
76 self.data_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
77 const base_cmd = self.base.load_commands.items[self.base.data_segment_cmd_index.?].Segment;
78 try self.copySegmentCommand(allocator, base_cmd);
79 }
6180 if (self.uuid_cmd_index == null) {
6281 const base_cmd = self.base.load_commands.items[self.base.uuid_cmd_index.?];
6382 self.uuid_cmd_index = @intCast(u16, self.load_commands.items.len);
......@@ -81,6 +100,53 @@ pub fn deinit(self: *DebugSymbols, allocator: *Allocator) void {
81100 self.file.close();
82101}
83102
103fn copySegmentCommand(self: *DebugSymbols, allocator: *Allocator, base_cmd: SegmentCommand) !void {
104 var cmd = SegmentCommand.empty(.{
105 .cmd = macho.LC_SEGMENT_64,
106 .cmdsize = base_cmd.inner.cmdsize,
107 .segname = undefined,
108 .vmaddr = base_cmd.inner.vmaddr,
109 .vmsize = base_cmd.inner.vmsize,
110 .fileoff = 0,
111 .filesize = 0,
112 .maxprot = base_cmd.inner.maxprot,
113 .initprot = base_cmd.inner.initprot,
114 .nsects = base_cmd.inner.nsects,
115 .flags = base_cmd.inner.flags,
116 });
117 mem.copy(u8, &cmd.inner.segname, &base_cmd.inner.segname);
118
119 try cmd.sections.ensureCapacity(allocator, cmd.inner.nsects);
120 for (base_cmd.sections.items) |base_sect, i| {
121 var sect = macho.section_64{
122 .sectname = undefined,
123 .segname = undefined,
124 .addr = base_sect.addr,
125 .size = base_sect.size,
126 .offset = 0,
127 .@"align" = base_sect.@"align",
128 .reloff = 0,
129 .nreloc = 0,
130 .flags = base_sect.flags,
131 .reserved1 = base_sect.reserved1,
132 .reserved2 = base_sect.reserved2,
133 .reserved3 = base_sect.reserved3,
134 };
135 mem.copy(u8, &sect.sectname, &base_sect.sectname);
136 mem.copy(u8, &sect.segname, &base_sect.segname);
137
138 if (self.base.text_section_index.? == i) {
139 self.text_section_index = @intCast(u16, i);
140 }
141
142 cmd.sections.appendAssumeCapacity(sect);
143 }
144
145 try self.load_commands.append(allocator, .{ .Segment = cmd });
146 self.header_dirty = true;
147 self.load_commands_dirty = true;
148}
149
84150/// Writes all load commands and section headers.
85151fn writeLoadCommands(self: *DebugSymbols, allocator: *Allocator) !void {
86152 if (!self.load_commands_dirty) return;