| ... | ... | @@ -28,6 +28,7 @@ locals: std.ArrayListUnmanaged(coff.Symbol) = .{}, |
| 28 | 28 | globals: std.ArrayListUnmanaged(SymbolWithLoc) = .{}, |
| 29 | 29 | resolver: std.StringHashMapUnmanaged(u32) = .{}, |
| 30 | 30 | unresolved: std.AutoArrayHashMapUnmanaged(u32, bool) = .{}, |
| 31 | need_got_table: std.AutoHashMapUnmanaged(u32, void) = .{}, |
| 31 | 32 | |
| 32 | 33 | locals_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 33 | 34 | globals_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| ... | ... | @@ -1168,12 +1169,17 @@ pub fn updateDecl( |
| 1168 | 1169 | const decl = mod.declPtr(decl_index); |
| 1169 | 1170 | |
| 1170 | 1171 | if (decl.val.getExternFunc(mod)) |_| { |
| 1171 | | return; // TODO Should we do more when front-end analyzed extern decl? |
| 1172 | return; |
| 1172 | 1173 | } |
| 1173 | | if (decl.val.getVariable(mod)) |variable| { |
| 1174 | | if (variable.is_extern) { |
| 1175 | | return; // TODO Should we do more when front-end analyzed extern decl? |
| 1176 | | } |
| 1174 | |
| 1175 | if (decl.isExtern(mod)) { |
| 1176 | // TODO make this part of getGlobalSymbol |
| 1177 | const variable = decl.getOwnedVariable(mod).?; |
| 1178 | const name = mod.intern_pool.stringToSlice(decl.name); |
| 1179 | const lib_name = mod.intern_pool.stringToSliceUnwrap(variable.lib_name); |
| 1180 | const global_index = try self.getGlobalSymbol(name, lib_name); |
| 1181 | try self.need_got_table.put(self.base.allocator, global_index, {}); |
| 1182 | return; |
| 1177 | 1183 | } |
| 1178 | 1184 | |
| 1179 | 1185 | const atom_index = try self.getOrCreateAtomForDecl(decl_index); |
| ... | ... | @@ -1519,14 +1525,25 @@ pub fn updateExports( |
| 1519 | 1525 | continue; |
| 1520 | 1526 | } |
| 1521 | 1527 | |
| 1522 | | const sym_index = metadata.getExport(self, mod.intern_pool.stringToSlice(exp.opts.name)) orelse blk: { |
| 1523 | | const sym_index = try self.allocateSymbol(); |
| 1528 | const exp_name = mod.intern_pool.stringToSlice(exp.opts.name); |
| 1529 | const sym_index = metadata.getExport(self, exp_name) orelse blk: { |
| 1530 | const sym_index = if (self.getGlobalIndex(exp_name)) |global_index| ind: { |
| 1531 | const global = self.globals.items[global_index]; |
| 1532 | // TODO this is just plain wrong as it all should happen in a single `resolveSymbols` |
| 1533 | // pass. This will go away once we abstact away Zig's incremental compilation into |
| 1534 | // its own module. |
| 1535 | if (global.file == null and self.getSymbol(global).section_number == .UNDEFINED) { |
| 1536 | _ = self.unresolved.swapRemove(global_index); |
| 1537 | break :ind global.sym_index; |
| 1538 | } |
| 1539 | break :ind try self.allocateSymbol(); |
| 1540 | } else try self.allocateSymbol(); |
| 1524 | 1541 | try metadata.exports.append(gpa, sym_index); |
| 1525 | 1542 | break :blk sym_index; |
| 1526 | 1543 | }; |
| 1527 | 1544 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; |
| 1528 | 1545 | const sym = self.getSymbolPtr(sym_loc); |
| 1529 | | try self.setSymbolName(sym, mod.intern_pool.stringToSlice(exp.opts.name)); |
| 1546 | try self.setSymbolName(sym, exp_name); |
| 1530 | 1547 | sym.value = atom.getSymbol(self).value; |
| 1531 | 1548 | sym.section_number = @as(coff.SectionNumber, @enumFromInt(metadata.section + 1)); |
| 1532 | 1549 | sym.type = atom.getSymbol(self).type; |
| ... | ... | @@ -1663,8 +1680,16 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 1663 | 1680 | if (metadata.rdata_state != .unused) metadata.rdata_state = .flushed; |
| 1664 | 1681 | } |
| 1665 | 1682 | |
| 1683 | { |
| 1684 | var it = self.need_got_table.iterator(); |
| 1685 | while (it.next()) |entry| { |
| 1686 | const global = self.globals.items[entry.key_ptr.*]; |
| 1687 | try self.addGotEntry(global); |
| 1688 | } |
| 1689 | } |
| 1690 | |
| 1666 | 1691 | while (self.unresolved.popOrNull()) |entry| { |
| 1667 | | assert(entry.value); // We only expect imports generated by the incremental linker for now. |
| 1692 | assert(entry.value); |
| 1668 | 1693 | const global = self.globals.items[entry.key]; |
| 1669 | 1694 | const sym = self.getSymbol(global); |
| 1670 | 1695 | const res = try self.import_tables.getOrPut(gpa, sym.value); |
| ... | ... | @@ -2459,6 +2484,11 @@ const GetOrPutGlobalPtrResult = struct { |
| 2459 | 2484 | value_ptr: *SymbolWithLoc, |
| 2460 | 2485 | }; |
| 2461 | 2486 | |
| 2487 | /// Used only for disambiguating local from global at relocation level. |
| 2488 | /// TODO this must go away. |
| 2489 | pub const global_symbol_bit: u32 = 0x80000000; |
| 2490 | pub const global_symbol_mask: u32 = 0x7fffffff; |
| 2491 | |
| 2462 | 2492 | /// Return pointer to the global entry for `name` if one exists. |
| 2463 | 2493 | /// Puts a new global entry for `name` if one doesn't exist, and |
| 2464 | 2494 | /// returns a pointer to it. |