From 3f2a0c3de47c8d359f3c7316badc281237d6c494 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 10 Aug 2024 17:18:02 +0200 Subject: [PATCH 1/6] elf: ensure we only ever put named symbols in the symtab --- src/link/Elf/ZigObject.zig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index e01c820f89..4eae851650 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -579,6 +579,8 @@ pub fn updateSymtabSize(self: *ZigObject, elf_file: *Elf) !void { for (self.local_symbols.items) |index| { const local = &self.symbols.items[index]; if (local.atom(elf_file)) |atom_ptr| if (!atom_ptr.alive) continue; + const name = local.name(elf_file); + assert(name.len > 0); const esym = local.elfSym(elf_file); switch (esym.st_type()) { elf.STT_SECTION, elf.STT_NOTYPE => continue, @@ -587,7 +589,7 @@ pub fn updateSymtabSize(self: *ZigObject, elf_file: *Elf) !void { local.flags.output_symtab = true; local.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, elf_file); self.output_symtab_ctx.nlocals += 1; - self.output_symtab_ctx.strsize += @as(u32, @intCast(local.name(elf_file).len)) + 1; + self.output_symtab_ctx.strsize += @as(u32, @intCast(name.len)) + 1; } for (self.global_symbols.items, self.symbols_resolver.items) |index, resolv| { From 421b105d85507e6e3a98cfcf932ca6a8d14e2791 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 10 Aug 2024 17:19:37 +0200 Subject: [PATCH 2/6] macho: ensure we only ever put named symbols in the symtab --- src/link/MachO/ZigObject.zig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/link/MachO/ZigObject.zig b/src/link/MachO/ZigObject.zig index eb240017ea..98c18643fd 100644 --- a/src/link/MachO/ZigObject.zig +++ b/src/link/MachO/ZigObject.zig @@ -550,6 +550,8 @@ pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) void { const file = ref.getFile(macho_file) orelse continue; if (file.getIndex() != self.index) continue; if (sym.getAtom(macho_file)) |atom| if (!atom.isAlive()) continue; + const name = sym.getName(macho_file); + assert(name.len > 0); sym.flags.output_symtab = true; if (sym.isLocal()) { sym.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, macho_file); @@ -562,7 +564,7 @@ pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) void { sym.addExtra(.{ .symtab = self.output_symtab_ctx.nimports }, macho_file); self.output_symtab_ctx.nimports += 1; } - self.output_symtab_ctx.strsize += @as(u32, @intCast(sym.getName(macho_file).len + 1)); + self.output_symtab_ctx.strsize += @as(u32, @intCast(name.len + 1)); } } From 5d6e49d0655b4523c249f1d62da9dc477f1c82af Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 10 Aug 2024 22:15:14 +0200 Subject: [PATCH 3/6] Elf/ZigObject: handle ref to an extern in getDeclVAddr Prior to this change, we would unconditionally create a symbol and atom pair for a Decl that could point to an extern, in which case no atom can be created. --- src/link/Elf.zig | 4 ++-- src/link/Elf/ZigObject.zig | 33 +++++++++++++++++++++++---------- 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/link/Elf.zig b/src/link/Elf.zig index e5885cefc4..16f8739b02 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -478,9 +478,9 @@ pub fn deinit(self: *Elf) void { self.comdat_group_sections.deinit(gpa); } -pub fn getDeclVAddr(self: *Elf, _: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 { +pub fn getDeclVAddr(self: *Elf, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 { assert(self.llvm_object == null); - return self.zigObjectPtr().?.getDeclVAddr(self, decl_index, reloc_info); + return self.zigObjectPtr().?.getDeclVAddr(self, pt, decl_index, reloc_info); } pub fn lowerAnonDecl( diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index 4eae851650..8384399eb9 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -664,10 +664,22 @@ pub fn codeAlloc(self: *ZigObject, elf_file: *Elf, atom_index: Atom.Index) ![]u8 pub fn getDeclVAddr( self: *ZigObject, elf_file: *Elf, + pt: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo, ) !u64 { - const this_sym_index = try self.getOrCreateMetadataForDecl(elf_file, decl_index); + const zcu = pt.zcu; + const ip = &zcu.intern_pool; + const decl = zcu.declPtr(decl_index); + log.debug("getDeclVAddr {}({d})", .{ decl.fqn.fmt(ip), decl_index }); + const this_sym_index = if (decl.isExtern(zcu)) blk: { + const name = decl.name.toSlice(ip); + const lib_name = if (decl.getOwnedExternFunc(zcu)) |ext_fn| + ext_fn.lib_name.toSlice(ip) + else + decl.getOwnedVariable(zcu).?.lib_name.toSlice(ip); + break :blk try self.getGlobalSymbol(elf_file, name, lib_name); + } else try self.getOrCreateMetadataForDecl(elf_file, decl_index); const this_sym = self.symbol(this_sym_index); const vaddr = this_sym.address(.{}, elf_file); const parent_atom = self.symbol(reloc_info.parent_atom_index).atom(elf_file).?; @@ -810,10 +822,8 @@ fn freeDeclMetadata(self: *ZigObject, elf_file: *Elf, sym_index: Symbol.Index) v pub fn freeDecl(self: *ZigObject, elf_file: *Elf, decl_index: InternPool.DeclIndex) void { const gpa = elf_file.base.comp.gpa; - const mod = elf_file.base.comp.module.?; - const decl = mod.declPtr(decl_index); - log.debug("freeDecl {*}", .{decl}); + log.debug("freeDecl ({d})", .{decl_index}); if (self.decls.fetchRemove(decl_index)) |const_kv| { var kv = const_kv; @@ -923,7 +933,7 @@ fn updateDeclCode( const ip = &mod.intern_pool; const decl = mod.declPtr(decl_index); - log.debug("updateDeclCode {}{*}", .{ decl.fqn.fmt(ip), decl }); + log.debug("updateDeclCode {}({d})", .{ decl.fqn.fmt(ip), decl_index }); const required_alignment = decl.getAlignment(pt).max( target_util.minFunctionAlignment(mod.getTarget()), @@ -1023,7 +1033,7 @@ fn updateTlv( const gpa = mod.gpa; const decl = mod.declPtr(decl_index); - log.debug("updateTlv {} ({*})", .{ decl.fqn.fmt(ip), decl }); + log.debug("updateTlv {}({d})", .{ decl.fqn.fmt(ip), decl_index }); const required_alignment = decl.getAlignment(pt); @@ -1077,11 +1087,14 @@ pub fn updateFunc( defer tracy.end(); const mod = pt.zcu; + const ip = &mod.intern_pool; const gpa = elf_file.base.comp.gpa; const func = mod.funcInfo(func_index); const decl_index = func.owner_decl; const decl = mod.declPtr(decl_index); + log.debug("updateFunc {}({d})", .{ decl.fqn.fmt(ip), decl_index }); + const sym_index = try self.getOrCreateMetadataForDecl(elf_file, decl_index); self.freeUnnamedConsts(elf_file, decl_index); self.symbol(sym_index).atom(elf_file).?.freeRelocs(elf_file); @@ -1139,12 +1152,12 @@ pub fn updateDecl( defer tracy.end(); const mod = pt.zcu; + const ip = &mod.intern_pool; const decl = mod.declPtr(decl_index); - if (decl.val.getExternFunc(mod)) |_| { - return; - } + log.debug("updateDecl {}({d})", .{ decl.fqn.fmt(ip), decl_index }); + if (decl.val.getExternFunc(mod)) |_| return; if (decl.isExtern(mod)) { // Extern variable gets a .got entry only. const variable = decl.getOwnedVariable(mod).?; @@ -1485,7 +1498,7 @@ pub fn updateDeclLineNumber( const decl = pt.zcu.declPtr(decl_index); - log.debug("updateDeclLineNumber {}{*}", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl }); + log.debug("updateDeclLineNumber {}({d})", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl_index }); if (self.dwarf) |*dw| { try dw.updateDeclLineNumber(pt.zcu, decl_index); From 8f82a66019dac33ee1065ffe9e4520949203a9a6 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 10 Aug 2024 22:17:19 +0200 Subject: [PATCH 4/6] MachO/ZigObject: handle ref to an extern in getDeclVAddr --- src/link/MachO.zig | 4 ++-- src/link/MachO/ZigObject.zig | 14 +++++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 71c67e57ad..d57a7ff7c0 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -3042,9 +3042,9 @@ pub fn freeDecl(self: *MachO, decl_index: InternPool.DeclIndex) void { return self.getZigObject().?.freeDecl(decl_index); } -pub fn getDeclVAddr(self: *MachO, _: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 { +pub fn getDeclVAddr(self: *MachO, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 { assert(self.llvm_object == null); - return self.getZigObject().?.getDeclVAddr(self, decl_index, reloc_info); + return self.getZigObject().?.getDeclVAddr(self, pt, decl_index, reloc_info); } pub fn lowerAnonDecl( diff --git a/src/link/MachO/ZigObject.zig b/src/link/MachO/ZigObject.zig index 98c18643fd..896bcf7afc 100644 --- a/src/link/MachO/ZigObject.zig +++ b/src/link/MachO/ZigObject.zig @@ -694,10 +694,22 @@ pub fn flushModule(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) pub fn getDeclVAddr( self: *ZigObject, macho_file: *MachO, + pt: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo, ) !u64 { - const sym_index = try self.getOrCreateMetadataForDecl(macho_file, decl_index); + const zcu = pt.zcu; + const ip = &zcu.intern_pool; + const decl = zcu.declPtr(decl_index); + log.debug("getDeclVAddr {}({d})", .{ decl.fqn.fmt(ip), decl_index }); + const sym_index = if (decl.isExtern(zcu)) blk: { + const name = decl.name.toSlice(ip); + const lib_name = if (decl.getOwnedExternFunc(zcu)) |ext_fn| + ext_fn.lib_name.toSlice(ip) + else + decl.getOwnedVariable(zcu).?.lib_name.toSlice(ip); + break :blk try self.getGlobalSymbol(macho_file, name, lib_name); + } else try self.getOrCreateMetadataForDecl(macho_file, decl_index); const sym = self.symbols.items[sym_index]; const vaddr = sym.getAddress(.{}, macho_file); const parent_atom = self.symbols.items[reloc_info.parent_atom_index].getAtom(macho_file).?; From 62fad66d648f8eb9d734a8d8aa36ea56f398c0f2 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 10 Aug 2024 22:19:36 +0200 Subject: [PATCH 5/6] Coff: handle ref to an extern in getDeclVAddr --- src/link/Coff.zig | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/link/Coff.zig b/src/link/Coff.zig index a7b16e9bd5..54e8504d00 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -1856,11 +1856,23 @@ pub fn flushModule(self: *Coff, arena: Allocator, tid: Zcu.PerThread.Id, prog_no assert(!self.imports_count_dirty); } -pub fn getDeclVAddr(self: *Coff, _: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 { +pub fn getDeclVAddr(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 { assert(self.llvm_object == null); - - const this_atom_index = try self.getOrCreateAtomForDecl(decl_index); - const sym_index = self.getAtom(this_atom_index).getSymbolIndex().?; + const zcu = pt.zcu; + const ip = &zcu.intern_pool; + const decl = zcu.declPtr(decl_index); + log.debug("getDeclVAddr {}({d})", .{ decl.fqn.fmt(ip), decl_index }); + const sym_index = if (decl.isExtern(zcu)) blk: { + const name = decl.name.toSlice(ip); + const lib_name = if (decl.getOwnedExternFunc(zcu)) |ext_fn| + ext_fn.lib_name.toSlice(ip) + else + decl.getOwnedVariable(zcu).?.lib_name.toSlice(ip); + break :blk try self.getGlobalSymbol(name, lib_name); + } else blk: { + const this_atom_index = try self.getOrCreateAtomForDecl(decl_index); + break :blk self.getAtom(this_atom_index).getSymbolIndex().?; + }; const atom_index = self.getAtomIndexForSymbol(.{ .sym_index = reloc_info.parent_atom_index, .file = null }).?; const target = SymbolWithLoc{ .sym_index = sym_index, .file = null }; try Atom.addRelocation(self, atom_index, .{ From 5dffd8cb7b5bfa68c9c0cbc1c7dc3590a6e0a42f Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Sat, 10 Aug 2024 22:22:09 +0200 Subject: [PATCH 6/6] Wasm: handle ref to an extern in getDeclVAddr --- src/link/Wasm/ZigObject.zig | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/link/Wasm/ZigObject.zig b/src/link/Wasm/ZigObject.zig index 28c5ccd28a..e3c257cd70 100644 --- a/src/link/Wasm/ZigObject.zig +++ b/src/link/Wasm/ZigObject.zig @@ -790,11 +790,22 @@ pub fn getDeclVAddr( reloc_info: link.File.RelocInfo, ) !u64 { const target = wasm_file.base.comp.root_mod.resolved_target.result; - const gpa = pt.zcu.gpa; - const decl = pt.zcu.declPtr(decl_index); + const zcu = pt.zcu; + const ip = &zcu.intern_pool; + const gpa = zcu.gpa; + const decl = zcu.declPtr(decl_index); const target_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index); - const target_symbol_index = @intFromEnum(wasm_file.getAtom(target_atom_index).sym_index); + const target_atom = wasm_file.getAtom(target_atom_index); + const target_symbol_index = @intFromEnum(target_atom.sym_index); + if (decl.isExtern(zcu)) { + const name = decl.name.toSlice(ip); + const lib_name = if (decl.getOwnedExternFunc(zcu)) |ext_fn| + ext_fn.lib_name.toSlice(ip) + else + decl.getOwnedVariable(zcu).?.lib_name.toSlice(ip); + try zig_object.addOrUpdateImport(wasm_file, name, target_atom.sym_index, lib_name, null); + } std.debug.assert(reloc_info.parent_atom_index != 0); const atom_index = wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = @enumFromInt(reloc_info.parent_atom_index) }).?;