| ... | ... | @@ -1229,14 +1229,16 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { |
| 1229 | 1229 | const this_addr = symbol.n_value + fixup.start; |
| 1230 | 1230 | switch (self.base.options.target.cpu.arch) { |
| 1231 | 1231 | .x86_64 => { |
| 1232 | | const displacement = @intCast(u32, target_addr - this_addr - fixup.len); |
| 1232 | assert(target_addr >= this_addr + fixup.len); |
| 1233 | const displacement = try math.cast(u32, target_addr - this_addr - fixup.len); |
| 1233 | 1234 | var placeholder = code_buffer.items[fixup.start + fixup.len - @sizeOf(u32) ..][0..@sizeOf(u32)]; |
| 1234 | 1235 | mem.writeIntSliceLittle(u32, placeholder, displacement); |
| 1235 | 1236 | }, |
| 1236 | 1237 | .aarch64 => { |
| 1237 | | const displacement = @intCast(u27, target_addr - this_addr); |
| 1238 | assert(target_addr >= this_addr); |
| 1239 | const displacement = try math.cast(u27, target_addr - this_addr); |
| 1238 | 1240 | var placeholder = code_buffer.items[fixup.start..][0..fixup.len]; |
| 1239 | | mem.writeIntSliceLittle(u32, placeholder, aarch64.Instruction.b(@intCast(i28, displacement)).toU32()); |
| 1241 | mem.writeIntSliceLittle(u32, placeholder, aarch64.Instruction.b(@as(i28, displacement)).toU32()); |
| 1240 | 1242 | }, |
| 1241 | 1243 | else => unreachable, // unsupported target architecture |
| 1242 | 1244 | } |
| ... | ... | @@ -1249,14 +1251,16 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { |
| 1249 | 1251 | const text_addr = symbol.n_value + fixup.start; |
| 1250 | 1252 | switch (self.base.options.target.cpu.arch) { |
| 1251 | 1253 | .x86_64 => { |
| 1252 | | const displacement = @intCast(u32, stub_addr - text_addr - fixup.len); |
| 1254 | assert(stub_addr >= text_addr + fixup.len); |
| 1255 | const displacement = try math.cast(u32, stub_addr - text_addr - fixup.len); |
| 1253 | 1256 | var placeholder = code_buffer.items[fixup.start + fixup.len - @sizeOf(u32) ..][0..@sizeOf(u32)]; |
| 1254 | 1257 | mem.writeIntSliceLittle(u32, placeholder, displacement); |
| 1255 | 1258 | }, |
| 1256 | 1259 | .aarch64 => { |
| 1257 | | const displacement = @intCast(u32, stub_addr - text_addr); |
| 1260 | assert(stub_addr >= text_addr); |
| 1261 | const displacement = try math.cast(i28, stub_addr - text_addr); |
| 1258 | 1262 | var placeholder = code_buffer.items[fixup.start..][0..fixup.len]; |
| 1259 | | mem.writeIntSliceLittle(u32, placeholder, aarch64.Instruction.bl(@intCast(i28, displacement)).toU32()); |
| 1263 | mem.writeIntSliceLittle(u32, placeholder, aarch64.Instruction.bl(displacement).toU32()); |
| 1260 | 1264 | }, |
| 1261 | 1265 | else => unreachable, // unsupported target architecture |
| 1262 | 1266 | } |
| ... | ... | @@ -2074,7 +2078,7 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 2074 | 2078 | code[1] = 0x8d; |
| 2075 | 2079 | code[2] = 0x1d; |
| 2076 | 2080 | { |
| 2077 | | const displacement = @intCast(u32, data.addr - stub_helper.addr - 7); |
| 2081 | const displacement = try math.cast(u32, data.addr - stub_helper.addr - 7); |
| 2078 | 2082 | mem.writeIntLittle(u32, code[3..7], displacement); |
| 2079 | 2083 | } |
| 2080 | 2084 | // push %r11 |
| ... | ... | @@ -2084,7 +2088,7 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 2084 | 2088 | code[9] = 0xff; |
| 2085 | 2089 | code[10] = 0x25; |
| 2086 | 2090 | { |
| 2087 | | const displacement = @intCast(u32, got.addr - stub_helper.addr - code_size); |
| 2091 | const displacement = try math.cast(u32, got.addr - stub_helper.addr - code_size); |
| 2088 | 2092 | mem.writeIntLittle(u32, code[11..], displacement); |
| 2089 | 2093 | } |
| 2090 | 2094 | self.stub_helper_stubs_start_off = stub_helper.offset + code_size; |
| ... | ... | @@ -2093,8 +2097,8 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 2093 | 2097 | .aarch64 => { |
| 2094 | 2098 | var code: [4 * @sizeOf(u32)]u8 = undefined; |
| 2095 | 2099 | { |
| 2096 | | const displacement = data.addr - stub_helper.addr; |
| 2097 | | mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.adr(.x17, @intCast(i21, displacement)).toU32()); |
| 2100 | const displacement = try math.cast(i21, data.addr - stub_helper.addr); |
| 2101 | mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.adr(.x17, displacement).toU32()); |
| 2098 | 2102 | } |
| 2099 | 2103 | mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.stp( |
| 2100 | 2104 | .x16, |
| ... | ... | @@ -2103,9 +2107,10 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 2103 | 2107 | aarch64.Instruction.LoadStorePairOffset.pre_index(-16), |
| 2104 | 2108 | ).toU32()); |
| 2105 | 2109 | { |
| 2106 | | const displacement = got.addr - stub_helper.addr - 2 * @sizeOf(u32); |
| 2110 | const displacement = try math.divExact(u64, got.addr - stub_helper.addr - 2 * @sizeOf(u32), 4); |
| 2111 | const literal = try math.cast(u19, displacement); |
| 2107 | 2112 | mem.writeIntLittle(u32, code[8..12], aarch64.Instruction.ldr(.x16, .{ |
| 2108 | | .literal = @intCast(u19, displacement / 4), |
| 2113 | .literal = literal, |
| 2109 | 2114 | }).toU32()); |
| 2110 | 2115 | } |
| 2111 | 2116 | mem.writeIntLittle(u32, code[12..16], aarch64.Instruction.br(.x16).toU32()); |
| ... | ... | @@ -2445,8 +2450,8 @@ fn writeOffsetTableEntry(self: *MachO, index: usize) !void { |
| 2445 | 2450 | var code: [8]u8 = undefined; |
| 2446 | 2451 | switch (self.base.options.target.cpu.arch) { |
| 2447 | 2452 | .x86_64 => { |
| 2448 | | const pos_symbol_off = @intCast(u31, vmaddr - self.offset_table.items[index] + 7); |
| 2449 | | const symbol_off = @bitCast(u32, @intCast(i32, pos_symbol_off) * -1); |
| 2453 | const pos_symbol_off = try math.cast(u31, vmaddr - self.offset_table.items[index] + 7); |
| 2454 | const symbol_off = @bitCast(u32, @as(i32, pos_symbol_off) * -1); |
| 2450 | 2455 | // lea %rax, [rip - disp] |
| 2451 | 2456 | code[0] = 0x48; |
| 2452 | 2457 | code[1] = 0x8D; |
| ... | ... | @@ -2456,8 +2461,8 @@ fn writeOffsetTableEntry(self: *MachO, index: usize) !void { |
| 2456 | 2461 | code[7] = 0xC3; |
| 2457 | 2462 | }, |
| 2458 | 2463 | .aarch64 => { |
| 2459 | | const pos_symbol_off = @intCast(u20, vmaddr - self.offset_table.items[index]); |
| 2460 | | const symbol_off = @intCast(i21, pos_symbol_off) * -1; |
| 2464 | const pos_symbol_off = try math.cast(u20, vmaddr - self.offset_table.items[index]); |
| 2465 | const symbol_off = @as(i21, pos_symbol_off) * -1; |
| 2461 | 2466 | // adr x0, #-disp |
| 2462 | 2467 | mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.adr(.x0, symbol_off).toU32()); |
| 2463 | 2468 | // ret x28 |
| ... | ... | @@ -2503,16 +2508,19 @@ fn writeStub(self: *MachO, index: u32) !void { |
| 2503 | 2508 | defer self.base.allocator.free(code); |
| 2504 | 2509 | switch (self.base.options.target.cpu.arch) { |
| 2505 | 2510 | .x86_64 => { |
| 2506 | | const displacement = @intCast(u32, la_ptr_addr - stub_addr - stubs.reserved2); |
| 2511 | assert(la_ptr_addr >= stub_addr + stubs.reserved2); |
| 2512 | const displacement = try math.cast(u32, la_ptr_addr - stub_addr - stubs.reserved2); |
| 2507 | 2513 | // jmp |
| 2508 | 2514 | code[0] = 0xff; |
| 2509 | 2515 | code[1] = 0x25; |
| 2510 | 2516 | mem.writeIntLittle(u32, code[2..][0..4], displacement); |
| 2511 | 2517 | }, |
| 2512 | 2518 | .aarch64 => { |
| 2513 | | const displacement = la_ptr_addr - stub_addr; |
| 2519 | assert(la_ptr_addr >= stub_addr); |
| 2520 | const displacement = try math.divExact(u64, la_ptr_addr - stub_addr, 4); |
| 2521 | const literal = try math.cast(u19, displacement); |
| 2514 | 2522 | mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.ldr(.x16, .{ |
| 2515 | | .literal = @intCast(u19, displacement / 4), |
| 2523 | .literal = literal, |
| 2516 | 2524 | }).toU32()); |
| 2517 | 2525 | mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.br(.x16).toU32()); |
| 2518 | 2526 | }, |
| ... | ... | @@ -2535,7 +2543,10 @@ fn writeStubInStubHelper(self: *MachO, index: u32) !void { |
| 2535 | 2543 | defer self.base.allocator.free(code); |
| 2536 | 2544 | switch (self.base.options.target.cpu.arch) { |
| 2537 | 2545 | .x86_64 => { |
| 2538 | | const displacement = @intCast(i32, @intCast(i64, stub_helper.offset) - @intCast(i64, stub_off) - stub_size); |
| 2546 | const displacement = try math.cast( |
| 2547 | i32, |
| 2548 | @intCast(i64, stub_helper.offset) - @intCast(i64, stub_off) - stub_size, |
| 2549 | ); |
| 2539 | 2550 | // pushq |
| 2540 | 2551 | code[0] = 0x68; |
| 2541 | 2552 | mem.writeIntLittle(u32, code[1..][0..4], 0x0); // Just a placeholder populated in `populateLazyBindOffsetsInStubHelper`. |
| ... | ... | @@ -2544,11 +2555,11 @@ fn writeStubInStubHelper(self: *MachO, index: u32) !void { |
| 2544 | 2555 | mem.writeIntLittle(u32, code[6..][0..4], @bitCast(u32, displacement)); |
| 2545 | 2556 | }, |
| 2546 | 2557 | .aarch64 => { |
| 2547 | | const displacement = @intCast(i64, stub_helper.offset) - @intCast(i64, stub_off) - 4; |
| 2558 | const displacement = try math.cast(i28, @intCast(i64, stub_helper.offset) - @intCast(i64, stub_off) - 4); |
| 2548 | 2559 | mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.ldr(.w16, .{ |
| 2549 | | .literal = 0x2, |
| 2560 | .literal = @divExact(stub_size - @sizeOf(u32), 4), |
| 2550 | 2561 | }).toU32()); |
| 2551 | | mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.b(@intCast(i28, displacement)).toU32()); |
| 2562 | mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.b(displacement).toU32()); |
| 2552 | 2563 | mem.writeIntLittle(u32, code[8..12], 0x0); // Just a placeholder populated in `populateLazyBindOffsetsInStubHelper`. |
| 2553 | 2564 | }, |
| 2554 | 2565 | else => unreachable, |