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