mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
MachO: fix dynamic lookup of undefined symbols at runtime
Ensures `MH_NOUNDEFS` is not set when dynamic lookup is enabled for undefined symbols via `linker_allow_shlib_undefined`.
This commit is contained in:
parent
53e615b920
commit
8710c5f2f7
2 changed files with 31 additions and 1 deletions
|
|
@ -2937,7 +2937,13 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } {
|
|||
|
||||
fn writeHeader(self: *MachO, ncmds: usize, sizeofcmds: usize) !void {
|
||||
var header: macho.mach_header_64 = .{};
|
||||
header.flags = macho.MH_NOUNDEFS | macho.MH_DYLDLINK;
|
||||
header.flags = macho.MH_DYLDLINK;
|
||||
|
||||
// Only set MH_NOUNDEFS if we're not allowing undefined symbols via dynamic lookup.
|
||||
// When dynamic_lookup is enabled, undefined symbols are resolved at runtime by dyld.
|
||||
if (self.undefined_treatment != .dynamic_lookup) {
|
||||
header.flags |= macho.MH_NOUNDEFS;
|
||||
}
|
||||
|
||||
// TODO: if (self.options.namespace == .two_level) {
|
||||
header.flags |= macho.MH_TWOLEVEL;
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
|
|||
macho_step.dependOn(testTlsLargeTbss(b, .{ .target = default_target }));
|
||||
macho_step.dependOn(testTlsZig(b, .{ .target = default_target }));
|
||||
macho_step.dependOn(testUndefinedFlag(b, .{ .target = default_target }));
|
||||
macho_step.dependOn(testUndefinedDynamicLookup(b, .{ .target = default_target }));
|
||||
macho_step.dependOn(testDiscardLocalSymbols(b, .{ .target = default_target }));
|
||||
macho_step.dependOn(testUnresolvedError(b, .{ .target = default_target }));
|
||||
macho_step.dependOn(testUnresolvedError2(b, .{ .target = default_target }));
|
||||
|
|
@ -2632,6 +2633,29 @@ fn testUndefinedFlag(b: *Build, opts: Options) *Step {
|
|||
return test_step;
|
||||
}
|
||||
|
||||
fn testUndefinedDynamicLookup(b: *Build, opts: Options) *Step {
|
||||
const test_step = addTestStep(b, "undefined-dynamic-lookup", opts);
|
||||
|
||||
// Create a dylib with an undefined external symbol reference
|
||||
const dylib = addSharedLibrary(b, opts, .{ .name = "a" });
|
||||
addCSourceBytes(dylib,
|
||||
\\extern int undefined_symbol(void);
|
||||
\\int call_undefined(void) {
|
||||
\\ return undefined_symbol();
|
||||
\\}
|
||||
, &.{});
|
||||
dylib.linker_allow_shlib_undefined = true;
|
||||
|
||||
// Verify the Mach-O header does NOT contain NOUNDEFS flag
|
||||
const check = dylib.checkObject();
|
||||
check.checkInHeaders();
|
||||
check.checkExact("header");
|
||||
check.checkNotPresent("NOUNDEFS");
|
||||
test_step.dependOn(&check.step);
|
||||
|
||||
return test_step;
|
||||
}
|
||||
|
||||
fn testUnresolvedError(b: *Build, opts: Options) *Step {
|
||||
const test_step = addTestStep(b, "unresolved-error", opts);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue