| ... | @@ -113,14 +113,6 @@ debug_str_section_index: ?u16 = null, | ... | @@ -113,14 +113,6 @@ debug_str_section_index: ?u16 = null, |
| 113 | debug_aranges_section_index: ?u16 = null, | 113 | debug_aranges_section_index: ?u16 = null, |
| 114 | debug_line_section_index: ?u16 = null, | 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 | copy_rel_section_index: ?u16 = null, | 116 | copy_rel_section_index: ?u16 = null, |
| 125 | dynamic_section_index: ?u16 = null, | 117 | dynamic_section_index: ?u16 = null, |
| 126 | dynstrtab_section_index: ?u16 = null, | 118 | dynstrtab_section_index: ?u16 = null, |
| ... | @@ -170,12 +162,6 @@ symbols_free_list: std.ArrayListUnmanaged(Symbol.Index) = .{}, | ... | @@ -170,12 +162,6 @@ symbols_free_list: std.ArrayListUnmanaged(Symbol.Index) = .{}, |
| 170 | has_text_reloc: bool = false, | 162 | has_text_reloc: bool = false, |
| 171 | num_ifunc_dynrelocs: usize = 0, | 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 | error_flags: link.File.ErrorFlags = link.File.ErrorFlags{}, | 165 | error_flags: link.File.ErrorFlags = link.File.ErrorFlags{}, |
| 180 | misc_errors: std.ArrayListUnmanaged(link.File.ErrorMsg) = .{}, | 166 | misc_errors: std.ArrayListUnmanaged(link.File.ErrorMsg) = .{}, |
| 181 | | 167 | |
| ... | @@ -696,7 +682,8 @@ pub fn initMetadata(self: *Elf) !void { | ... | @@ -696,7 +682,8 @@ pub fn initMetadata(self: *Elf) !void { |
| 696 | try self.last_atom_and_free_list_table.putNoClobber(gpa, self.zig_bss_section_index.?, .{}); | 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 | if (self.debug_str_section_index == null) { | 687 | if (self.debug_str_section_index == null) { |
| 701 | assert(dw.strtab.buffer.items.len == 0); | 688 | assert(dw.strtab.buffer.items.len == 0); |
| 702 | try dw.strtab.buffer.append(gpa, 0); | 689 | try dw.strtab.buffer.append(gpa, 0); |
| ... | @@ -706,7 +693,7 @@ pub fn initMetadata(self: *Elf) !void { | ... | @@ -706,7 +693,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 706 | .flags = elf.SHF_MERGE | elf.SHF_STRINGS, | 693 | .flags = elf.SHF_MERGE | elf.SHF_STRINGS, |
| 707 | .entsize = 1, | 694 | .entsize = 1, |
| 708 | }); | 695 | }); |
| 709 | self.debug_strtab_dirty = true; | 696 | zig_object.debug_strtab_dirty = true; |
| 710 | } | 697 | } |
| 711 | | 698 | |
| 712 | if (self.debug_info_section_index == null) { | 699 | if (self.debug_info_section_index == null) { |
| ... | @@ -715,7 +702,7 @@ pub fn initMetadata(self: *Elf) !void { | ... | @@ -715,7 +702,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 715 | .size = 200, | 702 | .size = 200, |
| 716 | .alignment = 1, | 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 | if (self.debug_abbrev_section_index == null) { | 708 | if (self.debug_abbrev_section_index == null) { |
| ... | @@ -724,7 +711,7 @@ pub fn initMetadata(self: *Elf) !void { | ... | @@ -724,7 +711,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 724 | .size = 128, | 711 | .size = 128, |
| 725 | .alignment = 1, | 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 | if (self.debug_aranges_section_index == null) { | 717 | if (self.debug_aranges_section_index == null) { |
| ... | @@ -733,7 +720,7 @@ pub fn initMetadata(self: *Elf) !void { | ... | @@ -733,7 +720,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 733 | .size = 160, | 720 | .size = 160, |
| 734 | .alignment = 16, | 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 | if (self.debug_line_section_index == null) { | 726 | if (self.debug_line_section_index == null) { |
| ... | @@ -742,7 +729,7 @@ pub fn initMetadata(self: *Elf) !void { | ... | @@ -742,7 +729,7 @@ pub fn initMetadata(self: *Elf) !void { |
| 742 | .size = 250, | 729 | .size = 250, |
| 743 | .alignment = 1, | 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,17 +820,18 @@ pub fn growNonAllocSection( |
| 833 | } | 820 | } |
| 834 | | 821 | |
| 835 | pub fn markDirty(self: *Elf, shdr_index: u16) void { | 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 | if (self.debug_info_section_index.? == shdr_index) { | 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 | } else if (self.debug_line_section_index.? == shdr_index) { | 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 | } else if (self.debug_abbrev_section_index.? == shdr_index) { | 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 | } else if (self.debug_str_section_index.? == shdr_index) { | 831 | } else if (self.debug_str_section_index.? == shdr_index) { |
| 844 | self.debug_strtab_dirty = true; | 832 | zig_object.debug_strtab_dirty = true; |
| 845 | } else if (self.debug_aranges_section_index.? == shdr_index) { | 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,39 +1331,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1343 | try self.handleAndReportParseError(obj.path, err, &parse_ctx); | 1331 | try self.handleAndReportParseError(obj.path, err, &parse_ctx); |
| 1344 | } | 1332 | } |
| 1345 | | 1333 | |
| 1346 | if (self.zigObjectPtr()) |zig_object| { | 1334 | if (self.zigObjectPtr()) |zig_object| try zig_object.flushModule(self); |
| 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 | } | | |
| 1379 | | 1335 | |
| 1380 | // Dedup shared objects | 1336 | // Dedup shared objects |
| 1381 | { | 1337 | { |
| ... | @@ -1437,47 +1393,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1437,47 +1393,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1437 | // Scan and create missing synthetic entries such as GOT indirection. | 1393 | // Scan and create missing synthetic entries such as GOT indirection. |
| 1438 | try self.scanRelocs(); | 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 | // Generate and emit non-incremental sections. | 1396 | // Generate and emit non-incremental sections. |
| 1482 | try self.initSections(); | 1397 | try self.initSections(); |
| 1483 | try self.initSpecialPhdrs(); | 1398 | try self.initSpecialPhdrs(); |
| ... | @@ -1542,14 +1457,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1542,14 +1457,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1542 | self.error_flags.no_entry_point_found = false; | 1457 | self.error_flags.no_entry_point_found = false; |
| 1543 | try self.writeHeader(); | 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 | const ParseError = error{ | 1462 | const ParseError = error{ |
| ... | @@ -3815,24 +3722,6 @@ fn sortShdrs(self: *Elf) !void { | ... | @@ -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 | fn updateSectionSizes(self: *Elf) !void { | 3725 | fn updateSectionSizes(self: *Elf) !void { |
| 3837 | for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| { | 3726 | for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| { |
| 3838 | if (atom_list.items.len == 0) continue; | 3727 | if (atom_list.items.len == 0) continue; |
| ... | @@ -4189,12 +4078,18 @@ fn allocateNonAllocSections(self: *Elf) !void { | ... | @@ -4189,12 +4078,18 @@ fn allocateNonAllocSections(self: *Elf) !void { |
| 4189 | shdr.sh_offset, | 4078 | shdr.sh_offset, |
| 4190 | new_offset, | 4079 | new_offset, |
| 4191 | }); | 4080 | }); |
| | 4081 | const zig_object = self.zigObjectPtr().?; |
| 4192 | const existing_size = blk: { | 4082 | const existing_size = blk: { |
| 4193 | if (shndx == self.debug_info_section_index.?) break :blk self.debug_info_section_zig_size; | 4083 | if (shndx == self.debug_info_section_index.?) |
| 4194 | if (shndx == self.debug_abbrev_section_index.?) break :blk self.debug_abbrev_section_zig_size; | 4084 | break :blk zig_object.debug_info_section_zig_size; |
| 4195 | if (shndx == self.debug_str_section_index.?) break :blk self.debug_str_section_zig_size; | 4085 | if (shndx == self.debug_abbrev_section_index.?) |
| 4196 | if (shndx == self.debug_aranges_section_index.?) break :blk self.debug_aranges_section_zig_size; | 4086 | break :blk zig_object.debug_abbrev_section_zig_size; |
| 4197 | if (shndx == self.debug_line_section_index.?) break :blk self.debug_line_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 | unreachable; | 4093 | unreachable; |
| 4199 | }; | 4094 | }; |
| 4200 | const amt = try self.base.file.?.copyRangeAll( | 4095 | const amt = try self.base.file.?.copyRangeAll( |
| ... | @@ -4296,11 +4191,17 @@ fn writeAtoms(self: *Elf) !void { | ... | @@ -4296,11 +4191,17 @@ fn writeAtoms(self: *Elf) !void { |
| 4296 | | 4191 | |
| 4297 | // TODO really, really handle debug section separately | 4192 | // TODO really, really handle debug section separately |
| 4298 | const base_offset = if (self.isDebugSection(@intCast(shndx))) blk: { | 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; | 4194 | const zig_object = self.zigObjectPtr().?; |
| 4300 | if (shndx == self.debug_abbrev_section_index.?) break :blk self.debug_abbrev_section_zig_size; | 4195 | if (shndx == self.debug_info_section_index.?) |
| 4301 | if (shndx == self.debug_str_section_index.?) break :blk self.debug_str_section_zig_size; | 4196 | break :blk zig_object.debug_info_section_zig_size; |
| 4302 | if (shndx == self.debug_aranges_section_index.?) break :blk self.debug_aranges_section_zig_size; | 4197 | if (shndx == self.debug_abbrev_section_index.?) |
| 4303 | if (shndx == self.debug_line_section_index.?) break :blk self.debug_line_section_zig_size; | 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 | unreachable; | 4205 | unreachable; |
| 4305 | } else 0; | 4206 | } else 0; |
| 4306 | const sh_offset = shdr.sh_offset + base_offset; | 4207 | const sh_offset = shdr.sh_offset + base_offset; |