authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-01-19 18:59:10+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-01-19 22:39:49+01:00
log7d3aa58e16dc90852316324efddae5ffc11d0606
tree08ef320a14e742ea3b568c49d906c3f87ba44272
parent287f640cc94d7f1cddb30e9ef57a8c921621a5b9

macho: make int casts safer


1 files changed, 34 insertions(+), 23 deletions(-)

src/link/MachO.zig+34-23
......@@ -1229,14 +1229,16 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
12291229 const this_addr = symbol.n_value + fixup.start;
12301230 switch (self.base.options.target.cpu.arch) {
12311231 .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);
12331234 var placeholder = code_buffer.items[fixup.start + fixup.len - @sizeOf(u32) ..][0..@sizeOf(u32)];
12341235 mem.writeIntSliceLittle(u32, placeholder, displacement);
12351236 },
12361237 .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);
12381240 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());
12401242 },
12411243 else => unreachable, // unsupported target architecture
12421244 }
......@@ -1249,14 +1251,16 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
12491251 const text_addr = symbol.n_value + fixup.start;
12501252 switch (self.base.options.target.cpu.arch) {
12511253 .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);
12531256 var placeholder = code_buffer.items[fixup.start + fixup.len - @sizeOf(u32) ..][0..@sizeOf(u32)];
12541257 mem.writeIntSliceLittle(u32, placeholder, displacement);
12551258 },
12561259 .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);
12581262 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());
12601264 },
12611265 else => unreachable, // unsupported target architecture
12621266 }
......@@ -2074,7 +2078,7 @@ pub fn populateMissingMetadata(self: *MachO) !void {
20742078 code[1] = 0x8d;
20752079 code[2] = 0x1d;
20762080 {
2077 const displacement = @intCast(u32, data.addr - stub_helper.addr - 7);
2081 const displacement = try math.cast(u32, data.addr - stub_helper.addr - 7);
20782082 mem.writeIntLittle(u32, code[3..7], displacement);
20792083 }
20802084 // push %r11
......@@ -2084,7 +2088,7 @@ pub fn populateMissingMetadata(self: *MachO) !void {
20842088 code[9] = 0xff;
20852089 code[10] = 0x25;
20862090 {
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);
20882092 mem.writeIntLittle(u32, code[11..], displacement);
20892093 }
20902094 self.stub_helper_stubs_start_off = stub_helper.offset + code_size;
......@@ -2093,8 +2097,8 @@ pub fn populateMissingMetadata(self: *MachO) !void {
20932097 .aarch64 => {
20942098 var code: [4 * @sizeOf(u32)]u8 = undefined;
20952099 {
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());
20982102 }
20992103 mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.stp(
21002104 .x16,
......@@ -2103,9 +2107,10 @@ pub fn populateMissingMetadata(self: *MachO) !void {
21032107 aarch64.Instruction.LoadStorePairOffset.pre_index(-16),
21042108 ).toU32());
21052109 {
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);
21072112 mem.writeIntLittle(u32, code[8..12], aarch64.Instruction.ldr(.x16, .{
2108 .literal = @intCast(u19, displacement / 4),
2113 .literal = literal,
21092114 }).toU32());
21102115 }
21112116 mem.writeIntLittle(u32, code[12..16], aarch64.Instruction.br(.x16).toU32());
......@@ -2445,8 +2450,8 @@ fn writeOffsetTableEntry(self: *MachO, index: usize) !void {
24452450 var code: [8]u8 = undefined;
24462451 switch (self.base.options.target.cpu.arch) {
24472452 .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);
24502455 // lea %rax, [rip - disp]
24512456 code[0] = 0x48;
24522457 code[1] = 0x8D;
......@@ -2456,8 +2461,8 @@ fn writeOffsetTableEntry(self: *MachO, index: usize) !void {
24562461 code[7] = 0xC3;
24572462 },
24582463 .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;
24612466 // adr x0, #-disp
24622467 mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.adr(.x0, symbol_off).toU32());
24632468 // ret x28
......@@ -2503,16 +2508,19 @@ fn writeStub(self: *MachO, index: u32) !void {
25032508 defer self.base.allocator.free(code);
25042509 switch (self.base.options.target.cpu.arch) {
25052510 .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);
25072513 // jmp
25082514 code[0] = 0xff;
25092515 code[1] = 0x25;
25102516 mem.writeIntLittle(u32, code[2..][0..4], displacement);
25112517 },
25122518 .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);
25142522 mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.ldr(.x16, .{
2515 .literal = @intCast(u19, displacement / 4),
2523 .literal = literal,
25162524 }).toU32());
25172525 mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.br(.x16).toU32());
25182526 },
......@@ -2535,7 +2543,10 @@ fn writeStubInStubHelper(self: *MachO, index: u32) !void {
25352543 defer self.base.allocator.free(code);
25362544 switch (self.base.options.target.cpu.arch) {
25372545 .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 );
25392550 // pushq
25402551 code[0] = 0x68;
25412552 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 {
25442555 mem.writeIntLittle(u32, code[6..][0..4], @bitCast(u32, displacement));
25452556 },
25462557 .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);
25482559 mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.ldr(.w16, .{
2549 .literal = 0x2,
2560 .literal = @divExact(stub_size - @sizeOf(u32), 4),
25502561 }).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());
25522563 mem.writeIntLittle(u32, code[8..12], 0x0); // Just a placeholder populated in `populateLazyBindOffsetsInStubHelper`.
25532564 },
25542565 else => unreachable,