authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-19 14:20:16+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-21 22:44:27+02:00
logc55e821df6d6adca449720e052f40463eef8174b
tree95d5e956fb6093135c35414f4c98b268aad735fe
parent91bb9302e57c62a1340291b8b207b1638b981bc6

macho: resolve relocs before writing to memory (fixes HCS)


1 files changed, 8 insertions(+), 8 deletions(-)

src/link/MachO.zig+8-8
...@@ -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 }
761761
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 }
768770
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 }
12511253
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 }
12591263
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);
12621265
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 {
12871290
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 });
12971300
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);
13011304
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}
21242125
...@@ -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);