| ... | @@ -84,6 +84,11 @@ common_section_index: ?u16 = null, | ... | @@ -84,6 +84,11 @@ common_section_index: ?u16 = null, |
| 84 | globals: std.StringArrayHashMapUnmanaged(*Symbol) = .{}, | 84 | globals: std.StringArrayHashMapUnmanaged(*Symbol) = .{}, |
| 85 | imports: std.StringArrayHashMapUnmanaged(*Symbol) = .{}, | 85 | imports: std.StringArrayHashMapUnmanaged(*Symbol) = .{}, |
| 86 | unresolved: std.StringArrayHashMapUnmanaged(*Symbol) = .{}, | 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 | strtab: std.ArrayListUnmanaged(u8) = .{}, | 93 | strtab: std.ArrayListUnmanaged(u8) = .{}, |
| 89 | strtab_dir: std.StringHashMapUnmanaged(u32) = .{}, | 94 | strtab_dir: std.StringHashMapUnmanaged(u32) = .{}, |
| ... | @@ -144,6 +149,7 @@ pub fn deinit(self: *Zld) void { | ... | @@ -144,6 +149,7 @@ pub fn deinit(self: *Zld) void { |
| 144 | } | 149 | } |
| 145 | self.dylibs.deinit(self.allocator); | 150 | self.dylibs.deinit(self.allocator); |
| 146 | | 151 | |
| | 152 | self.tentatives.deinit(self.allocator); |
| 147 | self.globals.deinit(self.allocator); | 153 | self.globals.deinit(self.allocator); |
| 148 | self.imports.deinit(self.allocator); | 154 | self.imports.deinit(self.allocator); |
| 149 | self.unresolved.deinit(self.allocator); | 155 | self.unresolved.deinit(self.allocator); |
| ... | @@ -1379,6 +1385,10 @@ fn resolveSymbolsInObject(self: *Zld, object: *Object) !void { | ... | @@ -1379,6 +1385,10 @@ fn resolveSymbolsInObject(self: *Zld, object: *Object) !void { |
| 1379 | if (sym.cast(Symbol.Regular)) |reg| { | 1385 | if (sym.cast(Symbol.Regular)) |reg| { |
| 1380 | if (reg.linkage == .translation_unit) continue; // Symbol local to TU. | 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 | if (self.unresolved.fetchSwapRemove(sym.name)) |kv| { | 1392 | if (self.unresolved.fetchSwapRemove(sym.name)) |kv| { |
| 1383 | // Create link to the global. | 1393 | // Create link to the global. |
| 1384 | kv.value.alias = sym; | 1394 | kv.value.alias = sym; |
| ... | @@ -1412,11 +1422,33 @@ fn resolveSymbolsInObject(self: *Zld, object: *Object) !void { | ... | @@ -1412,11 +1422,33 @@ fn resolveSymbolsInObject(self: *Zld, object: *Object) !void { |
| 1412 | | 1422 | |
| 1413 | g_sym.alias = sym; | 1423 | g_sym.alias = sym; |
| 1414 | sym_ptr.* = sym; | 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 | } else if (sym.cast(Symbol.Unresolved)) |und| { | 1443 | } else if (sym.cast(Symbol.Unresolved)) |und| { |
| 1416 | if (self.globals.get(sym.name)) |g_sym| { | 1444 | if (self.globals.get(sym.name)) |g_sym| { |
| 1417 | sym.alias = g_sym; | 1445 | sym.alias = g_sym; |
| 1418 | continue; | 1446 | continue; |
| 1419 | } | 1447 | } |
| | 1448 | if (self.tentatives.get(sym.name)) |t_sym| { |
| | 1449 | sym.alias = t_sym; |
| | 1450 | continue; |
| | 1451 | } |
| 1420 | if (self.unresolved.get(sym.name)) |u_sym| { | 1452 | if (self.unresolved.get(sym.name)) |u_sym| { |
| 1421 | sym.alias = u_sym; | 1453 | sym.alias = u_sym; |
| 1422 | continue; | 1454 | continue; |