| ... | ... | @@ -107,12 +107,6 @@ const HotUpdateState = struct { |
| 107 | 107 | loaded_base_address: ?std.os.windows.HMODULE = null, |
| 108 | 108 | }; |
| 109 | 109 | |
| 110 | | const Entry = struct { |
| 111 | | target: SymbolWithLoc, |
| 112 | | // Index into the synthetic symbol table (i.e., file == null). |
| 113 | | sym_index: u32, |
| 114 | | }; |
| 115 | | |
| 116 | 110 | const RelocTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation)); |
| 117 | 111 | const BaseRelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); |
| 118 | 112 | const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); |
| ... | ... | @@ -843,17 +837,17 @@ fn writeOffsetTableEntry(self: *Coff, index: usize) !void { |
| 843 | 837 | const file_offset = header.pointer_to_raw_data + entry_offset; |
| 844 | 838 | const vmaddr = header.virtual_address + entry_offset; |
| 845 | 839 | |
| 846 | | log.debug("writing GOT entry {d}: @{x} => {x}", .{ index, vmaddr, entry_value }); |
| 840 | log.debug("writing GOT entry {d}: @{x} => {x}", .{ index, vmaddr, entry_value + self.getImageBase() }); |
| 847 | 841 | |
| 848 | 842 | switch (self.ptr_width) { |
| 849 | 843 | .p32 => { |
| 850 | 844 | var buf: [4]u8 = undefined; |
| 851 | | mem.writeIntLittle(u32, &buf, @intCast(u32, entry_value)); |
| 845 | mem.writeIntLittle(u32, &buf, @intCast(u32, entry_value + self.getImageBase())); |
| 852 | 846 | try self.base.file.?.pwriteAll(&buf, file_offset); |
| 853 | 847 | }, |
| 854 | 848 | .p64 => { |
| 855 | 849 | var buf: [8]u8 = undefined; |
| 856 | | mem.writeIntLittle(u64, &buf, entry_value); |
| 850 | mem.writeIntLittle(u64, &buf, entry_value + self.getImageBase()); |
| 857 | 851 | try self.base.file.?.pwriteAll(&buf, file_offset); |
| 858 | 852 | }, |
| 859 | 853 | } |
| ... | ... | @@ -881,12 +875,14 @@ fn writeOffsetTableEntry(self: *Coff, index: usize) !void { |
| 881 | 875 | switch (self.ptr_width) { |
| 882 | 876 | .p32 => { |
| 883 | 877 | var buf: [4]u8 = undefined; |
| 878 | mem.writeIntLittle(u32, &buf, @intCast(u32, entry_value + slide)); |
| 884 | 879 | writeMem(handle, pvaddr, &buf) catch |err| { |
| 885 | 880 | log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)}); |
| 886 | 881 | }; |
| 887 | 882 | }, |
| 888 | 883 | .p64 => { |
| 889 | 884 | var buf: [8]u8 = undefined; |
| 885 | mem.writeIntLittle(u64, &buf, entry_value + slide); |
| 890 | 886 | writeMem(handle, pvaddr, &buf) catch |err| { |
| 891 | 887 | log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)}); |
| 892 | 888 | }; |
| ... | ... | @@ -1744,69 +1740,82 @@ pub fn updateDeclLineNumber(self: *Coff, module: *Module, decl_index: Module.Dec |
| 1744 | 1740 | fn writeBaseRelocations(self: *Coff) !void { |
| 1745 | 1741 | const gpa = self.base.allocator; |
| 1746 | 1742 | |
| 1747 | | var pages = std.AutoHashMap(u32, std.ArrayList(coff.BaseRelocation)).init(gpa); |
| 1743 | var page_table = std.AutoHashMap(u32, std.ArrayList(coff.BaseRelocation)).init(gpa); |
| 1748 | 1744 | defer { |
| 1749 | | var it = pages.valueIterator(); |
| 1745 | var it = page_table.valueIterator(); |
| 1750 | 1746 | while (it.next()) |inner| { |
| 1751 | 1747 | inner.deinit(); |
| 1752 | 1748 | } |
| 1753 | | pages.deinit(); |
| 1749 | page_table.deinit(); |
| 1754 | 1750 | } |
| 1755 | 1751 | |
| 1756 | | var it = self.base_relocs.iterator(); |
| 1757 | | while (it.next()) |entry| { |
| 1758 | | const atom_index = entry.key_ptr.*; |
| 1759 | | const atom = self.getAtom(atom_index); |
| 1760 | | const sym = atom.getSymbol(self); |
| 1761 | | const offsets = entry.value_ptr.*; |
| 1762 | | |
| 1763 | | for (offsets.items) |offset| { |
| 1764 | | const rva = sym.value + offset; |
| 1765 | | const page = mem.alignBackwardGeneric(u32, rva, self.page_size); |
| 1766 | | const gop = try pages.getOrPut(page); |
| 1767 | | if (!gop.found_existing) { |
| 1768 | | gop.value_ptr.* = std.ArrayList(coff.BaseRelocation).init(gpa); |
| 1752 | { |
| 1753 | var it = self.base_relocs.iterator(); |
| 1754 | while (it.next()) |entry| { |
| 1755 | const atom_index = entry.key_ptr.*; |
| 1756 | const atom = self.getAtom(atom_index); |
| 1757 | const sym = atom.getSymbol(self); |
| 1758 | const offsets = entry.value_ptr.*; |
| 1759 | |
| 1760 | for (offsets.items) |offset| { |
| 1761 | const rva = sym.value + offset; |
| 1762 | const page = mem.alignBackwardGeneric(u32, rva, self.page_size); |
| 1763 | const gop = try page_table.getOrPut(page); |
| 1764 | if (!gop.found_existing) { |
| 1765 | gop.value_ptr.* = std.ArrayList(coff.BaseRelocation).init(gpa); |
| 1766 | } |
| 1767 | try gop.value_ptr.append(.{ |
| 1768 | .offset = @intCast(u12, rva - page), |
| 1769 | .type = .DIR64, |
| 1770 | }); |
| 1769 | 1771 | } |
| 1770 | | try gop.value_ptr.append(.{ |
| 1771 | | .offset = @intCast(u12, rva - page), |
| 1772 | | .type = .DIR64, |
| 1773 | | }); |
| 1774 | 1772 | } |
| 1775 | | } |
| 1776 | 1773 | |
| 1777 | | { |
| 1778 | | const header = &self.sections.items(.header)[self.got_section_index.?]; |
| 1779 | | for (self.got_table.entries.items, 0..) |entry, index| { |
| 1780 | | if (!self.got_table.lookup.contains(entry)) continue; |
| 1774 | { |
| 1775 | const header = &self.sections.items(.header)[self.got_section_index.?]; |
| 1776 | for (self.got_table.entries.items, 0..) |entry, index| { |
| 1777 | if (!self.got_table.lookup.contains(entry)) continue; |
| 1781 | 1778 | |
| 1782 | | const sym = self.getSymbol(entry); |
| 1783 | | if (sym.section_number == .UNDEFINED) continue; |
| 1779 | const sym = self.getSymbol(entry); |
| 1780 | if (sym.section_number == .UNDEFINED) continue; |
| 1784 | 1781 | |
| 1785 | | const rva = @intCast(u32, header.virtual_address + index * self.ptr_width.size()); |
| 1786 | | const page = mem.alignBackwardGeneric(u32, rva, self.page_size); |
| 1787 | | const gop = try pages.getOrPut(page); |
| 1788 | | if (!gop.found_existing) { |
| 1789 | | gop.value_ptr.* = std.ArrayList(coff.BaseRelocation).init(gpa); |
| 1782 | const rva = @intCast(u32, header.virtual_address + index * self.ptr_width.size()); |
| 1783 | const page = mem.alignBackwardGeneric(u32, rva, self.page_size); |
| 1784 | const gop = try page_table.getOrPut(page); |
| 1785 | if (!gop.found_existing) { |
| 1786 | gop.value_ptr.* = std.ArrayList(coff.BaseRelocation).init(gpa); |
| 1787 | } |
| 1788 | try gop.value_ptr.append(.{ |
| 1789 | .offset = @intCast(u12, rva - page), |
| 1790 | .type = .DIR64, |
| 1791 | }); |
| 1790 | 1792 | } |
| 1791 | | try gop.value_ptr.append(.{ |
| 1792 | | .offset = @intCast(u12, rva - page), |
| 1793 | | .type = .DIR64, |
| 1794 | | }); |
| 1795 | 1793 | } |
| 1796 | 1794 | } |
| 1797 | 1795 | |
| 1796 | // Sort pages by address. |
| 1797 | var pages = try std.ArrayList(u32).initCapacity(gpa, page_table.count()); |
| 1798 | defer pages.deinit(); |
| 1799 | { |
| 1800 | var it = page_table.keyIterator(); |
| 1801 | while (it.next()) |page| { |
| 1802 | pages.appendAssumeCapacity(page.*); |
| 1803 | } |
| 1804 | } |
| 1805 | std.sort.sort(u32, pages.items, {}, std.sort.asc(u32)); |
| 1806 | |
| 1798 | 1807 | var buffer = std.ArrayList(u8).init(gpa); |
| 1799 | 1808 | defer buffer.deinit(); |
| 1800 | 1809 | |
| 1801 | | var pages_it = pages.iterator(); |
| 1802 | | while (pages_it.next()) |entry| { |
| 1810 | for (pages.items) |page| { |
| 1811 | const entries = page_table.getPtr(page).?; |
| 1803 | 1812 | // Pad to required 4byte alignment |
| 1804 | 1813 | if (!mem.isAlignedGeneric( |
| 1805 | 1814 | usize, |
| 1806 | | entry.value_ptr.items.len * @sizeOf(coff.BaseRelocation), |
| 1815 | entries.items.len * @sizeOf(coff.BaseRelocation), |
| 1807 | 1816 | @sizeOf(u32), |
| 1808 | 1817 | )) { |
| 1809 | | try entry.value_ptr.append(.{ |
| 1818 | try entries.append(.{ |
| 1810 | 1819 | .offset = 0, |
| 1811 | 1820 | .type = .ABSOLUTE, |
| 1812 | 1821 | }); |
| ... | ... | @@ -1814,14 +1823,14 @@ fn writeBaseRelocations(self: *Coff) !void { |
| 1814 | 1823 | |
| 1815 | 1824 | const block_size = @intCast( |
| 1816 | 1825 | u32, |
| 1817 | | entry.value_ptr.items.len * @sizeOf(coff.BaseRelocation) + @sizeOf(coff.BaseRelocationDirectoryEntry), |
| 1826 | entries.items.len * @sizeOf(coff.BaseRelocation) + @sizeOf(coff.BaseRelocationDirectoryEntry), |
| 1818 | 1827 | ); |
| 1819 | 1828 | try buffer.ensureUnusedCapacity(block_size); |
| 1820 | 1829 | buffer.appendSliceAssumeCapacity(mem.asBytes(&coff.BaseRelocationDirectoryEntry{ |
| 1821 | | .page_rva = entry.key_ptr.*, |
| 1830 | .page_rva = page, |
| 1822 | 1831 | .block_size = block_size, |
| 1823 | 1832 | })); |
| 1824 | | buffer.appendSliceAssumeCapacity(mem.sliceAsBytes(entry.value_ptr.items)); |
| 1833 | buffer.appendSliceAssumeCapacity(mem.sliceAsBytes(entries.items)); |
| 1825 | 1834 | } |
| 1826 | 1835 | |
| 1827 | 1836 | const header = &self.sections.items(.header)[self.reloc_section_index.?]; |