| ... | @@ -185,12 +185,12 @@ misc_errors: std.ArrayListUnmanaged(link.File.ErrorMsg) = .{}, | ... | @@ -185,12 +185,12 @@ misc_errors: std.ArrayListUnmanaged(link.File.ErrorMsg) = .{}, |
| 185 | lazy_syms: LazySymbolTable = .{}, | 185 | lazy_syms: LazySymbolTable = .{}, |
| 186 | | 186 | |
| 187 | /// Table of tracked Decls. | 187 | /// Table of tracked Decls. |
| 188 | decls: std.AutoHashMapUnmanaged(Module.Decl.Index, DeclMetadata) = .{}, | 188 | decls: DeclTable = .{}, |
| 189 | | 189 | |
| 190 | /// List of atoms that are owned directly by the linker. | 190 | /// List of atoms that are owned directly by the linker. |
| 191 | atoms: std.ArrayListUnmanaged(Atom) = .{}, | 191 | atoms: std.ArrayListUnmanaged(Atom) = .{}, |
| 192 | /// Table of last atom index in a section and matching atom free list if any. | 192 | /// Table of last atom index in a section and matching atom free list if any. |
| 193 | last_atom_and_free_list_table: std.AutoArrayHashMapUnmanaged(u16, LastAtomAndFreeList) = .{}, | 193 | last_atom_and_free_list_table: LastAtomAndFreeListTable = .{}, |
| 194 | | 194 | |
| 195 | /// Table of unnamed constants associated with a parent `Decl`. | 195 | /// Table of unnamed constants associated with a parent `Decl`. |
| 196 | /// We store them here so that we can free the constants whenever the `Decl` | 196 | /// We store them here so that we can free the constants whenever the `Decl` |
| ... | @@ -220,8 +220,10 @@ comdat_groups_table: std.AutoHashMapUnmanaged(u32, ComdatGroupOwner.Index) = .{} | ... | @@ -220,8 +220,10 @@ comdat_groups_table: std.AutoHashMapUnmanaged(u32, ComdatGroupOwner.Index) = .{} |
| 220 | | 220 | |
| 221 | const AtomList = std.ArrayListUnmanaged(Atom.Index); | 221 | const AtomList = std.ArrayListUnmanaged(Atom.Index); |
| 222 | const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Symbol.Index)); | 222 | const UnnamedConstTable = std.AutoHashMapUnmanaged(Module.Decl.Index, std.ArrayListUnmanaged(Symbol.Index)); |
| 223 | const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, Symbol.Index); | 223 | const DeclTable = std.AutoHashMapUnmanaged(Module.Decl.Index, DeclMetadata); |
| | 224 | const AnonDeclTable = std.AutoHashMapUnmanaged(InternPool.Index, DeclMetadata); |
| 224 | const LazySymbolTable = std.AutoArrayHashMapUnmanaged(Module.Decl.OptionalIndex, LazySymbolMetadata); | 225 | const LazySymbolTable = std.AutoArrayHashMapUnmanaged(Module.Decl.OptionalIndex, LazySymbolMetadata); |
| | 226 | const LastAtomAndFreeListTable = std.AutoArrayHashMapUnmanaged(u16, LastAtomAndFreeList); |
| 225 | | 227 | |
| 226 | /// When allocating, the ideal_capacity is calculated by | 228 | /// When allocating, the ideal_capacity is calculated by |
| 227 | /// actual_capacity + (actual_capacity / ideal_factor) | 229 | /// actual_capacity + (actual_capacity / ideal_factor) |
| ... | @@ -445,7 +447,14 @@ pub fn deinit(self: *Elf) void { | ... | @@ -445,7 +447,14 @@ pub fn deinit(self: *Elf) void { |
| 445 | } | 447 | } |
| 446 | self.unnamed_consts.deinit(gpa); | 448 | self.unnamed_consts.deinit(gpa); |
| 447 | } | 449 | } |
| 448 | self.anon_decls.deinit(gpa); | 450 | |
| | 451 | { |
| | 452 | var it = self.anon_decls.iterator(); |
| | 453 | while (it.next()) |entry| { |
| | 454 | entry.value_ptr.exports.deinit(gpa); |
| | 455 | } |
| | 456 | self.anon_decls.deinit(gpa); |
| | 457 | } |
| 449 | | 458 | |
| 450 | if (self.dwarf) |*dw| { | 459 | if (self.dwarf) |*dw| { |
| 451 | dw.deinit(); | 460 | dw.deinit(); |
| ... | @@ -497,8 +506,8 @@ pub fn lowerAnonDecl( | ... | @@ -497,8 +506,8 @@ pub fn lowerAnonDecl( |
| 497 | .none => ty.abiAlignment(mod), | 506 | .none => ty.abiAlignment(mod), |
| 498 | else => explicit_alignment, | 507 | else => explicit_alignment, |
| 499 | }; | 508 | }; |
| 500 | if (self.anon_decls.get(decl_val)) |sym_index| { | 509 | if (self.anon_decls.get(decl_val)) |metadata| { |
| 501 | const existing_alignment = self.symbol(sym_index).atom(self).?.alignment; | 510 | const existing_alignment = self.symbol(metadata.symbol_index).atom(self).?.alignment; |
| 502 | if (decl_alignment.order(existing_alignment).compare(.lte)) | 511 | if (decl_alignment.order(existing_alignment).compare(.lte)) |
| 503 | return .ok; | 512 | return .ok; |
| 504 | } | 513 | } |
| ... | @@ -528,13 +537,13 @@ pub fn lowerAnonDecl( | ... | @@ -528,13 +537,13 @@ pub fn lowerAnonDecl( |
| 528 | .ok => |sym_index| sym_index, | 537 | .ok => |sym_index| sym_index, |
| 529 | .fail => |em| return .{ .fail = em }, | 538 | .fail => |em| return .{ .fail = em }, |
| 530 | }; | 539 | }; |
| 531 | try self.anon_decls.put(gpa, decl_val, sym_index); | 540 | try self.anon_decls.put(gpa, decl_val, .{ .symbol_index = sym_index }); |
| 532 | return .ok; | 541 | return .ok; |
| 533 | } | 542 | } |
| 534 | | 543 | |
| 535 | pub fn getAnonDeclVAddr(self: *Elf, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { | 544 | pub fn getAnonDeclVAddr(self: *Elf, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { |
| 536 | assert(self.llvm_object == null); | 545 | assert(self.llvm_object == null); |
| 537 | const sym_index = self.anon_decls.get(decl_val).?; | 546 | const sym_index = self.anon_decls.get(decl_val).?.symbol_index; |
| 538 | const sym = self.symbol(sym_index); | 547 | const sym = self.symbol(sym_index); |
| 539 | const vaddr = sym.value; | 548 | const vaddr = sym.value; |
| 540 | const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(self).?; | 549 | const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(self).?; |
| ... | @@ -3122,10 +3131,7 @@ pub fn getOrCreateMetadataForDecl(self: *Elf, decl_index: Module.Decl.Index) !Sy | ... | @@ -3122,10 +3131,7 @@ pub fn getOrCreateMetadataForDecl(self: *Elf, decl_index: Module.Decl.Index) !Sy |
| 3122 | const gop = try self.decls.getOrPut(self.base.allocator, decl_index); | 3131 | const gop = try self.decls.getOrPut(self.base.allocator, decl_index); |
| 3123 | if (!gop.found_existing) { | 3132 | if (!gop.found_existing) { |
| 3124 | const zig_module = self.file(self.zig_module_index.?).?.zig_module; | 3133 | const zig_module = self.file(self.zig_module_index.?).?.zig_module; |
| 3125 | gop.value_ptr.* = .{ | 3134 | gop.value_ptr.* = .{ .symbol_index = try zig_module.addAtom(self) }; |
| 3126 | .symbol_index = try zig_module.addAtom(self), | | |
| 3127 | .exports = .{}, | | |
| 3128 | }; | | |
| 3129 | } | 3135 | } |
| 3130 | return gop.value_ptr.symbol_index; | 3136 | return gop.value_ptr.symbol_index; |
| 3131 | } | 3137 | } |
| ... | @@ -3573,31 +3579,30 @@ pub fn updateExports( | ... | @@ -3573,31 +3579,30 @@ pub fn updateExports( |
| 3573 | defer tracy.end(); | 3579 | defer tracy.end(); |
| 3574 | | 3580 | |
| 3575 | const gpa = self.base.allocator; | 3581 | const gpa = self.base.allocator; |
| 3576 | | 3582 | const zig_module = self.file(self.zig_module_index.?).?.zig_module; |
| 3577 | const decl_index = switch (exported) { | 3583 | const metadata = switch (exported) { |
| 3578 | .decl_index => |i| i, | 3584 | .decl_index => |decl_index| blk: { |
| 3579 | .value => |val| { | 3585 | _ = try self.getOrCreateMetadataForDecl(decl_index); |
| 3580 | _ = val; | 3586 | break :blk self.decls.getPtr(decl_index).?; |
| 3581 | @panic("TODO: implement ELF linker code for exporting a constant value"); | | |
| 3582 | }, | 3587 | }, |
| | 3588 | // TODO is it possible to request export before const being lowered? |
| | 3589 | .value => |value| self.anon_decls.getPtr(value).?, |
| 3583 | }; | 3590 | }; |
| 3584 | const zig_module = self.file(self.zig_module_index.?).?.zig_module; | 3591 | const sym_index = metadata.symbol_index; |
| 3585 | const decl = mod.declPtr(decl_index); | 3592 | const esym_index = self.symbol(sym_index).esym_index; |
| 3586 | const decl_sym_index = try self.getOrCreateMetadataForDecl(decl_index); | 3593 | const esym = zig_module.local_esyms.items(.elf_sym)[esym_index]; |
| 3587 | const decl_esym_index = self.symbol(decl_sym_index).esym_index; | 3594 | const esym_shndx = zig_module.local_esyms.items(.shndx)[esym_index]; |
| 3588 | const decl_esym = zig_module.local_esyms.items(.elf_sym)[decl_esym_index]; | | |
| 3589 | const decl_esym_shndx = zig_module.local_esyms.items(.shndx)[decl_esym_index]; | | |
| 3590 | const decl_metadata = self.decls.getPtr(decl_index).?; | | |
| 3591 | | 3595 | |
| 3592 | for (exports) |exp| { | 3596 | for (exports) |exp| { |
| 3593 | const exp_name = mod.intern_pool.stringToSlice(exp.opts.name); | | |
| 3594 | if (exp.opts.section.unwrap()) |section_name| { | 3597 | if (exp.opts.section.unwrap()) |section_name| { |
| 3595 | if (!mod.intern_pool.stringEqlSlice(section_name, ".text")) { | 3598 | if (!mod.intern_pool.stringEqlSlice(section_name, ".text")) { |
| 3596 | try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1); | 3599 | try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1); |
| 3597 | mod.failed_exports.putAssumeCapacityNoClobber( | 3600 | mod.failed_exports.putAssumeCapacityNoClobber(exp, try Module.ErrorMsg.create( |
| 3598 | exp, | 3601 | gpa, |
| 3599 | try Module.ErrorMsg.create(gpa, decl.srcLoc(mod), "Unimplemented: ExportOptions.section", .{}), | 3602 | exp.getSrcLoc(mod), |
| 3600 | ); | 3603 | "Unimplemented: ExportOptions.section", |
| | 3604 | .{}, |
| | 3605 | )); |
| 3601 | continue; | 3606 | continue; |
| 3602 | } | 3607 | } |
| 3603 | } | 3608 | } |
| ... | @@ -3607,34 +3612,37 @@ pub fn updateExports( | ... | @@ -3607,34 +3612,37 @@ pub fn updateExports( |
| 3607 | .Weak => elf.STB_WEAK, | 3612 | .Weak => elf.STB_WEAK, |
| 3608 | .LinkOnce => { | 3613 | .LinkOnce => { |
| 3609 | try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1); | 3614 | try mod.failed_exports.ensureUnusedCapacity(mod.gpa, 1); |
| 3610 | mod.failed_exports.putAssumeCapacityNoClobber( | 3615 | mod.failed_exports.putAssumeCapacityNoClobber(exp, try Module.ErrorMsg.create( |
| 3611 | exp, | 3616 | gpa, |
| 3612 | try Module.ErrorMsg.create(gpa, decl.srcLoc(mod), "Unimplemented: GlobalLinkage.LinkOnce", .{}), | 3617 | exp.getSrcLoc(mod), |
| 3613 | ); | 3618 | "Unimplemented: GlobalLinkage.LinkOnce", |
| | 3619 | .{}, |
| | 3620 | )); |
| 3614 | continue; | 3621 | continue; |
| 3615 | }, | 3622 | }, |
| 3616 | }; | 3623 | }; |
| 3617 | const stt_bits: u8 = @as(u4, @truncate(decl_esym.st_info)); | 3624 | const stt_bits: u8 = @as(u4, @truncate(esym.st_info)); |
| 3618 | | 3625 | const exp_name = mod.intern_pool.stringToSlice(exp.opts.name); |
| 3619 | const name_off = try self.strtab.insert(gpa, exp_name); | 3626 | const name_off = try self.strtab.insert(gpa, exp_name); |
| 3620 | const sym_index = if (decl_metadata.@"export"(self, exp_name)) |exp_index| exp_index.* else blk: { | 3627 | const global_esym_index = if (metadata.@"export"(self, exp_name)) |exp_index| exp_index.* else blk: { |
| 3621 | const sym_index = try zig_module.addGlobalEsym(gpa); | 3628 | const global_esym_index = try zig_module.addGlobalEsym(gpa); |
| 3622 | const lookup_gop = try zig_module.globals_lookup.getOrPut(gpa, name_off); | 3629 | const lookup_gop = try zig_module.globals_lookup.getOrPut(gpa, name_off); |
| 3623 | const esym = zig_module.elfSym(sym_index); | 3630 | const global_esym = zig_module.elfSym(global_esym_index); |
| 3624 | esym.st_name = name_off; | 3631 | global_esym.st_name = name_off; |
| 3625 | lookup_gop.value_ptr.* = sym_index; | 3632 | lookup_gop.value_ptr.* = global_esym_index; |
| 3626 | try decl_metadata.exports.append(gpa, sym_index); | 3633 | try metadata.exports.append(gpa, global_esym_index); |
| 3627 | const gop = try self.getOrPutGlobal(name_off); | 3634 | const gop = try self.getOrPutGlobal(name_off); |
| 3628 | try zig_module.global_symbols.append(gpa, gop.index); | 3635 | try zig_module.global_symbols.append(gpa, gop.index); |
| 3629 | break :blk sym_index; | 3636 | break :blk global_esym_index; |
| 3630 | }; | 3637 | }; |
| 3631 | const global_esym_index = sym_index & ZigModule.symbol_mask; | 3638 | |
| 3632 | const global_esym = &zig_module.global_esyms.items(.elf_sym)[global_esym_index]; | 3639 | const actual_esym_index = global_esym_index & ZigModule.symbol_mask; |
| 3633 | global_esym.st_value = self.symbol(decl_sym_index).value; | 3640 | const global_esym = &zig_module.global_esyms.items(.elf_sym)[actual_esym_index]; |
| 3634 | global_esym.st_shndx = decl_esym.st_shndx; | 3641 | global_esym.st_value = self.symbol(sym_index).value; |
| | 3642 | global_esym.st_shndx = esym.st_shndx; |
| 3635 | global_esym.st_info = (stb_bits << 4) | stt_bits; | 3643 | global_esym.st_info = (stb_bits << 4) | stt_bits; |
| 3636 | global_esym.st_name = name_off; | 3644 | global_esym.st_name = name_off; |
| 3637 | zig_module.global_esyms.items(.shndx)[global_esym_index] = decl_esym_shndx; | 3645 | zig_module.global_esyms.items(.shndx)[actual_esym_index] = esym_shndx; |
| 3638 | } | 3646 | } |
| 3639 | } | 3647 | } |
| 3640 | | 3648 | |