| ... | @@ -492,7 +492,7 @@ fn growSection(self: *Coff, sect_id: u32, needed_size: u32) !void { | ... | @@ -492,7 +492,7 @@ fn growSection(self: *Coff, sect_id: u32, needed_size: u32) !void { |
| 492 | | 492 | |
| 493 | const sect_vm_capacity = self.allocatedVirtualSize(header.virtual_address); | 493 | const sect_vm_capacity = self.allocatedVirtualSize(header.virtual_address); |
| 494 | if (needed_size > sect_vm_capacity) { | 494 | if (needed_size > sect_vm_capacity) { |
| 495 | self.markRelocsDirtyByAddress(header.virtual_address + needed_size); | 495 | self.markRelocsDirtyByAddress(header.virtual_address + header.virtual_size); |
| 496 | try self.growSectionVirtualMemory(sect_id, needed_size); | 496 | try self.growSectionVirtualMemory(sect_id, needed_size); |
| 497 | } | 497 | } |
| 498 | | 498 | |
| ... | @@ -759,7 +759,9 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void { | ... | @@ -759,7 +759,9 @@ fn writeAtom(self: *Coff, atom_index: Atom.Index, code: []u8) !void { |
| 759 | if (self.relocs.getPtr(atom_index)) |rels| { | 759 | if (self.relocs.getPtr(atom_index)) |rels| { |
| 760 | try relocs.ensureTotalCapacityPrecise(rels.items.len); | 760 | try relocs.ensureTotalCapacityPrecise(rels.items.len); |
| 761 | for (rels.items) |*reloc| { | 761 | for (rels.items) |*reloc| { |
| 762 | if (reloc.isResolvable(self)) relocs.appendAssumeCapacity(reloc); | 762 | if (reloc.isResolvable(self) and reloc.dirty) { |
| | 763 | relocs.appendAssumeCapacity(reloc); |
| | 764 | } |
| 763 | } | 765 | } |
| 764 | } | 766 | } |
| 765 | | 767 | |
| ... | @@ -904,18 +906,28 @@ fn markRelocsDirtyByTarget(self: *Coff, target: SymbolWithLoc) void { | ... | @@ -904,18 +906,28 @@ fn markRelocsDirtyByTarget(self: *Coff, target: SymbolWithLoc) void { |
| 904 | } | 906 | } |
| 905 | | 907 | |
| 906 | fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void { | 908 | fn markRelocsDirtyByAddress(self: *Coff, addr: u32) void { |
| | 909 | const got_moved = blk: { |
| | 910 | const sect_id = self.got_section_index orelse break :blk false; |
| | 911 | break :blk self.sections.items(.header)[sect_id].virtual_address > addr; |
| | 912 | }; |
| | 913 | |
| | 914 | // TODO: dirty relocations targeting import table if that got moved in memory |
| | 915 | |
| 907 | for (self.relocs.values()) |*relocs| { | 916 | for (self.relocs.values()) |*relocs| { |
| 908 | for (relocs.items) |*reloc| { | 917 | for (relocs.items) |*reloc| { |
| 909 | const target_vaddr = reloc.getTargetAddress(self) orelse continue; | 918 | if (reloc.isGotIndirection()) { |
| 910 | if (target_vaddr < addr) continue; | 919 | reloc.dirty = reloc.dirty or got_moved; |
| 911 | reloc.dirty = true; | 920 | } else { |
| | 921 | const target_vaddr = reloc.getTargetAddress(self) orelse continue; |
| | 922 | if (target_vaddr > addr) reloc.dirty = true; |
| | 923 | } |
| 912 | } | 924 | } |
| 913 | } | 925 | } |
| 914 | | 926 | |
| 915 | // TODO: dirty only really affected GOT cells | 927 | // TODO: dirty only really affected GOT cells |
| 916 | for (self.got_table.entries.items) |entry| { | 928 | for (self.got_table.entries.items) |entry| { |
| 917 | const target_addr = self.getSymbol(entry).value; | 929 | const target_addr = self.getSymbol(entry).value; |
| 918 | if (target_addr >= addr) { | 930 | if (target_addr > addr) { |
| 919 | self.got_table_contents_dirty = true; | 931 | self.got_table_contents_dirty = true; |
| 920 | break; | 932 | break; |
| 921 | } | 933 | } |
| ... | @@ -1624,7 +1636,7 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -1624,7 +1636,7 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 1624 | | 1636 | |
| 1625 | for (self.relocs.keys(), self.relocs.values()) |atom_index, relocs| { | 1637 | for (self.relocs.keys(), self.relocs.values()) |atom_index, relocs| { |
| 1626 | const needs_update = for (relocs.items) |reloc| { | 1638 | const needs_update = for (relocs.items) |reloc| { |
| 1627 | if (reloc.isResolvable(self)) break true; | 1639 | if (reloc.dirty) break true; |
| 1628 | } else false; | 1640 | } else false; |
| 1629 | | 1641 | |
| 1630 | if (!needs_update) continue; | 1642 | if (!needs_update) continue; |