authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-12-27 21:51:40+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-12-31 10:19:04+01:00
logd4725cb40bf378959f254ba447a47f5e2f5726fa
tree2c515f117cfd143b8d9d1b5dc4553cb709fc713f
parent3174508903ed0cfdd06a395dd19b6fc2cbc395ed

macho: prealloc space for debug sections in dSym


2 files changed, 192 insertions(+), 3 deletions(-)

src/link/MachO.zig+4
......@@ -108,6 +108,9 @@ dyld_stub_binder_index: ?u16 = null,
108108/// Table of symbol names aka the string table.
109109string_table: std.ArrayListUnmanaged(u8) = .{},
110110
111/// Table of debug symbol names aka the debug string table.
112debug_string_table: std.ArrayListUnmanaged(u8) = .{},
113
111114/// Table of trampolines to the actual symbols in __text section.
112115offset_table: std.ArrayListUnmanaged(u64) = .{},
113116
......@@ -980,6 +983,7 @@ pub fn deinit(self: *MachO) void {
980983 self.text_block_free_list.deinit(self.base.allocator);
981984 self.offset_table.deinit(self.base.allocator);
982985 self.offset_table_free_list.deinit(self.base.allocator);
986 self.debug_string_table.deinit(self.base.allocator);
983987 self.string_table.deinit(self.base.allocator);
984988 self.undef_symbols.deinit(self.base.allocator);
985989 self.global_symbols.deinit(self.base.allocator);
src/link/MachO/DebugSymbols.zig+188-3
......@@ -15,9 +15,12 @@ const MachO = @import("../MachO.zig");
1515const satMul = MachO.satMul;
1616const alloc_num = MachO.alloc_num;
1717const alloc_den = MachO.alloc_den;
18const makeStaticString = MachO.makeStaticString;
1819
1920usingnamespace @import("commands.zig");
2021
22const page_size: u16 = 0x1000;
23
2124base: *MachO,
2225file: fs.File,
2326
......@@ -44,12 +47,25 @@ uuid_cmd_index: ?u16 = null,
4447/// Index into __TEXT,__text section.
4548text_section_index: ?u16 = null,
4649
47linkedit_off: u16 = 0x1000,
48linkedit_size: u16 = 0x1000,
50linkedit_off: u16 = page_size,
51linkedit_size: u16 = page_size,
52
53debug_info_section_index: ?u16 = null,
54debug_abbrev_section_index: ?u16 = null,
55debug_str_section_index: ?u16 = null,
56debug_aranges_section_index: ?u16 = null,
57debug_line_section_index: ?u16 = null,
58
59debug_abbrev_table_offset: ?u64 = null,
4960
5061header_dirty: bool = false,
5162load_commands_dirty: bool = false,
5263string_table_dirty: bool = false,
64debug_string_table_dirty: bool = false,
65debug_abbrev_section_dirty: bool = false,
66debug_aranges_section_dirty: bool = false,
67debug_info_header_dirty: bool = false,
68debug_line_header_dirty: bool = false,
5369
5470/// You must call this function *after* `MachO.populateMissingMetadata()`
5571/// has been called to get a viable debug symbols output.
......@@ -98,7 +114,6 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
98114 .strsize = base_cmd.strsize,
99115 },
100116 });
101 try self.writeLocalSymbol(0);
102117 self.header_dirty = true;
103118 self.load_commands_dirty = true;
104119 self.string_table_dirty = true;
......@@ -139,6 +154,176 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
139154 self.header_dirty = true;
140155 self.load_commands_dirty = true;
141156 }
157 if (self.dwarf_segment_cmd_index == null) {
158 self.dwarf_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
159
160 const linkedit = self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
161 const ideal_size: u16 = 200 + 128 + 160 + 250;
162 const needed_size = mem.alignForwardGeneric(u64, satMul(ideal_size, alloc_num) / alloc_den, page_size);
163 const off = linkedit.inner.fileoff + linkedit.inner.filesize;
164 const vmaddr = linkedit.inner.vmaddr + linkedit.inner.vmsize;
165
166 log.debug("found dSym __DWARF segment free space 0x{x} to 0x{x}", .{ off, off + needed_size });
167
168 try self.load_commands.append(allocator, .{
169 .Segment = SegmentCommand.empty(.{
170 .cmd = macho.LC_SEGMENT_64,
171 .cmdsize = @sizeOf(macho.segment_command_64),
172 .segname = makeStaticString("__DWARF"),
173 .vmaddr = vmaddr,
174 .vmsize = needed_size,
175 .fileoff = off,
176 .filesize = needed_size,
177 .maxprot = 0,
178 .initprot = 0,
179 .nsects = 0,
180 .flags = 0,
181 }),
182 });
183 self.header_dirty = true;
184 self.load_commands_dirty = true;
185 }
186 if (self.debug_str_section_index == null) {
187 const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment;
188 self.debug_str_section_index = @intCast(u16, dwarf_segment.sections.items.len);
189 assert(self.base.debug_string_table.items.len == 0);
190
191 const file_size_hint = 200;
192 const p_align = 1;
193 const off = dwarf_segment.findFreeSpace(file_size_hint, p_align, null);
194
195 log.debug("found dSym __debug_strtab free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });
196
197 try dwarf_segment.addSection(allocator, .{
198 .sectname = makeStaticString("__debug_str"),
199 .segname = makeStaticString("__DWARF"),
200 .addr = dwarf_segment.inner.vmaddr + off,
201 .size = @intCast(u32, self.base.debug_string_table.items.len),
202 .offset = @intCast(u32, off),
203 .@"align" = 1,
204 .reloff = 0,
205 .nreloc = 0,
206 .flags = macho.S_REGULAR,
207 .reserved1 = 0,
208 .reserved2 = 0,
209 .reserved3 = 0,
210 });
211 self.header_dirty = true;
212 self.load_commands_dirty = true;
213 self.debug_string_table_dirty = true;
214 }
215 if (self.debug_info_section_index == null) {
216 const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment;
217 self.debug_info_section_index = @intCast(u16, dwarf_segment.sections.items.len);
218
219 const file_size_hint = 200;
220 const p_align = 1;
221 const off = dwarf_segment.findFreeSpace(file_size_hint, p_align, null);
222
223 log.debug("found dSym __debug_info free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });
224
225 try dwarf_segment.addSection(allocator, .{
226 .sectname = makeStaticString("__debug_info"),
227 .segname = makeStaticString("__DWARF"),
228 .addr = dwarf_segment.inner.vmaddr + off,
229 .size = file_size_hint,
230 .offset = @intCast(u32, off),
231 .@"align" = p_align,
232 .reloff = 0,
233 .nreloc = 0,
234 .flags = macho.S_REGULAR,
235 .reserved1 = 0,
236 .reserved2 = 0,
237 .reserved3 = 0,
238 });
239 self.header_dirty = true;
240 self.load_commands_dirty = true;
241 self.debug_info_header_dirty = true;
242 }
243 if (self.debug_abbrev_section_index == null) {
244 const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment;
245 self.debug_abbrev_section_index = @intCast(u16, dwarf_segment.sections.items.len);
246
247 const file_size_hint = 128;
248 const p_align = 1;
249 const off = dwarf_segment.findFreeSpace(file_size_hint, p_align, null);
250
251 log.debug("found dSym __debug_abbrev free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });
252
253 try dwarf_segment.addSection(allocator, .{
254 .sectname = makeStaticString("__debug_abbrev"),
255 .segname = makeStaticString("__DWARF"),
256 .addr = dwarf_segment.inner.vmaddr + off,
257 .size = file_size_hint,
258 .offset = @intCast(u32, off),
259 .@"align" = p_align,
260 .reloff = 0,
261 .nreloc = 0,
262 .flags = macho.S_REGULAR,
263 .reserved1 = 0,
264 .reserved2 = 0,
265 .reserved3 = 0,
266 });
267 self.header_dirty = true;
268 self.load_commands_dirty = true;
269 self.debug_abbrev_section_dirty = true;
270 }
271 if (self.debug_aranges_section_index == null) {
272 const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment;
273 self.debug_aranges_section_index = @intCast(u16, dwarf_segment.sections.items.len);
274
275 const file_size_hint = 160;
276 const p_align = 16;
277 const off = dwarf_segment.findFreeSpace(file_size_hint, p_align, null);
278
279 log.debug("found dSym __debug_aranges free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });
280
281 try dwarf_segment.addSection(allocator, .{
282 .sectname = makeStaticString("__debug_aranges"),
283 .segname = makeStaticString("__DWARF"),
284 .addr = dwarf_segment.inner.vmaddr + off,
285 .size = file_size_hint,
286 .offset = @intCast(u32, off),
287 .@"align" = p_align,
288 .reloff = 0,
289 .nreloc = 0,
290 .flags = macho.S_REGULAR,
291 .reserved1 = 0,
292 .reserved2 = 0,
293 .reserved3 = 0,
294 });
295 self.header_dirty = true;
296 self.load_commands_dirty = true;
297 self.debug_aranges_section_dirty = true;
298 }
299 if (self.debug_line_section_index == null) {
300 const dwarf_segment = &self.load_commands.items[self.dwarf_segment_cmd_index.?].Segment;
301 self.debug_line_section_index = @intCast(u16, dwarf_segment.sections.items.len);
302
303 const file_size_hint = 250;
304 const p_align = 1;
305 const off = dwarf_segment.findFreeSpace(file_size_hint, p_align, null);
306
307 log.debug("found dSym __debug_line free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });
308
309 try dwarf_segment.addSection(allocator, .{
310 .sectname = makeStaticString("__debug_line"),
311 .segname = makeStaticString("__DWARF"),
312 .addr = dwarf_segment.inner.vmaddr + off,
313 .size = file_size_hint,
314 .offset = @intCast(u32, off),
315 .@"align" = p_align,
316 .reloff = 0,
317 .nreloc = 0,
318 .flags = macho.S_REGULAR,
319 .reserved1 = 0,
320 .reserved2 = 0,
321 .reserved3 = 0,
322 });
323 self.header_dirty = true;
324 self.load_commands_dirty = true;
325 self.debug_line_header_dirty = true;
326 }
142327}
143328
144329pub fn flush(self: *DebugSymbols, allocator: *Allocator) !void {