authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-09-05 16:06:58+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-09-07 22:42:58+02:00
log79e51c5e4b5f9701676079ea23e67cc355a8d42c
treefb9d1bee5bbd5174c8381f4f0b48bb2209c686df
parent08f6546c8405dd7d9da80f857122f43f4d627a22

coff: differentiate between file space and VM space for alloc


1 files changed, 62 insertions(+), 14 deletions(-)

src/link/Coff.zig+62-14
...@@ -411,12 +411,19 @@ fn populateMissingMetadata(self: *Coff) !void {...@@ -411,12 +411,19 @@ fn populateMissingMetadata(self: *Coff) !void {
411411
412fn allocateSection(self: *Coff, name: []const u8, size: u32, flags: coff.SectionHeaderFlags) !u16 {412fn allocateSection(self: *Coff, name: []const u8, size: u32, flags: coff.SectionHeaderFlags) !u16 {
413 const index = @intCast(u16, self.sections.slice().len);413 const index = @intCast(u16, self.sections.slice().len);
414 const off = self.findFreeSpace(size, self.page_size); // TODO: we overalign here414 const off = self.findFreeSpace(size, default_file_alignment);
415 log.debug("found {s} free space 0x{x} to 0x{x}", .{ name, off, off + size });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 var header = coff.SectionHeader{423 var header = coff.SectionHeader{
417 .name = undefined,424 .name = undefined,
418 .virtual_size = size,425 .virtual_size = size,
419 .virtual_address = off,426 .virtual_address = vaddr,
420 .size_of_raw_data = size,427 .size_of_raw_data = size,
421 .pointer_to_raw_data = off,428 .pointer_to_raw_data = off,
422 .pointer_to_relocations = 0,429 .pointer_to_relocations = 0,
...@@ -513,16 +520,22 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u...@@ -513,16 +520,22 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u
513 const sect_capacity = self.allocatedSize(header.pointer_to_raw_data);520 const sect_capacity = self.allocatedSize(header.pointer_to_raw_data);
514 const needed_size: u32 = (vaddr + new_atom_size) - header.virtual_address;521 const needed_size: u32 = (vaddr + new_atom_size) - header.virtual_address;
515 if (needed_size > sect_capacity) {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 @panic("TODO move section");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 maybe_last_atom.* = atom;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 }
522538
523 // if (header.getAlignment().? < alignment) {
524 // header.setAlignment(alignment);
525 // }
526 atom.size = new_atom_size;539 atom.size = new_atom_size;
527 atom.alignment = alignment;540 atom.alignment = alignment;
528541
...@@ -1778,14 +1791,15 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {...@@ -1778,14 +1791,15 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {
1778}1791}
17791792
1780fn detectAllocCollision(self: *Coff, start: u32, size: u32) ?u32 {1793fn detectAllocCollision(self: *Coff, start: u32, size: u32) ?u32 {
1781 const headers_size = self.getSizeOfHeaders();1794 const headers_size = @maximum(self.getSizeOfHeaders(), 0x1000);
1782 if (start < headers_size)1795 if (start < headers_size)
1783 return headers_size;1796 return headers_size;
17841797
1785 const end = start + size;1798 const end = start + padToIdeal(size);
17861799
1787 if (self.strtab_offset) |off| {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 const test_end = off + increased_size;1803 const test_end = off + increased_size;
1790 if (end > off and start < test_end) {1804 if (end > off and start < test_end) {
1791 return test_end;1805 return test_end;
...@@ -1793,7 +1807,8 @@ fn detectAllocCollision(self: *Coff, start: u32, size: u32) ?u32 {...@@ -1793,7 +1807,8 @@ fn detectAllocCollision(self: *Coff, start: u32, size: u32) ?u32 {
1793 }1807 }
17941808
1795 for (self.sections.items(.header)) |header| {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 const test_end = header.pointer_to_raw_data + increased_size;1812 const test_end = header.pointer_to_raw_data + increased_size;
1798 if (end > header.pointer_to_raw_data and start < test_end) {1813 if (end > header.pointer_to_raw_data and start < test_end) {
1799 return test_end;1814 return test_end;
...@@ -1803,7 +1818,7 @@ fn detectAllocCollision(self: *Coff, start: u32, size: u32) ?u32 {...@@ -1803,7 +1818,7 @@ fn detectAllocCollision(self: *Coff, start: u32, size: u32) ?u32 {
1803 return null;1818 return null;
1804}1819}
18051820
1806pub fn allocatedSize(self: *Coff, start: u32) u32 {1821fn allocatedSize(self: *Coff, start: u32) u32 {
1807 if (start == 0)1822 if (start == 0)
1808 return 0;1823 return 0;
1809 var min_pos: u32 = std.math.maxInt(u32);1824 var min_pos: u32 = std.math.maxInt(u32);
...@@ -1817,7 +1832,7 @@ pub fn allocatedSize(self: *Coff, start: u32) u32 {...@@ -1817,7 +1832,7 @@ pub fn allocatedSize(self: *Coff, start: u32) u32 {
1817 return min_pos - start;1832 return min_pos - start;
1818}1833}
18191834
1820pub fn findFreeSpace(self: *Coff, object_size: u32, min_alignment: u32) u32 {1835fn findFreeSpace(self: *Coff, object_size: u32, min_alignment: u32) u32 {
1821 var start: u32 = 0;1836 var start: u32 = 0;
1822 while (self.detectAllocCollision(start, object_size)) |item_end| {1837 while (self.detectAllocCollision(start, object_size)) |item_end| {
1823 start = mem.alignForwardGeneric(u32, item_end, min_alignment);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,6 +1840,39 @@ pub fn findFreeSpace(self: *Coff, object_size: u32, min_alignment: u32) u32 {
1825 return start;1840 return start;
1826}1841}
18271842
1843fn 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
1868fn 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
1828inline fn getSizeOfHeaders(self: Coff) u32 {1876inline fn getSizeOfHeaders(self: Coff) u32 {
1829 const msdos_hdr_size = msdos_stub.len + 4;1877 const msdos_hdr_size = msdos_stub.len + 4;
1830 return @intCast(u32, msdos_hdr_size + @sizeOf(coff.CoffHeader) + self.getOptionalHeaderSize() +1878 return @intCast(u32, msdos_hdr_size + @sizeOf(coff.CoffHeader) + self.getOptionalHeaderSize() +