diff --git a/src/Compilation.zig b/src/Compilation.zig index 4866b12ed7c2df92509e891f3625b1332c471e48..bd0996efb4ec3ab2fb874ec07da0d136f1d1ff6b 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -3710,8 +3710,15 @@ pub fn saveState(comp: *Compilation) !void { // linker state switch (lf.tag) { + .elf => {}, + .elf2 => { + const elf = lf.cast(.elf2).?; + try bufs.ensureUnusedCapacity(3); + addBuf(&bufs, @ptrCast(elf.mf.nodes.items)); + addBuf(&bufs, @ptrCast(&elf.mf.free_ni)); + addBuf(&bufs, @ptrCast(elf.mf.large.items)); + }, .wasm => { - dev.check(link.File.Tag.wasm.devFeature()); const wasm = lf.cast(.wasm).?; const is_obj = comp.config.output_mode == .Obj; try bufs.ensureUnusedCapacity(85); diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 29062dd7b199efded0558712cd2ca9150a033741..5a5cec3bdf0f2d512e71695c0d0127d566184886 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1431,7 +1431,7 @@ pub const Object = struct { pub fn getDebugType(o: *Object, pt: Zcu.PerThread, ty: Type) Allocator.Error!Builder.Metadata { assert(!o.builder.strip); - const index = try o.type_pool.get(pt, .{ .llvm = o }, ty.toIntern()); + const index = o.type_pool.get(pt, .{ .llvm = o }, ty.toIntern()) catch |err| return @errorCast(err); return o.debug_types.items[@backingInt(index)]; } @@ -4108,7 +4108,7 @@ pub const Object = struct { } pub fn lazyAbiAlignment(o: *Object, pt: Zcu.PerThread, ty: Type) Allocator.Error!Builder.Alignment.Lazy { - const index = try o.type_pool.get(pt, .{ .llvm = o }, ty.toIntern()); + const index = o.type_pool.get(pt, .{ .llvm = o }, ty.toIntern()) catch |err| return @errorCast(err); return o.lazy_abi_aligns.items[@backingInt(index)]; } diff --git a/src/link/C.zig b/src/link/C.zig index d6d9b1f67d993082e8a592aaa0ef9e18531dc696..e2245881def411213663310963e39ca2519492d6 100644 --- a/src/link/C.zig +++ b/src/link/C.zig @@ -209,7 +209,7 @@ pub fn addConst( pt: Zcu.PerThread, pool_index: link.ConstPool.Index, val: InternPool.Index, -) Allocator.Error!void { +) link.Error!void { const zcu = pt.zcu; const gpa = zcu.comp.gpa; assert(zcu.intern_pool.typeOf(val) == .type_type); @@ -310,7 +310,7 @@ pub fn updateConst( pt: Zcu.PerThread, index: link.ConstPool.Index, val: InternPool.Index, -) Allocator.Error!void { +) link.Error!void { const zcu = pt.zcu; const gpa = zcu.comp.gpa; @@ -1344,7 +1344,7 @@ fn addCTypeDependencies( c: *C, pt: Zcu.PerThread, deps: *const codegen.CType.Dependencies, -) Allocator.Error!CTypeDependencies { +) link.Error!CTypeDependencies { const gpa = pt.zcu.comp.gpa; try c.bigint_types.ensureUnusedCapacity(gpa, deps.bigint.count()); diff --git a/src/link/ConstPool.zig b/src/link/ConstPool.zig index e2b334a83dfb51c28e4898f9e7289f1763a22c18..a2d0b1d06ae84b242a4dfb0027e7df4c206ccf20 100644 --- a/src/link/ConstPool.zig +++ b/src/link/ConstPool.zig @@ -59,7 +59,7 @@ pub const User = union(enum) { pt: Zcu.PerThread, index: Index, val: InternPool.Index, - ) Allocator.Error!void { + ) link.Error!void { switch (user) { inline else => |impl| return impl.addConst(pt, index, val), } @@ -144,7 +144,7 @@ pub fn updateContainerType( /// After this is called, there may be a constant for which debug information (complete or not) has /// not yet been emitted, so the user must call `flushPending` at some point after this call. -pub fn get(pool: *ConstPool, pt: Zcu.PerThread, user: User, val: InternPool.Index) Allocator.Error!ConstPool.Index { +pub fn get(pool: *ConstPool, pt: Zcu.PerThread, user: User, val: InternPool.Index) link.Error!ConstPool.Index { const zcu = pt.zcu; const ip = &zcu.intern_pool; const gpa = zcu.comp.gpa; diff --git a/src/link/Dwarf2.zig b/src/link/Dwarf2.zig index 63936350d2647cd802605a8b4106213877d22537..bea17968b46b9a51fc250168fc84517fb908124b 100644 --- a/src/link/Dwarf2.zig +++ b/src/link/Dwarf2.zig @@ -6,7 +6,7 @@ const_pool: link.ConstPool, units: std.array_hash_map.Auto(*Module, Unit), /// Indices are `link.ConstPool.Index`. -values: std.ArrayList(Value), +consts: std.ArrayList(Const), globals: std.array_hash_map.Auto(InternPool.Nav.Index, Global), funcs: std.array_hash_map.Auto(InternPool.Nav.Index, Func), decls: std.array_hash_map.Auto(InternPool.TrackedInst.Index, MappedFile.Node.Index), @@ -92,20 +92,12 @@ pub const Unit = struct { } }; -pub const Value = struct { - debug_info_ni: MappedFile.Node.Index, +pub const Const = struct { + debug_info_ni: MappedFile.Node.Index.Optional, - pub const Index = enum(u32) { - _, - - pub fn cpi(vi: Value.Index, dwarf: *Dwarf) link.ConstPool.Index { - return dwarf.values[@backingInt(vi)]; - } - - pub fn get(vi: Value.Index, dwarf: *Dwarf) *Global { - return &dwarf.values[@backingInt(vi)]; - } - }; + pub fn get(cpi: link.ConstPool.Index, dwarf: *Dwarf) *Const { + return &dwarf.consts.items[@backingInt(cpi)]; + } }; pub const Global = struct { @@ -626,14 +618,14 @@ pub const WipNav = struct { return debug.wip_nav.genDebugFrame(loc, cfa); } - pub fn startDebugInfo(debug: *Debug) link.Error!void { + pub fn startFuncDebugInfo(debug: *Debug) link.Error!void { assert(debug.wip_nav.func != .none); - debug.startDebugInfoInner() catch |err| switch (err) { + debug.startFuncDebugInfoInner() catch |err| switch (err) { error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.info_writer), else => |e| return e, }; } - fn startDebugInfoInner(debug: *Debug) link.EmitError!void { + fn startFuncDebugInfoInner(debug: *Debug) link.EmitError!void { const dwarf = debug.wip_nav.dwarf; const zcu = debug.pt.zcu; const ip = &zcu.intern_pool; @@ -644,6 +636,7 @@ pub const WipNav = struct { const nav = ip.getNav(func.owner_nav); const diw = &debug.info_writer.interface; try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_func)); + try debug.refType(.fromInterned(zcu.fileRootType(inst_info.file))); try diw.writeInt(u32, decl.src_line + 1, dwarf.endian); try diw.writeUleb128(decl.src_column + 1); try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private); @@ -730,7 +723,7 @@ pub const WipNav = struct { debug: *Debug, tag: LocalVarTag, opt_name: ?[]const u8, - ty: ZigType, + ty: Type, loc: Loc, ) link.Error!void { return debug.genLocalVarDebugInfoInner(tag, opt_name, ty, loc) catch |err| switch (err) { @@ -742,7 +735,7 @@ pub const WipNav = struct { debug: *Debug, tag: LocalVarTag, opt_name: ?[]const u8, - ty: ZigType, + ty: Type, loc: Loc, ) link.EmitError!void { assert(debug.wip_nav.func != .none); @@ -761,7 +754,7 @@ pub const WipNav = struct { debug: *Debug, tag: LocalConstTag, opt_name: ?[]const u8, - val: ZigValue, + val: Value, ) link.Error!void { return debug.genLocalConstDebugInfoInner(tag, opt_name, val) catch |err| switch (err) { error.WriteFailed => return debug.wip_nav.dwarf.reportWriteError(&debug.info_writer), @@ -772,7 +765,7 @@ pub const WipNav = struct { debug: *Debug, tag: LocalConstTag, opt_name: ?[]const u8, - val: ZigValue, + val: Value, ) link.EmitError!void { assert(debug.wip_nav.func != .none); const zcu = debug.pt.zcu; @@ -1059,11 +1052,11 @@ pub const WipNav = struct { const old_owner_nav = zcu.funcInfo(debug.wip_nav.func).owner_nav; const old_inst_info = ip.getNav(old_owner_nav).srcInst(ip).resolveFull(ip).?; - const old_file = zcu.fileByIndex(old_inst_info.file); + const old_zf = zcu.fileByIndex(old_inst_info.file); const new_inst_info = ip.getNav(new_owner_nav).srcInst(ip).resolveFull(ip).?; - const new_file = zcu.fileByIndex(new_inst_info.file); + const new_zf = zcu.fileByIndex(new_inst_info.file); if (old_inst_info.file != new_inst_info.file) { - const new_ui = dwarf.getUnit(new_file.mod.?); + const new_ui = dwarf.getUnit(new_zf.mod.?); _, const new_fi = try debug.wip_nav.unit.get(dwarf).getFile(zcu.gpa, new_ui, new_inst_info.file); @@ -1071,8 +1064,8 @@ pub const WipNav = struct { try dlw.writeUleb128(@backingInt(new_fi)); } - const old_src_line: i33 = old_file.zir.?.getDeclaration(old_inst_info.inst).src_line; - const new_src_line: i33 = new_file.zir.?.getDeclaration(new_inst_info.inst).src_line; + const old_src_line: i33 = old_zf.zir.?.getDeclaration(old_inst_info.inst).src_line; + const new_src_line: i33 = new_zf.zir.?.getDeclaration(new_inst_info.inst).src_line; if (new_src_line != old_src_line) { try dlw.writeByte(DW.LNS.advance_line); try dlw.writeSleb128(new_src_line - old_src_line); @@ -1137,27 +1130,21 @@ pub const WipNav = struct { ); } - fn refType(debug: *Debug, ty: ZigType) link.EmitError!void { + fn refType(debug: *Debug, ty: Type) link.EmitError!void { return debug.refValue(ty.toValue()); } - fn refValue(debug: *Debug, value: ZigValue) link.EmitError!void { - try debug.wip_nav.dwarf.sectionOffset(&debug.info_writer, try debug.getValueNode(value), 0); - } - - fn getValueNode(debug: *Debug, value: ZigValue) link.Error!MappedFile.Node.Index { - const zcu = debug.pt.zcu; - if (value.typeOf(zcu).toIntern() != .type_type) { - assert(value.typeOf(zcu).comptimeOnly(zcu)); - } + fn refValue(debug: *Debug, val: Value) link.EmitError!void { const dwarf = debug.wip_nav.dwarf; - const index = try dwarf.const_pool.get(debug.pt, .{ - .elf2 = dwarf.lf.cast(.elf2).?, - }, value.toIntern()); - return dwarf.values.items[@backingInt(index)].debug_info_ni; + const cpi = try dwarf.getConst(debug.pt, val); + try dwarf.sectionOffset( + &debug.info_writer, + Const.get(cpi, dwarf).debug_info_ni.unwrap().?, + 0, + ); } - fn blockValue(debug: *Debug, val: ZigValue) link.EmitError!void { + fn blockValue(debug: *Debug, val: Value) link.EmitError!void { const ty = val.typeOf(debug.pt.zcu); const diw = &debug.info_writer.interface; const size = ty.abiSize(debug.pt.zcu); @@ -1355,7 +1342,7 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf { .const_pool = .empty, .units = .empty, - .values = .empty, + .consts = .empty, .globals = .empty, .funcs = .empty, .decls = .empty, @@ -1429,9 +1416,10 @@ pub fn deinit(dwarf: *Dwarf) void { dwarf.const_pool.deinit(gpa); for (dwarf.units.values()) |*unit| unit.deinit(gpa); dwarf.units.deinit(gpa); - dwarf.values.deinit(gpa); + dwarf.consts.deinit(gpa); dwarf.globals.deinit(gpa); dwarf.funcs.deinit(gpa); + dwarf.decls.deinit(gpa); dwarf.debug_line_str.map.deinit(gpa); dwarf.debug_str.map.deinit(gpa); dwarf.* = undefined; @@ -1471,6 +1459,13 @@ pub fn getUnit(dwarf: *Dwarf, mod: *Module) Unit.Index { return @fromBackingInt(@intCast(dwarf.units.getIndex(mod).?)); } +pub fn getConst(dwarf: *Dwarf, pt: Zcu.PerThread, val: Value) link.Error!link.ConstPool.Index { + const zcu = pt.zcu; + const ty = val.typeOf(zcu); + if (ty.toIntern() != .type_type) assert(ty.comptimeOnly(zcu)); + return dwarf.const_pool.get(pt, .{ .elf2 = dwarf.lf.cast(.elf2).? }, val.toIntern()); +} + pub fn getGlobal(dwarf: *Dwarf, nav: InternPool.Nav.Index) link.Error!Global.Index { const comp = dwarf.lf.comp; const gpa = comp.gpa; @@ -1483,10 +1478,9 @@ pub fn getGlobal(dwarf: *Dwarf, nav: InternPool.Nav.Index) link.Error!Global.Ind const elf = dwarf.lf.cast(.elf2).?; try elf.nodes.ensureUnusedCapacity(gpa, 1); try elf.dwarf_globals.ensureUnusedCapacity(gpa, 1); - const unit = dwarf.getUnit(comp.zcu.?.zcu.navFileScope(nav).mod.?).get(dwarf); - assert(unit.debug_info_ni != .none); - global_gop.value_ptr.debug_info_ni = elf.addNodeAssumeCapacity( - elf.mf.addLastChildNode(gpa, unit.debug_info_ni, .{ + const unit = dwarf.getUnit(comp.zcu.?.navFileScope(nav).mod.?).get(dwarf); + global_gop.value_ptr.debug_info_ni = .wrap(elf.addNodeAssumeCapacity( + unit.debug_info_ni.unwrap().?.addFloatingChild(gpa, &elf.mf, .{ .enable_next_moved = true, }) catch |err| switch (err) { else => |e| return e, @@ -1495,7 +1489,7 @@ pub fn getGlobal(dwarf: *Dwarf, nav: InternPool.Nav.Index) link.Error!Global.Ind }), }, .{ .global_debug_info = gi }, - ); + )); elf.dwarf_globals.addOneAssumeCapacity().* = .{ .debug_info_first_target_reloc = .none, .debug_info_first_node_reloc = .none, @@ -1773,7 +1767,6 @@ pub fn genDebugInfoPadding(dwarf: *Dwarf, diw: *Writer, size: u64) Writer.Error! pub fn genDebugLineHeader( dwarf: *Dwarf, - mod: *Module, unit: *Unit, dlh_nw: *MappedFile.Node.Writer, zcu: *Zcu, @@ -1817,7 +1810,7 @@ pub fn genDebugLineHeader( try dlhw.writeByte(1); try dlhw.writeUleb128(DW.LNCT.path); try dlhw.writeUleb128(DW.FORM.line_strp); - const dir_count = 1; + const dir_count = unit.dirs.count(); const directory_index_form: DeclValEnum(DW.FORM) = if (dir_count <= 1 << 8) .data1 else if (dir_count <= 1 << 16) @@ -1825,8 +1818,8 @@ pub fn genDebugLineHeader( else .udata; try dlhw.writeUleb128(dir_count); - { - const root_dir_path = try mod.root.toAbsolute(&zcu.comp.dirs, comp.gpa); + for (unit.dirs.keys()) |ui| { + const root_dir_path = try ui.mod(dwarf).root.toAbsolute(&zcu.comp.dirs, comp.gpa); defer comp.gpa.free(root_dir_path); try dwarf.strp(&dwarf.debug_line_str, dlh_nw, root_dir_path); } @@ -1845,11 +1838,12 @@ pub fn genDebugLineHeader( for (unit.files.keys()) |zfi| { const zf = zcu.fileByIndex(zfi); try dwarf.strp(&dwarf.debug_line_str, dlh_nw, zf.sub_file_path); + const di = unit.dirs.getIndex(dwarf.getUnit(zf.mod.?)).?; switch (directory_index_form) { else => unreachable, - .data1 => try dlhw.writeByte(0), - .data2 => try dlhw.writeInt(u16, 0, dwarf.endian), - .udata => try dlhw.writeUleb128(0), + .data1 => try dlhw.writeByte(@intCast(di)), + .data2 => try dlhw.writeInt(u16, @intCast(di), dwarf.endian), + .udata => try dlhw.writeUleb128(di), } try dlhw.writeInt(i64, @truncate(zf.stat.mtime.nanoseconds), dwarf.endian); try dlhw.writeInt(u64, zf.stat.size, dwarf.endian); @@ -1938,6 +1932,209 @@ pub fn genDebugRnglists( try drw.writeByte(DW.RLE.end_of_list); } +pub fn updateComptimeNav( + dwarf: *Dwarf, + pt: Zcu.PerThread, + nav_index: InternPool.Nav.Index, +) link.Error!void { + const zcu = dwarf.lf.comp.zcu.?; + const ip = &zcu.intern_pool; + const nav = ip.getNav(nav_index); + const inst_info = nav.srcInst(ip).resolveFull(ip).?; + const nav_val: Value = .fromInterned(nav.resolved.?.value); + const file = zcu.fileByIndex(inst_info.file); + const zir = &file.zir.?; + const decl = zir.getDeclaration(inst_info.inst); + switch (decl.kind) { + .unnamed_test, .@"test", .decltest => return, + .@"comptime", .@"const", .@"var" => {}, + } + emit: switch (ip.indexToKey(nav_val.toIntern())) { + .struct_type => { + const loaded_struct = ip.loadStructType(nav_val.toIntern()); + if (nav_index.toOptional() == loaded_struct.name_nav) { + _ = try dwarf.const_pool.get(pt, .{ .elf2 = dwarf.lf.cast(.elf2).? }, nav_val.toIntern()); + break :emit; + } + }, + .enum_type => { + const loaded_enum = ip.loadEnumType(nav_val.toIntern()); + if (nav_index.toOptional() == loaded_enum.name_nav) { + _ = try dwarf.const_pool.get(pt, .{ .elf2 = dwarf.lf.cast(.elf2).? }, nav_val.toIntern()); + break :emit; + } + }, + .union_type => { + const loaded_union = ip.loadUnionType(nav_val.toIntern()); + if (nav_index.toOptional() == loaded_union.name_nav) { + _ = try dwarf.const_pool.get(pt, .{ .elf2 = dwarf.lf.cast(.elf2).? }, nav_val.toIntern()); + break :emit; + } + }, + .opaque_type => { + const loaded_opaque = ip.loadOpaqueType(nav_val.toIntern()); + if (nav_index.toOptional() == loaded_opaque.name_nav) { + _ = try dwarf.const_pool.get(pt, .{ .elf2 = dwarf.lf.cast(.elf2).? }, nav_val.toIntern()); + break :emit; + } + }, + .func => |func| if (func.owner_nav == nav_index and func.generic_owner == .none) { + const fi = try dwarf.getFunc(func.owner_nav); + const f = fi.get(dwarf); + if (f.fde_ni != .none or f.debug_line_ni != .none) return; + var di_nw: MappedFile.Node.Writer = undefined; + f.debug_info_ni.unwrap().?.writer(zcu.gpa, &dwarf.lf.cast(.elf2).?.mf, &di_nw); + defer di_nw.deinit(); + const parent_cpi = try dwarf.getConst(pt, .fromInterned(zcu.fileRootType(inst_info.file))); + dwarf.genDeclFuncGeneric( + &di_nw, + zir, + parent_cpi, + &decl, + &ip.indexToKey(func.ty).func_type, + nav.name.toSlice(ip), + zir.getParamBody(func.zir_body_inst.resolve(ip).?), + ) catch |err| switch (err) { + else => |e| return e, + error.WriteFailed => return dwarf.reportWriteError(&di_nw), + }; + } else return, + + else => return, + + // memoization, not values + .memoized_call => unreachable, + } + try dwarf.const_pool.flushPending(pt, .{ .elf2 = dwarf.lf.cast(.elf2).? }); +} +fn genDeclFuncGeneric( + dwarf: *Dwarf, + di_nw: *MappedFile.Node.Writer, + zir: *const std.zig.Zir, + parent_cpi: link.ConstPool.Index, + decl: *const std.zig.Zir.Inst.Declaration.Unwrapped, + fn_ty: *const InternPool.Key.FuncType, + name: []const u8, + param_body: []const std.zig.Zir.Inst.Index, +) link.EmitError!void { + const diw = &di_nw.interface; + try diw.writeUleb128(try dwarf.refAbbrevCode(.decl_func_generic)); + try dwarf.sectionOffset(di_nw, Const.get(parent_cpi, dwarf).debug_info_ni.unwrap().?, 0); + try diw.writeInt(u32, decl.src_line + 1, dwarf.endian); + try diw.writeUleb128(decl.src_column + 1); + try diw.writeByte(if (decl.is_pub) DW.ACCESS.public else DW.ACCESS.private); + try dwarf.strp(&dwarf.debug_str, di_nw, name); + for (param_body) |param_inst| switch (zir.getParamName(param_inst) orelse continue) { + .empty => { + try diw.writeUleb128(try dwarf.refAbbrevCode(.unnamed_arg)); + try diw.writeUleb128(0); + }, + else => |param_name| { + try diw.writeUleb128(try dwarf.refAbbrevCode(.arg)); + try dwarf.strp(&dwarf.debug_str, di_nw, zir.nullTerminatedString(param_name)); + try diw.writeUleb128(0); + }, + }; + if (fn_ty.is_var_args) try diw.writeUleb128(try dwarf.refAbbrevCode(.is_var_args)); + try diw.writeUleb128(@backingInt(AbbrevCode.null)); + try dwarf.genDebugInfoPadding(diw, diw.unusedCapacityLen()); +} + +pub fn addConst(dwarf: *Dwarf, cpi: link.ConstPool.Index, val: InternPool.Index) link.Error!void { + const comp = dwarf.lf.comp; + const zcu = comp.zcu.?; + const ip = &zcu.intern_pool; + try dwarf.consts.ensureUnusedCapacity(comp.gpa, 1); + + assert(@backingInt(cpi) == dwarf.consts.items.len); + dwarf.consts.appendAssumeCapacity(.{ + .debug_info_ni = switch (ip.indexToKey(val)) { + else => .none, + .struct_type, .union_type, .enum_type, .opaque_type => |_, tag| debug_info_ni: { + if (switch (tag) { + .struct_type => ip.loadStructType(val).name_nav, + .union_type => ip.loadUnionType(val).name_nav, + .enum_type => ip.loadEnumType(val).name_nav, + .opaque_type => ip.loadOpaqueType(val).name_nav, + else => unreachable, + }.unwrap()) |name_nav| { + const name_gi = try dwarf.getGlobal(name_nav); + break :debug_info_ni name_gi.get(dwarf).debug_info_ni.unwrap().?; + } + const elf = dwarf.lf.cast(.elf2).?; + try elf.nodes.ensureUnusedCapacity(comp.gpa, 1); + try elf.dwarf_consts.ensureUnusedCapacity(comp.gpa, 1); + const src_inst = Type.fromInterned(val).typeDeclInstAllowGeneratedTag(zcu).?; + const unit = dwarf.getUnit(zcu.fileByIndex(src_inst.resolveFile(ip)).mod.?).get(dwarf); + const debug_info_ni = elf.addNodeAssumeCapacity( + unit.debug_info_ni.unwrap().?.addFloatingChild(comp.gpa, &elf.mf, .{ + .enable_next_moved = true, + }) catch |err| switch (err) { + else => |e| return e, + error.MappedFileIo => return comp.link_diags.fail("failed to write output file: {t}", .{ + elf.mf.io_err.?, + }), + }, + .{ .const_debug_info = cpi }, + ); + elf.dwarf_consts.putAssumeCapacity(cpi, .{ + .debug_info_first_target_reloc = .none, + .debug_info_first_symbol_reloc = .none, + .debug_info_first_node_reloc = .none, + }); + + break :debug_info_ni debug_info_ni; + }.toOptional(), + }, + }); +} + +pub fn updateConst(dwarf: *Dwarf, cpi: link.ConstPool.Index, val: InternPool.Index) void { + _ = dwarf; + _ = cpi; + _ = val; +} + +pub fn updateConstIncomplete( + dwarf: *Dwarf, + di_nw: *MappedFile.Node.Writer, + val: InternPool.Index, +) link.Error!void { + dwarf.updateConstIncompleteInner(di_nw, val) catch |err| switch (err) { + else => |e| return e, + error.WriteFailed => return dwarf.reportWriteError(di_nw), + }; +} +fn updateConstIncompleteInner( + dwarf: *Dwarf, + di_nw: *MappedFile.Node.Writer, + val: InternPool.Index, +) link.EmitError!void { + const comp = dwarf.lf.comp; + const zcu = comp.zcu.?; + const ip = &zcu.intern_pool; + const diw = &di_nw.interface; + emit: switch (ip.indexToKey(val)) { + .struct_type => { + const loaded_struct = ip.loadStructType(val); + if (loaded_struct.zir_index.resolveFull(ip)) |src_inst| switch (src_inst.inst) { + .main_struct_inst => { + const ui = dwarf.getUnit(comp.zcu.?.fileByIndex(src_inst.file).mod.?); + _, const fi = try ui.get(dwarf).getFile(comp.gpa, ui, src_inst.file); + try diw.writeUleb128(try dwarf.refAbbrevCode(.empty_file)); + try diw.writeUleb128(@backingInt(fi)); + try dwarf.strp(&dwarf.debug_str, di_nw, loaded_struct.name.toSlice(ip)); + break :emit; + }, + else => return, + }; + return; + }, + else => return, + } + try dwarf.genDebugInfoPadding(diw, diw.unusedCapacityLen()); +} + pub fn updateLineNumber( dwarf: *Dwarf, mf: *MappedFile, @@ -2221,7 +2418,7 @@ pub const AbbrevCode = enum { DeclValEnum(DW.FORM), }; const decl_attrs = &[_]Attr{ - //.{ .ZIG_parent, .ref_addr }, + .{ .ZIG_parent, .ref_addr }, .{ .decl_line, .data4 }, .{ .decl_column, .udata }, .{ .accessibility, .data1 }, @@ -2233,7 +2430,7 @@ pub const AbbrevCode = enum { }; const decl_instance_attrs = &[_]Attr{ - //.{ .ZIG_parent, .ref_addr }, + .{ .ZIG_parent, .ref_addr }, .{ .specification, .ref_addr }, }; @@ -2387,14 +2584,16 @@ pub const AbbrevCode = enum { .decl_nullary_func_generic = .{ .tag = .subprogram, .attrs = decl_attrs ++ .{ - .{ .type, .ref_addr }, + //.{ .type, .ref_addr }, + //.{ .noreturn, .flag }, }, }, .decl_func_generic = .{ .tag = .subprogram, .children = true, .attrs = decl_attrs ++ .{ - .{ .type, .ref_addr }, + //.{ .type, .ref_addr }, + //.{ .noreturn, .flag }, }, }, .decl_extern_nullary_func = .{ @@ -3304,7 +3503,7 @@ const link = @import("../link.zig"); const MappedFile = @import("MappedFile.zig"); const Module = @import("../Module.zig"); const std = @import("std"); -const ZigType = @import("../Type.zig"); -const ZigValue = @import("../Value.zig"); +const Type = @import("../Type.zig"); +const Value = @import("../Value.zig"); const Writer = std.Io.Writer; const Zcu = @import("../Zcu.zig"); diff --git a/src/link/Elf2.zig b/src/link/Elf2.zig index 93e6caa3562d9bf46c0110eff63fa72f4486a456..1388fbcf4cf5be95b3c1a83341f05cd5289eeffc 100644 --- a/src/link/Elf2.zig +++ b/src/link/Elf2.zig @@ -224,7 +224,7 @@ dwarf_units: std.ArrayList(struct { debug_rnglists_first_target_reloc: NodeReloc.Index, debug_rnglists_symbol_relocs: std.array_hash_map.Auto(SymbolReloc.Index, void), }), -dwarf_values: std.ArrayList(struct { +dwarf_consts: std.array_hash_map.Auto(link.ConstPool.Index, struct { debug_info_first_target_reloc: NodeReloc.Index, debug_info_first_symbol_reloc: SymbolReloc.Index, debug_info_first_node_reloc: NodeReloc.Index, @@ -318,7 +318,7 @@ const Node = union(enum) { unit_debug_line_header: Dwarf.Unit.Index, unit_debug_rnglists: Dwarf.Unit.Index, - value_debug_info: link.ConstPool.Index, + const_debug_info: link.ConstPool.Index, global_debug_info: Dwarf.Global.Index, func_frame_fde: Dwarf.Func.Index, func_debug_info: Dwarf.Func.Index, @@ -1142,7 +1142,8 @@ const SymbolReloc = struct { /// * An input section /// * A section /// * A NAV, UAV, or lazy code/data - node: MappedFile.Node.Index, + /// * `.none`, if this relocation was deleted (in which case it should be ignored) + node: MappedFile.Node.Index.Optional, /// The offset of the relocation inside of `node`. offset: u64, /// A symbol used to compute the relocated value. Precise meaning depends on `@"type"`. @@ -1182,7 +1183,7 @@ const SymbolReloc = struct { /// because relocations in the GOTPLT are handled specially, without `SymbolReloc` entries. fn relaSection(sr: *const SymbolReloc, elf: *Elf) Section.Index { const shndx = switch (elf.ehdrType()) { - .REL => elf.getNodeShndx(sr.node).get(elf).rela.shndx, + .REL => elf.getNodeShndx(sr.node.unwrap().?).get(elf).rela.shndx, .EXEC, .DYN => elf.shndx.rela_dyn, }; assert(shndx != .UNDEF); @@ -1619,7 +1620,8 @@ const SymbolReloc = struct { fn apply(reloc: *SymbolReloc, elf: *Elf) void { assert(elf.ehdrType() != .REL); - if (reloc.node.hasMoved(&elf.mf) or reloc.target.hasMoved(elf)) { + const node = reloc.node.unwrap() orelse return; // deleted + if (node.hasMoved(&elf.mf) or reloc.target.hasMoved(elf)) { // There's no point applying the relocation now, because it will be re-applied by // `flushMoved` at some point anyway. return; @@ -1644,8 +1646,9 @@ const SymbolReloc = struct { } } fn applyInner(reloc: *const SymbolReloc, elf: *Elf) error{ RelocationOverflow, RelocationMisaligned }!void { - const dest_vaddr = elf.getNodeVAddr(reloc.node) + reloc.offset; - const dest_slice = reloc.node.slice(&elf.mf)[@intCast(reloc.offset)..]; + const node = reloc.node.unwrap().?; + const dest_vaddr = elf.getNodeVAddr(node) + reloc.offset; + const dest_slice = node.slice(&elf.mf)[@intCast(reloc.offset)..]; const addend: u64 = @bitCast(reloc.addend); const target_val: u64 = type: switch (reloc.type.target) { @@ -1737,6 +1740,7 @@ const SymbolReloc = struct { } reloc.* = undefined; + reloc.node = .none; } /// If `reloc.rela_index` is populated, reset it to `.none` and delete the relocation, updating @@ -1746,7 +1750,7 @@ const SymbolReloc = struct { reloc.relaSection(elf).relaDeleteOne(elf, rela_index); switch (elf.ehdrType()) { .REL => {}, - .EXEC, .DYN => switch (elf.nodeWantsDsoRelocation(reloc.node)) { + .EXEC, .DYN => switch (elf.nodeWantsDsoRelocation(reloc.node.unwrap().?)) { .no => unreachable, // there *was* a dynamic relocation! .yes => {}, .yes_textrel => elf.textrel_count -= 1, @@ -1760,7 +1764,7 @@ const SymbolReloc = struct { /// This represents a symbol reloc against the section symbol containing the node /// with a variable addend that changes when the target node moves. const NodeReloc = struct { - node: MappedFile.Node.Index, + node: MappedFile.Node.Index.Optional, offset: u64, target: MappedFile.Node.Index, addend: i64, @@ -1786,7 +1790,7 @@ const NodeReloc = struct { assert(elf.ehdrType() == .REL); // The node has moved, so the offset of the relocation within the section might have // changed, so update the `offset` field of the `ElfN.Rela` entry. - elf.getNodeShndx(reloc.node).get(elf).rela.shndx.relaSetOffset(elf, rela_index, node_vaddr + reloc.offset); + elf.getNodeShndx(reloc.node.unwrap().?).get(elf).rela.shndx.relaSetOffset(elf, rela_index, node_vaddr + reloc.offset); } else { assert(elf.ehdrType() != .REL); reloc.apply(elf); @@ -1797,7 +1801,7 @@ const NodeReloc = struct { if (reloc.rela_index.unwrap()) |rela_index| { assert(elf.ehdrType() == .REL); // The target has moved, so the `addend` field of the `ElfN.Rela` entry needs to be updated. - elf.getNodeShndx(reloc.node).get(elf).rela.shndx.relaSetAddend(elf, rela_index, target_section_offset +% @as(u64, @bitCast(reloc.addend))); + elf.getNodeShndx(reloc.node.unwrap().?).get(elf).rela.shndx.relaSetAddend(elf, rela_index, target_section_offset +% @as(u64, @bitCast(reloc.addend))); } else { assert(elf.ehdrType() != .REL); reloc.apply(elf); @@ -1805,12 +1809,13 @@ const NodeReloc = struct { } fn apply(reloc: *NodeReloc, elf: *Elf) void { + const node = reloc.node.unwrap() orelse return; // deleted if (reloc.rela_index.unwrap()) |rela_index| { assert(elf.ehdrType() == .REL); _ = rela_index; } else { assert(elf.ehdrType() != .REL); - if (reloc.node.hasMoved(&elf.mf) or reloc.target.hasMoved(&elf.mf)) { + if (node.hasMoved(&elf.mf) or reloc.target.hasMoved(&elf.mf)) { // There's no point applying the relocation now, because it will be re-applied by // `flushMoved` at some point anyway. return; @@ -1842,7 +1847,7 @@ const NodeReloc = struct { }, .cast = .unsigned, .shift = .@"0" }; const addend: u64 = @bitCast(reloc.addend); const target_val = elf.getNodeVAddr(reloc.target) +% addend; - const dest_slice = reloc.node.slice(&elf.mf)[@intCast(reloc.offset)..]; + const dest_slice = reloc.node.unwrap().?.slice(&elf.mf)[@intCast(reloc.offset)..]; try simple.write(target_val, dest_slice, elf.targetEndian()); } @@ -1858,7 +1863,7 @@ const NodeReloc = struct { .unit_debug_info_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_info_header_first_target_reloc, .unit_debug_line_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_line_header_first_target_reloc, .unit_debug_rnglists => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_rnglists_first_target_reloc, - .value_debug_info => |vi| &elf.dwarf_values.items[@backingInt(vi)].debug_info_first_target_reloc, + .const_debug_info => |cpi| &elf.dwarf_consts.getPtr(cpi).?.debug_info_first_target_reloc, .global_debug_info => |gi| &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_target_reloc, .func_debug_info => |fi| &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_target_reloc, }; @@ -1877,13 +1882,14 @@ const NodeReloc = struct { } reloc.* = undefined; + reloc.node = .none; } /// If `reloc.rela_index` is populated, reset it to `.none` and delete the relocation. fn deleteOutputRel(reloc: *NodeReloc, elf: *Elf) void { const rela_index = reloc.rela_index.unwrap() orelse return; assert(elf.ehdrType() == .REL); - elf.getNodeShndx(reloc.node).get(elf).rela.shndx.relaDeleteOne(elf, rela_index); + elf.getNodeShndx(reloc.node.unwrap().?).get(elf).rela.shndx.relaDeleteOne(elf, rela_index); reloc.rela_index = .none; } }; @@ -3175,7 +3181,8 @@ const Symbol = struct { .abs, .pltabs => {}, } if (!reloc.type.action.simple.dest.isAddr(elf)) continue; - switch (elf.nodeWantsDsoRelocation(reloc.node)) { + const node = reloc.node.unwrap().?; + switch (elf.nodeWantsDsoRelocation(node)) { .no => continue, .yes_textrel => elf.textrel_count += 1, .yes => {}, @@ -3183,7 +3190,7 @@ const Symbol = struct { // There is capacity for a relocation because we just deleted one earlier. reloc.rela_index = elf.shndx.rela_dyn.relaAddOneAssumeCapacity(elf, .{ .type = .relative(elf), - .offset = elf.getNodeVAddr(reloc.node) + reloc.offset, + .offset = elf.getNodeVAddr(node) + reloc.offset, .raw_sym_index = 0, .addend = 0, }).toOptional(); @@ -3310,7 +3317,7 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId { .unit_debug_line, .unit_debug_line_header, .unit_debug_rnglists, - .value_debug_info, + .const_debug_info, .global_debug_info, .func_frame_fde, .func_debug_info, @@ -3823,7 +3830,7 @@ fn create( .first_target_reloc = .none, }), .dwarf_units = .empty, - .dwarf_values = .empty, + .dwarf_consts = .empty, .dwarf_globals = .empty, .dwarf_funcs = .empty, @@ -3878,7 +3885,7 @@ pub fn deinit(elf: *Elf) void { elf.dwarf.deinit(); for (elf.dwarf_units.items) |*dwarf_unit| dwarf_unit.debug_rnglists_symbol_relocs.deinit(gpa); elf.dwarf_units.deinit(gpa); - elf.dwarf_values.deinit(gpa); + elf.dwarf_consts.deinit(gpa); elf.dwarf_globals.deinit(gpa); elf.dwarf_funcs.deinit(gpa); @@ -5176,7 +5183,7 @@ fn getNodeShndx(elf: *const Elf, ni: MappedFile.Node.Index) Section.Index { .unit_frame_cie, .unit_debug_info_header, .unit_debug_line_header, - .value_debug_info, + .const_debug_info, .global_debug_info, .func_frame_fde, .func_debug_info, @@ -5213,7 +5220,7 @@ fn getNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 { .unit_debug_line, .unit_debug_line_header, .unit_debug_rnglists, - .value_debug_info, + .const_debug_info, .global_debug_info, .func_frame_fde, .func_debug_info, @@ -5252,7 +5259,7 @@ fn computeNodeVAddr(elf: *Elf, ni: MappedFile.Node.Index) u64 { .unit_debug_info_header, .unit_debug_line_header, .unit_debug_rnglists, - .value_debug_info, + .const_debug_info, .global_debug_info, .func_frame_fde, .func_debug_info, @@ -5287,7 +5294,7 @@ fn computeNodeSectionOffset(elf: *Elf, ni: MappedFile.Node.Index) u64 { .unit_debug_info_header, .unit_debug_line_header, .unit_debug_rnglists, - .value_debug_info, + .const_debug_info, .global_debug_info, .func_frame_fde, .func_debug_info, @@ -5356,9 +5363,9 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void { .first_node_reloc = &elf.dwarf_units.items[@backingInt(ui)].debug_line_header_first_node_reloc, }, .unit_debug_rnglists => unreachable, // unsupported - .value_debug_info => |vi| .{ - .first_symbol_reloc = &elf.dwarf_values.items[@backingInt(vi)].debug_info_first_symbol_reloc, - .first_node_reloc = &elf.dwarf_values.items[@backingInt(vi)].debug_info_first_node_reloc, + .const_debug_info => |cpi| .{ + .first_symbol_reloc = &elf.dwarf_consts.getPtr(cpi).?.debug_info_first_symbol_reloc, + .first_node_reloc = &elf.dwarf_consts.getPtr(cpi).?.debug_info_first_node_reloc, }, .global_debug_info => |gi| .{ .first_symbol_reloc = &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_symbol_reloc, @@ -5387,8 +5394,11 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void { if (opts.first_symbol_reloc) |ptr| { if (ptr.* != .none) { for (elf.symbol_relocs.items[@backingInt(ptr.*)..], @backingInt(ptr.*)..) |*reloc, index| { - if (reloc.node.toOptional() == opts.skip_symbol_relocs) continue; - if (reloc.node != ni) break; + if (reloc.node != ni.toOptional()) { + if (reloc.node == .none) continue; + if (reloc.node == opts.skip_symbol_relocs) continue; + break; + } reloc.delete(elf, @fromBackingInt(@intCast(index))); } } @@ -5398,8 +5408,11 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void { if (opts.first_node_reloc) |ptr| { if (ptr.* != .none) { for (elf.node_relocs.items[@backingInt(ptr.*)..]) |*reloc| { - if (reloc.node.toOptional() == opts.skip_node_relocs) continue; - if (reloc.node != ni) break; + if (reloc.node != ni.toOptional()) { + if (reloc.node == .none) continue; + if (reloc.node == opts.skip_node_relocs) continue; + break; + } reloc.delete(elf); } } @@ -5409,7 +5422,10 @@ fn resetNodeRelocs(elf: *Elf, ni: MappedFile.Node.Index) void { if (opts.first_got_reloc) |ptr| { if (ptr.* != .none) { for (elf.got_relocs.items[@backingInt(ptr.*)..]) |*reloc| { - if (reloc.node != ni.toOptional()) break; + if (reloc.node != ni.toOptional()) { + if (reloc.node == .none) continue; + break; + } reloc.delete(elf); } } @@ -5433,23 +5449,32 @@ fn flushMovedNodeRelocs( ) void { if (opts.first_symbol_reloc != .none) { for (elf.symbol_relocs.items[@backingInt(opts.first_symbol_reloc)..]) |*reloc| { - if (reloc.node.toOptional() == opts.skip_symbol_relocs) continue; - if (reloc.node != node) break; + if (reloc.node != node.toOptional()) { + if (reloc.node == .none) continue; + if (reloc.node == opts.skip_symbol_relocs) continue; + break; + } reloc.flushMovedNode(elf, node_vaddr); } } if (opts.first_node_reloc != .none) { for (elf.node_relocs.items[@backingInt(opts.first_node_reloc)..]) |*reloc| { - if (reloc.node.toOptional() == opts.skip_node_relocs) continue; - if (reloc.node != node) break; + if (reloc.node != node.toOptional()) { + if (reloc.node == .none) continue; + if (reloc.node == opts.skip_node_relocs) continue; + break; + } reloc.flushMovedNode(elf, node_vaddr); } } if (opts.first_got_reloc != .none) { for (elf.got_relocs.items[@backingInt(opts.first_got_reloc)..]) |*reloc| { - if (reloc.node != node.toOptional()) break; + if (reloc.node != node.toOptional()) { + if (reloc.node == .none) continue; + break; + } reloc.apply(elf); } } @@ -7277,7 +7302,7 @@ fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void { fn flushFiles(elf: *Elf) Error!void { const gpa = elf.base.comp.gpa; - if (elf.shndx.debug_line != .UNDEF) for (elf.dwarf.units.keys(), elf.dwarf.units.values()) |mod, *unit| { + if (elf.shndx.debug_line != .UNDEF) for (elf.dwarf.units.values()) |*unit| { if (!unit.cleanDebugLineHeaderChanged()) continue; const debug_line_header_ni = unit.debug_line_header_ni.unwrap().?; try debug_line_header_ni.parent(&elf.mf).unwrap().?.nextMoved(gpa, &elf.mf); @@ -7287,7 +7312,7 @@ fn flushFiles(elf: *Elf) Error!void { debug_line_header_ni.writer(gpa, &elf.mf, &dlh_nw); defer dlh_nw.deinit(); elf.resetNodeRelocs(debug_line_header_ni); - elf.dwarf.genDebugLineHeader(mod, unit, &dlh_nw, elf.base.comp.zcu.?) catch |err| switch (err) { + elf.dwarf.genDebugLineHeader(unit, &dlh_nw, elf.base.comp.zcu.?) catch |err| switch (err) { else => |e| return e, error.WriteFailed => return dlh_nw.err.?, }; @@ -7629,7 +7654,7 @@ fn addRelocAssumeCapacity( first_target_reloc.* = ri; if (next != .none) next.get(elf).prev = ri; elf.symbol_relocs.appendAssumeCapacity(.{ - .node = node, + .node = node.toOptional(), .offset = offset, .type = undefined, .target = target, @@ -8067,7 +8092,7 @@ fn addSymbolRelocAssumeCapacity( first_target_reloc.* = ri; if (next != .none) next.get(elf).prev = ri; elf.symbol_relocs.appendAssumeCapacity(.{ - .node = node, + .node = node.toOptional(), .offset = offset, .target = target, .addend = addend, @@ -8101,7 +8126,7 @@ fn addNodeRelocAssumeCapacity( .unit_debug_info_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_info_header_first_target_reloc, .unit_debug_line_header => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_line_header_first_target_reloc, .unit_debug_rnglists => |ui| &elf.dwarf_units.items[@backingInt(ui)].debug_rnglists_first_target_reloc, - .value_debug_info => |vi| &elf.dwarf_values.items[@backingInt(vi)].debug_info_first_target_reloc, + .const_debug_info => |cpi| &elf.dwarf_consts.getPtr(cpi).?.debug_info_first_target_reloc, .global_debug_info => |gi| &elf.dwarf_globals.items[@backingInt(gi)].debug_info_first_target_reloc, .func_debug_info => |fi| &elf.dwarf_funcs.items[@backingInt(fi)].debug_info_first_target_reloc, }; @@ -8151,7 +8176,7 @@ fn addNodeRelocAssumeCapacity( .addend = 0, }); elf.node_relocs.appendAssumeCapacity(.{ - .node = node, + .node = node.toOptional(), .offset = offset, .type = undefined, .target = target, @@ -8164,7 +8189,7 @@ fn addNodeRelocAssumeCapacity( }, .DYN, .EXEC => { elf.node_relocs.appendAssumeCapacity(.{ - .node = node, + .node = node.toOptional(), .offset = offset, .target = target, .addend = addend, @@ -8209,7 +8234,7 @@ fn addGotRelocAssumeCapacity( .unit_debug_line, .unit_debug_line_header, .unit_debug_rnglists, - .value_debug_info, + .const_debug_info, .global_debug_info, .func_frame_fde, .func_debug_info, @@ -8502,7 +8527,8 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) const nav = ip.getNav(nav_index); if (ip.indexToKey(nav.resolved.?.value) == .@"extern") return; - if (!Type.fromInterned(nav.resolved.?.type).hasRuntimeBits(zcu)) return; + if (!Type.fromInterned(nav.resolved.?.type).hasRuntimeBits(zcu)) + return elf.dwarf.updateComptimeNav(pt, nav_index); const nmi = try elf.navMapIndex(zcu, nav_index); const ni = nmi.symbol(elf).index().ptr(elf).node.unwrap().?; @@ -8546,11 +8572,11 @@ pub fn updateContainerType( pub fn addConst( elf: *Elf, - pt: Zcu.PerThread, + _: Zcu.PerThread, index: link.ConstPool.Index, val: InternPool.Index, -) std.mem.Allocator.Error!void { - if (false) try elf.dwarf.addConst(pt, index, val); +) link.Error!void { + try elf.dwarf.addConst(index, val); } pub fn updateConst( @@ -8570,7 +8596,7 @@ fn updateConstInner( ) link.Error!void { var lazy_it = elf.lazy.iterator(); while (lazy_it.next()) |lazy| if (lazy.value.getIndex(cpi)) |li| { - const lazy_ty: Type = .fromInterned(cpi.val(&elf.dwarf.const_pool)); + const lazy_ty: Type = .fromInterned(val); var prog_name_buf: [std.Progress.Node.max_name_len]u8 = undefined; const prog_name: []const u8 = switch (lazy_ty.zigTypeTag(pt.zcu)) { .@"enum" => std.mem.print(&prog_name_buf, "@tagName({f})", .{lazy_ty.fmt(pt)}) catch &prog_name_buf, @@ -8590,16 +8616,20 @@ fn updateConstInner( ), }; }; - if (false) try elf.dwarf.updateConst(pt, cpi, val); + elf.dwarf.updateConst(cpi, val); } pub fn updateConstIncomplete( elf: *Elf, - pt: Zcu.PerThread, + _: Zcu.PerThread, cpi: link.ConstPool.Index, val: InternPool.Index, ) link.Error!void { - if (false) try elf.dwarf.updateConstIncomplete(pt, cpi, val); + const debug_info_ni = Dwarf.Const.get(cpi, &elf.dwarf).debug_info_ni.unwrap().?; + var di_nw: MappedFile.Node.Writer = undefined; + debug_info_ni.writer(elf.base.comp.gpa, &elf.mf, &di_nw); + defer di_nw.deinit(); + try elf.dwarf.updateConstIncomplete(&di_nw, val); } pub fn updateFunc( @@ -8770,7 +8800,7 @@ fn updateFuncInner( elf.resetNodeRelocs(dwarf_func.debug_line_ni.unwrap().?); try debug.startDebugLine(); elf.resetNodeRelocs(dwarf_func.debug_info_ni.unwrap().?); - try debug.startDebugInfo(); + try debug.startFuncDebugInfo(); }, .none => {}, } @@ -9187,7 +9217,7 @@ fn idleProgNode( }, ui.mod(&elf.dwarf).fully_qualified_name, }) catch &name, - .value_debug_info => |cpi| std.mem.print(&name, "debug info for {f}", .{ + .const_debug_info => |cpi| std.mem.print(&name, "debug info for {f}", .{ Value.fromInterned(cpi.val(&elf.dwarf.const_pool)) .fmtValue(.{ .zcu = elf.base.comp.zcu.?, .tid = tid }), }) catch &name, @@ -9648,14 +9678,14 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void const node_vaddr = elf.computeNodeVAddr(ni); for (dwarf_unit.debug_rnglists_symbol_relocs.keys()) |symbol_ri| { const symbol_reloc = symbol_ri.get(elf); - assert(symbol_reloc.node == ni); + assert(symbol_reloc.node.unwrap().? == ni); symbol_reloc.flushMovedNode(elf, node_vaddr); } }, - .value_debug_info => |vi| { - const dwarf_value = &elf.dwarf_values.items[@backingInt(vi)]; + .const_debug_info => |cpi| { + const dwarf_const = &elf.dwarf_consts.get(cpi).?; const target_section_offset = elf.computeNodeSectionOffset(ni); - var target_ri = dwarf_value.debug_info_first_target_reloc; + var target_ri = dwarf_const.debug_info_first_target_reloc; while (target_ri != .none) { const target_reloc = target_ri.get(elf); assert(target_reloc.target == ni); @@ -9663,12 +9693,12 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void target_ri = target_reloc.next; } elf.flushMovedNodeRelocs(ni, elf.computeNodeVAddr(ni), .{ - .first_symbol_reloc = dwarf_value.debug_info_first_symbol_reloc, - .first_node_reloc = dwarf_value.debug_info_first_node_reloc, + .first_symbol_reloc = dwarf_const.debug_info_first_symbol_reloc, + .first_node_reloc = dwarf_const.debug_info_first_node_reloc, }); }, - .global_debug_info => |vi| { - const dwarf_global = &elf.dwarf_globals.items[@backingInt(vi)]; + .global_debug_info => |gi| { + const dwarf_global = &elf.dwarf_globals.items[@backingInt(gi)]; const target_section_offset = elf.computeNodeSectionOffset(ni); var target_ri = dwarf_global.debug_info_first_target_reloc; while (target_ri != .none) { @@ -9972,7 +10002,7 @@ fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!vo .unit_debug_line, .unit_debug_line_header, .unit_debug_rnglists, - .value_debug_info, + .const_debug_info, .global_debug_info, .func_frame_fde, .func_debug_info, @@ -10036,7 +10066,7 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error! .unit_debug_info_header, .unit_debug_line_header, .unit_debug_rnglists, - .value_debug_info, + .const_debug_info, .global_debug_info, .func_frame_fde, .func_debug_info, @@ -10089,7 +10119,7 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error! }, .unit_debug_info_header, .unit_debug_line_header, - .value_debug_info, + .const_debug_info, .global_debug_info, .func_debug_info, .func_debug_line, @@ -10105,7 +10135,7 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error! switch (tag) { else => unreachable, .unit_debug_info_header, - .value_debug_info, + .const_debug_info, .global_debug_info, .func_debug_info, => for (0..2) |_| fw.writeUleb128(@backingInt(Dwarf.AbbrevCode.null)) catch unreachable, @@ -10119,7 +10149,7 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error! elf.dwarf.updateUnitLength(fw.buffer, fw.buffer.len); switch (tag) { else => unreachable, - .unit_debug_info_header, .value_debug_info, .global_debug_info, .func_debug_info => { + .unit_debug_info_header, .const_debug_info, .global_debug_info, .func_debug_info => { comptime assert(Dwarf.uleb128Size(@backingInt(Dwarf.AbbrevCode.null)) == 1); @memset(fw.unusedCapacitySlice(), @backingInt(Dwarf.AbbrevCode.null)); }, @@ -10143,7 +10173,7 @@ fn flushNextMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error! @memset(fw.buffer, std.dwarf.CFA.nop); }, .unit_debug_info_header, - .value_debug_info, + .const_debug_info, .global_debug_info, .func_debug_info, => elf.dwarf.genDebugInfoPadding(&fw, fw.buffer.len) catch unreachable, @@ -10693,9 +10723,11 @@ pub fn printNode( .unit_debug_line_header, .unit_debug_rnglists, => |ui| try w.print("({s})", .{ui.mod(&elf.dwarf).fully_qualified_name}), - .value_debug_info => |cpi| try w.print("({f})", .{ - Value.fromInterned(cpi.val(&elf.dwarf.const_pool)) - .fmtValue(.{ .zcu = elf.base.comp.zcu.?, .tid = tid }), + .const_debug_info => |cpi| try w.print("({f})", .{ + Value.fromInterned(cpi.val(&elf.dwarf.const_pool)).fmtValue(.{ + .zcu = elf.base.comp.zcu.?, + .tid = tid, + }), }), .global_debug_info => |gi| { const zcu = elf.base.comp.zcu.?;