From 6b617afe2a3904ad3d5c9e3542a30bd7f35ed54e Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 11 Jan 2024 18:50:53 +0100 Subject: [PATCH] macho: resolve synthetic symbols --- src/link/MachO.zig | 48 +++++++++++++++++++++++++++++++ src/link/MachO/InternalObject.zig | 12 ++++---- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 8a43526fab..9514d6d71f 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -498,6 +498,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node try self.addUndefinedGlobals(); try self.resolveSymbols(); + try self.resolveSyntheticSymbols(); state_log.debug("{}", .{self.dumpState()}); @@ -1215,6 +1216,53 @@ fn markLive(self: *MachO) void { } } +fn resolveSyntheticSymbols(self: *MachO) !void { + const internal = self.getInternalObject() orelse return; + + if (!self.base.isDynLib()) { + self.mh_execute_header_index = try internal.addSymbol("__mh_execute_header", self); + const sym = self.getSymbol(self.mh_execute_header_index.?); + sym.flags.@"export" = true; + sym.flags.dyn_ref = true; + sym.visibility = .global; + } else { + self.mh_dylib_header_index = try internal.addSymbol("__mh_dylib_header", self); + } + + self.dso_handle_index = try internal.addSymbol("___dso_handle", self); + self.dyld_private_index = try internal.addSymbol("dyld_private", self); + + { + const gpa = self.base.comp.gpa; + var boundary_symbols = std.AutoHashMap(Symbol.Index, void).init(gpa); + defer boundary_symbols.deinit(); + + for (self.objects.items) |index| { + const object = self.getFile(index).?.object; + for (object.symbols.items, 0..) |sym_index, i| { + const nlist = object.symtab.items(.nlist)[i]; + const name = self.getSymbol(sym_index).getName(self); + if (!nlist.undf() or !nlist.ext()) continue; + if (mem.startsWith(u8, name, "segment$start$") or + mem.startsWith(u8, name, "segment$stop$") or + mem.startsWith(u8, name, "section$start$") or + mem.startsWith(u8, name, "section$stop$")) + { + _ = try boundary_symbols.put(sym_index, {}); + } + } + } + + try self.boundary_symbols.ensureTotalCapacityPrecise(gpa, boundary_symbols.count()); + + var it = boundary_symbols.iterator(); + while (it.next()) |entry| { + _ = try internal.addSymbol(self.getSymbol(entry.key_ptr.*).getName(self), self); + self.boundary_symbols.appendAssumeCapacity(entry.key_ptr.*); + } + } +} + fn shrinkAtom(self: *MachO, atom_index: Atom.Index, new_block_size: u64) void { _ = self; _ = atom_index; diff --git a/src/link/MachO/InternalObject.zig b/src/link/MachO/InternalObject.zig index e139e4efab..26ec86bb67 100644 --- a/src/link/MachO/InternalObject.zig +++ b/src/link/MachO/InternalObject.zig @@ -20,9 +20,9 @@ pub fn deinit(self: *InternalObject, allocator: Allocator) void { } pub fn addSymbol(self: *InternalObject, name: [:0]const u8, macho_file: *MachO) !Symbol.Index { - const gpa = macho_file.base.allocator; + const gpa = macho_file.base.comp.gpa; try self.symbols.ensureUnusedCapacity(gpa, 1); - const off = try macho_file.string_intern.insert(gpa, name); + const off = try macho_file.strings.insert(gpa, name); const gop = try macho_file.getOrCreateGlobal(off); self.symbols.addOneAssumeCapacity().* = gop.index; const sym = macho_file.getSymbol(gop.index); @@ -37,7 +37,7 @@ pub fn addObjcMsgsendSections(self: *InternalObject, sym_name: []const u8, macho } fn addObjcMethnameSection(self: *InternalObject, methname: []const u8, macho_file: *MachO) !Atom.Index { - const gpa = macho_file.base.allocator; + const gpa = macho_file.base.comp.gpa; const atom_index = try macho_file.addAtom(); try self.atoms.append(gpa, atom_index); @@ -45,7 +45,7 @@ fn addObjcMethnameSection(self: *InternalObject, methname: []const u8, macho_fil defer gpa.free(name); const atom = macho_file.getAtom(atom_index).?; atom.atom_index = atom_index; - atom.name = try macho_file.string_intern.insert(gpa, name); + atom.name = try macho_file.strings.insert(gpa, name); atom.file = self.index; atom.size = methname.len + 1; atom.alignment = 0; @@ -71,7 +71,7 @@ fn addObjcSelrefsSection( methname_atom_index: Atom.Index, macho_file: *MachO, ) !Atom.Index { - const gpa = macho_file.base.allocator; + const gpa = macho_file.base.comp.gpa; const atom_index = try macho_file.addAtom(); try self.atoms.append(gpa, atom_index); @@ -79,7 +79,7 @@ fn addObjcSelrefsSection( defer gpa.free(name); const atom = macho_file.getAtom(atom_index).?; atom.atom_index = atom_index; - atom.name = try macho_file.string_intern.insert(gpa, name); + atom.name = try macho_file.strings.insert(gpa, name); atom.file = self.index; atom.size = @sizeOf(u64); atom.alignment = 3;