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 {...@@ -1427,7 +1427,7 @@ pub fn populateMissingMetadata(self: *MachO) !void {
1427 .addr = text_segment.inner.vmaddr + off,1427 .addr = text_segment.inner.vmaddr + off,
1428 .size = needed_size,1428 .size = needed_size,
1429 .offset = @intCast(u32, off),1429 .offset = @intCast(u32, off),
1430 .@"align" = @sizeOf(u64),1430 .@"align" = 3, // 2^@sizeOf(u64)
1431 .reloff = 0,1431 .reloff = 0,
1432 .nreloc = 0,1432 .nreloc = 0,
1433 .flags = flags,1433 .flags = flags,
...@@ -1749,8 +1749,14 @@ fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64,...@@ -1749,8 +1749,14 @@ fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64,
17491749
1750 self.last_text_block = text_block;1750 self.last_text_block = text_block;
1751 text_section.size = needed_size;1751 text_section.size = needed_size;
1752
1753 self.load_commands_dirty = true; // TODO Make more granular.1752 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 }
1754 }1760 }
1755 text_block.size = new_block_size;1761 text_block.size = new_block_size;
17561762
src/link/MachO/DebugSymbols.zig+68-2
...@@ -26,17 +26,20 @@ load_commands: std.ArrayListUnmanaged(LoadCommand) = .{},...@@ -26,17 +26,20 @@ load_commands: std.ArrayListUnmanaged(LoadCommand) = .{},
26pagezero_segment_cmd_index: ?u16 = null,26pagezero_segment_cmd_index: ?u16 = null,
27/// __TEXT segment27/// __TEXT segment
28text_segment_cmd_index: ?u16 = null,28text_segment_cmd_index: ?u16 = null,
29/// __DWARF segment
30dwarf_segment_cmd_index: ?u16 = null,
31/// __DATA segment29/// __DATA segment
32data_segment_cmd_index: ?u16 = null,30data_segment_cmd_index: ?u16 = null,
33/// __LINKEDIT segment31/// __LINKEDIT segment
34linkedit_segment_cmd_index: ?u16 = null,32linkedit_segment_cmd_index: ?u16 = null,
33/// __DWARF segment
34dwarf_segment_cmd_index: ?u16 = null,
35/// Symbol table35/// Symbol table
36symtab_cmd_index: ?u16 = null,36symtab_cmd_index: ?u16 = null,
37/// UUID load command37/// UUID load command
38uuid_cmd_index: ?u16 = null,38uuid_cmd_index: ?u16 = null,
3939
40/// Index into __TEXT,__text section.
41text_section_index: ?u16 = null,
42
40header_dirty: bool = false,43header_dirty: bool = false,
41load_commands_dirty: bool = false,44load_commands_dirty: bool = false,
4245
...@@ -58,6 +61,22 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void...@@ -58,6 +61,22 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
58 self.header = header;61 self.header = header;
59 self.header_dirty = true;62 self.header_dirty = true;
60 }63 }
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 }
61 if (self.uuid_cmd_index == null) {80 if (self.uuid_cmd_index == null) {
62 const base_cmd = self.base.load_commands.items[self.base.uuid_cmd_index.?];81 const base_cmd = self.base.load_commands.items[self.base.uuid_cmd_index.?];
63 self.uuid_cmd_index = @intCast(u16, self.load_commands.items.len);82 self.uuid_cmd_index = @intCast(u16, self.load_commands.items.len);
...@@ -81,6 +100,53 @@ pub fn deinit(self: *DebugSymbols, allocator: *Allocator) void {...@@ -81,6 +100,53 @@ pub fn deinit(self: *DebugSymbols, allocator: *Allocator) void {
81 self.file.close();100 self.file.close();
82}101}
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
84/// Writes all load commands and section headers.150/// Writes all load commands and section headers.
85fn writeLoadCommands(self: *DebugSymbols, allocator: *Allocator) !void {151fn writeLoadCommands(self: *DebugSymbols, allocator: *Allocator) !void {
86 if (!self.load_commands_dirty) return;152 if (!self.load_commands_dirty) return;