Commit 7f74b3562d

Jakub Konka <kubkon@jakubkonka.com>
2023-08-26 22:05:42
macho: unify creating atoms
1 parent ef0d35e
Changed files (5)
src/link/MachO/Atom.zig
@@ -4,13 +4,13 @@
 /// a stub trampoline, it can be found in the linkers `locals` arraylist.
 /// If this field is 0 and file is 0, it means the codegen size = 0 and there is no symbol or
 /// offset table entry.
-sym_index: u32,
+sym_index: u32 = 0,
 
 /// 0 means an Atom is a synthetic Atom such as a GOT cell defined by the linker.
 /// Otherwise, it is the index into appropriate object file (indexing from 1).
 /// Prefer using `getFile()` helper to get the file index out rather than using
 /// the field directly.
-file: u32,
+file: u32 = 0,
 
 /// If this Atom is not a synthetic Atom, i.e., references a subsection in an
 /// Object file, `inner_sym_index` and `inner_nsyms_trailing` tell where and if
@@ -18,22 +18,22 @@ file: u32,
 /// address range. These could for example be an alias symbol which can be used
 /// internally by the relocation records, or if the Object file couldn't be split
 /// into subsections, this Atom may encompass an entire input section.
-inner_sym_index: u32,
-inner_nsyms_trailing: u32,
+inner_sym_index: u32 = 0,
+inner_nsyms_trailing: u32 = 0,
 
 /// Size and alignment of this atom
 /// Unlike in Elf, we need to store the size of this symbol as part of
 /// the atom since macho.nlist_64 lacks this information.
-size: u64,
+size: u64 = 0,
 
 /// Alignment of this atom as a power of 2.
 /// For instance, aligmment of 0 should be read as 2^0 = 1 byte aligned.
-alignment: u32,
+alignment: u32 = 0,
 
 /// Points to the previous and next neighbours
 /// TODO use the same trick as with symbols: reserve index 0 as null atom
-next_index: ?Index,
-prev_index: ?Index,
+next_index: ?Index = null,
+prev_index: ?Index = null,
 
 pub const Index = u32;
 
