| ... | @@ -1263,9 +1263,10 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { | ... | @@ -1263,9 +1263,10 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { |
| 1263 | const stub_h = &text_segment.sections.items[self.stub_helper_section_index.?]; | 1263 | 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; | 1264 | 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.?]; | 1265 | const la_ptr = &data_segment.sections.items[self.la_symbol_ptr_section_index.?]; |
| 1266 | while (self.stub_fixups.popOrNull()) |fixup| { | 1266 | for (self.stub_fixups.items) |fixup, idx| { |
| | 1267 | const i = @intCast(u32, idx); |
| 1267 | // TODO increment offset for stub writing | 1268 | // TODO increment offset for stub writing |
| 1268 | const stub_addr = stubs.addr; | 1269 | const stub_addr = stubs.addr + i * stubs.reserved2; |
| 1269 | const text_addr = symbol.n_value + fixup.start; | 1270 | const text_addr = symbol.n_value + fixup.start; |
| 1270 | const displacement = @intCast(u32, stub_addr - text_addr); | 1271 | const displacement = @intCast(u32, stub_addr - text_addr); |
| 1271 | var placeholder = code_buffer.items[fixup.start..][0..fixup.len]; | 1272 | var placeholder = code_buffer.items[fixup.start..][0..fixup.len]; |
| ... | @@ -1274,17 +1275,16 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { | ... | @@ -1274,17 +1275,16 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { |
| 1274 | const end = stub_h.addr + self.next_stub_helper_off.? - stub_h.offset; | 1275 | const end = stub_h.addr + self.next_stub_helper_off.? - stub_h.offset; |
| 1275 | var buf: [@sizeOf(u64)]u8 = undefined; | 1276 | var buf: [@sizeOf(u64)]u8 = undefined; |
| 1276 | mem.writeIntLittle(u64, &buf, end); | 1277 | mem.writeIntLittle(u64, &buf, end); |
| 1277 | try self.base.file.?.pwriteAll(&buf, la_ptr.offset); | 1278 | try self.base.file.?.pwriteAll(&buf, la_ptr.offset + i * @sizeOf(u64)); |
| 1278 | | 1279 | |
| 1279 | const displacement2 = la_ptr.addr - stubs.addr; | 1280 | const la_ptr_addr = la_ptr.addr + i * @sizeOf(u64); |
| | 1281 | const displacement2 = la_ptr_addr - stub_addr; |
| 1280 | var ccode: [2 * @sizeOf(u32)]u8 = undefined; | 1282 | var ccode: [2 * @sizeOf(u32)]u8 = undefined; |
| 1281 | mem.writeIntLittle(u32, ccode[0..4], aarch64.Instruction.ldr(.x16, .{ | 1283 | mem.writeIntLittle(u32, ccode[0..4], aarch64.Instruction.ldr(.x16, .{ |
| 1282 | .literal = @intCast(u19, displacement2 / 4), | 1284 | .literal = @intCast(u19, displacement2 / 4), |
| 1283 | }).toU32()); | 1285 | }).toU32()); |
| 1284 | mem.writeIntLittle(u32, ccode[4..8], aarch64.Instruction.br(.x16).toU32()); | 1286 | mem.writeIntLittle(u32, ccode[4..8], aarch64.Instruction.br(.x16).toU32()); |
| 1285 | try self.base.file.?.pwriteAll(&ccode, stubs.offset); | 1287 | try self.base.file.?.pwriteAll(&ccode, stubs.offset + i * stubs.reserved2); |
| 1286 | stubs.size = 2 * @sizeOf(u32); | | |
| 1287 | stubs.reserved2 = 2 * @sizeOf(u32); | | |
| 1288 | | 1288 | |
| 1289 | const displacement3 = @intCast(i64, stub_h.addr) - @intCast(i64, end + 4); | 1289 | const displacement3 = @intCast(i64, stub_h.addr) - @intCast(i64, end + 4); |
| 1290 | var cccode: [3 * @sizeOf(u32)]u8 = undefined; | 1290 | var cccode: [3 * @sizeOf(u32)]u8 = undefined; |
| ... | @@ -1292,13 +1292,13 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { | ... | @@ -1292,13 +1292,13 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { |
| 1292 | .literal = 0x2, | 1292 | .literal = 0x2, |
| 1293 | }).toU32()); | 1293 | }).toU32()); |
| 1294 | mem.writeIntLittle(u32, cccode[4..8], aarch64.Instruction.b(@intCast(i28, displacement3)).toU32()); | 1294 | mem.writeIntLittle(u32, cccode[4..8], aarch64.Instruction.b(@intCast(i28, displacement3)).toU32()); |
| 1295 | mem.writeIntLittle(u32, cccode[8..12], 0); | 1295 | mem.writeIntLittle(u32, cccode[8..12], i * 0xd); |
| 1296 | try self.base.file.?.pwriteAll(&cccode, self.next_stub_helper_off.?); | 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); | 1297 | self.next_stub_helper_off = self.next_stub_helper_off.? + 3 * @sizeOf(u32); |
| 1298 | | 1298 | |
| 1299 | try self.rebase_info_table.symbols.append(self.base.allocator, .{ | 1299 | try self.rebase_info_table.symbols.append(self.base.allocator, .{ |
| 1300 | .segment = 3, | 1300 | .segment = 3, |
| 1301 | .offset = 0, | 1301 | .offset = i * stubs.reserved2, |
| 1302 | }); | 1302 | }); |
| 1303 | self.rebase_info_dirty = true; | 1303 | self.rebase_info_dirty = true; |
| 1304 | | 1304 | |
| ... | @@ -1308,12 +1308,13 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { | ... | @@ -1308,12 +1308,13 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void { |
| 1308 | mem.copy(u8, name, name_str); | 1308 | mem.copy(u8, name, name_str); |
| 1309 | try self.lazy_binding_info_table.symbols.append(self.base.allocator, .{ | 1309 | try self.lazy_binding_info_table.symbols.append(self.base.allocator, .{ |
| 1310 | .segment = 3, | 1310 | .segment = 3, |
| 1311 | .offset = 0, | 1311 | .offset = i * @sizeOf(u64), |
| 1312 | .dylib_ordinal = 1, | 1312 | .dylib_ordinal = 1, |
| 1313 | .name = name, | 1313 | .name = name, |
| 1314 | }); | 1314 | }); |
| 1315 | self.lazy_binding_info_dirty = true; | 1315 | self.lazy_binding_info_dirty = true; |
| 1316 | } | 1316 | } |
| | 1317 | self.stub_fixups.shrinkRetainingCapacity(0); |
| 1317 | | 1318 | |
| 1318 | const text_section = text_segment.sections.items[self.text_section_index.?]; | 1319 | const text_section = text_segment.sections.items[self.text_section_index.?]; |
| 1319 | const section_offset = symbol.n_value - text_section.addr; | 1320 | const section_offset = symbol.n_value - text_section.addr; |
| ... | @@ -1634,7 +1635,7 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -1634,7 +1635,7 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 1634 | .nreloc = 0, | 1635 | .nreloc = 0, |
| 1635 | .flags = flags, | 1636 | .flags = flags, |
| 1636 | .reserved1 = 0, | 1637 | .reserved1 = 0, |
| 1637 | .reserved2 = 0, | 1638 | .reserved2 = 2 * @sizeOf(u32), |
| 1638 | .reserved3 = 0, | 1639 | .reserved3 = 0, |
| 1639 | }); | 1640 | }); |
| 1640 | self.header_dirty = true; | 1641 | self.header_dirty = true; |
| ... | @@ -2539,20 +2540,45 @@ fn writeIndirectSymbolTable(self: *MachO) !void { | ... | @@ -2539,20 +2540,45 @@ fn writeIndirectSymbolTable(self: *MachO) !void { |
| 2539 | const la = &data_seg.sections.items[self.la_symbol_ptr_section_index.?]; | 2540 | const la = &data_seg.sections.items[self.la_symbol_ptr_section_index.?]; |
| 2540 | const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab; | 2541 | const dysymtab = &self.load_commands.items[self.dysymtab_cmd_index.?].Dysymtab; |
| 2541 | dysymtab.nindirectsyms = 0; | 2542 | dysymtab.nindirectsyms = 0; |
| | 2543 | |
| | 2544 | var buf: [@sizeOf(u32)]u8 = undefined; |
| | 2545 | var off = dysymtab.indirectsymoff; |
| | 2546 | var idx: u32 = 0; |
| | 2547 | |
| | 2548 | stubs.reserved1 = 0; |
| 2542 | for (self.undef_symbols.items) |sym, i| { | 2549 | for (self.undef_symbols.items) |sym, i| { |
| 2543 | const idx = @intCast(u32, dysymtab.iundefsym + i); | 2550 | if (i == self.dyld_stub_binder_index.?) { |
| 2544 | var buf: [@sizeOf(u32)]u8 = undefined; | 2551 | continue; |
| 2545 | mem.writeIntLittle(u32, &buf, idx); | 2552 | } |
| 2546 | try self.base.file.?.pwriteAll(&buf, dysymtab.indirectsymoff + i * @sizeOf(u32)); | 2553 | const symtab_idx = @intCast(u32, dysymtab.iundefsym + i); |
| | 2554 | mem.writeIntLittle(u32, &buf, symtab_idx); |
| | 2555 | try self.base.file.?.pwriteAll(&buf, off); |
| | 2556 | off += @sizeOf(u32); |
| | 2557 | dysymtab.nindirectsyms += 1; |
| | 2558 | idx += 1; |
| | 2559 | } |
| | 2560 | |
| | 2561 | got.reserved1 = @intCast(u32, self.undef_symbols.items.len - 1); |
| | 2562 | if (self.dyld_stub_binder_index) |i| { |
| | 2563 | const symtab_idx = i + dysymtab.iundefsym; |
| | 2564 | mem.writeIntLittle(u32, &buf, symtab_idx); |
| | 2565 | try self.base.file.?.pwriteAll(&buf, off); |
| | 2566 | off += @sizeOf(u32); |
| 2547 | dysymtab.nindirectsyms += 1; | 2567 | dysymtab.nindirectsyms += 1; |
| | 2568 | idx += 1; |
| | 2569 | } |
| | 2570 | |
| | 2571 | la.reserved1 = got.reserved1 + 1; |
| | 2572 | for (self.undef_symbols.items) |sym, i| { |
| 2548 | if (i == self.dyld_stub_binder_index.?) { | 2573 | if (i == self.dyld_stub_binder_index.?) { |
| 2549 | got.reserved1 = @intCast(u32, i); | | |
| 2550 | continue; | 2574 | continue; |
| 2551 | } | 2575 | } |
| 2552 | stubs.reserved1 = @intCast(u32, i); | 2576 | const symtab_idx = @intCast(u32, dysymtab.iundefsym + i); |
| 2553 | try self.base.file.?.pwriteAll(&buf, dysymtab.indirectsymoff + (i + 1) * @sizeOf(u32)); | 2577 | mem.writeIntLittle(u32, &buf, symtab_idx); |
| 2554 | la.reserved1 = @intCast(u32, i + 1); | 2578 | try self.base.file.?.pwriteAll(&buf, off); |
| | 2579 | off += @sizeOf(u32); |
| 2555 | dysymtab.nindirectsyms += 1; | 2580 | dysymtab.nindirectsyms += 1; |
| | 2581 | idx += 1; |
| 2556 | } | 2582 | } |
| 2557 | } | 2583 | } |
| 2558 | | 2584 | |