authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-12 22:52:11+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-08-13 13:30:24+02:00
loge1ce9a7065e92e3e9b61229c7903f82c3684f489
tree039c2522ef691cc87253fdbd12c3cb706ef4e6f8
parente3f6ebaea94bb11c2e990e1fa17b48e51e598b5c

elf: add poorman's reporting tool for unallocated NAVs/UAVs


1 files changed, 45 insertions(+), 1 deletions(-)

src/link/Elf/ZigObject.zig+45-1
...@@ -164,6 +164,16 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi...@@ -164,6 +164,16 @@ pub fn flushModule(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !voi
164 if (metadata.rodata_state != .unused) metadata.rodata_state = .flushed;164 if (metadata.rodata_state != .unused) metadata.rodata_state = .flushed;
165 }165 }
166166
167 if (build_options.enable_logging) {
168 const pt: Zcu.PerThread = .{ .zcu = elf_file.base.comp.module.?, .tid = tid };
169 for (self.navs.keys(), self.navs.values()) |nav_index, meta| {
170 checkNavAllocated(pt, nav_index, meta);
171 }
172 for (self.uavs.keys(), self.uavs.values()) |uav_index, meta| {
173 checkUavAllocated(pt, uav_index, meta);
174 }
175 }
176
167 if (self.dwarf) |*dw| {177 if (self.dwarf) |*dw| {
168 const pt: Zcu.PerThread = .{ .zcu = elf_file.base.comp.module.?, .tid = tid };178 const pt: Zcu.PerThread = .{ .zcu = elf_file.base.comp.module.?, .tid = tid };
169 try dw.flushModule(pt);179 try dw.flushModule(pt);
...@@ -701,6 +711,7 @@ pub fn lowerUav(...@@ -701,6 +711,7 @@ pub fn lowerUav(
701 else => explicit_alignment,711 else => explicit_alignment,
702 };712 };
703 if (self.uavs.get(uav)) |metadata| {713 if (self.uavs.get(uav)) |metadata| {
714 assert(metadata.allocated);
704 const sym = self.symbol(metadata.symbol_index);715 const sym = self.symbol(metadata.symbol_index);
705 const existing_alignment = sym.atom(elf_file).?.alignment;716 const existing_alignment = sym.atom(elf_file).?.alignment;
706 if (uav_alignment.order(existing_alignment).compare(.lte))717 if (uav_alignment.order(existing_alignment).compare(.lte))
...@@ -732,7 +743,7 @@ pub fn lowerUav(...@@ -732,7 +743,7 @@ pub fn lowerUav(
732 .ok => |sym_index| sym_index,743 .ok => |sym_index| sym_index,
733 .fail => |em| return .{ .fail = em },744 .fail => |em| return .{ .fail = em },
734 };745 };
735 try self.uavs.put(gpa, uav, .{ .symbol_index = sym_index });746 try self.uavs.put(gpa, uav, .{ .symbol_index = sym_index, .allocated = true });
736 return .{ .mcv = .{ .load_symbol = sym_index } };747 return .{ .mcv = .{ .load_symbol = sym_index } };
737}748}
738749
...@@ -921,6 +932,8 @@ fn updateNavCode(...@@ -921,6 +932,8 @@ fn updateNavCode(
921 esym.st_value = 0;932 esym.st_value = 0;
922 }933 }
923934
935 self.navs.getPtr(nav_index).?.allocated = true;
936
924 if (elf_file.base.child_pid) |pid| {937 if (elf_file.base.child_pid) |pid| {
925 switch (builtin.os.tag) {938 switch (builtin.os.tag) {
926 .linux => {939 .linux => {
...@@ -988,6 +1001,8 @@ fn updateTlv(...@@ -988,6 +1001,8 @@ fn updateTlv(
988 atom_ptr.alignment = required_alignment;1001 atom_ptr.alignment = required_alignment;
989 atom_ptr.size = code.len;1002 atom_ptr.size = code.len;
9901003
1004 self.navs.getPtr(nav_index).?.allocated = true;
1005
991 {1006 {
992 const gop = try self.tls_variables.getOrPut(gpa, atom_ptr.atom_index);1007 const gop = try self.tls_variables.getOrPut(gpa, atom_ptr.atom_index);
993 assert(!gop.found_existing); // TODO incremental updates1008 assert(!gop.found_existing); // TODO incremental updates
...@@ -1695,6 +1710,8 @@ const AvMetadata = struct {...@@ -1695,6 +1710,8 @@ const AvMetadata = struct {
1695 symbol_index: Symbol.Index,1710 symbol_index: Symbol.Index,
1696 /// A list of all exports aliases of this Av.1711 /// A list of all exports aliases of this Av.
1697 exports: std.ArrayListUnmanaged(Symbol.Index) = .{},1712 exports: std.ArrayListUnmanaged(Symbol.Index) = .{},
1713 /// Set to true if the AV has been initialized and allocated.
1714 allocated: bool = false,
16981715
1699 fn @"export"(m: AvMetadata, zig_object: *ZigObject, name: []const u8) ?*u32 {1716 fn @"export"(m: AvMetadata, zig_object: *ZigObject, name: []const u8) ?*u32 {
1700 for (m.exports.items) |*exp| {1717 for (m.exports.items) |*exp| {
...@@ -1705,6 +1722,32 @@ const AvMetadata = struct {...@@ -1705,6 +1722,32 @@ const AvMetadata = struct {
1705 }1722 }
1706};1723};
17071724
1725fn checkNavAllocated(pt: Zcu.PerThread, index: InternPool.Nav.Index, meta: AvMetadata) void {
1726 if (!meta.allocated) {
1727 const zcu = pt.zcu;
1728 const ip = &zcu.intern_pool;
1729 const nav = ip.getNav(index);
1730 log.err("NAV {}({d}) assigned symbol {d} but not allocated!", .{
1731 nav.fqn.fmt(ip),
1732 index,
1733 meta.symbol_index,
1734 });
1735 }
1736}
1737
1738fn checkUavAllocated(pt: Zcu.PerThread, index: InternPool.Index, meta: AvMetadata) void {
1739 if (!meta.allocated) {
1740 const zcu = pt.zcu;
1741 const uav = Value.fromInterned(index);
1742 const ty = uav.typeOf(zcu);
1743 log.err("UAV {}({d}) assigned symbol {d} but not allocated!", .{
1744 ty.fmt(pt),
1745 index,
1746 meta.symbol_index,
1747 });
1748 }
1749}
1750
1708const TlsVariable = struct {1751const TlsVariable = struct {
1709 symbol_index: Symbol.Index,1752 symbol_index: Symbol.Index,
1710 code: []const u8 = &[0]u8{},1753 code: []const u8 = &[0]u8{},
...@@ -1881,6 +1924,7 @@ pub const OffsetTable = struct {...@@ -1881,6 +1924,7 @@ pub const OffsetTable = struct {
1881};1924};
18821925
1883const assert = std.debug.assert;1926const assert = std.debug.assert;
1927const build_options = @import("build_options");
1884const builtin = @import("builtin");1928const builtin = @import("builtin");
1885const codegen = @import("../../codegen.zig");1929const codegen = @import("../../codegen.zig");
1886const elf = std.elf;1930const elf = std.elf;