| ... | @@ -167,9 +167,11 @@ last_text_block: ?*TextBlock = null, | ... | @@ -167,9 +167,11 @@ last_text_block: ?*TextBlock = null, |
| 167 | pie_fixups: std.ArrayListUnmanaged(PieFixup) = .{}, | 167 | pie_fixups: std.ArrayListUnmanaged(PieFixup) = .{}, |
| 168 | | 168 | |
| 169 | stub_fixups: std.ArrayListUnmanaged(StubFixup) = .{}, | 169 | stub_fixups: std.ArrayListUnmanaged(StubFixup) = .{}, |
| | 170 | externs: std.StringHashMapUnmanaged(u32) = .{}, |
| 170 | | 171 | |
| 171 | pub const StubFixup = struct { | 172 | pub const StubFixup = struct { |
| 172 | symbol: usize, | 173 | symbol: u32, |
| | 174 | exists: bool, |
| 173 | start: usize, | 175 | start: usize, |
| 174 | len: usize, | 176 | len: usize, |
| 175 | }; | 177 | }; |
| ... | @@ -1263,56 +1265,57 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { | ... | @@ -1263,56 +1265,57 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { |
| 1263 | const stub_h = &text_segment.sections.items[self.stub_helper_section_index.?]; | 1265 | const stub_h = &text_segment.sections.items[self.stub_helper_section_index.?]; |
| 1264 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 1266 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 1265 | const la_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?]; | 1267 | const la_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?]; |
| 1266 | for (self.stub_fixups.items) |fixup, idx| { | 1268 | for (self.stub_fixups.items) |fixup| { |
| 1267 | const i = @intCast(u32, idx); | | |
| 1268 | // TODO increment offset for stub writing | 1269 | // TODO increment offset for stub writing |
| 1269 | const stub_addr = stubs.addr + i * stubs.reserved2; | 1270 | const stub_addr = stubs.addr + fixup.symbol * stubs.reserved2; |
| 1270 | const text_addr = symbol.n_value + fixup.start; | 1271 | const text_addr = symbol.n_value + fixup.start; |
| 1271 | const displacement = @intCast(u32, stub_addr - text_addr); | 1272 | const displacement = @intCast(u32, stub_addr - text_addr); |
| 1272 | var placeholder = code_buffer.items[fixup.start..][0..fixup.len]; | 1273 | var placeholder = code_buffer.items[fixup.start..][0..fixup.len]; |
| 1273 | mem.writeIntSliceLittle(u32, placeholder, aarch64.Instruction.bl(@intCast(i28, displacement)).toU32()); | 1274 | mem.writeIntSliceLittle(u32, placeholder, aarch64.Instruction.bl(@intCast(i28, displacement)).toU32()); |
| 1274 | | 1275 | |
| 1275 | const end = stub_h.addr + self.next_stub_helper_off.? - stub_h.offset; | 1276 | if (!fixup.exists) { |
| 1276 | var buf: [@sizeOf(u64)]u8 = undefined; | 1277 | const end = stub_h.addr + self.next_stub_helper_off.? - stub_h.offset; |
| 1277 | mem.writeIntLittle(u64, &buf, end); | 1278 | var buf: [@sizeOf(u64)]u8 = undefined; |
| 1278 | try self.base.file.?.pwriteAll(&buf, la_ptr.offset + i * @sizeOf(u64)); | 1279 | mem.writeIntLittle(u64, &buf, end); |
| 1279 | | 1280 | try self.base.file.?.pwriteAll(&buf, la_ptr.offset + fixup.symbol * @sizeOf(u64)); |
| 1280 | const la_ptr_addr = la_ptr.addr + i * @sizeOf(u64); | 1281 | |
| 1281 | const displacement2 = la_ptr_addr - stub_addr; | 1282 | const la_ptr_addr = la_ptr.addr + fixup.symbol * @sizeOf(u64); |
| 1282 | var ccode: [2 * @sizeOf(u32)]u8 = undefined; | 1283 | const displacement2 = la_ptr_addr - stub_addr; |
| 1283 | mem.writeIntLittle(u32, ccode[0..4], aarch64.Instruction.ldr(.x16, .{ | 1284 | var ccode: [2 * @sizeOf(u32)]u8 = undefined; |
| 1284 | .literal = @intCast(u19, displacement2 / 4), | 1285 | mem.writeIntLittle(u32, ccode[0..4], aarch64.Instruction.ldr(.x16, .{ |
| 1285 | }).toU32()); | 1286 | .literal = @intCast(u19, displacement2 / 4), |
| 1286 | mem.writeIntLittle(u32, ccode[4..8], aarch64.Instruction.br(.x16).toU32()); | 1287 | }).toU32()); |
| 1287 | try self.base.file.?.pwriteAll(&ccode, stubs.offset + i * stubs.reserved2); | 1288 | mem.writeIntLittle(u32, ccode[4..8], aarch64.Instruction.br(.x16).toU32()); |
| 1288 | | 1289 | try self.base.file.?.pwriteAll(&ccode, stubs.offset + fixup.symbol * stubs.reserved2); |
| 1289 | const displacement3 = @intCast(i64, stub_h.addr) - @intCast(i64, end + 4); | 1290 | |
| 1290 | var cccode: [3 * @sizeOf(u32)]u8 = undefined; | 1291 | const displacement3 = @intCast(i64, stub_h.addr) - @intCast(i64, end + 4); |
| 1291 | mem.writeIntLittle(u32, cccode[0..4], aarch64.Instruction.ldr(.w16, .{ | 1292 | var cccode: [3 * @sizeOf(u32)]u8 = undefined; |
| 1292 | .literal = 0x2, | 1293 | mem.writeIntLittle(u32, cccode[0..4], aarch64.Instruction.ldr(.w16, .{ |
| 1293 | }).toU32()); | 1294 | .literal = 0x2, |
| 1294 | mem.writeIntLittle(u32, cccode[4..8], aarch64.Instruction.b(@intCast(i28, displacement3)).toU32()); | 1295 | }).toU32()); |
| 1295 | mem.writeIntLittle(u32, cccode[8..12], i * 0xd); | 1296 | mem.writeIntLittle(u32, cccode[4..8], aarch64.Instruction.b(@intCast(i28, displacement3)).toU32()); |
| 1296 | try self.base.file.?.pwriteAll(&cccode, self.next_stub_helper_off.?); | 1297 | mem.writeIntLittle(u32, cccode[8..12], fixup.symbol * 0xd); |
| 1297 | self.next_stub_helper_off = self.next_stub_helper_off.? + 3 * @sizeOf(u32); | 1298 | try self.base.file.?.pwriteAll(&cccode, self.next_stub_helper_off.?); |
| 1298 | | 1299 | self.next_stub_helper_off = self.next_stub_helper_off.? + 3 * @sizeOf(u32); |
| 1299 | try self.rebase_info_table.symbols.append(self.base.allocator, .{ | 1300 | |
| 1300 | .segment = 3, | 1301 | try self.rebase_info_table.symbols.append(self.base.allocator, .{ |
| 1301 | .offset = i * stubs.reserved2, | 1302 | .segment = 3, |
| 1302 | }); | 1303 | .offset = fixup.symbol * stubs.reserved2, |
| 1303 | self.rebase_info_dirty = true; | 1304 | }); |
| 1304 | | 1305 | self.rebase_info_dirty = true; |
| 1305 | const sym = self.undef_symbols.items[fixup.symbol]; | 1306 | |
| 1306 | const name_str = self.getString(sym.n_strx); | 1307 | const sym = self.undef_symbols.items[fixup.symbol + 1]; |
| 1307 | var name = try self.base.allocator.alloc(u8, name_str.len); | 1308 | const name_str = self.getString(sym.n_strx); |
| 1308 | mem.copy(u8, name, name_str); | 1309 | var name = try self.base.allocator.alloc(u8, name_str.len); |
| 1309 | try self.lazy_binding_info_table.symbols.append(self.base.allocator, .{ | 1310 | mem.copy(u8, name, name_str); |
| 1310 | .segment = 3, | 1311 | try self.lazy_binding_info_table.symbols.append(self.base.allocator, .{ |
| 1311 | .offset = i * @sizeOf(u64), | 1312 | .segment = 3, |
| 1312 | .dylib_ordinal = 1, | 1313 | .offset = fixup.symbol * @sizeOf(u64), |
| 1313 | .name = name, | 1314 | .dylib_ordinal = 1, |
| 1314 | }); | 1315 | .name = name, |
| 1315 | self.lazy_binding_info_dirty = true; | 1316 | }); |
| | 1317 | self.lazy_binding_info_dirty = true; |
| | 1318 | } |
| 1316 | } | 1319 | } |
| 1317 | self.stub_fixups.shrinkRetainingCapacity(0); | 1320 | self.stub_fixups.shrinkRetainingCapacity(0); |
| 1318 | | 1321 | |