link: make MachO atoms fully owned by the linker

This commit is contained in:
Jakub Konka 2023-01-30 18:22:50 +01:00
parent 23b7d28896
commit d42a931051
12 changed files with 495 additions and 432 deletions

View file

@ -4098,7 +4098,7 @@ pub fn ensureDeclAnalyzed(mod: *Module, decl_index: Decl.Index) SemaError!void {
// The exports this Decl performs will be re-discovered, so we remove them here
// prior to re-analysis.
mod.deleteDeclExports(decl_index);
try mod.deleteDeclExports(decl_index);
// Similarly, `@setAlignStack` invocations will be re-discovered.
if (decl.getFunction()) |func| {
@ -5265,7 +5265,7 @@ pub fn clearDecl(
assert(emit_h.decl_table.swapRemove(decl_index));
}
_ = mod.compile_log_decls.swapRemove(decl_index);
mod.deleteDeclExports(decl_index);
try mod.deleteDeclExports(decl_index);
if (decl.has_tv) {
if (decl.ty.isFnOrHasRuntimeBits()) {
@ -5276,7 +5276,7 @@ pub fn clearDecl(
decl.link = switch (mod.comp.bin_file.tag) {
.coff => .{ .coff = link.File.Coff.Atom.empty },
.elf => .{ .elf = link.File.Elf.TextBlock.empty },
.macho => .{ .macho = link.File.MachO.Atom.empty },
.macho => .{ .macho = {} },
.plan9 => .{ .plan9 = link.File.Plan9.DeclBlock.empty },
.c => .{ .c = {} },
.wasm => .{ .wasm = link.File.Wasm.DeclBlock.empty },
@ -5358,7 +5358,7 @@ pub fn abortAnonDecl(mod: *Module, decl_index: Decl.Index) void {
/// Delete all the Export objects that are caused by this Decl. Re-analysis of
/// this Decl will cause them to be re-created (or not).
fn deleteDeclExports(mod: *Module, decl_index: Decl.Index) void {
fn deleteDeclExports(mod: *Module, decl_index: Decl.Index) Allocator.Error!void {
var export_owners = (mod.export_owners.fetchSwapRemove(decl_index) orelse return).value;
for (export_owners.items) |exp| {
@ -5384,7 +5384,7 @@ fn deleteDeclExports(mod: *Module, decl_index: Decl.Index) void {
elf.deleteExport(exp.link.elf);
}
if (mod.comp.bin_file.cast(link.File.MachO)) |macho| {
macho.deleteExport(exp.link.macho);
try macho.deleteDeclExport(decl_index, exp.options.name);
}
if (mod.comp.bin_file.cast(link.File.Wasm)) |wasm| {
wasm.deleteExport(exp.link.wasm);
@ -5696,7 +5696,7 @@ pub fn allocateNewDecl(
.link = switch (mod.comp.bin_file.tag) {
.coff => .{ .coff = link.File.Coff.Atom.empty },
.elf => .{ .elf = link.File.Elf.TextBlock.empty },
.macho => .{ .macho = link.File.MachO.Atom.empty },
.macho => .{ .macho = {} },
.plan9 => .{ .plan9 = link.File.Plan9.DeclBlock.empty },
.c => .{ .c = {} },
.wasm => .{ .wasm = link.File.Wasm.DeclBlock.empty },

View file

@ -5567,7 +5567,7 @@ pub fn analyzeExport(
.link = switch (mod.comp.bin_file.tag) {
.coff => .{ .coff = .{} },
.elf => .{ .elf = .{} },
.macho => .{ .macho = .{} },
.macho => .{ .macho = {} },
.plan9 => .{ .plan9 = null },
.c => .{ .c = {} },
.wasm => .{ .wasm = .{} },

View file

@ -4022,7 +4022,11 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
const mod = self.bin_file.options.module.?;
const owner_decl = mod.declPtr(self.mod_fn.owner_decl);
const atom_index = switch (self.bin_file.tag) {
.macho => owner_decl.link.macho.getSymbolIndex().?,
.macho => blk: {
const macho_file = self.bin_file.cast(link.File.MachO).?;
const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
break :blk macho_file.getAtom(atom).getSymbolIndex().?;
},
.coff => owner_decl.link.coff.getSymbolIndex().?,
else => unreachable, // unsupported target format
};
@ -4308,11 +4312,12 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
const got_addr = @intCast(u32, fn_owner_decl.link.elf.getOffsetTableAddress(elf_file));
try self.genSetReg(Type.initTag(.usize), .x30, .{ .memory = got_addr });
} else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
try fn_owner_decl.link.macho.ensureInitialized(macho_file);
const atom = try macho_file.getOrCreateAtomForDecl(func.owner_decl);
const sym_index = macho_file.getAtom(atom).getSymbolIndex().?;
try self.genSetReg(Type.initTag(.u64), .x30, .{
.linker_load = .{
.type = .got,
.sym_index = fn_owner_decl.link.macho.getSymbolIndex().?,
.sym_index = sym_index,
},
});
} else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
@ -4349,11 +4354,13 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
if (self.bin_file.cast(link.File.MachO)) |macho_file| {
const sym_index = try macho_file.getGlobalSymbol(mem.sliceTo(decl_name, 0));
const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
const atom_index = macho_file.getAtom(atom).getSymbolIndex().?;
_ = try self.addInst(.{
.tag = .call_extern,
.data = .{
.relocation = .{
.atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.getSymbolIndex().?,
.atom_index = atom_index,
.sym_index = sym_index,
},
},
@ -5491,7 +5498,11 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
const mod = self.bin_file.options.module.?;
const owner_decl = mod.declPtr(self.mod_fn.owner_decl);
const atom_index = switch (self.bin_file.tag) {
.macho => owner_decl.link.macho.getSymbolIndex().?,
.macho => blk: {
const macho_file = self.bin_file.cast(link.File.MachO).?;
const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
break :blk macho_file.getAtom(atom).getSymbolIndex().?;
},
.coff => owner_decl.link.coff.getSymbolIndex().?,
else => unreachable, // unsupported target format
};
@ -5605,7 +5616,11 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
const mod = self.bin_file.options.module.?;
const owner_decl = mod.declPtr(self.mod_fn.owner_decl);
const atom_index = switch (self.bin_file.tag) {
.macho => owner_decl.link.macho.getSymbolIndex().?,
.macho => blk: {
const macho_file = self.bin_file.cast(link.File.MachO).?;
const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
break :blk macho_file.getAtom(atom).getSymbolIndex().?;
},
.coff => owner_decl.link.coff.getSymbolIndex().?,
else => unreachable, // unsupported target format
};
@ -5799,7 +5814,11 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
const mod = self.bin_file.options.module.?;
const owner_decl = mod.declPtr(self.mod_fn.owner_decl);
const atom_index = switch (self.bin_file.tag) {
.macho => owner_decl.link.macho.getSymbolIndex().?,
.macho => blk: {
const macho_file = self.bin_file.cast(link.File.MachO).?;
const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
break :blk macho_file.getAtom(atom).getSymbolIndex().?;
},
.coff => owner_decl.link.coff.getSymbolIndex().?,
else => unreachable, // unsupported target format
};
@ -6122,10 +6141,11 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne
try decl.link.elf.ensureInitialized(elf_file);
return MCValue{ .memory = decl.link.elf.getOffsetTableAddress(elf_file) };
} else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
try decl.link.macho.ensureInitialized(macho_file);
const atom = try macho_file.getOrCreateAtomForDecl(decl_index);
const sym_index = macho_file.getAtom(atom).getSymbolIndex().?;
return MCValue{ .linker_load = .{
.type = .got,
.sym_index = decl.link.macho.getSymbolIndex().?,
.sym_index = sym_index,
} };
} else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
try decl.link.coff.ensureInitialized(coff_file);

View file

@ -670,9 +670,9 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {
if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
// Add relocation to the decl.
const atom = macho_file.getAtomForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;
const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;
const target = macho_file.getGlobalByIndex(relocation.sym_index);
try atom.addRelocation(macho_file, .{
try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
.type = @enumToInt(std.macho.reloc_type_arm64.ARM64_RELOC_BRANCH26),
.target = target,
.offset = offset,
@ -883,10 +883,10 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
}
if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
const atom = macho_file.getAtomForSymbol(.{ .sym_index = data.atom_index, .file = null }).?;
const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = data.atom_index, .file = null }).?;
// TODO this causes segfault in stage1
// try atom.addRelocations(macho_file, 2, .{
try atom.addRelocation(macho_file, .{
try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
.target = .{ .sym_index = data.sym_index, .file = null },
.offset = offset,
.addend = 0,
@ -902,7 +902,7 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
else => unreachable,
},
});
try atom.addRelocation(macho_file, .{
try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
.target = .{ .sym_index = data.sym_index, .file = null },
.offset = offset + 4,
.addend = 0,

View file

@ -2556,9 +2556,7 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne
try decl.link.elf.ensureInitialized(elf_file);
return MCValue{ .memory = decl.link.elf.getOffsetTableAddress(elf_file) };
} else if (self.bin_file.cast(link.File.MachO)) |_| {
// TODO I'm hacking my way through here by repurposing .memory for storing
// index to the GOT target symbol index.
return MCValue{ .memory = decl.link.macho.sym_index };
unreachable;
} else if (self.bin_file.cast(link.File.Coff)) |_| {
return self.fail("TODO codegen COFF const Decl pointer", .{});
} else if (self.bin_file.cast(link.File.Plan9)) |p9| {

View file

@ -2670,10 +2670,12 @@ fn loadMemPtrIntoRegister(self: *Self, reg: Register, ptr_ty: Type, ptr: MCValue
const abi_size = @intCast(u32, ptr_ty.abiSize(self.target.*));
const mod = self.bin_file.options.module.?;
const fn_owner_decl = mod.declPtr(self.mod_fn.owner_decl);
const atom_index = if (self.bin_file.tag == link.File.MachO.base_tag)
fn_owner_decl.link.macho.getSymbolIndex().?
else
fn_owner_decl.link.coff.getSymbolIndex().?;
const atom_index = if (self.bin_file.cast(link.File.MachO)) |macho_file| blk: {
const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
break :blk macho_file.getAtom(atom).getSymbolIndex().?;
} else if (self.bin_file.cast(link.File.Coff)) |_| blk: {
break :blk fn_owner_decl.link.coff.getSymbolIndex().?;
} else unreachable;
const flags: u2 = switch (load_struct.type) {
.got => 0b00,
.direct => 0b01,
@ -4023,8 +4025,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
.data = undefined,
});
} else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
try fn_owner_decl.link.macho.ensureInitialized(macho_file);
const sym_index = fn_owner_decl.link.macho.getSymbolIndex().?;
const atom_index = try macho_file.getOrCreateAtomForDecl(func.owner_decl);
const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
try self.genSetReg(Type.initTag(.usize), .rax, .{
.linker_load = .{
.type = .got,
@ -4080,15 +4082,15 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
});
} else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
const sym_index = try macho_file.getGlobalSymbol(mem.sliceTo(decl_name, 0));
const atom = try macho_file.getOrCreateAtomForDecl(self.mod_fn.owner_decl);
const atom_index = macho_file.getAtom(atom).getSymbolIndex().?;
_ = try self.addInst(.{
.tag = .call_extern,
.ops = undefined,
.data = .{
.relocation = .{
.atom_index = mod.declPtr(self.mod_fn.owner_decl).link.macho.getSymbolIndex().?,
.sym_index = sym_index,
},
},
.data = .{ .relocation = .{
.atom_index = atom_index,
.sym_index = sym_index,
} },
});
} else {
return self.fail("TODO implement calling extern functions", .{});
@ -6722,10 +6724,11 @@ fn lowerDeclRef(self: *Self, tv: TypedValue, decl_index: Module.Decl.Index) Inne
try decl.link.elf.ensureInitialized(elf_file);
return MCValue{ .memory = decl.link.elf.getOffsetTableAddress(elf_file) };
} else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
try decl.link.macho.ensureInitialized(macho_file);
const atom_index = try macho_file.getOrCreateAtomForDecl(decl_index);
const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
return MCValue{ .linker_load = .{
.type = .got,
.sym_index = decl.link.macho.getSymbolIndex().?,
.sym_index = sym_index,
} };
} else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
try decl.link.coff.ensureInitialized(coff_file);

View file

@ -1001,8 +1001,8 @@ fn mirLeaPic(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
0b01 => @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_SIGNED),
else => unreachable,
};
const atom = macho_file.getAtomForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;
try atom.addRelocation(macho_file, .{
const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;
try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
.type = reloc_type,
.target = .{ .sym_index = relocation.sym_index, .file = null },
.offset = @intCast(u32, end_offset - 4),
@ -1140,9 +1140,9 @@ fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
// Add relocation to the decl.
const atom = macho_file.getAtomForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;
const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = relocation.atom_index, .file = null }).?;
const target = macho_file.getGlobalByIndex(relocation.sym_index);
try atom.addRelocation(macho_file, .{
try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
.type = @enumToInt(std.macho.reloc_type_x86_64.X86_64_RELOC_BRANCH),
.target = target,
.offset = offset,

View file

@ -264,7 +264,7 @@ pub const File = struct {
pub const LinkBlock = union {
elf: Elf.TextBlock,
coff: Coff.Atom,
macho: MachO.Atom,
macho: void,
plan9: Plan9.DeclBlock,
c: void,
wasm: Wasm.DeclBlock,
@ -286,7 +286,7 @@ pub const File = struct {
pub const Export = union {
elf: Elf.Export,
coff: Coff.Export,
macho: MachO.Export,
macho: void,
plan9: Plan9.Export,
c: void,
wasm: Wasm.Export,

View file

@ -2639,7 +2639,7 @@ fn getDbgInfoAtom(tag: File.Tag, mod: *Module, decl_index: Module.Decl.Index) *A
const decl = mod.declPtr(decl_index);
return switch (tag) {
.elf => &decl.link.elf.dbg_info_atom,
.macho => &decl.link.macho.dbg_info_atom,
.macho => unreachable,
.wasm => &decl.link.wasm.dbg_info_atom,
else => unreachable,
};

File diff suppressed because it is too large Load diff

View file

@ -39,11 +39,14 @@ size: u64,
alignment: u32,
/// Points to the previous and next neighbours
next: ?*Atom,
prev: ?*Atom,
/// TODO use the same trick as with symbols: reserve index 0 as null atom
next_index: ?Atom.Index,
prev_index: ?Atom.Index,
dbg_info_atom: Dwarf.Atom,
pub const Index = u32;
pub const Binding = struct {
target: SymbolWithLoc,
offset: u64,
@ -54,22 +57,6 @@ pub const SymbolAtOffset = struct {
offset: u64,
};
pub const empty = Atom{
.sym_index = 0,
.file = null,
.size = 0,
.alignment = 0,
.prev = null,
.next = null,
.dbg_info_atom = undefined,
};
pub fn ensureInitialized(self: *Atom, macho_file: *MachO) !void {
if (self.getSymbolIndex() != null) return; // Already initialized
self.sym_index = try macho_file.allocateSymbol();
try macho_file.atom_by_index_table.putNoClobber(macho_file.base.allocator, self.sym_index, self);
}
pub fn getSymbolIndex(self: Atom) ?u32 {
if (self.sym_index == 0) return null;
return self.sym_index;
@ -108,7 +95,8 @@ pub fn getName(self: Atom, macho_file: *MachO) []const u8 {
/// this calculation.
pub fn capacity(self: Atom, macho_file: *MachO) u64 {
const self_sym = self.getSymbol(macho_file);
if (self.next) |next| {
if (self.next_index) |next_index| {
const next = macho_file.getAtom(next_index);
const next_sym = next.getSymbol(macho_file);
return next_sym.n_value - self_sym.n_value;
} else {
@ -120,7 +108,8 @@ pub fn capacity(self: Atom, macho_file: *MachO) u64 {
pub fn freeListEligible(self: Atom, macho_file: *MachO) bool {
// No need to keep a free list node for the last atom.
const next = self.next orelse return false;
const next_index = self.next_index orelse return false;
const next = macho_file.getAtom(next_index);
const self_sym = self.getSymbol(macho_file);
const next_sym = next.getSymbol(macho_file);
const cap = next_sym.n_value - self_sym.n_value;
@ -130,19 +119,19 @@ pub fn freeListEligible(self: Atom, macho_file: *MachO) bool {
return surplus >= MachO.min_text_capacity;
}
pub fn addRelocation(self: *Atom, macho_file: *MachO, reloc: Relocation) !void {
return self.addRelocations(macho_file, 1, .{reloc});
pub fn addRelocation(macho_file: *MachO, atom_index: Atom.Index, reloc: Relocation) !void {
return addRelocations(macho_file, atom_index, 1, .{reloc});
}
pub fn addRelocations(
self: *Atom,
macho_file: *MachO,
atom_index: Atom.Index,
comptime count: comptime_int,
relocs: [count]Relocation,
) !void {
const gpa = macho_file.base.allocator;
const target = macho_file.base.options.target;
const gop = try macho_file.relocs.getOrPut(gpa, self);
const gop = try macho_file.relocs.getOrPut(gpa, atom_index);
if (!gop.found_existing) {
gop.value_ptr.* = .{};
}
@ -156,56 +145,72 @@ pub fn addRelocations(
}
}
pub fn addRebase(self: *Atom, macho_file: *MachO, offset: u32) !void {
pub fn addRebase(macho_file: *MachO, atom_index: Atom.Index, offset: u32) !void {
const gpa = macho_file.base.allocator;
log.debug(" (adding rebase at offset 0x{x} in %{?d})", .{ offset, self.getSymbolIndex() });
const gop = try macho_file.rebases.getOrPut(gpa, self);
const atom = macho_file.getAtom(atom_index);
log.debug(" (adding rebase at offset 0x{x} in %{?d})", .{ offset, atom.getSymbolIndex() });
const gop = try macho_file.rebases.getOrPut(gpa, atom_index);
if (!gop.found_existing) {
gop.value_ptr.* = .{};
}
try gop.value_ptr.append(gpa, offset);
}
pub fn addBinding(self: *Atom, macho_file: *MachO, binding: Binding) !void {
pub fn addBinding(macho_file: *MachO, atom_index: Atom.Index, binding: Binding) !void {
const gpa = macho_file.base.allocator;
const atom = macho_file.getAtom(atom_index);
log.debug(" (adding binding to symbol {s} at offset 0x{x} in %{?d})", .{
macho_file.getSymbolName(binding.target),
binding.offset,
self.getSymbolIndex(),
atom.getSymbolIndex(),
});
const gop = try macho_file.bindings.getOrPut(gpa, self);
const gop = try macho_file.bindings.getOrPut(gpa, atom_index);
if (!gop.found_existing) {
gop.value_ptr.* = .{};
}
try gop.value_ptr.append(gpa, binding);
}
pub fn addLazyBinding(self: *Atom, macho_file: *MachO, binding: Binding) !void {
pub fn addLazyBinding(macho_file: *MachO, atom_index: Atom.Index, binding: Binding) !void {
const gpa = macho_file.base.allocator;
const atom = macho_file.getAtom(atom_index);
log.debug(" (adding lazy binding to symbol {s} at offset 0x{x} in %{?d})", .{
macho_file.getSymbolName(binding.target),
binding.offset,
self.getSymbolIndex(),
atom.getSymbolIndex(),
});
const gop = try macho_file.lazy_bindings.getOrPut(gpa, self);
const gop = try macho_file.lazy_bindings.getOrPut(gpa, atom_index);
if (!gop.found_existing) {
gop.value_ptr.* = .{};
}
try gop.value_ptr.append(gpa, binding);
}
pub fn resolveRelocations(self: *Atom, macho_file: *MachO) !void {
const relocs = macho_file.relocs.get(self) orelse return;
const source_sym = self.getSymbol(macho_file);
pub fn resolveRelocations(macho_file: *MachO, atom_index: Atom.Index) !void {
const atom = macho_file.getAtom(atom_index);
const relocs = macho_file.relocs.get(atom_index) orelse return;
const source_sym = atom.getSymbol(macho_file);
const source_section = macho_file.sections.get(source_sym.n_sect - 1).header;
const file_offset = source_section.offset + source_sym.n_value - source_section.addr;
log.debug("relocating '{s}'", .{self.getName(macho_file)});
log.debug("relocating '{s}'", .{atom.getName(macho_file)});
for (relocs.items) |*reloc| {
if (!reloc.dirty) continue;
try reloc.resolve(self, macho_file, file_offset);
try reloc.resolve(macho_file, atom_index, file_offset);
reloc.dirty = false;
}
}
pub fn freeRelocations(macho_file: *MachO, atom_index: Atom.Index) void {
const gpa = macho_file.base.allocator;
var removed_relocs = macho_file.relocs.fetchOrderedRemove(atom_index);
if (removed_relocs) |*relocs| relocs.value.deinit(gpa);
var removed_rebases = macho_file.rebases.fetchOrderedRemove(atom_index);
if (removed_rebases) |*rebases| rebases.value.deinit(gpa);
var removed_bindings = macho_file.bindings.fetchOrderedRemove(atom_index);
if (removed_bindings) |*bindings| bindings.value.deinit(gpa);
var removed_lazy_bindings = macho_file.lazy_bindings.fetchOrderedRemove(atom_index);
if (removed_lazy_bindings) |*lazy_bindings| lazy_bindings.value.deinit(gpa);
}

View file

@ -29,33 +29,35 @@ pub fn fmtType(self: Relocation, target: std.Target) []const u8 {
}
}
pub fn getTargetAtom(self: Relocation, macho_file: *MachO) ?*Atom {
pub fn getTargetAtomIndex(self: Relocation, macho_file: *MachO) ?Atom.Index {
switch (macho_file.base.options.target.cpu.arch) {
.aarch64 => switch (@intToEnum(macho.reloc_type_arm64, self.type)) {
.ARM64_RELOC_GOT_LOAD_PAGE21,
.ARM64_RELOC_GOT_LOAD_PAGEOFF12,
.ARM64_RELOC_POINTER_TO_GOT,
=> return macho_file.getGotAtomForSymbol(self.target),
=> return macho_file.getGotAtomIndexForSymbol(self.target),
else => {},
},
.x86_64 => switch (@intToEnum(macho.reloc_type_x86_64, self.type)) {
.X86_64_RELOC_GOT,
.X86_64_RELOC_GOT_LOAD,
=> return macho_file.getGotAtomForSymbol(self.target),
=> return macho_file.getGotAtomIndexForSymbol(self.target),
else => {},
},
else => unreachable,
}
if (macho_file.getStubsAtomForSymbol(self.target)) |stubs_atom| return stubs_atom;
return macho_file.getAtomForSymbol(self.target);
if (macho_file.getStubsAtomIndexForSymbol(self.target)) |stubs_atom| return stubs_atom;
return macho_file.getAtomIndexForSymbol(self.target);
}
pub fn resolve(self: Relocation, atom: *Atom, macho_file: *MachO, base_offset: u64) !void {
pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, base_offset: u64) !void {
const arch = macho_file.base.options.target.cpu.arch;
const atom = macho_file.getAtom(atom_index);
const source_sym = atom.getSymbol(macho_file);
const source_addr = source_sym.n_value + self.offset;
const target_atom = self.getTargetAtom(macho_file) orelse return;
const target_atom_index = self.getTargetAtomIndex(macho_file) orelse return;
const target_atom = macho_file.getAtom(target_atom_index);
const target_addr = @intCast(i64, target_atom.getSymbol(macho_file).n_value) + self.addend;
log.debug(" ({x}: [() => 0x{x} ({s})) ({s})", .{