authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-10-24 16:57:00+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-10-24 21:01:04+02:00
log6cf5305e47dd8382508f867b04067be615448b41
tree3c70af183ca2fbf4151ce15b5a90ba5e30148241
parentf80fd7e1a6bd3d4f9094301a3815909ce64a3696

macho: remove unresolved ref in the correct place

* without this, when an included relocatable references a common symbol from another translation unit would not be correctly removed from the unresolved lookup table triggering a misleading assertion down the line * assert upon removal that we indeed removed a ref instead of silently ignoring in debug * add test case that covers this issue

5 files changed, 19 insertions(+), 7 deletions(-)

src/link/MachO.zig+7-6
...@@ -2311,7 +2311,7 @@ fn createDsoHandleAtom(self: *MachO) !void {...@@ -2311,7 +2311,7 @@ fn createDsoHandleAtom(self: *MachO) !void {
2311 nlist.n_desc = macho.N_WEAK_DEF;2311 nlist.n_desc = macho.N_WEAK_DEF;
2312 try self.globals.append(self.base.allocator, nlist);2312 try self.globals.append(self.base.allocator, nlist);
23132313
2314 _ = self.unresolved.fetchSwapRemove(resolv.where_index);2314 assert(self.unresolved.swapRemove(resolv.where_index));
23152315
2316 undef.* = .{2316 undef.* = .{
2317 .n_strx = 0,2317 .n_strx = 0,
...@@ -2409,7 +2409,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {...@@ -2409,7 +2409,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
2409 const global = &self.globals.items[resolv.where_index];2409 const global = &self.globals.items[resolv.where_index];
24102410
2411 if (symbolIsTentative(global.*)) {2411 if (symbolIsTentative(global.*)) {
2412 _ = self.tentatives.fetchSwapRemove(resolv.where_index);2412 assert(self.tentatives.swapRemove(resolv.where_index));
2413 } else if (!(symbolIsWeakDef(sym) or symbolIsPext(sym)) and2413 } else if (!(symbolIsWeakDef(sym) or symbolIsPext(sym)) and
2414 !(symbolIsWeakDef(global.*) or symbolIsPext(global.*)))2414 !(symbolIsWeakDef(global.*) or symbolIsPext(global.*)))
2415 {2415 {
...@@ -2437,7 +2437,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {...@@ -2437,7 +2437,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
2437 .n_desc = 0,2437 .n_desc = 0,
2438 .n_value = 0,2438 .n_value = 0,
2439 };2439 };
2440 _ = self.unresolved.fetchSwapRemove(resolv.where_index);2440 assert(self.unresolved.swapRemove(resolv.where_index));
2441 },2441 },
2442 }2442 }
24432443
...@@ -2496,6 +2496,8 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {...@@ -2496,6 +2496,8 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
2496 .n_value = sym.n_value,2496 .n_value = sym.n_value,
2497 });2497 });
2498 _ = try self.tentatives.getOrPut(self.base.allocator, global_sym_index);2498 _ = try self.tentatives.getOrPut(self.base.allocator, global_sym_index);
2499 assert(self.unresolved.swapRemove(resolv.where_index));
2500
2499 resolv.* = .{2501 resolv.* = .{
2500 .where = .global,2502 .where = .global,
2501 .where_index = global_sym_index,2503 .where_index = global_sym_index,
...@@ -2508,7 +2510,6 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {...@@ -2508,7 +2510,6 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
2508 .n_desc = 0,2510 .n_desc = 0,
2509 .n_value = 0,2511 .n_value = 0,
2510 };2512 };
2511 _ = self.unresolved.fetchSwapRemove(resolv.where_index);
2512 },2513 },
2513 }2514 }
2514 } else {2515 } else {
...@@ -3412,7 +3413,7 @@ pub fn updateDeclExports(...@@ -3412,7 +3413,7 @@ pub fn updateDeclExports(
3412 const sym = &self.globals.items[resolv.where_index];3413 const sym = &self.globals.items[resolv.where_index];
34133414
3414 if (symbolIsTentative(sym.*)) {3415 if (symbolIsTentative(sym.*)) {
3415 _ = self.tentatives.fetchSwapRemove(resolv.where_index);3416 assert(self.tentatives.swapRemove(resolv.where_index));
3416 } else if (!is_weak and !(symbolIsWeakDef(sym.*) or symbolIsPext(sym.*))) {3417 } else if (!is_weak and !(symbolIsWeakDef(sym.*) or symbolIsPext(sym.*))) {
3417 _ = try module.failed_exports.put(3418 _ = try module.failed_exports.put(
3418 module.gpa,3419 module.gpa,
...@@ -3438,7 +3439,7 @@ pub fn updateDeclExports(...@@ -3438,7 +3439,7 @@ pub fn updateDeclExports(
3438 continue;3439 continue;
3439 },3440 },
3440 .undef => {3441 .undef => {
3441 _ = self.unresolved.fetchSwapRemove(resolv.where_index);3442 assert(self.unresolved.swapRemove(resolv.where_index));
3442 _ = self.symbol_resolver.remove(n_strx);3443 _ = self.symbol_resolver.remove(n_strx);
3443 },3444 },
3444 }3445 }
test/standalone/link_common_symbols/b.c+1
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1long i;1long i;
2int j = 2;2int j = 2;
3int k;
34
4void incr_i() {5void incr_i() {
5 i++;6 i++;
test/standalone/link_common_symbols/build.zig+1-1
...@@ -4,7 +4,7 @@ pub fn build(b: *Builder) void {...@@ -4,7 +4,7 @@ pub fn build(b: *Builder) void {
4 const mode = b.standardReleaseOptions();4 const mode = b.standardReleaseOptions();
55
6 const lib_a = b.addStaticLibrary("a", null);6 const lib_a = b.addStaticLibrary("a", null);
7 lib_a.addCSourceFiles(&.{ "a.c", "b.c" }, &.{"-fcommon"});7 lib_a.addCSourceFiles(&.{ "c.c", "a.c", "b.c" }, &.{"-fcommon"});
8 lib_a.setBuildMode(mode);8 lib_a.setBuildMode(mode);
99
10 const test_exe = b.addTest("main.zig");10 const test_exe = b.addTest("main.zig");
test/standalone/link_common_symbols/c.c created+5
...@@ -0,0 +1,5 @@
1extern int k;
2
3int common_defined_externally() {
4 return k;
5}
test/standalone/link_common_symbols/main.zig+5
...@@ -1,9 +1,14 @@...@@ -1,9 +1,14 @@
1const std = @import("std");1const std = @import("std");
2const expect = std.testing.expect;2const expect = std.testing.expect;
33
4extern fn common_defined_externally() c_int;
4extern fn incr_i() void;5extern fn incr_i() void;
5extern fn add_to_i_and_j(x: c_int) c_int;6extern fn add_to_i_and_j(x: c_int) c_int;
67
8test "undef shadows common symbol: issue #9937" {
9 try expect(common_defined_externally() == 0);
10}
11
7test "import C common symbols" {12test "import C common symbols" {
8 incr_i();13 incr_i();
9 const res = add_to_i_and_j(2);14 const res = add_to_i_and_j(2);