authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-08-06 10:13:44-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-03 11:00:53-04:00
log2375b0063da554eeb1ed4b0b8dbe8dad485c5f6a
treecd402500c22638f6ac5a4c1a64c3f60f21deb939
parent79bb28aa57b3712116dc75288d60f2d29ba31cfb

link: improve explicit error sets

"I think we made the error sets good now"

16 files changed, 126 insertions(+), 114 deletions(-)

src/codegen.zig+7-8
...@@ -26,7 +26,6 @@ pub const aarch64 = @import("codegen/aarch64.zig");...@@ -26,7 +26,6 @@ pub const aarch64 = @import("codegen/aarch64.zig");
26pub const loongarch = @import("codegen/loongarch.zig");26pub const loongarch = @import("codegen/loongarch.zig");
2727
28pub const Error = link.Error;28pub const Error = link.Error;
29pub const EmitError = Error || std.Io.Writer.Error || error{MappedFileIo};
3029
31fn devFeatureForBackend(backend: std.lang.CompilerBackend) dev.Feature {30fn devFeatureForBackend(backend: std.lang.CompilerBackend) dev.Feature {
32 return switch (backend) {31 return switch (backend) {
...@@ -197,7 +196,7 @@ pub fn emitFunction(...@@ -197,7 +196,7 @@ pub fn emitFunction(
197 any_mir: *const AnyMir,196 any_mir: *const AnyMir,
198 w: *std.Io.Writer,197 w: *std.Io.Writer,
199 debug_output: link.File.DebugInfoOutput,198 debug_output: link.File.DebugInfoOutput,
200) EmitError!void {199) link.EmitError!void {
201 const zcu = pt.zcu;200 const zcu = pt.zcu;
202 const func = zcu.funcInfo(func_index);201 const func = zcu.funcInfo(func_index);
203 const target = &zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result;202 const target = &zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result;
...@@ -229,7 +228,7 @@ pub fn generateLazyFunction(...@@ -229,7 +228,7 @@ pub fn generateLazyFunction(
229 atom_id: link.File.AtomId,228 atom_id: link.File.AtomId,
230 w: *std.Io.Writer,229 w: *std.Io.Writer,
231 debug_output: link.File.DebugInfoOutput,230 debug_output: link.File.DebugInfoOutput,
232) EmitError!void {231) link.EmitError!void {
233 const zcu = pt.zcu;232 const zcu = pt.zcu;
234 const target = if (Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu)) |inst_index|233 const target = if (Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu)) |inst_index|
235 &zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.?.resolved_target.result234 &zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.?.resolved_target.result
...@@ -253,7 +252,7 @@ pub fn generateLazySymbol(...@@ -253,7 +252,7 @@ pub fn generateLazySymbol(
253 w: *std.Io.Writer,252 w: *std.Io.Writer,
254 debug_output: link.File.DebugInfoOutput,253 debug_output: link.File.DebugInfoOutput,
255 reloc_parent: link.File.RelocInfo.Parent,254 reloc_parent: link.File.RelocInfo.Parent,
256) EmitError!void {255) link.EmitError!void {
257 const tracy = trace(@src());256 const tracy = trace(@src());
258 defer tracy.end();257 defer tracy.end();
259 tracy.addTextFmt("{t}, {f}", .{ lazy_sym.kind, Type.fromInterned(lazy_sym.ty).fmt(pt) });258 tracy.addTextFmt("{t}, {f}", .{ lazy_sym.kind, Type.fromInterned(lazy_sym.ty).fmt(pt) });
...@@ -315,7 +314,7 @@ pub fn generateSymbol(...@@ -315,7 +314,7 @@ pub fn generateSymbol(
315 val: Value,314 val: Value,
316 w: *std.Io.Writer,315 w: *std.Io.Writer,
317 reloc_parent: link.File.RelocInfo.Parent,316 reloc_parent: link.File.RelocInfo.Parent,
318) (Error || std.Io.Writer.Error)!void {317) link.EmitError!void {
319 const tracy = trace(@src());318 const tracy = trace(@src());
320 defer tracy.end();319 defer tracy.end();
321320
...@@ -666,7 +665,7 @@ fn lowerPtr(...@@ -666,7 +665,7 @@ fn lowerPtr(
666 w: *std.Io.Writer,665 w: *std.Io.Writer,
667 reloc_parent: link.File.RelocInfo.Parent,666 reloc_parent: link.File.RelocInfo.Parent,
668 prev_offset: u64,667 prev_offset: u64,
669) (Error || std.Io.Writer.Error)!void {668) link.EmitError!void {
670 const zcu = pt.zcu;669 const zcu = pt.zcu;
671 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;670 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;
672 const offset: u64 = prev_offset + ptr.byte_offset;671 const offset: u64 = prev_offset + ptr.byte_offset;
...@@ -724,7 +723,7 @@ fn lowerUavRef(...@@ -724,7 +723,7 @@ fn lowerUavRef(
724 w: *std.Io.Writer,723 w: *std.Io.Writer,
725 reloc_parent: link.File.RelocInfo.Parent,724 reloc_parent: link.File.RelocInfo.Parent,
726 offset: u64,725 offset: u64,
727) (Error || std.Io.Writer.Error)!void {726) link.EmitError!void {
728 const zcu = pt.zcu;727 const zcu = pt.zcu;
729 const ip = &zcu.intern_pool;728 const ip = &zcu.intern_pool;
730 const comp = lf.comp;729 const comp = lf.comp;
...@@ -782,7 +781,7 @@ fn lowerNavRef(...@@ -782,7 +781,7 @@ fn lowerNavRef(
782 w: *std.Io.Writer,781 w: *std.Io.Writer,
783 reloc_parent: link.File.RelocInfo.Parent,782 reloc_parent: link.File.RelocInfo.Parent,
784 offset: u64,783 offset: u64,
785) (Error || std.Io.Writer.Error)!void {784) link.EmitError!void {
786 const zcu = pt.zcu;785 const zcu = pt.zcu;
787 const ip = &zcu.intern_pool;786 const ip = &zcu.intern_pool;
788 const target = &zcu.navFileScope(nav_index).mod.?.resolved_target.result;787 const target = &zcu.navFileScope(nav_index).mod.?.resolved_target.result;
src/codegen/loongarch/Select.zig+8-8
...@@ -1020,7 +1020,7 @@ pub const Value = struct {...@@ -1020,7 +1020,7 @@ pub const Value = struct {
1020 /// Defines a value with a location.1020 /// Defines a value with a location.
1021 /// Returned location must be free-ed by caller.1021 /// Returned location must be free-ed by caller.
1022 /// Extension unchanged.1022 /// Extension unchanged.
1023 fn def(vi: Value.Index, isel: *Select) error{ AlreadyReported, OutOfMemory }!?Location {1023 fn def(vi: Value.Index, isel: *Select) codegen.Error!?Location {
1024 try vi.collectDefs(isel);1024 try vi.collectDefs(isel);
1025 return vi.takeLocationMarkWritten(isel);1025 return vi.takeLocationMarkWritten(isel);
1026 }1026 }
...@@ -2046,7 +2046,7 @@ pub const Value = struct {...@@ -2046,7 +2046,7 @@ pub const Value = struct {
2046 if (!std.debug.runtime_safety) assert(@sizeOf(Mat) <= 32);2046 if (!std.debug.runtime_safety) assert(@sizeOf(Mat) <= 32);
2047 }2047 }
20482048
2049 const Error = error{ OutOfMemory, AlreadyReported };2049 const Error = codegen.Error;
20502050
2051 pub fn ra(mat: Value.Mat) Register.Alias {2051 pub fn ra(mat: Value.Mat) Register.Alias {
2052 return mat.location.register;2052 return mat.location.register;
...@@ -2296,13 +2296,13 @@ pub const Value = struct {...@@ -2296,13 +2296,13 @@ pub const Value = struct {
2296 };2296 };
2297};2297};
22982298
2299fn fail(isel: *Select, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } {2299fn fail(isel: *Select, comptime format: []const u8, args: anytype) codegen.Error {
2300 @branchHint(.cold);2300 @branchHint(.cold);
2301 wip_mir_log.debug("codegen error: " ++ format, args);2301 wip_mir_log.debug("codegen error: " ++ format, args);
2302 return isel.pt.zcu.codegenFail(isel.nav_index, format, args);2302 return isel.pt.zcu.codegenFail(isel.nav_index, format, args);
2303}2303}
23042304
2305fn failUnimplemented(isel: *Select, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported }!void {2305fn failUnimplemented(isel: *Select, comptime format: []const u8, args: anytype) codegen.Error!void {
2306 @branchHint(.cold);2306 @branchHint(.cold);
2307 if (debug_trap_unimplemented_code) {2307 if (debug_trap_unimplemented_code) {
2308 const gpa = isel.pt.zcu.gpa;2308 const gpa = isel.pt.zcu.gpa;
...@@ -2963,7 +2963,7 @@ pub fn verify(isel: *Select, check_values: bool) void {...@@ -2963,7 +2963,7 @@ pub fn verify(isel: *Select, check_values: bool) void {
2963 }2963 }
2964}2964}
29652965
2966pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, AlreadyReported }!void {2966pub fn body(isel: *Select, air_body: []const Air.Inst.Index) codegen.Error!void {
2967 const zcu = isel.pt.zcu;2967 const zcu = isel.pt.zcu;
2968 const ip = &zcu.intern_pool;2968 const ip = &zcu.intern_pool;
2969 const gpa = zcu.gpa;2969 const gpa = zcu.gpa;
...@@ -5341,7 +5341,7 @@ fn forgetReg(isel: *Select, dst_reg: Register) error{ OutOfMemory, AlreadyReport...@@ -5341,7 +5341,7 @@ fn forgetReg(isel: *Select, dst_reg: Register) error{ OutOfMemory, AlreadyReport
53415341
5342/// Frees a register by moving it to another place.5342/// Frees a register by moving it to another place.
5343/// Returns true on success, false on failure (i.e. dst_reg is locked/allocated or unallocatable).5343/// Returns true on success, false on failure (i.e. dst_reg is locked/allocated or unallocatable).
5344fn fillReg(isel: *Select, dst_reg: Register) error{ OutOfMemory, AlreadyReported }!bool {5344fn fillReg(isel: *Select, dst_reg: Register) codegen.Error!bool {
5345 if (!isRegisterAllocatable(dst_reg)) return false;5345 if (!isRegisterAllocatable(dst_reg)) return false;
5346 const dst_live_vi = isel.live_registers.getPtr(dst_reg);5346 const dst_live_vi = isel.live_registers.getPtr(dst_reg);
5347 const dst_vi = switch (dst_live_vi.*) {5347 const dst_vi = switch (dst_live_vi.*) {
...@@ -5377,7 +5377,7 @@ fn fillReg(isel: *Select, dst_reg: Register) error{ OutOfMemory, AlreadyReported...@@ -5377,7 +5377,7 @@ fn fillReg(isel: *Select, dst_reg: Register) error{ OutOfMemory, AlreadyReported
5377/// Frees a set of register. If locked is true, these registers are then locked.5377/// Frees a set of register. If locked is true, these registers are then locked.
5378/// Requires all registers to be unlocked.5378/// Requires all registers to be unlocked.
5379/// Returns true on success.5379/// Returns true on success.
5380fn fillRegsBatch(isel: *Select, regs: RegisterSet, locking: bool) error{ OutOfMemory, AlreadyReported }!void {5380fn fillRegsBatch(isel: *Select, regs: RegisterSet, locking: bool) codegen.Error!void {
5381 tracking_log.debug("batch fill: {f}", .{fmtRegisterSet(regs)});5381 tracking_log.debug("batch fill: {f}", .{fmtRegisterSet(regs)});
5382 // lock free registers5382 // lock free registers
5383 var regs_it = regs.iterator();5383 var regs_it = regs.iterator();
...@@ -5419,7 +5419,7 @@ fn fillRegsBatch(isel: *Select, regs: RegisterSet, locking: bool) error{ OutOfMe...@@ -5419,7 +5419,7 @@ fn fillRegsBatch(isel: *Select, regs: RegisterSet, locking: bool) error{ OutOfMe
54195419
5420/// Frees a register by moving it to stack.5420/// Frees a register by moving it to stack.
5421/// Returns true on success, false on failure (i.e. dst_reg is locked/allocated or unallocatable).5421/// Returns true on success, false on failure (i.e. dst_reg is locked/allocated or unallocatable).
5422fn fillRegToMemory(isel: *Select, dst_reg: Register) error{ OutOfMemory, AlreadyReported }!bool {5422fn fillRegToMemory(isel: *Select, dst_reg: Register) codegen.Error!bool {
5423 if (!isRegisterAllocatable(dst_reg)) return false;5423 if (!isRegisterAllocatable(dst_reg)) return false;
5424 const dst_live_vi = isel.live_registers.getPtr(dst_reg);5424 const dst_live_vi = isel.live_registers.getPtr(dst_reg);
5425 const dst_vi = switch (dst_live_vi.*) {5425 const dst_vi = switch (dst_live_vi.*) {
src/codegen/riscv64/CodeGen.zig+1-1
...@@ -856,7 +856,7 @@ pub fn generateLazy(...@@ -856,7 +856,7 @@ pub fn generateLazy(
856 atom_index: link.File.AtomId,856 atom_index: link.File.AtomId,
857 w: *std.Io.Writer,857 w: *std.Io.Writer,
858 debug_output: link.File.DebugInfoOutput,858 debug_output: link.File.DebugInfoOutput,
859) codegen.EmitError!void {859) link.EmitError!void {
860 _ = atom_index;860 _ = atom_index;
861 const comp = bin_file.comp;861 const comp = bin_file.comp;
862 const gpa = comp.gpa;862 const gpa = comp.gpa;
src/codegen/riscv64/Emit.zig+1-1
...@@ -13,7 +13,7 @@ prev_di_pc: usize,...@@ -13,7 +13,7 @@ prev_di_pc: usize,
13code_offset_mapping: std.AutoHashMapUnmanaged(Mir.Inst.Index, usize) = .empty,13code_offset_mapping: std.AutoHashMapUnmanaged(Mir.Inst.Index, usize) = .empty,
14relocs: std.ArrayList(Reloc) = .empty,14relocs: std.ArrayList(Reloc) = .empty,
1515
16pub const Error = Lower.Error || codegen.EmitError || error{16pub const Error = Lower.Error || link.EmitError || error{
17 EmitFail,17 EmitFail,
18};18};
1919
src/codegen/riscv64/Mir.zig+1-1
...@@ -111,7 +111,7 @@ pub fn emit(...@@ -111,7 +111,7 @@ pub fn emit(
111 atom_index: link.File.AtomId,111 atom_index: link.File.AtomId,
112 w: *std.Io.Writer,112 w: *std.Io.Writer,
113 debug_output: link.File.DebugInfoOutput,113 debug_output: link.File.DebugInfoOutput,
114) codegen.EmitError!void {114) link.EmitError!void {
115 _ = atom_index;115 _ = atom_index;
116 const zcu = pt.zcu;116 const zcu = pt.zcu;
117 const comp = zcu.comp;117 const comp = zcu.comp;
src/codegen/sparc64/Emit.zig+1-1
...@@ -41,7 +41,7 @@ branch_forward_origins: std.AutoHashMapUnmanaged(Mir.Inst.Index, std.ArrayList(M...@@ -41,7 +41,7 @@ branch_forward_origins: std.AutoHashMapUnmanaged(Mir.Inst.Index, std.ArrayList(M
41/// instruction41/// instruction
42code_offset_mapping: std.AutoHashMapUnmanaged(Mir.Inst.Index, usize) = .empty,42code_offset_mapping: std.AutoHashMapUnmanaged(Mir.Inst.Index, usize) = .empty,
4343
44const InnerError = codegen.EmitError || error{44const InnerError = link.EmitError || error{
45 EmitFail,45 EmitFail,
46};46};
4747
src/codegen/sparc64/Mir.zig+1-1
...@@ -382,7 +382,7 @@ pub fn emit(...@@ -382,7 +382,7 @@ pub fn emit(
382 atom_index: link.File.AtomId,382 atom_index: link.File.AtomId,
383 w: *std.Io.Writer,383 w: *std.Io.Writer,
384 debug_output: link.File.DebugInfoOutput,384 debug_output: link.File.DebugInfoOutput,
385) codegen.EmitError!void {385) link.EmitError!void {
386 _ = atom_index;386 _ = atom_index;
387 const zcu = pt.zcu;387 const zcu = pt.zcu;
388 const func = zcu.funcInfo(func_index);388 const func = zcu.funcInfo(func_index);
src/codegen/x86_64/CodeGen.zig+1-1
...@@ -1120,7 +1120,7 @@ pub fn generateLazy(...@@ -1120,7 +1120,7 @@ pub fn generateLazy(
1120 atom_id: link.File.AtomId,1120 atom_id: link.File.AtomId,
1121 w: *std.Io.Writer,1121 w: *std.Io.Writer,
1122 debug_output: link.File.DebugInfoOutput,1122 debug_output: link.File.DebugInfoOutput,
1123) codegen.EmitError!void {1123) link.EmitError!void {
1124 const gpa = pt.zcu.gpa;1124 const gpa = pt.zcu.gpa;
1125 // This function is for generating global code, so we use the root module.1125 // This function is for generating global code, so we use the root module.
1126 const mod = pt.zcu.comp.root_mod;1126 const mod = pt.zcu.comp.root_mod;
src/codegen/x86_64/Emit.zig+1-1
...@@ -16,7 +16,7 @@ code_offset_mapping: std.ArrayList(u32),...@@ -16,7 +16,7 @@ code_offset_mapping: std.ArrayList(u32),
16relocs: std.ArrayList(Reloc),16relocs: std.ArrayList(Reloc),
17table_relocs: std.ArrayList(TableReloc),17table_relocs: std.ArrayList(TableReloc),
1818
19pub const Error = Lower.Error || codegen.EmitError || error{19pub const Error = Lower.Error || codegen.Error || std.Io.Writer.Error || error{
20 EmitFail,20 EmitFail,
21} || std.posix.MMapError || std.posix.MRemapError || link.File.UpdateDebugInfoError;21} || std.posix.MMapError || std.posix.MRemapError || link.File.UpdateDebugInfoError;
2222
src/codegen/x86_64/Mir.zig+4-4
...@@ -1978,7 +1978,7 @@ pub fn emit(...@@ -1978,7 +1978,7 @@ pub fn emit(
1978 atom_id: link.File.AtomId,1978 atom_id: link.File.AtomId,
1979 w: *std.Io.Writer,1979 w: *std.Io.Writer,
1980 debug_output: link.File.DebugInfoOutput,1980 debug_output: link.File.DebugInfoOutput,
1981) codegen.EmitError!void {1981) link.EmitError!void {
1982 const zcu = pt.zcu;1982 const zcu = pt.zcu;
1983 const comp = zcu.comp;1983 const comp = zcu.comp;
1984 const gpa = comp.gpa;1984 const gpa = comp.gpa;
...@@ -2021,7 +2021,7 @@ pub fn emit(...@@ -2021,7 +2021,7 @@ pub fn emit(
2021 error.LowerFail, error.EmitFail => return zcu.codegenFailMsg(nav, em.lower.err_msg.?),2021 error.LowerFail, error.EmitFail => return zcu.codegenFailMsg(nav, em.lower.err_msg.?),
2022 error.InvalidInstruction, error.CannotEncode => return zcu.codegenFail(nav, "emit MIR failed: {s} (Zig compiler bug)", .{@errorName(err)}),2022 error.InvalidInstruction, error.CannotEncode => return zcu.codegenFail(nav, "emit MIR failed: {s} (Zig compiler bug)", .{@errorName(err)}),
2023 else => return zcu.codegenFail(nav, "emit MIR failed: {s}", .{@errorName(err)}),2023 else => return zcu.codegenFail(nav, "emit MIR failed: {s}", .{@errorName(err)}),
2024 error.AlreadyReported, error.Canceled, error.MappedFileIo, error.WriteFailed => |e| return e,2024 error.AlreadyReported, error.Canceled, error.WriteFailed => |e| return e,
2025 };2025 };
2026}2026}
20272027
...@@ -2033,7 +2033,7 @@ pub fn emitLazy(...@@ -2033,7 +2033,7 @@ pub fn emitLazy(
2033 atom_id: link.File.AtomId,2033 atom_id: link.File.AtomId,
2034 w: *std.Io.Writer,2034 w: *std.Io.Writer,
2035 debug_output: link.File.DebugInfoOutput,2035 debug_output: link.File.DebugInfoOutput,
2036) codegen.EmitError!void {2036) link.EmitError!void {
2037 const zcu = pt.zcu;2037 const zcu = pt.zcu;
2038 const comp = zcu.comp;2038 const comp = zcu.comp;
2039 const gpa = comp.gpa;2039 const gpa = comp.gpa;
...@@ -2065,7 +2065,7 @@ pub fn emitLazy(...@@ -2065,7 +2065,7 @@ pub fn emitLazy(
2065 error.LowerFail, error.EmitFail => return zcu.codegenFailTypeMsg(lazy_sym.ty, em.lower.err_msg.?),2065 error.LowerFail, error.EmitFail => return zcu.codegenFailTypeMsg(lazy_sym.ty, em.lower.err_msg.?),
2066 error.InvalidInstruction, error.CannotEncode => return zcu.codegenFailType(lazy_sym.ty, "emit MIR failed: {s} (Zig compiler bug)", .{@errorName(err)}),2066 error.InvalidInstruction, error.CannotEncode => return zcu.codegenFailType(lazy_sym.ty, "emit MIR failed: {s} (Zig compiler bug)", .{@errorName(err)}),
2067 else => return zcu.codegenFailType(lazy_sym.ty, "emit MIR failed: {s}", .{@errorName(err)}),2067 else => return zcu.codegenFailType(lazy_sym.ty, "emit MIR failed: {s}", .{@errorName(err)}),
2068 error.AlreadyReported, error.Canceled, error.MappedFileIo, error.WriteFailed => |e| return e,2068 error.AlreadyReported, error.Canceled, error.WriteFailed => |e| return e,
2069 };2069 };
2070}2070}
20712071
src/link.zig+1
...@@ -38,6 +38,7 @@ pub const Error = Allocator.Error || Io.Cancelable || error{...@@ -38,6 +38,7 @@ pub const Error = Allocator.Error || Io.Cancelable || error{
38 /// instance in `Compilation.link_diags`.38 /// instance in `Compilation.link_diags`.
39 AlreadyReported,39 AlreadyReported,
40};40};
41pub const EmitError = Error || Io.Writer.Error;
4142
42pub const Diags = struct {43pub const Diags = struct {
43 /// Stored here so that function definitions can distinguish between44 /// Stored here so that function definitions can distinguish between
src/link/Coff.zig+10-8
...@@ -7356,7 +7356,7 @@ fn updateExportInner(...@@ -7356,7 +7356,7 @@ fn updateExportInner(
7356 pt: Zcu.PerThread,7356 pt: Zcu.PerThread,
7357 export_index: Zcu.Export.Index,7357 export_index: Zcu.Export.Index,
7358 alias_syms: *std.array_hash_map.Auto(Symbol.Index, Symbol.Index),7358 alias_syms: *std.array_hash_map.Auto(Symbol.Index, Symbol.Index),
7359) !void {7359) Error!void {
7360 const zcu = pt.zcu;7360 const zcu = pt.zcu;
7361 const gpa = zcu.gpa;7361 const gpa = zcu.gpa;
7362 const ip = &zcu.intern_pool;7362 const ip = &zcu.intern_pool;
...@@ -7519,17 +7519,19 @@ fn updateExportInner(...@@ -7519,17 +7519,19 @@ fn updateExportInner(
7519 }7519 }
7520}7520}
75217521
7522fn dumpStderr(coff: *Coff, tid: Zcu.PerThread.Id) !void {7522fn dumpStderr(coff: *Coff, tid: Zcu.PerThread.Id) Io.File.Writer.Error!void {
7523 const comp = coff.base.comp;7523 const comp = coff.base.comp;
7524 const io = comp.io;7524 const io = comp.io;
7525 var buffer: [512]u8 = undefined;7525 var buffer: [512]u8 = undefined;
7526 const stderr = try io.lockStderr(&buffer, null);7526 const stderr = try io.lockStderr(&buffer, null);
7527 defer io.unlockStderr();7527 defer io.unlockStderr();
7528 const w = &stderr.file_writer.interface;7528 const w = &stderr.file_writer.interface;
7529 _ = try coff.dump(w, tid);7529 _ = coff.dump(w, tid) catch |err| switch (err) {
7530 error.WriteFailed => return stderr.file_writer.err.?,
7531 };
7530}7532}
75317533
7532pub fn dump(coff: *Coff, w: *Io.Writer, tid: Zcu.PerThread.Id) !link.File.DumpResult {7534pub fn dump(coff: *Coff, w: *Io.Writer, tid: Zcu.PerThread.Id) Io.Writer.Error!link.File.DumpResult {
7533 if (coff.options.enable_link_snapshots) {7535 if (coff.options.enable_link_snapshots) {
7534 try coff.printNode(tid, w, .root, 0);7536 try coff.printNode(tid, w, .root, 0);
7535 try w.writeAll("Section table:\n");7537 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...@@ -7544,7 +7546,7 @@ pub fn dump(coff: *Coff, w: *Io.Writer, tid: Zcu.PerThread.Id) !link.File.DumpRe
7544 return .disabled;7546 return .disabled;
7545}7547}
75467548
7547fn printSection(coff: *Coff, w: *Io.Writer, name: String, si: Symbol.Index) !void {7549fn printSection(coff: *Coff, w: *Io.Writer, name: String, si: Symbol.Index) Io.Writer.Error!void {
7548 const sym = si.get(coff);7550 const sym = si.get(coff);
7549 try w.print("{d:0>6}@{d:0>2} {x:08} n{d:0>8} | {s}\n", .{7551 try w.print("{d:0>6}@{d:0>2} {x:08} n{d:0>8} | {s}\n", .{
7550 si,7552 si,
...@@ -7560,7 +7562,7 @@ fn printSymbol(...@@ -7560,7 +7562,7 @@ fn printSymbol(
7560 w: *Io.Writer,7562 w: *Io.Writer,
7561 tid: Zcu.PerThread.Id,7563 tid: Zcu.PerThread.Id,
7562 si: Symbol.Index,7564 si: Symbol.Index,
7563) !void {7565) Io.Writer.Error!void {
7564 const sym = si.get(coff);7566 const sym = si.get(coff);
7565 try w.print("{d:0>6}@{d:0>2} {x:08} {s} {s} {s} n{d:0>8}+{x:08}:{s: <26} | {x:08} ", .{7567 try w.print("{d:0>6}@{d:0>2} {x:08} {s} {s} {s} n{d:0>8}+{x:08}:{s: <26} | {x:08} ", .{
7566 si,7568 si,
...@@ -7622,7 +7624,7 @@ fn printNodeName(...@@ -7622,7 +7624,7 @@ fn printNodeName(
7622 w: *std.Io.Writer,7624 w: *std.Io.Writer,
7623 tid: Zcu.PerThread.Id,7625 tid: Zcu.PerThread.Id,
7624 node: Node,7626 node: Node,
7625) !void {7627) Io.Writer.Error!void {
7626 switch (node) {7628 switch (node) {
7627 else => {},7629 else => {},
7628 .image_section => |si| try w.print("({s})", .{7630 .image_section => |si| try w.print("({s})", .{
...@@ -7702,7 +7704,7 @@ pub fn printNode(...@@ -7702,7 +7704,7 @@ pub fn printNode(
7702 w: *Io.Writer,7704 w: *Io.Writer,
7703 ni: MappedFile.Node.Index,7705 ni: MappedFile.Node.Index,
7704 indent: usize,7706 indent: usize,
7705) !void {7707) Io.Writer.Error!void {
7706 const node = coff.getNode(ni);7708 const node = coff.getNode(ni);
7707 try w.splatByteAll(' ', indent);7709 try w.splatByteAll(' ', indent);
7708 try w.writeAll(@tagName(node));7710 try w.writeAll(@tagName(node));
src/link/Dwarf2.zig+76-68
...@@ -16,8 +16,6 @@ frame: Frame,...@@ -16,8 +16,6 @@ frame: Frame,
16debug_info: DebugInfo,16debug_info: DebugInfo,
17debug_line: DebugLine,17debug_line: DebugLine,
1818
19pub const UpdateError = link.Error || error{MappedFileIo};
20
21pub const AddressSize = enum(u8) { @"32" = 4, @"64" = 8, _ };19pub const AddressSize = enum(u8) { @"32" = 4, @"64" = 8, _ };
2220
23pub const Unit = struct {21pub const Unit = struct {
...@@ -158,7 +156,7 @@ pub const Loc = union(enum) {...@@ -158,7 +156,7 @@ pub const Loc = union(enum) {
158 }156 }
159 }157 }
160158
161 fn write(loc: Loc, adapter: anytype) (UpdateError || Writer.Error)!void {159 fn write(loc: Loc, adapter: anytype) link.EmitError!void {
162 const writer = adapter.writer();160 const writer = adapter.writer();
163 switch (loc) {161 switch (loc) {
164 .empty => {},162 .empty => {},
...@@ -324,7 +322,7 @@ pub const Cfa = union(enum) {...@@ -324,7 +322,7 @@ pub const Cfa = union(enum) {
324 const RegOff = struct { reg: u32, off: i64 };322 const RegOff = struct { reg: u32, off: i64 };
325 const RegExpr = struct { reg: u32, expr: Loc };323 const RegExpr = struct { reg: u32, expr: Loc };
326324
327 fn write(cfa: Cfa, wip_nav: *WipNav) (UpdateError || Writer.Error)!void {325 fn write(cfa: Cfa, wip_nav: *WipNav) link.EmitError!void {
328 const dfw = &wip_nav.fde_writer.interface;326 const dfw = &wip_nav.fde_writer.interface;
329 switch (cfa) {327 switch (cfa) {
330 .nop => try dfw.writeByte(DW.CFA.nop),328 .nop => try dfw.writeByte(DW.CFA.nop),
...@@ -487,11 +485,11 @@ pub const WipNav = struct {...@@ -487,11 +485,11 @@ pub const WipNav = struct {
487 debug.* = undefined;485 debug.* = undefined;
488 }486 }
489487
490 pub fn genFuncHeaders(debug: *Debug) UpdateError!void {488 pub fn genFuncHeaders(debug: *Debug) link.Error!void {
491 try debug.wip_nav.genFuncHeaders();489 try debug.wip_nav.genFuncHeaders();
492 }490 }
493491
494 pub fn genDebugFrame(debug: *Debug, loc: u32, cfa: Cfa) UpdateError!void {492 pub fn genDebugFrame(debug: *Debug, loc: u32, cfa: Cfa) link.Error!void {
495 return debug.wip_nav.genDebugFrame(loc, cfa);493 return debug.wip_nav.genDebugFrame(loc, cfa);
496 }494 }
497495
...@@ -502,10 +500,10 @@ pub const WipNav = struct {...@@ -502,10 +500,10 @@ pub const WipNav = struct {
502 opt_name: ?[]const u8,500 opt_name: ?[]const u8,
503 ty: Type,501 ty: Type,
504 loc: Loc,502 loc: Loc,
505 ) UpdateError!void {503 ) link.Error!void {
506 if (true) return;504 if (true) return;
507 return debug.genLocalVarDebugInfoInner(tag, opt_name, ty, loc) catch |err| switch (err) {505 return debug.genLocalVarDebugInfoInner(tag, opt_name, ty, loc) catch |err| switch (err) {
508 error.WriteFailed => debug.info_writer.err.?,506 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),
509 else => |e| e,507 else => |e| e,
510 };508 };
511 }509 }
...@@ -515,7 +513,7 @@ pub const WipNav = struct {...@@ -515,7 +513,7 @@ pub const WipNav = struct {
515 opt_name: ?[]const u8,513 opt_name: ?[]const u8,
516 ty: Type,514 ty: Type,
517 loc: Loc,515 loc: Loc,
518 ) (UpdateError || Writer.Error)!void {516 ) link.EmitError!void {
519 assert(debug.wip_nav.func != null);517 assert(debug.wip_nav.func != null);
520 try debug.abbrevCode(switch (tag) {518 try debug.abbrevCode(switch (tag) {
521 .arg => if (opt_name) |_| .arg else .unnamed_arg,519 .arg => if (opt_name) |_| .arg else .unnamed_arg,
...@@ -533,10 +531,10 @@ pub const WipNav = struct {...@@ -533,10 +531,10 @@ pub const WipNav = struct {
533 tag: LocalConstTag,531 tag: LocalConstTag,
534 opt_name: ?[]const u8,532 opt_name: ?[]const u8,
535 val: Value,533 val: Value,
536 ) UpdateError!void {534 ) link.Error!void {
537 if (true) return;535 if (true) return;
538 return debug.genLocalConstDebugInfoInner(tag, opt_name, val) catch |err| switch (err) {536 return debug.genLocalConstDebugInfoInner(tag, opt_name, val) catch |err| switch (err) {
539 error.WriteFailed => debug.info_writer.err.?,537 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),
540 else => |e| e,538 else => |e| e,
541 };539 };
542 }540 }
...@@ -545,7 +543,7 @@ pub const WipNav = struct {...@@ -545,7 +543,7 @@ pub const WipNav = struct {
545 tag: LocalConstTag,543 tag: LocalConstTag,
546 opt_name: ?[]const u8,544 opt_name: ?[]const u8,
547 val: Value,545 val: Value,
548 ) (UpdateError || Writer.Error)!void {546 ) link.EmitError!void {
549 assert(debug.wip_nav.func != null);547 assert(debug.wip_nav.func != null);
550 const zcu = debug.pt.zcu;548 const zcu = debug.pt.zcu;
551 const ty = val.typeOf(zcu);549 const ty = val.typeOf(zcu);
...@@ -571,23 +569,23 @@ pub const WipNav = struct {...@@ -571,23 +569,23 @@ pub const WipNav = struct {
571 debug.any_children = true;569 debug.any_children = true;
572 }570 }
573571
574 pub fn genVarArgsDebugInfo(debug: *Debug) UpdateError!void {572 pub fn genVarArgsDebugInfo(debug: *Debug) link.Error!void {
575 if (true) return;573 if (true) return;
576 return debug.genVarArgsDebugInfoInner() catch |err| switch (err) {574 return debug.genVarArgsDebugInfoInner() catch |err| switch (err) {
577 error.WriteFailed => debug.info_writer.err.?,575 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),
578 else => |e| e,576 else => |e| e,
579 };577 };
580 }578 }
581 fn genVarArgsDebugInfoInner(debug: *Debug) (UpdateError || Writer.Error)!void {579 fn genVarArgsDebugInfoInner(debug: *Debug) link.EmitError!void {
582 assert(debug.wip_nav.func != null);580 assert(debug.wip_nav.func != null);
583 try debug.abbrevCode(.is_var_args);581 try debug.abbrevCode(.is_var_args);
584 debug.any_children = true;582 debug.any_children = true;
585 }583 }
586584
587 pub fn advancePcAndLine(debug: *Debug, delta_line: i33, delta_pc: u64) UpdateError!void {585 pub fn advancePcAndLine(debug: *Debug, delta_line: i33, delta_pc: u64) link.Error!void {
588 if (true) return;586 if (true) return;
589 return debug.advancePcAndLineInner(delta_line, delta_pc) catch |err| switch (err) {587 return debug.advancePcAndLineInner(delta_line, delta_pc) catch |err| switch (err) {
590 error.WriteFailed => debug.line_writer.err.?,588 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),
591 };589 };
592 }590 }
593 fn advancePcAndLineInner(debug: *Debug, delta_line: i33, delta_pc: u64) Writer.Error!void {591 fn advancePcAndLineInner(debug: *Debug, delta_line: i33, delta_pc: u64) Writer.Error!void {
...@@ -625,10 +623,10 @@ pub const WipNav = struct {...@@ -625,10 +623,10 @@ pub const WipNav = struct {
625 (header.line_range * remaining_op_advance) + header.opcode_base));623 (header.line_range * remaining_op_advance) + header.opcode_base));
626 }624 }
627625
628 pub fn setColumn(debug: *Debug, column: u32) UpdateError!void {626 pub fn setColumn(debug: *Debug, column: u32) link.Error!void {
629 if (true) return;627 if (true) return;
630 return debug.setColumnInner(column) catch |err| switch (err) {628 return debug.setColumnInner(column) catch |err| switch (err) {
631 error.WriteFailed => debug.line_writer.err.?,629 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),
632 };630 };
633 }631 }
634 fn setColumnInner(debug: *Debug, column: u32) Writer.Error!void {632 fn setColumnInner(debug: *Debug, column: u32) Writer.Error!void {
...@@ -637,44 +635,44 @@ pub const WipNav = struct {...@@ -637,44 +635,44 @@ pub const WipNav = struct {
637 try dlw.writeUleb128(column + 1);635 try dlw.writeUleb128(column + 1);
638 }636 }
639637
640 pub fn negateStmt(debug: *Debug) UpdateError!void {638 pub fn negateStmt(debug: *Debug) link.Error!void {
641 if (true) return;639 if (true) return;
642 return debug.negateStmtInner() catch |err| switch (err) {640 return debug.negateStmtInner() catch |err| switch (err) {
643 error.WriteFailed => debug.line_writer.err.?,641 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),
644 };642 };
645 }643 }
646 fn negateStmtInner(debug: *Debug) Writer.Error!void {644 fn negateStmtInner(debug: *Debug) Writer.Error!void {
647 try debug.line_writer.interface.writeByte(DW.LNS.negate_stmt);645 try debug.line_writer.interface.writeByte(DW.LNS.negate_stmt);
648 }646 }
649647
650 pub fn setPrologueEnd(debug: *Debug) UpdateError!void {648 pub fn setPrologueEnd(debug: *Debug) link.Error!void {
651 if (true) return;649 if (true) return;
652 return debug.setPrologueEndInner() catch |err| switch (err) {650 return debug.setPrologueEndInner() catch |err| switch (err) {
653 error.WriteFailed => debug.line_writer.err.?,651 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),
654 };652 };
655 }653 }
656 fn setPrologueEndInner(debug: *Debug) Writer.Error!void {654 fn setPrologueEndInner(debug: *Debug) Writer.Error!void {
657 try debug.line_writer.interface.writeByte(DW.LNS.set_prologue_end);655 try debug.line_writer.interface.writeByte(DW.LNS.set_prologue_end);
658 }656 }
659657
660 pub fn setEpilogueBegin(debug: *Debug) UpdateError!void {658 pub fn setEpilogueBegin(debug: *Debug) link.Error!void {
661 if (true) return;659 if (true) return;
662 return debug.setEpilogueBeginInner() catch |err| switch (err) {660 return debug.setEpilogueBeginInner() catch |err| switch (err) {
663 error.WriteFailed => debug.line_writer.err.?,661 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),
664 };662 };
665 }663 }
666 fn setEpilogueBeginInner(debug: *Debug) Writer.Error!void {664 fn setEpilogueBeginInner(debug: *Debug) Writer.Error!void {
667 try debug.line_writer.interface.writeByte(DW.LNS.set_epilogue_begin);665 try debug.line_writer.interface.writeByte(DW.LNS.set_epilogue_begin);
668 }666 }
669667
670 pub fn enterBlock(debug: *Debug, code_off: u64) UpdateError!void {668 pub fn enterBlock(debug: *Debug, code_off: u64) link.Error!void {
671 if (true) return;669 if (true) return;
672 return debug.enterBlockInner(code_off) catch |err| switch (err) {670 return debug.enterBlockInner(code_off) catch |err| switch (err) {
673 error.WriteFailed => debug.info_writer.err.?,671 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),
674 else => |e| e,672 else => |e| e,
675 };673 };
676 }674 }
677 fn enterBlockInner(debug: *Debug, code_off: u64) (UpdateError || Writer.Error)!void {675 fn enterBlockInner(debug: *Debug, code_off: u64) link.EmitError!void {
678 const dwarf = debug.wip_nav.dwarf;676 const dwarf = debug.wip_nav.dwarf;
679 const diw = &debug.info_writer.interface;677 const diw = &debug.info_writer.interface;
680 const block = try debug.blocks.addOne(dwarf.linkFile().comp.gpa);678 const block = try debug.blocks.addOne(dwarf.linkFile().comp.gpa);
...@@ -688,14 +686,14 @@ pub const WipNav = struct {...@@ -688,14 +686,14 @@ pub const WipNav = struct {
688 debug.any_children = false;686 debug.any_children = false;
689 }687 }
690688
691 pub fn leaveBlock(debug: *Debug, code_off: u64) UpdateError!void {689 pub fn leaveBlock(debug: *Debug, code_off: u64) link.Error!void {
692 if (true) return;690 if (true) return;
693 return debug.leaveBlockInner(code_off) catch |err| switch (err) {691 return debug.leaveBlockInner(code_off) catch |err| switch (err) {
694 error.WriteFailed => debug.info_writer.err.?,692 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),
695 else => |e| e,693 else => |e| e,
696 };694 };
697 }695 }
698 fn leaveBlockInner(debug: *Debug, code_off: u64) (UpdateError || Writer.Error)!void {696 fn leaveBlockInner(debug: *Debug, code_off: u64) link.EmitError!void {
699 const dwarf = debug.wip_nav.dwarf;697 const dwarf = debug.wip_nav.dwarf;
700 const block_bytes = comptime uleb128Bytes(@backingInt(AbbrevCode.block));698 const block_bytes = comptime uleb128Bytes(@backingInt(AbbrevCode.block));
701 const block = debug.blocks.pop().?;699 const block = debug.blocks.pop().?;
...@@ -722,10 +720,10 @@ pub const WipNav = struct {...@@ -722,10 +720,10 @@ pub const WipNav = struct {
722 code_off: u64,720 code_off: u64,
723 line: u32,721 line: u32,
724 column: u32,722 column: u32,
725 ) UpdateError!void {723 ) link.Error!void {
726 if (true) return;724 if (true) return;
727 return debug.enterInlineFuncInner(func, code_off, line, column) catch |err| switch (err) {725 return debug.enterInlineFuncInner(func, code_off, line, column) catch |err| switch (err) {
728 error.WriteFailed => debug.info_writer.err.?,726 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),
729 else => |e| e,727 else => |e| e,
730 };728 };
731 }729 }
...@@ -735,7 +733,7 @@ pub const WipNav = struct {...@@ -735,7 +733,7 @@ pub const WipNav = struct {
735 code_off: u64,733 code_off: u64,
736 line: u32,734 line: u32,
737 column: u32,735 column: u32,
738 ) (UpdateError || Writer.Error)!void {736 ) link.EmitError!void {
739 const dwarf = debug.wip_nav.dwarf;737 const dwarf = debug.wip_nav.dwarf;
740 const zcu = debug.pt.zcu;738 const zcu = debug.pt.zcu;
741 const diw = &debug.info_writer.interface;739 const diw = &debug.info_writer.interface;
...@@ -754,10 +752,10 @@ pub const WipNav = struct {...@@ -754,10 +752,10 @@ pub const WipNav = struct {
754 debug.any_children = false;752 debug.any_children = false;
755 }753 }
756754
757 pub fn leaveInlineFunc(debug: *Debug, func: InternPool.Index, code_off: u64) UpdateError!void {755 pub fn leaveInlineFunc(debug: *Debug, func: InternPool.Index, code_off: u64) link.Error!void {
758 if (true) return;756 if (true) return;
759 return debug.leaveInlineFuncInner(func, code_off) catch |err| switch (err) {757 return debug.leaveInlineFuncInner(func, code_off) catch |err| switch (err) {
760 error.WriteFailed => debug.info_writer.err.?,758 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.info_writer),
761 else => |e| e,759 else => |e| e,
762 };760 };
763 }761 }
...@@ -765,7 +763,7 @@ pub const WipNav = struct {...@@ -765,7 +763,7 @@ pub const WipNav = struct {
765 debug: *Debug,763 debug: *Debug,
766 func: InternPool.Index,764 func: InternPool.Index,
767 code_off: u64,765 code_off: u64,
768 ) (UpdateError || Writer.Error)!void {766 ) link.EmitError!void {
769 const dwarf = debug.wip_nav.dwarf;767 const dwarf = debug.wip_nav.dwarf;
770 const inlined_func_bytes = comptime uleb128Bytes(@backingInt(AbbrevCode.inlined_func));768 const inlined_func_bytes = comptime uleb128Bytes(@backingInt(AbbrevCode.inlined_func));
771 const block = debug.blocks.pop().?;769 const block = debug.blocks.pop().?;
...@@ -787,13 +785,13 @@ pub const WipNav = struct {...@@ -787,13 +785,13 @@ pub const WipNav = struct {
787 debug.any_children = true;785 debug.any_children = true;
788 }786 }
789787
790 pub fn setInlineFunc(debug: *Debug, func: InternPool.Index) UpdateError!void {788 pub fn setInlineFunc(debug: *Debug, func: InternPool.Index) link.Error!void {
791 return debug.setInlineFuncInner(func) catch |err| switch (err) {789 return debug.setInlineFuncInner(func) catch |err| switch (err) {
792 error.WriteFailed => debug.line_writer.err.?,790 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),
793 else => |e| e,791 else => |e| e,
794 };792 };
795 }793 }
796 fn setInlineFuncInner(debug: *Debug, func: InternPool.Index) (UpdateError || Writer.Error)!void {794 fn setInlineFuncInner(debug: *Debug, func: InternPool.Index) link.EmitError!void {
797 const wip_nav = &debug.wip_nav;795 const wip_nav = &debug.wip_nav;
798 const zcu = debug.pt.zcu;796 const zcu = debug.pt.zcu;
799 const dwarf = wip_nav.dwarf;797 const dwarf = wip_nav.dwarf;
...@@ -855,7 +853,7 @@ pub const WipNav = struct {...@@ -855,7 +853,7 @@ pub const WipNav = struct {
855 wip_nav.func = func;853 wip_nav.func = func;
856 }854 }
857855
858 fn abbrevCode(debug: *Debug, abbrev_code: AbbrevCode) (UpdateError || Writer.Error)!void {856 fn abbrevCode(debug: *Debug, abbrev_code: AbbrevCode) link.EmitError!void {
859 try debug.info_writer.interface.writeUleb128(try debug.wip_nav.dwarf.refAbbrevCode(abbrev_code));857 try debug.info_writer.interface.writeUleb128(try debug.wip_nav.dwarf.refAbbrevCode(abbrev_code));
860 }858 }
861859
...@@ -872,7 +870,7 @@ pub const WipNav = struct {...@@ -872,7 +870,7 @@ pub const WipNav = struct {
872 debug: *Debug,870 debug: *Debug,
873 target: MappedFile.Node.Index,871 target: MappedFile.Node.Index,
874 addend: i64,872 addend: i64,
875 ) (UpdateError || Writer.Error)!void {873 ) link.EmitError!void {
876 const dwarf = debug.wip_nav.dwarf;874 const dwarf = debug.wip_nav.dwarf;
877 const diw = &debug.info_writer.interface;875 const diw = &debug.info_writer.interface;
878 const offset = diw.end;876 const offset = diw.end;
...@@ -892,7 +890,7 @@ pub const WipNav = struct {...@@ -892,7 +890,7 @@ pub const WipNav = struct {
892 );890 );
893 }891 }
894892
895 fn strp(debug: *Debug, str: []const u8) (UpdateError || Writer.Error)!void {893 fn strp(debug: *Debug, str: []const u8) link.EmitError!void {
896 if (true) @panic("TODO");894 if (true) @panic("TODO");
897 const dwarf = debug.wip_nav.dwarf;895 const dwarf = debug.wip_nav.dwarf;
898 try debug.infoSectionOffset(.debug_str, try dwarf.debug_str.addString(dwarf, str), 0);896 try debug.infoSectionOffset(.debug_str, try dwarf.debug_str.addString(dwarf, str), 0);
...@@ -902,14 +900,14 @@ pub const WipNav = struct {...@@ -902,14 +900,14 @@ pub const WipNav = struct {
902 debug: *Debug,900 debug: *Debug,
903 comptime fmt: []const u8,901 comptime fmt: []const u8,
904 args: anytype,902 args: anytype,
905 ) (UpdateError || Writer.Error)!void {903 ) link.EmitError!void {
906 const gpa = &debug.wip_nav.dwarf.gpa;904 const gpa = &debug.wip_nav.dwarf.gpa;
907 const str = try std.fmt.allocPrint(gpa, fmt, args);905 const str = try std.fmt.allocPrint(gpa, fmt, args);
908 defer gpa.free(str);906 defer gpa.free(str);
909 return debug.strp(str);907 return debug.strp(str);
910 }908 }
911909
912 fn infoExprLoc(debug: *Debug, loc: Loc) (UpdateError || Writer.Error)!void {910 fn infoExprLoc(debug: *Debug, loc: Loc) link.EmitError!void {
913 var buf: [64]u8 = undefined;911 var buf: [64]u8 = undefined;
914 var counter: ExprLocCounter = .init(debug.wip_nav.dwarf, &buf);912 var counter: ExprLocCounter = .init(debug.wip_nav.dwarf, &buf);
915 try loc.write(&counter);913 try loc.write(&counter);
...@@ -922,13 +920,13 @@ pub const WipNav = struct {...@@ -922,13 +920,13 @@ pub const WipNav = struct {
922 fn endian(ctx: @This()) std.lang.Endian {920 fn endian(ctx: @This()) std.lang.Endian {
923 return ctx.debug.wip_nav.dwarf.endian;921 return ctx.debug.wip_nav.dwarf.endian;
924 }922 }
925 fn addrSym(ctx: @This(), si: link.File.SymbolId) (UpdateError || Writer.Error)!void {923 fn addrSym(ctx: @This(), si: link.File.SymbolId) link.EmitError!void {
926 try ctx.debug.infoAddrSym(si, 0);924 try ctx.debug.infoAddrSym(si, 0);
927 }925 }
928 fn infoEntry(926 fn infoEntry(
929 ctx: @This(),927 ctx: @This(),
930 node: MappedFile.Node.Index,928 node: MappedFile.Node.Index,
931 ) (UpdateError || Writer.Error)!void {929 ) link.EmitError!void {
932 try ctx.debug.infoSectionOffset(node, 0);930 try ctx.debug.infoSectionOffset(node, 0);
933 }931 }
934 } = .{ .debug = debug };932 } = .{ .debug = debug };
...@@ -940,7 +938,7 @@ pub const WipNav = struct {...@@ -940,7 +938,7 @@ pub const WipNav = struct {
940 debug: *Debug,938 debug: *Debug,
941 si: link.File.SymbolId,939 si: link.File.SymbolId,
942 sym_off: u64,940 sym_off: u64,
943 ) (UpdateError || Writer.Error)!void {941 ) link.EmitError!void {
944 const diw = &debug.info_writer.interface;942 const diw = &debug.info_writer.interface;
945 try debug.infoExternalReloc(.{943 try debug.infoExternalReloc(.{
946 .source_off = @intCast(diw.end),944 .source_off = @intCast(diw.end),
...@@ -950,20 +948,20 @@ pub const WipNav = struct {...@@ -950,20 +948,20 @@ pub const WipNav = struct {
950 try diw.splatByteAll(0, @backingInt(debug.wip_nav.dwarf.address_size));948 try diw.splatByteAll(0, @backingInt(debug.wip_nav.dwarf.address_size));
951 }949 }
952950
953 fn refNav(debug: *Debug, nav_index: InternPool.Nav.Index) (UpdateError || Writer.Error)!void {951 fn refNav(debug: *Debug, nav_index: InternPool.Nav.Index) link.EmitError!void {
954 try debug.infoSectionOffset(try debug.wip_nav.dwarf.getNavNode(nav_index), 0);952 try debug.infoSectionOffset(try debug.wip_nav.dwarf.getNavNode(nav_index), 0);
955 }953 }
956954
957 fn refType(debug: *Debug, ty: Type) (UpdateError || Writer.Error)!void {955 fn refType(debug: *Debug, ty: Type) link.EmitError!void {
958 return debug.refValue(ty.toValue());956 return debug.refValue(ty.toValue());
959 }957 }
960958
961 fn refValue(debug: *Debug, value: Value) (UpdateError || Writer.Error)!void {959 fn refValue(debug: *Debug, value: Value) link.EmitError!void {
962 if (true) @panic("TODO");960 if (true) @panic("TODO");
963 try debug.infoSectionOffset(.debug_info, try debug.getValueNode(value), 0);961 try debug.infoSectionOffset(.debug_info, try debug.getValueNode(value), 0);
964 }962 }
965963
966 fn getValueNode(debug: *Debug, value: Value) UpdateError!MappedFile.Node.Index {964 fn getValueNode(debug: *Debug, value: Value) link.Error!MappedFile.Node.Index {
967 if (value.typeOf(debug.zcu).toIntern() != .type_type) {965 if (value.typeOf(debug.zcu).toIntern() != .type_type) {
968 assert(value.typeOf(debug.zcu).comptimeOnly(debug.zcu));966 assert(value.typeOf(debug.zcu).comptimeOnly(debug.zcu));
969 }967 }
...@@ -972,7 +970,7 @@ pub const WipNav = struct {...@@ -972,7 +970,7 @@ pub const WipNav = struct {
972 return dwarf.values.items[@backingInt(index)];970 return dwarf.values.items[@backingInt(index)];
973 }971 }
974972
975 fn blockValue(debug: *Debug, val: Value) (UpdateError || Writer.Error)!void {973 fn blockValue(debug: *Debug, val: Value) link.EmitError!void {
976 const ty = val.typeOf(debug.pt.zcu);974 const ty = val.typeOf(debug.pt.zcu);
977 const diw = &debug.info_writer.interface;975 const diw = &debug.info_writer.interface;
978 const size = ty.abiSize(debug.pt.zcu);976 const size = ty.abiSize(debug.pt.zcu);
...@@ -1004,13 +1002,13 @@ pub const WipNav = struct {...@@ -1004,13 +1002,13 @@ pub const WipNav = struct {
1004 wip_nav.* = undefined;1002 wip_nav.* = undefined;
1005 }1003 }
10061004
1007 pub fn genFuncHeaders(wip_nav: *WipNav) UpdateError!void {1005 pub fn genFuncHeaders(wip_nav: *WipNav) link.Error!void {
1008 wip_nav.genDebugFrameHeader() catch |err| switch (err) {1006 wip_nav.genDebugFrameHeader() catch |err| switch (err) {
1009 error.WriteFailed => return wip_nav.fde_writer.err.?,1007 error.WriteFailed => return wip_nav.reportWriteError(&wip_nav.fde_writer),
1010 else => |e| return e,1008 else => |e| return e,
1011 };1009 };
1012 }1010 }
1013 fn genDebugFrameHeader(wip_nav: *WipNav) (UpdateError || Writer.Error)!void {1011 fn genDebugFrameHeader(wip_nav: *WipNav) link.EmitError!void {
1014 assert(wip_nav.func != null);1012 assert(wip_nav.func != null);
1015 const dwarf = wip_nav.dwarf;1013 const dwarf = wip_nav.dwarf;
1016 const dfw = &wip_nav.fde_writer.interface;1014 const dfw = &wip_nav.fde_writer.interface;
...@@ -1050,13 +1048,13 @@ pub const WipNav = struct {...@@ -1050,13 +1048,13 @@ pub const WipNav = struct {
1050 }1048 }
1051 }1049 }
10521050
1053 pub fn genDebugFrame(wip_nav: *WipNav, loc: u32, cfa: Cfa) UpdateError!void {1051 pub fn genDebugFrame(wip_nav: *WipNav, loc: u32, cfa: Cfa) link.Error!void {
1054 return wip_nav.genDebugFrameInner(loc, cfa) catch |err| switch (err) {1052 return wip_nav.genDebugFrameInner(loc, cfa) catch |err| switch (err) {
1055 error.WriteFailed => wip_nav.fde_writer.err.?,1053 error.WriteFailed => return wip_nav.reportWriteError(&wip_nav.fde_writer),
1056 else => |e| e,1054 else => |e| return e,
1057 };1055 };
1058 }1056 }
1059 fn genDebugFrameInner(wip_nav: *WipNav, loc: u32, cfa: Cfa) (UpdateError || Writer.Error)!void {1057 fn genDebugFrameInner(wip_nav: *WipNav, loc: u32, cfa: Cfa) link.EmitError!void {
1060 assert(wip_nav.func != null);1058 assert(wip_nav.func != null);
1061 const loc_cfa: Cfa = .{ .advance_loc = loc };1059 const loc_cfa: Cfa = .{ .advance_loc = loc };
1062 try loc_cfa.write(wip_nav);1060 try loc_cfa.write(wip_nav);
...@@ -1123,7 +1121,7 @@ pub const WipNav = struct {...@@ -1123,7 +1121,7 @@ pub const WipNav = struct {
1123 wip_nav: *WipNav,1121 wip_nav: *WipNav,
1124 target: MappedFile.Node.Index,1122 target: MappedFile.Node.Index,
1125 addend: i64,1123 addend: i64,
1126 ) (UpdateError || Writer.Error)!void {1124 ) link.EmitError!void {
1127 const dwarf = wip_nav.dwarf;1125 const dwarf = wip_nav.dwarf;
1128 const dfw = &wip_nav.fde_writer.interface;1126 const dfw = &wip_nav.fde_writer.interface;
1129 const offset = dfw.end;1127 const offset = dfw.end;
...@@ -1143,7 +1141,7 @@ pub const WipNav = struct {...@@ -1143,7 +1141,7 @@ pub const WipNav = struct {
1143 );1141 );
1144 }1142 }
11451143
1146 fn frameExprLoc(wip_nav: *WipNav, loc: Loc) (UpdateError || Writer.Error)!void {1144 fn frameExprLoc(wip_nav: *WipNav, loc: Loc) link.EmitError!void {
1147 var buf: [64]u8 = undefined;1145 var buf: [64]u8 = undefined;
1148 var counter: ExprLocCounter = .init(wip_nav.dwarf, &buf);1146 var counter: ExprLocCounter = .init(wip_nav.dwarf, &buf);
1149 try loc.write(&counter);1147 try loc.write(&counter);
...@@ -1156,10 +1154,10 @@ pub const WipNav = struct {...@@ -1156,10 +1154,10 @@ pub const WipNav = struct {
1156 fn endian(ctx: @This()) std.lang.Endian {1154 fn endian(ctx: @This()) std.lang.Endian {
1157 return ctx.wip_nav.dwarf.endian;1155 return ctx.wip_nav.dwarf.endian;
1158 }1156 }
1159 fn addrSym(ctx: @This(), si: link.File.SymbolId) (UpdateError || Writer.Error)!void {1157 fn addrSym(ctx: @This(), si: link.File.SymbolId) link.EmitError!void {
1160 try ctx.wip_nav.frameAddrSym(si, 0);1158 try ctx.wip_nav.frameAddrSym(si, 0);
1161 }1159 }
1162 fn infoEntry(ctx: @This(), node: MappedFile.Node.Index) (UpdateError || Writer.Error)!void {1160 fn infoEntry(ctx: @This(), node: MappedFile.Node.Index) link.EmitError!void {
1163 try ctx.wip_nav.frameSectionOffset(node, 0);1161 try ctx.wip_nav.frameSectionOffset(node, 0);
1164 }1162 }
1165 } = .{ .wip_nav = wip_nav };1163 } = .{ .wip_nav = wip_nav };
...@@ -1171,7 +1169,7 @@ pub const WipNav = struct {...@@ -1171,7 +1169,7 @@ pub const WipNav = struct {
1171 wip_nav: *WipNav,1169 wip_nav: *WipNav,
1172 si: link.File.SymbolId,1170 si: link.File.SymbolId,
1173 sym_off: u64,1171 sym_off: u64,
1174 ) (UpdateError || Writer.Error)!void {1172 ) link.EmitError!void {
1175 const dwarf = wip_nav.dwarf;1173 const dwarf = wip_nav.dwarf;
1176 const dfw = &wip_nav.fde_writer.interface;1174 const dfw = &wip_nav.fde_writer.interface;
1177 const offset = dfw.end;1175 const offset = dfw.end;
...@@ -1188,6 +1186,16 @@ pub const WipNav = struct {...@@ -1188,6 +1186,16 @@ pub const WipNav = struct {
1188 },1186 },
1189 );1187 );
1190 }1188 }
1189
1190 fn reportWriteError(wip_nav: *WipNav, mfnw: *const MappedFile.Node.Writer) link.Error {
1191 switch (mfnw.err.?) {
1192 else => |e| return e,
1193 error.MappedFileIo => return wip_nav.dwarf.linkFile().comp.link_diags.fail(
1194 "failed to write output file: {t}",
1195 .{mfnw.mf.io_err.?},
1196 ),
1197 }
1198 }
1191};1199};
11921200
1193pub fn init(lf: *link.File, format: DW.Format) Dwarf {1201pub fn init(lf: *link.File, format: DW.Format) Dwarf {
...@@ -1283,7 +1291,7 @@ pub fn initUnits(dwarf: *Dwarf, zcu: *Zcu) Allocator.Error!void {...@@ -1283,7 +1291,7 @@ pub fn initUnits(dwarf: *Dwarf, zcu: *Zcu) Allocator.Error!void {
1283 };1291 };
1284}1292}
12851293
1286fn getNavNode(dwarf: *Dwarf, nav_index: InternPool.Nav.Index) UpdateError!MappedFile.Node.Index {1294fn getNavNode(dwarf: *Dwarf, nav_index: InternPool.Nav.Index) link.Error!MappedFile.Node.Index {
1287 if (true) @panic("TODO");1295 if (true) @panic("TODO");
1288 const zcu = dwarf.linkFile().comp.zcu.?;1296 const zcu = dwarf.linkFile().comp.zcu.?;
1289 const ip = &zcu.intern_pool;1297 const ip = &zcu.intern_pool;
...@@ -1329,7 +1337,7 @@ pub fn genEhFrameHdr(...@@ -1329,7 +1337,7 @@ pub fn genEhFrameHdr(
1329 eh_frame_hdr_ai: link.File.AtomId,1337 eh_frame_hdr_ai: link.File.AtomId,
1330 eh_frame_hdr: *EhFrameHdr,1338 eh_frame_hdr: *EhFrameHdr,
1331 eh_frame_si: link.File.SymbolId,1339 eh_frame_si: link.File.SymbolId,
1332) UpdateError!void {1340) link.Error!void {
1333 eh_frame_hdr.* = .{1341 eh_frame_hdr.* = .{
1334 .version = 1,1342 .version = 1,
1335 .eh_frame_ptr_enc = .{ .type = .sdata4, .rel = .pcrel },1343 .eh_frame_ptr_enc = .{ .type = .sdata4, .rel = .pcrel },
...@@ -1423,7 +1431,7 @@ pub fn updateEhFrameFde(dwarf: *Dwarf, fde: []u8, fde_offset: u64) void {...@@ -1423,7 +1431,7 @@ pub fn updateEhFrameFde(dwarf: *Dwarf, fde: []u8, fde_offset: u64) void {
1423fn refAbbrevCode(1431fn refAbbrevCode(
1424 dwarf: *Dwarf,1432 dwarf: *Dwarf,
1425 abbrev_code: AbbrevCode,1433 abbrev_code: AbbrevCode,
1426) (UpdateError || Writer.Error)!@typeInfo(AbbrevCode).@"enum".tag_type {1434) link.EmitError!@typeInfo(AbbrevCode).@"enum".tag_type {
1427 if (true) @panic("TODO");1435 if (true) @panic("TODO");
1428 const Entry = {};1436 const Entry = {};
1429 const DebugAbbrev = {};1437 const DebugAbbrev = {};
src/link/Elf/ZigObject.zig-1
...@@ -1549,7 +1549,6 @@ pub fn updateFunc(...@@ -1549,7 +1549,6 @@ pub fn updateFunc(
1549 if (debug_wip_nav) |*dn| .{ .dwarf = dn } else .none,1549 if (debug_wip_nav) |*dn| .{ .dwarf = dn } else .none,
1550 ) catch |err| switch (err) {1550 ) catch |err| switch (err) {
1551 error.WriteFailed => return error.OutOfMemory,1551 error.WriteFailed => return error.OutOfMemory,
1552 error.MappedFileIo => unreachable, // MappedFile is not being used
1553 else => |e| return e,1552 else => |e| return e,
1554 };1553 };
1555 const code = aw.written();1554 const code = aw.written();
src/link/Elf2.zig+13-9
...@@ -181,10 +181,10 @@ lazy: std.EnumArray(link.File.LazySymbol.Kind, struct {...@@ -181,10 +181,10 @@ lazy: std.EnumArray(link.File.LazySymbol.Kind, struct {
181}),181}),
182pending_uavs: std.ArrayList(Node.UavMapIndex),182pending_uavs: std.ArrayList(Node.UavMapIndex),
183symbol_relocs: std.ArrayList(SymbolReloc),183symbol_relocs: std.ArrayList(SymbolReloc),
184/// Set of relocations which must be re-applied if the size of the TLS segment changes.
185tls_size_symbol_relocs: std.array_hash_map.Auto(SymbolReloc.Index, void),
186node_relocs: std.ArrayList(NodeReloc),184node_relocs: std.ArrayList(NodeReloc),
187got_relocs: std.ArrayList(GotReloc),185got_relocs: std.ArrayList(GotReloc),
186/// Set of relocations which must be re-applied if the size of the TLS segment changes.
187tls_size_symbol_relocs: std.array_hash_map.Auto(SymbolReloc.Index, void),
188/// Index matches the index into `shdrs`. Like `shdrs`, this map excludes `SHN_UNDEF`.188/// Index matches the index into `shdrs`. Like `shdrs`, this map excludes `SHN_UNDEF`.
189section_by_name: std.array_hash_map.Auto(String(.shstrtab), void),189section_by_name: std.array_hash_map.Auto(String(.shstrtab), void),
190/// Key is the name of a global symbol which has been moved to a new symtab index. Any relocation190/// 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(...@@ -3708,15 +3708,15 @@ fn create(
3708 }),3708 }),
3709 .pending_uavs = .empty,3709 .pending_uavs = .empty,
3710 .symbol_relocs = .empty,3710 .symbol_relocs = .empty,
3711 .tls_size_symbol_relocs = .empty,
3712 .node_relocs = .empty,3711 .node_relocs = .empty,
3713 .got_relocs = .empty,3712 .got_relocs = .empty,
3713 .tls_size_symbol_relocs = .empty,
3714 .section_by_name = .empty,3714 .section_by_name = .empty,
3715 .changed_symtab_index = .empty,3715 .changed_symtab_index = .empty,
3716 .textrel_count = 0,3716 .textrel_count = 0,
37173717
3718 .dwarf = .init(&elf.base, switch (comp.config.debug_format) {3718 .dwarf = .init(&elf.base, switch (comp.config.debug_format) {
3719 .strip => .@"32",3719 .strip => .@"32", // for .eh_frame
3720 .dwarf => |v| v,3720 .dwarf => |v| v,
3721 .code_view => unreachable,3721 .code_view => unreachable,
3722 }),3722 }),
...@@ -3768,9 +3768,9 @@ pub fn deinit(elf: *Elf) void {...@@ -3768,9 +3768,9 @@ pub fn deinit(elf: *Elf) void {
3768 for (&elf.lazy.values) |*lazy| lazy.map.deinit(gpa);3768 for (&elf.lazy.values) |*lazy| lazy.map.deinit(gpa);
3769 elf.pending_uavs.deinit(gpa);3769 elf.pending_uavs.deinit(gpa);
3770 elf.symbol_relocs.deinit(gpa);3770 elf.symbol_relocs.deinit(gpa);
3771 elf.tls_size_symbol_relocs.deinit(gpa);
3772 elf.node_relocs.deinit(gpa);3771 elf.node_relocs.deinit(gpa);
3773 elf.got_relocs.deinit(gpa);3772 elf.got_relocs.deinit(gpa);
3773 elf.tls_size_symbol_relocs.deinit(gpa);
3774 elf.section_by_name.deinit(gpa);3774 elf.section_by_name.deinit(gpa);
3775 elf.changed_symtab_index.deinit(gpa);3775 elf.changed_symtab_index.deinit(gpa);
37763776
...@@ -8342,7 +8342,9 @@ fn updateFuncInner(...@@ -8342,7 +8342,9 @@ fn updateFuncInner(
8342 &nw.interface,8342 &nw.interface,
8343 debug_output,8343 debug_output,
8344 ) catch |err| switch (err) {8344 ) catch |err| switch (err) {
8345 error.WriteFailed => return nw.err.?,8345 error.WriteFailed => {
8346 if (nw.err) |e| return e;
8347 },
8346 else => |e| return e,8348 else => |e| return e,
8347 };8349 };
8348 const func_length = nw.interface.end;8350 const func_length = nw.interface.end;
...@@ -9899,17 +9901,19 @@ fn updateExportInner(...@@ -9899,17 +9901,19 @@ fn updateExportInner(
9899 };9901 };
9900}9902}
99019903
9902fn dumpStderr(elf: *Elf, tid: Zcu.PerThread.Id) !void {9904fn dumpStderr(elf: *Elf, tid: Zcu.PerThread.Id) Io.File.Writer.Error!void {
9903 const comp = elf.base.comp;9905 const comp = elf.base.comp;
9904 const io = comp.io;9906 const io = comp.io;
9905 var buffer: [512]u8 = undefined;9907 var buffer: [512]u8 = undefined;
9906 const stderr = try io.lockStderr(&buffer, null);9908 const stderr = try io.lockStderr(&buffer, null);
9907 defer io.unlockStderr();9909 defer io.unlockStderr();
9908 const w = &stderr.file_writer.interface;9910 const w = &stderr.file_writer.interface;
9909 _ = try elf.dump(w, tid);9911 _ = elf.dump(w, tid) catch |err| switch (err) {
9912 error.WriteFailed => return stderr.file_writer.err.?,
9913 };
9910}9914}
99119915
9912pub fn dump(elf: *Elf, w: *Io.Writer, tid: Zcu.PerThread.Id) !link.File.DumpResult {9916pub fn dump(elf: *Elf, w: *Io.Writer, tid: Zcu.PerThread.Id) Io.Writer.Error!link.File.DumpResult {
9913 if (elf.options.enable_link_snapshots) {9917 if (elf.options.enable_link_snapshots) {
9914 try elf.printNode(tid, w, .root, 0);9918 try elf.printNode(tid, w, .root, 0);
9915 return .enabled;9919 return .enabled;
src/link/MachO/ZigObject.zig-1
...@@ -790,7 +790,6 @@ pub fn updateFunc(...@@ -790,7 +790,6 @@ pub fn updateFunc(
790 if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,790 if (debug_wip_nav) |*wip_nav| .{ .dwarf = wip_nav } else .none,
791 ) catch |err| switch (err) {791 ) catch |err| switch (err) {
792 error.WriteFailed => return error.OutOfMemory,792 error.WriteFailed => return error.OutOfMemory,
793 error.MappedFileIo => unreachable, // MappedFile is not being used
794 else => |e| return e,793 else => |e| return e,
795 };794 };
796 const code = aw.written();795 const code = aw.written();