| ... | ... | @@ -113,14 +113,6 @@ debug_str_section_index: ?u16 = null, |
| 113 | 113 | debug_aranges_section_index: ?u16 = null, |
| 114 | 114 | debug_line_section_index: ?u16 = null, |
| 115 | 115 | |
| 116 | | /// Size contribution of Zig's metadata to each debug section. |
| 117 | | /// Used to track start of metadata from input object files. |
| 118 | | debug_info_section_zig_size: u64 = 0, |
| 119 | | debug_abbrev_section_zig_size: u64 = 0, |
| 120 | | debug_str_section_zig_size: u64 = 0, |
| 121 | | debug_aranges_section_zig_size: u64 = 0, |
| 122 | | debug_line_section_zig_size: u64 = 0, |
| 123 | | |
| 124 | 116 | copy_rel_section_index: ?u16 = null, |
| 125 | 117 | dynamic_section_index: ?u16 = null, |
| 126 | 118 | dynstrtab_section_index: ?u16 = null, |
| ... | ... | @@ -170,12 +162,6 @@ symbols_free_list: std.ArrayListUnmanaged(Symbol.Index) = .{}, |
| 170 | 162 | has_text_reloc: bool = false, |
| 171 | 163 | num_ifunc_dynrelocs: usize = 0, |
| 172 | 164 | |
| 173 | | debug_strtab_dirty: bool = false, |
| 174 | | debug_abbrev_section_dirty: bool = false, |
| 175 | | debug_aranges_section_dirty: bool = false, |
| 176 | | debug_info_header_dirty: bool = false, |
| 177 | | debug_line_header_dirty: bool = false, |
| 178 | | |
| 179 | 165 | error_flags: link.File.ErrorFlags = link.File.ErrorFlags{}, |
| 180 | 166 | misc_errors: std.ArrayListUnmanaged(link.File.ErrorMsg) = .{}, |
| 181 | 167 | |
| ... | ... | @@ -696,7 +682,8 @@ pub fn initMetadata(self: *Elf) !void { |
| 696 | 682 | try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_bss_section_index.?, .{}); |
| 697 | 683 | } |
| 698 | 684 | |
| 699 | | if (self.zigObjectPtr().?.dwarf) |*dw| { |
| 685 | const zig_object = self.zigObjectPtr().?; |
| 686 | if (zig_object.dwarf) |*dw| { |
| 700 | 687 | if (self.debug_str_section_index == null) { |
| 701 | 688 | assert(dw.strtab.buffer.items.len == 0); |
| 702 | 689 | try dw.strtab.buffer.append(gpa, 0); |
| ... | ... | @@ -706,7 +693,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 706 | 693 | .flags = elf.SHF_MERGE | elf.SHF_STRINGS, |
| 707 | 694 | .entsize = 1, |
| 708 | 695 | }); |
| 709 | | self.debug_strtab_dirty = true; |
| 696 | zig_object.debug_strtab_dirty = true; |
| 710 | 697 | } |
| 711 | 698 | |
| 712 | 699 | if (self.debug_info_section_index == null) { |
| ... | ... | @@ -715,7 +702,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 715 | 702 | .size = 200, |
| 716 | 703 | .alignment = 1, |
| 717 | 704 | }); |
| 718 | | self.debug_info_header_dirty = true; |
| 705 | zig_object.debug_info_header_dirty = true; |
| 719 | 706 | } |
| 720 | 707 | |
| 721 | 708 | if (self.debug_abbrev_section_index == null) { |
| ... | ... | @@ -724,7 +711,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 724 | 711 | .size = 128, |
| 725 | 712 | .alignment = 1, |
| 726 | 713 | }); |
| 727 | | self.debug_abbrev_section_dirty = true; |
| 714 | zig_object.debug_abbrev_section_dirty = true; |
| 728 | 715 | } |
| 729 | 716 | |
| 730 | 717 | if (self.debug_aranges_section_index == null) { |
| ... | ... | @@ -733,7 +720,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 733 | 720 | .size = 160, |
| 734 | 721 | .alignment = 16, |
| 735 | 722 | }); |
| 736 | | self.debug_aranges_section_dirty = true; |
| 723 | zig_object.debug_aranges_section_dirty = true; |
| 737 | 724 | } |
| 738 | 725 | |
| 739 | 726 | if (self.debug_line_section_index == null) { |
| ... | ... | @@ -742,7 +729,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 742 | 729 | .size = 250, |
| 743 | 730 | .alignment = 1, |
| 744 | 731 | }); |
| 745 | | self.debug_line_header_dirty = true; |
| 732 | zig_object.debug_line_header_dirty = true; |
| 746 | 733 | } |
| 747 | 734 | } |
| 748 | 735 | } |
| ... | ... | @@ -833,17 +820,18 @@ pub fn growNonAllocSection( |
| 833 | 820 | } |
| 834 | 821 | |
| 835 | 822 | pub fn markDirty(self: *Elf, shdr_index: u16) void { |
| 836 | | if (self.zigObjectPtr().?.dwarf) |_| { |
| 823 | const zig_object = self.zigObjectPtr().?; |
| 824 | if (zig_object.dwarf) |_| { |
| 837 | 825 | if (self.debug_info_section_index.? == shdr_index) { |
| 838 | | self.debug_info_header_dirty = true; |
| 826 | zig_object.debug_info_header_dirty = true; |
| 839 | 827 | } else if (self.debug_line_section_index.? == shdr_index) { |
| 840 | | self.debug_line_header_dirty = true; |
| 828 | zig_object.debug_line_header_dirty = true; |
| 841 | 829 | } else if (self.debug_abbrev_section_index.? == shdr_index) { |
| 842 | | self.debug_abbrev_section_dirty = true; |
| 830 | zig_object.debug_abbrev_section_dirty = true; |
| 843 | 831 | } else if (self.debug_str_section_index.? == shdr_index) { |
| 844 | | self.debug_strtab_dirty = true; |
| 832 | zig_object.debug_strtab_dirty = true; |
| 845 | 833 | } else if (self.debug_aranges_section_index.? == shdr_index) { |
| 846 | | self.debug_aranges_section_dirty = true; |
| 834 | zig_object.debug_aranges_section_dirty = true; |
| 847 | 835 | } |
| 848 | 836 | } |
| 849 | 837 | } |
| ... | ... | @@ -1343,39 +1331,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1343 | 1331 | try self.handleAndReportParseError(obj.path, err, &parse_ctx); |
| 1344 | 1332 | } |
| 1345 | 1333 | |
| 1346 | | if (self.zigObjectPtr()) |zig_object| { |
| 1347 | | // Handle any lazy symbols that were emitted by incremental compilation. |
| 1348 | | if (zig_object.lazy_syms.getPtr(.none)) |metadata| { |
| 1349 | | const module = self.base.options.module.?; |
| 1350 | | |
| 1351 | | // Most lazy symbols can be updated on first use, but |
| 1352 | | // anyerror needs to wait for everything to be flushed. |
| 1353 | | if (metadata.text_state != .unused) zig_object.updateLazySymbol( |
| 1354 | | self, |
| 1355 | | link.File.LazySymbol.initDecl(.code, null, module), |
| 1356 | | metadata.text_symbol_index, |
| 1357 | | ) catch |err| return switch (err) { |
| 1358 | | error.CodegenFail => error.FlushFailure, |
| 1359 | | else => |e| e, |
| 1360 | | }; |
| 1361 | | if (metadata.rodata_state != .unused) zig_object.updateLazySymbol( |
| 1362 | | self, |
| 1363 | | link.File.LazySymbol.initDecl(.const_data, null, module), |
| 1364 | | metadata.rodata_symbol_index, |
| 1365 | | ) catch |err| return switch (err) { |
| 1366 | | error.CodegenFail => error.FlushFailure, |
| 1367 | | else => |e| e, |
| 1368 | | }; |
| 1369 | | } |
| 1370 | | for (zig_object.lazy_syms.values()) |*metadata| { |
| 1371 | | if (metadata.text_state != .unused) metadata.text_state = .flushed; |
| 1372 | | if (metadata.rodata_state != .unused) metadata.rodata_state = .flushed; |
| 1373 | | } |
| 1374 | | |
| 1375 | | if (zig_object.dwarf) |*dw| { |
| 1376 | | try dw.flushModule(self.base.options.module.?); |
| 1377 | | } |
| 1378 | | } |
| 1334 | if (self.zigObjectPtr()) |zig_object| try zig_object.flushModule(self); |
| 1379 | 1335 | |
| 1380 | 1336 | // Dedup shared objects |
| 1381 | 1337 | { |
| ... | ... | @@ -1437,47 +1393,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1437 | 1393 | // Scan and create missing synthetic entries such as GOT indirection. |
| 1438 | 1394 | try self.scanRelocs(); |
| 1439 | 1395 | |
| 1440 | | if (self.zigObjectPtr()) |zig_object| { |
| 1441 | | // TODO I need to re-think how to handle ZigObject's debug sections AND debug sections |
| 1442 | | // extracted from input object files correctly. |
| 1443 | | if (zig_object.dwarf) |*dw| { |
| 1444 | | if (self.debug_abbrev_section_dirty) { |
| 1445 | | try dw.writeDbgAbbrev(); |
| 1446 | | self.debug_abbrev_section_dirty = false; |
| 1447 | | } |
| 1448 | | |
| 1449 | | if (self.debug_info_header_dirty) { |
| 1450 | | const text_phdr = &self.phdrs.items[self.phdr_zig_load_re_index.?]; |
| 1451 | | const low_pc = text_phdr.p_vaddr; |
| 1452 | | const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz; |
| 1453 | | try dw.writeDbgInfoHeader(self.base.options.module.?, low_pc, high_pc); |
| 1454 | | self.debug_info_header_dirty = false; |
| 1455 | | } |
| 1456 | | |
| 1457 | | if (self.debug_aranges_section_dirty) { |
| 1458 | | const text_phdr = &self.phdrs.items[self.phdr_zig_load_re_index.?]; |
| 1459 | | try dw.writeDbgAranges(text_phdr.p_vaddr, text_phdr.p_memsz); |
| 1460 | | self.debug_aranges_section_dirty = false; |
| 1461 | | } |
| 1462 | | |
| 1463 | | if (self.debug_line_header_dirty) { |
| 1464 | | try dw.writeDbgLineHeader(); |
| 1465 | | self.debug_line_header_dirty = false; |
| 1466 | | } |
| 1467 | | |
| 1468 | | if (self.debug_str_section_index) |shndx| { |
| 1469 | | if (self.debug_strtab_dirty or dw.strtab.buffer.items.len != self.shdrs.items[shndx].sh_size) { |
| 1470 | | try self.growNonAllocSection(shndx, dw.strtab.buffer.items.len, 1, false); |
| 1471 | | const shdr = self.shdrs.items[shndx]; |
| 1472 | | try self.base.file.?.pwriteAll(dw.strtab.buffer.items, shdr.sh_offset); |
| 1473 | | self.debug_strtab_dirty = false; |
| 1474 | | } |
| 1475 | | } |
| 1476 | | |
| 1477 | | self.saveDebugSectionsSizes(); |
| 1478 | | } |
| 1479 | | } |
| 1480 | | |
| 1481 | 1396 | // Generate and emit non-incremental sections. |
| 1482 | 1397 | try self.initSections(); |
| 1483 | 1398 | try self.initSpecialPhdrs(); |
| ... | ... | @@ -1542,14 +1457,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1542 | 1457 | self.error_flags.no_entry_point_found = false; |
| 1543 | 1458 | try self.writeHeader(); |
| 1544 | 1459 | } |
| 1545 | | |
| 1546 | | // The point of flush() is to commit changes, so in theory, nothing should |
| 1547 | | // be dirty after this. However, it is possible for some things to remain |
| 1548 | | // dirty because they fail to be written in the event of compile errors, |
| 1549 | | // such as debug_line_header_dirty and debug_info_header_dirty. |
| 1550 | | assert(!self.debug_abbrev_section_dirty); |
| 1551 | | assert(!self.debug_aranges_section_dirty); |
| 1552 | | assert(!self.debug_strtab_dirty); |
| 1553 | 1460 | } |
| 1554 | 1461 | |
| 1555 | 1462 | const ParseError = error{ |
| ... | ... | @@ -3815,24 +3722,6 @@ fn sortShdrs(self: *Elf) !void { |
| 3815 | 3722 | } |
| 3816 | 3723 | } |
| 3817 | 3724 | |
| 3818 | | fn saveDebugSectionsSizes(self: *Elf) void { |
| 3819 | | if (self.debug_info_section_index) |shndx| { |
| 3820 | | self.debug_info_section_zig_size = self.shdrs.items[shndx].sh_size; |
| 3821 | | } |
| 3822 | | if (self.debug_abbrev_section_index) |shndx| { |
| 3823 | | self.debug_abbrev_section_zig_size = self.shdrs.items[shndx].sh_size; |
| 3824 | | } |
| 3825 | | if (self.debug_str_section_index) |shndx| { |
| 3826 | | self.debug_str_section_zig_size = self.shdrs.items[shndx].sh_size; |
| 3827 | | } |
| 3828 | | if (self.debug_aranges_section_index) |shndx| { |
| 3829 | | self.debug_aranges_section_zig_size = self.shdrs.items[shndx].sh_size; |
| 3830 | | } |
| 3831 | | if (self.debug_line_section_index) |shndx| { |
| 3832 | | self.debug_line_section_zig_size = self.shdrs.items[shndx].sh_size; |
| 3833 | | } |
| 3834 | | } |
| 3835 | | |
| 3836 | 3725 | fn updateSectionSizes(self: *Elf) !void { |
| 3837 | 3726 | for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| { |
| 3838 | 3727 | if (atom_list.items.len == 0) continue; |
| ... | ... | @@ -4189,12 +4078,18 @@ fn allocateNonAllocSections(self: *Elf) !void { |
| 4189 | 4078 | shdr.sh_offset, |
| 4190 | 4079 | new_offset, |
| 4191 | 4080 | }); |
| 4081 | const zig_object = self.zigObjectPtr().?; |
| 4192 | 4082 | const existing_size = blk: { |
| 4193 | | if (shndx == self.debug_info_section_index.?) break :blk self.debug_info_section_zig_size; |
| 4194 | | if (shndx == self.debug_abbrev_section_index.?) break :blk self.debug_abbrev_section_zig_size; |
| 4195 | | if (shndx == self.debug_str_section_index.?) break :blk self.debug_str_section_zig_size; |
| 4196 | | if (shndx == self.debug_aranges_section_index.?) break :blk self.debug_aranges_section_zig_size; |
| 4197 | | if (shndx == self.debug_line_section_index.?) break :blk self.debug_line_section_zig_size; |
| 4083 | if (shndx == self.debug_info_section_index.?) |
| 4084 | break :blk zig_object.debug_info_section_zig_size; |
| 4085 | if (shndx == self.debug_abbrev_section_index.?) |
| 4086 | break :blk zig_object.debug_abbrev_section_zig_size; |
| 4087 | if (shndx == self.debug_str_section_index.?) |
| 4088 | break :blk zig_object.debug_str_section_zig_size; |
| 4089 | if (shndx == self.debug_aranges_section_index.?) |
| 4090 | break :blk zig_object.debug_aranges_section_zig_size; |
| 4091 | if (shndx == self.debug_line_section_index.?) |
| 4092 | break :blk zig_object.debug_line_section_zig_size; |
| 4198 | 4093 | unreachable; |
| 4199 | 4094 | }; |
| 4200 | 4095 | const amt = try self.base.file.?.copyRangeAll( |
| ... | ... | @@ -4296,11 +4191,17 @@ fn writeAtoms(self: *Elf) !void { |
| 4296 | 4191 | |
| 4297 | 4192 | // TODO really, really handle debug section separately |
| 4298 | 4193 | const base_offset = if (self.isDebugSection(@intCast(shndx))) blk: { |
| 4299 | | if (shndx == self.debug_info_section_index.?) break :blk self.debug_info_section_zig_size; |
| 4300 | | if (shndx == self.debug_abbrev_section_index.?) break :blk self.debug_abbrev_section_zig_size; |
| 4301 | | if (shndx == self.debug_str_section_index.?) break :blk self.debug_str_section_zig_size; |
| 4302 | | if (shndx == self.debug_aranges_section_index.?) break :blk self.debug_aranges_section_zig_size; |
| 4303 | | if (shndx == self.debug_line_section_index.?) break :blk self.debug_line_section_zig_size; |
| 4194 | const zig_object = self.zigObjectPtr().?; |
| 4195 | if (shndx == self.debug_info_section_index.?) |
| 4196 | break :blk zig_object.debug_info_section_zig_size; |
| 4197 | if (shndx == self.debug_abbrev_section_index.?) |
| 4198 | break :blk zig_object.debug_abbrev_section_zig_size; |
| 4199 | if (shndx == self.debug_str_section_index.?) |
| 4200 | break :blk zig_object.debug_str_section_zig_size; |
| 4201 | if (shndx == self.debug_aranges_section_index.?) |
| 4202 | break :blk zig_object.debug_aranges_section_zig_size; |
| 4203 | if (shndx == self.debug_line_section_index.?) |
| 4204 | break :blk zig_object.debug_line_section_zig_size; |
| 4304 | 4205 | unreachable; |
| 4305 | 4206 | } else 0; |
| 4306 | 4207 | const sh_offset = shdr.sh_offset + base_offset; |