authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-08-25 07:09:07+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-08-29 11:39:34+02:00
log7c1135555652311fcd069e15e99ecd37e21360be
treeaec14057058f3871b5f08763633eab5b8ba087a4
parentbf5c35145da5cdaa9290d000728c0b8f307d89df

macho: collect rebase data by scanning atoms directly in objects


1 files changed, 56 insertions(+), 70 deletions(-)

src/link/MachO/zld.zig+56-70
......@@ -1368,85 +1368,71 @@ pub const Zld = struct {
13681368 }
13691369
13701370 // 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| {
13921374 const atom = self.getAtom(atom_index);
13931375 const sym = self.getSymbol(atom.getSymbolWithLoc());
1376 if (sym.n_desc == MachO.N_DEAD) continue;
13941377
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 }
13991391
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 });
14061397
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);
14101401
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;
14341425
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});
14391430
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 });
14451435 }
1446
1447 if (atom.next_index) |next_index| {
1448 atom_index = next_index;
1449 } else break;
14501436 }
14511437 }
14521438