authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-09-06 09:59:42+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-09-07 22:42:58+02:00
log9116e0f7464c65912d758ebd58aad35d9b07cabc
tree14924660b95b5183909f3eef4c3207f0d48ebc2f
parent79e51c5e4b5f9701676079ea23e67cc355a8d42c

coff: find new file space for a section (file offsets)


1 files changed, 66 insertions(+), 15 deletions(-)

src/link/Coff.zig+66-15
...@@ -520,19 +520,36 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u...@@ -520,19 +520,36 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u
520 const sect_capacity = self.allocatedSize(header.pointer_to_raw_data);520 const sect_capacity = self.allocatedSize(header.pointer_to_raw_data);
521 const needed_size: u32 = (vaddr + new_atom_size) - header.virtual_address;521 const needed_size: u32 = (vaddr + new_atom_size) - header.virtual_address;
522 if (needed_size > sect_capacity) {522 if (needed_size > sect_capacity) {
523 // const new_offset = self.findFreeSpace(needed_size, self.page_size);523 const new_offset = self.findFreeSpace(needed_size, default_file_alignment);
524 // const current_size = if (last_atom) |atom| blk: {524 const current_size = if (maybe_last_atom.*) |last_atom| blk: {
525 // const sym = last_atom.getSymbol(self);525 const sym = last_atom.getSymbol(self);
526 // break :blk (sym.value + atom.size) - header.virtual_address;526 break :blk (sym.value + last_atom.size) - header.virtual_address;
527 // } else 0;527 } else 0;
528 // log.debug("moving {s} from 0x{x} to 0x{x}", .{ header.pointer_to_raw_data, new_offset });528 log.debug("moving {s} from (0x{x} - 0x{x}) to (0x{x} - 0x{x})", .{
529 // const amt = try self.base.file.?.copyRangeAll(header.pointer_to_raw_data, self.base.file.?, new_offset, current_size);529 self.getSectionName(header),
530 // if (amt != current_size) return error.InputOutput;530 header.pointer_to_raw_data,
531531 header.pointer_to_raw_data + current_size,
532 @panic("TODO move section");532 new_offset,
533 // header.virtual_size = needed_size;533 new_offset + current_size,
534 // header.size_of_raw_data = mem.alignForwardGeneric(u32, needed_size, default_file_alignment);534 });
535 const amt = try self.base.file.?.copyRangeAll(
536 header.pointer_to_raw_data,
537 self.base.file.?,
538 new_offset,
539 current_size,
540 );
541 if (amt != current_size) return error.InputOutput;
542 header.pointer_to_raw_data = new_offset;
543 }
544
545 const sect_vm_capacity = self.allocatedSizeVM(header.virtual_address);
546 if (needed_size > sect_vm_capacity) {
547 log.err("needed {x}, available {x}", .{ needed_size, sect_vm_capacity });
548 @panic("TODO expand section in virtual address space");
535 }549 }
550
551 header.virtual_size = @maximum(header.virtual_size, needed_size);
552 header.size_of_raw_data = needed_size;
536 maybe_last_atom.* = atom;553 maybe_last_atom.* = atom;
537 }554 }
538555
...@@ -778,8 +795,9 @@ fn resolveRelocs(self: *Coff, atom: *Atom) !void {...@@ -778,8 +795,9 @@ fn resolveRelocs(self: *Coff, atom: *Atom) !void {
778795
779 if (reloc.pcrel) {796 if (reloc.pcrel) {
780 const source_vaddr = source_sym.value + reloc.offset;797 const source_vaddr = source_sym.value + reloc.offset;
781 const disp = target_vaddr_with_addend - source_vaddr - 4;798 const disp =
782 try self.base.file.?.pwriteAll(mem.asBytes(&@intCast(u32, disp)), file_offset + reloc.offset);799 @intCast(i32, target_vaddr_with_addend) - @intCast(i32, source_vaddr) - 4;
800 try self.base.file.?.pwriteAll(mem.asBytes(&disp), file_offset + reloc.offset);
783 continue;801 continue;
784 }802 }
785803
...@@ -1515,7 +1533,24 @@ fn writeBaseRelocations(self: *Coff) !void {...@@ -1515,7 +1533,24 @@ fn writeBaseRelocations(self: *Coff) !void {
1515 const header = &self.sections.items(.header)[self.reloc_section_index.?];1533 const header = &self.sections.items(.header)[self.reloc_section_index.?];
1516 const sect_capacity = self.allocatedSize(header.pointer_to_raw_data);1534 const sect_capacity = self.allocatedSize(header.pointer_to_raw_data);
1517 const needed_size = @intCast(u32, buffer.items.len);1535 const needed_size = @intCast(u32, buffer.items.len);
1518 assert(needed_size < sect_capacity); // TODO expand .reloc section1536 if (needed_size > sect_capacity) {
1537 const new_offset = self.findFreeSpace(needed_size, default_file_alignment);
1538 log.debug("writing {s} at 0x{x} to 0x{x} (0x{x} - 0x{x})", .{
1539 self.getSectionName(header),
1540 header.pointer_to_raw_data,
1541 header.pointer_to_raw_data + needed_size,
1542 new_offset,
1543 new_offset + needed_size,
1544 });
1545 header.pointer_to_raw_data = new_offset;
1546
1547 const sect_vm_capacity = self.allocatedSizeVM(header.virtual_address);
1548 if (needed_size > sect_vm_capacity) {
1549 @panic("TODO expand section in virtual address space");
1550 }
1551 }
1552 header.virtual_size = @maximum(header.virtual_size, needed_size);
1553 header.size_of_raw_data = needed_size;
15191554
1520 try self.base.file.?.pwriteAll(buffer.items, header.pointer_to_raw_data);1555 try self.base.file.?.pwriteAll(buffer.items, header.pointer_to_raw_data);
15211556
...@@ -1608,6 +1643,8 @@ fn writeImportTable(self: *Coff) !void {...@@ -1608,6 +1643,8 @@ fn writeImportTable(self: *Coff) !void {
1608}1643}
16091644
1610fn writeStrtab(self: *Coff) !void {1645fn writeStrtab(self: *Coff) !void {
1646 if (self.strtab_offset == null) return;
1647
1611 const allocated_size = self.allocatedSize(self.strtab_offset.?);1648 const allocated_size = self.allocatedSize(self.strtab_offset.?);
1612 const needed_size = @intCast(u32, self.strtab.len());1649 const needed_size = @intCast(u32, self.strtab.len());
16131650
...@@ -1840,6 +1877,20 @@ fn findFreeSpace(self: *Coff, object_size: u32, min_alignment: u32) u32 {...@@ -1840,6 +1877,20 @@ fn findFreeSpace(self: *Coff, object_size: u32, min_alignment: u32) u32 {
1840 return start;1877 return start;
1841}1878}
18421879
1880fn allocatedSizeVM(self: *Coff, start: u32) u32 {
1881 if (start == 0)
1882 return 0;
1883 var min_pos: u32 = std.math.maxInt(u32);
1884 if (self.strtab_offset) |off| {
1885 if (off > start and off < min_pos) min_pos = off;
1886 }
1887 for (self.sections.items(.header)) |header| {
1888 if (header.virtual_address <= start) continue;
1889 if (header.virtual_address < min_pos) min_pos = header.virtual_address;
1890 }
1891 return min_pos - start;
1892}
1893
1843fn detectAllocCollisionVM(self: *Coff, start: u32, size: u32) ?u32 {1894fn detectAllocCollisionVM(self: *Coff, start: u32, size: u32) ?u32 {
1844 const headers_size = @maximum(self.getSizeOfHeaders(), 0x1000);1895 const headers_size = @maximum(self.getSizeOfHeaders(), 0x1000);
1845 if (start < headers_size)1896 if (start < headers_size)