| ... | ... | @@ -531,6 +531,16 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 { |
| 531 | 531 | |
| 532 | 532 | const end = start + padToIdeal(size); |
| 533 | 533 | |
| 534 | if (self.shdr_table_offset) |off| { |
| 535 | const shdr_size: u64 = if (small_ptr) @sizeOf(elf.Elf32_Shdr) else @sizeOf(elf.Elf64_Shdr); |
| 536 | const tight_size = self.shdrs.items.len * shdr_size; |
| 537 | const increased_size = padToIdeal(tight_size); |
| 538 | const test_end = off + increased_size; |
| 539 | if (end > off and start < test_end) { |
| 540 | return test_end; |
| 541 | } |
| 542 | } |
| 543 | |
| 534 | 544 | for (self.shdrs.items) |shdr| { |
| 535 | 545 | // SHT_NOBITS takes no physical space in the output file so set its size to 0. |
| 536 | 546 | const sh_size = if (shdr.sh_type == elf.SHT_NOBITS) 0 else shdr.sh_size; |
| ... | ... | @@ -553,6 +563,9 @@ fn detectAllocCollision(self: *Elf, start: u64, size: u64) ?u64 { |
| 553 | 563 | fn allocatedSize(self: *Elf, start: u64) u64 { |
| 554 | 564 | if (start == 0) return 0; |
| 555 | 565 | var min_pos: u64 = std.math.maxInt(u64); |
| 566 | if (self.shdr_table_offset) |off| { |
| 567 | if (off > start and off < min_pos) min_pos = off; |
| 568 | } |
| 556 | 569 | for (self.shdrs.items) |section| { |
| 557 | 570 | if (section.sh_offset <= start) continue; |
| 558 | 571 | if (section.sh_offset < min_pos) min_pos = section.sh_offset; |
| ... | ... | @@ -1673,8 +1686,8 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 1673 | 1686 | } |
| 1674 | 1687 | } |
| 1675 | 1688 | |
| 1676 | | try self.writeShdrTable(); |
| 1677 | 1689 | try self.writePhdrTable(); |
| 1690 | try self.writeShdrTable(); |
| 1678 | 1691 | try self.writeAtoms(); |
| 1679 | 1692 | try self.writeSyntheticSections(); |
| 1680 | 1693 | |
| ... | ... | @@ -2773,14 +2786,20 @@ fn writeShdrTable(self: *Elf) !void { |
| 2773 | 2786 | .p32 => @alignOf(elf.Elf32_Shdr), |
| 2774 | 2787 | .p64 => @alignOf(elf.Elf64_Shdr), |
| 2775 | 2788 | }; |
| 2789 | |
| 2790 | const shoff = self.shdr_table_offset orelse 0; |
| 2776 | 2791 | const needed_size = self.shdrs.items.len * shsize; |
| 2777 | | var shoff: u64 = 0; |
| 2778 | | for (self.shdrs.items) |shdr| { |
| 2779 | | const off = mem.alignForward(u64, shdr.sh_offset + shdr.sh_size, shalign); |
| 2780 | | shoff = @max(shoff, off); |
| 2792 | |
| 2793 | if (needed_size > self.allocatedSize(shoff)) { |
| 2794 | self.shdr_table_offset = null; |
| 2795 | self.shdr_table_offset = self.findFreeSpace(needed_size, shalign); |
| 2781 | 2796 | } |
| 2782 | | self.shdr_table_offset = shoff; |
| 2783 | | log.debug("writing section headers from 0x{x} to 0x{x}", .{ shoff, shoff + needed_size }); |
| 2797 | |
| 2798 | log.debug("writing section headers from 0x{x} to 0x{x}", .{ |
| 2799 | self.shdr_table_offset.?, |
| 2800 | self.shdr_table_offset.? + needed_size, |
| 2801 | }); |
| 2802 | |
| 2784 | 2803 | switch (self.ptr_width) { |
| 2785 | 2804 | .p32 => { |
| 2786 | 2805 | const buf = try gpa.alloc(elf.Elf32_Shdr, self.shdrs.items.len); |