macho: claim unresolved symbols

This commit is contained in:
Jakub Konka 2024-01-11 19:04:50 +01:00
parent 1b76779857
commit 21e3bb38af

View File

@ -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");