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 {
411411
412412fn allocateSection(self: *Coff, name: []const u8, size: u32, flags: coff.SectionHeaderFlags) !u16 {
413413 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 });
416423 var header = coff.SectionHeader{
417424 .name = undefined,
418425 .virtual_size = size,
419 .virtual_address = off,
426 .virtual_address = vaddr,
420427 .size_of_raw_data = size,
421428 .pointer_to_raw_data = off,
422429 .pointer_to_relocations = 0,
......@@ -513,16 +520,22 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u
513520 const sect_capacity = self.allocatedSize(header.pointer_to_raw_data);
514521 const needed_size: u32 = (vaddr + new_atom_size) - header.virtual_address;
515522 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
516532 @panic("TODO move section");
533 // header.virtual_size = needed_size;
534 // header.size_of_raw_data = mem.alignForwardGeneric(u32, needed_size, default_file_alignment);
517535 }
518536 maybe_last_atom.* = atom;
519 // header.virtual_size = needed_size;
520 // header.size_of_raw_data = mem.alignForwardGeneric(u32, needed_size, default_file_alignment);
521537 }
522538
523 // if (header.getAlignment().? < alignment) {
524 // header.setAlignment(alignment);
525 // }
526539 atom.size = new_atom_size;
527540 atom.alignment = alignment;
528541
......@@ -1778,14 +1791,15 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) {
17781791}
17791792
17801793fn detectAllocCollision(self: *Coff, start: u32, size: u32) ?u32 {
1781 const headers_size = self.getSizeOfHeaders();
1794 const headers_size = @maximum(self.getSizeOfHeaders(), 0x1000);
17821795 if (start < headers_size)
17831796 return headers_size;
17841797
1785 const end = start + size;
1798 const end = start + padToIdeal(size);
17861799
17871800 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);
17891803 const test_end = off + increased_size;
17901804 if (end > off and start < test_end) {
17911805 return test_end;
......@@ -1793,7 +1807,8 @@ fn detectAllocCollision(self: *Coff, start: u32, size: u32) ?u32 {
17931807 }
17941808
17951809 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);
17971812 const test_end = header.pointer_to_raw_data + increased_size;
17981813 if (end > header.pointer_to_raw_data and start < test_end) {
17991814 return test_end;
......@@ -1803,7 +1818,7 @@ fn detectAllocCollision(self: *Coff, start: u32, size: u32) ?u32 {
18031818 return null;
18041819}
18051820
1806pub fn allocatedSize(self: *Coff, start: u32) u32 {
1821fn allocatedSize(self: *Coff, start: u32) u32 {
18071822 if (start == 0)
18081823 return 0;
18091824 var min_pos: u32 = std.math.maxInt(u32);
......@@ -1817,7 +1832,7 @@ pub fn allocatedSize(self: *Coff, start: u32) u32 {
18171832 return min_pos - start;
18181833}
18191834
1820pub fn findFreeSpace(self: *Coff, object_size: u32, min_alignment: u32) u32 {
1835fn findFreeSpace(self: *Coff, object_size: u32, min_alignment: u32) u32 {
18211836 var start: u32 = 0;
18221837 while (self.detectAllocCollision(start, object_size)) |item_end| {
18231838 start = mem.alignForwardGeneric(u32, item_end, min_alignment);
......@@ -1825,6 +1840,39 @@ pub fn findFreeSpace(self: *Coff, object_size: u32, min_alignment: u32) u32 {
18251840 return start;
18261841}
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
18281876inline fn getSizeOfHeaders(self: Coff) u32 {
18291877 const msdos_hdr_size = msdos_stub.len + 4;
18301878 return @intCast(u32, msdos_hdr_size + @sizeOf(coff.CoffHeader) + self.getOptionalHeaderSize() +