| ... | ... | @@ -1146,7 +1146,9 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void { |
| 1146 | 1146 | if (self.relocs.getPtr(atom_index)) |rels| { |
| 1147 | 1147 | try relocs.ensureTotalCapacityPrecise(rels.items.len); |
| 1148 | 1148 | for (rels.items) |*reloc| { |
| 1149 | | if (reloc.isResolvable(self)) relocs.appendAssumeCapacity(reloc); |
| 1149 | if (reloc.isResolvable(self) and reloc.dirty) { |
| 1150 | relocs.appendAssumeCapacity(reloc); |
| 1151 | } |
| 1150 | 1152 | } |
| 1151 | 1153 | } |
| 1152 | 1154 | |
| ... | ... | @@ -1332,18 +1334,33 @@ fn markRelocsDirtyByTarget(self: *MachO, target: SymbolWithLoc) void { |
| 1332 | 1334 | |
| 1333 | 1335 | fn markRelocsDirtyByAddress(self: *MachO, addr: u64) void { |
| 1334 | 1336 | log.debug("marking relocs dirty by address: {x}", .{addr}); |
| 1337 | |
| 1338 | const got_moved = blk: { |
| 1339 | const sect_id = self.got_section_index orelse break :blk false; |
| 1340 | break :blk self.sections.items(.header)[sect_id].addr > addr; |
| 1341 | }; |
| 1342 | const stubs_moved = blk: { |
| 1343 | const sect_id = self.stubs_section_index orelse break :blk false; |
| 1344 | break :blk self.sections.items(.header)[sect_id].addr > addr; |
| 1345 | }; |
| 1346 | |
| 1335 | 1347 | for (self.relocs.values()) |*relocs| { |
| 1336 | 1348 | for (relocs.items) |*reloc| { |
| 1337 | | const target_addr = reloc.getTargetBaseAddress(self) orelse continue; |
| 1338 | | if (target_addr < addr) continue; |
| 1339 | | reloc.dirty = true; |
| 1349 | if (reloc.isGotIndirection()) { |
| 1350 | reloc.dirty = reloc.dirty or got_moved; |
| 1351 | } else if (reloc.isStubTrampoline(self)) { |
| 1352 | reloc.dirty = reloc.dirty or stubs_moved; |
| 1353 | } else { |
| 1354 | const target_addr = reloc.getTargetBaseAddress(self) orelse continue; |
| 1355 | if (target_addr > addr) reloc.dirty = true; |
| 1356 | } |
| 1340 | 1357 | } |
| 1341 | 1358 | } |
| 1342 | 1359 | |
| 1343 | 1360 | // TODO: dirty only really affected GOT cells |
| 1344 | 1361 | for (self.got_table.entries.items) |entry| { |
| 1345 | 1362 | const target_addr = self.getSymbol(entry).n_value; |
| 1346 | | if (target_addr >= addr) { |
| 1363 | if (target_addr > addr) { |
| 1347 | 1364 | self.got_table_contents_dirty = true; |
| 1348 | 1365 | break; |
| 1349 | 1366 | } |
| ... | ... | @@ -1353,7 +1370,7 @@ fn markRelocsDirtyByAddress(self: *MachO, addr: u64) void { |
| 1353 | 1370 | const stubs_addr = self.getSegment(self.stubs_section_index.?).vmaddr; |
| 1354 | 1371 | const stub_helper_addr = self.getSegment(self.stub_helper_section_index.?).vmaddr; |
| 1355 | 1372 | const laptr_addr = self.getSegment(self.la_symbol_ptr_section_index.?).vmaddr; |
| 1356 | | if (stubs_addr >= addr or stub_helper_addr >= addr or laptr_addr >= addr) |
| 1373 | if (stubs_addr > addr or stub_helper_addr > addr or laptr_addr > addr) |
| 1357 | 1374 | self.stub_table_contents_dirty = true; |
| 1358 | 1375 | } |
| 1359 | 1376 | } |
| ... | ... | @@ -2794,7 +2811,7 @@ fn growSection(self: *MachO, sect_id: u8, needed_size: u64) !void { |
| 2794 | 2811 | |
| 2795 | 2812 | const sect_vm_capacity = self.allocatedVirtualSize(segment.vmaddr); |
| 2796 | 2813 | if (needed_size > sect_vm_capacity) { |
| 2797 | | self.markRelocsDirtyByAddress(segment.vmaddr + needed_size); |
| 2814 | self.markRelocsDirtyByAddress(segment.vmaddr + segment.vmsize); |
| 2798 | 2815 | try self.growSectionVirtualMemory(sect_id, needed_size); |
| 2799 | 2816 | } |
| 2800 | 2817 | |
| ... | ... | @@ -4067,11 +4084,12 @@ pub fn findFirst(comptime T: type, haystack: []align(1) const T, start: usize, p |
| 4067 | 4084 | pub fn logSections(self: *MachO) void { |
| 4068 | 4085 | log.debug("sections:", .{}); |
| 4069 | 4086 | for (self.sections.items(.header), 0..) |header, i| { |
| 4070 | | log.debug(" sect({d}): {s},{s} @{x}, sizeof({x})", .{ |
| 4087 | log.debug(" sect({d}): {s},{s} @{x} ({x}), sizeof({x})", .{ |
| 4071 | 4088 | i + 1, |
| 4072 | 4089 | header.segName(), |
| 4073 | 4090 | header.sectName(), |
| 4074 | 4091 | header.offset, |
| 4092 | header.addr, |
| 4075 | 4093 | header.size, |
| 4076 | 4094 | }); |
| 4077 | 4095 | } |