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