| ... | @@ -28,6 +28,7 @@ locals: std.ArrayListUnmanaged(coff.Symbol) = .{}, | ... | @@ -28,6 +28,7 @@ locals: std.ArrayListUnmanaged(coff.Symbol) = .{}, |
| 28 | globals: std.ArrayListUnmanaged(SymbolWithLoc) = .{}, | 28 | globals: std.ArrayListUnmanaged(SymbolWithLoc) = .{}, |
| 29 | resolver: std.StringHashMapUnmanaged(u32) = .{}, | 29 | resolver: std.StringHashMapUnmanaged(u32) = .{}, |
| 30 | unresolved: std.AutoArrayHashMapUnmanaged(u32, bool) = .{}, | 30 | unresolved: std.AutoArrayHashMapUnmanaged(u32, bool) = .{}, |
| | 31 | need_got_table: std.AutoHashMapUnmanaged(u32, void) = .{}, |
| 31 | | 32 | |
| 32 | locals_free_list: std.ArrayListUnmanaged(u32) = .{}, | 33 | locals_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| 33 | globals_free_list: std.ArrayListUnmanaged(u32) = .{}, | 34 | globals_free_list: std.ArrayListUnmanaged(u32) = .{}, |
| ... | @@ -1168,12 +1169,17 @@ pub fn updateDecl( | ... | @@ -1168,12 +1169,17 @@ pub fn updateDecl( |
| 1168 | const decl = mod.declPtr(decl_index); | 1169 | const decl = mod.declPtr(decl_index); |
| 1169 | | 1170 | |
| 1170 | if (decl.val.getExternFunc(mod)) |_| { | 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 | |
| 1174 | if (variable.is_extern) { | 1175 | if (decl.isExtern(mod)) { |
| 1175 | return; // TODO Should we do more when front-end analyzed extern decl? | 1176 | // TODO make this part of getGlobalSymbol |
| 1176 | } | 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 | const atom_index = try self.getOrCreateAtomForDecl(decl_index); | 1185 | const atom_index = try self.getOrCreateAtomForDecl(decl_index); |
| ... | @@ -1519,14 +1525,25 @@ pub fn updateExports( | ... | @@ -1519,14 +1525,25 @@ pub fn updateExports( |
| 1519 | continue; | 1525 | continue; |
| 1520 | } | 1526 | } |
| 1521 | | 1527 | |
| 1522 | const sym_index = metadata.getExport(self, mod.intern_pool.stringToSlice(exp.opts.name)) orelse blk: { | 1528 | const exp_name = mod.intern_pool.stringToSlice(exp.opts.name); |
| 1523 | const sym_index = try self.allocateSymbol(); | 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 | try metadata.exports.append(gpa, sym_index); | 1541 | try metadata.exports.append(gpa, sym_index); |
| 1525 | break :blk sym_index; | 1542 | break :blk sym_index; |
| 1526 | }; | 1543 | }; |
| 1527 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; | 1544 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; |
| 1528 | const sym = self.getSymbolPtr(sym_loc); | 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 | sym.value = atom.getSymbol(self).value; | 1547 | sym.value = atom.getSymbol(self).value; |
| 1531 | sym.section_number = @as(coff.SectionNumber, @enumFromInt(metadata.section + 1)); | 1548 | sym.section_number = @as(coff.SectionNumber, @enumFromInt(metadata.section + 1)); |
| 1532 | sym.type = atom.getSymbol(self).type; | 1549 | sym.type = atom.getSymbol(self).type; |
| ... | @@ -1663,8 +1680,16 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod | ... | @@ -1663,8 +1680,16 @@ pub fn flushModule(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod |
| 1663 | if (metadata.rdata_state != .unused) metadata.rdata_state = .flushed; | 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 | while (self.unresolved.popOrNull()) |entry| { | 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 | const global = self.globals.items[entry.key]; | 1693 | const global = self.globals.items[entry.key]; |
| 1669 | const sym = self.getSymbol(global); | 1694 | const sym = self.getSymbol(global); |
| 1670 | const res = try self.import_tables.getOrPut(gpa, sym.value); | 1695 | const res = try self.import_tables.getOrPut(gpa, sym.value); |
| ... | @@ -2459,6 +2484,11 @@ const GetOrPutGlobalPtrResult = struct { | ... | @@ -2459,6 +2484,11 @@ const GetOrPutGlobalPtrResult = struct { |
| 2459 | value_ptr: *SymbolWithLoc, | 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 | /// Return pointer to the global entry for `name` if one exists. | 2492 | /// Return pointer to the global entry for `name` if one exists. |
| 2463 | /// Puts a new global entry for `name` if one doesn't exist, and | 2493 | /// Puts a new global entry for `name` if one doesn't exist, and |
| 2464 | /// returns a pointer to it. | 2494 | /// returns a pointer to it. |