authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-27 16:19:43+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-03-28 12:28:48+02:00
logd2040b2763ad2684dcacce9acd8f8511bf9db397
tree5c990f10078ef4c79eb973c12f87541e1e65553b
parent28d6dd75ac151449ddc29f3937a9e333f0a608c1

coff: grow .idata if required


1 files changed, 18 insertions(+), 11 deletions(-)

src/link/Coff.zig+18-11
...@@ -1625,12 +1625,10 @@ fn writeBaseRelocations(self: *Coff) !void {...@@ -1625,12 +1625,10 @@ fn writeBaseRelocations(self: *Coff) !void {
1625 const needed_size = @intCast(u32, buffer.items.len);1625 const needed_size = @intCast(u32, buffer.items.len);
1626 if (needed_size > sect_capacity) {1626 if (needed_size > sect_capacity) {
1627 const new_offset = self.findFreeSpace(needed_size, default_file_alignment);1627 const new_offset = self.findFreeSpace(needed_size, default_file_alignment);
1628 log.debug("writing {s} at 0x{x} to 0x{x} (0x{x} - 0x{x})", .{1628 log.debug("moving {s} from 0x{x} to 0x{x}", .{
1629 self.getSectionName(header),1629 self.getSectionName(header),
1630 header.pointer_to_raw_data,1630 header.pointer_to_raw_data,
1631 header.pointer_to_raw_data + needed_size,
1632 new_offset,1631 new_offset,
1633 new_offset + needed_size,
1634 });1632 });
1635 header.pointer_to_raw_data = new_offset;1633 header.pointer_to_raw_data = new_offset;
16361634
...@@ -1656,11 +1654,11 @@ fn writeImportTable(self: *Coff) !void {...@@ -1656,11 +1654,11 @@ fn writeImportTable(self: *Coff) !void {
16561654
1657 const gpa = self.base.allocator;1655 const gpa = self.base.allocator;
16581656
1659 const section = self.sections.get(self.idata_section_index.?);1657 const last_atom_index = self.sections.items(.last_atom_index)[self.idata_section_index.?] orelse return;
1660 const last_atom_index = section.last_atom_index orelse return;1658 const header = &self.sections.items(.header)[self.idata_section_index.?];
1661 const last_atom = self.getAtom(last_atom_index);1659 const last_atom = self.getAtom(last_atom_index);
16621660
1663 const iat_rva = section.header.virtual_address;1661 const iat_rva = header.virtual_address;
1664 const iat_size = last_atom.getSymbol(self).value + last_atom.size * 2 - iat_rva; // account for sentinel zero pointer1662 const iat_size = last_atom.getSymbol(self).value + last_atom.size * 2 - iat_rva; // account for sentinel zero pointer
16651663
1666 const dll_name = "KERNEL32.dll";1664 const dll_name = "KERNEL32.dll";
...@@ -1696,9 +1694,18 @@ fn writeImportTable(self: *Coff) !void {...@@ -1696,9 +1694,18 @@ fn writeImportTable(self: *Coff) !void {
1696 try lookup_table.append(.{ .name_table_rva = 0 }); // the sentinel1694 try lookup_table.append(.{ .name_table_rva = 0 }); // the sentinel
16971695
1698 const dir_entry_size = @sizeOf(coff.ImportDirectoryEntry) + lookup_table.items.len * @sizeOf(coff.ImportLookupEntry64.ByName) + names_table.items.len + dll_name.len + 1;1696 const dir_entry_size = @sizeOf(coff.ImportDirectoryEntry) + lookup_table.items.len * @sizeOf(coff.ImportLookupEntry64.ByName) + names_table.items.len + dll_name.len + 1;
1699 const needed_size = iat_size + dir_entry_size + @sizeOf(coff.ImportDirectoryEntry);1697 const sect_capacity = self.allocatedSize(header.pointer_to_raw_data);
1700 const sect_capacity = self.allocatedSize(section.header.pointer_to_raw_data);1698 const needed_size = @intCast(u32, iat_size + dir_entry_size + @sizeOf(coff.ImportDirectoryEntry));
1701 assert(needed_size < sect_capacity); // TODO: implement expanding .idata section1699 if (needed_size > sect_capacity) {
1700 const new_offset = self.findFreeSpace(needed_size, default_file_alignment);
1701 log.debug("moving .idata from 0x{x} to 0x{x}", .{ header.pointer_to_raw_data, new_offset });
1702 header.pointer_to_raw_data = new_offset;
1703
1704 const sect_vm_capacity = self.allocatedVirtualSize(header.virtual_address);
1705 if (needed_size > sect_vm_capacity) {
1706 try self.growSectionVM(self.idata_section_index.?, needed_size);
1707 }
1708 }
17021709
1703 // Fixup offsets1710 // Fixup offsets
1704 const base_rva = iat_rva + iat_size;1711 const base_rva = iat_rva + iat_size;
...@@ -1719,10 +1726,10 @@ fn writeImportTable(self: *Coff) !void {...@@ -1719,10 +1726,10 @@ fn writeImportTable(self: *Coff) !void {
1719 buffer.appendSliceAssumeCapacity(dll_name);1726 buffer.appendSliceAssumeCapacity(dll_name);
1720 buffer.appendAssumeCapacity(0);1727 buffer.appendAssumeCapacity(0);
17211728
1722 try self.base.file.?.pwriteAll(buffer.items, section.header.pointer_to_raw_data + iat_size);1729 try self.base.file.?.pwriteAll(buffer.items, header.pointer_to_raw_data + iat_size);
1723 // Override the IAT atoms1730 // Override the IAT atoms
1724 // TODO: we should rewrite only dirtied atoms, but that's for way later1731 // TODO: we should rewrite only dirtied atoms, but that's for way later
1725 try self.base.file.?.pwriteAll(mem.sliceAsBytes(lookup_table.items), section.header.pointer_to_raw_data);1732 try self.base.file.?.pwriteAll(mem.sliceAsBytes(lookup_table.items), header.pointer_to_raw_data);
17261733
1727 self.data_directories[@enumToInt(coff.DirectoryEntry.IMPORT)] = .{1734 self.data_directories[@enumToInt(coff.DirectoryEntry.IMPORT)] = .{
1728 .virtual_address = iat_rva + iat_size,1735 .virtual_address = iat_rva + iat_size,