src/link/MachO/Object.zig
@@ -573,7 +573,7 @@ fn createAtomFromSubsection(
     out_sect_id: u8,
 ) !Atom.Index {
     const gpa = zld.gpa;
-    const atom_index = try zld.createEmptyAtom(sym_index, size, alignment);
+    const atom_index = try zld.createAtom(sym_index, .{ .size = size, .alignment = alignment });
     const atom = zld.getAtomPtr(atom_index);
     atom.inner_sym_index = inner_sym_index;
     atom.inner_nsyms_trailing = inner_nsyms_trailing;
src/link/MachO/thunks.zig
@@ -342,7 +342,7 @@ fn isReachable(
 
 fn createThunkAtom(zld: *Zld) !Atom.Index {
     const sym_index = try zld.allocateSymbol();
-    const atom_index = try zld.createEmptyAtom(sym_index, @sizeOf(u32) * 3, 2);
+    const atom_index = try zld.createAtom(sym_index, .{ .size = @sizeOf(u32) * 3, .alignment = 2 });
     const sym = zld.getSymbolPtr(.{ .sym_index = sym_index });
     sym.n_type = macho.N_SECT;
     sym.n_sect = zld.text_section_index.? + 1;
src/link/MachO/zld.zig
@@ -112,32 +112,26 @@ pub const Zld = struct {
         self.sections.set(sym.n_sect - 1, section);
     }
 
-    pub fn createEmptyAtom(self: *Zld, sym_index: u32, size: u64, alignment: u32) !Atom.Index {
+    const CreateAtomOpts = struct {
+        size: u64 = 0,
+        alignment: u32 = 0,
+    };
+
+    pub fn createAtom(self: *Zld, sym_index: u32, opts: CreateAtomOpts) !Atom.Index {
         const gpa = self.gpa;
         const index = @as(Atom.Index, @intCast(self.atoms.items.len));
         const atom = try self.atoms.addOne(gpa);
-        atom.* = .{
-            .sym_index = 0,
-            .inner_sym_index = 0,
-            .inner_nsyms_trailing = 0,
-            .file = 0,
-            .size = 0,
-            .alignment = 0,
-            .prev_index = null,
-            .next_index = null,
-        };
+        atom.* = .{};
         atom.sym_index = sym_index;
-        atom.size = size;
-        atom.alignment = alignment;
-
+        atom.size = opts.size;
+        atom.alignment = opts.alignment;
         log.debug("creating ATOM(%{d}) at index {d}", .{ sym_index, index });
-
         return index;
     }
 
     fn createDyldPrivateAtom(self: *Zld) !void {
         const sym_index = try self.allocateSymbol();
-        const atom_index = try self.createEmptyAtom(sym_index, @sizeOf(u64), 3);
+        const atom_index = try self.createAtom(sym_index, .{ .size = @sizeOf(u64), .alignment = 3 });
         const sym = self.getSymbolPtr(.{ .sym_index = sym_index });
         sym.n_type = macho.N_SECT;
 
@@ -176,7 +170,10 @@ pub const Zld = struct {
                 .n_value = 0,
             };
 
-            const atom_index = try self.createEmptyAtom(global.sym_index, size, alignment);
+            const atom_index = try self.createAtom(global.sym_index, .{
+                .size = size,
+                .alignment = alignment,
+            });
             const atom = self.getAtomPtr(atom_index);
             atom.file = global.file;
 
src/link/MachO.zig
@@ -1410,30 +1410,29 @@ pub fn allocateSpecialSymbols(self: anytype) !void {
     }
 }
 
-pub fn createAtom(self: *MachO) !Atom.Index {
+const CreateAtomOpts = struct {
+    size: u64 = 0,
+    alignment: u32 = 0,
+};
+
+pub fn createAtom(self: *MachO, sym_index: u32, opts: CreateAtomOpts) !Atom.Index {
     const gpa = self.base.allocator;
-    const atom_index = @as(Atom.Index, @intCast(self.atoms.items.len));
+    const index = @as(Atom.Index, @intCast(self.atoms.items.len));
     const atom = try self.atoms.addOne(gpa);
-    const sym_index = try self.allocateSymbol();
-    try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom_index);
-    atom.* = .{
-        .sym_index = sym_index,
-        .inner_sym_index = 0,
-        .inner_nsyms_trailing = 0,
-        .file = 0,
-        .size = 0,
-        .alignment = 0,
-        .prev_index = null,
-        .next_index = null,
-    };
-    log.debug("creating ATOM(%{d}) at index {d}", .{ sym_index, atom_index });
-    return atom_index;
+    atom.* = .{};
+    atom.sym_index = sym_index;
+    atom.size = opts.size;
+    atom.alignment = opts.alignment;
+    log.debug("creating ATOM(%{d}) at index {d}", .{ sym_index, index });
+    return index;
 }
 
 fn createDyldPrivateAtom(self: *MachO) !void {
     if (self.dyld_private_atom_index != null) return;
 
-    const atom_index = try self.createAtom();
+    const sym_index = try self.allocateSymbol();
+    const atom_index = try self.createAtom(sym_index, .{});
+    try self.atom_by_index_table.putNoClobber(self.base.allocator, sym_index, atom_index);
     const atom = self.getAtomPtr(atom_index);
     atom.size = @sizeOf(u64);
 
@@ -1452,7 +1451,9 @@ fn createThreadLocalDescriptorAtom(self: *MachO, sym_name: []const u8, target: S
     const gpa = self.base.allocator;
     const size = 3 * @sizeOf(u64);
     const required_alignment: u32 = 1;
-    const atom_index = try self.createAtom();
+    const sym_index = try self.allocateSymbol();
+    const atom_index = try self.createAtom(sym_index, .{});
+    try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom_index);
     self.getAtomPtr(atom_index).size = size;
 
     const sym = self.getAtom(atom_index).getSymbolPtr(self);
@@ -1936,7 +1937,9 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu
 
     log.debug("allocating symbol indexes for {s}", .{name});
 
-    const atom_index = try self.createAtom();
+    const sym_index = try self.allocateSymbol();
+    const atom_index = try self.createAtom(sym_index, .{});
+    try self.atom_by_index_table.putNoClobber(gpa, sym_index, atom_index);
 
     const res = try codegen.generateSymbol(&self.base, decl.srcLoc(mod), typed_value, &code_buffer, .none, .{
         .parent_atom_index = self.getAtom(atom_index).getSymbolIndex().?,
@@ -2138,7 +2141,11 @@ pub fn getOrCreateAtomForLazySymbol(self: *MachO, sym: File.LazySymbol) !Atom.In
         },
     };
     switch (metadata.state.*) {
-        .unused => metadata.atom.* = try self.createAtom(),
+        .unused => {
+            const sym_index = try self.allocateSymbol();
+            metadata.atom.* = try self.createAtom(sym_index, .{});
+            try self.atom_by_index_table.putNoClobber(self.base.allocator, sym_index, metadata.atom.*);
+        },
         .pending_flush => return metadata.atom.*,
         .flushed => {},
     }
@@ -2250,8 +2257,11 @@ fn updateThreadlocalVariable(self: *MachO, module: *Module, decl_index: Module.D
 pub fn getOrCreateAtomForDecl(self: *MachO, decl_index: Module.Decl.Index) !Atom.Index {
     const gop = try self.decls.getOrPut(self.base.allocator, decl_index);
     if (!gop.found_existing) {
+        const sym_index = try self.allocateSymbol();
+        const atom_index = try self.createAtom(sym_index, .{});
+        try self.atom_by_index_table.putNoClobber(self.base.allocator, sym_index, atom_index);
         gop.value_ptr.* = .{
-            .atom = try self.createAtom(),
+            .atom = atom_index,
             .section = self.getDeclOutputSection(decl_index),
             .exports = .{},
         };