| ... | @@ -759,11 +759,13 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No | ... | @@ -759,11 +759,13 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 759 | try self.writeAtom(atom_index, code.items); | 759 | try self.writeAtom(atom_index, code.items); |
| 760 | } | 760 | } |
| 761 | | 761 | |
| | 762 | // Update GOT if it got moved in memory. |
| 762 | if (self.got_table_contents_dirty) { | 763 | if (self.got_table_contents_dirty) { |
| 763 | for (self.got_table.entries.items, 0..) |entry, i| { | 764 | for (self.got_table.entries.items, 0..) |entry, i| { |
| 764 | if (!self.got_table.lookup.contains(entry)) continue; | 765 | if (!self.got_table.lookup.contains(entry)) continue; |
| 765 | try self.writeOffsetTableEntry(i); | 766 | try self.writeOffsetTableEntry(i); |
| 766 | } | 767 | } |
| | 768 | self.got_table_contents_dirty = false; |
| 767 | } | 769 | } |
| 768 | | 770 | |
| 769 | if (build_options.enable_logging) { | 771 | if (build_options.enable_logging) { |
| ... | @@ -1249,6 +1251,8 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void { | ... | @@ -1249,6 +1251,8 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void { |
| 1249 | } | 1251 | } |
| 1250 | } | 1252 | } |
| 1251 | | 1253 | |
| | 1254 | Atom.resolveRelocations(self, atom_index, relocs.items, code); |
| | 1255 | |
| 1252 | if (is_hot_update_compatible) { | 1256 | if (is_hot_update_compatible) { |
| 1253 | if (self.hot_state.mach_task) |task| { | 1257 | if (self.hot_state.mach_task) |task| { |
| 1254 | self.writeToMemory(task, section.segment_index, sym.n_value, code) catch |err| { | 1258 | self.writeToMemory(task, section.segment_index, sym.n_value, code) catch |err| { |
| ... | @@ -1257,7 +1261,6 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void { | ... | @@ -1257,7 +1261,6 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void { |
| 1257 | } | 1261 | } |
| 1258 | } | 1262 | } |
| 1259 | | 1263 | |
| 1260 | Atom.resolveRelocations(self, atom_index, relocs.items, code); | | |
| 1261 | try self.base.file.?.pwriteAll(code, file_offset); | 1264 | try self.base.file.?.pwriteAll(code, file_offset); |
| 1262 | | 1265 | |
| 1263 | // Now we can mark the relocs as resolved. | 1266 | // Now we can mark the relocs as resolved. |
| ... | @@ -1287,19 +1290,18 @@ fn writeOffsetTableEntry(self: *MachO, index: usize) !void { | ... | @@ -1287,19 +1290,18 @@ fn writeOffsetTableEntry(self: *MachO, index: usize) !void { |
| 1287 | | 1290 | |
| 1288 | const header = &self.sections.items(.header)[sect_id]; | 1291 | const header = &self.sections.items(.header)[sect_id]; |
| 1289 | const segment_index = self.sections.items(.segment_index)[sect_id]; | 1292 | const segment_index = self.sections.items(.segment_index)[sect_id]; |
| 1290 | const segment = self.getSegment(sect_id); | | |
| 1291 | const entry = self.got_table.entries.items[index]; | 1293 | const entry = self.got_table.entries.items[index]; |
| 1292 | const entry_value = self.getSymbol(entry).n_value; | 1294 | const entry_value = self.getSymbol(entry).n_value; |
| 1293 | const entry_offset = index * @sizeOf(u64); | 1295 | const entry_offset = index * @sizeOf(u64); |
| 1294 | const file_offset = header.offset + entry_offset; | 1296 | const file_offset = header.offset + entry_offset; |
| 1295 | const vmaddr = segment.vmaddr + entry_offset; | 1297 | const vmaddr = header.addr + entry_offset; |
| 1296 | log.warn("writing GOT entry {d}: @{x} => {x}", .{ index, vmaddr, entry_value }); | 1298 | |
| | 1299 | log.debug("writing GOT entry {d}: @{x} => {x}", .{ index, vmaddr, entry_value }); |
| 1297 | | 1300 | |
| 1298 | var buf: [8]u8 = undefined; | 1301 | var buf: [@sizeOf(u64)]u8 = undefined; |
| 1299 | mem.writeIntLittle(u64, &buf, entry_value); | 1302 | mem.writeIntLittle(u64, &buf, entry_value); |
| 1300 | try self.base.file.?.pwriteAll(&buf, file_offset); | 1303 | try self.base.file.?.pwriteAll(&buf, file_offset); |
| 1301 | | 1304 | |
| 1302 | // TODO write in memory | | |
| 1303 | if (is_hot_update_compatible) { | 1305 | if (is_hot_update_compatible) { |
| 1304 | if (self.hot_state.mach_task) |task| { | 1306 | if (self.hot_state.mach_task) |task| { |
| 1305 | self.writeToMemory(task, segment_index, vmaddr, &buf) catch |err| { | 1307 | self.writeToMemory(task, segment_index, vmaddr, &buf) catch |err| { |
| ... | @@ -2118,7 +2120,6 @@ fn addGotEntry(self: *MachO, target: SymbolWithLoc) !void { | ... | @@ -2118,7 +2120,6 @@ fn addGotEntry(self: *MachO, target: SymbolWithLoc) !void { |
| 2118 | if (self.got_table.lookup.contains(target)) return; | 2120 | if (self.got_table.lookup.contains(target)) return; |
| 2119 | const got_index = try self.got_table.allocateEntry(self.base.allocator, target); | 2121 | const got_index = try self.got_table.allocateEntry(self.base.allocator, target); |
| 2120 | try self.writeOffsetTableEntry(got_index); | 2122 | try self.writeOffsetTableEntry(got_index); |
| 2121 | self.markRelocsDirtyByTarget(target); | | |
| 2122 | self.got_table_count_dirty = true; | 2123 | self.got_table_count_dirty = true; |
| 2123 | } | 2124 | } |
| 2124 | | 2125 | |
| ... | @@ -2542,7 +2543,6 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 | ... | @@ -2542,7 +2543,6 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 |
| 2542 | const tlv_atom = self.getAtom(tlv_atom_index); | 2543 | const tlv_atom = self.getAtom(tlv_atom_index); |
| 2543 | break :blk tlv_atom.getSymbolWithLoc(); | 2544 | break :blk tlv_atom.getSymbolWithLoc(); |
| 2544 | } else .{ .sym_index = sym_index }; | 2545 | } else .{ .sym_index = sym_index }; |
| 2545 | self.markRelocsDirtyByTarget(target); | | |
| 2546 | log.debug(" (updating GOT entry)", .{}); | 2546 | log.debug(" (updating GOT entry)", .{}); |
| 2547 | const got_atom_index = self.got_table.lookup.get(target).?; | 2547 | const got_atom_index = self.got_table.lookup.get(target).?; |
| 2548 | try self.writeOffsetTableEntry(got_atom_index); | 2548 | try self.writeOffsetTableEntry(got_atom_index); |