authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-06 16:19:36-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-07 16:11:00-04:00
logbf68590236d6d7ceb0283cb706d76717755c896a
treef23777b0a46ad8cdc19fb191ceb55da5537e2bef
parent72c64dd1976f7ea87f56ba640181d4f45dda2090

Dwarf2: implement comptime navs


4 files changed, 257 insertions(+), 95 deletions(-)

src/Zcu/PerThread.zig+19-3
...@@ -2657,7 +2657,13 @@ fn computeAliveFiles(pt: Zcu.PerThread) Allocator.Error!bool {...@@ -2657,7 +2657,13 @@ fn computeAliveFiles(pt: Zcu.PerThread) Allocator.Error!bool {
2657 // We've not necessarily generated builtin modules yet, so `doImport` could fail. Instead,2657 // We've not necessarily generated builtin modules yet, so `doImport` could fail. Instead,
2658 // create the module here. Then, since we know that `builtin.zig` doesn't have an error and2658 // create the module here. Then, since we know that `builtin.zig` doesn't have an error and
2659 // has no imports other than 'std', we can just continue onto the next import.2659 // has no imports other than 'std', we can just continue onto the next import.
2660 try pt.updateBuiltinModule(file.mod.?.getBuiltinOptions(comp.config));2660 const res = try pt.updateBuiltinModule(file.mod.?.getBuiltinOptions(comp.config));
2661 const gop = zcu.alive_files.getOrPutAssumeCapacity(res.file);
2662 if (!gop.found_existing) gop.value_ptr.* = .{ .import = .{
2663 .importer = file_idx,
2664 .tok = item.data.token,
2665 .module = res.module_root,
2666 } };
2661 continue;2667 continue;
2662 }2668 }
26632669
...@@ -2756,14 +2762,20 @@ fn computeAliveFiles(pt: Zcu.PerThread) Allocator.Error!bool {...@@ -2756,14 +2762,20 @@ fn computeAliveFiles(pt: Zcu.PerThread) Allocator.Error!bool {
2756/// up-to-date, setting a misc failure if updating it fails.2762/// up-to-date, setting a misc failure if updating it fails.
2757/// Asserts that the imported `builtin.zig` has no ZIR errors, and that it has only one2763/// Asserts that the imported `builtin.zig` has no ZIR errors, and that it has only one
2758/// import, which is 'std'.2764/// import, which is 'std'.
2759pub fn updateBuiltinModule(pt: Zcu.PerThread, opts: Builtin) Allocator.Error!void {2765fn updateBuiltinModule(pt: Zcu.PerThread, opts: Builtin) Allocator.Error!struct {
2766 file: Zcu.File.Index,
2767 module_root: *Module,
2768} {
2760 const zcu = pt.zcu;2769 const zcu = pt.zcu;
2761 const comp = zcu.comp;2770 const comp = zcu.comp;
2762 const gpa = comp.gpa;2771 const gpa = comp.gpa;
2763 const io = comp.io;2772 const io = comp.io;
27642773
2765 const gop = try zcu.builtin_modules.getOrPut(gpa, opts.hash());2774 const gop = try zcu.builtin_modules.getOrPut(gpa, opts.hash());
2766 if (gop.found_existing) return; // the `File` is up-to-date2775 if (gop.found_existing) return .{ // the `File` is up-to-date
2776 .file = zcu.module_roots.get(gop.value_ptr.*).?.unwrap().?,
2777 .module_root = gop.value_ptr.*,
2778 };
2767 errdefer _ = zcu.builtin_modules.pop();2779 errdefer _ = zcu.builtin_modules.pop();
27682780
2769 const mod: *Module = try .createBuiltin(comp.arena, opts, comp.dirs);2781 const mod: *Module = try .createBuiltin(comp.arena, opts, comp.dirs);
...@@ -2829,6 +2841,10 @@ pub fn updateBuiltinModule(pt: Zcu.PerThread, opts: Builtin) Allocator.Error!voi...@@ -2829,6 +2841,10 @@ pub fn updateBuiltinModule(pt: Zcu.PerThread, opts: Builtin) Allocator.Error!voi
2829 "unable to write '{f}': {s}",2841 "unable to write '{f}': {s}",
2830 .{ file.path.fmt(comp), @errorName(err) },2842 .{ file.path.fmt(comp), @errorName(err) },
2831 );2843 );
2844 return .{
2845 .file = file_index,
2846 .module_root = mod,
2847 };
2832}2848}
28332849
2834pub fn embedFile(2850pub fn embedFile(
src/link/Dwarf2.zig+202-60
...@@ -81,6 +81,7 @@ pub const Unit = struct {...@@ -81,6 +81,7 @@ pub const Unit = struct {
81 ui: Unit.Index,81 ui: Unit.Index,
82 zfi: Zcu.File.Index,82 zfi: Zcu.File.Index,
83 ) std.mem.Allocator.Error!struct { DirIndex, FileIndex } {83 ) std.mem.Allocator.Error!struct { DirIndex, FileIndex } {
84 assert(unit.alive);
84 try unit.dirs.ensureUnusedCapacity(gpa, 1);85 try unit.dirs.ensureUnusedCapacity(gpa, 1);
85 try unit.files.ensureUnusedCapacity(gpa, 1);86 try unit.files.ensureUnusedCapacity(gpa, 1);
86 const dir_gop = unit.dirs.getOrPutAssumeCapacity(ui);87 const dir_gop = unit.dirs.getOrPutAssumeCapacity(ui);
...@@ -737,8 +738,8 @@ pub const WipNav = struct {...@@ -737,8 +738,8 @@ pub const WipNav = struct {
737 try dl_w.writeByte(DW.LNE.set_address);738 try dl_w.writeByte(DW.LNE.set_address);
738 try dwarf.addrSym(dl_nw, debug.wip_nav.func_si, 0);739 try dwarf.addrSym(dl_nw, debug.wip_nav.func_si, 0);
739740
740 const unit = dwarf.getUnit(zf.mod.?);741 const ui = dwarf.getUnit(zf.mod.?);
741 _, const fi = try unit.get(dwarf).getFile(zcu.gpa, unit, inst_info.file);742 _, const fi = try ui.get(dwarf).getFile(zcu.gpa, ui, inst_info.file);
742 try dl_w.writeByte(DW.LNS.set_file);743 try dl_w.writeByte(DW.LNS.set_file);
743 try dl_w.writeUleb128(@backingInt(fi));744 try dl_w.writeUleb128(@backingInt(fi));
744745
...@@ -1515,7 +1516,6 @@ pub fn getDecl(...@@ -1515,7 +1516,6 @@ pub fn getDecl(
1515 pt: Zcu.PerThread,1516 pt: Zcu.PerThread,
1516 instance_val: InternPool.Index,1517 instance_val: InternPool.Index,
1517) link.Error!link.MappedFile.Node.Index {1518) link.Error!link.MappedFile.Node.Index {
1518 assert(dwarf.pending_decl.instance_val == .none);
1519 const comp = dwarf.lf.comp;1519 const comp = dwarf.lf.comp;
1520 const gpa = comp.gpa;1520 const gpa = comp.gpa;
1521 const zcu = pt.zcu;1521 const zcu = pt.zcu;
...@@ -1949,11 +1949,11 @@ pub fn genDebugRnglists(...@@ -1949,11 +1949,11 @@ pub fn genDebugRnglists(
1949pub fn updateComptimeNav(1949pub fn updateComptimeNav(
1950 dwarf: *Dwarf,1950 dwarf: *Dwarf,
1951 pt: Zcu.PerThread,1951 pt: Zcu.PerThread,
1952 nav_index: InternPool.Nav.Index,1952 ni: InternPool.Nav.Index,
1953) link.Error!void {1953) link.Error!void {
1954 const zcu = pt.zcu;1954 const zcu = pt.zcu;
1955 const ip = &zcu.intern_pool;1955 const ip = &zcu.intern_pool;
1956 const nav = ip.getNav(nav_index);1956 const nav = ip.getNav(ni);
1957 log.debug("updateComptimeNav({f})", .{nav.fqn.fmt(ip)});1957 log.debug("updateComptimeNav({f})", .{nav.fqn.fmt(ip)});
1958 const inst_info = nav.srcInst(ip).resolveFull(ip).?;1958 const inst_info = nav.srcInst(ip).resolveFull(ip).?;
1959 const nav_val: Value = .fromInterned(nav.resolved.?.value);1959 const nav_val: Value = .fromInterned(nav.resolved.?.value);
...@@ -1964,49 +1964,184 @@ pub fn updateComptimeNav(...@@ -1964,49 +1964,184 @@ pub fn updateComptimeNav(
1964 .@"comptime", .@"const", .@"var" => {},1964 .@"comptime", .@"const", .@"var" => {},
1965 }1965 }
1966 done: switch (ip.indexToKey(nav_val.toIntern())) {1966 done: switch (ip.indexToKey(nav_val.toIntern())) {
1967 .int_type,
1968 .ptr_type,
1969 .array_type,
1970 .vector_type,
1971 .opt_type,
1972 .error_union_type,
1973 .anyframe_type,
1974 .simple_type,
1975 .tuple_type,
1976 .func_type,
1977 .error_set_type,
1978 .inferred_error_set_type,
1979 .spirv_type,
1980 => try dwarf.genDeclType(pt, ni, &decl),
1967 .struct_type => {1981 .struct_type => {
1968 const loaded_struct = ip.loadStructType(nav_val.toIntern());1982 const loaded_struct = ip.loadStructType(nav_val.toIntern());
1969 if (nav_index.toOptional() == loaded_struct.name_nav) {1983 if (ni.toOptional() == loaded_struct.name_nav)
1970 _ = try dwarf.const_pool.get(pt, dwarf.constPoolUser(), nav_val.toIntern());1984 _ = try dwarf.const_pool.get(pt, dwarf.constPoolUser(), nav_val.toIntern())
1971 break :done;1985 else
1972 }1986 try dwarf.genDeclType(pt, ni, &decl);
1973 return;
1974 },1987 },
1975 .enum_type => {1988 .enum_type => {
1976 const loaded_enum = ip.loadEnumType(nav_val.toIntern());1989 const loaded_enum = ip.loadEnumType(nav_val.toIntern());
1977 if (nav_index.toOptional() == loaded_enum.name_nav) {1990 if (ni.toOptional() == loaded_enum.name_nav)
1978 _ = try dwarf.const_pool.get(pt, dwarf.constPoolUser(), nav_val.toIntern());1991 _ = try dwarf.const_pool.get(pt, dwarf.constPoolUser(), nav_val.toIntern())
1979 break :done;1992 else
1980 }1993 try dwarf.genDeclType(pt, ni, &decl);
1981 return;
1982 },1994 },
1983 .union_type => {1995 .union_type => {
1984 const loaded_union = ip.loadUnionType(nav_val.toIntern());1996 const loaded_union = ip.loadUnionType(nav_val.toIntern());
1985 if (nav_index.toOptional() == loaded_union.name_nav) {1997 if (ni.toOptional() == loaded_union.name_nav)
1986 _ = try dwarf.const_pool.get(pt, dwarf.constPoolUser(), nav_val.toIntern());1998 _ = try dwarf.const_pool.get(pt, dwarf.constPoolUser(), nav_val.toIntern())
1987 break :done;1999 else
1988 }2000 try dwarf.genDeclType(pt, ni, &decl);
1989 return;
1990 },2001 },
1991 .opaque_type => {2002 .opaque_type => {
1992 const loaded_opaque = ip.loadOpaqueType(nav_val.toIntern());2003 const loaded_opaque = ip.loadOpaqueType(nav_val.toIntern());
1993 if (nav_index.toOptional() == loaded_opaque.name_nav) {2004 if (ni.toOptional() == loaded_opaque.name_nav)
1994 _ = try dwarf.const_pool.get(pt, dwarf.constPoolUser(), nav_val.toIntern());2005 _ = try dwarf.const_pool.get(pt, dwarf.constPoolUser(), nav_val.toIntern())
1995 break :done;2006 else
1996 }2007 try dwarf.genDeclType(pt, ni, &decl);
1997 return;2008 },
1998 },2009 .undef,
1999 .func => |func| if (func.owner_nav == nav_index and func.generic_owner == .none) {2010 .simple_value,
2011 .int,
2012 .err,
2013 .error_union,
2014 .enum_literal,
2015 .enum_tag,
2016 .float,
2017 .ptr,
2018 .slice,
2019 .opt,
2020 .aggregate,
2021 .un,
2022 .bitpack,
2023 => try dwarf.genDeclValue(pt, ni, &decl),
2024 .@"extern" => unreachable,
2025 .func => |func| if (func.owner_nav == ni and func.generic_owner == .none) {
2000 _ = try dwarf.const_pool.get(pt, dwarf.constPoolUser(), nav_val.toIntern());2026 _ = try dwarf.const_pool.get(pt, dwarf.constPoolUser(), nav_val.toIntern());
2001 break :done;2027 break :done;
2002 } else return,2028 } else return,
2003
2004 else => return,
2005
2006 // memoization, not values2029 // memoization, not values
2007 .memoized_call => unreachable,2030 .memoized_call => unreachable,
2008 }2031 }
2009 try dwarf.const_pool.flushPending(pt, dwarf.constPoolUser());2032}
2033
2034fn genDeclType(
2035 dwarf: *Dwarf,
2036 pt: Zcu.PerThread,
2037 ni: InternPool.Nav.Index,
2038 decl: *const std.zig.Zir.Inst.Declaration.Unwrapped,
2039) link.Error!void {
2040 const gi = try dwarf.getGlobal(ni);
2041 const debug_info_ni = gi.get(dwarf).debug_info_ni.unwrap().?;
2042 var di_nw: link.MappedFile.Node.Writer = undefined;
2043 if (dwarf.lf.cast(.elf2)) |elf| {
2044 debug_info_ni.writer(pt.zcu.gpa, &elf.mf, &di_nw);
2045 elf.resetNodeRelocs(debug_info_ni);
2046 } else unreachable;
2047 defer di_nw.deinit();
2048 dwarf.genDeclTypeInner(pt, &di_nw, ni, decl) catch |err| switch (err) {
2049 error.WriteFailed => return dwarf.reportWriteError(&di_nw),
2050 else => |e| return e,
2051 };
2052}
2053fn genDeclTypeInner(
2054 dwarf: *Dwarf,
2055 pt: Zcu.PerThread,
2056 di_nw: *link.MappedFile.Node.Writer,
2057 ni: InternPool.Nav.Index,
2058 decl: *const std.zig.Zir.Inst.Declaration.Unwrapped,
2059) link.EmitError!void {
2060 const ip = &pt.zcu.intern_pool;
2061 const nav = ip.getNav(ni);
2062 const parent_ni = try dwarf.getDecl(pt, ip.namespacePtr(nav.analysis.?.namespace).owner_type);
2063 const di_w = &di_nw.interface;
2064 try dwarf.abbrevCode(di_nw, .decl_type);
2065 try dwarf.secOffset(di_nw, parent_ni, 0);
2066 try di_w.writeInt(u32, decl.src_line + 1, dwarf.endian);
2067 try di_w.writeUleb128(decl.src_column + 1);
2068 try di_w.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
2069 try dwarf.strp(&dwarf.debug_str, di_nw, nav.name.toSlice(ip));
2070 try dwarf.refConst(pt, di_nw, .fromInterned(nav.resolved.?.value));
2071 try dwarf.genDebugInfoPadding(di_w, di_w.unusedCapacityLen());
2072}
2073
2074fn genDeclValue(
2075 dwarf: *Dwarf,
2076 pt: Zcu.PerThread,
2077 ni: InternPool.Nav.Index,
2078 decl: *const std.zig.Zir.Inst.Declaration.Unwrapped,
2079) link.Error!void {
2080 const gi = try dwarf.getGlobal(ni);
2081 const debug_info_ni = gi.get(dwarf).debug_info_ni.unwrap().?;
2082 var di_nw: link.MappedFile.Node.Writer = undefined;
2083 if (dwarf.lf.cast(.elf2)) |elf| {
2084 debug_info_ni.writer(pt.zcu.gpa, &elf.mf, &di_nw);
2085 elf.resetNodeRelocs(debug_info_ni);
2086 } else unreachable;
2087 defer di_nw.deinit();
2088 dwarf.genDeclValueInner(pt, &di_nw, ni, decl) catch |err| switch (err) {
2089 error.WriteFailed => return dwarf.reportWriteError(&di_nw),
2090 else => |e| return e,
2091 };
2092}
2093fn genDeclValueInner(
2094 dwarf: *Dwarf,
2095 pt: Zcu.PerThread,
2096 di_nw: *link.MappedFile.Node.Writer,
2097 ni: InternPool.Nav.Index,
2098 decl: *const std.zig.Zir.Inst.Declaration.Unwrapped,
2099) link.EmitError!void {
2100 const zcu = pt.zcu;
2101 const ip = &zcu.intern_pool;
2102 const nav = ip.getNav(ni);
2103 const nav_const, const nav_ty: Type, const nav_align, const nav_val: Value = resolved: {
2104 const resolved = nav.resolved.?;
2105 break :resolved .{
2106 resolved.@"const",
2107 .fromInterned(resolved.type),
2108 resolved.@"align",
2109 .fromInterned(resolved.value),
2110 };
2111 };
2112 const nav_class = nav_ty.classify(zcu);
2113 const parent_ni = try dwarf.getDecl(pt, ip.namespacePtr(nav.analysis.?.namespace).owner_type);
2114 const di_w = &di_nw.interface;
2115 try dwarf.abbrevCode(di_nw, if (nav_const) switch (nav_class) {
2116 .no_possible_value, .one_possible_value => .decl_const,
2117 .runtime => .decl_const_fully_runtime,
2118 .partially_comptime => .decl_const_partially_comptime,
2119 .fully_comptime => .decl_const_fully_comptime,
2120 } else .decl_var);
2121 try dwarf.secOffset(di_nw, parent_ni, 0);
2122 try di_w.writeInt(u32, decl.src_line + 1, dwarf.endian);
2123 try di_w.writeUleb128(decl.src_column + 1);
2124 try di_w.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private);
2125 try dwarf.strp(&dwarf.debug_str, di_nw, nav.name.toSlice(ip));
2126 try dwarf.strp(&dwarf.debug_str, di_nw, switch (decl.linkage) {
2127 .normal => nav.fqn,
2128 .@"extern", .@"export" => nav.name,
2129 }.toSlice(ip));
2130 const type_offset = di_w.end;
2131 if (nav_const) try dwarf.secOffsetPlaceholder(di_w) else {
2132 try dwarf.refType(pt, di_nw, nav_ty);
2133 try dwarf.blockConst(pt, di_nw, nav_val);
2134 }
2135 try di_w.writeUleb128(nav_align.toByteUnits() orelse nav_ty.abiAlignment(zcu).toByteUnits().?);
2136 try di_w.writeByte(@intFromBool(decl.linkage != .normal));
2137 if (nav_const) {
2138 if (nav_class.hasRuntimeBits()) try dwarf.blockConst(pt, di_nw, nav_val);
2139 if (nav_class.comptimeOnly()) try dwarf.refConst(pt, di_nw, nav_val);
2140 try dwarf.secOffsetFinish(di_nw, type_offset, di_nw.ni, di_w.end);
2141 try dwarf.abbrevCode(di_nw, .is_const);
2142 try dwarf.refType(pt, di_nw, nav_ty);
2143 }
2144 try dwarf.genDebugInfoPadding(di_w, di_w.unusedCapacityLen());
2010}2145}
20112146
2012pub fn addConst(2147pub fn addConst(
...@@ -2044,9 +2179,11 @@ pub fn addConst(...@@ -2044,9 +2179,11 @@ pub fn addConst(
2044 const name_gi = try dwarf.getGlobal(name_nav);2179 const name_gi = try dwarf.getGlobal(name_nav);
2045 break :debug_info_ni name_gi.get(dwarf).debug_info_ni.unwrap().?;2180 break :debug_info_ni name_gi.get(dwarf).debug_info_ni.unwrap().?;
2046 }2181 }
2047 break :debug_info_ni try addConstNode(dwarf.lf, dwarf.getUnit(zcu.fileByIndex(2182 const mod = zcu.fileByIndex(
2048 Type.fromInterned(val).typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip),2183 Type.fromInterned(val).typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(ip),
2049 ).mod.?), cpi);2184 ).mod.?;
2185 assert(!mod.strip);
2186 break :debug_info_ni try addConstNode(dwarf.lf, dwarf.getUnit(mod), cpi);
2050 },2187 },
2051 }.toOptional(),2188 }.toOptional(),
2052 });2189 });
...@@ -2456,9 +2593,8 @@ fn updateConstInner(...@@ -2456,9 +2593,8 @@ fn updateConstInner(
2456 } else if (loaded_struct.name_nav.unwrap()) |name_ni| {2593 } else if (loaded_struct.name_nav.unwrap()) |name_ni| {
2457 const name_nav = ip.getNav(name_ni);2594 const name_nav = ip.getNav(name_ni);
2458 const decl = zf.zir.?.getDeclaration(name_nav.srcInst(ip).resolve(ip).?);2595 const decl = zf.zir.?.getDeclaration(name_nav.srcInst(ip).resolve(ip).?);
2459 const parent_ni = try dwarf.getDecl(pt, ip.namespacePtr(2596 const parent_ni =
2460 name_nav.analysis.?.namespace,2597 try dwarf.getDecl(pt, ip.namespacePtr(name_nav.analysis.?.namespace).owner_type);
2461 ).owner_type);
2462 try dwarf.abbrevCode(di_nw, if (loaded_struct.field_types.len > 0)2598 try dwarf.abbrevCode(di_nw, if (loaded_struct.field_types.len > 0)
2463 switch (loaded_struct.layout) {2599 switch (loaded_struct.layout) {
2464 .auto, .@"extern" => .decl_struct,2600 .auto, .@"extern" => .decl_struct,
...@@ -2589,9 +2725,8 @@ fn updateConstInner(...@@ -2589,9 +2725,8 @@ fn updateConstInner(
2589 } else if (loaded_union.name_nav.unwrap()) |name_ni| {2725 } else if (loaded_union.name_nav.unwrap()) |name_ni| {
2590 const name_nav = ip.getNav(name_ni);2726 const name_nav = ip.getNav(name_ni);
2591 const decl = zf.zir.?.getDeclaration(name_nav.srcInst(ip).resolve(ip).?);2727 const decl = zf.zir.?.getDeclaration(name_nav.srcInst(ip).resolve(ip).?);
2592 const parent_ni = try dwarf.getDecl(pt, ip.namespacePtr(2728 const parent_ni =
2593 name_nav.analysis.?.namespace,2729 try dwarf.getDecl(pt, ip.namespacePtr(name_nav.analysis.?.namespace).owner_type);
2594 ).owner_type);
2595 try dwarf.abbrevCode(di_nw, if (loaded_union.field_types.len > 0)2730 try dwarf.abbrevCode(di_nw, if (loaded_union.field_types.len > 0)
2596 switch (loaded_union.layout) {2731 switch (loaded_union.layout) {
2597 .auto, .@"extern" => .decl_union,2732 .auto, .@"extern" => .decl_union,
...@@ -3137,9 +3272,8 @@ fn updateConstIncompleteInner(...@@ -3137,9 +3272,8 @@ fn updateConstIncompleteInner(
3137 } else if (maybe_name_nav.unwrap()) |name_ni| {3272 } else if (maybe_name_nav.unwrap()) |name_ni| {
3138 const name_nav = ip.getNav(name_ni);3273 const name_nav = ip.getNav(name_ni);
3139 const decl = zf.zir.?.getDeclaration(name_nav.srcInst(ip).resolve(ip).?);3274 const decl = zf.zir.?.getDeclaration(name_nav.srcInst(ip).resolve(ip).?);
3140 const parent_ni = try dwarf.getDecl(pt, ip.namespacePtr(3275 const parent_ni =
3141 name_nav.analysis.?.namespace,3276 try dwarf.getDecl(pt, ip.namespacePtr(name_nav.analysis.?.namespace).owner_type);
3142 ).owner_type);
3143 try dwarf.abbrevCode(di_nw, if (captures.len > 0) switch (kind) {3277 try dwarf.abbrevCode(di_nw, if (captures.len > 0) switch (kind) {
3144 .@"struct" => .decl_incomplete_struct,3278 .@"struct" => .decl_incomplete_struct,
3145 .@"union" => .decl_incomplete_union,3279 .@"union" => .decl_incomplete_union,
...@@ -3399,9 +3533,8 @@ fn genDeclInner(...@@ -3399,9 +3533,8 @@ fn genDeclInner(
3399 if (maybe_name_nav.unwrap()) |name_ni| {3533 if (maybe_name_nav.unwrap()) |name_ni| {
3400 const name_nav = ip.getNav(name_ni);3534 const name_nav = ip.getNav(name_ni);
3401 const decl = zir.getDeclaration(name_nav.srcInst(ip).resolve(ip).?);3535 const decl = zir.getDeclaration(name_nav.srcInst(ip).resolve(ip).?);
3402 const parent_ni = try dwarf.getDecl(pt, ip.namespacePtr(3536 const parent_ni =
3403 name_nav.analysis.?.namespace,3537 try dwarf.getDecl(pt, ip.namespacePtr(name_nav.analysis.?.namespace).owner_type);
3404 ).owner_type);
3405 try dwarf.abbrevCode(di_nw, if (captures.len > 0) switch (kind) {3538 try dwarf.abbrevCode(di_nw, if (captures.len > 0) switch (kind) {
3406 .@"struct" => .decl_specification_struct,3539 .@"struct" => .decl_specification_struct,
3407 .@"union" => .decl_specification_union,3540 .@"union" => .decl_specification_union,
...@@ -3537,9 +3670,6 @@ pub fn secOffsetSize(dwarf: *Dwarf) usize {...@@ -3537,9 +3670,6 @@ pub fn secOffsetSize(dwarf: *Dwarf) usize {
3537 .@"64" => 8,3670 .@"64" => 8,
3538 };3671 };
3539}3672}
3540fn secOffsetPlaceholder(dwarf: *Dwarf, w: *std.Io.Writer) std.Io.Writer.Error!void {
3541 @memset(try w.writableSlice(dwarf.secOffsetSize()), undefined);
3542}
3543fn secOffset(3673fn secOffset(
3544 dwarf: *Dwarf,3674 dwarf: *Dwarf,
3545 nw: *link.MappedFile.Node.Writer,3675 nw: *link.MappedFile.Node.Writer,
...@@ -3548,6 +3678,18 @@ fn secOffset(...@@ -3548,6 +3678,18 @@ fn secOffset(
3548) link.EmitError!void {3678) link.EmitError!void {
3549 const offset = nw.interface.end;3679 const offset = nw.interface.end;
3550 try dwarf.secOffsetPlaceholder(&nw.interface);3680 try dwarf.secOffsetPlaceholder(&nw.interface);
3681 try dwarf.secOffsetFinish(nw, offset, target_ni, addend);
3682}
3683fn secOffsetPlaceholder(dwarf: *Dwarf, w: *std.Io.Writer) std.Io.Writer.Error!void {
3684 @memset(try w.writableSlice(dwarf.secOffsetSize()), undefined);
3685}
3686fn secOffsetFinish(
3687 dwarf: *Dwarf,
3688 nw: *link.MappedFile.Node.Writer,
3689 offset: usize,
3690 target_ni: link.MappedFile.Node.Index,
3691 addend: usize,
3692) link.Error!void {
3551 if (dwarf.lf.cast(.elf2)) |elf| try elf.addNodeReloc(3693 if (dwarf.lf.cast(.elf2)) |elf| try elf.addNodeReloc(
3552 nw.ni,3694 nw.ni,
3553 offset,3695 offset,
...@@ -3745,7 +3887,7 @@ pub const AbbrevCode = enum {...@@ -3745,7 +3887,7 @@ pub const AbbrevCode = enum {
3745 pad_n,3887 pad_n,
3746 // decl, specification, and instance codes are assumed to all have the same uleb128 size3888 // decl, specification, and instance codes are assumed to all have the same uleb128 size
3747 decl_lost,3889 decl_lost,
3748 decl_alias,3890 decl_type,
3749 decl_empty_incomplete_enum,3891 decl_empty_incomplete_enum,
3750 decl_incomplete_enum,3892 decl_incomplete_enum,
3751 decl_empty_enum,3893 decl_empty_enum,
...@@ -3780,9 +3922,9 @@ pub const AbbrevCode = enum {...@@ -3780,9 +3922,9 @@ pub const AbbrevCode = enum {
3780 type_decl_packed_union,3922 type_decl_packed_union,
3781 decl_var,3923 decl_var,
3782 decl_const,3924 decl_const,
3783 decl_const_runtime_bits,3925 decl_const_fully_runtime,
3784 decl_const_comptime_state,3926 decl_const_partially_comptime,
3785 decl_const_runtime_bits_comptime_state,3927 decl_const_fully_comptime,
3786 decl_empty_func,3928 decl_empty_func,
3787 decl_func,3929 decl_func,
3788 decl_empty_func_generic,3930 decl_empty_func_generic,
...@@ -3802,7 +3944,7 @@ pub const AbbrevCode = enum {...@@ -3802,7 +3944,7 @@ pub const AbbrevCode = enum {
3802 type_decl_specification_empty_union,3944 type_decl_specification_empty_union,
3803 type_decl_specification_union,3945 type_decl_specification_union,
3804 decl_specification_func,3946 decl_specification_func,
3805 decl_instance_alias,3947 decl_instance_type,
3806 decl_instance_empty_incomplete_enum,3948 decl_instance_empty_incomplete_enum,
3807 decl_instance_incomplete_enum,3949 decl_instance_incomplete_enum,
3808 decl_instance_empty_enum,3950 decl_instance_empty_enum,
...@@ -3921,7 +4063,7 @@ pub const AbbrevCode = enum {...@@ -3921,7 +4063,7 @@ pub const AbbrevCode = enum {
3921 comptime {4063 comptime {
3922 assert(uleb128Size(@backingInt(AbbrevCode.pad_1)) == 1);4064 assert(uleb128Size(@backingInt(AbbrevCode.pad_1)) == 1);
3923 assert(uleb128Size(@backingInt(AbbrevCode.pad_n)) == 1);4065 assert(uleb128Size(@backingInt(AbbrevCode.pad_n)) == 1);
3924 assert(uleb128Size(@backingInt(AbbrevCode.decl_alias)) == decl_size);4066 assert(uleb128Size(@backingInt(AbbrevCode.decl_type)) == decl_size);
3925 }4067 }
39264068
3927 const Attr = struct {4069 const Attr = struct {
...@@ -3969,7 +4111,7 @@ pub const AbbrevCode = enum {...@@ -3969,7 +4111,7 @@ pub const AbbrevCode = enum {
3969 .decl_lost = .{4111 .decl_lost = .{
3970 .tag = .ZIG_lost_declaration,4112 .tag = .ZIG_lost_declaration,
3971 },4113 },
3972 .decl_alias = .{4114 .decl_type = .{
3973 .tag = .imported_declaration,4115 .tag = .imported_declaration,
3974 .attrs = decl_attrs ++ .{4116 .attrs = decl_attrs ++ .{
3975 .{ .import, .ref_addr },4117 .{ .import, .ref_addr },
...@@ -4186,7 +4328,7 @@ pub const AbbrevCode = enum {...@@ -4186,7 +4328,7 @@ pub const AbbrevCode = enum {
4186 .{ .external, .flag },4328 .{ .external, .flag },
4187 },4329 },
4188 },4330 },
4189 .decl_const_runtime_bits = .{4331 .decl_const_fully_runtime = .{
4190 .tag = .constant,4332 .tag = .constant,
4191 .attrs = decl_attrs ++ .{4333 .attrs = decl_attrs ++ .{
4192 .{ .linkage_name, .strp },4334 .{ .linkage_name, .strp },
...@@ -4196,24 +4338,24 @@ pub const AbbrevCode = enum {...@@ -4196,24 +4338,24 @@ pub const AbbrevCode = enum {
4196 .{ .const_value, .block },4338 .{ .const_value, .block },
4197 },4339 },
4198 },4340 },
4199 .decl_const_comptime_state = .{4341 .decl_const_partially_comptime = .{
4200 .tag = .constant,4342 .tag = .constant,
4201 .attrs = decl_attrs ++ .{4343 .attrs = decl_attrs ++ .{
4202 .{ .linkage_name, .strp },4344 .{ .linkage_name, .strp },
4203 .{ .type, .ref_addr },4345 .{ .type, .ref_addr },
4204 .{ .alignment, .udata },4346 .{ .alignment, .udata },
4205 .{ .external, .flag },4347 .{ .external, .flag },
4348 .{ .const_value, .block },
4206 .{ .ZIG_comptime_value, .ref_addr },4349 .{ .ZIG_comptime_value, .ref_addr },
4207 },4350 },
4208 },4351 },
4209 .decl_const_runtime_bits_comptime_state = .{4352 .decl_const_fully_comptime = .{
4210 .tag = .constant,4353 .tag = .constant,
4211 .attrs = decl_attrs ++ .{4354 .attrs = decl_attrs ++ .{
4212 .{ .linkage_name, .strp },4355 .{ .linkage_name, .strp },
4213 .{ .type, .ref_addr },4356 .{ .type, .ref_addr },
4214 .{ .alignment, .udata },4357 .{ .alignment, .udata },
4215 .{ .external, .flag },4358 .{ .external, .flag },
4216 .{ .const_value, .block },
4217 .{ .ZIG_comptime_value, .ref_addr },4359 .{ .ZIG_comptime_value, .ref_addr },
4218 },4360 },
4219 },4361 },
...@@ -4334,7 +4476,7 @@ pub const AbbrevCode = enum {...@@ -4334,7 +4476,7 @@ pub const AbbrevCode = enum {
4334 .tag = .subprogram,4476 .tag = .subprogram,
4335 .attrs = decl_specification_attrs,4477 .attrs = decl_specification_attrs,
4336 },4478 },
4337 .decl_instance_alias = .{4479 .decl_instance_type = .{
4338 .tag = .imported_declaration,4480 .tag = .imported_declaration,
4339 .attrs = decl_instance_attrs ++ .{4481 .attrs = decl_instance_attrs ++ .{
4340 .{ .import, .ref_addr },4482 .{ .import, .ref_addr },
src/link/Elf2.zig+35-31
...@@ -7197,7 +7197,7 @@ fn prelinkInner(elf: *Elf) Error!void {...@@ -7197,7 +7197,7 @@ fn prelinkInner(elf: *Elf) Error!void {
7197 };7197 };
7198 elf.input_pending_index += 1;7198 elf.input_pending_index += 1;
71997199
7200 try elf.nodes.ensureUnusedCapacity(gpa, 5 + 4);7200 try elf.nodes.ensureUnusedCapacity(gpa, 4 + 5);
72017201
7202 switch (elf.shndx.debug_abbrev) {7202 switch (elf.shndx.debug_abbrev) {
7203 .UNDEF => {},7203 .UNDEF => {},
...@@ -7301,7 +7301,7 @@ fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {...@@ -7301,7 +7301,7 @@ fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {
7301 });7301 });
7302 }7302 }
7303 if (!try elf.dwarf.updateUnits(zcu)) return;7303 if (!try elf.dwarf.updateUnits(zcu)) return;
7304 try elf.nodes.ensureUnusedCapacity(gpa, 5 * units_len);7304 try elf.nodes.ensureUnusedCapacity(gpa, 6 * units_len);
7305 for (0..units_len) |unit_index| {7305 for (0..units_len) |unit_index| {
7306 const ui: Dwarf.Unit.Index = @fromBackingInt(@intCast(unit_index));7306 const ui: Dwarf.Unit.Index = @fromBackingInt(@intCast(unit_index));
7307 const unit = ui.get(&elf.dwarf);7307 const unit = ui.get(&elf.dwarf);
...@@ -8633,37 +8633,37 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index)...@@ -8633,37 +8633,37 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index)
86338633
8634 const nav = ip.getNav(nav_index);8634 const nav = ip.getNav(nav_index);
8635 if (ip.indexToKey(nav.resolved.?.value) == .@"extern") return;8635 if (ip.indexToKey(nav.resolved.?.value) == .@"extern") return;
8636 if (!Type.fromInterned(nav.resolved.?.type).hasRuntimeBits(zcu)) {8636 if (Type.fromInterned(nav.resolved.?.type).hasRuntimeBits(zcu)) {
8637 if (elf.ehdrMachine() != .X86_64) return;8637 const nmi = try elf.navMapIndex(zcu, nav_index);
8638 const mod = zcu.fileByIndex(nav.srcInst(ip).resolveFile(ip)).mod.?;8638 const ni = nmi.symbol(elf).index().ptr(elf).node.unwrap().?;
8639 return if (!mod.strip) elf.dwarf.updateComptimeNav(pt, nav_index);
8640 }
8641
8642 const nmi = try elf.navMapIndex(zcu, nav_index);
8643 const ni = nmi.symbol(elf).index().ptr(elf).node.unwrap().?;
86448639
8645 // Ensure the NAV is marked as moved so that once we're done, `flushMoved` will eventually be8640 // Ensure the NAV is marked as moved so that once we're done, `flushMoved` will eventually be
8646 // called to apply the NAV's new relocations.8641 // called to apply the NAV's new relocations.
8647 try ni.moved(gpa, &elf.mf);8642 try ni.moved(gpa, &elf.mf);
86488643
8649 {8644 {
8650 var nw: MappedFile.Node.Writer = undefined;8645 var nw: MappedFile.Node.Writer = undefined;
8651 ni.writer(gpa, &elf.mf, &nw);8646 ni.writer(gpa, &elf.mf, &nw);
8652 defer nw.deinit();8647 defer nw.deinit();
8653 elf.resetNodeRelocs(ni);8648 elf.resetNodeRelocs(ni);
8654 codegen.generateSymbol(8649 codegen.generateSymbol(
8655 &elf.base,8650 &elf.base,
8656 pt,8651 pt,
8657 .fromInterned(nav.resolved.?.value),8652 .fromInterned(nav.resolved.?.value),
8658 &nw.interface,8653 &nw.interface,
8659 .{ .atom_index = Node.toAtom(ni) },8654 .{ .atom_index = Node.toAtom(ni) },
8660 ) catch |err| switch (err) {8655 ) catch |err| switch (err) {
8661 else => |e| return e,8656 else => |e| return e,
8662 error.WriteFailed => return nw.err.?,8657 error.WriteFailed => return nw.err.?,
8663 };8658 };
8664 switch (elf.symPtr(nmi.symbol(elf).index())) {8659 switch (elf.symPtr(nmi.symbol(elf).index())) {
8665 inline else => |sym| elf.targetStore(&sym.size, @intCast(nw.interface.end)),8660 inline else => |sym| elf.targetStore(&sym.size, @intCast(nw.interface.end)),
8661 }
8666 }8662 }
8663 } else {
8664 if (elf.ehdrMachine() != .X86_64) return;
8665 const mod = zcu.fileByIndex(nav.srcInst(ip).resolveFile(ip)).mod.?;
8666 if (!mod.strip) try elf.dwarf.updateComptimeNav(pt, nav_index);
8667 }8667 }
86688668
8669 // The NAV's node is done---now generate any UAVs or lazy code/data which the NAV needs.8669 // The NAV's node is done---now generate any UAVs or lazy code/data which the NAV needs.
...@@ -8726,7 +8726,11 @@ pub fn addConst(...@@ -8726,7 +8726,11 @@ pub fn addConst(
8726 .code_view => unreachable,8726 .code_view => unreachable,
8727 }8727 }
8728}8728}
8729fn addConstNode(lf: *link.File, ui: Dwarf.Unit.Index, cpi: link.ConstPool.Index) link.Error!MappedFile.Node.Index {8729fn addConstNode(
8730 lf: *link.File,
8731 ui: Dwarf.Unit.Index,
8732 cpi: link.ConstPool.Index,
8733) link.Error!MappedFile.Node.Index {
8730 const elf = lf.cast(.elf2).?;8734 const elf = lf.cast(.elf2).?;
8731 const unit = ui.get(&elf.dwarf);8735 const unit = ui.get(&elf.dwarf);
8732 const debug_info_ni = elf.addNodeAssumeCapacity(8736 const debug_info_ni = elf.addNodeAssumeCapacity(
test/src/Debugger.zig+1-1
...@@ -629,7 +629,7 @@ pub fn addTests(db: *Debugger) void {...@@ -629,7 +629,7 @@ pub fn addTests(db: *Debugger) void {
629 \\(lldb) breakpoint delete --force 1629 \\(lldb) breakpoint delete --force 1
630 \\1 breakpoints deleted; 0 breakpoint locations disabled.630 \\1 breakpoints deleted; 0 breakpoint locations disabled.
631 },631 },
632 .{ .skip_new_linker = true },632 .{ .skip_new_linker = true }, // passes, but prints errors
633 );633 );
634 db.addLldbTest(634 db.addLldbTest(
635 "optionals",635 "optionals",