mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
macho: refactor common logic between synthetic tables
This commit is contained in:
parent
38ecaf3ab6
commit
ef645ab175
3 changed files with 147 additions and 161 deletions
|
|
@ -5,7 +5,6 @@ const build_options = @import("build_options");
|
||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const assert = std.debug.assert;
|
const assert = std.debug.assert;
|
||||||
const dwarf = std.dwarf;
|
const dwarf = std.dwarf;
|
||||||
const fmt = std.fmt;
|
|
||||||
const fs = std.fs;
|
const fs = std.fs;
|
||||||
const log = std.log.scoped(.link);
|
const log = std.log.scoped(.link);
|
||||||
const macho = std.macho;
|
const macho = std.macho;
|
||||||
|
|
@ -155,13 +154,9 @@ stub_helper_preamble_atom_index: ?Atom.Index = null,
|
||||||
|
|
||||||
strtab: StringTable(.strtab) = .{},
|
strtab: StringTable(.strtab) = .{},
|
||||||
|
|
||||||
got_entries: std.ArrayListUnmanaged(Entry) = .{},
|
got_table: SectionTable = .{},
|
||||||
got_entries_free_list: std.ArrayListUnmanaged(u32) = .{},
|
stubs_table: SectionTable = .{},
|
||||||
got_entries_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{},
|
tlvp_table: SectionTable = .{},
|
||||||
|
|
||||||
stubs: std.ArrayListUnmanaged(Entry) = .{},
|
|
||||||
stubs_free_list: std.ArrayListUnmanaged(u32) = .{},
|
|
||||||
stubs_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{},
|
|
||||||
|
|
||||||
error_flags: File.ErrorFlags = File.ErrorFlags{},
|
error_flags: File.ErrorFlags = File.ErrorFlags{},
|
||||||
|
|
||||||
|
|
@ -270,26 +265,120 @@ const DeclMetadata = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const Entry = struct {
|
const SectionTable = struct {
|
||||||
target: SymbolWithLoc,
|
entries: std.ArrayListUnmanaged(Entry) = .{},
|
||||||
// Index into the synthetic symbol table (i.e., file == null).
|
free_list: std.ArrayListUnmanaged(u32) = .{},
|
||||||
sym_index: u32,
|
lookup: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{},
|
||||||
|
|
||||||
pub fn getSymbol(entry: Entry, macho_file: *MachO) macho.nlist_64 {
|
pub fn deinit(st: *ST, allocator: Allocator) void {
|
||||||
return macho_file.getSymbol(.{ .sym_index = entry.sym_index, .file = null });
|
st.entries.deinit(allocator);
|
||||||
|
st.free_list.deinit(allocator);
|
||||||
|
st.lookup.deinit(allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getSymbolPtr(entry: Entry, macho_file: *MachO) *macho.nlist_64 {
|
pub fn allocateEntry(st: *ST, allocator: Allocator, target: SymbolWithLoc) !u32 {
|
||||||
return macho_file.getSymbolPtr(.{ .sym_index = entry.sym_index, .file = null });
|
try st.entries.ensureUnusedCapacity(allocator, 1);
|
||||||
|
const index = blk: {
|
||||||
|
if (st.free_list.popOrNull()) |index| {
|
||||||
|
log.debug(" (reusing entry index {d})", .{index});
|
||||||
|
break :blk index;
|
||||||
|
} else {
|
||||||
|
log.debug(" (allocating entry at index {d})", .{st.entries.items.len});
|
||||||
|
const index = @intCast(u32, st.entries.items.len);
|
||||||
|
_ = st.entries.addOneAssumeCapacity();
|
||||||
|
break :blk index;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
st.entries.items[index] = .{ .target = target, .sym_index = 0 };
|
||||||
|
try st.lookup.putNoClobber(allocator, target, index);
|
||||||
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getAtomIndex(entry: Entry, macho_file: *MachO) ?Atom.Index {
|
pub fn freeEntry(st: *ST, allocator: Allocator, target: SymbolWithLoc) void {
|
||||||
return macho_file.getAtomIndexForSymbol(.{ .sym_index = entry.sym_index, .file = null });
|
const index = st.lookup.get(target) orelse return;
|
||||||
|
st.free_list.append(allocator, index) catch {};
|
||||||
|
st.entries.items[index] = .{
|
||||||
|
.target = .{ .sym_index = 0 },
|
||||||
|
.sym_index = 0,
|
||||||
|
};
|
||||||
|
_ = st.lookup.remove(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getName(entry: Entry, macho_file: *MachO) []const u8 {
|
pub fn getAtomIndex(st: *const ST, macho_file: *MachO, target: SymbolWithLoc) ?Atom.Index {
|
||||||
return macho_file.getSymbolName(.{ .sym_index = entry.sym_index, .file = null });
|
const index = st.lookup.get(target) orelse return null;
|
||||||
|
return st.entries.items[index].getAtomIndex(macho_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const FormatContext = struct {
|
||||||
|
macho_file: *MachO,
|
||||||
|
st: *const ST,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn fmt(
|
||||||
|
ctx: FormatContext,
|
||||||
|
comptime unused_format_string: []const u8,
|
||||||
|
options: std.fmt.FormatOptions,
|
||||||
|
writer: anytype,
|
||||||
|
) @TypeOf(writer).Error!void {
|
||||||
|
_ = options;
|
||||||
|
comptime assert(unused_format_string.len == 0);
|
||||||
|
try writer.writeAll("SectionTable:\n");
|
||||||
|
for (ctx.st.entries.items, 0..) |entry, i| {
|
||||||
|
const atom_sym = entry.getSymbol(ctx.macho_file);
|
||||||
|
const target_sym = ctx.macho_file.getSymbol(entry.target);
|
||||||
|
try writer.print(" {d}@{x} => ", .{ i, atom_sym.n_value });
|
||||||
|
if (target_sym.undf()) {
|
||||||
|
try writer.print("import('{s}')", .{
|
||||||
|
ctx.macho_file.getSymbolName(entry.target),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
try writer.print("local(%{d}) in object({?d})", .{
|
||||||
|
entry.target.sym_index,
|
||||||
|
entry.target.file,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
try writer.writeByte('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format(st: *const ST, comptime unused_format_string: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
|
||||||
|
_ = st;
|
||||||
|
_ = unused_format_string;
|
||||||
|
_ = options;
|
||||||
|
_ = writer;
|
||||||
|
@compileError("do not format SectionTable directly; use st.fmtDebug()");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fmtDebug(st: *const ST, macho_file: *MachO) std.fmt.Formatter(fmt) {
|
||||||
|
return .{ .data = .{
|
||||||
|
.macho_file = macho_file,
|
||||||
|
.st = st,
|
||||||
|
} };
|
||||||
|
}
|
||||||
|
|
||||||
|
const ST = @This();
|
||||||
|
|
||||||
|
const Entry = struct {
|
||||||
|
target: SymbolWithLoc,
|
||||||
|
// Index into the synthetic symbol table (i.e., file == null).
|
||||||
|
sym_index: u32,
|
||||||
|
|
||||||
|
pub fn getSymbol(entry: Entry, macho_file: *MachO) macho.nlist_64 {
|
||||||
|
return macho_file.getSymbol(.{ .sym_index = entry.sym_index });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getSymbolPtr(entry: Entry, macho_file: *MachO) *macho.nlist_64 {
|
||||||
|
return macho_file.getSymbolPtr(.{ .sym_index = entry.sym_index });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getAtomIndex(entry: Entry, macho_file: *MachO) ?Atom.Index {
|
||||||
|
return macho_file.getAtomIndexForSymbol(.{ .sym_index = entry.sym_index });
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getName(entry: Entry, macho_file: *MachO) []const u8 {
|
||||||
|
return macho_file.getSymbolName(.{ .sym_index = entry.sym_index });
|
||||||
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const BindingTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Atom.Binding));
|
const BindingTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Atom.Binding));
|
||||||
|
|
@ -399,7 +488,7 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {
|
||||||
// Create dSYM bundle.
|
// Create dSYM bundle.
|
||||||
log.debug("creating {s}.dSYM bundle", .{sub_path});
|
log.debug("creating {s}.dSYM bundle", .{sub_path});
|
||||||
|
|
||||||
const d_sym_path = try fmt.allocPrint(
|
const d_sym_path = try std.fmt.allocPrint(
|
||||||
allocator,
|
allocator,
|
||||||
"{s}.dSYM" ++ fs.path.sep_str ++ "Contents" ++ fs.path.sep_str ++ "Resources" ++ fs.path.sep_str ++ "DWARF",
|
"{s}.dSYM" ++ fs.path.sep_str ++ "Contents" ++ fs.path.sep_str ++ "Resources" ++ fs.path.sep_str ++ "DWARF",
|
||||||
.{sub_path},
|
.{sub_path},
|
||||||
|
|
@ -613,9 +702,9 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
|
||||||
if (self.dyld_stub_binder_index == null) {
|
if (self.dyld_stub_binder_index == null) {
|
||||||
self.dyld_stub_binder_index = try self.addUndefined("dyld_stub_binder", .add_got);
|
self.dyld_stub_binder_index = try self.addUndefined("dyld_stub_binder", .add_got);
|
||||||
}
|
}
|
||||||
if (!self.base.options.single_threaded) {
|
// if (!self.base.options.single_threaded) {
|
||||||
_ = try self.addUndefined("_tlv_bootstrap", .none);
|
// _ = try self.addUndefined("_tlv_bootstrap", .none);
|
||||||
}
|
// }
|
||||||
|
|
||||||
try self.createMhExecuteHeaderSymbol();
|
try self.createMhExecuteHeaderSymbol();
|
||||||
|
|
||||||
|
|
@ -1757,12 +1846,9 @@ pub fn deinit(self: *MachO) void {
|
||||||
d_sym.deinit();
|
d_sym.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.got_entries.deinit(gpa);
|
self.got_table.deinit(gpa);
|
||||||
self.got_entries_free_list.deinit(gpa);
|
|
||||||
self.got_entries_table.deinit(gpa);
|
|
||||||
self.stubs.deinit(gpa);
|
|
||||||
self.stubs_free_list.deinit(gpa);
|
|
||||||
self.stubs_table.deinit(gpa);
|
self.stubs_table.deinit(gpa);
|
||||||
|
self.tlvp_table.deinit(gpa);
|
||||||
self.strtab.deinit(gpa);
|
self.strtab.deinit(gpa);
|
||||||
|
|
||||||
self.locals.deinit(gpa);
|
self.locals.deinit(gpa);
|
||||||
|
|
@ -1895,20 +1981,10 @@ fn freeAtom(self: *MachO, atom_index: Atom.Index) void {
|
||||||
self.locals_free_list.append(gpa, sym_index) catch {};
|
self.locals_free_list.append(gpa, sym_index) catch {};
|
||||||
|
|
||||||
// Try freeing GOT atom if this decl had one
|
// Try freeing GOT atom if this decl had one
|
||||||
const got_target = SymbolWithLoc{ .sym_index = sym_index, .file = null };
|
self.got_table.freeEntry(gpa, .{ .sym_index = sym_index });
|
||||||
if (self.got_entries_table.get(got_target)) |got_index| {
|
|
||||||
self.got_entries_free_list.append(gpa, @intCast(u32, got_index)) catch {};
|
|
||||||
self.got_entries.items[got_index] = .{
|
|
||||||
.target = .{ .sym_index = 0, .file = null },
|
|
||||||
.sym_index = 0,
|
|
||||||
};
|
|
||||||
_ = self.got_entries_table.remove(got_target);
|
|
||||||
|
|
||||||
if (self.d_sym) |*d_sym| {
|
if (self.d_sym) |*d_sym| {
|
||||||
d_sym.swapRemoveRelocs(sym_index);
|
d_sym.swapRemoveRelocs(sym_index);
|
||||||
}
|
|
||||||
|
|
||||||
log.debug(" adding GOT index {d} to free list (target local@{d})", .{ got_index, sym_index });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.locals.items[sym_index].n_type = 0;
|
self.locals.items[sym_index].n_type = 0;
|
||||||
|
|
@ -1983,70 +2059,25 @@ fn allocateGlobal(self: *MachO) !u32 {
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn allocateGotEntry(self: *MachO, target: SymbolWithLoc) !u32 {
|
|
||||||
const gpa = self.base.allocator;
|
|
||||||
try self.got_entries.ensureUnusedCapacity(gpa, 1);
|
|
||||||
|
|
||||||
const index = blk: {
|
|
||||||
if (self.got_entries_free_list.popOrNull()) |index| {
|
|
||||||
log.debug(" (reusing GOT entry index {d})", .{index});
|
|
||||||
break :blk index;
|
|
||||||
} else {
|
|
||||||
log.debug(" (allocating GOT entry at index {d})", .{self.got_entries.items.len});
|
|
||||||
const index = @intCast(u32, self.got_entries.items.len);
|
|
||||||
_ = self.got_entries.addOneAssumeCapacity();
|
|
||||||
break :blk index;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.got_entries.items[index] = .{ .target = target, .sym_index = 0 };
|
|
||||||
try self.got_entries_table.putNoClobber(gpa, target, index);
|
|
||||||
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn addGotEntry(self: *MachO, target: SymbolWithLoc) !void {
|
fn addGotEntry(self: *MachO, target: SymbolWithLoc) !void {
|
||||||
if (self.got_entries_table.contains(target)) return;
|
if (self.got_table.lookup.contains(target)) return;
|
||||||
|
const got_index = try self.got_table.allocateEntry(self.base.allocator, target);
|
||||||
const got_index = try self.allocateGotEntry(target);
|
|
||||||
const got_atom_index = try self.createGotAtom(target);
|
const got_atom_index = try self.createGotAtom(target);
|
||||||
const got_atom = self.getAtom(got_atom_index);
|
const got_atom = self.getAtom(got_atom_index);
|
||||||
self.got_entries.items[got_index].sym_index = got_atom.getSymbolIndex().?;
|
self.got_table.entries.items[got_index].sym_index = got_atom.getSymbolIndex().?;
|
||||||
try self.writePtrWidthAtom(got_atom_index);
|
try self.writePtrWidthAtom(got_atom_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn allocateStubEntry(self: *MachO, target: SymbolWithLoc) !u32 {
|
|
||||||
try self.stubs.ensureUnusedCapacity(self.base.allocator, 1);
|
|
||||||
|
|
||||||
const index = blk: {
|
|
||||||
if (self.stubs_free_list.popOrNull()) |index| {
|
|
||||||
log.debug(" (reusing stub entry index {d})", .{index});
|
|
||||||
break :blk index;
|
|
||||||
} else {
|
|
||||||
log.debug(" (allocating stub entry at index {d})", .{self.stubs.items.len});
|
|
||||||
const index = @intCast(u32, self.stubs.items.len);
|
|
||||||
_ = self.stubs.addOneAssumeCapacity();
|
|
||||||
break :blk index;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.stubs.items[index] = .{ .target = target, .sym_index = 0 };
|
|
||||||
try self.stubs_table.putNoClobber(self.base.allocator, target, index);
|
|
||||||
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void {
|
fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void {
|
||||||
if (self.stubs_table.contains(target)) return;
|
if (self.stubs_table.lookup.contains(target)) return;
|
||||||
|
const stub_index = try self.stubs_table.allocateEntry(self.base.allocator, target);
|
||||||
const stub_index = try self.allocateStubEntry(target);
|
|
||||||
const stub_helper_atom_index = try self.createStubHelperAtom();
|
const stub_helper_atom_index = try self.createStubHelperAtom();
|
||||||
const stub_helper_atom = self.getAtom(stub_helper_atom_index);
|
const stub_helper_atom = self.getAtom(stub_helper_atom_index);
|
||||||
const laptr_atom_index = try self.createLazyPointerAtom(stub_helper_atom.getSymbolIndex().?, target);
|
const laptr_atom_index = try self.createLazyPointerAtom(stub_helper_atom.getSymbolIndex().?, target);
|
||||||
const laptr_atom = self.getAtom(laptr_atom_index);
|
const laptr_atom = self.getAtom(laptr_atom_index);
|
||||||
const stub_atom_index = try self.createStubAtom(laptr_atom.getSymbolIndex().?);
|
const stub_atom_index = try self.createStubAtom(laptr_atom.getSymbolIndex().?);
|
||||||
const stub_atom = self.getAtom(stub_atom_index);
|
const stub_atom = self.getAtom(stub_atom_index);
|
||||||
self.stubs.items[stub_index].sym_index = stub_atom.getSymbolIndex().?;
|
self.stubs_table.entries.items[stub_index].sym_index = stub_atom.getSymbolIndex().?;
|
||||||
self.markRelocsDirtyByTarget(target);
|
self.markRelocsDirtyByTarget(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2431,7 +2462,7 @@ fn updateDeclCode(self: *MachO, decl_index: Module.Decl.Index, code: []u8) !u64
|
||||||
sym.n_value = vaddr;
|
sym.n_value = vaddr;
|
||||||
log.debug(" (updating GOT entry)", .{});
|
log.debug(" (updating GOT entry)", .{});
|
||||||
const got_target = SymbolWithLoc{ .sym_index = sym_index, .file = null };
|
const got_target = SymbolWithLoc{ .sym_index = sym_index, .file = null };
|
||||||
const got_atom_index = self.getGotAtomIndexForSymbol(got_target).?;
|
const got_atom_index = self.got_table.getAtomIndex(self, got_target).?;
|
||||||
self.markRelocsDirtyByTarget(got_target);
|
self.markRelocsDirtyByTarget(got_target);
|
||||||
try self.writePtrWidthAtom(got_atom_index);
|
try self.writePtrWidthAtom(got_atom_index);
|
||||||
}
|
}
|
||||||
|
|
@ -3481,8 +3512,8 @@ const SymtabCtx = struct {
|
||||||
|
|
||||||
fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void {
|
fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void {
|
||||||
const gpa = self.base.allocator;
|
const gpa = self.base.allocator;
|
||||||
const nstubs = @intCast(u32, self.stubs_table.count());
|
const nstubs = @intCast(u32, self.stubs_table.lookup.count());
|
||||||
const ngot_entries = @intCast(u32, self.got_entries_table.count());
|
const ngot_entries = @intCast(u32, self.got_table.lookup.count());
|
||||||
const nindirectsyms = nstubs * 2 + ngot_entries;
|
const nindirectsyms = nstubs * 2 + ngot_entries;
|
||||||
const iextdefsym = ctx.nlocalsym;
|
const iextdefsym = ctx.nlocalsym;
|
||||||
const iundefsym = iextdefsym + ctx.nextdefsym;
|
const iundefsym = iextdefsym + ctx.nextdefsym;
|
||||||
|
|
@ -3504,7 +3535,7 @@ fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void {
|
||||||
if (self.stubs_section_index) |sect_id| {
|
if (self.stubs_section_index) |sect_id| {
|
||||||
const stubs = &self.sections.items(.header)[sect_id];
|
const stubs = &self.sections.items(.header)[sect_id];
|
||||||
stubs.reserved1 = 0;
|
stubs.reserved1 = 0;
|
||||||
for (self.stubs.items) |entry| {
|
for (self.stubs_table.entries.items) |entry| {
|
||||||
if (entry.sym_index == 0) continue;
|
if (entry.sym_index == 0) continue;
|
||||||
const target_sym = self.getSymbol(entry.target);
|
const target_sym = self.getSymbol(entry.target);
|
||||||
assert(target_sym.undf());
|
assert(target_sym.undf());
|
||||||
|
|
@ -3515,7 +3546,7 @@ fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void {
|
||||||
if (self.got_section_index) |sect_id| {
|
if (self.got_section_index) |sect_id| {
|
||||||
const got = &self.sections.items(.header)[sect_id];
|
const got = &self.sections.items(.header)[sect_id];
|
||||||
got.reserved1 = nstubs;
|
got.reserved1 = nstubs;
|
||||||
for (self.got_entries.items) |entry| {
|
for (self.got_table.entries.items) |entry| {
|
||||||
if (entry.sym_index == 0) continue;
|
if (entry.sym_index == 0) continue;
|
||||||
const target_sym = self.getSymbol(entry.target);
|
const target_sym = self.getSymbol(entry.target);
|
||||||
if (target_sym.undf()) {
|
if (target_sym.undf()) {
|
||||||
|
|
@ -3529,7 +3560,7 @@ fn writeDysymtab(self: *MachO, ctx: SymtabCtx) !void {
|
||||||
if (self.la_symbol_ptr_section_index) |sect_id| {
|
if (self.la_symbol_ptr_section_index) |sect_id| {
|
||||||
const la_symbol_ptr = &self.sections.items(.header)[sect_id];
|
const la_symbol_ptr = &self.sections.items(.header)[sect_id];
|
||||||
la_symbol_ptr.reserved1 = nstubs + ngot_entries;
|
la_symbol_ptr.reserved1 = nstubs + ngot_entries;
|
||||||
for (self.stubs.items) |entry| {
|
for (self.stubs_table.entries.items) |entry| {
|
||||||
if (entry.sym_index == 0) continue;
|
if (entry.sym_index == 0) continue;
|
||||||
const target_sym = self.getSymbol(entry.target);
|
const target_sym = self.getSymbol(entry.target);
|
||||||
assert(target_sym.undf());
|
assert(target_sym.undf());
|
||||||
|
|
@ -3874,20 +3905,6 @@ pub fn getAtomIndexForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?Atom.In
|
||||||
return self.atom_by_index_table.get(sym_with_loc.sym_index);
|
return self.atom_by_index_table.get(sym_with_loc.sym_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns GOT atom that references `sym_with_loc` if one exists.
|
|
||||||
/// Returns null otherwise.
|
|
||||||
pub fn getGotAtomIndexForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?Atom.Index {
|
|
||||||
const got_index = self.got_entries_table.get(sym_with_loc) orelse return null;
|
|
||||||
return self.got_entries.items[got_index].getAtomIndex(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns stubs atom that references `sym_with_loc` if one exists.
|
|
||||||
/// Returns null otherwise.
|
|
||||||
pub fn getStubsAtomIndexForSymbol(self: *MachO, sym_with_loc: SymbolWithLoc) ?Atom.Index {
|
|
||||||
const stubs_index = self.stubs_table.get(sym_with_loc) orelse return null;
|
|
||||||
return self.stubs.items[stubs_index].getAtomIndex(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns symbol location corresponding to the set entrypoint.
|
/// Returns symbol location corresponding to the set entrypoint.
|
||||||
/// Asserts output mode is executable.
|
/// Asserts output mode is executable.
|
||||||
pub fn getEntryPoint(self: MachO) error{MissingMainEntrypoint}!SymbolWithLoc {
|
pub fn getEntryPoint(self: MachO) error{MissingMainEntrypoint}!SymbolWithLoc {
|
||||||
|
|
@ -4234,37 +4251,10 @@ pub fn logSymtab(self: *MachO) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("GOT entries:", .{});
|
log.debug("GOT entries:", .{});
|
||||||
for (self.got_entries.items, 0..) |entry, i| {
|
log.debug("{}", .{self.got_table.fmtDebug(self)});
|
||||||
const atom_sym = entry.getSymbol(self);
|
|
||||||
const target_sym = self.getSymbol(entry.target);
|
|
||||||
if (target_sym.undf()) {
|
|
||||||
log.debug(" {d}@{x} => import('{s}')", .{
|
|
||||||
i,
|
|
||||||
atom_sym.n_value,
|
|
||||||
self.getSymbolName(entry.target),
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
log.debug(" {d}@{x} => local(%{d}) in object({?d}) {s}", .{
|
|
||||||
i,
|
|
||||||
atom_sym.n_value,
|
|
||||||
entry.target.sym_index,
|
|
||||||
entry.target.file,
|
|
||||||
logSymAttributes(target_sym, &buf),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.debug("stubs entries:", .{});
|
log.debug("stubs entries:", .{});
|
||||||
for (self.stubs.items, 0..) |entry, i| {
|
log.debug("{}", .{self.stubs_table.fmtDebug(self)});
|
||||||
const target_sym = self.getSymbol(entry.target);
|
|
||||||
const atom_sym = entry.getSymbol(self);
|
|
||||||
assert(target_sym.undf());
|
|
||||||
log.debug(" {d}@{x} => import('{s}')", .{
|
|
||||||
i,
|
|
||||||
atom_sym.n_value,
|
|
||||||
self.getSymbolName(entry.target),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn logAtoms(self: *MachO) void {
|
pub fn logAtoms(self: *MachO) void {
|
||||||
|
|
|
||||||
|
|
@ -226,26 +226,20 @@ pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {
|
||||||
|
|
||||||
for (self.relocs.items) |*reloc| {
|
for (self.relocs.items) |*reloc| {
|
||||||
const sym = switch (reloc.type) {
|
const sym = switch (reloc.type) {
|
||||||
.direct_load => macho_file.getSymbol(.{ .sym_index = reloc.target, .file = null }),
|
.direct_load => macho_file.getSymbol(.{ .sym_index = reloc.target }),
|
||||||
.got_load => blk: {
|
.got_load => blk: {
|
||||||
const got_index = macho_file.got_entries_table.get(.{
|
const got_index = macho_file.got_table.lookup.get(.{ .sym_index = reloc.target }).?;
|
||||||
.sym_index = reloc.target,
|
const got_entry = macho_file.got_table.entries.items[got_index];
|
||||||
.file = null,
|
|
||||||
}).?;
|
|
||||||
const got_entry = macho_file.got_entries.items[got_index];
|
|
||||||
break :blk got_entry.getSymbol(macho_file);
|
break :blk got_entry.getSymbol(macho_file);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
if (sym.n_value == reloc.prev_vaddr) continue;
|
if (sym.n_value == reloc.prev_vaddr) continue;
|
||||||
|
|
||||||
const sym_name = switch (reloc.type) {
|
const sym_name = switch (reloc.type) {
|
||||||
.direct_load => macho_file.getSymbolName(.{ .sym_index = reloc.target, .file = null }),
|
.direct_load => macho_file.getSymbolName(.{ .sym_index = reloc.target }),
|
||||||
.got_load => blk: {
|
.got_load => blk: {
|
||||||
const got_index = macho_file.got_entries_table.get(.{
|
const got_index = macho_file.got_table.lookup.get(.{ .sym_index = reloc.target }).?;
|
||||||
.sym_index = reloc.target,
|
const got_entry = macho_file.got_table.entries.items[got_index];
|
||||||
.file = null,
|
|
||||||
}).?;
|
|
||||||
const got_entry = macho_file.got_entries.items[got_index];
|
|
||||||
break :blk got_entry.getName(macho_file);
|
break :blk got_entry.getName(macho_file);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -46,13 +46,15 @@ pub fn isResolvable(self: Relocation, macho_file: *MachO) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getTargetAtomIndex(self: Relocation, macho_file: *MachO) ?Atom.Index {
|
pub fn getTargetAtomIndex(self: Relocation, macho_file: *MachO) ?Atom.Index {
|
||||||
switch (self.type) {
|
return switch (self.type) {
|
||||||
.got, .got_page, .got_pageoff => return macho_file.getGotAtomIndexForSymbol(self.target),
|
.got, .got_page, .got_pageoff => macho_file.got_table.getAtomIndex(macho_file, self.target),
|
||||||
.tlv, .tlv_page, .tlv_pageoff => return macho_file.getTlvpAtomIndexForSymbol(self.target),
|
.tlv, .tlv_page, .tlv_pageoff => macho_file.tlvp_table.getAtomIndex(macho_file, self.target),
|
||||||
else => {},
|
.branch => if (macho_file.stubs_table.getAtomIndex(macho_file, self.target)) |index|
|
||||||
}
|
index
|
||||||
if (macho_file.getStubsAtomIndexForSymbol(self.target)) |stubs_atom| return stubs_atom;
|
else
|
||||||
return macho_file.getAtomIndexForSymbol(self.target);
|
macho_file.getAtomIndexForSymbol(self.target),
|
||||||
|
else => macho_file.getAtomIndexForSymbol(self.target),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, code: []u8) void {
|
pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, code: []u8) void {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue