| ... | ... | @@ -84,6 +84,11 @@ common_section_index: ?u16 = null, |
| 84 | 84 | globals: std.StringArrayHashMapUnmanaged(*Symbol) = .{}, |
| 85 | 85 | imports: std.StringArrayHashMapUnmanaged(*Symbol) = .{}, |
| 86 | 86 | unresolved: std.StringArrayHashMapUnmanaged(*Symbol) = .{}, |
| 87 | tentatives: std.StringArrayHashMapUnmanaged(*Symbol) = .{}, |
| 88 | |
| 89 | // /// Offset into __DATA,__common section. |
| 90 | // /// Set if the linker found tentative definitions in any of the objects. |
| 91 | // tentative_defs_offset: u32 = 0, |
| 87 | 92 | |
| 88 | 93 | strtab: std.ArrayListUnmanaged(u8) = .{}, |
| 89 | 94 | strtab_dir: std.StringHashMapUnmanaged(u32) = .{}, |
| ... | ... | @@ -144,6 +149,7 @@ pub fn deinit(self: *Zld) void { |
| 144 | 149 | } |
| 145 | 150 | self.dylibs.deinit(self.allocator); |
| 146 | 151 | |
| 152 | self.tentatives.deinit(self.allocator); |
| 147 | 153 | self.globals.deinit(self.allocator); |
| 148 | 154 | self.imports.deinit(self.allocator); |
| 149 | 155 | self.unresolved.deinit(self.allocator); |
| ... | ... | @@ -1379,6 +1385,10 @@ fn resolveSymbolsInObject(self: *Zld, object: *Object) !void { |
| 1379 | 1385 | if (sym.cast(Symbol.Regular)) |reg| { |
| 1380 | 1386 | if (reg.linkage == .translation_unit) continue; // Symbol local to TU. |
| 1381 | 1387 | |
| 1388 | if (self.tentatives.fetchSwapRemove(sym.name)) |kv| { |
| 1389 | // Create link to the global. |
| 1390 | kv.value.alias = sym; |
| 1391 | } |
| 1382 | 1392 | if (self.unresolved.fetchSwapRemove(sym.name)) |kv| { |
| 1383 | 1393 | // Create link to the global. |
| 1384 | 1394 | kv.value.alias = sym; |
| ... | ... | @@ -1412,11 +1422,33 @@ fn resolveSymbolsInObject(self: *Zld, object: *Object) !void { |
| 1412 | 1422 | |
| 1413 | 1423 | g_sym.alias = sym; |
| 1414 | 1424 | sym_ptr.* = sym; |
| 1425 | } else if (sym.cast(Symbol.Tentative)) |tent| { |
| 1426 | if (self.globals.get(sym.name)) |g_sym| { |
| 1427 | sym.alias = g_sym; |
| 1428 | continue; |
| 1429 | } |
| 1430 | |
| 1431 | if (self.unresolved.fetchSwapRemove(sym.name)) |kv| { |
| 1432 | kv.value.alias = sym; |
| 1433 | } |
| 1434 | |
| 1435 | const t_sym = self.tentatives.get(sym.name) orelse { |
| 1436 | // Put new tentative definition symbol into symbol table. |
| 1437 | try self.tentatives.putNoClobber(self.allocator, sym.name, sym); |
| 1438 | continue; |
| 1439 | }; |
| 1440 | |
| 1441 | // TODO compare by size and pick the largest. |
| 1442 | return error.TODOResolveTentatives; |
| 1415 | 1443 | } else if (sym.cast(Symbol.Unresolved)) |und| { |
| 1416 | 1444 | if (self.globals.get(sym.name)) |g_sym| { |
| 1417 | 1445 | sym.alias = g_sym; |
| 1418 | 1446 | continue; |
| 1419 | 1447 | } |
| 1448 | if (self.tentatives.get(sym.name)) |t_sym| { |
| 1449 | sym.alias = t_sym; |
| 1450 | continue; |
| 1451 | } |
| 1420 | 1452 | if (self.unresolved.get(sym.name)) |u_sym| { |
| 1421 | 1453 | sym.alias = u_sym; |
| 1422 | 1454 | continue; |