| ... | @@ -142,7 +142,7 @@ data_section_index: ?u8 = null, | ... | @@ -142,7 +142,7 @@ data_section_index: ?u8 = null, |
| 142 | locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | 142 | locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 143 | globals: std.ArrayListUnmanaged(SymbolWithLoc) = .{}, | 143 | globals: std.ArrayListUnmanaged(SymbolWithLoc) = .{}, |
| 144 | resolver: std.StringHashMapUnmanaged(u32) = .{}, | 144 | resolver: std.StringHashMapUnmanaged(u32) = .{}, |
| 145 | unresolved: std.AutoArrayHashMapUnmanaged(u32, bool) = .{}, | 145 | unresolved: std.AutoArrayHashMapUnmanaged(u32, ResolveAction.Kind) = .{}, |
| 146 | | 146 | |
| 147 | locals_free_list: std.ArrayListUnmanaged(u32) = .{}, | 147 | locals_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 148 | globals_free_list: std.ArrayListUnmanaged(u32) = .{}, | 148 | globals_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| ... | @@ -295,10 +295,15 @@ const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.A | ... | @@ -295,10 +295,15 @@ const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.A |
| 295 | const RebaseTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); | 295 | const RebaseTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); |
| 296 | const RelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation)); | 296 | const RelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation)); |
| 297 | | 297 | |
| 298 | const PendingUpdate = union(enum) { | 298 | const ResolveAction = struct { |
| 299 | resolve_undef: u32, | 299 | kind: Kind, |
| 300 | add_stub_entry: u32, | 300 | target: SymbolWithLoc, |
| 301 | add_got_entry: u32, | 301 | |
| | 302 | const Kind = enum { |
| | 303 | none, |
| | 304 | add_got, |
| | 305 | add_stub, |
| | 306 | }; |
| 302 | }; | 307 | }; |
| 303 | | 308 | |
| 304 | pub const SymbolWithLoc = struct { | 309 | pub const SymbolWithLoc = struct { |
| ... | @@ -603,16 +608,29 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No | ... | @@ -603,16 +608,29 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 603 | try self.parseDependentLibs(self.base.options.sysroot, &dependent_libs); | 608 | try self.parseDependentLibs(self.base.options.sysroot, &dependent_libs); |
| 604 | } | 609 | } |
| 605 | | 610 | |
| | 611 | if (self.dyld_stub_binder_index == null) { |
| | 612 | self.dyld_stub_binder_index = try self.addUndefined("dyld_stub_binder", .add_got); |
| | 613 | } |
| | 614 | |
| 606 | try self.createMhExecuteHeaderSymbol(); | 615 | try self.createMhExecuteHeaderSymbol(); |
| 607 | try self.resolveDyldStubBinder(); | 616 | |
| 608 | try self.createDyldPrivateAtom(); | 617 | var actions = std.ArrayList(ResolveAction).init(self.base.allocator); |
| 609 | try self.createStubHelperPreambleAtom(); | 618 | defer actions.deinit(); |
| 610 | try self.resolveSymbolsInDylibs(); | 619 | try self.resolveSymbolsInDylibs(&actions); |
| 611 | | 620 | |
| 612 | if (self.unresolved.count() > 0) { | 621 | if (self.unresolved.count() > 0) { |
| 613 | return error.UndefinedSymbolReference; | 622 | return error.UndefinedSymbolReference; |
| 614 | } | 623 | } |
| 615 | | 624 | |
| | 625 | try self.createDyldPrivateAtom(); |
| | 626 | try self.createStubHelperPreambleAtom(); |
| | 627 | |
| | 628 | for (actions.items) |action| switch (action.kind) { |
| | 629 | .none => {}, |
| | 630 | .add_got => try self.addGotEntry(action.target), |
| | 631 | .add_stub => try self.addStubEntry(action.target), |
| | 632 | }; |
| | 633 | |
| 616 | try self.allocateSpecialSymbols(); | 634 | try self.allocateSpecialSymbols(); |
| 617 | | 635 | |
| 618 | for (self.relocs.keys()) |atom_index| { | 636 | for (self.relocs.keys()) |atom_index| { |
| ... | @@ -1242,8 +1260,7 @@ pub fn createGotAtom(self: *MachO, target: SymbolWithLoc) !Atom.Index { | ... | @@ -1242,8 +1260,7 @@ pub fn createGotAtom(self: *MachO, target: SymbolWithLoc) !Atom.Index { |
| 1242 | return atom_index; | 1260 | return atom_index; |
| 1243 | } | 1261 | } |
| 1244 | | 1262 | |
| 1245 | pub fn createDyldPrivateAtom(self: *MachO) !void { | 1263 | fn createDyldPrivateAtom(self: *MachO) !void { |
| 1246 | if (self.dyld_stub_binder_index == null) return; | | |
| 1247 | if (self.dyld_private_atom_index != null) return; | 1264 | if (self.dyld_private_atom_index != null) return; |
| 1248 | | 1265 | |
| 1249 | const atom_index = try self.createAtom(); | 1266 | const atom_index = try self.createAtom(); |
| ... | @@ -1260,8 +1277,7 @@ pub fn createDyldPrivateAtom(self: *MachO) !void { | ... | @@ -1260,8 +1277,7 @@ pub fn createDyldPrivateAtom(self: *MachO) !void { |
| 1260 | try self.writePtrWidthAtom(atom_index); | 1277 | try self.writePtrWidthAtom(atom_index); |
| 1261 | } | 1278 | } |
| 1262 | | 1279 | |
| 1263 | pub fn createStubHelperPreambleAtom(self: *MachO) !void { | 1280 | fn createStubHelperPreambleAtom(self: *MachO) !void { |
| 1264 | if (self.dyld_stub_binder_index == null) return; | | |
| 1265 | if (self.stub_helper_preamble_atom_index != null) return; | 1281 | if (self.stub_helper_preamble_atom_index != null) return; |
| 1266 | | 1282 | |
| 1267 | const gpa = self.base.allocator; | 1283 | const gpa = self.base.allocator; |
| ... | @@ -1285,10 +1301,8 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { | ... | @@ -1285,10 +1301,8 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { |
| 1285 | sym.n_type = macho.N_SECT; | 1301 | sym.n_type = macho.N_SECT; |
| 1286 | sym.n_sect = self.stub_helper_section_index.? + 1; | 1302 | sym.n_sect = self.stub_helper_section_index.? + 1; |
| 1287 | | 1303 | |
| 1288 | const dyld_private_sym_index = if (self.dyld_private_atom_index) |dyld_index| | 1304 | const dyld_private = self.getAtom(self.dyld_private_atom_index.?).getSymbolWithLoc(); |
| 1289 | self.getAtom(dyld_index).getSymbolIndex().? | 1305 | const dyld_stub_binder = self.globals.items[self.dyld_stub_binder_index.?]; |
| 1290 | else | | |
| 1291 | unreachable; | | |
| 1292 | | 1306 | |
| 1293 | const code = try gpa.alloc(u8, size); | 1307 | const code = try gpa.alloc(u8, size); |
| 1294 | defer gpa.free(code); | 1308 | defer gpa.free(code); |
| ... | @@ -1309,14 +1323,14 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { | ... | @@ -1309,14 +1323,14 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { |
| 1309 | | 1323 | |
| 1310 | try Atom.addRelocations(self, atom_index, 2, .{ .{ | 1324 | try Atom.addRelocations(self, atom_index, 2, .{ .{ |
| 1311 | .type = @enumToInt(macho.reloc_type_x86_64.X86_64_RELOC_SIGNED), | 1325 | .type = @enumToInt(macho.reloc_type_x86_64.X86_64_RELOC_SIGNED), |
| 1312 | .target = .{ .sym_index = dyld_private_sym_index, .file = null }, | 1326 | .target = dyld_private, |
| 1313 | .offset = 3, | 1327 | .offset = 3, |
| 1314 | .addend = 0, | 1328 | .addend = 0, |
| 1315 | .pcrel = true, | 1329 | .pcrel = true, |
| 1316 | .length = 2, | 1330 | .length = 2, |
| 1317 | }, .{ | 1331 | }, .{ |
| 1318 | .type = @enumToInt(macho.reloc_type_x86_64.X86_64_RELOC_GOT), | 1332 | .type = @enumToInt(macho.reloc_type_x86_64.X86_64_RELOC_GOT), |
| 1319 | .target = .{ .sym_index = self.dyld_stub_binder_index.?, .file = null }, | 1333 | .target = dyld_stub_binder, |
| 1320 | .offset = 11, | 1334 | .offset = 11, |
| 1321 | .addend = 0, | 1335 | .addend = 0, |
| 1322 | .pcrel = true, | 1336 | .pcrel = true, |
| ... | @@ -1349,28 +1363,28 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { | ... | @@ -1349,28 +1363,28 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { |
| 1349 | | 1363 | |
| 1350 | try Atom.addRelocations(self, atom_index, 4, .{ .{ | 1364 | try Atom.addRelocations(self, atom_index, 4, .{ .{ |
| 1351 | .type = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_PAGE21), | 1365 | .type = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_PAGE21), |
| 1352 | .target = .{ .sym_index = dyld_private_sym_index, .file = null }, | 1366 | .target = dyld_private, |
| 1353 | .offset = 0, | 1367 | .offset = 0, |
| 1354 | .addend = 0, | 1368 | .addend = 0, |
| 1355 | .pcrel = true, | 1369 | .pcrel = true, |
| 1356 | .length = 2, | 1370 | .length = 2, |
| 1357 | }, .{ | 1371 | }, .{ |
| 1358 | .type = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_PAGEOFF12), | 1372 | .type = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_PAGEOFF12), |
| 1359 | .target = .{ .sym_index = dyld_private_sym_index, .file = null }, | 1373 | .target = dyld_private, |
| 1360 | .offset = 4, | 1374 | .offset = 4, |
| 1361 | .addend = 0, | 1375 | .addend = 0, |
| 1362 | .pcrel = false, | 1376 | .pcrel = false, |
| 1363 | .length = 2, | 1377 | .length = 2, |
| 1364 | }, .{ | 1378 | }, .{ |
| 1365 | .type = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGE21), | 1379 | .type = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGE21), |
| 1366 | .target = .{ .sym_index = self.dyld_stub_binder_index.?, .file = null }, | 1380 | .target = dyld_stub_binder, |
| 1367 | .offset = 12, | 1381 | .offset = 12, |
| 1368 | .addend = 0, | 1382 | .addend = 0, |
| 1369 | .pcrel = true, | 1383 | .pcrel = true, |
| 1370 | .length = 2, | 1384 | .length = 2, |
| 1371 | }, .{ | 1385 | }, .{ |
| 1372 | .type = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGEOFF12), | 1386 | .type = @enumToInt(macho.reloc_type_arm64.ARM64_RELOC_GOT_LOAD_PAGEOFF12), |
| 1373 | .target = .{ .sym_index = self.dyld_stub_binder_index.?, .file = null }, | 1387 | .target = dyld_stub_binder, |
| 1374 | .offset = 16, | 1388 | .offset = 16, |
| 1375 | .addend = 0, | 1389 | .addend = 0, |
| 1376 | .pcrel = false, | 1390 | .pcrel = false, |
| ... | @@ -1387,7 +1401,7 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { | ... | @@ -1387,7 +1401,7 @@ pub fn createStubHelperPreambleAtom(self: *MachO) !void { |
| 1387 | try self.writeAtom(atom_index, code); | 1401 | try self.writeAtom(atom_index, code); |
| 1388 | } | 1402 | } |
| 1389 | | 1403 | |
| 1390 | pub fn createStubHelperAtom(self: *MachO) !Atom.Index { | 1404 | fn createStubHelperAtom(self: *MachO) !Atom.Index { |
| 1391 | const gpa = self.base.allocator; | 1405 | const gpa = self.base.allocator; |
| 1392 | const arch = self.base.options.target.cpu.arch; | 1406 | const arch = self.base.options.target.cpu.arch; |
| 1393 | const size: u4 = switch (arch) { | 1407 | const size: u4 = switch (arch) { |
| ... | @@ -1468,7 +1482,7 @@ pub fn createStubHelperAtom(self: *MachO) !Atom.Index { | ... | @@ -1468,7 +1482,7 @@ pub fn createStubHelperAtom(self: *MachO) !Atom.Index { |
| 1468 | return atom_index; | 1482 | return atom_index; |
| 1469 | } | 1483 | } |
| 1470 | | 1484 | |
| 1471 | pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWithLoc) !Atom.Index { | 1485 | fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWithLoc) !Atom.Index { |
| 1472 | const atom_index = try self.createAtom(); | 1486 | const atom_index = try self.createAtom(); |
| 1473 | const atom = self.getAtomPtr(atom_index); | 1487 | const atom = self.getAtomPtr(atom_index); |
| 1474 | atom.size = @sizeOf(u64); | 1488 | atom.size = @sizeOf(u64); |
| ... | @@ -1502,7 +1516,7 @@ pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWi | ... | @@ -1502,7 +1516,7 @@ pub fn createLazyPointerAtom(self: *MachO, stub_sym_index: u32, target: SymbolWi |
| 1502 | return atom_index; | 1516 | return atom_index; |
| 1503 | } | 1517 | } |
| 1504 | | 1518 | |
| 1505 | pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index { | 1519 | fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index { |
| 1506 | const gpa = self.base.allocator; | 1520 | const gpa = self.base.allocator; |
| 1507 | const arch = self.base.options.target.cpu.arch; | 1521 | const arch = self.base.options.target.cpu.arch; |
| 1508 | const size: u4 = switch (arch) { | 1522 | const size: u4 = switch (arch) { |
| ... | @@ -1585,7 +1599,7 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index { | ... | @@ -1585,7 +1599,7 @@ pub fn createStubAtom(self: *MachO, laptr_sym_index: u32) !Atom.Index { |
| 1585 | return atom_index; | 1599 | return atom_index; |
| 1586 | } | 1600 | } |
| 1587 | | 1601 | |
| 1588 | pub fn createMhExecuteHeaderSymbol(self: *MachO) !void { | 1602 | fn createMhExecuteHeaderSymbol(self: *MachO) !void { |
| 1589 | if (self.base.options.output_mode != .Exe) return; | 1603 | if (self.base.options.output_mode != .Exe) return; |
| 1590 | if (self.getGlobal("__mh_execute_header")) |global| { | 1604 | if (self.getGlobal("__mh_execute_header")) |global| { |
| 1591 | const sym = self.getSymbol(global); | 1605 | const sym = self.getSymbol(global); |
| ... | @@ -1608,7 +1622,7 @@ pub fn createMhExecuteHeaderSymbol(self: *MachO) !void { | ... | @@ -1608,7 +1622,7 @@ pub fn createMhExecuteHeaderSymbol(self: *MachO) !void { |
| 1608 | gop.value_ptr.* = sym_loc; | 1622 | gop.value_ptr.* = sym_loc; |
| 1609 | } | 1623 | } |
| 1610 | | 1624 | |
| 1611 | pub fn createDsoHandleSymbol(self: *MachO) !void { | 1625 | fn createDsoHandleSymbol(self: *MachO) !void { |
| 1612 | const global = self.getGlobalPtr("___dso_handle") orelse return; | 1626 | const global = self.getGlobalPtr("___dso_handle") orelse return; |
| 1613 | if (!self.getSymbol(global.*).undf()) return; | 1627 | if (!self.getSymbol(global.*).undf()) return; |
| 1614 | | 1628 | |
| ... | @@ -1636,7 +1650,7 @@ fn resolveGlobalSymbol(self: *MachO, current: SymbolWithLoc) !void { | ... | @@ -1636,7 +1650,7 @@ fn resolveGlobalSymbol(self: *MachO, current: SymbolWithLoc) !void { |
| 1636 | if (!gop.found_existing) { | 1650 | if (!gop.found_existing) { |
| 1637 | gop.value_ptr.* = current; | 1651 | gop.value_ptr.* = current; |
| 1638 | if (sym.undf() and !sym.tentative()) { | 1652 | if (sym.undf() and !sym.tentative()) { |
| 1639 | try self.unresolved.putNoClobber(gpa, self.getGlobalIndex(sym_name).?, false); | 1653 | try self.unresolved.putNoClobber(gpa, self.getGlobalIndex(sym_name).?, .none); |
| 1640 | } | 1654 | } |
| 1641 | return; | 1655 | return; |
| 1642 | } | 1656 | } |
| ... | @@ -1683,7 +1697,7 @@ fn resolveGlobalSymbol(self: *MachO, current: SymbolWithLoc) !void { | ... | @@ -1683,7 +1697,7 @@ fn resolveGlobalSymbol(self: *MachO, current: SymbolWithLoc) !void { |
| 1683 | gop.value_ptr.* = current; | 1697 | gop.value_ptr.* = current; |
| 1684 | } | 1698 | } |
| 1685 | | 1699 | |
| 1686 | pub fn resolveSymbolsInDylibs(self: *MachO) !void { | 1700 | fn resolveSymbolsInDylibs(self: *MachO, actions: *std.ArrayList(ResolveAction)) !void { |
| 1687 | if (self.dylibs.items.len == 0) return; | 1701 | if (self.dylibs.items.len == 0) return; |
| 1688 | | 1702 | |
| 1689 | const gpa = self.base.allocator; | 1703 | const gpa = self.base.allocator; |
| ... | @@ -1711,19 +1725,8 @@ pub fn resolveSymbolsInDylibs(self: *MachO) !void { | ... | @@ -1711,19 +1725,8 @@ pub fn resolveSymbolsInDylibs(self: *MachO) !void { |
| 1711 | } | 1725 | } |
| 1712 | | 1726 | |
| 1713 | if (self.unresolved.fetchSwapRemove(global_index)) |entry| blk: { | 1727 | if (self.unresolved.fetchSwapRemove(global_index)) |entry| blk: { |
| 1714 | if (!entry.value) break :blk; | | |
| 1715 | if (!sym.undf()) break :blk; | 1728 | if (!sym.undf()) break :blk; |
| 1716 | if (self.stubs_table.contains(global)) break :blk; | 1729 | try actions.append(.{ .kind = entry.value, .target = global }); |
| 1717 | | | |
| 1718 | const stub_index = try self.allocateStubEntry(global); | | |
| 1719 | const stub_helper_atom_index = try self.createStubHelperAtom(); | | |
| 1720 | const stub_helper_atom = self.getAtom(stub_helper_atom_index); | | |
| 1721 | const laptr_atom_index = try self.createLazyPointerAtom(stub_helper_atom.getSymbolIndex().?, global); | | |
| 1722 | const laptr_atom = self.getAtom(laptr_atom_index); | | |
| 1723 | const stub_atom_index = try self.createStubAtom(laptr_atom.getSymbolIndex().?); | | |
| 1724 | const stub_atom = self.getAtom(stub_atom_index); | | |
| 1725 | self.stubs.items[stub_index].sym_index = stub_atom.getSymbolIndex().?; | | |
| 1726 | self.markRelocsDirtyByTarget(global); | | |
| 1727 | } | 1730 | } |
| 1728 | | 1731 | |
| 1729 | continue :loop; | 1732 | continue :loop; |
| ... | @@ -1733,101 +1736,6 @@ pub fn resolveSymbolsInDylibs(self: *MachO) !void { | ... | @@ -1733,101 +1736,6 @@ pub fn resolveSymbolsInDylibs(self: *MachO) !void { |
| 1733 | } | 1736 | } |
| 1734 | } | 1737 | } |
| 1735 | | 1738 | |
| 1736 | pub fn resolveSymbolsAtLoading(self: *MachO) !void { | | |
| 1737 | const is_lib = self.base.options.output_mode == .Lib; | | |
| 1738 | const is_dyn_lib = self.base.options.link_mode == .Dynamic and is_lib; | | |
| 1739 | const allow_undef = is_dyn_lib and (self.base.options.allow_shlib_undefined orelse false); | | |
| 1740 | | | |
| 1741 | var next_sym: usize = 0; | | |
| 1742 | while (next_sym < self.unresolved.count()) { | | |
| 1743 | const global_index = self.unresolved.keys()[next_sym]; | | |
| 1744 | const global = self.globals.items[global_index]; | | |
| 1745 | const sym = self.getSymbolPtr(global); | | |
| 1746 | const sym_name = self.getSymbolName(global); | | |
| 1747 | | | |
| 1748 | if (sym.discarded()) { | | |
| 1749 | sym.* = .{ | | |
| 1750 | .n_strx = 0, | | |
| 1751 | .n_type = macho.N_UNDF, | | |
| 1752 | .n_sect = 0, | | |
| 1753 | .n_desc = 0, | | |
| 1754 | .n_value = 0, | | |
| 1755 | }; | | |
| 1756 | _ = self.unresolved.swapRemove(global_index); | | |
| 1757 | continue; | | |
| 1758 | } else if (allow_undef) { | | |
| 1759 | const n_desc = @bitCast( | | |
| 1760 | u16, | | |
| 1761 | macho.BIND_SPECIAL_DYLIB_FLAT_LOOKUP * @intCast(i16, macho.N_SYMBOL_RESOLVER), | | |
| 1762 | ); | | |
| 1763 | // TODO allow_shlib_undefined is an ELF flag so figure out macOS specific flags too. | | |
| 1764 | sym.n_type = macho.N_EXT; | | |
| 1765 | sym.n_desc = n_desc; | | |
| 1766 | _ = self.unresolved.swapRemove(global_index); | | |
| 1767 | continue; | | |
| 1768 | } | | |
| 1769 | | | |
| 1770 | log.err("undefined reference to symbol '{s}'", .{sym_name}); | | |
| 1771 | if (global.file) |file| { | | |
| 1772 | log.err(" first referenced in '{s}'", .{self.objects.items[file].name}); | | |
| 1773 | } | | |
| 1774 | | | |
| 1775 | next_sym += 1; | | |
| 1776 | } | | |
| 1777 | } | | |
| 1778 | | | |
| 1779 | pub fn resolveDyldStubBinder(self: *MachO) !void { | | |
| 1780 | if (self.dyld_stub_binder_index != null) return; | | |
| 1781 | if (self.unresolved.count() == 0) return; // no need for a stub binder if we don't have any imports | | |
| 1782 | | | |
| 1783 | log.debug("resolving dyld_stub_binder", .{}); | | |
| 1784 | | | |
| 1785 | const gpa = self.base.allocator; | | |
| 1786 | const sym_index = try self.allocateSymbol(); | | |
| 1787 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; | | |
| 1788 | const sym = self.getSymbolPtr(sym_loc); | | |
| 1789 | const sym_name = "dyld_stub_binder"; | | |
| 1790 | sym.* = .{ | | |
| 1791 | .n_strx = try self.strtab.insert(gpa, sym_name), | | |
| 1792 | .n_type = macho.N_UNDF, | | |
| 1793 | .n_sect = 0, | | |
| 1794 | .n_desc = 0, | | |
| 1795 | .n_value = 0, | | |
| 1796 | }; | | |
| 1797 | const gop = try self.getOrPutGlobalPtr(sym_name); | | |
| 1798 | gop.value_ptr.* = sym_loc; | | |
| 1799 | const global = gop.value_ptr.*; | | |
| 1800 | | | |
| 1801 | for (self.dylibs.items, 0..) |dylib, id| { | | |
| 1802 | if (!dylib.symbols.contains(sym_name)) continue; | | |
| 1803 | | | |
| 1804 | const dylib_id = @intCast(u16, id); | | |
| 1805 | if (!self.referenced_dylibs.contains(dylib_id)) { | | |
| 1806 | try self.referenced_dylibs.putNoClobber(gpa, dylib_id, {}); | | |
| 1807 | } | | |
| 1808 | | | |
| 1809 | const ordinal = self.referenced_dylibs.getIndex(dylib_id) orelse unreachable; | | |
| 1810 | sym.n_type |= macho.N_EXT; | | |
| 1811 | sym.n_desc = @intCast(u16, ordinal + 1) * macho.N_SYMBOL_RESOLVER; | | |
| 1812 | self.dyld_stub_binder_index = sym_index; | | |
| 1813 | | | |
| 1814 | break; | | |
| 1815 | } | | |
| 1816 | | | |
| 1817 | if (self.dyld_stub_binder_index == null) { | | |
| 1818 | log.err("undefined reference to symbol '{s}'", .{sym_name}); | | |
| 1819 | return error.UndefinedSymbolReference; | | |
| 1820 | } | | |
| 1821 | | | |
| 1822 | // Add dyld_stub_binder as the final GOT entry. | | |
| 1823 | const got_index = try self.allocateGotEntry(global); | | |
| 1824 | const got_atom_index = try self.createGotAtom(global); | | |
| 1825 | const got_atom = self.getAtom(got_atom_index); | | |
| 1826 | self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?; | | |
| 1827 | | | |
| 1828 | try self.writePtrWidthAtom(got_atom_index); | | |
| 1829 | } | | |
| 1830 | | | |
| 1831 | pub fn deinit(self: *MachO) void { | 1739 | pub fn deinit(self: *MachO) void { |
| 1832 | const gpa = self.base.allocator; | 1740 | const gpa = self.base.allocator; |
| 1833 | | 1741 | |
| ... | @@ -2016,7 +1924,7 @@ fn growAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignment: | ... | @@ -2016,7 +1924,7 @@ fn growAtom(self: *MachO, atom_index: Atom.Index, new_atom_size: u64, alignment: |
| 2016 | return self.allocateAtom(atom_index, new_atom_size, alignment); | 1924 | return self.allocateAtom(atom_index, new_atom_size, alignment); |
| 2017 | } | 1925 | } |
| 2018 | | 1926 | |
| 2019 | pub fn allocateSymbol(self: *MachO) !u32 { | 1927 | fn allocateSymbol(self: *MachO) !u32 { |
| 2020 | try self.locals.ensureUnusedCapacity(self.base.allocator, 1); | 1928 | try self.locals.ensureUnusedCapacity(self.base.allocator, 1); |
| 2021 | | 1929 | |
| 2022 | const index = blk: { | 1930 | const index = blk: { |
| ... | @@ -2065,7 +1973,7 @@ fn allocateGlobal(self: *MachO) !u32 { | ... | @@ -2065,7 +1973,7 @@ fn allocateGlobal(self: *MachO) !u32 { |
| 2065 | return index; | 1973 | return index; |
| 2066 | } | 1974 | } |
| 2067 | | 1975 | |
| 2068 | pub fn allocateGotEntry(self: *MachO, target: SymbolWithLoc) !u32 { | 1976 | fn allocateGotEntry(self: *MachO, target: SymbolWithLoc) !u32 { |
| 2069 | const gpa = self.base.allocator; | 1977 | const gpa = self.base.allocator; |
| 2070 | try self.got_entries.ensureUnusedCapacity(gpa, 1); | 1978 | try self.got_entries.ensureUnusedCapacity(gpa, 1); |
| 2071 | | 1979 | |
| ... | @@ -2087,7 +1995,17 @@ pub fn allocateGotEntry(self: *MachO, target: SymbolWithLoc) !u32 { | ... | @@ -2087,7 +1995,17 @@ pub fn allocateGotEntry(self: *MachO, target: SymbolWithLoc) !u32 { |
| 2087 | return index; | 1995 | return index; |
| 2088 | } | 1996 | } |
| 2089 | | 1997 | |
| 2090 | pub fn allocateStubEntry(self: *MachO, target: SymbolWithLoc) !u32 { | 1998 | fn addGotEntry(self: *MachO, target: SymbolWithLoc) !void { |
| | 1999 | if (self.got_entries_table.contains(target)) return; |
| | 2000 | |
| | 2001 | const got_index = try self.allocateGotEntry(target); |
| | 2002 | const got_atom_index = try self.createGotAtom(target); |
| | 2003 | const got_atom = self.getAtom(got_atom_index); |
| | 2004 | self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?; |
| | 2005 | try self.writePtrWidthAtom(got_atom_index); |
| | 2006 | } |
| | 2007 | |
| | 2008 | fn allocateStubEntry(self: *MachO, target: SymbolWithLoc) !u32 { |
| 2091 | try self.stubs.ensureUnusedCapacity(self.base.allocator, 1); | 2009 | try self.stubs.ensureUnusedCapacity(self.base.allocator, 1); |
| 2092 | | 2010 | |
| 2093 | const index = blk: { | 2011 | const index = blk: { |
| ... | @@ -2108,6 +2026,20 @@ pub fn allocateStubEntry(self: *MachO, target: SymbolWithLoc) !u32 { | ... | @@ -2108,6 +2026,20 @@ pub fn allocateStubEntry(self: *MachO, target: SymbolWithLoc) !u32 { |
| 2108 | return index; | 2026 | return index; |
| 2109 | } | 2027 | } |
| 2110 | | 2028 | |
| | 2029 | fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void { |
| | 2030 | if (self.stubs_table.contains(target)) return; |
| | 2031 | |
| | 2032 | const stub_index = try self.allocateStubEntry(target); |
| | 2033 | const stub_helper_atom_index = try self.createStubHelperAtom(); |
| | 2034 | const stub_helper_atom = self.getAtom(stub_helper_atom_index); |
| | 2035 | const laptr_atom_index = try self.createLazyPointerAtom(stub_helper_atom.getSymbolIndex().?, target); |
| | 2036 | const laptr_atom = self.getAtom(laptr_atom_index); |
| | 2037 | const stub_atom_index = try self.createStubAtom(laptr_atom.getSymbolIndex().?); |
| | 2038 | const stub_atom = self.getAtom(stub_atom_index); |
| | 2039 | self.stubs.items[stub_index].sym_index = stub_atom.getSymbolIndex().?; |
| | 2040 | self.markRelocsDirtyByTarget(target); |
| | 2041 | } |
| | 2042 | |
| 2111 | pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void { | 2043 | pub fn updateFunc(self: *MachO, module: *Module, func: *Module.Fn, air: Air, liveness: Liveness) !void { |
| 2112 | if (build_options.skip_non_native and builtin.object_format != .macho) { | 2044 | if (build_options.skip_non_native and builtin.object_format != .macho) { |
| 2113 | @panic("Attempted to compile for object format that was disabled by build configuration"); | 2045 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| ... | @@ -2376,13 +2308,7 @@ fn updateLazySymbolAtom( | ... | @@ -2376,13 +2308,7 @@ fn updateLazySymbolAtom( |
| 2376 | atom.size = code.len; | 2308 | atom.size = code.len; |
| 2377 | symbol.n_value = vaddr; | 2309 | symbol.n_value = vaddr; |
| 2378 | | 2310 | |
| 2379 | const got_target = SymbolWithLoc{ .sym_index = local_sym_index, .file = null }; | 2311 | try self.addGotEntry(.{ .sym_index = local_sym_index }); |
| 2380 | const got_index = try self.allocateGotEntry(got_target); | | |
| 2381 | const got_atom_index = try self.createGotAtom(got_target); | | |
| 2382 | const got_atom = self.getAtom(got_atom_index); | | |
| 2383 | self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?; | | |
| 2384 | try self.writePtrWidthAtom(got_atom_index); | | |
| 2385 | | | |
| 2386 | self.markRelocsDirtyByTarget(atom.getSymbolWithLoc()); | 2312 | self.markRelocsDirtyByTarget(atom.getSymbolWithLoc()); |
| 2387 | try self.writeAtom(atom_index, code); | 2313 | try self.writeAtom(atom_index, code); |
| 2388 | } | 2314 | } |
| ... | @@ -2445,114 +2371,6 @@ fn getDeclOutputSection(self: *MachO, decl_index: Module.Decl.Index) u8 { | ... | @@ -2445,114 +2371,6 @@ fn getDeclOutputSection(self: *MachO, decl_index: Module.Decl.Index) u8 { |
| 2445 | return sect_id; | 2371 | return sect_id; |
| 2446 | } | 2372 | } |
| 2447 | | 2373 | |
| 2448 | pub fn getOutputSection(self: *MachO, sect: macho.section_64) !?u8 { | | |
| 2449 | const segname = sect.segName(); | | |
| 2450 | const sectname = sect.sectName(); | | |
| 2451 | const sect_id: ?u8 = blk: { | | |
| 2452 | if (mem.eql(u8, "__LLVM", segname)) { | | |
| 2453 | log.debug("TODO LLVM section: type 0x{x}, name '{s},{s}'", .{ | | |
| 2454 | sect.flags, segname, sectname, | | |
| 2455 | }); | | |
| 2456 | break :blk null; | | |
| 2457 | } | | |
| 2458 | | | |
| 2459 | if (sect.isCode()) { | | |
| 2460 | if (self.text_section_index == null) { | | |
| 2461 | self.text_section_index = try self.initSection("__TEXT", "__text", .{ | | |
| 2462 | .flags = macho.S_REGULAR | | | |
| 2463 | macho.S_ATTR_PURE_INSTRUCTIONS | | | |
| 2464 | macho.S_ATTR_SOME_INSTRUCTIONS, | | |
| 2465 | }); | | |
| 2466 | } | | |
| 2467 | break :blk self.text_section_index.?; | | |
| 2468 | } | | |
| 2469 | | | |
| 2470 | if (sect.isDebug()) { | | |
| 2471 | // TODO debug attributes | | |
| 2472 | if (mem.eql(u8, "__LD", segname) and mem.eql(u8, "__compact_unwind", sectname)) { | | |
| 2473 | log.debug("TODO compact unwind section: type 0x{x}, name '{s},{s}'", .{ | | |
| 2474 | sect.flags, segname, sectname, | | |
| 2475 | }); | | |
| 2476 | } | | |
| 2477 | break :blk null; | | |
| 2478 | } | | |
| 2479 | | | |
| 2480 | switch (sect.type()) { | | |
| 2481 | macho.S_4BYTE_LITERALS, | | |
| 2482 | macho.S_8BYTE_LITERALS, | | |
| 2483 | macho.S_16BYTE_LITERALS, | | |
| 2484 | => { | | |
| 2485 | if (self.getSectionByName("__TEXT", "__const")) |sect_id| break :blk sect_id; | | |
| 2486 | break :blk try self.initSection("__TEXT", "__const", .{}); | | |
| 2487 | }, | | |
| 2488 | macho.S_CSTRING_LITERALS => { | | |
| 2489 | if (mem.startsWith(u8, sectname, "__objc")) { | | |
| 2490 | if (self.getSectionByName(segname, sectname)) |sect_id| break :blk sect_id; | | |
| 2491 | break :blk try self.initSection(segname, sectname, .{}); | | |
| 2492 | } | | |
| 2493 | if (self.getSectionByName("__TEXT", "__cstring")) |sect_id| break :blk sect_id; | | |
| 2494 | break :blk try self.initSection("__TEXT", "__cstring", .{ | | |
| 2495 | .flags = macho.S_CSTRING_LITERALS, | | |
| 2496 | }); | | |
| 2497 | }, | | |
| 2498 | macho.S_MOD_INIT_FUNC_POINTERS, | | |
| 2499 | macho.S_MOD_TERM_FUNC_POINTERS, | | |
| 2500 | => { | | |
| 2501 | if (self.getSectionByName("__DATA_CONST", sectname)) |sect_id| break :blk sect_id; | | |
| 2502 | break :blk try self.initSection("__DATA_CONST", sectname, .{ | | |
| 2503 | .flags = sect.flags, | | |
| 2504 | }); | | |
| 2505 | }, | | |
| 2506 | macho.S_LITERAL_POINTERS, | | |
| 2507 | macho.S_ZEROFILL, | | |
| 2508 | macho.S_THREAD_LOCAL_VARIABLES, | | |
| 2509 | macho.S_THREAD_LOCAL_VARIABLE_POINTERS, | | |
| 2510 | macho.S_THREAD_LOCAL_REGULAR, | | |
| 2511 | macho.S_THREAD_LOCAL_ZEROFILL, | | |
| 2512 | => { | | |
| 2513 | if (self.getSectionByName(segname, sectname)) |sect_id| break :blk sect_id; | | |
| 2514 | break :blk try self.initSection(segname, sectname, .{ .flags = sect.flags }); | | |
| 2515 | }, | | |
| 2516 | macho.S_COALESCED => { | | |
| 2517 | if (self.getSectionByName(segname, sectname)) |sect_id| break :blk sect_id; | | |
| 2518 | break :blk try self.initSection(segname, sectname, .{}); | | |
| 2519 | }, | | |
| 2520 | macho.S_REGULAR => { | | |
| 2521 | if (mem.eql(u8, segname, "__TEXT")) { | | |
| 2522 | if (mem.eql(u8, sectname, "__rodata") or | | |
| 2523 | mem.eql(u8, sectname, "__typelink") or | | |
| 2524 | mem.eql(u8, sectname, "__itablink") or | | |
| 2525 | mem.eql(u8, sectname, "__gosymtab") or | | |
| 2526 | mem.eql(u8, sectname, "__gopclntab")) | | |
| 2527 | { | | |
| 2528 | if (self.getSectionByName("__DATA_CONST", "__const")) |sect_id| break :blk sect_id; | | |
| 2529 | break :blk try self.initSection("__DATA_CONST", "__const", .{}); | | |
| 2530 | } | | |
| 2531 | } | | |
| 2532 | if (mem.eql(u8, segname, "__DATA")) { | | |
| 2533 | if (mem.eql(u8, sectname, "__const") or | | |
| 2534 | mem.eql(u8, sectname, "__cfstring") or | | |
| 2535 | mem.eql(u8, sectname, "__objc_classlist") or | | |
| 2536 | mem.eql(u8, sectname, "__objc_imageinfo")) | | |
| 2537 | { | | |
| 2538 | if (self.getSectionByName("__DATA_CONST", sectname)) |sect_id| break :blk sect_id; | | |
| 2539 | break :blk try self.initSection("__DATA_CONST", sectname, .{}); | | |
| 2540 | } else if (mem.eql(u8, sectname, "__data")) { | | |
| 2541 | if (self.data_section_index == null) { | | |
| 2542 | self.data_section_index = try self.initSection(segname, sectname, .{}); | | |
| 2543 | } | | |
| 2544 | break :blk self.data_section_index.?; | | |
| 2545 | } | | |
| 2546 | } | | |
| 2547 | if (self.getSectionByName(segname, sectname)) |sect_id| break :blk sect_id; | | |
| 2548 | break :blk try self.initSection(segname, sectname, .{}); | | |
| 2549 | }, | | |
| 2550 | else => break :blk null, | | |
| 2551 | } | | |
| 2552 | }; | | |
| 2553 | return sect_id; | | |
| 2554 | } | | |
| 2555 | | | |
| 2556 | fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 { | 2374 | fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 { |
| 2557 | const gpa = self.base.allocator; | 2375 | const gpa = self.base.allocator; |
| 2558 | const mod = self.base.options.module.?; | 2376 | const mod = self.base.options.module.?; |
| ... | @@ -2619,12 +2437,7 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 | ... | @@ -2619,12 +2437,7 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64 |
| 2619 | self.getAtomPtr(atom_index).size = code_len; | 2437 | self.getAtomPtr(atom_index).size = code_len; |
| 2620 | sym.n_value = vaddr; | 2438 | sym.n_value = vaddr; |
| 2621 | | 2439 | |
| 2622 | const got_target = SymbolWithLoc{ .sym_index = sym_index, .file = null }; | 2440 | try self.addGotEntry(.{ .sym_index = sym_index }); |
| 2623 | const got_index = try self.allocateGotEntry(got_target); | | |
| 2624 | const got_atom_index = try self.createGotAtom(got_target); | | |
| 2625 | const got_atom = self.getAtom(got_atom_index); | | |
| 2626 | self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?; | | |
| 2627 | try self.writePtrWidthAtom(got_atom_index); | | |
| 2628 | } | 2441 | } |
| 2629 | | 2442 | |
| 2630 | self.markRelocsDirtyByTarget(atom.getSymbolWithLoc()); | 2443 | self.markRelocsDirtyByTarget(atom.getSymbolWithLoc()); |
| ... | @@ -2837,7 +2650,7 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil | ... | @@ -2837,7 +2650,7 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil |
| 2837 | return 0; | 2650 | return 0; |
| 2838 | } | 2651 | } |
| 2839 | | 2652 | |
| 2840 | pub fn populateMissingMetadata(self: *MachO) !void { | 2653 | fn populateMissingMetadata(self: *MachO) !void { |
| 2841 | assert(self.mode == .incremental); | 2654 | assert(self.mode == .incremental); |
| 2842 | | 2655 | |
| 2843 | const gpa = self.base.allocator; | 2656 | const gpa = self.base.allocator; |
| ... | @@ -3273,79 +3086,12 @@ fn getSectionPrecedence(header: macho.section_64) u4 { | ... | @@ -3273,79 +3086,12 @@ fn getSectionPrecedence(header: macho.section_64) u4 { |
| 3273 | } | 3086 | } |
| 3274 | } | 3087 | } |
| 3275 | | 3088 | |
| 3276 | const InitSectionOpts = struct { | | |
| 3277 | flags: u32 = macho.S_REGULAR, | | |
| 3278 | reserved1: u32 = 0, | | |
| 3279 | reserved2: u32 = 0, | | |
| 3280 | }; | | |
| 3281 | | | |
| 3282 | pub fn initSection(self: *MachO, segname: []const u8, sectname: []const u8, opts: InitSectionOpts) !u8 { | | |
| 3283 | const segment_id = self.getSegmentByName(segname).?; | | |
| 3284 | const seg = &self.segments.items[segment_id]; | | |
| 3285 | const index = try self.insertSection(segment_id, .{ | | |
| 3286 | .sectname = makeStaticString(sectname), | | |
| 3287 | .segname = seg.segname, | | |
| 3288 | .flags = opts.flags, | | |
| 3289 | .reserved1 = opts.reserved1, | | |
| 3290 | .reserved2 = opts.reserved2, | | |
| 3291 | }); | | |
| 3292 | seg.cmdsize += @sizeOf(macho.section_64); | | |
| 3293 | seg.nsects += 1; | | |
| 3294 | return index; | | |
| 3295 | } | | |
| 3296 | | | |
| 3297 | fn insertSection(self: *MachO, segment_index: u8, header: macho.section_64) !u8 { | | |
| 3298 | const precedence = getSectionPrecedence(header); | | |
| 3299 | const indexes = self.getSectionIndexes(segment_index); | | |
| 3300 | const insertion_index = for (self.sections.items(.header)[indexes.start..indexes.end], 0..) |hdr, i| { | | |
| 3301 | if (getSectionPrecedence(hdr) > precedence) break @intCast(u8, i + indexes.start); | | |
| 3302 | } else indexes.end; | | |
| 3303 | log.debug("inserting section '{s},{s}' at index {d}", .{ | | |
| 3304 | header.segName(), | | |
| 3305 | header.sectName(), | | |
| 3306 | insertion_index, | | |
| 3307 | }); | | |
| 3308 | for (&[_]*?u8{ | | |
| 3309 | &self.text_section_index, | | |
| 3310 | &self.stubs_section_index, | | |
| 3311 | &self.stub_helper_section_index, | | |
| 3312 | &self.got_section_index, | | |
| 3313 | &self.la_symbol_ptr_section_index, | | |
| 3314 | &self.data_section_index, | | |
| 3315 | }) |maybe_index| { | | |
| 3316 | const index = maybe_index.* orelse continue; | | |
| 3317 | if (insertion_index <= index) maybe_index.* = index + 1; | | |
| 3318 | } | | |
| 3319 | try self.sections.insert(self.base.allocator, insertion_index, .{ | | |
| 3320 | .segment_index = segment_index, | | |
| 3321 | .header = header, | | |
| 3322 | }); | | |
| 3323 | return insertion_index; | | |
| 3324 | } | | |
| 3325 | | | |
| 3326 | pub fn getGlobalSymbol(self: *MachO, name: []const u8, lib_name: ?[]const u8) !u32 { | 3089 | pub fn getGlobalSymbol(self: *MachO, name: []const u8, lib_name: ?[]const u8) !u32 { |
| 3327 | _ = lib_name; | 3090 | _ = lib_name; |
| 3328 | const gpa = self.base.allocator; | 3091 | const gpa = self.base.allocator; |
| 3329 | | | |
| 3330 | const sym_name = try std.fmt.allocPrint(gpa, "_{s}", .{name}); | 3092 | const sym_name = try std.fmt.allocPrint(gpa, "_{s}", .{name}); |
| 3331 | defer gpa.free(sym_name); | 3093 | defer gpa.free(sym_name); |
| 3332 | const gop = try self.getOrPutGlobalPtr(sym_name); | 3094 | return self.addUndefined(sym_name, .add_stub); |
| 3333 | const global_index = self.getGlobalIndex(sym_name).?; | | |
| 3334 | | | |
| 3335 | if (gop.found_existing) { | | |
| 3336 | return global_index; | | |
| 3337 | } | | |
| 3338 | | | |
| 3339 | const sym_index = try self.allocateSymbol(); | | |
| 3340 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; | | |
| 3341 | gop.value_ptr.* = sym_loc; | | |
| 3342 | | | |
| 3343 | const sym = self.getSymbolPtr(sym_loc); | | |
| 3344 | sym.n_strx = try self.strtab.insert(gpa, sym_name); | | |
| 3345 | | | |
| 3346 | try self.unresolved.putNoClobber(gpa, global_index, true); | | |
| 3347 | | | |
| 3348 | return global_index; | | |
| 3349 | } | 3095 | } |
| 3350 | | 3096 | |
| 3351 | fn writeSegmentHeaders(self: *MachO, writer: anytype) !void { | 3097 | fn writeSegmentHeaders(self: *MachO, writer: anytype) !void { |
| ... | @@ -3953,6 +3699,29 @@ pub fn ptraceDetach(self: *MachO, pid: std.os.pid_t) !void { | ... | @@ -3953,6 +3699,29 @@ pub fn ptraceDetach(self: *MachO, pid: std.os.pid_t) !void { |
| 3953 | self.hot_state.mach_task = null; | 3699 | self.hot_state.mach_task = null; |
| 3954 | } | 3700 | } |
| 3955 | | 3701 | |
| | 3702 | fn addUndefined(self: *MachO, name: []const u8, action: ResolveAction.Kind) !u32 { |
| | 3703 | const gpa = self.base.allocator; |
| | 3704 | |
| | 3705 | const gop = try self.getOrPutGlobalPtr(name); |
| | 3706 | const global_index = self.getGlobalIndex(name).?; |
| | 3707 | |
| | 3708 | if (gop.found_existing) { |
| | 3709 | return global_index; |
| | 3710 | } |
| | 3711 | |
| | 3712 | const sym_index = try self.allocateSymbol(); |
| | 3713 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index }; |
| | 3714 | gop.value_ptr.* = sym_loc; |
| | 3715 | |
| | 3716 | const sym = self.getSymbolPtr(sym_loc); |
| | 3717 | sym.n_strx = try self.strtab.insert(gpa, name); |
| | 3718 | sym.n_type = macho.N_UNDF; |
| | 3719 | |
| | 3720 | try self.unresolved.putNoClobber(gpa, global_index, action); |
| | 3721 | |
| | 3722 | return global_index; |
| | 3723 | } |
| | 3724 | |
| 3956 | pub fn makeStaticString(bytes: []const u8) [16]u8 { | 3725 | pub fn makeStaticString(bytes: []const u8) [16]u8 { |
| 3957 | var buf = [_]u8{0} ** 16; | 3726 | var buf = [_]u8{0} ** 16; |
| 3958 | assert(bytes.len <= buf.len); | 3727 | assert(bytes.len <= buf.len); |