From 2375b0063da554eeb1ed4b0b8dbe8dad485c5f6a Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Thu, 6 Aug 2026 10:13:44 -0400 Subject: [PATCH] link: improve explicit error sets "I think we made the error sets good now" --- src/codegen.zig | 15 ++-- src/codegen/loongarch/Select.zig | 16 ++-- src/codegen/riscv64/CodeGen.zig | 2 +- src/codegen/riscv64/Emit.zig | 2 +- src/codegen/riscv64/Mir.zig | 2 +- src/codegen/sparc64/Emit.zig | 2 +- src/codegen/sparc64/Mir.zig | 2 +- src/codegen/x86_64/CodeGen.zig | 2 +- src/codegen/x86_64/Emit.zig | 2 +- src/codegen/x86_64/Mir.zig | 8 +- src/link.zig | 1 + src/link/Coff.zig | 18 ++-- src/link/Dwarf2.zig | 144 ++++++++++++++++--------------- src/link/Elf/ZigObject.zig | 1 - src/link/Elf2.zig | 22 +++-- src/link/MachO/ZigObject.zig | 1 - 16 files changed, 126 insertions(+), 114 deletions(-) diff --git a/src/codegen.zig b/src/codegen.zig index 2986419f9292d754a83e13048a008c862fa74e78..e921a76dd462139db5bd2eee743dcb0c5357a45b 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -26,7 +26,6 @@ pub const aarch64 = @import("codegen/aarch64.zig"); pub const loongarch = @import("codegen/loongarch.zig"); pub const Error = link.Error; -pub const EmitError = Error || std.Io.Writer.Error || error{MappedFileIo}; fn devFeatureForBackend(backend: std.lang.CompilerBackend) dev.Feature { return switch (backend) { @@ -197,7 +196,7 @@ pub fn emitFunction( any_mir: *const AnyMir, w: *std.Io.Writer, debug_output: link.File.DebugInfoOutput, -) EmitError!void { +) link.EmitError!void { const zcu = pt.zcu; const func = zcu.funcInfo(func_index); const target = &zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result; @@ -229,7 +228,7 @@ pub fn generateLazyFunction( atom_id: link.File.AtomId, w: *std.Io.Writer, debug_output: link.File.DebugInfoOutput, -) EmitError!void { +) link.EmitError!void { const zcu = pt.zcu; const target = if (Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu)) |inst_index| &zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.?.resolved_target.result @@ -253,7 +252,7 @@ pub fn generateLazySymbol( w: *std.Io.Writer, debug_output: link.File.DebugInfoOutput, reloc_parent: link.File.RelocInfo.Parent, -) EmitError!void { +) link.EmitError!void { const tracy = trace(@src()); defer tracy.end(); tracy.addTextFmt("{t}, {f}", .{ lazy_sym.kind, Type.fromInterned(lazy_sym.ty).fmt(pt) }); @@ -315,7 +314,7 @@ pub fn generateSymbol( val: Value, w: *std.Io.Writer, reloc_parent: link.File.RelocInfo.Parent, -) (Error || std.Io.Writer.Error)!void { +) link.EmitError!void { const tracy = trace(@src()); defer tracy.end(); @@ -666,7 +665,7 @@ fn lowerPtr( w: *std.Io.Writer, reloc_parent: link.File.RelocInfo.Parent, prev_offset: u64, -) (Error || std.Io.Writer.Error)!void { +) link.EmitError!void { const zcu = pt.zcu; const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; const offset: u64 = prev_offset + ptr.byte_offset; @@ -724,7 +723,7 @@ fn lowerUavRef( w: *std.Io.Writer, reloc_parent: link.File.RelocInfo.Parent, offset: u64, -) (Error || std.Io.Writer.Error)!void { +) link.EmitError!void { const zcu = pt.zcu; const ip = &zcu.intern_pool; const comp = lf.comp; @@ -782,7 +781,7 @@ fn lowerNavRef( w: *std.Io.Writer, reloc_parent: link.File.RelocInfo.Parent, offset: u64, -) (Error || std.Io.Writer.Error)!void { +) link.EmitError!void { const zcu = pt.zcu; const ip = &zcu.intern_pool; const target = &zcu.navFileScope(nav_index).mod.?.resolved_target.result; diff --git a/src/codegen/loongarch/Select.zig b/src/codegen/loongarch/Select.zig index ba97c62105485c98a9044dd6c9a75c332c4e933e..49e9fb09702b345c28d0058f2a48b353414edebc 100644 --- a/src/codegen/loongarch/Select.zig +++ b/src/codegen/loongarch/Select.zig @@ -1020,7 +1020,7 @@ pub const Value = struct { /// Defines a value with a location. /// Returned location must be free-ed by caller. /// Extension unchanged. - fn def(vi: Value.Index, isel: *Select) error{ AlreadyReported, OutOfMemory }!?Location { + fn def(vi: Value.Index, isel: *Select) codegen.Error!?Location { try vi.collectDefs(isel); return vi.takeLocationMarkWritten(isel); } @@ -2046,7 +2046,7 @@ pub const Value = struct { if (!std.debug.runtime_safety) assert(@sizeOf(Mat) <= 32); } - const Error = error{ OutOfMemory, AlreadyReported }; + const Error = codegen.Error; pub fn ra(mat: Value.Mat) Register.Alias { return mat.location.register; @@ -2296,13 +2296,13 @@ pub const Value = struct { }; }; -fn fail(isel: *Select, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } { +fn fail(isel: *Select, comptime format: []const u8, args: anytype) codegen.Error { @branchHint(.cold); wip_mir_log.debug("codegen error: " ++ format, args); return isel.pt.zcu.codegenFail(isel.nav_index, format, args); } -fn failUnimplemented(isel: *Select, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported }!void { +fn failUnimplemented(isel: *Select, comptime format: []const u8, args: anytype) codegen.Error!void { @branchHint(.cold); if (debug_trap_unimplemented_code) { const gpa = isel.pt.zcu.gpa; @@ -2963,7 +2963,7 @@ pub fn verify(isel: *Select, check_values: bool) void { } } -pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, AlreadyReported }!void { +pub fn body(isel: *Select, air_body: []const Air.Inst.Index) codegen.Error!void { const zcu = isel.pt.zcu; const ip = &zcu.intern_pool; const gpa = zcu.gpa; @@ -5341,7 +5341,7 @@ fn forgetReg(isel: *Select, dst_reg: Register) error{ OutOfMemory, AlreadyReport /// Frees a register by moving it to another place. /// Returns true on success, false on failure (i.e. dst_reg is locked/allocated or unallocatable). -fn fillReg(isel: *Select, dst_reg: Register) error{ OutOfMemory, AlreadyReported }!bool { +fn fillReg(isel: *Select, dst_reg: Register) codegen.Error!bool { if (!isRegisterAllocatable(dst_reg)) return false; const dst_live_vi = isel.live_registers.getPtr(dst_reg); const dst_vi = switch (dst_live_vi.*) { @@ -5377,7 +5377,7 @@ fn fillReg(isel: *Select, dst_reg: Register) error{ OutOfMemory, AlreadyReported /// Frees a set of register. If locked is true, these registers are then locked. /// Requires all registers to be unlocked. /// Returns true on success. -fn fillRegsBatch(isel: *Select, regs: RegisterSet, locking: bool) error{ OutOfMemory, AlreadyReported }!void { +fn fillRegsBatch(isel: *Select, regs: RegisterSet, locking: bool) codegen.Error!void { tracking_log.debug("batch fill: {f}", .{fmtRegisterSet(regs)}); // lock free registers var regs_it = regs.iterator(); @@ -5419,7 +5419,7 @@ fn fillRegsBatch(isel: *Select, regs: RegisterSet, locking: bool) error{ OutOfMe /// Frees a register by moving it to stack. /// Returns true on success, false on failure (i.e. dst_reg is locked/allocated or unallocatable). -fn fillRegToMemory(isel: *Select, dst_reg: Register) error{ OutOfMemory, AlreadyReported }!bool { +fn fillRegToMemory(isel: *Select, dst_reg: Register) codegen.Error!bool { if (!isRegisterAllocatable(dst_reg)) return false; const dst_live_vi = isel.live_registers.getPtr(dst_reg); const dst_vi = switch (dst_live_vi.*) { diff --git a/src/codegen/riscv64/CodeGen.zig b/src/codegen/riscv64/CodeGen.zig index 97921d321136f3070f9188f2d93cadebc8c4be92..450ef37e8eda3f8fd5d26584b8884b5049d554a6 100644 --- a/src/codegen/riscv64/CodeGen.zig +++ b/src/codegen/riscv64/CodeGen.zig @@ -856,7 +856,7 @@ pub fn generateLazy( atom_index: link.File.AtomId, w: *std.Io.Writer, debug_output: link.File.DebugInfoOutput, -) codegen.EmitError!void { +) link.EmitError!void { _ = atom_index; const comp = bin_file.comp; const gpa = comp.gpa; diff --git a/src/codegen/riscv64/Emit.zig b/src/codegen/riscv64/Emit.zig index fd145a3dce7fe5dd1db20a72d8c8549d0f038ed9..bd59e64ccb6a9c2f62aa5373d78711d78c5b6cac 100644 --- a/src/codegen/riscv64/Emit.zig +++ b/src/codegen/riscv64/Emit.zig @@ -13,7 +13,7 @@ prev_di_pc: usize, code_offset_mapping: std.AutoHashMapUnmanaged(Mir.Inst.Index, usize) = .empty, relocs: std.ArrayList(Reloc) = .empty, -pub const Error = Lower.Error || codegen.EmitError || error{ +pub const Error = Lower.Error || link.EmitError || error{ EmitFail, }; diff --git a/src/codegen/riscv64/Mir.zig b/src/codegen/riscv64/Mir.zig index 3c2c6ac1d625d908bc25cdec6396863aede7b554..64cd1d506e76ff057ce1f46f37edc6c0e9544dd3 100644 --- a/src/codegen/riscv64/Mir.zig +++ b/src/codegen/riscv64/Mir.zig @@ -111,7 +111,7 @@ pub fn emit( atom_index: link.File.AtomId, w: *std.Io.Writer, debug_output: link.File.DebugInfoOutput, -) codegen.EmitError!void { +) link.EmitError!void { _ = atom_index; const zcu = pt.zcu; const comp = zcu.comp; diff --git a/src/codegen/sparc64/Emit.zig b/src/codegen/sparc64/Emit.zig index 80c9f25832cc17240f53a3b8f9ad9b7397d6f7b1..1b03f31fd830c0b6d84bedbef9ad88663129a437 100644 --- a/src/codegen/sparc64/Emit.zig +++ b/src/codegen/sparc64/Emit.zig @@ -41,7 +41,7 @@ branch_forward_origins: std.AutoHashMapUnmanaged(Mir.Inst.Index, std.ArrayList(M /// instruction code_offset_mapping: std.AutoHashMapUnmanaged(Mir.Inst.Index, usize) = .empty, -const InnerError = codegen.EmitError || error{ +const InnerError = link.EmitError || error{ EmitFail, }; diff --git a/src/codegen/sparc64/Mir.zig b/src/codegen/sparc64/Mir.zig index aa5c204d96697c8afe9d9869c51faf67bfd96f99..ecac6f5f6746e3582195753717f745e2d8a80f4e 100644 --- a/src/codegen/sparc64/Mir.zig +++ b/src/codegen/sparc64/Mir.zig @@ -382,7 +382,7 @@ pub fn emit( atom_index: link.File.AtomId, w: *std.Io.Writer, debug_output: link.File.DebugInfoOutput, -) codegen.EmitError!void { +) link.EmitError!void { _ = atom_index; const zcu = pt.zcu; const func = zcu.funcInfo(func_index); diff --git a/src/codegen/x86_64/CodeGen.zig b/src/codegen/x86_64/CodeGen.zig index f44fc72d83e9b4fabc55d20b80d4de0658d0c0ca..e1cd83e45768e7a8726b2f48ba4dfce867de728e 100644 --- a/src/codegen/x86_64/CodeGen.zig +++ b/src/codegen/x86_64/CodeGen.zig @@ -1120,7 +1120,7 @@ pub fn generateLazy( atom_id: link.File.AtomId, w: *std.Io.Writer, debug_output: link.File.DebugInfoOutput, -) codegen.EmitError!void { +) link.EmitError!void { const gpa = pt.zcu.gpa; // This function is for generating global code, so we use the root module. const mod = pt.zcu.comp.root_mod; diff --git a/src/codegen/x86_64/Emit.zig b/src/codegen/x86_64/Emit.zig index 6523d7f638b40721d0247496b453acd35af1e37a..34045d411f07df3519633cfb0c81e2e4e565028d 100644 --- a/src/codegen/x86_64/Emit.zig +++ b/src/codegen/x86_64/Emit.zig @@ -16,7 +16,7 @@ code_offset_mapping: std.ArrayList(u32), relocs: std.ArrayList(Reloc), table_relocs: std.ArrayList(TableReloc), -pub const Error = Lower.Error || codegen.EmitError || error{ +pub const Error = Lower.Error || codegen.Error || std.Io.Writer.Error || error{ EmitFail, } || std.posix.MMapError || std.posix.MRemapError || link.File.UpdateDebugInfoError; diff --git a/src/codegen/x86_64/Mir.zig b/src/codegen/x86_64/Mir.zig index dd385854d441428dd1b657ae22ee1ce737b4dc86..01cbecc44936c987272acd482b037bfae160fd4a 100644 --- a/src/codegen/x86_64/Mir.zig +++ b/src/codegen/x86_64/Mir.zig @@ -1978,7 +1978,7 @@ pub fn emit( atom_id: link.File.AtomId, w: *std.Io.Writer, debug_output: link.File.DebugInfoOutput, -) codegen.EmitError!void { +) link.EmitError!void { const zcu = pt.zcu; const comp = zcu.comp; const gpa = comp.gpa; @@ -2021,7 +2021,7 @@ pub fn emit( error.LowerFail, error.EmitFail => return zcu.codegenFailMsg(nav, em.lower.err_msg.?), error.InvalidInstruction, error.CannotEncode => return zcu.codegenFail(nav, "emit MIR failed: {s} (Zig compiler bug)", .{@errorName(err)}), else => return zcu.codegenFail(nav, "emit MIR failed: {s}", .{@errorName(err)}), - error.AlreadyReported, error.Canceled, error.MappedFileIo, error.WriteFailed => |e| return e, + error.AlreadyReported, error.Canceled, error.WriteFailed => |e| return e, }; } @@ -2033,7 +2033,7 @@ pub fn emitLazy( atom_id: link.File.AtomId, w: *std.Io.Writer, debug_output: link.File.DebugInfoOutput, -) codegen.EmitError!void { +) link.EmitError!void { const zcu = pt.zcu; const comp = zcu.comp; const gpa = comp.gpa; @@ -2065,7 +2065,7 @@ pub fn emitLazy( error.LowerFail, error.EmitFail => return zcu.codegenFailTypeMsg(lazy_sym.ty, em.lower.err_msg.?), error.InvalidInstruction, error.CannotEncode => return zcu.codegenFailType(lazy_sym.ty, "emit MIR failed: {s} (Zig compiler bug)", .{@errorName(err)}), else => return zcu.codegenFailType(lazy_sym.ty, "emit MIR failed: {s}", .{@errorName(err)}), - error.AlreadyReported, error.Canceled, error.MappedFileIo, error.WriteFailed => |e| return e, + error.AlreadyReported, error.Canceled, error.WriteFailed => |e| return e, }; } diff --git a/src/link.zig b/src/link.zig index 158570be706b99cbcf650d34b18fd963ec49070a..d5c0759bfc353ca7982f3aa94546b7ae431975b1 100644 --- a/src/link.zig +++ b/src/link.zig @@ -38,6 +38,7 @@ pub const Error = Allocator.Error || Io.Cancelable || error{ /// instance in `Compilation.link_diags`. AlreadyReported, }; +pub const EmitError = Error || Io.Writer.Error; pub const Diags = struct { /// Stored here so that function definitions can distinguish between diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 91ee0ab5bda97079f456ac74bf68c3d9d4868493..b1ae945300e65c46776f2f43b69b3f0e7ec9f65a 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -7356,7 +7356,7 @@ fn updateExportInner( pt: Zcu.PerThread, export_index: Zcu.Export.Index, alias_syms: *std.array_hash_map.Auto(Symbol.Index, Symbol.Index), -) !void { +) Error!void { const zcu = pt.zcu; const gpa = zcu.gpa; const ip = &zcu.intern_pool; @@ -7519,17 +7519,19 @@ fn updateExportInner( } } -fn dumpStderr(coff: *Coff, tid: Zcu.PerThread.Id) !void { +fn dumpStderr(coff: *Coff, tid: Zcu.PerThread.Id) Io.File.Writer.Error!void { const comp = coff.base.comp; const io = comp.io; var buffer: [512]u8 = undefined; const stderr = try io.lockStderr(&buffer, null); defer io.unlockStderr(); const w = &stderr.file_writer.interface; - _ = try coff.dump(w, tid); + _ = coff.dump(w, tid) catch |err| switch (err) { + error.WriteFailed => return stderr.file_writer.err.?, + }; } -pub fn dump(coff: *Coff, w: *Io.Writer, tid: Zcu.PerThread.Id) !link.File.DumpResult { +pub fn dump(coff: *Coff, w: *Io.Writer, tid: Zcu.PerThread.Id) Io.Writer.Error!link.File.DumpResult { if (coff.options.enable_link_snapshots) { try coff.printNode(tid, w, .root, 0); try w.writeAll("Section table:\n"); @@ -7544,7 +7546,7 @@ pub fn dump(coff: *Coff, w: *Io.Writer, tid: Zcu.PerThread.Id) !link.File.DumpRe return .disabled; } -fn printSection(coff: *Coff, w: *Io.Writer, name: String, si: Symbol.Index) !void { +fn printSection(coff: *Coff, w: *Io.Writer, name: String, si: Symbol.Index) Io.Writer.Error!void { const sym = si.get(coff); try w.print("{d:0>6}@{d:0>2} {x:08} n{d:0>8} | {s}\n", .{ si, @@ -7560,7 +7562,7 @@ fn printSymbol( w: *Io.Writer, tid: Zcu.PerThread.Id, si: Symbol.Index, -) !void { +) Io.Writer.Error!void { const sym = si.get(coff); try w.print("{d:0>6}@{d:0>2} {x:08} {s} {s} {s} n{d:0>8}+{x:08}:{s: <26} | {x:08} ", .{ si, @@ -7622,7 +7624,7 @@ fn printNodeName( w: *std.Io.Writer, tid: Zcu.PerThread.Id, node: Node, -) !void { +) Io.Writer.Error!void { switch (node) { else => {}, .image_section => |si| try w.print("({s})", .{ @@ -7702,7 +7704,7 @@ pub fn printNode( w: *Io.Writer, ni: MappedFile.Node.Index, indent: usize, -) !void { +) Io.Writer.Error!void { const node = coff.getNode(ni); try w.splatByteAll(' ', indent); try w.writeAll(@tagName(node)); diff --git a/src/link/Dwarf2.zig b/src/link/Dwarf2.zig index 2d49814581426bfcdce4022532620e1d1e3b9d87..2d3c41849afca1a48a8cc834036acae704adc7fd 100644 --- a/src/link/Dwarf2.zig +++ b/src/link/Dwarf2.zig @@ -16,8 +16,6 @@ frame: Frame, debug_info: DebugInfo, debug_line: DebugLine, -pub const UpdateError = link.Error || error{MappedFileIo}; - pub const AddressSize = enum(u8) { @"32" = 4, @"64" = 8, _ }; pub const Unit = struct { @@ -158,7 +156,7 @@ pub const Loc = union(enum) { } } - fn write(loc: Loc, adapter: anytype) (UpdateError || Writer.Error)!void { + fn write(loc: Loc, adapter: anytype) link.EmitError!void { const writer = adapter.writer(); switch (loc) { .empty => {}, @@ -324,7 +322,7 @@ pub const Cfa = union(enum) { const RegOff = struct { reg: u32, off: i64 }; const RegExpr = struct { reg: u32, expr: Loc }; - fn write(cfa: Cfa, wip_nav: *WipNav) (UpdateError || Writer.Error)!void { + fn write(cfa: Cfa, wip_nav: *WipNav) link.EmitError!void { const dfw = &wip_nav.fde_writer.interface; switch (cfa) { .nop => try dfw.writeByte(DW.CFA.nop), @@ -487,11 +485,11 @@ pub const WipNav = struct { debug.* = undefined; } - pub fn genFuncHeaders(debug: *Debug) UpdateError!void { + pub fn genFuncHeaders(debug: *Debug) link.Error!void { try debug.wip_nav.genFuncHeaders(); } - pub fn genDebugFrame(debug: *Debug, loc: u32, cfa: Cfa) UpdateError!void { + pub fn genDebugFrame(debug: *Debug, loc: u32, cfa: Cfa) link.Error!void { return debug.wip_nav.genDebugFrame(loc, cfa); } @@ -502,10 +500,10 @@ pub const WipNav = struct { opt_name: ?[]const u8, ty: Type, loc: Loc, - ) UpdateError!void { + ) link.Error!void { if (true) return; return debug.genLocalVarDebugInfoInner(tag, opt_name, ty, loc) catch |err| switch (err) { - error.WriteFailed => debug.info_writer.err.?, + error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer), else => |e| e, }; } @@ -515,7 +513,7 @@ pub const WipNav = struct { opt_name: ?[]const u8, ty: Type, loc: Loc, - ) (UpdateError || Writer.Error)!void { + ) link.EmitError!void { assert(debug.wip_nav.func != null); try debug.abbrevCode(switch (tag) { .arg => if (opt_name) |_| .arg else .unnamed_arg, @@ -533,10 +531,10 @@ pub const WipNav = struct { tag: LocalConstTag, opt_name: ?[]const u8, val: Value, - ) UpdateError!void { + ) link.Error!void { if (true) return; return debug.genLocalConstDebugInfoInner(tag, opt_name, val) catch |err| switch (err) { - error.WriteFailed => debug.info_writer.err.?, + error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer), else => |e| e, }; } @@ -545,7 +543,7 @@ pub const WipNav = struct { tag: LocalConstTag, opt_name: ?[]const u8, val: Value, - ) (UpdateError || Writer.Error)!void { + ) link.EmitError!void { assert(debug.wip_nav.func != null); const zcu = debug.pt.zcu; const ty = val.typeOf(zcu); @@ -571,23 +569,23 @@ pub const WipNav = struct { debug.any_children = true; } - pub fn genVarArgsDebugInfo(debug: *Debug) UpdateError!void { + pub fn genVarArgsDebugInfo(debug: *Debug) link.Error!void { if (true) return; return debug.genVarArgsDebugInfoInner() catch |err| switch (err) { - error.WriteFailed => debug.info_writer.err.?, + error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer), else => |e| e, }; } - fn genVarArgsDebugInfoInner(debug: *Debug) (UpdateError || Writer.Error)!void { + fn genVarArgsDebugInfoInner(debug: *Debug) link.EmitError!void { assert(debug.wip_nav.func != null); try debug.abbrevCode(.is_var_args); debug.any_children = true; } - pub fn advancePcAndLine(debug: *Debug, delta_line: i33, delta_pc: u64) UpdateError!void { + pub fn advancePcAndLine(debug: *Debug, delta_line: i33, delta_pc: u64) link.Error!void { if (true) return; return debug.advancePcAndLineInner(delta_line, delta_pc) catch |err| switch (err) { - error.WriteFailed => debug.line_writer.err.?, + error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer), }; } fn advancePcAndLineInner(debug: *Debug, delta_line: i33, delta_pc: u64) Writer.Error!void { @@ -625,10 +623,10 @@ pub const WipNav = struct { (header.line_range * remaining_op_advance) + header.opcode_base)); } - pub fn setColumn(debug: *Debug, column: u32) UpdateError!void { + pub fn setColumn(debug: *Debug, column: u32) link.Error!void { if (true) return; return debug.setColumnInner(column) catch |err| switch (err) { - error.WriteFailed => debug.line_writer.err.?, + error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer), }; } fn setColumnInner(debug: *Debug, column: u32) Writer.Error!void { @@ -637,44 +635,44 @@ pub const WipNav = struct { try dlw.writeUleb128(column + 1); } - pub fn negateStmt(debug: *Debug) UpdateError!void { + pub fn negateStmt(debug: *Debug) link.Error!void { if (true) return; return debug.negateStmtInner() catch |err| switch (err) { - error.WriteFailed => debug.line_writer.err.?, + error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer), }; } fn negateStmtInner(debug: *Debug) Writer.Error!void { try debug.line_writer.interface.writeByte(DW.LNS.negate_stmt); } - pub fn setPrologueEnd(debug: *Debug) UpdateError!void { + pub fn setPrologueEnd(debug: *Debug) link.Error!void { if (true) return; return debug.setPrologueEndInner() catch |err| switch (err) { - error.WriteFailed => debug.line_writer.err.?, + error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer), }; } fn setPrologueEndInner(debug: *Debug) Writer.Error!void { try debug.line_writer.interface.writeByte(DW.LNS.set_prologue_end); } - pub fn setEpilogueBegin(debug: *Debug) UpdateError!void { + pub fn setEpilogueBegin(debug: *Debug) link.Error!void { if (true) return; return debug.setEpilogueBeginInner() catch |err| switch (err) { - error.WriteFailed => debug.line_writer.err.?, + error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer), }; } fn setEpilogueBeginInner(debug: *Debug) Writer.Error!void { try debug.line_writer.interface.writeByte(DW.LNS.set_epilogue_begin); } - pub fn enterBlock(debug: *Debug, code_off: u64) UpdateError!void { + pub fn enterBlock(debug: *Debug, code_off: u64) link.Error!void { if (true) return; return debug.enterBlockInner(code_off) catch |err| switch (err) { - error.WriteFailed => debug.info_writer.err.?, + error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer), else => |e| e, }; } - fn enterBlockInner(debug: *Debug, code_off: u64) (UpdateError || Writer.Error)!void { + fn enterBlockInner(debug: *Debug, code_off: u64) link.EmitError!void { const dwarf = debug.wip_nav.dwarf; const diw = &debug.info_writer.interface; const block = try debug.blocks.addOne(dwarf.linkFile().comp.gpa); @@ -688,14 +686,14 @@ pub const WipNav = struct { debug.any_children = false; } - pub fn leaveBlock(debug: *Debug, code_off: u64) UpdateError!void { + pub fn leaveBlock(debug: *Debug, code_off: u64) link.Error!void { if (true) return; return debug.leaveBlockInner(code_off) catch |err| switch (err) { - error.WriteFailed => debug.info_writer.err.?, + error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer), else => |e| e, }; } - fn leaveBlockInner(debug: *Debug, code_off: u64) (UpdateError || Writer.Error)!void { + fn leaveBlockInner(debug: *Debug, code_off: u64) link.EmitError!void { const dwarf = debug.wip_nav.dwarf; const block_bytes = comptime uleb128Bytes(@backingInt(AbbrevCode.block)); const block = debug.blocks.pop().?; @@ -722,10 +720,10 @@ pub const WipNav = struct { code_off: u64, line: u32, column: u32, - ) UpdateError!void { + ) link.Error!void { if (true) return; return debug.enterInlineFuncInner(func, code_off, line, column) catch |err| switch (err) { - error.WriteFailed => debug.info_writer.err.?, + error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer), else => |e| e, }; } @@ -735,7 +733,7 @@ pub const WipNav = struct { code_off: u64, line: u32, column: u32, - ) (UpdateError || Writer.Error)!void { + ) link.EmitError!void { const dwarf = debug.wip_nav.dwarf; const zcu = debug.pt.zcu; const diw = &debug.info_writer.interface; @@ -754,10 +752,10 @@ pub const WipNav = struct { debug.any_children = false; } - pub fn leaveInlineFunc(debug: *Debug, func: InternPool.Index, code_off: u64) UpdateError!void { + pub fn leaveInlineFunc(debug: *Debug, func: InternPool.Index, code_off: u64) link.Error!void { if (true) return; return debug.leaveInlineFuncInner(func, code_off) catch |err| switch (err) { - error.WriteFailed => debug.info_writer.err.?, + error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer), else => |e| e, }; } @@ -765,7 +763,7 @@ pub const WipNav = struct { debug: *Debug, func: InternPool.Index, code_off: u64, - ) (UpdateError || Writer.Error)!void { + ) link.EmitError!void { const dwarf = debug.wip_nav.dwarf; const inlined_func_bytes = comptime uleb128Bytes(@backingInt(AbbrevCode.inlined_func)); const block = debug.blocks.pop().?; @@ -787,13 +785,13 @@ pub const WipNav = struct { debug.any_children = true; } - pub fn setInlineFunc(debug: *Debug, func: InternPool.Index) UpdateError!void { + pub fn setInlineFunc(debug: *Debug, func: InternPool.Index) link.Error!void { return debug.setInlineFuncInner(func) catch |err| switch (err) { - error.WriteFailed => debug.line_writer.err.?, + error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer), else => |e| e, }; } - fn setInlineFuncInner(debug: *Debug, func: InternPool.Index) (UpdateError || Writer.Error)!void { + fn setInlineFuncInner(debug: *Debug, func: InternPool.Index) link.EmitError!void { const wip_nav = &debug.wip_nav; const zcu = debug.pt.zcu; const dwarf = wip_nav.dwarf; @@ -855,7 +853,7 @@ pub const WipNav = struct { wip_nav.func = func; } - fn abbrevCode(debug: *Debug, abbrev_code: AbbrevCode) (UpdateError || Writer.Error)!void { + fn abbrevCode(debug: *Debug, abbrev_code: AbbrevCode) link.EmitError!void { try debug.info_writer.interface.writeUleb128(try debug.wip_nav.dwarf.refAbbrevCode(abbrev_code)); } @@ -872,7 +870,7 @@ pub const WipNav = struct { debug: *Debug, target: MappedFile.Node.Index, addend: i64, - ) (UpdateError || Writer.Error)!void { + ) link.EmitError!void { const dwarf = debug.wip_nav.dwarf; const diw = &debug.info_writer.interface; const offset = diw.end; @@ -892,7 +890,7 @@ pub const WipNav = struct { ); } - fn strp(debug: *Debug, str: []const u8) (UpdateError || Writer.Error)!void { + fn strp(debug: *Debug, str: []const u8) link.EmitError!void { if (true) @panic("TODO"); const dwarf = debug.wip_nav.dwarf; try debug.infoSectionOffset(.debug_str, try dwarf.debug_str.addString(dwarf, str), 0); @@ -902,14 +900,14 @@ pub const WipNav = struct { debug: *Debug, comptime fmt: []const u8, args: anytype, - ) (UpdateError || Writer.Error)!void { + ) link.EmitError!void { const gpa = &debug.wip_nav.dwarf.gpa; const str = try std.fmt.allocPrint(gpa, fmt, args); defer gpa.free(str); return debug.strp(str); } - fn infoExprLoc(debug: *Debug, loc: Loc) (UpdateError || Writer.Error)!void { + fn infoExprLoc(debug: *Debug, loc: Loc) link.EmitError!void { var buf: [64]u8 = undefined; var counter: ExprLocCounter = .init(debug.wip_nav.dwarf, &buf); try loc.write(&counter); @@ -922,13 +920,13 @@ pub const WipNav = struct { fn endian(ctx: @This()) std.lang.Endian { return ctx.debug.wip_nav.dwarf.endian; } - fn addrSym(ctx: @This(), si: link.File.SymbolId) (UpdateError || Writer.Error)!void { + fn addrSym(ctx: @This(), si: link.File.SymbolId) link.EmitError!void { try ctx.debug.infoAddrSym(si, 0); } fn infoEntry( ctx: @This(), node: MappedFile.Node.Index, - ) (UpdateError || Writer.Error)!void { + ) link.EmitError!void { try ctx.debug.infoSectionOffset(node, 0); } } = .{ .debug = debug }; @@ -940,7 +938,7 @@ pub const WipNav = struct { debug: *Debug, si: link.File.SymbolId, sym_off: u64, - ) (UpdateError || Writer.Error)!void { + ) link.EmitError!void { const diw = &debug.info_writer.interface; try debug.infoExternalReloc(.{ .source_off = @intCast(diw.end), @@ -950,20 +948,20 @@ pub const WipNav = struct { try diw.splatByteAll(0, @backingInt(debug.wip_nav.dwarf.address_size)); } - fn refNav(debug: *Debug, nav_index: InternPool.Nav.Index) (UpdateError || Writer.Error)!void { + fn refNav(debug: *Debug, nav_index: InternPool.Nav.Index) link.EmitError!void { try debug.infoSectionOffset(try debug.wip_nav.dwarf.getNavNode(nav_index), 0); } - fn refType(debug: *Debug, ty: Type) (UpdateError || Writer.Error)!void { + fn refType(debug: *Debug, ty: Type) link.EmitError!void { return debug.refValue(ty.toValue()); } - fn refValue(debug: *Debug, value: Value) (UpdateError || Writer.Error)!void { + fn refValue(debug: *Debug, value: Value) link.EmitError!void { if (true) @panic("TODO"); try debug.infoSectionOffset(.debug_info, try debug.getValueNode(value), 0); } - fn getValueNode(debug: *Debug, value: Value) UpdateError!MappedFile.Node.Index { + fn getValueNode(debug: *Debug, value: Value) link.Error!MappedFile.Node.Index { if (value.typeOf(debug.zcu).toIntern() != .type_type) { assert(value.typeOf(debug.zcu).comptimeOnly(debug.zcu)); } @@ -972,7 +970,7 @@ pub const WipNav = struct { return dwarf.values.items[@backingInt(index)]; } - fn blockValue(debug: *Debug, val: Value) (UpdateError || Writer.Error)!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); @@ -1004,13 +1002,13 @@ pub const WipNav = struct { wip_nav.* = undefined; } - pub fn genFuncHeaders(wip_nav: *WipNav) UpdateError!void { + pub fn genFuncHeaders(wip_nav: *WipNav) link.Error!void { wip_nav.genDebugFrameHeader() catch |err| switch (err) { - error.WriteFailed => return wip_nav.fde_writer.err.?, + error.WriteFailed => return wip_nav.reportWriteError(&wip_nav.fde_writer), else => |e| return e, }; } - fn genDebugFrameHeader(wip_nav: *WipNav) (UpdateError || Writer.Error)!void { + fn genDebugFrameHeader(wip_nav: *WipNav) link.EmitError!void { assert(wip_nav.func != null); const dwarf = wip_nav.dwarf; const dfw = &wip_nav.fde_writer.interface; @@ -1050,13 +1048,13 @@ pub const WipNav = struct { } } - pub fn genDebugFrame(wip_nav: *WipNav, loc: u32, cfa: Cfa) UpdateError!void { + pub fn genDebugFrame(wip_nav: *WipNav, loc: u32, cfa: Cfa) link.Error!void { return wip_nav.genDebugFrameInner(loc, cfa) catch |err| switch (err) { - error.WriteFailed => wip_nav.fde_writer.err.?, - else => |e| e, + error.WriteFailed => return wip_nav.reportWriteError(&wip_nav.fde_writer), + else => |e| return e, }; } - fn genDebugFrameInner(wip_nav: *WipNav, loc: u32, cfa: Cfa) (UpdateError || Writer.Error)!void { + fn genDebugFrameInner(wip_nav: *WipNav, loc: u32, cfa: Cfa) link.EmitError!void { assert(wip_nav.func != null); const loc_cfa: Cfa = .{ .advance_loc = loc }; try loc_cfa.write(wip_nav); @@ -1123,7 +1121,7 @@ pub const WipNav = struct { wip_nav: *WipNav, target: MappedFile.Node.Index, addend: i64, - ) (UpdateError || Writer.Error)!void { + ) link.EmitError!void { const dwarf = wip_nav.dwarf; const dfw = &wip_nav.fde_writer.interface; const offset = dfw.end; @@ -1143,7 +1141,7 @@ pub const WipNav = struct { ); } - fn frameExprLoc(wip_nav: *WipNav, loc: Loc) (UpdateError || Writer.Error)!void { + fn frameExprLoc(wip_nav: *WipNav, loc: Loc) link.EmitError!void { var buf: [64]u8 = undefined; var counter: ExprLocCounter = .init(wip_nav.dwarf, &buf); try loc.write(&counter); @@ -1156,10 +1154,10 @@ pub const WipNav = struct { fn endian(ctx: @This()) std.lang.Endian { return ctx.wip_nav.dwarf.endian; } - fn addrSym(ctx: @This(), si: link.File.SymbolId) (UpdateError || Writer.Error)!void { + fn addrSym(ctx: @This(), si: link.File.SymbolId) link.EmitError!void { try ctx.wip_nav.frameAddrSym(si, 0); } - fn infoEntry(ctx: @This(), node: MappedFile.Node.Index) (UpdateError || Writer.Error)!void { + fn infoEntry(ctx: @This(), node: MappedFile.Node.Index) link.EmitError!void { try ctx.wip_nav.frameSectionOffset(node, 0); } } = .{ .wip_nav = wip_nav }; @@ -1171,7 +1169,7 @@ pub const WipNav = struct { wip_nav: *WipNav, si: link.File.SymbolId, sym_off: u64, - ) (UpdateError || Writer.Error)!void { + ) link.EmitError!void { const dwarf = wip_nav.dwarf; const dfw = &wip_nav.fde_writer.interface; const offset = dfw.end; @@ -1188,6 +1186,16 @@ pub const WipNav = struct { }, ); } + + fn reportWriteError(wip_nav: *WipNav, mfnw: *const MappedFile.Node.Writer) link.Error { + switch (mfnw.err.?) { + else => |e| return e, + error.MappedFileIo => return wip_nav.dwarf.linkFile().comp.link_diags.fail( + "failed to write output file: {t}", + .{mfnw.mf.io_err.?}, + ), + } + } }; pub fn init(lf: *link.File, format: DW.Format) Dwarf { @@ -1283,7 +1291,7 @@ pub fn initUnits(dwarf: *Dwarf, zcu: *Zcu) Allocator.Error!void { }; } -fn getNavNode(dwarf: *Dwarf, nav_index: InternPool.Nav.Index) UpdateError!MappedFile.Node.Index { +fn getNavNode(dwarf: *Dwarf, nav_index: InternPool.Nav.Index) link.Error!MappedFile.Node.Index { if (true) @panic("TODO"); const zcu = dwarf.linkFile().comp.zcu.?; const ip = &zcu.intern_pool; @@ -1329,7 +1337,7 @@ pub fn genEhFrameHdr( eh_frame_hdr_ai: link.File.AtomId, eh_frame_hdr: *EhFrameHdr, eh_frame_si: link.File.SymbolId, -) UpdateError!void { +) link.Error!void { eh_frame_hdr.* = .{ .version = 1, .eh_frame_ptr_enc = .{ .type = .sdata4, .rel = .pcrel }, @@ -1423,7 +1431,7 @@ pub fn updateEhFrameFde(dwarf: *Dwarf, fde: []u8, fde_offset: u64) void { fn refAbbrevCode( dwarf: *Dwarf, abbrev_code: AbbrevCode, -) (UpdateError || Writer.Error)!@typeInfo(AbbrevCode).@"enum".tag_type { +) link.EmitError!@typeInfo(AbbrevCode).@"enum".tag_type { if (true) @panic("TODO"); const Entry = {}; const DebugAbbrev = {}; diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index bf45dcc7353ff11676bb5bb8d50e75ac6bb82f34..27268c24d136157379a9a76f5bf059df9f81c2c6 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -1549,7 +1549,6 @@ pub fn updateFunc( if (debug_wip_nav) |*dn| .{ .dwarf = dn } else .none, ) catch |err| switch (err) { error.WriteFailed => return error.OutOfMemory, - error.MappedFileIo => unreachable, // MappedFile is not being used else => |e| return e, }; const code = aw.written(); diff --git a/src/link/Elf2.zig b/src/link/Elf2.zig index 5d9d719a455129a817391d7faa13ed456c3a800e..1e2b6560526a77cd7d93c0b3b247737f2a590eca 100644 --- a/src/link/Elf2.zig +++ b/src/link/Elf2.zig @@ -181,10 +181,10 @@ lazy: std.EnumArray(link.File.LazySymbol.Kind, struct { }), pending_uavs: std.ArrayList(Node.UavMapIndex), symbol_relocs: std.ArrayList(SymbolReloc), -/// Set of relocations which must be re-applied if the size of the TLS segment changes. -tls_size_symbol_relocs: std.array_hash_map.Auto(SymbolReloc.Index, void), node_relocs: std.ArrayList(NodeReloc), got_relocs: std.ArrayList(GotReloc), +/// Set of relocations which must be re-applied if the size of the TLS segment changes. +tls_size_symbol_relocs: std.array_hash_map.Auto(SymbolReloc.Index, void), /// Index matches the index into `shdrs`. Like `shdrs`, this map excludes `SHN_UNDEF`. section_by_name: std.array_hash_map.Auto(String(.shstrtab), void), /// Key is the name of a global symbol which has been moved to a new symtab index. Any relocation @@ -3708,15 +3708,15 @@ fn create( }), .pending_uavs = .empty, .symbol_relocs = .empty, - .tls_size_symbol_relocs = .empty, .node_relocs = .empty, .got_relocs = .empty, + .tls_size_symbol_relocs = .empty, .section_by_name = .empty, .changed_symtab_index = .empty, .textrel_count = 0, .dwarf = .init(&elf.base, switch (comp.config.debug_format) { - .strip => .@"32", + .strip => .@"32", // for .eh_frame .dwarf => |v| v, .code_view => unreachable, }), @@ -3768,9 +3768,9 @@ pub fn deinit(elf: *Elf) void { for (&elf.lazy.values) |*lazy| lazy.map.deinit(gpa); elf.pending_uavs.deinit(gpa); elf.symbol_relocs.deinit(gpa); - elf.tls_size_symbol_relocs.deinit(gpa); elf.node_relocs.deinit(gpa); elf.got_relocs.deinit(gpa); + elf.tls_size_symbol_relocs.deinit(gpa); elf.section_by_name.deinit(gpa); elf.changed_symtab_index.deinit(gpa); @@ -8342,7 +8342,9 @@ fn updateFuncInner( &nw.interface, debug_output, ) catch |err| switch (err) { - error.WriteFailed => return nw.err.?, + error.WriteFailed => { + if (nw.err) |e| return e; + }, else => |e| return e, }; const func_length = nw.interface.end; @@ -9899,17 +9901,19 @@ fn updateExportInner( }; } -fn dumpStderr(elf: *Elf, tid: Zcu.PerThread.Id) !void { +fn dumpStderr(elf: *Elf, tid: Zcu.PerThread.Id) Io.File.Writer.Error!void { const comp = elf.base.comp; const io = comp.io; var buffer: [512]u8 = undefined; const stderr = try io.lockStderr(&buffer, null); defer io.unlockStderr(); const w = &stderr.file_writer.interface; - _ = try elf.dump(w, tid); + _ = elf.dump(w, tid) catch |err| switch (err) { + error.WriteFailed => return stderr.file_writer.err.?, + }; } -pub fn dump(elf: *Elf, w: *Io.Writer, tid: Zcu.PerThread.Id) !link.File.DumpResult { +pub fn dump(elf: *Elf, w: *Io.Writer, tid: Zcu.PerThread.Id) Io.Writer.Error!link.File.DumpResult { if (elf.options.enable_link_snapshots) { try elf.printNode(tid, w, .root, 0); return .enabled; diff --git a/src/link/MachO/ZigObject.zig b/src/link/MachO/ZigObject.zig index d6e87a551ac0a5c15fb94dea437db825d906fb26..3ae2cda02926c7dcf650d050d59785ee8b276acf 100644 --- a/src/link/MachO/ZigObject.zig +++ b/src/link/MachO/ZigObject.zig @@ -790,7 +790,6 @@ pub fn updateFunc( if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none, ) catch |err| switch (err) { error.WriteFailed => return error.OutOfMemory, - error.MappedFileIo => unreachable, // MappedFile is not being used else => |e| return e, }; const code = aw.written(); -- 2.54.0