| ... | ... | @@ -411,12 +411,19 @@ fn populateMissingMetadata(self: *Coff) !void { |
| 411 | 411 | |
| 412 | 412 | fn allocateSection(self: *Coff, name: []const u8, size: u32, flags: coff.SectionHeaderFlags) !u16 { |
| 413 | 413 | const index = @intCast(u16, self.sections.slice().len); |
| 414 | | const off = self.findFreeSpace(size, self.page_size); // TODO: we overalign here |
| 415 | | log.debug("found {s} free space 0x{x} to 0x{x}", .{ name, off, off + size }); |
| 414 | const off = self.findFreeSpace(size, default_file_alignment); |
| 415 | const vaddr = self.findFreeSpaceVM(size, self.page_size); |
| 416 | log.debug("found {s} free space 0x{x} to 0x{x} (0x{x} - 0x{x})", .{ |
| 417 | name, |
| 418 | off, |
| 419 | off + size, |
| 420 | vaddr, |
| 421 | vaddr + size, |
| 422 | }); |
| 416 | 423 | var header = coff.SectionHeader{ |
| 417 | 424 | .name = undefined, |
| 418 | 425 | .virtual_size = size, |
| 419 | | .virtual_address = off, |
| 426 | .virtual_address = vaddr, |
| 420 | 427 | .size_of_raw_data = size, |
| 421 | 428 | .pointer_to_raw_data = off, |
| 422 | 429 | .pointer_to_relocations = 0, |
| ... | ... | @@ -513,16 +520,22 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u |
| 513 | 520 | const sect_capacity = self.allocatedSize(header.pointer_to_raw_data); |
| 514 | 521 | const needed_size: u32 = (vaddr + new_atom_size) - header.virtual_address; |
| 515 | 522 | if (needed_size > sect_capacity) { |
| 523 | // const new_offset = self.findFreeSpace(needed_size, self.page_size); |
| 524 | // const current_size = if (last_atom) |atom| blk: { |
| 525 | // const sym = last_atom.getSymbol(self); |
| 526 | // break :blk (sym.value + atom.size) - header.virtual_address; |
| 527 | // } else 0; |
| 528 | // log.debug("moving {s} from 0x{x} to 0x{x}", .{ header.pointer_to_raw_data, new_offset }); |
| 529 | // const amt = try self.base.file.?.copyRangeAll(header.pointer_to_raw_data, self.base.file.?, new_offset, current_size); |
| 530 | // if (amt != current_size) return error.InputOutput; |
| 531 | |
| 516 | 532 | @panic("TODO move section"); |
| 533 | // header.virtual_size = needed_size; |
| 534 | // header.size_of_raw_data = mem.alignForwardGeneric(u32, needed_size, default_file_alignment); |
| 517 | 535 | } |
| 518 | 536 | maybe_last_atom.* = atom; |
| 519 | | // header.virtual_size = needed_size; |
| 520 | | // header.size_of_raw_data = mem.alignForwardGeneric(u32, needed_size, default_file_alignment); |
| 521 | 537 | } |
| 522 | 538 | |
| 523 | | // if (header.getAlignment().? < alignment) { |
| 524 | | // header.setAlignment(alignment); |
| 525 | | // } |
| 526 | 539 | atom.size = new_atom_size; |
| 527 | 540 | atom.alignment = alignment; |
| 528 | 541 | |
| ... | ... | @@ -1778,14 +1791,15 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) { |
| 1778 | 1791 | } |
| 1779 | 1792 | |
| 1780 | 1793 | fn detectAllocCollision(self: *Coff, start: u32, size: u32) ?u32 { |
| 1781 | | const headers_size = self.getSizeOfHeaders(); |
| 1794 | const headers_size = @maximum(self.getSizeOfHeaders(), 0x1000); |
| 1782 | 1795 | if (start < headers_size) |
| 1783 | 1796 | return headers_size; |
| 1784 | 1797 | |
| 1785 | | const end = start + size; |
| 1798 | const end = start + padToIdeal(size); |
| 1786 | 1799 | |
| 1787 | 1800 | if (self.strtab_offset) |off| { |
| 1788 | | const increased_size = @intCast(u32, self.strtab.len()); |
| 1801 | const tight_size = @intCast(u32, self.strtab.len()); |
| 1802 | const increased_size = padToIdeal(tight_size); |
| 1789 | 1803 | const test_end = off + increased_size; |
| 1790 | 1804 | if (end > off and start < test_end) { |
| 1791 | 1805 | return test_end; |
| ... | ... | @@ -1793,7 +1807,8 @@ fn detectAllocCollision(self: *Coff, start: u32, size: u32) ?u32 { |
| 1793 | 1807 | } |
| 1794 | 1808 | |
| 1795 | 1809 | for (self.sections.items(.header)) |header| { |
| 1796 | | const increased_size = header.size_of_raw_data; |
| 1810 | const tight_size = header.size_of_raw_data; |
| 1811 | const increased_size = padToIdeal(tight_size); |
| 1797 | 1812 | const test_end = header.pointer_to_raw_data + increased_size; |
| 1798 | 1813 | if (end > header.pointer_to_raw_data and start < test_end) { |
| 1799 | 1814 | return test_end; |
| ... | ... | @@ -1803,7 +1818,7 @@ fn detectAllocCollision(self: *Coff, start: u32, size: u32) ?u32 { |
| 1803 | 1818 | return null; |
| 1804 | 1819 | } |
| 1805 | 1820 | |
| 1806 | | pub fn allocatedSize(self: *Coff, start: u32) u32 { |
| 1821 | fn allocatedSize(self: *Coff, start: u32) u32 { |
| 1807 | 1822 | if (start == 0) |
| 1808 | 1823 | return 0; |
| 1809 | 1824 | var min_pos: u32 = std.math.maxInt(u32); |
| ... | ... | @@ -1817,7 +1832,7 @@ pub fn allocatedSize(self: *Coff, start: u32) u32 { |
| 1817 | 1832 | return min_pos - start; |
| 1818 | 1833 | } |
| 1819 | 1834 | |
| 1820 | | pub fn findFreeSpace(self: *Coff, object_size: u32, min_alignment: u32) u32 { |
| 1835 | fn findFreeSpace(self: *Coff, object_size: u32, min_alignment: u32) u32 { |
| 1821 | 1836 | var start: u32 = 0; |
| 1822 | 1837 | while (self.detectAllocCollision(start, object_size)) |item_end| { |
| 1823 | 1838 | start = mem.alignForwardGeneric(u32, item_end, min_alignment); |
| ... | ... | @@ -1825,6 +1840,39 @@ pub fn findFreeSpace(self: *Coff, object_size: u32, min_alignment: u32) u32 { |
| 1825 | 1840 | return start; |
| 1826 | 1841 | } |
| 1827 | 1842 | |
| 1843 | fn detectAllocCollisionVM(self: *Coff, start: u32, size: u32) ?u32 { |
| 1844 | const headers_size = @maximum(self.getSizeOfHeaders(), 0x1000); |
| 1845 | if (start < headers_size) |
| 1846 | return headers_size; |
| 1847 | |
| 1848 | const end = start + size; |
| 1849 | |
| 1850 | if (self.strtab_offset) |off| { |
| 1851 | const increased_size = @intCast(u32, self.strtab.len()); |
| 1852 | const test_end = off + increased_size; |
| 1853 | if (end > off and start < test_end) { |
| 1854 | return test_end; |
| 1855 | } |
| 1856 | } |
| 1857 | |
| 1858 | for (self.sections.items(.header)) |header| { |
| 1859 | const increased_size = header.virtual_size; |
| 1860 | const test_end = header.virtual_address + increased_size; |
| 1861 | if (end > header.virtual_address and start < test_end) { |
| 1862 | return test_end; |
| 1863 | } |
| 1864 | } |
| 1865 | return null; |
| 1866 | } |
| 1867 | |
| 1868 | fn findFreeSpaceVM(self: *Coff, object_size: u32, min_alignment: u32) u32 { |
| 1869 | var start: u32 = 0; |
| 1870 | while (self.detectAllocCollisionVM(start, object_size)) |item_end| { |
| 1871 | start = mem.alignForwardGeneric(u32, item_end, min_alignment); |
| 1872 | } |
| 1873 | return start; |
| 1874 | } |
| 1875 | |
| 1828 | 1876 | inline fn getSizeOfHeaders(self: Coff) u32 { |
| 1829 | 1877 | const msdos_hdr_size = msdos_stub.len + 4; |
| 1830 | 1878 | return @intCast(u32, msdos_hdr_size + @sizeOf(coff.CoffHeader) + self.getOptionalHeaderSize() + |