| ... | ... | @@ -108,12 +108,21 @@ zig_rodata_section_index: ?u16 = null, |
| 108 | 108 | zig_data_section_index: ?u16 = null, |
| 109 | 109 | zig_bss_section_index: ?u16 = null, |
| 110 | 110 | zig_got_section_index: ?u16 = null, |
| 111 | |
| 111 | 112 | debug_info_section_index: ?u16 = null, |
| 112 | 113 | debug_abbrev_section_index: ?u16 = null, |
| 113 | 114 | debug_str_section_index: ?u16 = null, |
| 114 | 115 | debug_aranges_section_index: ?u16 = null, |
| 115 | 116 | debug_line_section_index: ?u16 = null, |
| 116 | 117 | |
| 118 | /// Size contribution of Zig's metadata to each debug section. |
| 119 | /// Used to track start of metadata from input object files. |
| 120 | debug_info_section_zig_size: u64 = 0, |
| 121 | debug_abbrev_section_zig_size: u64 = 0, |
| 122 | debug_str_section_zig_size: u64 = 0, |
| 123 | debug_aranges_section_zig_size: u64 = 0, |
| 124 | debug_line_section_zig_size: u64 = 0, |
| 125 | |
| 117 | 126 | copy_rel_section_index: ?u16 = null, |
| 118 | 127 | dynamic_section_index: ?u16 = null, |
| 119 | 128 | dynstrtab_section_index: ?u16 = null, |
| ... | ... | @@ -924,7 +933,7 @@ pub fn growNonAllocSection( |
| 924 | 933 | shdr.sh_offset = new_offset; |
| 925 | 934 | } |
| 926 | 935 | |
| 927 | | shdr.sh_size = needed_size; // anticipating adding the global symbols later |
| 936 | shdr.sh_size = needed_size; |
| 928 | 937 | |
| 929 | 938 | self.markDirty(shdr_index); |
| 930 | 939 | } |
| ... | ... | @@ -1522,8 +1531,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1522 | 1531 | } |
| 1523 | 1532 | |
| 1524 | 1533 | if (self.debug_info_header_dirty) { |
| 1525 | | // Currently only one compilation unit is supported, so the address range is simply |
| 1526 | | // identical to the main program header virtual address and memory size. |
| 1527 | 1534 | const text_phdr = &self.phdrs.items[self.phdr_zig_load_re_index.?]; |
| 1528 | 1535 | const low_pc = text_phdr.p_vaddr; |
| 1529 | 1536 | const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz; |
| ... | ... | @@ -1532,8 +1539,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1532 | 1539 | } |
| 1533 | 1540 | |
| 1534 | 1541 | if (self.debug_aranges_section_dirty) { |
| 1535 | | // Currently only one compilation unit is supported, so the address range is simply |
| 1536 | | // identical to the main program header virtual address and memory size. |
| 1537 | 1542 | const text_phdr = &self.phdrs.items[self.phdr_zig_load_re_index.?]; |
| 1538 | 1543 | try dw.writeDbgAranges(text_phdr.p_vaddr, text_phdr.p_memsz); |
| 1539 | 1544 | self.debug_aranges_section_dirty = false; |
| ... | ... | @@ -1552,6 +1557,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1552 | 1557 | self.debug_strtab_dirty = false; |
| 1553 | 1558 | } |
| 1554 | 1559 | } |
| 1560 | |
| 1561 | self.saveDebugSectionsSizes(); |
| 1555 | 1562 | } |
| 1556 | 1563 | |
| 1557 | 1564 | // Generate and emit non-incremental sections. |
| ... | ... | @@ -4345,6 +4352,24 @@ fn sortShdrs(self: *Elf) !void { |
| 4345 | 4352 | } |
| 4346 | 4353 | } |
| 4347 | 4354 | |
| 4355 | fn saveDebugSectionsSizes(self: *Elf) void { |
| 4356 | if (self.debug_info_section_index) |shndx| { |
| 4357 | self.debug_info_section_zig_size = self.shdrs.items[shndx].sh_size; |
| 4358 | } |
| 4359 | if (self.debug_abbrev_section_index) |shndx| { |
| 4360 | self.debug_abbrev_section_zig_size = self.shdrs.items[shndx].sh_size; |
| 4361 | } |
| 4362 | if (self.debug_str_section_index) |shndx| { |
| 4363 | self.debug_str_section_zig_size = self.shdrs.items[shndx].sh_size; |
| 4364 | } |
| 4365 | if (self.debug_aranges_section_index) |shndx| { |
| 4366 | self.debug_aranges_section_zig_size = self.shdrs.items[shndx].sh_size; |
| 4367 | } |
| 4368 | if (self.debug_line_section_index) |shndx| { |
| 4369 | self.debug_line_section_zig_size = self.shdrs.items[shndx].sh_size; |
| 4370 | } |
| 4371 | } |
| 4372 | |
| 4348 | 4373 | fn updateSectionSizes(self: *Elf) !void { |
| 4349 | 4374 | for (self.output_sections.keys(), self.output_sections.values()) |shndx, atom_list| { |
| 4350 | 4375 | if (atom_list.items.len == 0) continue; |
| ... | ... | @@ -4675,18 +4700,31 @@ fn allocateNonAllocSections(self: *Elf) !void { |
| 4675 | 4700 | const new_offset = self.findFreeSpace(needed_size, shdr.sh_addralign); |
| 4676 | 4701 | |
| 4677 | 4702 | if (self.isDebugSection(@intCast(shndx))) { |
| 4703 | log.debug("moving {s} from 0x{x} to 0x{x}", .{ |
| 4704 | self.shstrtab.getAssumeExists(shdr.sh_name), |
| 4705 | shdr.sh_offset, |
| 4706 | new_offset, |
| 4707 | }); |
| 4708 | const existing_size = blk: { |
| 4709 | if (shndx == self.debug_info_section_index.?) break :blk self.debug_info_section_zig_size; |
| 4710 | if (shndx == self.debug_abbrev_section_index.?) break :blk self.debug_abbrev_section_zig_size; |
| 4711 | if (shndx == self.debug_str_section_index.?) break :blk self.debug_str_section_zig_size; |
| 4712 | if (shndx == self.debug_aranges_section_index.?) break :blk self.debug_aranges_section_zig_size; |
| 4713 | if (shndx == self.debug_line_section_index.?) break :blk self.debug_line_section_zig_size; |
| 4714 | unreachable; |
| 4715 | }; |
| 4678 | 4716 | const amt = try self.base.file.?.copyRangeAll( |
| 4679 | 4717 | shdr.sh_offset, |
| 4680 | 4718 | self.base.file.?, |
| 4681 | 4719 | new_offset, |
| 4682 | | needed_size, // TODO this will copy too much but ah well |
| 4720 | existing_size, |
| 4683 | 4721 | ); |
| 4684 | | if (amt != needed_size) return error.InputOutput; |
| 4722 | if (amt != existing_size) return error.InputOutput; |
| 4685 | 4723 | } |
| 4686 | 4724 | |
| 4687 | 4725 | shdr.sh_offset = new_offset; |
| 4726 | shdr.sh_size = needed_size; |
| 4688 | 4727 | } |
| 4689 | | shdr.sh_size = needed_size; |
| 4690 | 4728 | } |
| 4691 | 4729 | } |
| 4692 | 4730 | |
| ... | ... | @@ -4771,7 +4809,19 @@ fn writeAtoms(self: *Elf) !void { |
| 4771 | 4809 | |
| 4772 | 4810 | log.debug("writing atoms in '{s}' section", .{self.shstrtab.getAssumeExists(shdr.sh_name)}); |
| 4773 | 4811 | |
| 4774 | | const buffer = try gpa.alloc(u8, shdr.sh_size); |
| 4812 | // TODO really, really handle debug section separately |
| 4813 | const base_offset = if (self.isDebugSection(@intCast(shndx))) blk: { |
| 4814 | if (shndx == self.debug_info_section_index.?) break :blk self.debug_info_section_zig_size; |
| 4815 | if (shndx == self.debug_abbrev_section_index.?) break :blk self.debug_abbrev_section_zig_size; |
| 4816 | if (shndx == self.debug_str_section_index.?) break :blk self.debug_str_section_zig_size; |
| 4817 | if (shndx == self.debug_aranges_section_index.?) break :blk self.debug_aranges_section_zig_size; |
| 4818 | if (shndx == self.debug_line_section_index.?) break :blk self.debug_line_section_zig_size; |
| 4819 | unreachable; |
| 4820 | } else 0; |
| 4821 | const sh_offset = shdr.sh_offset + base_offset; |
| 4822 | const sh_size = shdr.sh_size - base_offset; |
| 4823 | |
| 4824 | const buffer = try gpa.alloc(u8, sh_size); |
| 4775 | 4825 | defer gpa.free(buffer); |
| 4776 | 4826 | const padding_byte: u8 = if (shdr.sh_type == elf.SHT_PROGBITS and |
| 4777 | 4827 | shdr.sh_flags & elf.SHF_EXECINSTR != 0) |
| ... | ... | @@ -4785,9 +4835,9 @@ fn writeAtoms(self: *Elf) !void { |
| 4785 | 4835 | assert(atom_ptr.flags.alive); |
| 4786 | 4836 | |
| 4787 | 4837 | const object = atom_ptr.file(self).?.object; |
| 4788 | | const offset = atom_ptr.value - shdr.sh_addr; |
| 4838 | const offset = atom_ptr.value - shdr.sh_addr - base_offset; |
| 4789 | 4839 | |
| 4790 | | log.debug("writing atom({d}) at 0x{x}", .{ atom_index, shdr.sh_offset + offset }); |
| 4840 | log.debug("writing atom({d}) at 0x{x}", .{ atom_index, sh_offset + offset }); |
| 4791 | 4841 | |
| 4792 | 4842 | // TODO decompress directly into provided buffer |
| 4793 | 4843 | const out_code = buffer[offset..][0..atom_ptr.size]; |
| ... | ... | @@ -4808,7 +4858,7 @@ fn writeAtoms(self: *Elf) !void { |
| 4808 | 4858 | } |
| 4809 | 4859 | } |
| 4810 | 4860 | |
| 4811 | | try self.base.file.?.pwriteAll(buffer, shdr.sh_offset); |
| 4861 | try self.base.file.?.pwriteAll(buffer, sh_offset); |
| 4812 | 4862 | } |
| 4813 | 4863 | |
| 4814 | 4864 | try self.reportUndefined(&undefs); |