diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2024-01-11 19:04:50 +0100 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2024-01-24 12:34:39 +0100 |
| commit | 21e3bb38afad7a2cc4e84910d7630e4ee3435a85 (patch) | |
| tree | 18102b8d55943cf89dd54034b777b4735caee3ab | |
| parent | 1b76779857cae1d8212f574a4a3059fad9419476 (diff) | |
| download | zig-21e3bb38afad7a2cc4e84910d7630e4ee3435a85.tar.gz zig-21e3bb38afad7a2cc4e84910d7630e4ee3435a85.zip | |
macho: claim unresolved symbols
| -rw-r--r-- | src/link/MachO.zig | 64 |
1 files changed, 55 insertions, 9 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig index b07d30bb11..d083471fee 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -92,6 +92,9 @@ headerpad_size: ?u32, headerpad_max_install_names: bool, /// Remove dylibs that are unreachable by the entry point or exported symbols. dead_strip_dylibs: bool, +/// Treatment of undefined symbols +undefined_treatment: UndefinedTreatment, +/// List of input frameworks frameworks: []const Framework, /// Install name for the dylib. /// TODO: unify with soname @@ -122,14 +125,6 @@ pub fn hashAddFrameworks(man: *Cache.Manifest, hm: []const Framework) !void { } } -/// The filesystem layout of darwin SDK elements. -pub const SdkLayout = enum { - /// macOS SDK layout: TOP { /usr/include, /usr/lib, /System/Library/Frameworks }. - sdk, - /// Shipped libc layout: TOP { /lib/libc/include, /lib/libc/darwin, <NONE> }. - vendored, -}; - pub fn createEmpty( arena: Allocator, comp: *Compilation, @@ -153,6 +148,7 @@ pub fn createEmpty( null else try std.fmt.allocPrint(arena, "{s}.o", .{emit.sub_path}); + const allow_shlib_undefined = options.allow_shlib_undefined orelse false; const self = try arena.create(MachO); self.* = .{ @@ -164,7 +160,7 @@ pub fn createEmpty( .gc_sections = options.gc_sections orelse (optimize_mode != .Debug), .print_gc_sections = options.print_gc_sections, .stack_size = options.stack_size orelse 16777216, - .allow_shlib_undefined = options.allow_shlib_undefined orelse false, + .allow_shlib_undefined = allow_shlib_undefined, .file = null, .disable_lld_caching = options.disable_lld_caching, .build_id = options.build_id, @@ -187,6 +183,7 @@ pub fn createEmpty( }, .platform = Platform.fromTarget(target), .sdk_version = if (options.darwin_sdk_layout) |layout| inferSdkVersion(comp, layout) else null, + .undefined_treatment = if (allow_shlib_undefined) .dynamic_lookup else .@"error", }; if (use_llvm and comp.config.have_zcu) { self.llvm_object = try LlvmObject.create(arena, comp); @@ -502,6 +499,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node try self.convertTentativeDefinitions(); try self.createObjcSections(); + try self.claimUnresolved(); state_log.debug("{}", .{self.dumpState()}); @@ -1310,6 +1308,39 @@ fn createObjcSections(self: *MachO) !void { } } +fn claimUnresolved(self: *MachO) error{OutOfMemory}!void { + for (self.objects.items) |index| { + const object = self.getFile(index).?.object; + + for (object.symbols.items, 0..) |sym_index, i| { + const nlist_idx = @as(Symbol.Index, @intCast(i)); + const nlist = object.symtab.items(.nlist)[nlist_idx]; + if (!nlist.ext()) continue; + if (!nlist.undf()) continue; + + const sym = self.getSymbol(sym_index); + if (sym.getFile(self) != null) continue; + + const is_import = switch (self.undefined_treatment) { + .@"error" => false, + .warn, .suppress => nlist.weakRef(), + .dynamic_lookup => true, + }; + if (is_import) { + sym.value = 0; + sym.atom = 0; + sym.nlist_idx = 0; + sym.file = self.internal_object.?; + sym.flags.weak = false; + sym.flags.weak_ref = nlist.weakRef(); + sym.flags.import = is_import; + sym.visibility = .global; + try self.getInternalObject().?.symbols.append(self.base.comp.gpa, sym_index); + } + } + } +} + fn shrinkAtom(self: *MachO, atom_index: Atom.Index, new_block_size: u64) void { _ = self; _ = atom_index; @@ -2350,6 +2381,21 @@ const SystemLib = struct { must_link: bool = false, }; +/// The filesystem layout of darwin SDK elements. +pub const SdkLayout = enum { + /// macOS SDK layout: TOP { /usr/include, /usr/lib, /System/Library/Frameworks }. + sdk, + /// Shipped libc layout: TOP { /lib/libc/include, /lib/libc/darwin, <NONE> }. + vendored, +}; + +const UndefinedTreatment = enum { + @"error", + warn, + suppress, + dynamic_lookup, +}; + const MachO = @This(); const std = @import("std"); |
