From e1ce9a7065e92e3e9b61229c7903f82c3684f489 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Mon, 12 Aug 2024 22:52:11 +0200 Subject: [PATCH] elf: add poorman's reporting tool for unallocated NAVs/UAVs --- src/link/Elf/ZigObject.zig | 46 +++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index 0cb47d7473..4415180597 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -164,6 +164,16 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi if (metadata.rodata_state != .unused) metadata.rodata_state = .flushed; } + if (build_options.enable_logging) { + const pt: Zcu.PerThread = .{ .zcu = elf_file.base.comp.module.?, .tid = tid }; + for (self.navs.keys(), self.navs.values()) |nav_index, meta| { + checkNavAllocated(pt, nav_index, meta); + } + for (self.uavs.keys(), self.uavs.values()) |uav_index, meta| { + checkUavAllocated(pt, uav_index, meta); + } + } + if (self.dwarf) |*dw| { const pt: Zcu.PerThread = .{ .zcu = elf_file.base.comp.module.?, .tid = tid }; try dw.flushModule(pt); @@ -701,6 +711,7 @@ pub fn lowerUav( else => explicit_alignment, }; if (self.uavs.get(uav)) |metadata| { + assert(metadata.allocated); const sym = self.symbol(metadata.symbol_index); const existing_alignment = sym.atom(elf_file).?.alignment; if (uav_alignment.order(existing_alignment).compare(.lte)) @@ -732,7 +743,7 @@ pub fn lowerUav( .ok => |sym_index| sym_index, .fail => |em| return .{ .fail = em }, }; - try self.uavs.put(gpa, uav, .{ .symbol_index = sym_index }); + try self.uavs.put(gpa, uav, .{ .symbol_index = sym_index, .allocated = true }); return .{ .mcv = .{ .load_symbol = sym_index } }; } @@ -921,6 +932,8 @@ fn updateNavCode( esym.st_value = 0; } + self.navs.getPtr(nav_index).?.allocated = true; + if (elf_file.base.child_pid) |pid| { switch (builtin.os.tag) { .linux => { @@ -988,6 +1001,8 @@ fn updateTlv( atom_ptr.alignment = required_alignment; atom_ptr.size = code.len; + self.navs.getPtr(nav_index).?.allocated = true; + { const gop = try self.tls_variables.getOrPut(gpa, atom_ptr.atom_index); assert(!gop.found_existing); // TODO incremental updates @@ -1695,6 +1710,8 @@ const AvMetadata = struct { symbol_index: Symbol.Index, /// A list of all exports aliases of this Av. exports: std.ArrayListUnmanaged(Symbol.Index) = .{}, + /// Set to true if the AV has been initialized and allocated. + allocated: bool = false, fn @"export"(m: AvMetadata, zig_object: *ZigObject, name: []const u8) ?*u32 { for (m.exports.items) |*exp| { @@ -1705,6 +1722,32 @@ const AvMetadata = struct { } }; +fn checkNavAllocated(pt: Zcu.PerThread, index: InternPool.Nav.Index, meta: AvMetadata) void { + if (!meta.allocated) { + const zcu = pt.zcu; + const ip = &zcu.intern_pool; + const nav = ip.getNav(index); + log.err("NAV {}({d}) assigned symbol {d} but not allocated!", .{ + nav.fqn.fmt(ip), + index, + meta.symbol_index, + }); + } +} + +fn checkUavAllocated(pt: Zcu.PerThread, index: InternPool.Index, meta: AvMetadata) void { + if (!meta.allocated) { + const zcu = pt.zcu; + const uav = Value.fromInterned(index); + const ty = uav.typeOf(zcu); + log.err("UAV {}({d}) assigned symbol {d} but not allocated!", .{ + ty.fmt(pt), + index, + meta.symbol_index, + }); + } +} + const TlsVariable = struct { symbol_index: Symbol.Index, code: []const u8 = &[0]u8{}, @@ -1881,6 +1924,7 @@ pub const OffsetTable = struct { }; const assert = std.debug.assert; +const build_options = @import("build_options"); const builtin = @import("builtin"); const codegen = @import("../../codegen.zig"); const elf = std.elf;