authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-11 19:04:50+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-24 12:34:39+01:00
log21e3bb38afad7a2cc4e84910d7630e4ee3435a85
tree18102b8d55943cf89dd54034b777b4735caee3ab
parent1b76779857cae1d8212f574a4a3059fad9419476

macho: claim unresolved symbols


1 files changed, 55 insertions(+), 9 deletions(-)

src/link/MachO.zig+55-9
...@@ -92,6 +92,9 @@ headerpad_size: ?u32,...@@ -92,6 +92,9 @@ headerpad_size: ?u32,
92headerpad_max_install_names: bool,92headerpad_max_install_names: bool,
93/// Remove dylibs that are unreachable by the entry point or exported symbols.93/// Remove dylibs that are unreachable by the entry point or exported symbols.
94dead_strip_dylibs: bool,94dead_strip_dylibs: bool,
95/// Treatment of undefined symbols
96undefined_treatment: UndefinedTreatment,
97/// List of input frameworks
95frameworks: []const Framework,98frameworks: []const Framework,
96/// Install name for the dylib.99/// Install name for the dylib.
97/// TODO: unify with soname100/// TODO: unify with soname
...@@ -122,14 +125,6 @@ pub fn hashAddFrameworks(man: *Cache.Manifest, hm: []const Framework) !void {...@@ -122,14 +125,6 @@ pub fn hashAddFrameworks(man: *Cache.Manifest, hm: []const Framework) !void {
122 }125 }
123}126}
124127
125/// The filesystem layout of darwin SDK elements.
126pub const SdkLayout = enum {
127 /// macOS SDK layout: TOP { /usr/include, /usr/lib, /System/Library/Frameworks }.
128 sdk,
129 /// Shipped libc layout: TOP { /lib/libc/include, /lib/libc/darwin, <NONE> }.
130 vendored,
131};
132
133pub fn createEmpty(128pub fn createEmpty(
134 arena: Allocator,129 arena: Allocator,
135 comp: *Compilation,130 comp: *Compilation,
...@@ -153,6 +148,7 @@ pub fn createEmpty(...@@ -153,6 +148,7 @@ pub fn createEmpty(
153 null148 null
154 else149 else
155 try std.fmt.allocPrint(arena, "{s}.o", .{emit.sub_path});150 try std.fmt.allocPrint(arena, "{s}.o", .{emit.sub_path});
151 const allow_shlib_undefined = options.allow_shlib_undefined orelse false;
156152
157 const self = try arena.create(MachO);153 const self = try arena.create(MachO);
158 self.* = .{154 self.* = .{
...@@ -164,7 +160,7 @@ pub fn createEmpty(...@@ -164,7 +160,7 @@ pub fn createEmpty(
164 .gc_sections = options.gc_sections orelse (optimize_mode != .Debug),160 .gc_sections = options.gc_sections orelse (optimize_mode != .Debug),
165 .print_gc_sections = options.print_gc_sections,161 .print_gc_sections = options.print_gc_sections,
166 .stack_size = options.stack_size orelse 16777216,162 .stack_size = options.stack_size orelse 16777216,
167 .allow_shlib_undefined = options.allow_shlib_undefined orelse false,163 .allow_shlib_undefined = allow_shlib_undefined,
168 .file = null,164 .file = null,
169 .disable_lld_caching = options.disable_lld_caching,165 .disable_lld_caching = options.disable_lld_caching,
170 .build_id = options.build_id,166 .build_id = options.build_id,
...@@ -187,6 +183,7 @@ pub fn createEmpty(...@@ -187,6 +183,7 @@ pub fn createEmpty(
187 },183 },
188 .platform = Platform.fromTarget(target),184 .platform = Platform.fromTarget(target),
189 .sdk_version = if (options.darwin_sdk_layout) |layout| inferSdkVersion(comp, layout) else null,185 .sdk_version = if (options.darwin_sdk_layout) |layout| inferSdkVersion(comp, layout) else null,
186 .undefined_treatment = if (allow_shlib_undefined) .dynamic_lookup else .@"error",
190 };187 };
191 if (use_llvm and comp.config.have_zcu) {188 if (use_llvm and comp.config.have_zcu) {
192 self.llvm_object = try LlvmObject.create(arena, comp);189 self.llvm_object = try LlvmObject.create(arena, comp);
...@@ -502,6 +499,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node...@@ -502,6 +499,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node
502499
503 try self.convertTentativeDefinitions();500 try self.convertTentativeDefinitions();
504 try self.createObjcSections();501 try self.createObjcSections();
502 try self.claimUnresolved();
505503
506 state_log.debug("{}", .{self.dumpState()});504 state_log.debug("{}", .{self.dumpState()});
507505
...@@ -1310,6 +1308,39 @@ fn createObjcSections(self: *MachO) !void {...@@ -1310,6 +1308,39 @@ fn createObjcSections(self: *MachO) !void {
1310 }1308 }
1311}1309}
13121310
1311fn claimUnresolved(self: *MachO) error{OutOfMemory}!void {
1312 for (self.objects.items) |index| {
1313 const object = self.getFile(index).?.object;
1314
1315 for (object.symbols.items, 0..) |sym_index, i| {
1316 const nlist_idx = @as(Symbol.Index, @intCast(i));
1317 const nlist = object.symtab.items(.nlist)[nlist_idx];
1318 if (!nlist.ext()) continue;
1319 if (!nlist.undf()) continue;
1320
1321 const sym = self.getSymbol(sym_index);
1322 if (sym.getFile(self) != null) continue;
1323
1324 const is_import = switch (self.undefined_treatment) {
1325 .@"error" => false,
1326 .warn, .suppress => nlist.weakRef(),
1327 .dynamic_lookup => true,
1328 };
1329 if (is_import) {
1330 sym.value = 0;
1331 sym.atom = 0;
1332 sym.nlist_idx = 0;
1333 sym.file = self.internal_object.?;
1334 sym.flags.weak = false;
1335 sym.flags.weak_ref = nlist.weakRef();
1336 sym.flags.import = is_import;
1337 sym.visibility = .global;
1338 try self.getInternalObject().?.symbols.append(self.base.comp.gpa, sym_index);
1339 }
1340 }
1341 }
1342}
1343
1313fn shrinkAtom(self: *MachO, atom_index: Atom.Index, new_block_size: u64) void {1344fn shrinkAtom(self: *MachO, atom_index: Atom.Index, new_block_size: u64) void {
1314 _ = self;1345 _ = self;
1315 _ = atom_index;1346 _ = atom_index;
...@@ -2350,6 +2381,21 @@ const SystemLib = struct {...@@ -2350,6 +2381,21 @@ const SystemLib = struct {
2350 must_link: bool = false,2381 must_link: bool = false,
2351};2382};
23522383
2384/// The filesystem layout of darwin SDK elements.
2385pub const SdkLayout = enum {
2386 /// macOS SDK layout: TOP { /usr/include, /usr/lib, /System/Library/Frameworks }.
2387 sdk,
2388 /// Shipped libc layout: TOP { /lib/libc/include, /lib/libc/darwin, <NONE> }.
2389 vendored,
2390};
2391
2392const UndefinedTreatment = enum {
2393 @"error",
2394 warn,
2395 suppress,
2396 dynamic_lookup,
2397};
2398
2353const MachO = @This();2399const MachO = @This();
23542400
2355const std = @import("std");2401const std = @import("std");