authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-08 10:19:52+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-09 09:24:25+01:00
log05e221796a7c60f26c4c7bc996f12e1392c83d97
tree03e3fa5caa6156887a36d16daf522d44c7d7195d
parent4c38ba7d1b64ac69bbb7cc612503bd32661cbbe5

dwarf+d_sym: move logic for growing section to d_sym


2 files changed, 55 insertions(+), 30 deletions(-)

src/link/Dwarf.zig+11-30
...@@ -1106,7 +1106,7 @@ pub fn commitDeclState(...@@ -1106,7 +1106,7 @@ pub fn commitDeclState(
1106 .macho => {1106 .macho => {
1107 const macho_file = self.bin_file.cast(File.MachO).?;1107 const macho_file = self.bin_file.cast(File.MachO).?;
1108 const d_sym = &macho_file.d_sym.?;1108 const d_sym = &macho_file.d_sym.?;
1109 const debug_line_sect = &d_sym.sections.items[d_sym.debug_line_section_index.?];1109 const debug_line_sect = d_sym.getSectionPtr(d_sym.debug_line_section_index.?);
1110 const file_pos = debug_line_sect.offset + src_fn.off;1110 const file_pos = debug_line_sect.offset + src_fn.off;
1111 try pwriteDbgLineNops(d_sym.file, file_pos, 0, &[0]u8{}, src_fn.len);1111 try pwriteDbgLineNops(d_sym.file, file_pos, 0, &[0]u8{}, src_fn.len);
1112 },1112 },
...@@ -1187,7 +1187,7 @@ pub fn commitDeclState(...@@ -1187,7 +1187,7 @@ pub fn commitDeclState(
1187 .macho => {1187 .macho => {
1188 const macho_file = self.bin_file.cast(File.MachO).?;1188 const macho_file = self.bin_file.cast(File.MachO).?;
1189 const d_sym = &macho_file.d_sym.?;1189 const d_sym = &macho_file.d_sym.?;
1190 const debug_line_sect = &d_sym.sections.items[d_sym.debug_line_section_index.?];1190 const debug_line_sect = d_sym.getSectionPtr(d_sym.debug_line_section_index.?);
1191 if (needed_size != debug_line_sect.size) {1191 if (needed_size != debug_line_sect.size) {
1192 if (needed_size > d_sym.allocatedSize(debug_line_sect.offset)) {1192 if (needed_size > d_sym.allocatedSize(debug_line_sect.offset)) {
1193 const new_offset = d_sym.findFreeSpace(needed_size, 1);1193 const new_offset = d_sym.findFreeSpace(needed_size, 1);
...@@ -1381,7 +1381,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom: *Atom, len: u32) !void {...@@ -1381,7 +1381,7 @@ fn updateDeclDebugInfoAllocation(self: *Dwarf, atom: *Atom, len: u32) !void {
1381 .macho => {1381 .macho => {
1382 const macho_file = self.bin_file.cast(File.MachO).?;1382 const macho_file = self.bin_file.cast(File.MachO).?;
1383 const d_sym = &macho_file.d_sym.?;1383 const d_sym = &macho_file.d_sym.?;
1384 const debug_info_sect = &d_sym.sections.items[d_sym.debug_info_section_index.?];1384 const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?);
1385 const file_pos = debug_info_sect.offset + atom.off;1385 const file_pos = debug_info_sect.offset + atom.off;
1386 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, &[0]u8{}, atom.len, false);1386 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, &[0]u8{}, atom.len, false);
1387 },1387 },
...@@ -1477,29 +1477,10 @@ fn writeDeclDebugInfo(self: *Dwarf, atom: *Atom, dbg_info_buf: []const u8) !void...@@ -1477,29 +1477,10 @@ fn writeDeclDebugInfo(self: *Dwarf, atom: *Atom, dbg_info_buf: []const u8) !void
1477 .macho => {1477 .macho => {
1478 const macho_file = self.bin_file.cast(File.MachO).?;1478 const macho_file = self.bin_file.cast(File.MachO).?;
1479 const d_sym = &macho_file.d_sym.?;1479 const d_sym = &macho_file.d_sym.?;
1480 const debug_info_sect = &d_sym.sections.items[d_sym.debug_info_section_index.?];1480 const sect_index = d_sym.debug_info_section_index.?;
1481 if (needed_size != debug_info_sect.size) {1481 try d_sym.growSection(sect_index, needed_size);
1482 if (needed_size > d_sym.allocatedSize(debug_info_sect.offset)) {1482 const sect = d_sym.getSection(sect_index);
1483 const new_offset = d_sym.findFreeSpace(needed_size, 1);1483 const file_pos = sect.offset + atom.off;
1484 const existing_size = last_decl.off;
1485 std.log.scoped(.dsym).debug("moving __debug_info section: {} bytes from 0x{x} to 0x{x}", .{
1486 existing_size,
1487 debug_info_sect.offset,
1488 new_offset,
1489 });
1490 const amt = try d_sym.file.copyRangeAll(
1491 debug_info_sect.offset,
1492 d_sym.file,
1493 new_offset,
1494 existing_size,
1495 );
1496 if (amt != existing_size) return error.InputOutput;
1497 debug_info_sect.offset = @intCast(u32, new_offset);
1498 }
1499 debug_info_sect.size = needed_size;
1500 d_sym.debug_info_header_dirty = true;
1501 }
1502 const file_pos = debug_info_sect.offset + atom.off;
1503 try pwriteDbgInfoNops(1484 try pwriteDbgInfoNops(
1504 d_sym.file,1485 d_sym.file,
1505 file_pos,1486 file_pos,
...@@ -1916,7 +1897,7 @@ pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u...@@ -1916,7 +1897,7 @@ pub fn writeDbgInfoHeader(self: *Dwarf, module: *Module, low_pc: u64, high_pc: u
1916 .macho => {1897 .macho => {
1917 const macho_file = self.bin_file.cast(File.MachO).?;1898 const macho_file = self.bin_file.cast(File.MachO).?;
1918 const d_sym = &macho_file.d_sym.?;1899 const d_sym = &macho_file.d_sym.?;
1919 const debug_info_sect = d_sym.sections.items[d_sym.debug_info_section_index.?];1900 const debug_info_sect = d_sym.getSection(d_sym.debug_info_section_index.?);
1920 const file_pos = debug_info_sect.offset;1901 const file_pos = debug_info_sect.offset;
1921 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt, false);1902 try pwriteDbgInfoNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt, false);
1922 },1903 },
...@@ -2406,7 +2387,7 @@ pub fn writeDbgLineHeader(self: *Dwarf, module: *Module) !void {...@@ -2406,7 +2387,7 @@ pub fn writeDbgLineHeader(self: *Dwarf, module: *Module) !void {
24062387
2407 const macho_file = self.bin_file.cast(File.MachO).?;2388 const macho_file = self.bin_file.cast(File.MachO).?;
2408 const d_sym = &macho_file.d_sym.?;2389 const d_sym = &macho_file.d_sym.?;
2409 const debug_line_sect = &d_sym.sections.items[d_sym.debug_line_section_index.?];2390 const debug_line_sect = d_sym.getSectionPtr(d_sym.debug_line_section_index.?);
2410 const needed_size = debug_line_sect.size + delta;2391 const needed_size = debug_line_sect.size + delta;
24112392
2412 if (needed_size > d_sym.allocatedSize(debug_line_sect.offset)) {2393 if (needed_size > d_sym.allocatedSize(debug_line_sect.offset)) {
...@@ -2463,7 +2444,7 @@ pub fn writeDbgLineHeader(self: *Dwarf, module: *Module) !void {...@@ -2463,7 +2444,7 @@ pub fn writeDbgLineHeader(self: *Dwarf, module: *Module) !void {
2463 .macho => {2444 .macho => {
2464 const macho_file = self.bin_file.cast(File.MachO).?;2445 const macho_file = self.bin_file.cast(File.MachO).?;
2465 const d_sym = &macho_file.d_sym.?;2446 const d_sym = &macho_file.d_sym.?;
2466 const debug_line_sect = d_sym.sections.items[d_sym.debug_line_section_index.?];2447 const debug_line_sect = d_sym.getSection(d_sym.debug_line_section_index.?);
2467 const file_pos = debug_line_sect.offset;2448 const file_pos = debug_line_sect.offset;
2468 try pwriteDbgLineNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt);2449 try pwriteDbgLineNops(d_sym.file, file_pos, 0, di_buf.items, jmp_amt);
2469 },2450 },
...@@ -2606,7 +2587,7 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {...@@ -2606,7 +2587,7 @@ pub fn flushModule(self: *Dwarf, module: *Module) !void {
2606 .macho => {2587 .macho => {
2607 const macho_file = self.bin_file.cast(File.MachO).?;2588 const macho_file = self.bin_file.cast(File.MachO).?;
2608 const d_sym = &macho_file.d_sym.?;2589 const d_sym = &macho_file.d_sym.?;
2609 const debug_info_sect = &d_sym.sections.items[d_sym.debug_info_section_index.?];2590 const debug_info_sect = d_sym.getSectionPtr(d_sym.debug_info_section_index.?);
2610 break :blk debug_info_sect.offset;2591 break :blk debug_info_sect.offset;
2611 },2592 },
2612 // for wasm, the offset is always 0 as we write to memory first2593 // for wasm, the offset is always 0 as we write to memory first
src/link/MachO/DebugSymbols.zig+44
...@@ -148,6 +148,40 @@ fn allocateSection(self: *DebugSymbols, sectname: []const u8, size: u64, alignme...@@ -148,6 +148,40 @@ fn allocateSection(self: *DebugSymbols, sectname: []const u8, size: u64, alignme
148 return index;148 return index;
149}149}
150150
151pub fn growSection(self: *DebugSymbols, sect_index: u8, needed_size: u32) !void {
152 const sect = self.getSectionPtr(sect_index);
153
154 if (needed_size > self.allocatedSize(sect.offset)) {
155 const new_offset = self.findFreeSpace(needed_size, 1);
156
157 log.debug("moving {s} section: {} bytes from 0x{x} to 0x{x}", .{
158 sect.sectName(),
159 sect.size,
160 sect.offset,
161 new_offset,
162 });
163
164 const amt = try self.file.copyRangeAll(
165 sect.offset,
166 self.file,
167 new_offset,
168 sect.size,
169 );
170 if (amt != sect.size) return error.InputOutput;
171 sect.offset = @intCast(u32, new_offset);
172 }
173 sect.size = needed_size;
174 self.markDirty(sect_index);
175}
176
177pub fn markDirty(self: *DebugSymbols, sect_index: u8) void {
178 if (self.debug_info_section_index.? == sect_index) {
179 self.debug_info_header_dirty = true;
180 } else if (self.debug_line_section_index.? == sect_index) {
181 self.debug_line_header_dirty = true;
182 }
183}
184
151fn detectAllocCollision(self: *DebugSymbols, start: u64, size: u64) ?u64 {185fn detectAllocCollision(self: *DebugSymbols, start: u64, size: u64) ?u64 {
152 const end = start + padToIdeal(size);186 const end = start + padToIdeal(size);
153 for (self.sections.items) |section| {187 for (self.sections.items) |section| {
...@@ -556,3 +590,13 @@ fn getLinkeditSegmentPtr(self: *DebugSymbols) *macho.segment_command_64 {...@@ -556,3 +590,13 @@ fn getLinkeditSegmentPtr(self: *DebugSymbols) *macho.segment_command_64 {
556 const index = self.linkedit_segment_cmd_index.?;590 const index = self.linkedit_segment_cmd_index.?;
557 return &self.segments.items[index];591 return &self.segments.items[index];
558}592}
593
594pub fn getSectionPtr(self: *DebugSymbols, sect: u8) *macho.section_64 {
595 assert(sect < self.sections.items.len);
596 return &self.sections.items[sect];
597}
598
599pub fn getSection(self: DebugSymbols, sect: u8) macho.section_64 {
600 assert(sect < self.sections.items.len);
601 return self.sections.items[sect];
602}