| ... | ... | @@ -54,7 +54,7 @@ entry_addr: ?u32 = null, |
| 54 | 54 | lazy_syms: LazySymbolTable = .{}, |
| 55 | 55 | |
| 56 | 56 | /// Table of tracked Decls. |
| 57 | | decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, |
| 57 | decls: DeclTable = .{}, |
| 58 | 58 | |
| 59 | 59 | /// List of atoms that are either synthetic or map directly to the Zig source program. |
| 60 | 60 | atoms: std.ArrayListUnmanaged(Atom) = .{}, |
| ... | ... | @@ -108,7 +108,8 @@ const HotUpdateState = struct { |
| 108 | 108 | loaded_base_address: ?std.os.windows.HMODULE = null, |
| 109 | 109 | }; |
| 110 | 110 | |
| 111 | | const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, Atom.Index); |
| 111 | const DeclTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, DeclMetadata); |
| 112 | const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, DeclMetadata); |
| 112 | 113 | const RelocTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(Relocation)); |
| 113 | 114 | const BaseRelocationTable = std.AutoArrayHashMapUnmanaged(Atom.Index, std.ArrayListUnmanaged(u32)); |
| 114 | 115 | const UnnamedConstTable = std.AutoArrayHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Atom.Index)); |
| ... | ... | @@ -325,7 +326,14 @@ pub fn deinit(self: *Coff) void { |
| 325 | 326 | atoms.deinit(gpa); |
| 326 | 327 | } |
| 327 | 328 | self.unnamed_const_atoms.deinit(gpa); |
| 328 | | self.anon_decls.deinit(gpa); |
| 329 | |
| 330 | { |
| 331 | var it = self.anon_decls.iterator(); |
| 332 | while (it.next()) |entry| { |
| 333 | entry.value_ptr.exports.deinit(gpa); |
| 334 | } |
| 335 | self.anon_decls.deinit(gpa); |
| 336 | } |
| 329 | 337 | |
| 330 | 338 | for (self.relocs.values()) |*relocs| { |
| 331 | 339 | relocs.deinit(gpa); |
| ... | ... | @@ -1462,62 +1470,66 @@ pub fn updateExports( |
| 1462 | 1470 | |
| 1463 | 1471 | const gpa = self.base.allocator; |
| 1464 | 1472 | |
| 1465 | | const decl_index = switch (exported) { |
| 1466 | | .decl_index => |i| i, |
| 1467 | | .value => |val| { |
| 1468 | | _ = val; |
| 1469 | | @panic("TODO: implement COFF linker code for exporting a constant value"); |
| 1473 | const metadata = switch (exported) { |
| 1474 | .decl_index => |decl_index| blk: { |
| 1475 | _ = try self.getOrCreateAtomForDecl(decl_index); |
| 1476 | break :blk self.decls.getPtr(decl_index).?; |
| 1477 | }, |
| 1478 | .value => |value| self.anon_decls.getPtr(value) orelse blk: { |
| 1479 | const first_exp = exports[0]; |
| 1480 | const res = try self.lowerAnonDecl(value, .none, first_exp.getSrcLoc(mod)); |
| 1481 | switch (res) { |
| 1482 | .ok => {}, |
| 1483 | .fail => |em| { |
| 1484 | // TODO maybe it's enough to return an error here and let Module.processExportsInner |
| 1485 | // handle the error? |
| 1486 | try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1); |
| 1487 | mod.failed_exports.putAssumeCapacityNoClobber(first_exp, em); |
| 1488 | return; |
| 1489 | }, |
| 1490 | } |
| 1491 | break :blk self.anon_decls.getPtr(value).?; |
| 1470 | 1492 | }, |
| 1471 | 1493 | }; |
| 1472 | | const decl = mod.declPtr(decl_index); |
| 1473 | | const atom_index = try self.getOrCreateAtomForDecl(decl_index); |
| 1494 | const atom_index = metadata.atom; |
| 1474 | 1495 | const atom = self.getAtom(atom_index); |
| 1475 | | const decl_metadata = self.decls.getPtr(decl_index).?; |
| 1476 | 1496 | |
| 1477 | 1497 | for (exports) |exp| { |
| 1478 | 1498 | log.debug("adding new export '{}'", .{exp.opts.name.fmt(&mod.intern_pool)}); |
| 1479 | 1499 | |
| 1480 | 1500 | if (mod.intern_pool.stringToSliceUnwrap(exp.opts.section)) |section_name| { |
| 1481 | 1501 | if (!mem.eql(u8, section_name, ".text")) { |
| 1482 | | try mod.failed_exports.putNoClobber( |
| 1502 | try mod.failed_exports.putNoClobber(gpa, exp, try Module.ErrorMsg.create( |
| 1483 | 1503 | gpa, |
| 1484 | | exp, |
| 1485 | | try Module.ErrorMsg.create( |
| 1486 | | gpa, |
| 1487 | | decl.srcLoc(mod), |
| 1488 | | "Unimplemented: ExportOptions.section", |
| 1489 | | .{}, |
| 1490 | | ), |
| 1491 | | ); |
| 1504 | exp.getSrcLoc(mod), |
| 1505 | "Unimplemented: ExportOptions.section", |
| 1506 | .{}, |
| 1507 | )); |
| 1492 | 1508 | continue; |
| 1493 | 1509 | } |
| 1494 | 1510 | } |
| 1495 | 1511 | |
| 1496 | 1512 | if (exp.opts.linkage == .LinkOnce) { |
| 1497 | | try mod.failed_exports.putNoClobber( |
| 1513 | try mod.failed_exports.putNoClobber(gpa, exp, try Module.ErrorMsg.create( |
| 1498 | 1514 | gpa, |
| 1499 | | exp, |
| 1500 | | try Module.ErrorMsg.create( |
| 1501 | | gpa, |
| 1502 | | decl.srcLoc(mod), |
| 1503 | | "Unimplemented: GlobalLinkage.LinkOnce", |
| 1504 | | .{}, |
| 1505 | | ), |
| 1506 | | ); |
| 1515 | exp.getSrcLoc(mod), |
| 1516 | "Unimplemented: GlobalLinkage.LinkOnce", |
| 1517 | .{}, |
| 1518 | )); |
| 1507 | 1519 | continue; |
| 1508 | 1520 | } |
| 1509 | 1521 | |
| 1510 | | const sym_index = decl_metadata.getExport(self, mod.intern_pool.stringToSlice(exp.opts.name)) orelse blk: { |
| 1522 | const sym_index = metadata.getExport(self, mod.intern_pool.stringToSlice(exp.opts.name)) orelse blk: { |
| 1511 | 1523 | const sym_index = try self.allocateSymbol(); |
| 1512 | | try decl_metadata.exports.append(gpa, sym_index); |
| 1524 | try metadata.exports.append(gpa, sym_index); |
| 1513 | 1525 | break :blk sym_index; |
| 1514 | 1526 | }; |
| 1515 | 1527 | const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = null }; |
| 1516 | 1528 | const sym = self.getSymbolPtr(sym_loc); |
| 1517 | 1529 | try self.setSymbolName(sym, mod.intern_pool.stringToSlice(exp.opts.name)); |
| 1518 | 1530 | sym.value = atom.getSymbol(self).value; |
| 1519 | | sym.section_number = @as(coff.SectionNumber, @enumFromInt(self.text_section_index.? + 1)); |
| 1520 | | sym.type = .{ .complex_type = .FUNCTION, .base_type = .NULL }; |
| 1531 | sym.section_number = @as(coff.SectionNumber, @enumFromInt(metadata.section + 1)); |
| 1532 | sym.type = atom.getSymbol(self).type; |
| 1521 | 1533 | |
| 1522 | 1534 | switch (exp.opts.linkage) { |
| 1523 | 1535 | .Strong => { |
| ... | ... | @@ -1761,8 +1773,8 @@ pub fn lowerAnonDecl( |
| 1761 | 1773 | .none => ty.abiAlignment(mod), |
| 1762 | 1774 | else => explicit_alignment, |
| 1763 | 1775 | }; |
| 1764 | | if (self.anon_decls.get(decl_val)) |atom_index| { |
| 1765 | | const existing_addr = self.getAtom(atom_index).getSymbol(self).value; |
| 1776 | if (self.anon_decls.get(decl_val)) |metadata| { |
| 1777 | const existing_addr = self.getAtom(metadata.atom).getSymbol(self).value; |
| 1766 | 1778 | if (decl_alignment.check(existing_addr)) |
| 1767 | 1779 | return .ok; |
| 1768 | 1780 | } |
| ... | ... | @@ -1792,14 +1804,14 @@ pub fn lowerAnonDecl( |
| 1792 | 1804 | .ok => |atom_index| atom_index, |
| 1793 | 1805 | .fail => |em| return .{ .fail = em }, |
| 1794 | 1806 | }; |
| 1795 | | try self.anon_decls.put(gpa, decl_val, atom_index); |
| 1807 | try self.anon_decls.put(gpa, decl_val, .{ .atom = atom_index, .section = self.rdata_section_index.? }); |
| 1796 | 1808 | return .ok; |
| 1797 | 1809 | } |
| 1798 | 1810 | |
| 1799 | 1811 | pub fn getAnonDeclVAddr(self: *Coff, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { |
| 1800 | 1812 | assert(self.llvm_object == null); |
| 1801 | 1813 | |
| 1802 | | const this_atom_index = self.anon_decls.get(decl_val).?; |
| 1814 | const this_atom_index = self.anon_decls.get(decl_val).?.atom; |
| 1803 | 1815 | const sym_index = self.getAtom(this_atom_index).getSymbolIndex().?; |
| 1804 | 1816 | const atom_index = self.getAtomIndexForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?; |
| 1805 | 1817 | const target = SymbolWithLoc{ .sym_index = sym_index, .file = null }; |