| ... | ... | @@ -1368,85 +1368,71 @@ pub const Zld = struct { |
| 1368 | 1368 | } |
| 1369 | 1369 | |
| 1370 | 1370 | // Finally, unpack the rest. |
| 1371 | | const slice = self.sections.slice(); |
| 1372 | | for (slice.items(.header), 0..) |header, sect_id| { |
| 1373 | | switch (header.type()) { |
| 1374 | | macho.S_LITERAL_POINTERS, |
| 1375 | | macho.S_REGULAR, |
| 1376 | | macho.S_MOD_INIT_FUNC_POINTERS, |
| 1377 | | macho.S_MOD_TERM_FUNC_POINTERS, |
| 1378 | | => {}, |
| 1379 | | else => continue, |
| 1380 | | } |
| 1381 | | |
| 1382 | | const segment_index = slice.items(.segment_index)[sect_id]; |
| 1383 | | const segment = self.getSegment(@as(u8, @intCast(sect_id))); |
| 1384 | | if (segment.maxprot & macho.PROT.WRITE == 0) continue; |
| 1385 | | |
| 1386 | | log.debug("{s},{s}", .{ header.segName(), header.sectName() }); |
| 1387 | | |
| 1388 | | const cpu_arch = self.options.target.cpu.arch; |
| 1389 | | var atom_index = slice.items(.first_atom_index)[sect_id] orelse continue; |
| 1390 | | |
| 1391 | | while (true) { |
| 1371 | const cpu_arch = self.options.target.cpu.arch; |
| 1372 | for (self.objects.items) |*object| { |
| 1373 | for (object.atoms.items) |atom_index| { |
| 1392 | 1374 | const atom = self.getAtom(atom_index); |
| 1393 | 1375 | const sym = self.getSymbol(atom.getSymbolWithLoc()); |
| 1376 | if (sym.n_desc == MachO.N_DEAD) continue; |
| 1394 | 1377 | |
| 1395 | | const should_rebase = blk: { |
| 1396 | | if (atom_index == self.dyld_private_atom_index.?) break :blk false; |
| 1397 | | break :blk !sym.undf(); |
| 1398 | | }; |
| 1378 | const sect_id = sym.n_sect - 1; |
| 1379 | const section = self.sections.items(.header)[sect_id]; |
| 1380 | const segment_id = self.sections.items(.segment_index)[sect_id]; |
| 1381 | const segment = self.segments.items[segment_id]; |
| 1382 | if (segment.maxprot & macho.PROT.WRITE == 0) continue; |
| 1383 | switch (section.type()) { |
| 1384 | macho.S_LITERAL_POINTERS, |
| 1385 | macho.S_REGULAR, |
| 1386 | macho.S_MOD_INIT_FUNC_POINTERS, |
| 1387 | macho.S_MOD_TERM_FUNC_POINTERS, |
| 1388 | => {}, |
| 1389 | else => continue, |
| 1390 | } |
| 1399 | 1391 | |
| 1400 | | if (should_rebase) { |
| 1401 | | log.debug(" ATOM({d}, %{d}, '{s}')", .{ |
| 1402 | | atom_index, |
| 1403 | | atom.sym_index, |
| 1404 | | self.getSymbolName(atom.getSymbolWithLoc()), |
| 1405 | | }); |
| 1392 | log.debug(" ATOM({d}, %{d}, '{s}')", .{ |
| 1393 | atom_index, |
| 1394 | atom.sym_index, |
| 1395 | self.getSymbolName(atom.getSymbolWithLoc()), |
| 1396 | }); |
| 1406 | 1397 | |
| 1407 | | const code = Atom.getAtomCode(self, atom_index); |
| 1408 | | const relocs = Atom.getAtomRelocs(self, atom_index); |
| 1409 | | const ctx = Atom.getRelocContext(self, atom_index); |
| 1398 | const code = Atom.getAtomCode(self, atom_index); |
| 1399 | const relocs = Atom.getAtomRelocs(self, atom_index); |
| 1400 | const ctx = Atom.getRelocContext(self, atom_index); |
| 1410 | 1401 | |
| 1411 | | for (relocs) |rel| { |
| 1412 | | switch (cpu_arch) { |
| 1413 | | .aarch64 => { |
| 1414 | | const rel_type = @as(macho.reloc_type_arm64, @enumFromInt(rel.r_type)); |
| 1415 | | if (rel_type != .ARM64_RELOC_UNSIGNED) continue; |
| 1416 | | if (rel.r_length != 3) continue; |
| 1417 | | }, |
| 1418 | | .x86_64 => { |
| 1419 | | const rel_type = @as(macho.reloc_type_x86_64, @enumFromInt(rel.r_type)); |
| 1420 | | if (rel_type != .X86_64_RELOC_UNSIGNED) continue; |
| 1421 | | if (rel.r_length != 3) continue; |
| 1422 | | }, |
| 1423 | | else => unreachable, |
| 1424 | | } |
| 1425 | | const target = Atom.parseRelocTarget(self, .{ |
| 1426 | | .object_id = atom.getFile().?, |
| 1427 | | .rel = rel, |
| 1428 | | .code = code, |
| 1429 | | .base_offset = ctx.base_offset, |
| 1430 | | .base_addr = ctx.base_addr, |
| 1431 | | }); |
| 1432 | | const target_sym = self.getSymbol(target); |
| 1433 | | if (target_sym.undf()) continue; |
| 1402 | for (relocs) |rel| { |
| 1403 | switch (cpu_arch) { |
| 1404 | .aarch64 => { |
| 1405 | const rel_type = @as(macho.reloc_type_arm64, @enumFromInt(rel.r_type)); |
| 1406 | if (rel_type != .ARM64_RELOC_UNSIGNED) continue; |
| 1407 | if (rel.r_length != 3) continue; |
| 1408 | }, |
| 1409 | .x86_64 => { |
| 1410 | const rel_type = @as(macho.reloc_type_x86_64, @enumFromInt(rel.r_type)); |
| 1411 | if (rel_type != .X86_64_RELOC_UNSIGNED) continue; |
| 1412 | if (rel.r_length != 3) continue; |
| 1413 | }, |
| 1414 | else => unreachable, |
| 1415 | } |
| 1416 | const target = Atom.parseRelocTarget(self, .{ |
| 1417 | .object_id = atom.getFile().?, |
| 1418 | .rel = rel, |
| 1419 | .code = code, |
| 1420 | .base_offset = ctx.base_offset, |
| 1421 | .base_addr = ctx.base_addr, |
| 1422 | }); |
| 1423 | const target_sym = self.getSymbol(target); |
| 1424 | if (target_sym.undf()) continue; |
| 1434 | 1425 | |
| 1435 | | const base_offset = @as(i32, @intCast(sym.n_value - segment.vmaddr)); |
| 1436 | | const rel_offset = rel.r_address - ctx.base_offset; |
| 1437 | | const offset = @as(u64, @intCast(base_offset + rel_offset)); |
| 1438 | | log.debug(" | rebase at {x}", .{offset}); |
| 1426 | const base_offset = @as(i32, @intCast(sym.n_value - segment.vmaddr)); |
| 1427 | const rel_offset = rel.r_address - ctx.base_offset; |
| 1428 | const offset = @as(u64, @intCast(base_offset + rel_offset)); |
| 1429 | log.debug(" | rebase at {x}", .{offset}); |
| 1439 | 1430 | |
| 1440 | | try rebase.entries.append(self.gpa, .{ |
| 1441 | | .offset = offset, |
| 1442 | | .segment_id = segment_index, |
| 1443 | | }); |
| 1444 | | } |
| 1431 | try rebase.entries.append(self.gpa, .{ |
| 1432 | .offset = offset, |
| 1433 | .segment_id = segment_id, |
| 1434 | }); |
| 1445 | 1435 | } |
| 1446 | | |
| 1447 | | if (atom.next_index) |next_index| { |
| 1448 | | atom_index = next_index; |
| 1449 | | } else break; |
| 1450 | 1436 | } |
| 1451 | 1437 | } |
| 1452 | 1438 | |