| ... | @@ -107,12 +107,6 @@ const HotUpdateState = struct { | ... | @@ -107,12 +107,6 @@ const HotUpdateState = struct { |
| 107 | loaded_base_address: ?std.os.windows.HMODULE = null, | 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 | const RelocTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation)); | 110 | const RelocTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation)); |
| 117 | const BaseRelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); | 111 | const BaseRelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); |
| 118 | const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); | 112 | const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); |
| ... | @@ -843,17 +837,17 @@ fn writeOffsetTableEntry(self: *Coff, index: usize) !void { | ... | @@ -843,17 +837,17 @@ fn writeOffsetTableEntry(self: *Coff, index: usize) !void { |
| 843 | const file_offset = header.pointer_to_raw_data + entry_offset; | 837 | const file_offset = header.pointer_to_raw_data + entry_offset; |
| 844 | const vmaddr = header.virtual_address + entry_offset; | 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 | switch (self.ptr_width) { | 842 | switch (self.ptr_width) { |
| 849 | .p32 => { | 843 | .p32 => { |
| 850 | var buf: [4]u8 = undefined; | 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 | try self.base.file.?.pwriteAll(&buf, file_offset); | 846 | try self.base.file.?.pwriteAll(&buf, file_offset); |
| 853 | }, | 847 | }, |
| 854 | .p64 => { | 848 | .p64 => { |
| 855 | var buf: [8]u8 = undefined; | 849 | var buf: [8]u8 = undefined; |
| 856 | mem.writeIntLittle(u64, &buf, entry_value); | 850 | mem.writeIntLittle(u64, &buf, entry_value + self.getImageBase()); |
| 857 | try self.base.file.?.pwriteAll(&buf, file_offset); | 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,12 +875,14 @@ fn writeOffsetTableEntry(self: *Coff, index: usize) !void { |
| 881 | switch (self.ptr_width) { | 875 | switch (self.ptr_width) { |
| 882 | .p32 => { | 876 | .p32 => { |
| 883 | var buf: [4]u8 = undefined; | 877 | var buf: [4]u8 = undefined; |
| | 878 | mem.writeIntLittle(u32, &buf, @intCast(u32, entry_value + slide)); |
| 884 | writeMem(handle, pvaddr, &buf) catch |err| { | 879 | writeMem(handle, pvaddr, &buf) catch |err| { |
| 885 | log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)}); | 880 | log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)}); |
| 886 | }; | 881 | }; |
| 887 | }, | 882 | }, |
| 888 | .p64 => { | 883 | .p64 => { |
| 889 | var buf: [8]u8 = undefined; | 884 | var buf: [8]u8 = undefined; |
| | 885 | mem.writeIntLittle(u64, &buf, entry_value + slide); |
| 890 | writeMem(handle, pvaddr, &buf) catch |err| { | 886 | writeMem(handle, pvaddr, &buf) catch |err| { |
| 891 | log.warn("writing to protected memory failed with error: {s}", .{@errorName(err)}); | 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,69 +1740,82 @@ pub fn updateDeclLineNumber(self: *Coff, module: *Module, decl_index: Module.Dec |
| 1744 | fn writeBaseRelocations(self: *Coff) !void { | 1740 | fn writeBaseRelocations(self: *Coff) !void { |
| 1745 | const gpa = self.base.allocator; | 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 | defer { | 1744 | defer { |
| 1749 | var it = pages.valueIterator(); | 1745 | var it = page_table.valueIterator(); |
| 1750 | while (it.next()) |inner| { | 1746 | while (it.next()) |inner| { |
| 1751 | inner.deinit(); | 1747 | inner.deinit(); |
| 1752 | } | 1748 | } |
| 1753 | pages.deinit(); | 1749 | page_table.deinit(); |
| 1754 | } | 1750 | } |
| 1755 | | 1751 | |
| 1756 | var it = self.base_relocs.iterator(); | 1752 | { |
| 1757 | while (it.next()) |entry| { | 1753 | var it = self.base_relocs.iterator(); |
| 1758 | const atom_index = entry.key_ptr.*; | 1754 | while (it.next()) |entry| { |
| 1759 | const atom = self.getAtom(atom_index); | 1755 | const atom_index = entry.key_ptr.*; |
| 1760 | const sym = atom.getSymbol(self); | 1756 | const atom = self.getAtom(atom_index); |
| 1761 | const offsets = entry.value_ptr.*; | 1757 | const sym = atom.getSymbol(self); |
| 1762 | | 1758 | const offsets = entry.value_ptr.*; |
| 1763 | for (offsets.items) |offset| { | 1759 | |
| 1764 | const rva = sym.value + offset; | 1760 | for (offsets.items) |offset| { |
| 1765 | const page = mem.alignBackwardGeneric(u32, rva, self.page_size); | 1761 | const rva = sym.value + offset; |
| 1766 | const gop = try pages.getOrPut(page); | 1762 | const page = mem.alignBackwardGeneric(u32, rva, self.page_size); |
| 1767 | if (!gop.found_existing) { | 1763 | const gop = try page_table.getOrPut(page); |
| 1768 | gop.value_ptr.* = std.ArrayList(coff.BaseRelocation).init(gpa); | 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 | { | 1774 | { |
| 1778 | const header = &self.sections.items(.header)[self.got_section_index.?]; | 1775 | const header = &self.sections.items(.header)[self.got_section_index.?]; |
| 1779 | for (self.got_table.entries.items, 0..) |entry, index| { | 1776 | for (self.got_table.entries.items, 0..) |entry, index| { |
| 1780 | if (!self.got_table.lookup.contains(entry)) continue; | 1777 | if (!self.got_table.lookup.contains(entry)) continue; |
| 1781 | | 1778 | |
| 1782 | const sym = self.getSymbol(entry); | 1779 | const sym = self.getSymbol(entry); |
| 1783 | if (sym.section_number == .UNDEFINED) continue; | 1780 | if (sym.section_number == .UNDEFINED) continue; |
| 1784 | | 1781 | |
| 1785 | const rva = @intCast(u32, header.virtual_address + index * self.ptr_width.size()); | 1782 | const rva = @intCast(u32, header.virtual_address + index * self.ptr_width.size()); |
| 1786 | const page = mem.alignBackwardGeneric(u32, rva, self.page_size); | 1783 | const page = mem.alignBackwardGeneric(u32, rva, self.page_size); |
| 1787 | const gop = try pages.getOrPut(page); | 1784 | const gop = try page_table.getOrPut(page); |
| 1788 | if (!gop.found_existing) { | 1785 | if (!gop.found_existing) { |
| 1789 | gop.value_ptr.* = std.ArrayList(coff.BaseRelocation).init(gpa); | 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 | var buffer = std.ArrayList(u8).init(gpa); | 1807 | var buffer = std.ArrayList(u8).init(gpa); |
| 1799 | defer buffer.deinit(); | 1808 | defer buffer.deinit(); |
| 1800 | | 1809 | |
| 1801 | var pages_it = pages.iterator(); | 1810 | for (pages.items) |page| { |
| 1802 | while (pages_it.next()) |entry| { | 1811 | const entries = page_table.getPtr(page).?; |
| 1803 | // Pad to required 4byte alignment | 1812 | // Pad to required 4byte alignment |
| 1804 | if (!mem.isAlignedGeneric( | 1813 | if (!mem.isAlignedGeneric( |
| 1805 | usize, | 1814 | usize, |
| 1806 | entry.value_ptr.items.len * @sizeOf(coff.BaseRelocation), | 1815 | entries.items.len * @sizeOf(coff.BaseRelocation), |
| 1807 | @sizeOf(u32), | 1816 | @sizeOf(u32), |
| 1808 | )) { | 1817 | )) { |
| 1809 | try entry.value_ptr.append(.{ | 1818 | try entries.append(.{ |
| 1810 | .offset = 0, | 1819 | .offset = 0, |
| 1811 | .type = .ABSOLUTE, | 1820 | .type = .ABSOLUTE, |
| 1812 | }); | 1821 | }); |
| ... | @@ -1814,14 +1823,14 @@ fn writeBaseRelocations(self: *Coff) !void { | ... | @@ -1814,14 +1823,14 @@ fn writeBaseRelocations(self: *Coff) !void { |
| 1814 | | 1823 | |
| 1815 | const block_size = @intCast( | 1824 | const block_size = @intCast( |
| 1816 | u32, | 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 | try buffer.ensureUnusedCapacity(block_size); | 1828 | try buffer.ensureUnusedCapacity(block_size); |
| 1820 | buffer.appendSliceAssumeCapacity(mem.asBytes(&coff.BaseRelocationDirectoryEntry{ | 1829 | buffer.appendSliceAssumeCapacity(mem.asBytes(&coff.BaseRelocationDirectoryEntry{ |
| 1821 | .page_rva = entry.key_ptr.*, | 1830 | .page_rva = page, |
| 1822 | .block_size = block_size, | 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 | const header = &self.sections.items(.header)[self.reloc_section_index.?]; | 1836 | const header = &self.sections.items(.header)[self.reloc_section_index.?]; |