mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
macho: update ZigObject to use new ownership model
This commit is contained in:
parent
f8b5466aef
commit
5b4c0cc1f9
@ -51,12 +51,12 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
});
|
||||
} else if (emit.lower.bin_file.cast(link.File.MachO)) |macho_file| {
|
||||
// Add relocation to the decl.
|
||||
const atom = macho_file.getSymbol(symbol.atom_index).getAtom(macho_file).?;
|
||||
const sym_index = macho_file.getZigObject().?.symbols.items[symbol.sym_index];
|
||||
const zo = macho_file.getZigObject().?;
|
||||
const atom = zo.symbols.items[symbol.atom_index].getAtom(macho_file).?;
|
||||
try atom.addReloc(macho_file, .{
|
||||
.tag = .@"extern",
|
||||
.offset = end_offset - 4,
|
||||
.target = sym_index,
|
||||
.target = symbol.sym_index,
|
||||
.addend = 0,
|
||||
.type = .branch,
|
||||
.meta = .{
|
||||
@ -160,11 +160,11 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
.Obj => true,
|
||||
.Lib => emit.lower.link_mode == .static,
|
||||
};
|
||||
const atom = macho_file.getSymbol(data.atom_index).getAtom(macho_file).?;
|
||||
const sym_index = macho_file.getZigObject().?.symbols.items[data.sym_index];
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const zo = macho_file.getZigObject().?;
|
||||
const atom = zo.symbols.items[data.atom_index].getAtom(macho_file).?;
|
||||
const sym = zo.symbols.items[data.sym_index];
|
||||
if (sym.flags.needs_zig_got and !is_obj_or_static_lib) {
|
||||
_ = try sym.getOrCreateZigGotEntry(sym_index, macho_file);
|
||||
_ = try sym.getOrCreateZigGotEntry(data.sym_index, macho_file);
|
||||
}
|
||||
const @"type": link.File.MachO.Relocation.Type = if (sym.flags.needs_zig_got and !is_obj_or_static_lib)
|
||||
.zig_got_load
|
||||
@ -179,7 +179,7 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
try atom.addReloc(macho_file, .{
|
||||
.tag = .@"extern",
|
||||
.offset = @intCast(end_offset - 4),
|
||||
.target = sym_index,
|
||||
.target = data.sym_index,
|
||||
.addend = 0,
|
||||
.type = @"type",
|
||||
.meta = .{
|
||||
|
||||
@ -425,8 +425,8 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
|
||||
else => unreachable,
|
||||
};
|
||||
} else if (lower.bin_file.cast(link.File.MachO)) |macho_file| {
|
||||
const sym_index = macho_file.getZigObject().?.symbols.items[sym.sym_index];
|
||||
const macho_sym = macho_file.getSymbol(sym_index);
|
||||
const zo = macho_file.getZigObject().?;
|
||||
const macho_sym = zo.symbols.items[sym.sym_index];
|
||||
|
||||
if (macho_sym.flags.tlv) {
|
||||
_ = lower.reloc(.{ .linker_reloc = sym });
|
||||
|
||||
@ -901,15 +901,16 @@ fn genDeclRef(
|
||||
}
|
||||
return GenResult.mcv(.{ .load_symbol = sym.esym_index });
|
||||
} else if (lf.cast(link.File.MachO)) |macho_file| {
|
||||
const zo = macho_file.getZigObject().?;
|
||||
if (is_extern) {
|
||||
const name = decl.name.toSlice(ip);
|
||||
const lib_name = if (decl.getOwnedVariable(zcu)) |ov| ov.lib_name.toSlice(ip) else null;
|
||||
const sym_index = try macho_file.getGlobalSymbol(name, lib_name);
|
||||
macho_file.getSymbol(macho_file.getZigObject().?.symbols.items[sym_index]).flags.needs_got = true;
|
||||
zo.symbols.items[sym_index].flags.needs_got = true;
|
||||
return GenResult.mcv(.{ .load_symbol = sym_index });
|
||||
}
|
||||
const sym_index = try macho_file.getZigObject().?.getOrCreateMetadataForDecl(macho_file, decl_index);
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const sym_index = try zo.getOrCreateMetadataForDecl(macho_file, decl_index);
|
||||
const sym = zo.symbols.items[sym_index];
|
||||
if (is_threadlocal) {
|
||||
return GenResult.mcv(.{ .load_tlv = sym.nlist_idx });
|
||||
}
|
||||
@ -956,7 +957,7 @@ fn genUnnamedConst(
|
||||
},
|
||||
.macho => {
|
||||
const macho_file = lf.cast(link.File.MachO).?;
|
||||
const local = macho_file.getSymbol(local_sym_index);
|
||||
const local = macho_file.getZigObject().?.symbols.items[local_sym_index];
|
||||
return GenResult.mcv(.{ .load_symbol = local.nlist_idx });
|
||||
},
|
||||
.coff => {
|
||||
|
||||
@ -290,8 +290,10 @@ pub fn deinit(self: *MachO) void {
|
||||
self.dylibs.deinit(gpa);
|
||||
|
||||
self.segments.deinit(gpa);
|
||||
for (self.sections.items(.atoms)) |*list| {
|
||||
list.deinit(gpa);
|
||||
for (self.sections.items(.atoms), self.sections.items(.out), self.sections.items(.thunks)) |*atoms, *out, *thnks| {
|
||||
atoms.deinit(gpa);
|
||||
out.deinit(gpa);
|
||||
thnks.deinit(gpa);
|
||||
}
|
||||
self.sections.deinit(gpa);
|
||||
|
||||
@ -561,8 +563,8 @@ pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
|
||||
if (self.getZigObject()) |zo| {
|
||||
var has_resolve_error = false;
|
||||
|
||||
for (zo.atoms.items) |atom_index| {
|
||||
const atom = self.getAtom(atom_index) orelse continue;
|
||||
for (zo.getAtoms()) |atom_index| {
|
||||
const atom = zo.getAtom(atom_index) orelse continue;
|
||||
if (!atom.flags.alive) continue;
|
||||
const sect = &self.sections.items(.header)[atom.out_n_sect];
|
||||
if (sect.isZerofill()) continue;
|
||||
@ -573,7 +575,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
|
||||
const atom_size = math.cast(usize, atom.size) orelse return error.Overflow;
|
||||
const code = try gpa.alloc(u8, atom_size);
|
||||
defer gpa.free(code);
|
||||
atom.getData(self, code) catch |err| switch (err) {
|
||||
zo.getAtomData(self, atom.*, code) catch |err| switch (err) {
|
||||
error.InputOutput => {
|
||||
try self.reportUnexpectedError("fetching code for '{s}' failed", .{
|
||||
atom.getName(self),
|
||||
@ -1524,7 +1526,7 @@ fn scanRelocs(self: *MachO) !void {
|
||||
try self.getFile(index).?.object.scanRelocs(self);
|
||||
}
|
||||
if (self.getInternalObject()) |obj| {
|
||||
try obj.scanRelocs(self);
|
||||
obj.scanRelocs(self);
|
||||
}
|
||||
|
||||
try self.reportUndefs();
|
||||
@ -2394,7 +2396,7 @@ fn writeSectionsAndUpdateLinkeditSizes(self: *MachO) !void {
|
||||
self.objc_stubs_sect_index,
|
||||
}) |maybe_sect_id| {
|
||||
if (maybe_sect_id) |sect_id| {
|
||||
const out = &slice.items(.out)[sect_id];
|
||||
const out = slice.items(.out)[sect_id].items;
|
||||
try self.writeSyntheticSection(sect_id, out);
|
||||
}
|
||||
}
|
||||
@ -3970,9 +3972,11 @@ pub const base_tag: link.File.Tag = link.File.Tag.macho;
|
||||
const Section = struct {
|
||||
header: macho.section_64,
|
||||
segment_id: u8,
|
||||
atoms: std.ArrayListUnmanaged(Atom.Index) = .{},
|
||||
atoms: std.ArrayListUnmanaged(Ref) = .{},
|
||||
free_list: std.ArrayListUnmanaged(Atom.Index) = .{},
|
||||
last_atom_index: Atom.Index = 0,
|
||||
thunks: std.ArrayListUnmanaged(Thunk.Index) = .{},
|
||||
out: std.ArrayListUnmanaged(u8) = .{},
|
||||
};
|
||||
|
||||
pub const LiteralPool = struct {
|
||||
@ -4018,7 +4022,7 @@ pub const LiteralPool = struct {
|
||||
return .{
|
||||
.found_existing = gop.found_existing,
|
||||
.index = @intCast(gop.index),
|
||||
.atom = &lp.values.items[gop.index],
|
||||
.ref = &lp.values.items[gop.index],
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -423,7 +423,6 @@ pub fn addReloc(self: *Atom, macho_file: *MachO, reloc: Relocation) !void {
|
||||
const gpa = macho_file.base.comp.gpa;
|
||||
const file = self.getFile(macho_file);
|
||||
assert(file == .zig_object);
|
||||
assert(self.flags.relocs);
|
||||
var extra = self.getExtra(macho_file).?;
|
||||
const rels = &file.zig_object.relocs.items[extra.rel_index];
|
||||
try rels.append(gpa, reloc);
|
||||
@ -432,7 +431,6 @@ pub fn addReloc(self: *Atom, macho_file: *MachO, reloc: Relocation) !void {
|
||||
}
|
||||
|
||||
pub fn freeRelocs(self: *Atom, macho_file: *MachO) void {
|
||||
if (!self.flags.relocs) return;
|
||||
self.getFile(macho_file).zig_object.freeAtomRelocs(self.*, macho_file);
|
||||
var extra = self.getExtra(macho_file).?;
|
||||
extra.rel_count = 0;
|
||||
|
||||
@ -6,9 +6,15 @@ index: File.Index,
|
||||
symtab: std.MultiArrayList(Nlist) = .{},
|
||||
strtab: StringTable = .{},
|
||||
|
||||
symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
|
||||
atoms: std.ArrayListUnmanaged(Atom.Index) = .{},
|
||||
globals_lookup: std.AutoHashMapUnmanaged(u32, Symbol.Index) = .{},
|
||||
symbols: std.ArrayListUnmanaged(Symbol) = .{},
|
||||
symbols_extra: std.ArrayListUnmanaged(u32) = .{},
|
||||
globals: std.ArrayListUnmanaged(MachO.SymbolResolver.Index) = .{},
|
||||
/// Maps string index (so name) into nlist index for the global symbol defined within this
|
||||
/// module.
|
||||
globals_lookup: std.AutoHashMapUnmanaged(u32, u32) = .{},
|
||||
atoms: std.ArrayListUnmanaged(Atom) = .{},
|
||||
atoms_indexes: std.ArrayListUnmanaged(Atom.Index) = .{},
|
||||
atoms_extra: std.ArrayListUnmanaged(u32) = .{},
|
||||
|
||||
/// Table of tracked LazySymbols.
|
||||
lazy_syms: LazySymbolTable = .{},
|
||||
@ -58,10 +64,13 @@ debug_info_header_dirty: bool = false,
|
||||
debug_line_header_dirty: bool = false,
|
||||
|
||||
pub fn init(self: *ZigObject, macho_file: *MachO) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const comp = macho_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
|
||||
try self.atoms.append(gpa, 0); // null input section
|
||||
try self.atoms.append(gpa, .{ .extra = try self.addAtomExtra(gpa, .{}) }); // null input section
|
||||
try self.strtab.buffer.append(gpa, 0);
|
||||
|
||||
switch (comp.config.debug_format) {
|
||||
@ -84,8 +93,12 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
|
||||
self.symtab.deinit(allocator);
|
||||
self.strtab.deinit(allocator);
|
||||
self.symbols.deinit(allocator);
|
||||
self.atoms.deinit(allocator);
|
||||
self.symbols_extra.deinit(allocator);
|
||||
self.globals.deinit(allocator);
|
||||
self.globals_lookup.deinit(allocator);
|
||||
self.atoms.deinit(allocator);
|
||||
self.atoms_indexes.deinit(allocator);
|
||||
self.atoms_extra.deinit(allocator);
|
||||
|
||||
{
|
||||
var it = self.decls.iterator();
|
||||
@ -139,32 +152,21 @@ fn addNlist(self: *ZigObject, allocator: Allocator) !Symbol.Index {
|
||||
return index;
|
||||
}
|
||||
|
||||
pub fn addAtom(self: *ZigObject, macho_file: *MachO) !Symbol.Index {
|
||||
const gpa = macho_file.base.comp.gpa;
|
||||
const atom_index = try macho_file.addAtom();
|
||||
const symbol_index = try macho_file.addSymbol();
|
||||
const nlist_index = try self.addNlist(gpa);
|
||||
|
||||
try self.atoms.append(gpa, atom_index);
|
||||
try self.symbols.append(gpa, symbol_index);
|
||||
|
||||
const atom = macho_file.getAtom(atom_index).?;
|
||||
atom.file = self.index;
|
||||
atom.atom_index = atom_index;
|
||||
|
||||
const symbol = macho_file.getSymbol(symbol_index);
|
||||
symbol.file = self.index;
|
||||
symbol.atom = atom_index;
|
||||
|
||||
pub fn createAtomForDecl(self: *ZigObject, allocator: Allocator, macho_file: *MachO) !Symbol.Index {
|
||||
const atom_index = try self.addAtom(allocator);
|
||||
const symbol_index = try self.addSymbol(allocator);
|
||||
const nlist_index = try self.addNlist(allocator);
|
||||
self.symtab.items(.atom)[nlist_index] = atom_index;
|
||||
try self.atoms_indexes.append(allocator, atom_index);
|
||||
const symbol = &self.symbols.items[symbol_index];
|
||||
symbol.atom_ref = .{ .index = atom_index, .file = self.index };
|
||||
symbol.nlist_idx = nlist_index;
|
||||
|
||||
symbol.extra = try self.addSymbolExtra(allocator, .{});
|
||||
const relocs_index = @as(u32, @intCast(self.relocs.items.len));
|
||||
const relocs = try self.relocs.addOne(gpa);
|
||||
const relocs = try self.relocs.addOne(allocator);
|
||||
relocs.* = .{};
|
||||
try atom.addExtra(.{ .rel_index = relocs_index, .rel_count = 0 }, macho_file);
|
||||
atom.flags.relocs = true;
|
||||
|
||||
const atom = self.getAtom(atom_index).?;
|
||||
atom.addExtra(.{ .rel_index = relocs_index, .rel_count = 0 }, macho_file);
|
||||
return symbol_index;
|
||||
}
|
||||
|
||||
@ -191,89 +193,51 @@ pub fn getAtomData(self: ZigObject, macho_file: *MachO, atom: Atom, buffer: []u8
|
||||
}
|
||||
|
||||
pub fn getAtomRelocs(self: *ZigObject, atom: Atom, macho_file: *MachO) []const Relocation {
|
||||
if (!atom.flags.relocs) return &[0]Relocation{};
|
||||
const extra = atom.getExtra(macho_file).?;
|
||||
const extra = atom.getExtra(macho_file);
|
||||
const relocs = self.relocs.items[extra.rel_index];
|
||||
return relocs.items[0..extra.rel_count];
|
||||
}
|
||||
|
||||
pub fn freeAtomRelocs(self: *ZigObject, atom: Atom, macho_file: *MachO) void {
|
||||
if (atom.flags.relocs) {
|
||||
const extra = atom.getExtra(macho_file).?;
|
||||
self.relocs.items[extra.rel_index].clearRetainingCapacity();
|
||||
}
|
||||
const extra = atom.getExtra(macho_file);
|
||||
self.relocs.items[extra.rel_index].clearRetainingCapacity();
|
||||
}
|
||||
|
||||
pub fn resolveSymbols(self: *ZigObject, macho_file: *MachO) void {
|
||||
pub fn resolveSymbols(self: *ZigObject, macho_file: *MachO) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
for (self.symbols.items, 0..) |index, i| {
|
||||
const nlist_idx = @as(Symbol.Index, @intCast(i));
|
||||
const nlist = self.symtab.items(.nlist)[nlist_idx];
|
||||
const atom_index = self.symtab.items(.atom)[nlist_idx];
|
||||
const gpa = macho_file.base.comp.gpa;
|
||||
|
||||
for (self.symtab.items(.nlist), self.symtab.items(.atom), self.globals.items, 0..) |nlist, atom_index, *global, i| {
|
||||
if (!nlist.ext()) continue;
|
||||
if (nlist.undf() and !nlist.tentative()) continue;
|
||||
if (nlist.sect()) {
|
||||
const atom = macho_file.getAtom(atom_index).?;
|
||||
const atom = self.getAtom(atom_index).?;
|
||||
if (!atom.flags.alive) continue;
|
||||
}
|
||||
|
||||
const symbol = macho_file.getSymbol(index);
|
||||
const gop = try macho_file.resolver.getOrPut(gpa, .{
|
||||
.index = @intCast(i),
|
||||
.file = self.index,
|
||||
}, macho_file);
|
||||
if (!gop.found_existing) {
|
||||
gop.ref.* = .{ .index = 0, .file = 0 };
|
||||
}
|
||||
global.* = gop.index;
|
||||
|
||||
if (nlist.undf() and !nlist.tentative()) continue;
|
||||
if (gop.ref.getFile(macho_file) == null) {
|
||||
gop.ref.* = .{ .index = @intCast(i), .file = self.index };
|
||||
continue;
|
||||
}
|
||||
|
||||
if (self.asFile().getSymbolRank(.{
|
||||
.archive = false,
|
||||
.weak = nlist.weakDef(),
|
||||
.tentative = nlist.tentative(),
|
||||
}) < symbol.getSymbolRank(macho_file)) {
|
||||
const value = if (nlist.sect()) blk: {
|
||||
const atom = macho_file.getAtom(atom_index).?;
|
||||
break :blk nlist.n_value - atom.getInputAddress(macho_file);
|
||||
} else nlist.n_value;
|
||||
const out_n_sect = if (nlist.sect()) macho_file.getAtom(atom_index).?.out_n_sect else 0;
|
||||
symbol.value = value;
|
||||
symbol.atom = atom_index;
|
||||
symbol.out_n_sect = out_n_sect;
|
||||
symbol.nlist_idx = nlist_idx;
|
||||
symbol.file = self.index;
|
||||
symbol.flags.weak = nlist.weakDef();
|
||||
symbol.flags.abs = nlist.abs();
|
||||
symbol.flags.tentative = nlist.tentative();
|
||||
symbol.flags.weak_ref = false;
|
||||
symbol.flags.dyn_ref = nlist.n_desc & macho.REFERENCED_DYNAMICALLY != 0;
|
||||
symbol.flags.no_dead_strip = symbol.flags.no_dead_strip or nlist.noDeadStrip();
|
||||
// TODO: symbol.flags.interposable = macho_file.base.isDynLib() and macho_file.options.namespace == .flat and !nlist.pext();
|
||||
symbol.flags.interposable = false;
|
||||
|
||||
if (nlist.sect() and
|
||||
macho_file.sections.items(.header)[nlist.n_sect - 1].type() == macho.S_THREAD_LOCAL_VARIABLES)
|
||||
{
|
||||
symbol.flags.tlv = true;
|
||||
}
|
||||
}) < gop.ref.getSymbol(macho_file).?.getSymbolRank(macho_file)) {
|
||||
gop.ref.* = .{ .index = @intCast(i), .file = self.index };
|
||||
}
|
||||
|
||||
// Regardless of who the winner is, we still merge symbol visibility here.
|
||||
if (nlist.pext() or (nlist.weakDef() and nlist.weakRef())) {
|
||||
if (symbol.visibility != .global) {
|
||||
symbol.visibility = .hidden;
|
||||
}
|
||||
} else {
|
||||
symbol.visibility = .global;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resetGlobals(self: *ZigObject, macho_file: *MachO) void {
|
||||
for (self.symbols.items, 0..) |sym_index, nlist_idx| {
|
||||
if (!self.symtab.items(.nlist)[nlist_idx].ext()) continue;
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const name = sym.name;
|
||||
const global = sym.flags.global;
|
||||
const weak_ref = sym.flags.weak_ref;
|
||||
sym.* = .{};
|
||||
sym.name = name;
|
||||
sym.flags.global = global;
|
||||
sym.flags.weak_ref = weak_ref;
|
||||
}
|
||||
}
|
||||
|
||||
@ -281,12 +245,13 @@ pub fn markLive(self: *ZigObject, macho_file: *MachO) void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
for (self.symbols.items, 0..) |index, nlist_idx| {
|
||||
const nlist = self.symtab.items(.nlist)[nlist_idx];
|
||||
for (0..self.symbols.items.len) |i| {
|
||||
const nlist = self.symtab.items(.nlist)[i];
|
||||
if (!nlist.ext()) continue;
|
||||
|
||||
const sym = macho_file.getSymbol(index);
|
||||
const file = sym.getFile(macho_file) orelse continue;
|
||||
const ref = self.getSymbolRef(@intCast(i), macho_file);
|
||||
const file = ref.getFile(macho_file) orelse continue;
|
||||
const sym = ref.getSymbol(macho_file).?;
|
||||
const should_keep = nlist.undf() or (nlist.tentative() and !sym.flags.tentative);
|
||||
if (should_keep and file == .object and !file.object.alive) {
|
||||
file.object.alive = true;
|
||||
@ -295,24 +260,41 @@ pub fn markLive(self: *ZigObject, macho_file: *MachO) void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn checkDuplicates(self: *ZigObject, dupes: anytype, macho_file: *MachO) !void {
|
||||
for (self.symbols.items, 0..) |index, nlist_idx| {
|
||||
const sym = macho_file.getSymbol(index);
|
||||
if (sym.visibility != .global) continue;
|
||||
const file = sym.getFile(macho_file) orelse continue;
|
||||
if (file.getIndex() == self.index) continue;
|
||||
pub fn mergeSymbolVisibility(self: *ZigObject, macho_file: *MachO) void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const nlist = self.symtab.items(.nlist)[nlist_idx];
|
||||
if (!nlist.undf() and !nlist.tentative() and !(nlist.weakDef() or nlist.pext())) {
|
||||
const gop = try dupes.getOrPut(index);
|
||||
if (!gop.found_existing) {
|
||||
gop.value_ptr.* = .{};
|
||||
}
|
||||
try gop.value_ptr.append(macho_file.base.comp.gpa, self.index);
|
||||
for (self.symbols.items, 0..) |sym, i| {
|
||||
const ref = self.getSymbolRef(@intCast(i), macho_file);
|
||||
const global = ref.getSymbol(macho_file) orelse continue;
|
||||
if (global.visibility != .global) {
|
||||
global.visibility = sym.visibility;
|
||||
}
|
||||
if (sym.flags.weak_ref) {
|
||||
global.flags.weak_ref = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
// pub fn checkDuplicates(self: *ZigObject, dupes: anytype, macho_file: *MachO) !void {
|
||||
// for (self.symbols.items, 0..) |index, nlist_idx| {
|
||||
// const sym = macho_file.getSymbol(index);
|
||||
// if (sym.visibility != .global) continue;
|
||||
// const file = sym.getFile(macho_file) orelse continue;
|
||||
// if (file.getIndex() == self.index) continue;
|
||||
|
||||
// const nlist = self.symtab.items(.nlist)[nlist_idx];
|
||||
// if (!nlist.undf() and !nlist.tentative() and !(nlist.weakDef() or nlist.pext())) {
|
||||
// const gop = try dupes.getOrPut(index);
|
||||
// if (!gop.found_existing) {
|
||||
// gop.value_ptr.* = .{};
|
||||
// }
|
||||
// try gop.value_ptr.append(macho_file.base.comp.gpa, self.index);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
pub fn resolveLiterals(self: *ZigObject, lp: *MachO.LiteralPool, macho_file: *MachO) !void {
|
||||
_ = self;
|
||||
_ = lp;
|
||||
@ -362,8 +344,8 @@ pub fn writeAr(self: ZigObject, ar_format: Archive.Format, writer: anytype) !voi
|
||||
}
|
||||
|
||||
pub fn scanRelocs(self: *ZigObject, macho_file: *MachO) !void {
|
||||
for (self.atoms.items) |atom_index| {
|
||||
const atom = macho_file.getAtom(atom_index) orelse continue;
|
||||
for (self.getAtoms()) |atom_index| {
|
||||
const atom = self.getAtom(atom_index) orelse continue;
|
||||
if (!atom.flags.alive) continue;
|
||||
const sect = atom.getInputSection(macho_file);
|
||||
if (sect.isZerofill()) continue;
|
||||
@ -371,46 +353,49 @@ pub fn scanRelocs(self: *ZigObject, macho_file: *MachO) !void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) !void {
|
||||
pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
for (self.symbols.items) |sym_index| {
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const file = sym.getFile(macho_file) orelse continue;
|
||||
for (self.symbols.items, 0..) |*sym, i| {
|
||||
const ref = self.getSymbolRef(@intCast(i), macho_file);
|
||||
const file = ref.getFile(macho_file) orelse continue;
|
||||
if (file.getIndex() != self.index) continue;
|
||||
if (sym.getAtom(macho_file)) |atom| if (!atom.flags.alive) continue;
|
||||
sym.flags.output_symtab = true;
|
||||
if (sym.isLocal()) {
|
||||
try sym.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, macho_file);
|
||||
sym.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, macho_file);
|
||||
self.output_symtab_ctx.nlocals += 1;
|
||||
} else if (sym.flags.@"export") {
|
||||
try sym.addExtra(.{ .symtab = self.output_symtab_ctx.nexports }, macho_file);
|
||||
sym.addExtra(.{ .symtab = self.output_symtab_ctx.nexports }, macho_file);
|
||||
self.output_symtab_ctx.nexports += 1;
|
||||
} else {
|
||||
assert(sym.flags.import);
|
||||
try sym.addExtra(.{ .symtab = self.output_symtab_ctx.nimports }, macho_file);
|
||||
sym.addExtra(.{ .symtab = self.output_symtab_ctx.nimports }, macho_file);
|
||||
self.output_symtab_ctx.nimports += 1;
|
||||
}
|
||||
self.output_symtab_ctx.strsize += @as(u32, @intCast(sym.getName(macho_file).len + 1));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeSymtab(self: ZigObject, macho_file: *MachO, ctx: anytype) void {
|
||||
pub fn writeSymtab(self: ZigObject, macho_file: *MachO) void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
for (self.symbols.items) |sym_index| {
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const file = sym.getFile(macho_file) orelse continue;
|
||||
var n_strx = self.output_symtab_ctx.stroff;
|
||||
for (self.symbols.items, 0..) |sym, i| {
|
||||
const ref = self.getSymbolRef(@intCast(i), macho_file);
|
||||
const file = ref.getFile(macho_file) orelse continue;
|
||||
if (file.getIndex() != self.index) continue;
|
||||
const idx = sym.getOutputSymtabIndex(macho_file) orelse continue;
|
||||
const n_strx = @as(u32, @intCast(ctx.strtab.items.len));
|
||||
ctx.strtab.appendSliceAssumeCapacity(sym.getName(macho_file));
|
||||
ctx.strtab.appendAssumeCapacity(0);
|
||||
const out_sym = &ctx.symtab.items[idx];
|
||||
const out_sym = &macho_file.symtab.items[idx];
|
||||
out_sym.n_strx = n_strx;
|
||||
sym.setOutputSym(macho_file, out_sym);
|
||||
const name = sym.getName(macho_file);
|
||||
@memcpy(macho_file.strtab.items[n_strx..][0..name.len], name);
|
||||
n_strx += @intCast(name.len);
|
||||
macho_file.strtab.items[n_strx] = 0;
|
||||
n_strx += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -523,9 +508,9 @@ pub fn getDeclVAddr(
|
||||
reloc_info: link.File.RelocInfo,
|
||||
) !u64 {
|
||||
const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index);
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const sym = self.symbols.items[sym_index];
|
||||
const vaddr = sym.getAddress(.{}, macho_file);
|
||||
const parent_atom = macho_file.getSymbol(reloc_info.parent_atom_index).getAtom(macho_file).?;
|
||||
const parent_atom = self.symbols.items[reloc_info.parent_atom_index].getAtom(macho_file).?;
|
||||
try parent_atom.addReloc(macho_file, .{
|
||||
.tag = .@"extern",
|
||||
.offset = @intCast(reloc_info.offset),
|
||||
@ -549,9 +534,9 @@ pub fn getAnonDeclVAddr(
|
||||
reloc_info: link.File.RelocInfo,
|
||||
) !u64 {
|
||||
const sym_index = self.anon_decls.get(decl_val).?.symbol_index;
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const sym = self.symbols.items[sym_index];
|
||||
const vaddr = sym.getAddress(.{}, macho_file);
|
||||
const parent_atom = macho_file.getSymbol(reloc_info.parent_atom_index).getAtom(macho_file).?;
|
||||
const parent_atom = self.symbols.items[reloc_info.parent_atom_index].getAtom(macho_file).?;
|
||||
try parent_atom.addReloc(macho_file, .{
|
||||
.tag = .@"extern",
|
||||
.offset = @intCast(reloc_info.offset),
|
||||
@ -584,7 +569,7 @@ pub fn lowerAnonDecl(
|
||||
else => explicit_alignment,
|
||||
};
|
||||
if (self.anon_decls.get(decl_val)) |metadata| {
|
||||
const existing_alignment = macho_file.getSymbol(metadata.symbol_index).getAtom(macho_file).?.alignment;
|
||||
const existing_alignment = self.symbols.items[metadata.symbol_index].getAtom(macho_file).?.alignment;
|
||||
if (decl_alignment.order(existing_alignment).compare(.lte))
|
||||
return .ok;
|
||||
}
|
||||
@ -628,13 +613,10 @@ fn freeUnnamedConsts(self: *ZigObject, macho_file: *MachO, decl_index: InternPoo
|
||||
}
|
||||
|
||||
fn freeDeclMetadata(self: *ZigObject, macho_file: *MachO, sym_index: Symbol.Index) void {
|
||||
_ = self;
|
||||
const gpa = macho_file.base.comp.gpa;
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const sym = self.symbols.items[sym_index];
|
||||
sym.getAtom(macho_file).?.free(macho_file);
|
||||
log.debug("adding %{d} to local symbols free list", .{sym_index});
|
||||
macho_file.symbols_free_list.append(gpa, sym_index) catch {};
|
||||
macho_file.symbols.items[sym_index] = .{};
|
||||
// TODO redo this
|
||||
// TODO free GOT entry here
|
||||
}
|
||||
|
||||
@ -675,7 +657,7 @@ pub fn updateFunc(
|
||||
|
||||
const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index);
|
||||
self.freeUnnamedConsts(macho_file, decl_index);
|
||||
macho_file.getSymbol(sym_index).getAtom(macho_file).?.freeRelocs(macho_file);
|
||||
self.symbols.items[sym_index].getAtom(macho_file).?.freeRelocs(macho_file);
|
||||
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
defer code_buffer.deinit();
|
||||
@ -708,7 +690,7 @@ pub fn updateFunc(
|
||||
try self.updateDeclCode(macho_file, pt, decl_index, sym_index, sect_index, code);
|
||||
|
||||
if (decl_state) |*ds| {
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const sym = self.symbols.items[sym_index];
|
||||
try self.dwarf.?.commitDeclState(
|
||||
pt,
|
||||
decl_index,
|
||||
@ -743,13 +725,13 @@ pub fn updateDecl(
|
||||
const name = decl.name.toSlice(&mod.intern_pool);
|
||||
const lib_name = variable.lib_name.toSlice(&mod.intern_pool);
|
||||
const index = try self.getGlobalSymbol(macho_file, name, lib_name);
|
||||
const actual_index = self.symbols.items[index];
|
||||
macho_file.getSymbol(actual_index).flags.needs_got = true;
|
||||
const sym = &self.symbols.items[index];
|
||||
sym.flags.needs_got = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index);
|
||||
macho_file.getSymbol(sym_index).getAtom(macho_file).?.freeRelocs(macho_file);
|
||||
self.symbols.items[sym_index].getAtom(macho_file).?.freeRelocs(macho_file);
|
||||
|
||||
const gpa = macho_file.base.comp.gpa;
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
@ -784,7 +766,7 @@ pub fn updateDecl(
|
||||
}
|
||||
|
||||
if (decl_state) |*ds| {
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const sym = self.symbols.items[sym_index];
|
||||
try self.dwarf.?.commitDeclState(
|
||||
pt,
|
||||
decl_index,
|
||||
@ -816,7 +798,7 @@ fn updateDeclCode(
|
||||
const required_alignment = decl.getAlignment(pt);
|
||||
|
||||
const sect = &macho_file.sections.items(.header)[sect_index];
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const sym = &self.symbols.items[sym_index];
|
||||
const nlist = &self.symtab.items(.nlist)[sym.nlist_idx];
|
||||
const atom = sym.getAtom(macho_file).?;
|
||||
|
||||
@ -850,13 +832,13 @@ fn updateDeclCode(
|
||||
if (!macho_file.base.isRelocatable()) {
|
||||
log.debug(" (updating offset table entry)", .{});
|
||||
assert(sym.flags.has_zig_got);
|
||||
const extra = sym.getExtra(macho_file).?;
|
||||
const extra = sym.getExtra(macho_file);
|
||||
try macho_file.zig_got.writeOne(macho_file, extra.zig_got);
|
||||
}
|
||||
}
|
||||
} else if (code.len < old_size) {
|
||||
atom.shrink(macho_file);
|
||||
} else if (macho_file.getAtom(atom.next_index) == null) {
|
||||
} else if (self.getAtom(atom.next_index) == null) {
|
||||
const needed_size = atom.value + code.len;
|
||||
sect.size = needed_size;
|
||||
}
|
||||
@ -922,8 +904,8 @@ fn createTlvInitializer(
|
||||
const sym_name = try std.fmt.allocPrint(gpa, "{s}$tlv$init", .{name});
|
||||
defer gpa.free(sym_name);
|
||||
|
||||
const sym_index = try self.addAtom(macho_file);
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const sym_index = try self.createAtomForDecl(gpa, macho_file);
|
||||
const sym = &self.symbols.items[sym_index];
|
||||
const nlist = &self.symtab.items(.nlist)[sym.nlist_idx];
|
||||
const atom = sym.getAtom(macho_file).?;
|
||||
|
||||
@ -945,7 +927,6 @@ fn createTlvInitializer(
|
||||
|
||||
const slice = macho_file.sections.slice();
|
||||
const header = slice.items(.header)[sect_index];
|
||||
const atoms = &slice.items(.atoms)[sect_index];
|
||||
|
||||
const gop = try self.tlv_initializers.getOrPut(gpa, atom.atom_index);
|
||||
assert(!gop.found_existing); // TODO incremental updates
|
||||
@ -956,8 +937,6 @@ fn createTlvInitializer(
|
||||
gop.value_ptr.data = try gpa.dupe(u8, code);
|
||||
}
|
||||
|
||||
try atoms.append(gpa, atom.atom_index);
|
||||
|
||||
return sym_index;
|
||||
}
|
||||
|
||||
@ -970,7 +949,7 @@ fn createTlvDescriptor(
|
||||
) !void {
|
||||
const gpa = macho_file.base.comp.gpa;
|
||||
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const sym = &self.symbols.items[sym_index];
|
||||
const nlist = &self.symtab.items(.nlist)[sym.nlist_idx];
|
||||
const atom = sym.getAtom(macho_file).?;
|
||||
const alignment = Atom.Alignment.fromNonzeroByteUnits(@alignOf(u64));
|
||||
@ -1000,7 +979,7 @@ fn createTlvDescriptor(
|
||||
try atom.addReloc(macho_file, .{
|
||||
.tag = .@"extern",
|
||||
.offset = 0,
|
||||
.target = self.symbols.items[tlv_bootstrap_index],
|
||||
.target = tlv_bootstrap_index,
|
||||
.addend = 0,
|
||||
.type = .unsigned,
|
||||
.meta = .{
|
||||
@ -1020,11 +999,14 @@ fn createTlvDescriptor(
|
||||
.pcrel = false,
|
||||
.has_subtractor = false,
|
||||
.length = 3,
|
||||
.symbolnum = @intCast(macho_file.getSymbol(init_sym_index).nlist_idx),
|
||||
.symbolnum = @intCast(init_sym_index),
|
||||
},
|
||||
});
|
||||
|
||||
try macho_file.sections.items(.atoms)[sect_index].append(gpa, atom.atom_index);
|
||||
try macho_file.sections.items(.atoms)[sect_index].append(gpa, .{
|
||||
.index = atom.atom_index,
|
||||
.file = self.index,
|
||||
});
|
||||
}
|
||||
|
||||
fn getDeclOutputSection(
|
||||
@ -1115,7 +1097,7 @@ pub fn lowerUnnamedConst(
|
||||
return error.CodegenFail;
|
||||
},
|
||||
};
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const sym = self.symbols.items[sym_index];
|
||||
try unnamed_consts.append(gpa, sym.atom);
|
||||
return sym_index;
|
||||
}
|
||||
@ -1140,7 +1122,7 @@ fn lowerConst(
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
const sym_index = try self.addAtom(macho_file);
|
||||
const sym_index = try self.createAtomForDecl(gpa, macho_file);
|
||||
|
||||
const res = try codegen.generateSymbol(&macho_file.base, pt, src_loc, val, &code_buffer, .{
|
||||
.none = {},
|
||||
@ -1152,7 +1134,7 @@ fn lowerConst(
|
||||
.fail => |em| return .{ .fail = em },
|
||||
};
|
||||
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const sym = &self.symbols.items[sym_index];
|
||||
const name_str_index = try self.strtab.insert(gpa, name);
|
||||
sym.name = name_str_index;
|
||||
sym.out_n_sect = output_section_index;
|
||||
@ -1218,7 +1200,7 @@ pub fn updateExports(
|
||||
},
|
||||
};
|
||||
const sym_index = metadata.symbol_index;
|
||||
const nlist_idx = macho_file.getSymbol(sym_index).nlist_idx;
|
||||
const nlist_idx = self.symbols.items[sym_index].nlist_idx;
|
||||
const nlist = self.symtab.items(.nlist)[nlist_idx];
|
||||
|
||||
for (export_indices) |export_idx| {
|
||||
@ -1322,7 +1304,7 @@ fn updateLazySymbol(
|
||||
.code => macho_file.zig_text_sect_index.?,
|
||||
.const_data => macho_file.zig_const_sect_index.?,
|
||||
};
|
||||
const sym = macho_file.getSymbol(symbol_index);
|
||||
const sym = &self.symbols.items[symbol_index];
|
||||
sym.name = name_str_index;
|
||||
sym.out_n_sect = output_section_index;
|
||||
|
||||
@ -1382,12 +1364,12 @@ pub fn deleteExport(
|
||||
const nlist = &self.symtab.items(.nlist)[nlist_index.*];
|
||||
self.symtab.items(.size)[nlist_index.*] = 0;
|
||||
_ = self.globals_lookup.remove(nlist.n_strx);
|
||||
const sym_index = macho_file.globals.get(nlist.n_strx).?;
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
if (sym.file == self.index) {
|
||||
_ = macho_file.globals.swapRemove(nlist.n_strx);
|
||||
sym.* = .{};
|
||||
}
|
||||
// TODO actually remove the export
|
||||
// const sym_index = macho_file.globals.get(nlist.n_strx).?;
|
||||
// const sym = &self.symbols.items[sym_index];
|
||||
// if (sym.file == self.index) {
|
||||
// sym.* = .{};
|
||||
// }
|
||||
nlist.* = MachO.null_sym;
|
||||
}
|
||||
|
||||
@ -1404,9 +1386,11 @@ pub fn getGlobalSymbol(self: *ZigObject, macho_file: *MachO, name: []const u8, l
|
||||
nlist.n_strx = off;
|
||||
nlist.n_type = macho.N_EXT;
|
||||
lookup_gop.value_ptr.* = nlist_index;
|
||||
const global_name_off = try macho_file.strings.insert(gpa, sym_name);
|
||||
const gop = try macho_file.getOrCreateGlobal(global_name_off);
|
||||
try self.symbols.append(gpa, gop.index);
|
||||
_ = try macho_file.resolver.getOrPut(gpa, .{
|
||||
.index = nlist_index,
|
||||
.file = self.index,
|
||||
}, macho_file);
|
||||
try self.globals.append(gpa, nlist_index);
|
||||
}
|
||||
return lookup_gop.value_ptr.*;
|
||||
}
|
||||
@ -1420,10 +1404,10 @@ pub fn getOrCreateMetadataForDecl(
|
||||
const gop = try self.decls.getOrPut(gpa, decl_index);
|
||||
if (!gop.found_existing) {
|
||||
const any_non_single_threaded = macho_file.base.comp.config.any_non_single_threaded;
|
||||
const sym_index = try self.addAtom(macho_file);
|
||||
const sym_index = try self.createAtomForDecl(gpa, macho_file);
|
||||
const mod = macho_file.base.comp.module.?;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const sym = &self.symbols.items[sym_index];
|
||||
if (decl.getOwnedVariable(mod)) |variable| {
|
||||
if (variable.is_threadlocal and any_non_single_threaded) {
|
||||
sym.flags.tlv = true;
|
||||
@ -1463,8 +1447,8 @@ pub fn getOrCreateMetadataForLazySymbol(
|
||||
};
|
||||
switch (metadata.state.*) {
|
||||
.unused => {
|
||||
const symbol_index = try self.addAtom(macho_file);
|
||||
const sym = macho_file.getSymbol(symbol_index);
|
||||
const symbol_index = try self.createAtomForDecl(gpa, macho_file);
|
||||
const sym = &self.symbols.items[symbol_index];
|
||||
sym.flags.needs_zig_got = true;
|
||||
metadata.symbol_index.* = symbol_index;
|
||||
},
|
||||
@ -1478,6 +1462,130 @@ pub fn getOrCreateMetadataForLazySymbol(
|
||||
return symbol_index;
|
||||
}
|
||||
|
||||
fn addAtom(self: *ZigObject, allocator: Allocator) !Atom.Index {
|
||||
const atom_index: Atom.Index = @intCast(self.atoms.items.len);
|
||||
const atom = try self.atoms.addOne(allocator);
|
||||
atom.* = .{
|
||||
.file = self.index,
|
||||
.atom_index = atom_index,
|
||||
.extra = try self.addAtomExtra(allocator, .{}),
|
||||
};
|
||||
return atom_index;
|
||||
}
|
||||
|
||||
pub fn getAtom(self: *ZigObject, atom_index: Atom.Index) ?*Atom {
|
||||
if (atom_index == 0) return null;
|
||||
assert(atom_index < self.atoms.items.len);
|
||||
return &self.atoms.items[atom_index];
|
||||
}
|
||||
|
||||
pub fn getAtoms(self: *ZigObject) []const Atom.Index {
|
||||
return self.atoms_indexes.items;
|
||||
}
|
||||
|
||||
fn addAtomExtra(self: *ZigObject, allocator: Allocator, extra: Atom.Extra) !u32 {
|
||||
const fields = @typeInfo(Atom.Extra).Struct.fields;
|
||||
try self.atoms_extra.ensureUnusedCapacity(allocator, fields.len);
|
||||
return self.addAtomExtraAssumeCapacity(extra);
|
||||
}
|
||||
|
||||
fn addAtomExtraAssumeCapacity(self: *ZigObject, extra: Atom.Extra) u32 {
|
||||
const index = @as(u32, @intCast(self.atoms_extra.items.len));
|
||||
const fields = @typeInfo(Atom.Extra).Struct.fields;
|
||||
inline for (fields) |field| {
|
||||
self.atoms_extra.appendAssumeCapacity(switch (field.type) {
|
||||
u32 => @field(extra, field.name),
|
||||
else => @compileError("bad field type"),
|
||||
});
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
pub fn getAtomExtra(self: ZigObject, index: u32) Atom.Extra {
|
||||
const fields = @typeInfo(Atom.Extra).Struct.fields;
|
||||
var i: usize = index;
|
||||
var result: Atom.Extra = undefined;
|
||||
inline for (fields) |field| {
|
||||
@field(result, field.name) = switch (field.type) {
|
||||
u32 => self.atoms_extra.items[i],
|
||||
else => @compileError("bad field type"),
|
||||
};
|
||||
i += 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn setAtomExtra(self: *ZigObject, index: u32, extra: Atom.Extra) void {
|
||||
assert(index > 0);
|
||||
const fields = @typeInfo(Atom.Extra).Struct.fields;
|
||||
inline for (fields, 0..) |field, i| {
|
||||
self.atoms_extra.items[index + i] = switch (field.type) {
|
||||
u32 => @field(extra, field.name),
|
||||
else => @compileError("bad field type"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn addSymbol(self: *ZigObject, allocator: Allocator) !Symbol.Index {
|
||||
try self.symbols.ensureUnusedCapacity(allocator, 1);
|
||||
return self.addSymbolAssumeCapacity();
|
||||
}
|
||||
|
||||
fn addSymbolAssumeCapacity(self: *ZigObject) Symbol.Index {
|
||||
const index: Symbol.Index = @intCast(self.symbols.items.len);
|
||||
const symbol = self.symbols.addOneAssumeCapacity();
|
||||
symbol.* = .{ .file = self.index };
|
||||
return index;
|
||||
}
|
||||
|
||||
pub fn getSymbolRef(self: ZigObject, index: Symbol.Index, macho_file: *MachO) MachO.Ref {
|
||||
const global_index = self.globals.items[index];
|
||||
if (macho_file.resolver.get(global_index)) |ref| return ref;
|
||||
return .{ .index = index, .file = self.index };
|
||||
}
|
||||
|
||||
pub fn addSymbolExtra(self: *ZigObject, allocator: Allocator, extra: Symbol.Extra) !u32 {
|
||||
const fields = @typeInfo(Symbol.Extra).Struct.fields;
|
||||
try self.symbols_extra.ensureUnusedCapacity(allocator, fields.len);
|
||||
return self.addSymbolExtraAssumeCapacity(extra);
|
||||
}
|
||||
|
||||
fn addSymbolExtraAssumeCapacity(self: *ZigObject, extra: Symbol.Extra) u32 {
|
||||
const index = @as(u32, @intCast(self.symbols_extra.items.len));
|
||||
const fields = @typeInfo(Symbol.Extra).Struct.fields;
|
||||
inline for (fields) |field| {
|
||||
self.symbols_extra.appendAssumeCapacity(switch (field.type) {
|
||||
u32 => @field(extra, field.name),
|
||||
else => @compileError("bad field type"),
|
||||
});
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
pub fn getSymbolExtra(self: ZigObject, index: u32) Symbol.Extra {
|
||||
const fields = @typeInfo(Symbol.Extra).Struct.fields;
|
||||
var i: usize = index;
|
||||
var result: Symbol.Extra = undefined;
|
||||
inline for (fields) |field| {
|
||||
@field(result, field.name) = switch (field.type) {
|
||||
u32 => self.symbols_extra.items[i],
|
||||
else => @compileError("bad field type"),
|
||||
};
|
||||
i += 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn setSymbolExtra(self: *ZigObject, index: u32, extra: Symbol.Extra) void {
|
||||
const fields = @typeInfo(Symbol.Extra).Struct.fields;
|
||||
inline for (fields, 0..) |field, i| {
|
||||
self.symbols_extra.items[index + i] = switch (field.type) {
|
||||
u32 => @field(extra, field.name),
|
||||
else => @compileError("bad field type"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn asFile(self: *ZigObject) File {
|
||||
return .{ .zig_object = self };
|
||||
}
|
||||
@ -1503,9 +1611,16 @@ fn formatSymtab(
|
||||
_ = unused_fmt_string;
|
||||
_ = options;
|
||||
try writer.writeAll(" symbols\n");
|
||||
for (ctx.self.symbols.items) |index| {
|
||||
const sym = ctx.macho_file.getSymbol(index);
|
||||
try writer.print(" {}\n", .{sym.fmt(ctx.macho_file)});
|
||||
const self = ctx.self;
|
||||
const macho_file = ctx.macho_file;
|
||||
for (self.symbols.items, 0) |sym, i| {
|
||||
const ref = self.getSymbolRef(@intCast(i), macho_file);
|
||||
if (ref.getFile(macho_file) == null) {
|
||||
// TODO any better way of handling this?
|
||||
try writer.print(" {s} : unclaimed\n", .{sym.getName(macho_file)});
|
||||
} else {
|
||||
try writer.print(" {}\n", .{ref.getSymbol(macho_file).?.fmt(macho_file)});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1524,10 +1639,12 @@ fn formatAtoms(
|
||||
) !void {
|
||||
_ = unused_fmt_string;
|
||||
_ = options;
|
||||
const self = ctx.self;
|
||||
const macho_file = ctx.macho_file;
|
||||
try writer.writeAll(" atoms\n");
|
||||
for (ctx.self.atoms.items) |atom_index| {
|
||||
const atom = ctx.macho_file.getAtom(atom_index) orelse continue;
|
||||
try writer.print(" {}\n", .{atom.fmt(ctx.macho_file)});
|
||||
for (self.getAtoms()) |atom_index| {
|
||||
const atom = self.getAtom(atom_index) orelse continue;
|
||||
try writer.print(" {}\n", .{atom.fmt(macho_file)});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user