Skip to content

Commit

Permalink
macho: test complex interaction between common symbols and weak ref t…
Browse files Browse the repository at this point in the history
…o funcs
  • Loading branch information
kubkon committed Nov 23, 2023
1 parent 9be3246 commit 3b85afe
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/MachO/Dylib.zig
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ pub fn markLive(self: *Dylib, macho_file: *MachO) void {
const global = macho_file.getSymbol(index);
const file = global.getFile(macho_file) orelse continue;
const should_drop = switch (file) {
.dylib => |sh| !sh.needed and (nlist.weakDef() or nlist.pext()),
.dylib => |sh| !sh.needed and nlist.weakRef(),
else => false,
};
if (!should_drop and !file.isAlive()) {
Expand Down
5 changes: 3 additions & 2 deletions src/MachO/Object.zig
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,8 @@ pub fn markLive(self: *Object, macho_file: *MachO) void {
for (self.getGlobals(), 0..) |index, i| {
const nlist_idx = self.first_global + i;
const nlist = self.symtab.items[nlist_idx];
if (nlist.weakDef() or nlist.pext()) continue;
// TODO weakRef() is correct here, but not sure about weakDef() and pext()
if (nlist.weakDef() or nlist.pext() or nlist.weakRef()) continue;

const global = macho_file.getSymbol(index);
const file = global.getFile(macho_file) orelse continue;
Expand Down Expand Up @@ -472,7 +473,7 @@ pub fn claimUnresolved(self: Object, macho_file: *MachO) void {
}

const is_import = switch (macho_file.options.undefined_treatment) {
.@"error", .warn, .suppress => false,
.@"error", .warn, .suppress => nlist.weakRef(),
.dynamic_lookup => true,
};

Expand Down
7 changes: 5 additions & 2 deletions src/MachO/Symbol.zig
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,11 @@ pub fn getDylibOrdinal(symbol: Symbol, macho_file: *MachO) i16 {
// TODO handle BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE
const file = symbol.getFile(macho_file) orelse return macho.BIND_SPECIAL_DYLIB_SELF;
if (macho_file.options.namespace == .flat) return macho.BIND_SPECIAL_DYLIB_FLAT_LOOKUP;
if (file != .dylib and macho_file.options.undefined_treatment == .dynamic_lookup)
return macho.BIND_SPECIAL_DYLIB_FLAT_LOOKUP;
if (file != .dylib) {
if (macho_file.options.undefined_treatment == .dynamic_lookup)
return macho.BIND_SPECIAL_DYLIB_FLAT_LOOKUP;
return macho.BIND_SPECIAL_DYLIB_SELF;
}
return @bitCast(file.dylib.ordinal);
}

Expand Down
79 changes: 79 additions & 0 deletions test/macho.zig
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub fn addMachOTests(b: *Build, options: common.Options) *Step {
macho_step.dependOn(testStackSize(b, opts));
macho_step.dependOn(testTbdv3(b, opts));
macho_step.dependOn(testTentative(b, opts));
macho_step.dependOn(testTentativeArchive(b, opts));
macho_step.dependOn(testTls(b, opts));
macho_step.dependOn(testUnwindInfo(b, opts));
macho_step.dependOn(testUnwindInfoNoSubsectionsArm64(b, opts));
Expand Down Expand Up @@ -987,6 +988,84 @@ fn testTentative(b: *Build, opts: Options) *Step {
return test_step;
}

fn testTentativeArchive(b: *Build, opts: Options) *Step {
const test_step = b.step("test-macho-tentative-archive", "");

const a_o = cc(b, opts);
a_o.addCSource(
\\#include <stdio.h>
\\int foo;
\\int bar;
\\extern int baz;
\\__attribute__((weak)) int two();
\\int main() {
\\ printf("%d %d %d %d\n", foo, bar, baz, two ? two() : -1);
\\}
);
a_o.addArgs(&.{ "-fcommon", "-c" });
const a_o_out = a_o.saveOutputAs("a.o");

const b_o = cc(b, opts);
b_o.addCSource("int foo = 5;");
b_o.addArgs(&.{ "-fcommon", "-c" });
const b_o_out = b_o.saveOutputAs("b.o");

{
const c_o = cc(b, opts);
c_o.addCSource(
\\int bar;
\\int two() { return 2; }
);
c_o.addArgs(&.{ "-fcommon", "-c" });
const c_o_out = c_o.saveOutputAs("c.o");

const d_o = cc(b, opts);
d_o.addCSource("int baz;");
d_o.addArgs(&.{ "-fcommon", "-c" });
const d_o_out = d_o.saveOutputAs("d.o");

const lib = ar(b);
lib.addFileSource(b_o_out.file);
lib.addFileSource(c_o_out.file);
lib.addFileSource(d_o_out.file);
const lib_out = lib.saveOutputAs("libe.a");

const exe = cc(b, opts);
exe.addFileSource(a_o_out.file);
exe.addFileSource(lib_out.file);

const run = exe.run();
run.expectStdOutEqual("5 0 0 -1\n");
test_step.dependOn(run.step());
}

{
const e_o = cc(b, opts);
e_o.addCSource(
\\int bar = 0;
\\int baz = 7;
\\int two() { return 2; }
);
e_o.addArgs(&.{ "-fcommon", "-c" });
const e_o_out = e_o.saveOutputAs("e.o");

const lib = ar(b);
lib.addFileSource(b_o_out.file);
lib.addFileSource(e_o_out.file);
const lib_out = lib.saveOutputAs("libe.a");

const exe = cc(b, opts);
exe.addFileSource(a_o_out.file);
exe.addFileSource(lib_out.file);

const run = exe.run();
run.expectStdOutEqual("5 0 7 2\n");
test_step.dependOn(run.step());
}

return test_step;
}

fn testTls(b: *Build, opts: Options) *Step {
const test_step = b.step("test-macho-tls", "");

Expand Down

0 comments on commit 3b85afe

Please sign in to comment.