| ... | ... | @@ -1456,94 +1456,85 @@ pub const Zld = struct { |
| 1456 | 1456 | } |
| 1457 | 1457 | |
| 1458 | 1458 | // Finally, unpack the rest. |
| 1459 | | const slice = self.sections.slice(); |
| 1460 | | for (slice.items(.header), 0..) |header, sect_id| { |
| 1461 | | switch (header.type()) { |
| 1462 | | macho.S_LITERAL_POINTERS, |
| 1463 | | macho.S_REGULAR, |
| 1464 | | macho.S_MOD_INIT_FUNC_POINTERS, |
| 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; |
| 1459 | const cpu_arch = self.options.target.cpu.arch; |
| 1460 | for (self.objects.items) |*object| { |
| 1461 | for (object.atoms.items) |atom_index| { |
| 1462 | const atom = self.getAtom(atom_index); |
| 1463 | const sym = self.getSymbol(atom.getSymbolWithLoc()); |
| 1464 | if (sym.n_desc == MachO.N_DEAD) continue; |
| 1473 | 1465 | |
| 1474 | | const cpu_arch = self.options.target.cpu.arch; |
| 1475 | | var atom_index = slice.items(.first_atom_index)[sect_id] orelse continue; |
| 1466 | const sect_id = sym.n_sect - 1; |
| 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) { |
| 1480 | | const atom = self.getAtom(atom_index); |
| 1481 | | const sym = self.getSymbol(atom.getSymbolWithLoc()); |
| 1486 | const code = Atom.getAtomCode(self, atom_index); |
| 1487 | const relocs = Atom.getAtomRelocs(self, atom_index); |
| 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: { |
| 1486 | | if (atom_index == self.dyld_private_atom_index.?) break :blk false; |
| 1487 | | break :blk true; |
| 1488 | | }; |
| 1505 | const global = Atom.parseRelocTarget(self, .{ |
| 1506 | .object_id = atom.getFile().?, |
| 1507 | .rel = rel, |
| 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) { |
| 1491 | | const code = Atom.getAtomCode(self, atom_index); |
| 1492 | | const relocs = Atom.getAtomRelocs(self, atom_index); |
| 1493 | | const ctx = Atom.getRelocContext(self, atom_index); |
| 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 | | } |
| 1516 | const base_offset = sym.n_value - segment.vmaddr; |
| 1517 | const rel_offset = @as(u32, @intCast(rel.r_address - ctx.base_offset)); |
| 1518 | const offset = @as(u64, @intCast(base_offset + rel_offset)); |
| 1519 | const addend = mem.readIntLittle(i64, code[rel_offset..][0..8]); |
| 1509 | 1520 | |
| 1510 | | const global = Atom.parseRelocTarget(self, .{ |
| 1511 | | .object_id = atom.getFile().?, |
| 1512 | | .rel = rel, |
| 1513 | | .code = code, |
| 1514 | | .base_offset = ctx.base_offset, |
| 1515 | | .base_addr = ctx.base_addr, |
| 1516 | | }); |
| 1517 | | const bind_sym_name = self.getSymbolName(global); |
| 1518 | | const bind_sym = self.getSymbol(global); |
| 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 | | }); |
| 1521 | const dylib_ordinal = @divTrunc(@as(i16, @bitCast(bind_sym.n_desc)), macho.N_SYMBOL_RESOLVER); |
| 1522 | log.debug(" | bind at {x}, import('{s}') in dylib({d})", .{ |
| 1523 | base_offset, |
| 1524 | bind_sym_name, |
| 1525 | dylib_ordinal, |
| 1526 | }); |
| 1527 | log.debug(" | with addend {x}", .{addend}); |
| 1528 | if (bind_sym.weakRef()) { |
| 1529 | log.debug(" | marking as weak ref ", .{}); |
| 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 | |