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 {
23112311 nlist.n_desc = macho.N_WEAK_DEF;
23122312 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
23162316 undef.* = .{
23172317 .n_strx = 0,
......@@ -2409,7 +2409,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
24092409 const global = &self.globals.items[resolv.where_index];
24102410
24112411 if (symbolIsTentative(global.*)) {
2412 _ = self.tentatives.fetchSwapRemove(resolv.where_index);
2412 assert(self.tentatives.swapRemove(resolv.where_index));
24132413 } else if (!(symbolIsWeakDef(sym) or symbolIsPext(sym)) and
24142414 !(symbolIsWeakDef(global.*) or symbolIsPext(global.*)))
24152415 {
......@@ -2437,7 +2437,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
24372437 .n_desc = 0,
24382438 .n_value = 0,
24392439 };
2440 _ = self.unresolved.fetchSwapRemove(resolv.where_index);
2440 assert(self.unresolved.swapRemove(resolv.where_index));
24412441 },
24422442 }
24432443
......@@ -2496,6 +2496,8 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
24962496 .n_value = sym.n_value,
24972497 });
24982498 _ = try self.tentatives.getOrPut(self.base.allocator, global_sym_index);
2499 assert(self.unresolved.swapRemove(resolv.where_index));
2500
24992501 resolv.* = .{
25002502 .where = .global,
25012503 .where_index = global_sym_index,
......@@ -2508,7 +2510,6 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
25082510 .n_desc = 0,
25092511 .n_value = 0,
25102512 };
2511 _ = self.unresolved.fetchSwapRemove(resolv.where_index);
25122513 },
25132514 }
25142515 } else {
......@@ -3412,7 +3413,7 @@ pub fn updateDeclExports(
34123413 const sym = &self.globals.items[resolv.where_index];
34133414
34143415 if (symbolIsTentative(sym.*)) {
3415 _ = self.tentatives.fetchSwapRemove(resolv.where_index);
3416 assert(self.tentatives.swapRemove(resolv.where_index));
34163417 } else if (!is_weak and !(symbolIsWeakDef(sym.*) or symbolIsPext(sym.*))) {
34173418 _ = try module.failed_exports.put(
34183419 module.gpa,
......@@ -3438,7 +3439,7 @@ pub fn updateDeclExports(
34383439 continue;
34393440 },
34403441 .undef => {
3441 _ = self.unresolved.fetchSwapRemove(resolv.where_index);
3442 assert(self.unresolved.swapRemove(resolv.where_index));
34423443 _ = self.symbol_resolver.remove(n_strx);
34433444 },
34443445 }
test/standalone/link_common_symbols/b.c+1
......@@ -1,5 +1,6 @@
11long i;
22int j = 2;
3int k;
34
45void incr_i() {
56 i++;
test/standalone/link_common_symbols/build.zig+1-1
......@@ -4,7 +4,7 @@ pub fn build(b: *Builder) void {
44 const mode = b.standardReleaseOptions();
55
66 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"});
88 lib_a.setBuildMode(mode);
99
1010 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 @@
11const std = @import("std");
22const expect = std.testing.expect;
33
4extern fn common_defined_externally() c_int;
45extern fn incr_i() void;
56extern 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
712test "import C common symbols" {
813 incr_i();
914 const res = add_to_i_and_j(2);