Commit 9509fadbe3

Jakub Konka <kubkon@jakubkonka.com>
2024-01-17 07:17:58
macho: split symbol.flags.got into needs_got and has_got
1 parent b669113
src/link/MachO/Atom.zig
@@ -204,7 +204,7 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void {
                     (symbol.flags.@"export" and (symbol.flags.weak or symbol.flags.interposable)) or
                     macho_file.getTarget().cpu.arch == .aarch64) // TODO relax on arm64
                 {
-                    symbol.flags.got = true;
+                    symbol.flags.needs_got = true;
                     if (symbol.flags.weak) {
                         macho_file.binds_to_weak = true;
                     }
@@ -212,7 +212,7 @@ pub fn scanRelocs(self: Atom, macho_file: *MachO) !void {
             },
 
             .got => {
-                rel.getTargetSymbol(macho_file).flags.got = true;
+                rel.getTargetSymbol(macho_file).flags.needs_got = true;
             },
 
             .tlv,
@@ -452,7 +452,7 @@ fn resolveRelocInner(
             assert(rel.tag == .@"extern");
             assert(rel.meta.length == 2);
             assert(rel.meta.pcrel);
-            if (rel.getTargetSymbol(macho_file).flags.got) {
+            if (rel.getTargetSymbol(macho_file).flags.has_got) {
                 try writer.writeInt(i32, @intCast(G + A - P), .little);
             } else {
                 try x86_64.relaxGotLoad(code[rel_offset - 3 ..]);
src/link/MachO/Object.zig
@@ -1105,10 +1105,10 @@ pub fn scanRelocs(self: Object, macho_file: *MachO) !void {
         if (!rec.alive) continue;
         if (rec.getFde(macho_file)) |fde| {
             if (fde.getCie(macho_file).getPersonality(macho_file)) |sym| {
-                sym.flags.got = true;
+                sym.flags.needs_got = true;
             }
         } else if (rec.getPersonality(macho_file)) |sym| {
-            sym.flags.got = true;
+            sym.flags.needs_got = true;
         }
     }
 }
src/link/MachO/Symbol.zig
@@ -118,7 +118,7 @@ pub fn getAddress(symbol: Symbol, opts: struct {
 }
 
 pub fn getGotAddress(symbol: Symbol, macho_file: *MachO) u64 {
-    if (!symbol.flags.got) return 0;
+    if (!symbol.flags.has_got) return 0;
     const extra = symbol.getExtra(macho_file).?;
     return macho_file.got.getAddress(extra.got, macho_file);
 }
@@ -349,7 +349,8 @@ pub const Flags = packed struct {
     output_symtab: bool = false,
 
     /// Whether the symbol contains __got indirection.
-    got: bool = false,
+    needs_got: bool = false,
+    has_got: bool = false,
 
     /// Whether the symbols contains __stubs indirection.
     stubs: bool = false,
src/link/MachO/synthetic.zig
@@ -13,6 +13,7 @@ pub const GotSection = struct {
         const entry = try got.symbols.addOne(gpa);
         entry.* = sym_index;
         const symbol = macho_file.getSymbol(sym_index);
+        symbol.flags.has_got = true;
         try symbol.addExtra(.{ .got = index }, macho_file);
     }
 
src/link/MachO/ZigObject.zig
@@ -197,11 +197,88 @@ pub fn updateDecl(
     mod: *Module,
     decl_index: InternPool.DeclIndex,
 ) link.File.UpdateDeclError!void {
-    _ = self;
-    _ = macho_file;
-    _ = mod;
-    _ = decl_index;
-    @panic("TODO updateDecl");
+    const tracy = trace(@src());
+    defer tracy.end();
+
+    const decl = mod.declPtr(decl_index);
+
+    if (decl.val.getExternFunc(mod)) |_| {
+        return;
+    }
+
+    if (decl.isExtern(mod)) {
+        // Extern variable gets a __got entry only
+        const variable = decl.getOwnedVariable(mod).?;
+        const name = mod.intern_pool.stringToSlice(decl.name);
+        const lib_name = mod.intern_pool.stringToSliceUnwrap(variable.lib_name);
+        const index = try self.getGlobalSymbol(macho_file, name, lib_name);
+        macho_file.getSymbol(index).flags.needs_got = true;
+        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 addr = try self.updateDeclCode(decl_index, code);
+
+    // if (decl_state) |*ds| {
+    //     try self.d_sym.?.dwarf.commitDeclState(
+    //         mod,
+    //         decl_index,
+    //         addr,
+    //         self.getAtom(atom_index).size,
+    //         ds,
+    //     );
+    // }
+
+    // // Since we updated the vaddr and the size, each corresponding export symbol also
+    // // needs to be updated.
+    // try self.updateExports(mod, .{ .decl_index = decl_index }, mod.getDeclExports(decl_index));
 }
 
 pub fn lowerUnnamedConst(
src/link/MachO.zig
@@ -1601,18 +1601,18 @@ fn scanRelocs(self: *MachO) !void {
 
     if (self.dyld_stub_binder_index) |index| {
         const sym = self.getSymbol(index);
-        if (sym.getFile(self) != null) sym.flags.got = true;
+        if (sym.getFile(self) != null) sym.flags.needs_got = true;
     }
 
     if (self.objc_msg_send_index) |index| {
         const sym = self.getSymbol(index);
         if (sym.getFile(self) != null)
-            sym.flags.got = true; // TODO is it always needed, or only if we are synthesising fast stubs?
+            sym.flags.needs_got = true; // TODO is it always needed, or only if we are synthesising fast stubs?
     }
 
     for (self.symbols.items, 0..) |*symbol, i| {
         const index = @as(Symbol.Index, @intCast(i));
-        if (symbol.flags.got) {
+        if (symbol.flags.needs_got) {
             log.debug("'{s}' needs GOT", .{symbol.getName(self)});
             try self.got.addSymbol(index, self);
         }