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