From 103c16c87955facd373bd20435100fa7eb322349 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 15 Jul 2024 18:26:05 +0200 Subject: macho: clean up atom+symbol creation logic in ZigObject --- src/link/MachO/InternalObject.zig | 22 +++---- src/link/MachO/ZigObject.zig | 123 +++++++++++++++++++++----------------- 2 files changed, 79 insertions(+), 66 deletions(-) (limited to 'src') diff --git a/src/link/MachO/InternalObject.zig b/src/link/MachO/InternalObject.zig index 9578bc84ec..55d7be00fb 100644 --- a/src/link/MachO/InternalObject.zig +++ b/src/link/MachO/InternalObject.zig @@ -52,8 +52,8 @@ pub fn init(self: *InternalObject, allocator: Allocator) !void { } pub fn initSymbols(self: *InternalObject, macho_file: *MachO) !void { - const createSymbol = struct { - fn createSymbol(obj: *InternalObject, name: u32, args: struct { + const newSymbolAssumeCapacity = struct { + fn newSymbolAssumeCapacity(obj: *InternalObject, name: u32, args: struct { type: u8 = macho.N_UNDF | macho.N_EXT, desc: u16 = 0, }) Symbol.Index { @@ -78,7 +78,7 @@ pub fn initSymbols(self: *InternalObject, macho_file: *MachO) !void { symbol.nlist_idx = nlist_idx; return index; } - }.createSymbol; + }.newSymbolAssumeCapacity; const gpa = macho_file.base.comp.gpa; var nsyms = macho_file.base.comp.force_undefined_symbols.keys().len; @@ -102,28 +102,28 @@ pub fn initSymbols(self: *InternalObject, macho_file: *MachO) !void { try self.force_undefined.ensureTotalCapacityPrecise(gpa, macho_file.base.comp.force_undefined_symbols.keys().len); for (macho_file.base.comp.force_undefined_symbols.keys()) |name| { - self.force_undefined.addOneAssumeCapacity().* = createSymbol(self, try self.addString(gpa, name), .{}); + self.force_undefined.addOneAssumeCapacity().* = newSymbolAssumeCapacity(self, try self.addString(gpa, name), .{}); } - self.dyld_stub_binder_index = createSymbol(self, try self.addString(gpa, "dyld_stub_binder"), .{}); - self.objc_msg_send_index = createSymbol(self, try self.addString(gpa, "_objc_msgSend"), .{}); + self.dyld_stub_binder_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "dyld_stub_binder"), .{}); + self.objc_msg_send_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_objc_msgSend"), .{}); if (!macho_file.base.isDynLib()) { - self.entry_index = createSymbol(self, try self.addString(gpa, macho_file.entry_name orelse "_main"), .{}); - self.mh_execute_header_index = createSymbol(self, try self.addString(gpa, "__mh_execute_header"), .{ + self.entry_index = newSymbolAssumeCapacity(self, try self.addString(gpa, macho_file.entry_name orelse "_main"), .{}); + self.mh_execute_header_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__mh_execute_header"), .{ .type = macho.N_SECT | macho.N_EXT, .desc = macho.REFERENCED_DYNAMICALLY, }); } else { - self.mh_dylib_header_index = createSymbol(self, try self.addString(gpa, "__mh_dylib_header"), .{ + self.mh_dylib_header_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__mh_dylib_header"), .{ .type = macho.N_SECT | macho.N_EXT, }); } - self.dso_handle_index = createSymbol(self, try self.addString(gpa, "___dso_handle"), .{ + self.dso_handle_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "___dso_handle"), .{ .type = macho.N_SECT | macho.N_EXT, }); - self.dyld_private_index = createSymbol(self, try self.addString(gpa, "dyld_private"), .{ + self.dyld_private_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "dyld_private"), .{ .type = macho.N_SECT, }); } diff --git a/src/link/MachO/ZigObject.zig b/src/link/MachO/ZigObject.zig index b363ab91ed..fdeec186e5 100644 --- a/src/link/MachO/ZigObject.zig +++ b/src/link/MachO/ZigObject.zig @@ -141,34 +141,64 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void { } } -fn addNlist(self: *ZigObject, allocator: Allocator) !Symbol.Index { +fn newSymbol(self: *ZigObject, allocator: Allocator, name: u32, args: struct { + type: u8 = macho.N_UNDF | macho.N_EXT, + desc: u16 = 0, +}) !Symbol.Index { try self.symtab.ensureUnusedCapacity(allocator, 1); - const index = @as(Symbol.Index, @intCast(self.symtab.addOneAssumeCapacity())); - self.symtab.set(index, .{ - .nlist = MachO.null_sym, + try self.symbols.ensureUnusedCapacity(allocator, 1); + try self.symbols_extra.ensureUnusedCapacity(allocator, @sizeOf(Symbol.Extra)); + try self.globals.ensureUnusedCapacity(allocator, 1); + + const index = self.addSymbolAssumeCapacity(); + const symbol = &self.symbols.items[index]; + symbol.name = name; + symbol.extra = self.addSymbolExtraAssumeCapacity(.{}); + + const nlist_idx: u32 = @intCast(self.symtab.addOneAssumeCapacity()); + self.symtab.set(nlist_idx, .{ + .nlist = .{ + .n_strx = name, + .n_type = args.type, + .n_sect = 0, + .n_desc = args.desc, + .n_value = 0, + }, .size = 0, .atom = 0, }); + symbol.nlist_idx = nlist_idx; + + self.globals.appendAssumeCapacity(0); + return 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, .{}); +fn newAtom(self: *ZigObject, allocator: Allocator, name: u32, macho_file: *MachO) !Atom.Index { + try self.atoms.ensureUnusedCapacity(allocator, 1); + try self.atoms_extra.ensureUnusedCapacity(allocator, @sizeOf(Atom.Extra)); + try self.atoms_indexes.ensureUnusedCapacity(allocator, 1); + try self.relocs.ensureUnusedCapacity(allocator, 1); + + const index = self.addAtomAssumeCapacity(); + self.atoms_indexes.appendAssumeCapacity(index); + const atom = self.getAtom(index).?; + atom.name = name; + const relocs_index = @as(u32, @intCast(self.relocs.items.len)); - const relocs = try self.relocs.addOne(allocator); - relocs.* = .{}; - const atom = self.getAtom(atom_index).?; + self.relocs.addOneAssumeCapacity().* = .{}; atom.addExtra(.{ .rel_index = relocs_index, .rel_count = 0 }, macho_file); - try self.globals.append(allocator, 0); - return symbol_index; + + return index; +} + +fn newSymbolWithAtom(self: *ZigObject, allocator: Allocator, name: u32, macho_file: *MachO) !Symbol.Index { + const atom_index = try self.newAtom(allocator, name, macho_file); + const sym_index = try self.newSymbol(allocator, name, .{ .type = macho.N_SECT }); + const sym = &self.symbols.items[sym_index]; + sym.atom_ref = .{ .index = atom_index, .file = self.index }; + self.symtab.items(.atom)[sym.nlist_idx] = atom_index; + return sym_index; } pub fn getAtomData(self: ZigObject, macho_file: *MachO, atom: Atom, buffer: []u8) !void { @@ -1079,27 +1109,19 @@ fn createTlvInitializer( const gpa = macho_file.base.comp.gpa; const sym_name = try std.fmt.allocPrint(gpa, "{s}$tlv$init", .{name}); defer gpa.free(sym_name); + const off = try self.strtab.insert(gpa, sym_name); - const sym_index = try self.createAtomForDecl(gpa, macho_file); + const sym_index = try self.newSymbolWithAtom(gpa, off, macho_file); const sym = &self.symbols.items[sym_index]; const nlist = &self.symtab.items(.nlist)[sym.nlist_idx]; const atom = sym.getAtom(macho_file).?; - sym.out_n_sect = sect_index; atom.out_n_sect = sect_index; - - sym.value = 0; - sym.name = try self.strtab.insert(gpa, sym_name); atom.flags.alive = true; - atom.name = sym.name; - nlist.n_strx = sym.name; - nlist.n_sect = sect_index + 1; - nlist.n_type = macho.N_SECT; - nlist.n_value = 0; - self.symtab.items(.size)[sym.nlist_idx] = code.len; - atom.alignment = alignment; atom.size = code.len; + nlist.n_sect = sect_index + 1; + self.symtab.items(.size)[sym.nlist_idx] = code.len; const slice = macho_file.sections.slice(); const header = slice.items(.header)[sect_index]; @@ -1293,7 +1315,8 @@ fn lowerConst( var code_buffer = std.ArrayList(u8).init(gpa); defer code_buffer.deinit(); - const sym_index = try self.createAtomForDecl(gpa, macho_file); + const name_str_index = try self.strtab.insert(gpa, name); + const sym_index = try self.newSymbolWithAtom(gpa, name_str_index, macho_file); const res = try codegen.generateSymbol(&macho_file.base, pt, src_loc, val, &code_buffer, .{ .none = {}, @@ -1306,19 +1329,14 @@ fn lowerConst( }; 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; const nlist = &self.symtab.items(.nlist)[sym.nlist_idx]; - nlist.n_strx = name_str_index; - nlist.n_type = macho.N_SECT; nlist.n_sect = output_section_index + 1; self.symtab.items(.size)[sym.nlist_idx] = code.len; const atom = sym.getAtom(macho_file).?; atom.flags.alive = true; - atom.name = name_str_index; atom.alignment = required_alignment; atom.size = code.len; atom.out_n_sect = output_section_index; @@ -1327,9 +1345,6 @@ fn lowerConst( // TODO rename and re-audit this method errdefer self.freeDeclMetadata(macho_file, sym_index); - sym.value = 0; - nlist.n_value = 0; - const sect = macho_file.sections.items(.header)[output_section_index]; const file_offset = sect.offset + atom.value; try macho_file.base.file.?.pwriteAll(code, file_offset); @@ -1560,17 +1575,9 @@ pub fn getGlobalSymbol(self: *ZigObject, macho_file: *MachO, name: []const u8, l const off = try self.strtab.insert(gpa, sym_name); const lookup_gop = try self.globals_lookup.getOrPut(gpa, off); if (!lookup_gop.found_existing) { - const sym_index = try self.addSymbol(gpa); + const sym_index = try self.newSymbol(gpa, off, .{}); const sym = &self.symbols.items[sym_index]; - const nlist_index = try self.addNlist(gpa); - const nlist = &self.symtab.items(.nlist)[nlist_index]; - nlist.n_strx = off; - nlist.n_type = macho.N_EXT; - sym.name = off; - sym.nlist_idx = nlist_index; - sym.extra = try self.addSymbolExtra(gpa, .{}); - lookup_gop.value_ptr.* = nlist_index; - try self.globals.append(gpa, 0); + lookup_gop.value_ptr.* = sym.nlist_idx; } return lookup_gop.value_ptr.*; } @@ -1584,10 +1591,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.createAtomForDecl(gpa, macho_file); + const sym_index = try self.newSymbolWithAtom(gpa, 0, macho_file); + const sym = &self.symbols.items[sym_index]; const mod = macho_file.base.comp.module.?; const decl = mod.declPtr(decl_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; @@ -1627,7 +1634,7 @@ pub fn getOrCreateMetadataForLazySymbol( }; switch (metadata.state.*) { .unused => { - const symbol_index = try self.createAtomForDecl(gpa, macho_file); + const symbol_index = try self.newSymbolWithAtom(gpa, 0, macho_file); const sym = &self.symbols.items[symbol_index]; sym.flags.needs_zig_got = true; metadata.symbol_index.* = symbol_index; @@ -1643,12 +1650,18 @@ pub fn getOrCreateMetadataForLazySymbol( } fn addAtom(self: *ZigObject, allocator: Allocator) !Atom.Index { + try self.atoms.ensureUnusedCapacity(allocator, 1); + try self.atoms_extra.ensureUnusedCapacity(allocator, 1); + return self.addAtomAssumeCapacity(); +} + +fn addAtomAssumeCapacity(self: *ZigObject) Atom.Index { const atom_index: Atom.Index = @intCast(self.atoms.items.len); - const atom = try self.atoms.addOne(allocator); + const atom = self.atoms.addOneAssumeCapacity(); atom.* = .{ .file = self.index, .atom_index = atom_index, - .extra = try self.addAtomExtra(allocator, .{}), + .extra = self.addAtomExtraAssumeCapacity(.{}), }; return atom_index; } -- cgit v1.2.3