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