| ... | @@ -1515,6 +1515,47 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1515,6 +1515,47 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1515 | // Scan and create missing synthetic entries such as GOT indirection. | 1515 | // Scan and create missing synthetic entries such as GOT indirection. |
| 1516 | try self.scanRelocs(); | 1516 | try self.scanRelocs(); |
| 1517 | | 1517 | |
| | 1518 | // TODO I need to re-think how to handle ZigModule's debug sections AND debug sections |
| | 1519 | // extracted from input object files correctly. |
| | 1520 | if (self.dwarf) |*dw| { |
| | 1521 | if (self.debug_abbrev_section_dirty) { |
| | 1522 | try dw.writeDbgAbbrev(); |
| | 1523 | self.debug_abbrev_section_dirty = false; |
| | 1524 | } |
| | 1525 | |
| | 1526 | if (self.debug_info_header_dirty) { |
| | 1527 | // Currently only one compilation unit is supported, so the address range is simply |
| | 1528 | // identical to the main program header virtual address and memory size. |
| | 1529 | const text_phdr = &self.phdrs.items[self.phdr_zig_load_re_index.?]; |
| | 1530 | const low_pc = text_phdr.p_vaddr; |
| | 1531 | const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz; |
| | 1532 | try dw.writeDbgInfoHeader(self.base.options.module.?, low_pc, high_pc); |
| | 1533 | self.debug_info_header_dirty = false; |
| | 1534 | } |
| | 1535 | |
| | 1536 | if (self.debug_aranges_section_dirty) { |
| | 1537 | // Currently only one compilation unit is supported, so the address range is simply |
| | 1538 | // identical to the main program header virtual address and memory size. |
| | 1539 | const text_phdr = &self.phdrs.items[self.phdr_zig_load_re_index.?]; |
| | 1540 | try dw.writeDbgAranges(text_phdr.p_vaddr, text_phdr.p_memsz); |
| | 1541 | self.debug_aranges_section_dirty = false; |
| | 1542 | } |
| | 1543 | |
| | 1544 | if (self.debug_line_header_dirty) { |
| | 1545 | try dw.writeDbgLineHeader(); |
| | 1546 | self.debug_line_header_dirty = false; |
| | 1547 | } |
| | 1548 | |
| | 1549 | if (self.debug_str_section_index) |shndx| { |
| | 1550 | if (self.debug_strtab_dirty or dw.strtab.buffer.items.len != self.shdrs.items[shndx].sh_size) { |
| | 1551 | try self.growNonAllocSection(shndx, dw.strtab.buffer.items.len, 1, false); |
| | 1552 | const shdr = self.shdrs.items[shndx]; |
| | 1553 | try self.base.file.?.pwriteAll(dw.strtab.buffer.items, shdr.sh_offset); |
| | 1554 | self.debug_strtab_dirty = false; |
| | 1555 | } |
| | 1556 | } |
| | 1557 | } |
| | 1558 | |
| 1518 | // Generate and emit non-incremental sections. | 1559 | // Generate and emit non-incremental sections. |
| 1519 | try self.initSections(); | 1560 | try self.initSections(); |
| 1520 | try self.initSpecialPhdrs(); | 1561 | try self.initSpecialPhdrs(); |
| ... | @@ -1531,7 +1572,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1531,7 +1572,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1531 | | 1572 | |
| 1532 | self.allocatePhdrTable(); | 1573 | self.allocatePhdrTable(); |
| 1533 | try self.allocateAllocSections(); | 1574 | try self.allocateAllocSections(); |
| 1534 | self.allocateNonAllocSections(); | 1575 | try self.allocateNonAllocSections(); |
| 1535 | self.allocateSpecialPhdrs(); | 1576 | self.allocateSpecialPhdrs(); |
| 1536 | self.allocateAtoms(); | 1577 | self.allocateAtoms(); |
| 1537 | self.allocateLinkerDefinedSymbols(); | 1578 | self.allocateLinkerDefinedSymbols(); |
| ... | @@ -1574,45 +1615,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -1574,45 +1615,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1574 | }; | 1615 | }; |
| 1575 | try self.base.file.?.pwriteAll(code, file_offset); | 1616 | try self.base.file.?.pwriteAll(code, file_offset); |
| 1576 | } | 1617 | } |
| 1577 | | | |
| 1578 | if (self.dwarf) |*dw| { | | |
| 1579 | if (self.debug_abbrev_section_dirty) { | | |
| 1580 | try dw.writeDbgAbbrev(); | | |
| 1581 | self.debug_abbrev_section_dirty = false; | | |
| 1582 | } | | |
| 1583 | | | |
| 1584 | if (self.debug_info_header_dirty) { | | |
| 1585 | // Currently only one compilation unit is supported, so the address range is simply | | |
| 1586 | // identical to the main program header virtual address and memory size. | | |
| 1587 | const text_phdr = &self.phdrs.items[self.phdr_zig_load_re_index.?]; | | |
| 1588 | const low_pc = text_phdr.p_vaddr; | | |
| 1589 | const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz; | | |
| 1590 | try dw.writeDbgInfoHeader(self.base.options.module.?, low_pc, high_pc); | | |
| 1591 | self.debug_info_header_dirty = false; | | |
| 1592 | } | | |
| 1593 | | | |
| 1594 | if (self.debug_aranges_section_dirty) { | | |
| 1595 | // Currently only one compilation unit is supported, so the address range is simply | | |
| 1596 | // identical to the main program header virtual address and memory size. | | |
| 1597 | const text_phdr = &self.phdrs.items[self.phdr_zig_load_re_index.?]; | | |
| 1598 | try dw.writeDbgAranges(text_phdr.p_vaddr, text_phdr.p_memsz); | | |
| 1599 | self.debug_aranges_section_dirty = false; | | |
| 1600 | } | | |
| 1601 | | | |
| 1602 | if (self.debug_line_header_dirty) { | | |
| 1603 | try dw.writeDbgLineHeader(); | | |
| 1604 | self.debug_line_header_dirty = false; | | |
| 1605 | } | | |
| 1606 | | | |
| 1607 | if (self.debug_str_section_index) |shndx| { | | |
| 1608 | if (self.debug_strtab_dirty or dw.strtab.buffer.items.len != self.shdrs.items[shndx].sh_size) { | | |
| 1609 | try self.growNonAllocSection(shndx, dw.strtab.buffer.items.len, 1, false); | | |
| 1610 | const shdr = self.shdrs.items[shndx]; | | |
| 1611 | try self.base.file.?.pwriteAll(dw.strtab.buffer.items, shdr.sh_offset); | | |
| 1612 | self.debug_strtab_dirty = false; | | |
| 1613 | } | | |
| 1614 | } | | |
| 1615 | } | | |
| 1616 | } | 1618 | } |
| 1617 | | 1619 | |
| 1618 | try self.writePhdrTable(); | 1620 | try self.writePhdrTable(); |
| ... | @@ -4601,14 +4603,26 @@ fn allocateAllocSections(self: *Elf) error{OutOfMemory}!void { | ... | @@ -4601,14 +4603,26 @@ fn allocateAllocSections(self: *Elf) error{OutOfMemory}!void { |
| 4601 | } | 4603 | } |
| 4602 | | 4604 | |
| 4603 | /// Allocates non-alloc sections (debug info, symtabs, etc.). | 4605 | /// Allocates non-alloc sections (debug info, symtabs, etc.). |
| 4604 | fn allocateNonAllocSections(self: *Elf) void { | 4606 | fn allocateNonAllocSections(self: *Elf) !void { |
| 4605 | for (self.shdrs.items) |*shdr| { | 4607 | for (self.shdrs.items, 0..) |*shdr, shndx| { |
| 4606 | if (shdr.sh_type == elf.SHT_NULL) continue; | 4608 | if (shdr.sh_type == elf.SHT_NULL) continue; |
| 4607 | if (shdr.sh_flags & elf.SHF_ALLOC != 0) continue; | 4609 | if (shdr.sh_flags & elf.SHF_ALLOC != 0) continue; |
| 4608 | const needed_size = shdr.sh_size; | 4610 | const needed_size = shdr.sh_size; |
| 4609 | if (needed_size > self.allocatedSize(shdr.sh_offset)) { | 4611 | if (needed_size > self.allocatedSize(shdr.sh_offset)) { |
| 4610 | shdr.sh_size = 0; | 4612 | shdr.sh_size = 0; |
| 4611 | shdr.sh_offset = self.findFreeSpace(needed_size, shdr.sh_addralign); | 4613 | const new_offset = self.findFreeSpace(needed_size, shdr.sh_addralign); |
| | 4614 | |
| | 4615 | if (self.isDebugSection(@intCast(shndx))) { |
| | 4616 | const amt = try self.base.file.?.copyRangeAll( |
| | 4617 | shdr.sh_offset, |
| | 4618 | self.base.file.?, |
| | 4619 | new_offset, |
| | 4620 | needed_size, // TODO this will copy too much but ah well |
| | 4621 | ); |
| | 4622 | if (amt != needed_size) return error.InputOutput; |
| | 4623 | } |
| | 4624 | |
| | 4625 | shdr.sh_offset = new_offset; |
| 4612 | } | 4626 | } |
| 4613 | shdr.sh_size = needed_size; | 4627 | shdr.sh_size = needed_size; |
| 4614 | } | 4628 | } |
| ... | @@ -5354,6 +5368,21 @@ pub fn isZigSection(self: Elf, shndx: u16) bool { | ... | @@ -5354,6 +5368,21 @@ pub fn isZigSection(self: Elf, shndx: u16) bool { |
| 5354 | return false; | 5368 | return false; |
| 5355 | } | 5369 | } |
| 5356 | | 5370 | |
| | 5371 | pub fn isDebugSection(self: Elf, shndx: u16) bool { |
| | 5372 | inline for (&[_]?u16{ |
| | 5373 | self.debug_info_section_index, |
| | 5374 | self.debug_abbrev_section_index, |
| | 5375 | self.debug_str_section_index, |
| | 5376 | self.debug_aranges_section_index, |
| | 5377 | self.debug_line_section_index, |
| | 5378 | }) |maybe_index| { |
| | 5379 | if (maybe_index) |index| { |
| | 5380 | if (index == shndx) return true; |
| | 5381 | } |
| | 5382 | } |
| | 5383 | return false; |
| | 5384 | } |
| | 5385 | |
| 5357 | fn addPhdr(self: *Elf, opts: struct { | 5386 | fn addPhdr(self: *Elf, opts: struct { |
| 5358 | type: u32 = 0, | 5387 | type: u32 = 0, |
| 5359 | flags: u32 = 0, | 5388 | flags: u32 = 0, |