| ... | ... | @@ -520,19 +520,36 @@ fn allocateAtom(self: *Coff, atom: *Atom, new_atom_size: u32, alignment: u32) !u |
| 520 | 520 | const sect_capacity = self.allocatedSize(header.pointer_to_raw_data); |
| 521 | 521 | const needed_size: u32 = (vaddr + new_atom_size) - header.virtual_address; |
| 522 | 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 | | |
| 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); |
| 523 | const new_offset = self.findFreeSpace(needed_size, default_file_alignment); |
| 524 | const current_size = if (maybe_last_atom.*) |last_atom| blk: { |
| 525 | const sym = last_atom.getSymbol(self); |
| 526 | break :blk (sym.value + last_atom.size) - header.virtual_address; |
| 527 | } else 0; |
| 528 | log.debug("moving {s} from (0x{x} - 0x{x}) to (0x{x} - 0x{x})", .{ |
| 529 | self.getSectionName(header), |
| 530 | header.pointer_to_raw_data, |
| 531 | header.pointer_to_raw_data + current_size, |
| 532 | new_offset, |
| 533 | new_offset + current_size, |
| 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 | 553 | maybe_last_atom.* = atom; |
| 537 | 554 | } |
| 538 | 555 | |
| ... | ... | @@ -778,8 +795,9 @@ fn resolveRelocs(self: *Coff, atom: *Atom) !void { |
| 778 | 795 | |
| 779 | 796 | if (reloc.pcrel) { |
| 780 | 797 | const source_vaddr = source_sym.value + reloc.offset; |
| 781 | | const disp = target_vaddr_with_addend - source_vaddr - 4; |
| 782 | | try self.base.file.?.pwriteAll(mem.asBytes(&@intCast(u32, disp)), file_offset + reloc.offset); |
| 798 | const disp = |
| 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 | 801 | continue; |
| 784 | 802 | } |
| 785 | 803 | |
| ... | ... | @@ -1515,7 +1533,24 @@ fn writeBaseRelocations(self: *Coff) !void { |
| 1515 | 1533 | const header = &self.sections.items(.header)[self.reloc_section_index.?]; |
| 1516 | 1534 | const sect_capacity = self.allocatedSize(header.pointer_to_raw_data); |
| 1517 | 1535 | const needed_size = @intCast(u32, buffer.items.len); |
| 1518 | | assert(needed_size < sect_capacity); // TODO expand .reloc section |
| 1536 | 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; |
| 1519 | 1554 | |
| 1520 | 1555 | try self.base.file.?.pwriteAll(buffer.items, header.pointer_to_raw_data); |
| 1521 | 1556 | |
| ... | ... | @@ -1608,6 +1643,8 @@ fn writeImportTable(self: *Coff) !void { |
| 1608 | 1643 | } |
| 1609 | 1644 | |
| 1610 | 1645 | fn writeStrtab(self: *Coff) !void { |
| 1646 | if (self.strtab_offset == null) return; |
| 1647 | |
| 1611 | 1648 | const allocated_size = self.allocatedSize(self.strtab_offset.?); |
| 1612 | 1649 | const needed_size = @intCast(u32, self.strtab.len()); |
| 1613 | 1650 | |
| ... | ... | @@ -1840,6 +1877,20 @@ fn findFreeSpace(self: *Coff, object_size: u32, min_alignment: u32) u32 { |
| 1840 | 1877 | return start; |
| 1841 | 1878 | } |
| 1842 | 1879 | |
| 1880 | fn 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 | |
| 1843 | 1894 | fn detectAllocCollisionVM(self: *Coff, start: u32, size: u32) ?u32 { |
| 1844 | 1895 | const headers_size = @maximum(self.getSizeOfHeaders(), 0x1000); |
| 1845 | 1896 | if (start < headers_size) |