| ... | @@ -1456,94 +1456,85 @@ pub const Zld = struct { | ... | @@ -1456,94 +1456,85 @@ pub const Zld = struct { |
| 1456 | } | 1456 | } |
| 1457 | | 1457 | |
| 1458 | // Finally, unpack the rest. | 1458 | // Finally, unpack the rest. |
| 1459 | const slice = self.sections.slice(); | 1459 | const cpu_arch = self.options.target.cpu.arch; |
| 1460 | for (slice.items(.header), 0..) |header, sect_id| { | 1460 | for (self.objects.items) |*object| { |
| 1461 | switch (header.type()) { | 1461 | for (object.atoms.items) |atom_index| { |
| 1462 | macho.S_LITERAL_POINTERS, | 1462 | const atom = self.getAtom(atom_index); |
| 1463 | macho.S_REGULAR, | 1463 | const sym = self.getSymbol(atom.getSymbolWithLoc()); |
| 1464 | macho.S_MOD_INIT_FUNC_POINTERS, | 1464 | if (sym.n_desc == MachO.N_DEAD) continue; |
| 1465 | macho.S_MOD_TERM_FUNC_POINTERS, | | |
| 1466 | => {}, | | |
| 1467 | else => continue, | | |
| 1468 | } | | |
| 1469 | | | |
| 1470 | const segment_index = slice.items(.segment_index)[sect_id]; | | |
| 1471 | const segment = self.getSegment(@as(u8, @intCast(sect_id))); | | |
| 1472 | if (segment.maxprot & macho.PROT.WRITE == 0) continue; | | |
| 1473 | | 1465 | |
| 1474 | const cpu_arch = self.options.target.cpu.arch; | 1466 | const sect_id = sym.n_sect - 1; |
| 1475 | var atom_index = slice.items(.first_atom_index)[sect_id] orelse continue; | 1467 | const section = self.sections.items(.header)[sect_id]; |
| | 1468 | const segment_id = self.sections.items(.segment_index)[sect_id]; |
| | 1469 | const segment = self.segments.items[segment_id]; |
| | 1470 | if (segment.maxprot & macho.PROT.WRITE == 0) continue; |
| | 1471 | switch (section.type()) { |
| | 1472 | macho.S_LITERAL_POINTERS, |
| | 1473 | macho.S_REGULAR, |
| | 1474 | macho.S_MOD_INIT_FUNC_POINTERS, |
| | 1475 | macho.S_MOD_TERM_FUNC_POINTERS, |
| | 1476 | => {}, |
| | 1477 | else => continue, |
| | 1478 | } |
| 1476 | | 1479 | |
| 1477 | log.debug("{s},{s}", .{ header.segName(), header.sectName() }); | 1480 | log.debug(" ATOM({d}, %{d}, '{s}')", .{ |
| | 1481 | atom_index, |
| | 1482 | atom.sym_index, |
| | 1483 | self.getSymbolName(atom.getSymbolWithLoc()), |
| | 1484 | }); |
| 1478 | | 1485 | |
| 1479 | while (true) { | 1486 | const code = Atom.getAtomCode(self, atom_index); |
| 1480 | const atom = self.getAtom(atom_index); | 1487 | const relocs = Atom.getAtomRelocs(self, atom_index); |
| 1481 | const sym = self.getSymbol(atom.getSymbolWithLoc()); | 1488 | const ctx = Atom.getRelocContext(self, atom_index); |
| 1482 | | 1489 | |
| 1483 | log.debug(" ATOM({d}, %{d}, '{s}')", .{ atom_index, atom.sym_index, self.getSymbolName(atom.getSymbolWithLoc()) }); | 1490 | for (relocs) |rel| { |
| | 1491 | switch (cpu_arch) { |
| | 1492 | .aarch64 => { |
| | 1493 | const rel_type = @as(macho.reloc_type_arm64, @enumFromInt(rel.r_type)); |
| | 1494 | if (rel_type != .ARM64_RELOC_UNSIGNED) continue; |
| | 1495 | if (rel.r_length != 3) continue; |
| | 1496 | }, |
| | 1497 | .x86_64 => { |
| | 1498 | const rel_type = @as(macho.reloc_type_x86_64, @enumFromInt(rel.r_type)); |
| | 1499 | if (rel_type != .X86_64_RELOC_UNSIGNED) continue; |
| | 1500 | if (rel.r_length != 3) continue; |
| | 1501 | }, |
| | 1502 | else => unreachable, |
| | 1503 | } |
| 1484 | | 1504 | |
| 1485 | const should_bind = blk: { | 1505 | const global = Atom.parseRelocTarget(self, .{ |
| 1486 | if (atom_index == self.dyld_private_atom_index.?) break :blk false; | 1506 | .object_id = atom.getFile().?, |
| 1487 | break :blk true; | 1507 | .rel = rel, |
| 1488 | }; | 1508 | .code = code, |
| | 1509 | .base_offset = ctx.base_offset, |
| | 1510 | .base_addr = ctx.base_addr, |
| | 1511 | }); |
| | 1512 | const bind_sym_name = self.getSymbolName(global); |
| | 1513 | const bind_sym = self.getSymbol(global); |
| | 1514 | if (!bind_sym.undf()) continue; |
| 1489 | | 1515 | |
| 1490 | if (should_bind) { | 1516 | const base_offset = sym.n_value - segment.vmaddr; |
| 1491 | const code = Atom.getAtomCode(self, atom_index); | 1517 | const rel_offset = @as(u32, @intCast(rel.r_address - ctx.base_offset)); |
| 1492 | const relocs = Atom.getAtomRelocs(self, atom_index); | 1518 | const offset = @as(u64, @intCast(base_offset + rel_offset)); |
| 1493 | const ctx = Atom.getRelocContext(self, atom_index); | 1519 | const addend = mem.readIntLittle(i64, code[rel_offset..][0..8]); |
| 1494 | | | |
| 1495 | for (relocs) |rel| { | | |
| 1496 | switch (cpu_arch) { | | |
| 1497 | .aarch64 => { | | |
| 1498 | const rel_type = @as(macho.reloc_type_arm64, @enumFromInt(rel.r_type)); | | |
| 1499 | if (rel_type != .ARM64_RELOC_UNSIGNED) continue; | | |
| 1500 | if (rel.r_length != 3) continue; | | |
| 1501 | }, | | |
| 1502 | .x86_64 => { | | |
| 1503 | const rel_type = @as(macho.reloc_type_x86_64, @enumFromInt(rel.r_type)); | | |
| 1504 | if (rel_type != .X86_64_RELOC_UNSIGNED) continue; | | |
| 1505 | if (rel.r_length != 3) continue; | | |
| 1506 | }, | | |
| 1507 | else => unreachable, | | |
| 1508 | } | | |
| 1509 | | 1520 | |
| 1510 | const global = Atom.parseRelocTarget(self, .{ | 1521 | const dylib_ordinal = @divTrunc(@as(i16, @bitCast(bind_sym.n_desc)), macho.N_SYMBOL_RESOLVER); |
| 1511 | .object_id = atom.getFile().?, | 1522 | log.debug(" | bind at {x}, import('{s}') in dylib({d})", .{ |
| 1512 | .rel = rel, | 1523 | base_offset, |
| 1513 | .code = code, | 1524 | bind_sym_name, |
| 1514 | .base_offset = ctx.base_offset, | 1525 | dylib_ordinal, |
| 1515 | .base_addr = ctx.base_addr, | 1526 | }); |
| 1516 | }); | 1527 | log.debug(" | with addend {x}", .{addend}); |
| 1517 | const bind_sym_name = self.getSymbolName(global); | 1528 | if (bind_sym.weakRef()) { |
| 1518 | const bind_sym = self.getSymbol(global); | 1529 | log.debug(" | marking as weak ref ", .{}); |
| 1519 | if (!bind_sym.undf()) continue; | | |
| 1520 | | | |
| 1521 | const base_offset = sym.n_value - segment.vmaddr; | | |
| 1522 | const rel_offset = @as(u32, @intCast(rel.r_address - ctx.base_offset)); | | |
| 1523 | const offset = @as(u64, @intCast(base_offset + rel_offset)); | | |
| 1524 | const addend = mem.readIntLittle(i64, code[rel_offset..][0..8]); | | |
| 1525 | | | |
| 1526 | const dylib_ordinal = @divTrunc(@as(i16, @bitCast(bind_sym.n_desc)), macho.N_SYMBOL_RESOLVER); | | |
| 1527 | log.debug(" | bind at {x}, import('{s}') in dylib({d})", .{ | | |
| 1528 | base_offset, | | |
| 1529 | bind_sym_name, | | |
| 1530 | dylib_ordinal, | | |
| 1531 | }); | | |
| 1532 | log.debug(" | with addend {x}", .{addend}); | | |
| 1533 | if (bind_sym.weakRef()) { | | |
| 1534 | log.debug(" | marking as weak ref ", .{}); | | |
| 1535 | } | | |
| 1536 | try bind.entries.append(self.gpa, .{ | | |
| 1537 | .target = global, | | |
| 1538 | .offset = offset, | | |
| 1539 | .segment_id = segment_index, | | |
| 1540 | .addend = addend, | | |
| 1541 | }); | | |
| 1542 | } | 1530 | } |
| | 1531 | try bind.entries.append(self.gpa, .{ |
| | 1532 | .target = global, |
| | 1533 | .offset = offset, |
| | 1534 | .segment_id = segment_id, |
| | 1535 | .addend = addend, |
| | 1536 | }); |
| 1543 | } | 1537 | } |
| 1544 | if (atom.next_index) |next_index| { | | |
| 1545 | atom_index = next_index; | | |
| 1546 | } else break; | | |
| 1547 | } | 1538 | } |
| 1548 | } | 1539 | } |
| 1549 | | 1540 | |