| ... | @@ -1236,11 +1236,12 @@ fn resolveSymbolsInObject(self: *Zld, object_id: u16) !void { | ... | @@ -1236,11 +1236,12 @@ fn resolveSymbolsInObject(self: *Zld, object_id: u16) !void { |
| 1236 | continue; | 1236 | continue; |
| 1237 | } else if (Symbol.isGlobal(sym)) { | 1237 | } else if (Symbol.isGlobal(sym)) { |
| 1238 | const sym_name = object.getString(sym.n_strx); | 1238 | const sym_name = object.getString(sym.n_strx); |
| | 1239 | const is_weak = Symbol.isWeakDef(sym) or Symbol.isPext(sym); |
| 1239 | const global = self.symtab.getEntry(sym_name) orelse { | 1240 | const global = self.symtab.getEntry(sym_name) orelse { |
| 1240 | // Put new global symbol into the symbol table. | 1241 | // Put new global symbol into the symbol table. |
| 1241 | const name = try self.allocator.dupe(u8, sym_name); | 1242 | const name = try self.allocator.dupe(u8, sym_name); |
| 1242 | try self.symtab.putNoClobber(self.allocator, name, .{ | 1243 | try self.symtab.putNoClobber(self.allocator, name, .{ |
| 1243 | .tag = if (Symbol.isWeakDef(sym)) .weak else .strong, | 1244 | .tag = if (is_weak) .weak else .strong, |
| 1244 | .name = name, | 1245 | .name = name, |
| 1245 | .address = 0, | 1246 | .address = 0, |
| 1246 | .section = 0, | 1247 | .section = 0, |
| ... | @@ -1251,10 +1252,15 @@ fn resolveSymbolsInObject(self: *Zld, object_id: u16) !void { | ... | @@ -1251,10 +1252,15 @@ fn resolveSymbolsInObject(self: *Zld, object_id: u16) !void { |
| 1251 | }; | 1252 | }; |
| 1252 | | 1253 | |
| 1253 | switch (global.value.tag) { | 1254 | switch (global.value.tag) { |
| 1254 | .weak => continue, // If symbol is weak, nothing to do. | 1255 | .weak => { |
| | 1256 | if (is_weak) continue; // Nothing to do for weak symbol. |
| | 1257 | }, |
| 1255 | .strong => { | 1258 | .strong => { |
| 1256 | log.err("symbol '{s}' defined multiple times", .{sym_name}); | 1259 | if (!is_weak) { |
| 1257 | return error.MultipleSymbolDefinitions; | 1260 | log.err("symbol '{s}' defined multiple times", .{sym_name}); |
| | 1261 | return error.MultipleSymbolDefinitions; |
| | 1262 | } |
| | 1263 | continue; |
| 1258 | }, | 1264 | }, |
| 1259 | else => {}, | 1265 | else => {}, |
| 1260 | } | 1266 | } |
| ... | @@ -1340,6 +1346,21 @@ fn resolveSymbols(self: *Zld) !void { | ... | @@ -1340,6 +1346,21 @@ fn resolveSymbols(self: *Zld) !void { |
| 1340 | .section = 0, | 1346 | .section = 0, |
| 1341 | .file = 0, | 1347 | .file = 0, |
| 1342 | }); | 1348 | }); |
| | 1349 | |
| | 1350 | { |
| | 1351 | log.warn("symtab", .{}); |
| | 1352 | for (self.symtab.items()) |sym| { |
| | 1353 | switch (sym.value.tag) { |
| | 1354 | .weak, .strong => { |
| | 1355 | log.warn(" | {s} => {s}", .{ sym.key, self.objects.items[sym.value.file.?].name.? }); |
| | 1356 | }, |
| | 1357 | .import => { |
| | 1358 | log.warn(" | {s} => libSystem.B.dylib", .{sym.key}); |
| | 1359 | }, |
| | 1360 | else => unreachable, |
| | 1361 | } |
| | 1362 | } |
| | 1363 | } |
| 1343 | } | 1364 | } |
| 1344 | | 1365 | |
| 1345 | fn resolveStubsAndGotEntries(self: *Zld) !void { | 1366 | fn resolveStubsAndGotEntries(self: *Zld) !void { |