Commit bd9d8bd462
Changed files (4)
src
src/link/MachO/Atom.zig
@@ -55,7 +55,7 @@ pub fn getData(self: Atom, macho_file: *MachO) []const u8 {
pub fn getRelocs(self: Atom, macho_file: *MachO) []const Relocation {
return switch (self.getFile(macho_file)) {
- .zig_object => @panic("TODO Atom.getRelocs"),
+ .zig_object => |x| x.getAtomRelocs(self),
.object => |x| x.getAtomRelocs(self),
else => unreachable,
};
@@ -890,8 +890,8 @@ pub const Flags = packed struct {
};
pub const Loc = struct {
- pos: usize = 0,
- len: usize = 0,
+ pos: u32 = 0,
+ len: u32 = 0,
};
pub const Alignment = @import("../../InternPool.zig").Alignment;
src/link/MachO/Object.zig
@@ -608,7 +608,7 @@ fn initRelocs(self: *Object, macho_file: *MachO) !void {
for (slice.items(.header), slice.items(.relocs), slice.items(.subsections)) |sect, relocs, subsections| {
if (sect.isZerofill()) continue;
- var next_reloc: usize = 0;
+ var next_reloc: u32 = 0;
for (subsections.items) |subsection| {
const atom = macho_file.getAtom(subsection.atom).?;
if (!atom.flags.alive) continue;
@@ -1767,7 +1767,7 @@ const Subsection = struct {
off: u64,
};
-const Nlist = struct {
+pub const Nlist = struct {
nlist: macho.nlist_64,
size: u64,
atom: Atom.Index,
src/link/MachO/Symbol.zig
@@ -19,7 +19,7 @@ out_n_sect: u16 = 0,
/// Index of the source nlist this symbol references.
/// Use `getNlist` to pull the nlist from the relevant file.
-nlist_idx: u32 = 0,
+nlist_idx: Index = 0,
/// Misc flags for the symbol packaged as packed struct for compression.
flags: Flags = .{},
@@ -352,6 +352,10 @@ pub const Flags = packed struct {
needs_got: bool = false,
has_got: bool = false,
+ /// Whether the symbol contains __got_zig indirection.
+ needs_zig_got: bool = false,
+ has_zig_got: bool = false,
+
/// Whether the symbols contains __stubs indirection.
stubs: bool = false,
@@ -386,5 +390,6 @@ const std = @import("std");
const Atom = @import("Atom.zig");
const File = @import("file.zig").File;
const MachO = @import("../MachO.zig");
+const Nlist = Object.Nlist;
const Object = @import("Object.zig");
const Symbol = @This();
src/link/MachO/ZigObject.zig
@@ -7,6 +7,12 @@ symtab: std.MultiArrayList(Nlist) = .{},
symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
atoms: std.ArrayListUnmanaged(Atom.Index) = .{},
+/// Table of tracked Decls.
+decls: DeclTable = .{},
+
+/// A table of relocations.
+relocs: RelocationTable = .{},
+
output_symtab_ctx: MachO.SymtabCtx = .{},
pub fn init(self: *ZigObject, macho_file: *MachO) !void {
@@ -20,6 +26,19 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
self.symtab.deinit(allocator);
self.symbols.deinit(allocator);
self.atoms.deinit(allocator);
+
+ {
+ var it = self.decls.iterator();
+ while (it.next()) |entry| {
+ entry.value_ptr.exports.deinit(allocator);
+ }
+ self.decls.deinit(allocator);
+ }
+
+ for (self.relocs.items) |*list| {
+ list.deinit(allocator);
+ }
+ self.relocs.deinit(allocator);
}
fn addNlist(self: *ZigObject, allocator: Allocator) !Symbol.Index {
@@ -33,6 +52,38 @@ 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;
+
+ const symbol = macho_file.getSymbol(symbol_index);
+ symbol.file = self.index;
+ symbol.atom = atom_index;
+
+ self.symtab.items(.atom)[nlist_index] = atom_index;
+ symbol.nlist_idx = nlist_index;
+
+ const relocs_index = @as(u32, @intCast(self.relocs.items.len));
+ const relocs = try self.relocs.addOne(gpa);
+ relocs.* = .{};
+ atom.relocs = .{ .pos = relocs_index, .len = 0 };
+
+ return symbol_index;
+}
+
+pub fn getAtomRelocs(self: *ZigObject, atom: Atom) []const Relocation {
+ const relocs = self.relocs.items[atom.relocs.pos];
+ return relocs.items[0..atom.relocs.len];
+}
+
pub fn resolveSymbols(self: *ZigObject, macho_file: *MachO) void {
_ = self;
_ = macho_file;
@@ -216,54 +267,35 @@ pub fn updateDecl(
return;
}
- // const is_threadlocal = if (decl.val.getVariable(mod)) |variable|
- // variable.is_threadlocal and comp.config.any_non_single_threaded
- // else
- // false;
- // if (is_threadlocal) return self.updateThreadlocalVariable(mod, decl_index);
-
- // const atom_index = try self.getOrCreateAtomForDecl(decl_index);
- // const sym_index = self.getAtom(atom_index).getSymbolIndex().?;
- // Atom.freeRelocations(self, atom_index);
-
- // const comp = macho_file.base.comp;
- // const gpa = comp.gpa;
-
- // var code_buffer = std.ArrayList(u8).init(gpa);
- // defer code_buffer.deinit();
-
- // var decl_state: ?Dwarf.DeclState = if (self.d_sym) |*d_sym|
- // try d_sym.dwarf.initDeclState(mod, decl_index)
- // else
- // null;
- // defer if (decl_state) |*ds| ds.deinit();
-
- // const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
- // const res = if (decl_state) |*ds|
- // try codegen.generateSymbol(&self.base, decl.srcLoc(mod), .{
- // .ty = decl.ty,
- // .val = decl_val,
- // }, &code_buffer, .{
- // .dwarf = ds,
- // }, .{
- // .parent_atom_index = sym_index,
- // })
- // else
- // try codegen.generateSymbol(&self.base, decl.srcLoc(mod), .{
- // .ty = decl.ty,
- // .val = decl_val,
- // }, &code_buffer, .none, .{
- // .parent_atom_index = sym_index,
- // });
-
- // const code = switch (res) {
- // .ok => code_buffer.items,
- // .fail => |em| {
- // decl.analysis = .codegen_failure;
- // try mod.failed_decls.put(mod.gpa, decl_index, em);
- // return;
- // },
- // };
+ const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index);
+ // TODO: free relocs if any
+
+ const gpa = macho_file.base.comp.gpa;
+ var code_buffer = std.ArrayList(u8).init(gpa);
+ defer code_buffer.deinit();
+
+ var decl_state: ?Dwarf.DeclState = null; // TODO: Dwarf
+ defer if (decl_state) |*ds| ds.deinit();
+
+ const decl_val = if (decl.val.getVariable(mod)) |variable| Value.fromInterned(variable.init) else decl.val;
+ const dio: codegen.DebugInfoOutput = if (decl_state) |*ds| .{ .dwarf = ds } else .none;
+ const res =
+ try codegen.generateSymbol(&macho_file.base, decl.srcLoc(mod), .{
+ .ty = decl.ty,
+ .val = decl_val,
+ }, &code_buffer, dio, .{
+ .parent_atom_index = sym_index,
+ });
+
+ const code = switch (res) {
+ .ok => code_buffer.items,
+ .fail => |em| {
+ decl.analysis = .codegen_failure;
+ try mod.failed_decls.put(mod.gpa, decl_index, em);
+ return;
+ },
+ };
+ _ = code;
// const addr = try self.updateDeclCode(decl_index, code);
// if (decl_state) |*ds| {
@@ -342,6 +374,32 @@ pub fn getGlobalSymbol(self: *ZigObject, macho_file: *MachO, name: []const u8, l
@panic("TODO getGlobalSymbol");
}
+pub fn getOrCreateMetadataForDecl(
+ self: *ZigObject,
+ macho_file: *MachO,
+ decl_index: InternPool.DeclIndex,
+) !Symbol.Index {
+ const gpa = macho_file.base.comp.gpa;
+ 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 mod = macho_file.base.comp.module.?;
+ const decl = mod.declPtr(decl_index);
+ const sym = macho_file.getSymbol(self.symbols.items[sym_index]);
+ if (decl.getOwnedVariable(mod)) |variable| {
+ if (variable.is_threadlocal and any_non_single_threaded) {
+ sym.flags.tlv = true;
+ }
+ }
+ if (!sym.flags.tlv) {
+ sym.flags.needs_zig_got = true;
+ }
+ gop.value_ptr.* = .{ .symbol_index = sym_index };
+ }
+ return gop.value_ptr.symbol_index;
+}
+
pub fn asFile(self: *ZigObject) File {
return .{ .zig_object = self };
}
@@ -395,11 +453,23 @@ fn formatAtoms(
}
}
-const Nlist = struct {
- nlist: macho.nlist_64,
- size: u64,
- atom: Atom.Index,
+const DeclMetadata = struct {
+ symbol_index: Symbol.Index,
+ /// A list of all exports aliases of this Decl.
+ exports: std.ArrayListUnmanaged(Symbol.Index) = .{},
+
+ fn @"export"(m: DeclMetadata, zig_object: *ZigObject, macho_file: *MachO, name: []const u8) ?*u32 {
+ for (m.exports.items) |*exp| {
+ const nlist = zig_object.symtab.items(.nlist)[exp.*];
+ const exp_name = macho_file.strings.getAssumeExists(nlist.n_strx);
+ if (mem.eql(u8, name, exp_name)) return exp;
+ }
+ return null;
+ }
};
+const DeclTable = std.AutoHashMapUnmanaged(InternPool.DeclIndex, DeclMetadata);
+
+const RelocationTable = std.ArrayListUnmanaged(std.ArrayListUnmanaged(Relocation));
const assert = std.debug.assert;
const builtin = @import("builtin");
@@ -420,8 +490,10 @@ const File = @import("file.zig").File;
const InternPool = @import("../../InternPool.zig");
const Liveness = @import("../../Liveness.zig");
const MachO = @import("../MachO.zig");
+const Nlist = Object.Nlist;
const Module = @import("../../Module.zig");
const Object = @import("Object.zig");
+const Relocation = @import("Relocation.zig");
const Symbol = @import("Symbol.zig");
const StringTable = @import("../StringTable.zig");
const Type = @import("../../type.zig").Type;