From 7f74b3562deaa0dedfc2945a702fe82dbd103aa2 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 26 Aug 2023 22:05:42 +0200 Subject: [PATCH] macho: unify creating atoms --- src/link/MachO.zig | 52 +++++++++++++++++++++++---------------- src/link/MachO/Atom.zig | 16 ++++++------ src/link/MachO/Object.zig | 2 +- src/link/MachO/thunks.zig | 2 +- src/link/MachO/zld.zig | 31 +++++++++++------------ 5 files changed, 55 insertions(+), 48 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 6b9feeb4a4..ac07e5c687 100644 --- a/src/link/MachO.zig +++ b/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 = .{}, }; diff --git a/src/link/MachO/Atom.zig b/src/link/MachO/Atom.zig index fe118e0e3a..411c42c4dd 100644 --- a/src/link/MachO/Atom.zig +++ b/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; diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index 2eee9f5787..5042fe9849 100644 --- a/src/link/MachO/Object.zig +++ b/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; diff --git a/src/link/MachO/thunks.zig b/src/link/MachO/thunks.zig index da02074abe..c5debcc1fa 100644 --- a/src/link/MachO/thunks.zig +++ b/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; diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig index a9488c81b6..b9d2d34712 100644 --- a/src/link/MachO/zld.zig +++ b/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;