authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-05-31 06:13:47+01:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-06-01 10:26:01+01:00
log8fe1ec0cc9cfd0f3cf85b97889b4b9735e906926
tree0bd86634dd23d30464e0d75cd3e168945a169dda
parent748e7c5e39fcba3ed6b2b6e4cc4c01e1d442acbe
signaturelock-open Commit is signed but in an unrecognized format.

compiler: refactor backend error handling

All public codegen and linker APIs now use the following error set: Allocator.Error || Io.Cancelable || error{AlreadyReported} This is defined as `link.Error` and aliased as `codegen.Error`. The compiler "backend" (including both codegen and linker) has a fairly limited set of failure modes. Most of them are as follows: * Bad inline assembly (codegen) * Output file I/O error (link) * Symbol with no definition or multiple definitions (link) * Relocation error, e.g. overflow (link) * Unimplemented/unsupported feature (codegen/link) * `error.OutOfMemory` (codegen/link) * `error.Canceled` (codegen/link) The last two cases are special, because they are possible across most of the compiler codebase and have fixed code paths for handling---e.g. `error.OutOfMemory` almost always calls `Compilation.setAllocFailure`, and `error.Canceled` should typically propagate all the way up the call stack. However, all of the other cases should follow the same general pattern: the codegen/linker implementation should mark an error on `Compilation` somehow (either through `link_diags` or `failed_codegen`), and return `error.AlreadyReported`. This error code indicates that an operation failed, but that the caller does not need to take action to recover, because the failure has already been recorded in a way which will be expressed to the user. For instance, the codegen error set used to contain `error.Overflow`, but this case should have already been reported to the user, because implementation-agnostic code cannot know how best to express the failure to the user. The `error.AlreadyReported` error code encompasses what was previously represented by multiple errors, including `error.CodegenFail`, `error.LinkFailure`, and `error.AnalysisFail`. It is not necessary to differentiate these cases. (Not to be confused with the usage of `error.AnalysisFail` in the compiler *frontend*, i.e. `Sema`, which is unchanged by this diff.) Because the backend error set is now very small, it is easy to exhaustively `switch` on, and also many functions can be given concrete error sets. There are no longer different error sets for different operations. (As an exception, I have not tackled `link.File.open` in this diff, which has a big inferred error set where I think most errors are reported to the user with an `else => |e|` case.) I have also changed how `link.MappedFile`, our abstraction for handling the awkward "moving things around" aspect of incremental linking, does error handling. The public API of this abstraction now uses the following small error set: Allocator.Error || Io.Cancelable || error{MappedFileIo} The first two cases are self-explanatory. Then, `error.MappedFileIo` is a catch-all error code encompassing that an error was encountered when accessing the underlying `Io.File`. This error may have occurred when attempting to flush the file to disk, or to change its size, etc. In this case, the *specific* error---which was actually returned from the `Io.File` API---is available in the `MappedFile.io_err.?` field. Linker implementations which use `MappedFile` (currently `Elf2` and `Coff`) should eventually handle `error.MappedFileIo` by reporting an error in `Compilation.link_diags`, including that specific I/O error in the error message. The rationale here is essentially that error codes returned from functions exist for control flow purposes, and a linker implementation should not care about the distinction between file I/O error codes (e.g. `error.DiskQuota` vs `error.InputOutput`). The only reason it needs the concrete error is to expose it to the user. Therefore, by wrapping these failure modes under `error.MappedFileIo`, we keep the error set actually used by the linker implementation as small as possible, which encourages avoiding patterns like `else => |e| diags.fail(...)` (which is potentially dangerous since it may prevent `error.OutOfMemory` or `error.Canceled` from propagating correctly). It additionally helps linker implementations maintain more precise error messages---for instance, if `Elf2` encounters `error.NoSpaceLeft` writing to the output file, the error will now read "failed to write output file: NoSpaceLeft" instead of something more generic like "prelink failed: NoSpaceLeft". Finally, while working on these refactors, I was able to eliminate those pesky `src_loc: Zcu.LazySrcLoc` parameters from the codegen and link logic. These parameters did not make sense, because at this point in the compiler pipeline, we do not have precise source location information---so these parameters were always passed as just the location of the function declaration, or as some placeholder (`.unneeded` or the top of `lib/std/std.zig`) if there wasn't an appropriate function definition. The only logic which actually *uses* these source locations is codegen implementations' `fail` functions. Per my earlier list of failure modes, those functions are called in two main cases: * Bad inline assembly * Unimplemented/unsupported feature The first case should be moved to the compiler frontend (tracked by https://github.com/ziglang/zig/issues/10761), while the second case is essentially a compiler TODO so it is permissible for it to have imprecise error reporting. Therefore, codegen implementations' `fail` functions now just call `navSrcLoc` themselves when necessary, which (once we make improvements to inline assembly) will only happen when there is a deficiency in the codegen implementation. I was careful to make `Elf2` and `Coff` error reporting work well in this diff, by using no `else` case other than `else => |e| return e` when `switch`ing on errors and by always handling `error.MappedFileIo` by unwrapping `MappedFile.io_err.?`. I also added concrete error sets to almost every function in `Elf2`. (That was, um, actually why I started this diff, because it was annoying me that I wouldn't get as many compile errors at once...)

42 files changed, 973 insertions(+), 1126 deletions(-)

src/Compilation.zig+11-11
......@@ -3376,7 +3376,7 @@ fn flush(comp: *Compilation, arena: Allocator, tid: Zcu.PerThread.Id) (Io.Cancel
33763376 .fuzz = comp.config.any_fuzz,
33773377 .lto = comp.config.lto,
33783378 }) catch |err| switch (err) {
3379 error.LinkFailure => {}, // Already reported.
3379 error.AlreadyReported => {},
33803380 error.OutOfMemory => |e| return e,
33813381 };
33823382 }
......@@ -3390,7 +3390,7 @@ fn flush(comp: *Compilation, arena: Allocator, tid: Zcu.PerThread.Id) (Io.Cancel
33903390 };
33913391 // This is needed before reading the error flags.
33923392 lf.flush(arena, tid, comp.link_prog_node) catch |err| switch (err) {
3393 error.LinkFailure => {}, // Already reported.
3393 error.AlreadyReported => {},
33943394 error.OutOfMemory, error.Canceled => |e| return e,
33953395 };
33963396 }
......@@ -5249,7 +5249,7 @@ fn workerUpdateCObject(
52495249 progress_node: std.Progress.Node,
52505250) void {
52515251 comp.updateCObject(c_object, progress_node) catch |err| switch (err) {
5252 error.AnalysisFail => return,
5252 error.AlreadyReported => return,
52535253 else => {
52545254 comp.reportRetryableCObjectError(c_object, err) catch |oom| switch (oom) {
52555255 // Swallowing this error is OK because it's implied to be OOM when
......@@ -5266,7 +5266,7 @@ fn workerUpdateWin32Resource(
52665266 progress_node: std.Progress.Node,
52675267) void {
52685268 comp.updateWin32Resource(win32_resource, progress_node) catch |err| switch (err) {
5269 error.AnalysisFail => return,
5269 error.AlreadyReported => return,
52705270 else => {
52715271 comp.reportRetryableWin32ResourceError(win32_resource, err) catch |oom| switch (oom) {
52725272 // Swallowing this error is OK because it's implied to be OOM when
......@@ -5489,7 +5489,7 @@ fn reportRetryableCObjectError(comp: *Compilation, c_object: *CObject, err: anye
54895489 c_object.status = .failure_retryable;
54905490
54915491 switch (comp.failCObj(c_object, "{t}", .{err})) {
5492 error.AnalysisFail => return,
5492 error.AlreadyReported => return,
54935493 else => |e| return e,
54945494 }
54955495}
......@@ -6852,7 +6852,7 @@ fn failCObj(
68526852 c_object: *CObject,
68536853 comptime format: []const u8,
68546854 args: anytype,
6855) error{ OutOfMemory, AnalysisFail } {
6855) error{ OutOfMemory, AlreadyReported } {
68566856 @branchHint(.cold);
68576857 const diag_bundle = blk: {
68586858 const diag_bundle = try comp.gpa.create(CObject.Diag.Bundle);
......@@ -6876,7 +6876,7 @@ fn failCObjWithOwnedDiagBundle(
68766876 comp: *Compilation,
68776877 c_object: *CObject,
68786878 diag_bundle: *CObject.Diag.Bundle,
6879) error{ OutOfMemory, AnalysisFail } {
6879) error{ OutOfMemory, AlreadyReported } {
68806880 @branchHint(.cold);
68816881 assert(diag_bundle.diags.len > 0);
68826882 {
......@@ -6890,10 +6890,10 @@ fn failCObjWithOwnedDiagBundle(
68906890 comp.failed_c_objects.putAssumeCapacityNoClobber(c_object, diag_bundle);
68916891 }
68926892 c_object.status = .failure;
6893 return error.AnalysisFail;
6893 return error.AlreadyReported;
68946894}
68956895
6896fn failWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, comptime format: []const u8, args: anytype) error{ OutOfMemory, AnalysisFail } {
6896fn failWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } {
68976897 @branchHint(.cold);
68986898 var bundle: ErrorBundle.Wip = undefined;
68996899 try bundle.init(comp.gpa);
......@@ -6920,7 +6920,7 @@ fn failWin32ResourceWithOwnedBundle(
69206920 comp: *Compilation,
69216921 win32_resource: *Win32Resource,
69226922 err_bundle: ErrorBundle,
6923) error{ OutOfMemory, AnalysisFail } {
6923) error{ OutOfMemory, AlreadyReported } {
69246924 @branchHint(.cold);
69256925 {
69266926 const io = comp.io;
......@@ -6929,7 +6929,7 @@ fn failWin32ResourceWithOwnedBundle(
69296929 try comp.failed_win32_resources.putNoClobber(comp.gpa, win32_resource, err_bundle);
69306930 }
69316931 win32_resource.status = .failure;
6932 return error.AnalysisFail;
6932 return error.AlreadyReported;
69336933}
69346934
69356935pub const FileExt = enum {
src/Zcu.zig+8-17
......@@ -3912,12 +3912,12 @@ pub fn getTarget(zcu: *const Zcu) *const Target {
39123912pub fn handleUpdateExports(
39133913 zcu: *Zcu,
39143914 export_indices: []const Export.Index,
3915 result: link.File.UpdateExportsError!void,
3916) Allocator.Error!void {
3915 result: link.Error!void,
3916) (Allocator.Error || Io.Cancelable)!void {
39173917 const gpa = zcu.gpa;
39183918 result catch |err| switch (err) {
3919 error.OutOfMemory => |e| return e,
3920 error.AnalysisFail => {
3919 else => |e| return e,
3920 error.AlreadyReported => {
39213921 const export_idx = export_indices[0];
39223922 const new_export = export_idx.ptr(zcu);
39233923 new_export.status = .failed_retryable;
......@@ -4688,7 +4688,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum)
46884688
46894689pub const CodegenFailError = error{
46904690 /// Indicates the error message has been already stored at `Zcu.failed_codegen`.
4691 CodegenFail,
4691 AlreadyReported,
46924692 OutOfMemory,
46934693};
46944694
......@@ -4713,16 +4713,7 @@ pub fn codegenFailMsg(zcu: *Zcu, nav_index: InternPool.Nav.Index, msg: *ErrorMsg
47134713 errdefer msg.deinit(gpa);
47144714 try zcu.failed_codegen.putNoClobber(gpa, nav_index, msg);
47154715 }
4716 return error.CodegenFail;
4717}
4718
4719/// Asserts that `zcu.failed_codegen` contains the key `nav`, with the necessary lock held.
4720pub fn assertCodegenFailed(zcu: *Zcu, nav: InternPool.Nav.Index) void {
4721 const comp = zcu.comp;
4722 const io = comp.io;
4723 comp.mutex.lockUncancelable(io);
4724 defer comp.mutex.unlock(io);
4725 assert(zcu.failed_codegen.contains(nav));
4716 return error.AlreadyReported;
47264717}
47274718
47284719pub fn codegenFailType(
......@@ -4735,7 +4726,7 @@ pub fn codegenFailType(
47354726 try zcu.failed_types.ensureUnusedCapacity(gpa, 1);
47364727 const msg = try Zcu.ErrorMsg.create(gpa, zcu.typeSrcLoc(ty_index), format, args);
47374728 zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg);
4738 return error.CodegenFail;
4729 return error.AlreadyReported;
47394730}
47404731
47414732pub fn codegenFailTypeMsg(zcu: *Zcu, ty_index: InternPool.Index, msg: *ErrorMsg) CodegenFailError {
......@@ -4745,7 +4736,7 @@ pub fn codegenFailTypeMsg(zcu: *Zcu, ty_index: InternPool.Index, msg: *ErrorMsg)
47454736 try zcu.failed_types.ensureUnusedCapacity(gpa, 1);
47464737 }
47474738 zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg);
4748 return error.CodegenFail;
4739 return error.AlreadyReported;
47494740}
47504741
47514742/// Asserts that `zcu.multi_module_err != null`.
src/Zcu/PerThread.zig+5-12
......@@ -3700,7 +3700,7 @@ fn processExportsInner(
37003700 exported: Zcu.Exported,
37013701 export_indices: []const Zcu.Export.Index,
37023702 skip_linker_work: bool,
3703) error{OutOfMemory}!void {
3703) error{ OutOfMemory, Canceled }!void {
37043704 const zcu = pt.zcu;
37053705 const gpa = zcu.gpa;
37063706 const ip = &zcu.intern_pool;
......@@ -4533,7 +4533,7 @@ pub fn runCodegen(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) Ru
45334533 return codegen_result catch |err| {
45344534 switch (err) {
45354535 error.OutOfMemory => comp.setAllocFailure(),
4536 error.CodegenFail => zcu.assertCodegenFailed(zcu.funcInfo(func_index).owner_nav),
4536 error.AlreadyReported => {},
45374537 error.NoLinkFile => assert(comp.bin_file == null),
45384538 error.BackendDoesNotProduceMir => switch (target_util.zigBackend(
45394539 &zcu.root_mod.resolved_target.result,
......@@ -4552,7 +4552,7 @@ pub fn runCodegen(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) Ru
45524552fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) error{
45534553 OutOfMemory,
45544554 Canceled,
4555 CodegenFail,
4555 AlreadyReported,
45564556 NoLinkFile,
45574557 BackendDoesNotProduceMir,
45584558}!codegen.AnyMir {
......@@ -4628,19 +4628,12 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e
46284628 switch (err) {
46294629 error.OutOfMemory => comp.link_diags.setAllocFailure(),
46304630 }
4631 return error.CodegenFail;
4631 return error.AlreadyReported;
46324632 };
46334633 return error.BackendDoesNotProduceMir;
46344634 }
46354635
4636 return codegen.generateFunction(lf, pt, zcu.navSrcLoc(nav), func_index, air, &liveness) catch |err| switch (err) {
4637 error.OutOfMemory,
4638 error.CodegenFail,
4639 => |e| return e,
4640 error.Overflow,
4641 error.RelocationNotByteAligned,
4642 => return zcu.codegenFail(nav, "unable to codegen: {s}", .{@errorName(err)}),
4643 };
4636 return codegen.generateFunction(lf, pt, func_index, air, &liveness);
46444637}
46454638
46464639fn printVerboseAir(
src/codegen.zig+99-154
......@@ -24,10 +24,7 @@ const dev = @import("dev.zig");
2424
2525pub const aarch64 = @import("codegen/aarch64.zig");
2626
27pub const CodeGenError = GenerateSymbolError || error{
28 /// Indicates the error is already stored in Zcu `failed_codegen`.
29 CodegenFail,
30};
27pub const Error = link.Error;
3128
3229fn devFeatureForBackend(backend: std.lang.CompilerBackend) dev.Feature {
3330 return switch (backend) {
......@@ -141,11 +138,10 @@ pub const AnyMir = union {
141138pub fn generateFunction(
142139 lf: *link.File,
143140 pt: Zcu.PerThread,
144 src_loc: Zcu.LazySrcLoc,
145141 func_index: InternPool.Index,
146142 air: *const Air,
147143 liveness: *const ?Air.Liveness,
148) CodeGenError!AnyMir {
144) Error!AnyMir {
149145 const zcu = pt.zcu;
150146 const func = zcu.funcInfo(func_index);
151147 const target = &zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result;
......@@ -160,7 +156,7 @@ pub fn generateFunction(
160156 => |backend| {
161157 dev.check(devFeatureForBackend(backend));
162158 const CodeGen = importBackend(backend);
163 const mir = try CodeGen.generate(lf, pt, src_loc, func_index, air, liveness);
159 const mir = try CodeGen.generate(lf, pt, func_index, air, liveness);
164160 return @unionInit(AnyMir, AnyMir.tag(backend), mir);
165161 },
166162 }
......@@ -176,13 +172,12 @@ pub fn generateFunction(
176172pub fn emitFunction(
177173 lf: *link.File,
178174 pt: Zcu.PerThread,
179 src_loc: Zcu.LazySrcLoc,
180175 func_index: InternPool.Index,
181176 atom_id: link.File.AtomId,
182177 any_mir: *const AnyMir,
183178 w: *std.Io.Writer,
184179 debug_output: link.File.DebugInfoOutput,
185) (CodeGenError || std.Io.Writer.Error)!void {
180) (Error || std.Io.Writer.Error)!void {
186181 const zcu = pt.zcu;
187182 const func = zcu.funcInfo(func_index);
188183 const target = &zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result;
......@@ -201,7 +196,7 @@ pub fn emitFunction(
201196 => |backend| {
202197 dev.check(devFeatureForBackend(backend));
203198 const mir = &@field(any_mir, AnyMir.tag(backend));
204 return mir.emit(lf, pt, src_loc, func_index, atom_id, w, debug_output);
199 return mir.emit(lf, pt, func_index, atom_id, w, debug_output);
205200 },
206201 }
207202}
......@@ -209,12 +204,11 @@ pub fn emitFunction(
209204pub fn generateLazyFunction(
210205 lf: *link.File,
211206 pt: Zcu.PerThread,
212 src_loc: Zcu.LazySrcLoc,
213207 lazy_sym: link.File.LazySymbol,
214208 atom_id: link.File.AtomId,
215209 w: *std.Io.Writer,
216210 debug_output: link.File.DebugInfoOutput,
217) (CodeGenError || std.Io.Writer.Error)!void {
211) (Error || std.Io.Writer.Error)!void {
218212 const zcu = pt.zcu;
219213 const target = if (Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu)) |inst_index|
220214 &zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.?.resolved_target.result
......@@ -224,7 +218,7 @@ pub fn generateLazyFunction(
224218 else => unreachable,
225219 inline .stage2_riscv64, .stage2_x86_64 => |backend| {
226220 dev.check(devFeatureForBackend(backend));
227 return importBackend(backend).generateLazy(lf, pt, src_loc, lazy_sym, atom_id, w, debug_output);
221 return importBackend(backend).generateLazy(lf, pt, lazy_sym, atom_id, w, debug_output);
228222 },
229223 }
230224}
......@@ -232,14 +226,13 @@ pub fn generateLazyFunction(
232226pub fn generateLazySymbol(
233227 bin_file: *link.File,
234228 pt: Zcu.PerThread,
235 src_loc: Zcu.LazySrcLoc,
236229 lazy_sym: link.File.LazySymbol,
237230 // TODO don't use an "out" parameter like this; put it in the result instead
238231 alignment: *Alignment,
239232 w: *std.Io.Writer,
240233 debug_output: link.File.DebugInfoOutput,
241234 reloc_parent: link.File.RelocInfo.Parent,
242) (CodeGenError || std.Io.Writer.Error)!void {
235) (Error || std.Io.Writer.Error)!void {
243236 const tracy = trace(@src());
244237 defer tracy.end();
245238 tracy.addTextFmt("{t}, {f}", .{ lazy_sym.kind, Type.fromInterned(lazy_sym.ty).fmt(pt) });
......@@ -257,7 +250,7 @@ pub fn generateLazySymbol(
257250
258251 if (lazy_sym.kind == .code) {
259252 alignment.* = target_util.defaultFunctionAlignment(target);
260 return generateLazyFunction(bin_file, pt, src_loc, lazy_sym, reloc_parent.atom_index, w, debug_output);
253 return generateLazyFunction(bin_file, pt, lazy_sym, reloc_parent.atom_index, w, debug_output);
261254 }
262255
263256 if (lazy_sym.ty == .anyerror_type) {
......@@ -295,22 +288,13 @@ pub fn generateLazySymbol(
295288 }
296289}
297290
298pub const GenerateSymbolError = error{
299 OutOfMemory,
300 /// Compiler was asked to operate on a number larger than supported.
301 Overflow,
302 /// Compiler was asked to produce a non-byte-aligned relocation.
303 RelocationNotByteAligned,
304};
305
306291pub fn generateSymbol(
307292 bin_file: *link.File,
308293 pt: Zcu.PerThread,
309 src_loc: Zcu.LazySrcLoc,
310294 val: Value,
311295 w: *std.Io.Writer,
312296 reloc_parent: link.File.RelocInfo.Parent,
313) (GenerateSymbolError || std.Io.Writer.Error)!void {
297) (Error || std.Io.Writer.Error)!void {
314298 const tracy = trace(@src());
315299 defer tracy.end();
316300
......@@ -323,8 +307,11 @@ pub fn generateSymbol(
323307
324308 log.debug("generateSymbol: val = {f}", .{val.fmtValue(pt)});
325309
310 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse {
311 return zcu.comp.link_diags.fail("failed to generate symbol: type size overflow", .{});
312 };
313
326314 if (val.isUndef(zcu)) {
327 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
328315 try w.splatByteAll(0xaa, abi_size);
329316 return;
330317 }
......@@ -364,7 +351,6 @@ pub fn generateSymbol(
364351 .enum_literal,
365352 => unreachable, // non-runtime values
366353 .int => {
367 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
368354 var space: Value.BigIntSpace = undefined;
369355 const int_val = val.toBigInt(&space, zcu);
370356 int_val.writeTwosComplement(try w.writableSlice(abi_size), endian);
......@@ -397,13 +383,13 @@ pub fn generateSymbol(
397383 // emit payload part of the error union
398384 {
399385 const begin = w.end;
400 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (error_union.val) {
386 try generateSymbol(bin_file, pt, Value.fromInterned(switch (error_union.val) {
401387 .err_name => try pt.intern(.{ .undef = payload_ty.toIntern() }),
402388 .payload => |payload| payload,
403389 }), w, reloc_parent);
404390 const unpadded_end = w.end - begin;
405391 const padded_end = abi_align.forward(unpadded_end);
406 const padding = math.cast(usize, padded_end - unpadded_end) orelse return error.Overflow;
392 const padding: usize = @intCast(padded_end - unpadded_end);
407393
408394 if (padding > 0) {
409395 try w.splatByteAll(0, padding);
......@@ -416,7 +402,7 @@ pub fn generateSymbol(
416402 try w.writeInt(u16, err_val, endian);
417403 const unpadded_end = w.end - begin;
418404 const padded_end = abi_align.forward(unpadded_end);
419 const padding = math.cast(usize, padded_end - unpadded_end) orelse return error.Overflow;
405 const padding: usize = @intCast(padded_end - unpadded_end);
420406
421407 if (padding > 0) {
422408 try w.splatByteAll(0, padding);
......@@ -425,7 +411,7 @@ pub fn generateSymbol(
425411 },
426412 .enum_tag => |enum_tag| {
427413 const int_tag_ty = ty.intTagType(zcu);
428 try generateSymbol(bin_file, pt, src_loc, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), w, reloc_parent);
414 try generateSymbol(bin_file, pt, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), w, reloc_parent);
429415 },
430416 .float => |float| storage: switch (float.storage) {
431417 .f16 => |f16_val| try w.writeInt(u16, @bitCast(f16_val), endian),
......@@ -433,7 +419,6 @@ pub fn generateSymbol(
433419 .f64 => |f64_val| try w.writeInt(u64, @bitCast(f64_val), endian),
434420 .f80 => |f80_val| {
435421 try w.writeInt(u80, @bitCast(f80_val), endian);
436 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
437422 try w.splatByteAll(0, abi_size - 10);
438423 },
439424 .f128 => |f128_val| switch (Type.fromInterned(float.ty).floatBits(target)) {
......@@ -444,29 +429,28 @@ pub fn generateSymbol(
444429 128 => try w.writeInt(u128, @bitCast(f128_val), endian),
445430 },
446431 },
447 .ptr => try lowerPtr(bin_file, pt, src_loc, val.toIntern(), w, reloc_parent, 0),
432 .ptr => try lowerPtr(bin_file, pt, val.toIntern(), w, reloc_parent, 0),
448433 .slice => |slice| {
449 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), w, reloc_parent);
450 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), w, reloc_parent);
434 try generateSymbol(bin_file, pt, Value.fromInterned(slice.ptr), w, reloc_parent);
435 try generateSymbol(bin_file, pt, Value.fromInterned(slice.len), w, reloc_parent);
451436 },
452437 .opt => {
453438 const payload_type = ty.optionalChild(zcu);
454439 const payload_val = val.optionalValue(zcu);
455 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
456440
457441 if (ty.optionalReprIsPayload(zcu)) {
458442 if (payload_val) |value| {
459 try generateSymbol(bin_file, pt, src_loc, value, w, reloc_parent);
443 try generateSymbol(bin_file, pt, value, w, reloc_parent);
460444 } else {
461445 try w.splatByteAll(0, abi_size);
462446 }
463447 } else {
464 const padding = abi_size - (math.cast(usize, payload_type.abiSize(zcu)) orelse return error.Overflow) - 1;
448 const padding = abi_size - @as(usize, @intCast(payload_type.abiSize(zcu))) - 1;
465449 if (payload_type.hasRuntimeBits(zcu)) {
466450 const value = payload_val orelse Value.fromInterned(try pt.intern(.{
467451 .undef = payload_type.toIntern(),
468452 }));
469 try generateSymbol(bin_file, pt, src_loc, value, w, reloc_parent);
453 try generateSymbol(bin_file, pt, value, w, reloc_parent);
470454 }
471455 try w.writeByte(@intFromBool(payload_val != null));
472456 try w.splatByteAll(0, padding);
......@@ -478,7 +462,7 @@ pub fn generateSymbol(
478462 .elems, .repeated_elem => {
479463 var index: u64 = 0;
480464 while (index < array_type.lenIncludingSentinel()) : (index += 1) {
481 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) {
465 try generateSymbol(bin_file, pt, Value.fromInterned(switch (aggregate.storage) {
482466 .bytes => unreachable,
483467 .elems => |elems| elems[@intCast(index)],
484468 .repeated_elem => |elem| if (index < array_type.len)
......@@ -490,7 +474,6 @@ pub fn generateSymbol(
490474 },
491475 },
492476 .vector_type => |vector_type| {
493 const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow;
494477 const vector_bool_bitpacked = switch (zcu.comp.getZigBackend()) {
495478 .stage2_wasm => false,
496479 else => true,
......@@ -499,7 +482,9 @@ pub fn generateSymbol(
499482 const bytes = try w.writableSlice(abi_size);
500483 @memset(bytes, 0xaa);
501484 var index: usize = 0;
502 const len = math.cast(usize, vector_type.len) orelse return error.Overflow;
485 const len = math.cast(usize, vector_type.len) orelse {
486 return zcu.comp.link_diags.fail("failed to generate symbol: vector length overflow", .{});
487 };
503488 while (index < len) : (index += 1) {
504489 const bit_index = switch (endian) {
505490 .big => len - 1 - index,
......@@ -539,18 +524,16 @@ pub fn generateSymbol(
539524 .elems, .repeated_elem => {
540525 var index: u64 = 0;
541526 while (index < vector_type.len) : (index += 1) {
542 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) {
527 try generateSymbol(bin_file, pt, Value.fromInterned(switch (aggregate.storage) {
543528 .bytes => unreachable,
544 .elems => |elems| elems[math.cast(usize, index) orelse return error.Overflow],
529 .elems => |elems| elems[@intCast(index)],
545530 .repeated_elem => |elem| elem,
546531 }), w, reloc_parent);
547532 }
548533 },
549534 }
550535
551 const padding = abi_size -
552 (math.cast(usize, Type.fromInterned(vector_type.child).abiSize(zcu) * vector_type.len) orelse
553 return error.Overflow);
536 const padding = abi_size - @as(usize, @intCast(Type.fromInterned(vector_type.child).abiSize(zcu) * vector_type.len));
554537 if (padding > 0) try w.splatByteAll(0, padding);
555538 }
556539 },
......@@ -560,10 +543,9 @@ pub fn generateSymbol(
560543 if (field_val != .none) continue;
561544 if (!Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue;
562545
563 try w.splatByteAll(0, math.cast(usize, struct_begin +
564 Type.fromInterned(field_ty).abiAlignment(zcu).forward(w.end - struct_begin) - w.end) orelse
565 return error.Overflow);
566 try generateSymbol(bin_file, pt, src_loc, .fromInterned(switch (aggregate.storage) {
546 try w.splatByteAll(0, @intCast(struct_begin +
547 Type.fromInterned(field_ty).abiAlignment(zcu).forward(w.end - struct_begin) - w.end));
548 try generateSymbol(bin_file, pt, .fromInterned(switch (aggregate.storage) {
567549 .bytes => |bytes| try pt.intern(.{ .int = .{
568550 .ty = field_ty,
569551 .storage = .{ .u64 = bytes.at(field_index, ip) },
......@@ -572,8 +554,7 @@ pub fn generateSymbol(
572554 .repeated_elem => |elem| elem,
573555 }), w, reloc_parent);
574556 }
575 try w.splatByteAll(0, math.cast(usize, struct_begin + ty.abiSize(zcu) - w.end) orelse
576 return error.Overflow);
557 try w.splatByteAll(0, @intCast(struct_begin + ty.abiSize(zcu) - w.end));
577558 },
578559 .struct_type => {
579560 const struct_type = ip.loadStructType(ty.toIntern());
......@@ -598,20 +579,15 @@ pub fn generateSymbol(
598579 .repeated_elem => |elem| elem,
599580 };
600581
601 const padding = math.cast(
602 usize,
603 offsets[field_index] - (w.end - struct_begin),
604 ) orelse return error.Overflow;
582 const padding: usize = @intCast(offsets[field_index] - (w.end - struct_begin));
605583 if (padding > 0) try w.splatByteAll(0, padding);
606584
607 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), w, reloc_parent);
585 try generateSymbol(bin_file, pt, Value.fromInterned(field_val), w, reloc_parent);
608586 }
609587
610588 assert(struct_type.alignment.check(struct_type.size));
611589
612 const padding = math.cast(usize, struct_type.size - (w.end - struct_begin)) orelse {
613 return error.Overflow;
614 };
590 const padding: usize = @intCast(struct_type.size - (w.end - struct_begin));
615591 if (padding > 0) try w.splatByteAll(0, padding);
616592 },
617593 }
......@@ -622,12 +598,12 @@ pub fn generateSymbol(
622598 const layout = ty.unionGetLayout(zcu);
623599
624600 if (layout.payload_size == 0) {
625 return generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), w, reloc_parent);
601 return generateSymbol(bin_file, pt, Value.fromInterned(un.tag), w, reloc_parent);
626602 }
627603
628604 // Check if we should store the tag first.
629605 if (layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) {
630 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), w, reloc_parent);
606 try generateSymbol(bin_file, pt, Value.fromInterned(un.tag), w, reloc_parent);
631607 }
632608
633609 const union_obj = zcu.typeToUnion(ty).?;
......@@ -635,28 +611,28 @@ pub fn generateSymbol(
635611 const field_index = ty.unionTagFieldIndex(Value.fromInterned(un.tag), zcu).?;
636612 const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
637613 if (!field_ty.hasRuntimeBits(zcu)) {
638 try w.splatByteAll(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow);
614 try w.splatByteAll(0xaa, @intCast(layout.payload_size));
639615 } else {
640 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), w, reloc_parent);
616 try generateSymbol(bin_file, pt, Value.fromInterned(un.val), w, reloc_parent);
641617
642 const padding = math.cast(usize, layout.payload_size - field_ty.abiSize(zcu)) orelse return error.Overflow;
618 const padding: usize = @intCast(layout.payload_size - field_ty.abiSize(zcu));
643619 if (padding > 0) {
644620 try w.splatByteAll(0, padding);
645621 }
646622 }
647623 } else {
648 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), w, reloc_parent);
624 try generateSymbol(bin_file, pt, Value.fromInterned(un.val), w, reloc_parent);
649625 }
650626
651627 if (layout.tag_size > 0 and layout.tag_align.compare(.lt, layout.payload_align)) {
652 try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), w, reloc_parent);
628 try generateSymbol(bin_file, pt, Value.fromInterned(un.tag), w, reloc_parent);
653629
654630 if (layout.padding > 0) {
655631 try w.splatByteAll(0, layout.padding);
656632 }
657633 }
658634 },
659 .bitpack => |bitpack| try generateSymbol(bin_file, pt, src_loc, .fromInterned(bitpack.backing_int_val), w, reloc_parent),
635 .bitpack => |bitpack| try generateSymbol(bin_file, pt, .fromInterned(bitpack.backing_int_val), w, reloc_parent),
660636 .memoized_call => unreachable,
661637 }
662638}
......@@ -664,23 +640,21 @@ pub fn generateSymbol(
664640fn lowerPtr(
665641 bin_file: *link.File,
666642 pt: Zcu.PerThread,
667 src_loc: Zcu.LazySrcLoc,
668643 ptr_val: InternPool.Index,
669644 w: *std.Io.Writer,
670645 reloc_parent: link.File.RelocInfo.Parent,
671646 prev_offset: u64,
672) (GenerateSymbolError || std.Io.Writer.Error)!void {
647) (Error || std.Io.Writer.Error)!void {
673648 const zcu = pt.zcu;
674649 const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr;
675650 const offset: u64 = prev_offset + ptr.byte_offset;
676651 return switch (ptr.base_addr) {
677652 .nav => |nav| try lowerNavRef(bin_file, pt, nav, w, reloc_parent, offset),
678 .uav => |uav| try lowerUavRef(bin_file, pt, src_loc, uav, w, reloc_parent, offset),
679 .int => try generateSymbol(bin_file, pt, src_loc, try pt.intValue(Type.usize, offset), w, reloc_parent),
653 .uav => |uav| try lowerUavRef(bin_file, pt, uav, w, reloc_parent, offset),
654 .int => try generateSymbol(bin_file, pt, try pt.intValue(Type.usize, offset), w, reloc_parent),
680655 .eu_payload => |eu_ptr| try lowerPtr(
681656 bin_file,
682657 pt,
683 src_loc,
684658 eu_ptr,
685659 w,
686660 reloc_parent,
......@@ -689,7 +663,7 @@ fn lowerPtr(
689663 zcu,
690664 ),
691665 ),
692 .opt_payload => |opt_ptr| try lowerPtr(bin_file, pt, src_loc, opt_ptr, w, reloc_parent, offset),
666 .opt_payload => |opt_ptr| try lowerPtr(bin_file, pt, opt_ptr, w, reloc_parent, offset),
693667 .field => |field| {
694668 const base_ptr = Value.fromInterned(field.base);
695669 const base_ty = base_ptr.typeOf(zcu).childType(zcu);
......@@ -708,13 +682,13 @@ fn lowerPtr(
708682 },
709683 else => unreachable,
710684 };
711 return lowerPtr(bin_file, pt, src_loc, field.base, w, reloc_parent, offset + field_off);
685 return lowerPtr(bin_file, pt, field.base, w, reloc_parent, offset + field_off);
712686 },
713687 .arr_elem => |arr_elem| {
714688 const base_ptr_ty = Value.fromInterned(arr_elem.base).typeOf(zcu);
715689 assert(base_ptr_ty.ptrSize(zcu) == .many);
716690 const elem_size = base_ptr_ty.childType(zcu).abiSize(zcu);
717 return lowerPtr(bin_file, pt, src_loc, arr_elem.base, w, reloc_parent, offset + elem_size * arr_elem.index);
691 return lowerPtr(bin_file, pt, arr_elem.base, w, reloc_parent, offset + elem_size * arr_elem.index);
718692 },
719693 .comptime_alloc => unreachable,
720694 .comptime_field => unreachable,
......@@ -724,12 +698,11 @@ fn lowerPtr(
724698fn lowerUavRef(
725699 lf: *link.File,
726700 pt: Zcu.PerThread,
727 src_loc: Zcu.LazySrcLoc,
728701 uav: InternPool.Key.Ptr.BaseAddr.Uav,
729702 w: *std.Io.Writer,
730703 reloc_parent: link.File.RelocInfo.Parent,
731704 offset: u64,
732) (GenerateSymbolError || std.Io.Writer.Error)!void {
705) (Error || std.Io.Writer.Error)!void {
733706 const zcu = pt.zcu;
734707 const ip = &zcu.intern_pool;
735708 const comp = lf.comp;
......@@ -761,10 +734,7 @@ fn lowerUavRef(
761734 }
762735
763736 const uav_align = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu);
764 switch (try lf.lowerUav(pt, uav_val, uav_align, src_loc)) {
765 .sym_index => {},
766 .fail => |em| std.debug.panic("TODO rework lowerUav. internal error: {s}", .{em.msg}),
767 }
737 _ = try lf.lowerUav(pt, uav_val, uav_align);
768738
769739 const vaddr = lf.getUavVAddr(uav_val, .{
770740 .parent = reloc_parent,
......@@ -790,7 +760,7 @@ fn lowerNavRef(
790760 w: *std.Io.Writer,
791761 reloc_parent: link.File.RelocInfo.Parent,
792762 offset: u64,
793) (GenerateSymbolError || std.Io.Writer.Error)!void {
763) (Error || std.Io.Writer.Error)!void {
794764 const zcu = pt.zcu;
795765 const gpa = zcu.gpa;
796766 const ip = &zcu.intern_pool;
......@@ -859,15 +829,11 @@ fn lowerNavRef(
859829 }
860830}
861831
862pub const SymbolResult = union(enum) { sym_index: link.File.SymbolId, fail: *ErrorMsg };
863
864832pub fn genNavRef(
865833 lf: *link.File,
866834 pt: Zcu.PerThread,
867 src_loc: Zcu.LazySrcLoc,
868835 nav_index: InternPool.Nav.Index,
869 target: *const std.Target,
870) CodeGenError!SymbolResult {
836) Error!link.File.SymbolId {
871837 const zcu = pt.zcu;
872838 const ip = &zcu.intern_pool;
873839 const nav = ip.getNav(nav_index);
......@@ -884,7 +850,7 @@ pub fn genNavRef(
884850 .internal => {
885851 const sym_index = try zo.getOrCreateMetadataForNav(zcu, nav_index);
886852 if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true;
887 return .{ .sym_index = @enumFromInt(sym_index) };
853 return @enumFromInt(sym_index);
888854 },
889855 .strong, .weak => {
890856 const sym_index = try elf_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
......@@ -895,27 +861,19 @@ pub fn genNavRef(
895861 .link_once => unreachable,
896862 }
897863 if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true;
898 return .{ .sym_index = @enumFromInt(sym_index) };
864 return @enumFromInt(sym_index);
899865 },
900866 .link_once => unreachable,
901867 }
902868 } else if (lf.cast(.elf2)) |elf| {
903 return .{ .sym_index = elf.navSymbol(nav_index) catch |err| switch (err) {
904 error.OutOfMemory => |e| return e,
905 else => |e| return .{ .fail = try ErrorMsg.create(
906 zcu.gpa,
907 src_loc,
908 "linker failed to create a nav: {t}",
909 .{e},
910 ) },
911 } };
869 return elf.navSymbol(nav_index);
912870 } else if (lf.cast(.macho)) |macho_file| {
913871 const zo = macho_file.getZigObject().?;
914872 switch (linkage) {
915873 .internal => {
916874 const sym_index = try zo.getOrCreateMetadataForNav(macho_file, nav_index);
917875 if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true;
918 return .{ .sym_index = @enumFromInt(sym_index) };
876 return @enumFromInt(sym_index);
919877 },
920878 .strong, .weak => {
921879 const sym_index = try macho_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip));
......@@ -926,80 +884,67 @@ pub fn genNavRef(
926884 .link_once => unreachable,
927885 }
928886 if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true;
929 return .{ .sym_index = @enumFromInt(sym_index) };
887 return @enumFromInt(sym_index);
930888 },
931889 .link_once => unreachable,
932890 }
933891 } else if (lf.cast(.coff2)) |coff| {
934 return .{ .sym_index = @enumFromInt(@intFromEnum(try coff.navSymbol(zcu, nav_index))) };
892 return @enumFromInt(@intFromEnum(try coff.navSymbol(zcu, nav_index)));
935893 } else {
936 const msg = try ErrorMsg.create(zcu.gpa, src_loc, "TODO genNavRef for target {}", .{target});
937 return .{ .fail = msg };
894 std.debug.panic("TODO genNavRef for '{t}'", .{lf.tag});
938895 }
939896}
940897
941898/// deprecated legacy type
942pub const GenResult = union(enum) {
943 mcv: MCValue,
944 fail: *ErrorMsg,
945
946 const MCValue = union(enum) {
947 none,
948 undef,
949 /// The bit-width of the immediate may be smaller than `u64`. For example, on 32-bit targets
950 /// such as ARM, the immediate will never exceed 32-bits.
951 immediate: u64,
952 /// Decl with address deferred until the linker allocates everything in virtual memory.
953 /// Payload is a symbol index.
954 load_direct: link.File.SymbolId,
955 /// Decl with address deferred until the linker allocates everything in virtual memory.
956 /// Payload is a symbol index.
957 lea_direct: link.File.SymbolId,
958 /// Decl referenced via GOT with address deferred until the linker allocates
959 /// everything in virtual memory.
960 /// Payload is a symbol index.
961 load_got: link.File.SymbolId,
962 /// Direct by-address reference to memory location.
963 memory: u64,
964 /// Reference to memory location but deferred until linker allocated the Decl in memory.
965 /// Traditionally, this corresponds to emitting a relocation in a relocatable object file.
966 load_symbol: link.File.SymbolId,
967 /// Reference to memory location but deferred until linker allocated the Decl in memory.
968 /// Traditionally, this corresponds to emitting a relocation in a relocatable object file.
969 lea_symbol: link.File.SymbolId,
970 };
899pub const MCValue = union(enum) {
900 none,
901 undef,
902 /// The bit-width of the immediate may be smaller than `u64`. For example, on 32-bit targets
903 /// such as ARM, the immediate will never exceed 32-bits.
904 immediate: u64,
905 /// Decl with address deferred until the linker allocates everything in virtual memory.
906 /// Payload is a symbol index.
907 load_direct: link.File.SymbolId,
908 /// Decl with address deferred until the linker allocates everything in virtual memory.
909 /// Payload is a symbol index.
910 lea_direct: link.File.SymbolId,
911 /// Decl referenced via GOT with address deferred until the linker allocates
912 /// everything in virtual memory.
913 /// Payload is a symbol index.
914 load_got: link.File.SymbolId,
915 /// Direct by-address reference to memory location.
916 memory: u64,
917 /// Reference to memory location but deferred until linker allocated the Decl in memory.
918 /// Traditionally, this corresponds to emitting a relocation in a relocatable object file.
919 load_symbol: link.File.SymbolId,
920 /// Reference to memory location but deferred until linker allocated the Decl in memory.
921 /// Traditionally, this corresponds to emitting a relocation in a relocatable object file.
922 lea_symbol: link.File.SymbolId,
971923};
972924
973925/// deprecated legacy code path
974926pub fn genTypedValue(
975927 lf: *link.File,
976928 pt: Zcu.PerThread,
977 src_loc: Zcu.LazySrcLoc,
978929 val: Value,
979930 target: *const std.Target,
980) CodeGenError!GenResult {
931) Error!MCValue {
981932 const res = try lowerValue(pt, val, target);
982933 return switch (res) {
983 .none => .{ .mcv = .none },
984 .undef => .{ .mcv = .undef },
985 .immediate => |imm| .{ .mcv = .{ .immediate = imm } },
986 .lea_nav => |nav| switch (try genNavRef(lf, pt, src_loc, nav, target)) {
987 .sym_index => |sym_index| .{ .mcv = .{ .lea_symbol = sym_index } },
988 .fail => |em| .{ .fail = em },
989 },
990 .load_uav, .lea_uav => |uav| switch (try lf.lowerUav(
934 .none => .none,
935 .undef => .undef,
936 .immediate => |imm| .{ .immediate = imm },
937 .lea_nav => |nav| .{ .lea_symbol = try genNavRef(lf, pt, nav) },
938 .load_uav => |uav| .{ .load_symbol = try lf.lowerUav(
991939 pt,
992940 uav.val,
993941 Type.fromInterned(uav.orig_ty).ptrAlignment(pt.zcu),
994 src_loc,
995 )) {
996 .sym_index => |sym_index| .{ .mcv = switch (res) {
997 else => unreachable,
998 .load_uav => .{ .load_symbol = sym_index },
999 .lea_uav => .{ .lea_symbol = sym_index },
1000 } },
1001 .fail => |em| .{ .fail = em },
1002 },
942 ) },
943 .lea_uav => |uav| .{ .lea_symbol = try lf.lowerUav(
944 pt,
945 uav.val,
946 Type.fromInterned(uav.orig_ty).ptrAlignment(pt.zcu),
947 ) },
1003948 };
1004949}
1005950
src/codegen/aarch64.zig-1
......@@ -12,7 +12,6 @@ pub fn legalizeFeatures(_: *const std.Target) ?*Air.Legalize.Features {
1212pub fn generate(
1313 _: *link.File,
1414 pt: Zcu.PerThread,
15 _: Zcu.LazySrcLoc,
1615 func_index: InternPool.Index,
1716 air: *const Air,
1817 liveness: *const ?Air.Liveness,
src/codegen/aarch64/Mir.zig+4-14
......@@ -54,7 +54,6 @@ pub fn emit(
5454 mir: Mir,
5555 lf: *link.File,
5656 pt: Zcu.PerThread,
57 src_loc: Zcu.LazySrcLoc,
5857 func_index: InternPool.Index,
5958 atom_index: link.File.AtomId,
6059 w: *std.Io.Writer,
......@@ -94,16 +93,11 @@ pub fn emit(
9493 lf,
9594 zcu,
9695 atom_index,
97 switch (try @import("../../codegen.zig").genNavRef(
96 try @import("../../codegen.zig").genNavRef(
9897 lf,
9998 pt,
100 src_loc,
10199 nav_reloc.nav,
102 &mod.resolved_target.result,
103 )) {
104 .sym_index => |sym_index| sym_index,
105 .fail => |em| return zcu.codegenFailMsg(func.owner_nav, em),
106 },
100 ),
107101 mir.body[nav_reloc.reloc.label],
108102 body_end - Instruction.size * (1 + nav_reloc.reloc.label),
109103 nav_reloc.reloc.addend,
......@@ -113,15 +107,11 @@ pub fn emit(
113107 lf,
114108 zcu,
115109 atom_index,
116 switch (try lf.lowerUav(
110 try lf.lowerUav(
117111 pt,
118112 uav_reloc.uav.val,
119113 ZigType.fromInterned(uav_reloc.uav.orig_ty).ptrAlignment(zcu),
120 src_loc,
121 )) {
122 .sym_index => |sym_index| sym_index,
123 .fail => |em| return zcu.codegenFailMsg(func.owner_nav, em),
124 },
114 ),
125115 mir.body[uav_reloc.reloc.label],
126116 body_end - Instruction.size * (1 + uav_reloc.reloc.label),
127117 uav_reloc.reloc.addend,
src/codegen/aarch64/Select.zig+5-5
......@@ -883,7 +883,7 @@ pub fn finishAnalysis(isel: *Select) !void {
883883 }
884884}
885885
886pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, CodegenFail }!void {
886pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, AlreadyReported }!void {
887887 const zcu = isel.pt.zcu;
888888 const ip = &zcu.intern_pool;
889889 const gpa = zcu.gpa;
......@@ -8001,7 +8001,7 @@ fn emitLiteral(isel: *Select, bytes: []const u8) !void {
80018001 }
80028002}
80038003
8004fn fail(isel: *Select, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
8004fn fail(isel: *Select, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } {
80058005 @branchHint(.cold);
80068006 return isel.pt.zcu.codegenFail(isel.nav_index, format, args);
80078007}
......@@ -10595,7 +10595,7 @@ pub const Value = struct {
1059510595 vi: Value.Index,
1059610596 ra: Register.Alias,
1059710597
10598 fn finish(mat: Value.Materialize, isel: *Select) error{ OutOfMemory, CodegenFail }!void {
10598 fn finish(mat: Value.Materialize, isel: *Select) error{ OutOfMemory, AlreadyReported }!void {
1059910599 const live_vi = isel.live_registers.getPtr(mat.ra);
1060010600 assert(live_vi.* == .allocating);
1060110601 var vi = mat.vi;
......@@ -11636,7 +11636,7 @@ fn use(isel: *Select, air_ref: Air.Inst.Ref) !Value.Index {
1163611636 return vi;
1163711637}
1163811638
11639fn fill(isel: *Select, dst_ra: Register.Alias) error{ OutOfMemory, CodegenFail }!bool {
11639fn fill(isel: *Select, dst_ra: Register.Alias) error{ OutOfMemory, AlreadyReported }!bool {
1164011640 switch (dst_ra) {
1164111641 else => {},
1164211642 Register.Alias.fp, .zr, .sp, .pc, .fpcr, .fpsr, .ffr => return false,
......@@ -11669,7 +11669,7 @@ fn fill(isel: *Select, dst_ra: Register.Alias) error{ OutOfMemory, CodegenFail }
1166911669 return true;
1167011670}
1167111671
11672fn fillMemory(isel: *Select, dst_ra: Register.Alias) error{ OutOfMemory, CodegenFail }!bool {
11672fn fillMemory(isel: *Select, dst_ra: Register.Alias) error{ OutOfMemory, AlreadyReported }!bool {
1167311673 const dst_live_vi = isel.live_registers.getPtr(dst_ra);
1167411674 const dst_vi = switch (dst_live_vi.*) {
1167511675 _ => |dst_vi| dst_vi,
src/codegen/c.zig+4-12
......@@ -80,7 +80,7 @@ pub const Mir = struct {
8080 }
8181};
8282
83pub const Error = Writer.Error || Allocator.Error || error{AnalysisFail};
83pub const Error = Writer.Error || Allocator.Error || error{AlreadyReported};
8484
8585pub const CType = @import("c/type.zig").CType;
8686
......@@ -637,7 +637,6 @@ pub const DeclGen = struct {
637637 owner_nav: InternPool.Nav.Index.Optional,
638638 is_naked_fn: bool,
639639 expected_block: ?u32,
640 error_msg: ?*Zcu.ErrorMsg,
641640 ctype_deps: CType.Dependencies,
642641 /// This map contains all the UAVs we saw generating this function.
643642 /// `link.C` will merge them into its `uavs`/`aligned_uavs` fields.
......@@ -648,10 +647,7 @@ pub const DeclGen = struct {
648647
649648 fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) Error {
650649 @branchHint(.cold);
651 const zcu = dg.pt.zcu;
652 const src_loc = zcu.navSrcLoc(dg.owner_nav.unwrap().?);
653 dg.error_msg = try Zcu.ErrorMsg.create(dg.gpa, src_loc, format, args);
654 return error.AnalysisFail;
650 return dg.pt.zcu.codegenFail(dg.owner_nav.unwrap().?, format, args);
655651 }
656652
657653 fn renderUav(
......@@ -2184,15 +2180,13 @@ pub fn genLazyCallModifierFn(
21842180pub fn generate(
21852181 lf: *link.File,
21862182 pt: Zcu.PerThread,
2187 src_loc: Zcu.LazySrcLoc,
21882183 func_index: InternPool.Index,
21892184 air: *const Air,
21902185 liveness: *const ?Air.Liveness,
2191) @import("../codegen.zig").CodeGenError!Mir {
2186) @import("../codegen.zig").Error!Mir {
21922187 const zcu = pt.zcu;
21932188 const gpa = zcu.gpa;
21942189
2195 _ = src_loc;
21962190 assert(lf.tag == .c);
21972191
21982192 const func = zcu.funcInfo(func_index);
......@@ -2210,7 +2204,6 @@ pub fn generate(
22102204 .arena = arena.allocator(),
22112205 .pt = pt,
22122206 .mod = zcu.navFileScope(func.owner_nav).mod.?,
2213 .error_msg = null,
22142207 .owner_nav = func.owner_nav.toOptional(),
22152208 .is_naked_fn = Type.fromInterned(func.ty).fnCallingConvention(zcu) == .naked,
22162209 .expected_block = null,
......@@ -2237,9 +2230,8 @@ pub fn generate(
22372230 defer code_header.deinit();
22382231
22392232 genFunc(&function, &fwd_decl.writer, &code_header.writer) catch |err| switch (err) {
2240 error.AnalysisFail => return zcu.codegenFailMsg(func.owner_nav, function.dg.error_msg.?),
22412233 error.WriteFailed => return error.OutOfMemory,
2242 error.OutOfMemory => |e| return e,
2234 else => |e| return e,
22432235 };
22442236
22452237 var mir: Mir = .{
src/codegen/llvm.zig+3-3
......@@ -771,7 +771,7 @@ pub const Object = struct {
771771 lto: std.zig.LtoMode,
772772 };
773773
774 pub fn emit(o: *Object, pt: Zcu.PerThread, options: EmitOptions) error{ LinkFailure, OutOfMemory }!void {
774 pub fn emit(o: *Object, pt: Zcu.PerThread, options: EmitOptions) error{ AlreadyReported, OutOfMemory }!void {
775775 const zcu = o.zcu;
776776 const comp = zcu.comp;
777777 const io = comp.io;
......@@ -1705,7 +1705,7 @@ pub const Object = struct {
17051705 o: *Object,
17061706 exported: Zcu.Exported,
17071707 export_indices: []const Zcu.Export.Index,
1708 ) link.File.UpdateExportsError!void {
1708 ) link.Error!void {
17091709 const zcu = o.zcu;
17101710 const ip = &zcu.intern_pool;
17111711 const ty: Type, const llvm_ptr: Builder.Constant = switch (exported) {
......@@ -1735,7 +1735,7 @@ pub const Object = struct {
17351735 global_index: Builder.Global.Index,
17361736 ty: Type,
17371737 export_indices: []const Zcu.Export.Index,
1738 ) link.File.UpdateExportsError!void {
1738 ) link.Error!void {
17391739 const zcu = o.zcu;
17401740 const comp = zcu.comp;
17411741 const ip = &zcu.intern_pool;
src/codegen/riscv64/CodeGen.zig+24-40
......@@ -30,8 +30,6 @@ const verbose_tracking_log = std.log.scoped(.verbose_tracking);
3030const wip_mir_log = std.log.scoped(.wip_mir);
3131const Alignment = InternPool.Alignment;
3232
33const CodeGenError = codegen.CodeGenError;
34
3533const bits = @import("bits.zig");
3634const abi = @import("abi.zig");
3735const Lower = @import("Lower.zig");
......@@ -49,7 +47,7 @@ const RegisterManager = abi.RegisterManager;
4947const RegisterLock = RegisterManager.RegisterLock;
5048const Instruction = encoding.Instruction;
5149
52const InnerError = CodeGenError || error{OutOfRegisters};
50const InnerError = codegen.Error || error{OutOfRegisters};
5351
5452pub fn legalizeFeatures(_: *const std.Target) *const Air.Legalize.Features {
5553 return comptime &.initMany(&.{
......@@ -75,7 +73,6 @@ ret_mcv: InstTracking,
7573func_index: InternPool.Index,
7674fn_type: Type,
7775arg_index: usize,
78src_loc: Zcu.LazySrcLoc,
7976
8077mir_instructions: std.MultiArrayList(Mir.Inst) = .{},
8178
......@@ -742,11 +739,10 @@ const CallView = enum(u1) {
742739pub fn generate(
743740 bin_file: *link.File,
744741 pt: Zcu.PerThread,
745 src_loc: Zcu.LazySrcLoc,
746742 func_index: InternPool.Index,
747743 air: *const Air,
748744 liveness: *const ?Air.Liveness,
749) CodeGenError!Mir {
745) codegen.Error!Mir {
750746 const zcu = pt.zcu;
751747 const gpa = zcu.gpa;
752748 const ip = &zcu.intern_pool;
......@@ -777,7 +773,6 @@ pub fn generate(
777773 .fn_type = fn_type,
778774 .arg_index = 0,
779775 .branch_stack = &branch_stack,
780 .src_loc = src_loc,
781776 .end_di_line = func.rbrace_line,
782777 .end_di_column = func.rbrace_column,
783778 .scope_generation = 0,
......@@ -811,10 +806,7 @@ pub fn generate(
811806 );
812807
813808 const fn_info = zcu.typeToFunc(fn_type).?;
814 var call_info = function.resolveCallingConventionValues(fn_info, &.{}) catch |err| switch (err) {
815 error.CodegenFail => |e| return e,
816 else => |e| return e,
817 };
809 var call_info = try function.resolveCallingConventionValues(fn_info, &.{});
818810
819811 defer call_info.deinit(&function);
820812
......@@ -841,7 +833,6 @@ pub fn generate(
841833 }));
842834
843835 function.gen() catch |err| switch (err) {
844 error.CodegenFail => |e| return e,
845836 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
846837 else => |e| return e,
847838 };
......@@ -857,12 +848,11 @@ pub fn generate(
857848pub fn generateLazy(
858849 bin_file: *link.File,
859850 pt: Zcu.PerThread,
860 src_loc: Zcu.LazySrcLoc,
861851 lazy_sym: link.File.LazySymbol,
862852 atom_index: link.File.AtomId,
863853 w: *std.Io.Writer,
864854 debug_output: link.File.DebugInfoOutput,
865) (CodeGenError || std.Io.Writer.Error)!void {
855) (codegen.Error || std.Io.Writer.Error)!void {
866856 _ = atom_index;
867857 const comp = bin_file.comp;
868858 const gpa = comp.gpa;
......@@ -883,7 +873,6 @@ pub fn generateLazy(
883873 .fn_type = undefined,
884874 .arg_index = 0,
885875 .branch_stack = undefined,
886 .src_loc = src_loc,
887876 .end_di_line = undefined,
888877 .end_di_column = undefined,
889878 .scope_generation = 0,
......@@ -893,7 +882,6 @@ pub fn generateLazy(
893882 defer function.mir_instructions.deinit(gpa);
894883
895884 function.genLazy(lazy_sym) catch |err| switch (err) {
896 error.CodegenFail => |e| return e,
897885 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
898886 else => |e| return e,
899887 };
......@@ -910,7 +898,7 @@ pub fn generateLazy(
910898 .allocator = gpa,
911899 .mir = mir,
912900 .cc = .auto,
913 .src_loc = src_loc,
901 .src_loc = Type.fromInterned(lazy_sym.ty).srcLocOrNull(pt.zcu) orelse .unneeded,
914902 .output_mode = comp.config.output_mode,
915903 .link_mode = comp.config.link_mode,
916904 .pic = mod.pic,
......@@ -946,7 +934,10 @@ fn formatWipMir(data: FormatWipMirData, writer: *std.Io.Writer) std.Io.Writer.Er
946934 .frame_locs = data.func.frame_locs.slice(),
947935 },
948936 .cc = .auto,
949 .src_loc = data.func.src_loc,
937 .src_loc = switch (data.func.owner) {
938 .nav_index => |nav| pt.zcu.navSrcLoc(nav),
939 .lazy_sym => |lazy_sym| Type.fromInterned(lazy_sym.ty).srcLocOrNull(pt.zcu) orelse .unneeded,
940 },
950941 .output_mode = comp.config.output_mode,
951942 .link_mode = comp.config.link_mode,
952943 .pic = comp.root_mod.pic,
......@@ -8144,28 +8135,21 @@ fn genTypedValue(func: *Func, val: Value) InnerError!MCValue {
81448135 const pt = func.pt;
81458136
81468137 const lf = func.bin_file;
8147 const src_loc = func.src_loc;
81488138
8149 const result: codegen.GenResult = if (val.isUndef(pt.zcu))
8150 switch (try lf.lowerUav(pt, val.toIntern(), .none, src_loc)) {
8151 .sym_index => |sym_index| .{ .mcv = .{ .load_symbol = sym_index } },
8152 .fail => |em| .{ .fail = em },
8153 }
8139 const result: codegen.MCValue = if (val.isUndef(pt.zcu))
8140 .{ .load_symbol = try lf.lowerUav(pt, val.toIntern(), .none) }
81548141 else
8155 try codegen.genTypedValue(lf, pt, src_loc, val, func.target);
8142 try codegen.genTypedValue(lf, pt, val, func.target);
81568143 const mcv: MCValue = switch (result) {
8157 .mcv => |mcv| switch (mcv) {
8158 .none => .none,
8159 .undef => unreachable,
8160 .lea_symbol => |sym_index| .{ .lea_symbol = .{ .sym = sym_index } },
8161 .load_symbol => |sym_index| .{ .load_symbol = .{ .sym = sym_index } },
8162 .immediate => |imm| .{ .immediate = imm },
8163 .memory => |addr| .{ .memory = addr },
8164 .load_got, .load_direct, .lea_direct => {
8165 return func.fail("TODO: genTypedValue {s}", .{@tagName(mcv)});
8166 },
8144 .none => .none,
8145 .undef => unreachable,
8146 .lea_symbol => |sym_index| .{ .lea_symbol = .{ .sym = sym_index } },
8147 .load_symbol => |sym_index| .{ .load_symbol = .{ .sym = sym_index } },
8148 .immediate => |imm| .{ .immediate = imm },
8149 .memory => |addr| .{ .memory = addr },
8150 .load_got, .load_direct, .lea_direct => {
8151 return func.fail("TODO: genTypedValue {s}", .{@tagName(result)});
81678152 },
8168 .fail => |msg| return func.failMsg(msg),
81698153 };
81708154 return mcv;
81718155}
......@@ -8353,24 +8337,24 @@ fn wantSafety(func: *Func) bool {
83538337 };
83548338}
83558339
8356fn fail(func: *const Func, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
8340fn fail(func: *const Func, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } {
83578341 @branchHint(.cold);
83588342 const zcu = func.pt.zcu;
83598343 switch (func.owner) {
83608344 .nav_index => |i| return zcu.codegenFail(i, format, args),
83618345 .lazy_sym => |s| return zcu.codegenFailType(s.ty, format, args),
83628346 }
8363 return error.CodegenFail;
8347 return error.AlreadyReported;
83648348}
83658349
8366fn failMsg(func: *const Func, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } {
8350fn failMsg(func: *const Func, msg: *ErrorMsg) error{ OutOfMemory, AlreadyReported } {
83678351 @branchHint(.cold);
83688352 const zcu = func.pt.zcu;
83698353 switch (func.owner) {
83708354 .nav_index => |i| return zcu.codegenFailMsg(i, msg),
83718355 .lazy_sym => |s| return zcu.codegenFailTypeMsg(s.ty, msg),
83728356 }
8373 return error.CodegenFail;
8357 return error.AlreadyReported;
83748358}
83758359
83768360fn parseRegName(name: []const u8) ?Register {
src/codegen/riscv64/Mir.zig+2-3
......@@ -107,12 +107,11 @@ pub fn emit(
107107 mir: Mir,
108108 lf: *link.File,
109109 pt: Zcu.PerThread,
110 src_loc: Zcu.LazySrcLoc,
111110 func_index: InternPool.Index,
112111 atom_index: link.File.AtomId,
113112 w: *std.Io.Writer,
114113 debug_output: link.File.DebugInfoOutput,
115) (codegen.CodeGenError || std.Io.Writer.Error)!void {
114) (codegen.Error || std.Io.Writer.Error)!void {
116115 _ = atom_index;
117116 const zcu = pt.zcu;
118117 const comp = zcu.comp;
......@@ -127,7 +126,7 @@ pub fn emit(
127126 .allocator = gpa,
128127 .mir = mir,
129128 .cc = fn_info.cc,
130 .src_loc = src_loc,
129 .src_loc = zcu.navSrcLoc(nav),
131130 .output_mode = comp.config.output_mode,
132131 .link_mode = comp.config.link_mode,
133132 .pic = mod.pic,
src/codegen/sparc64/CodeGen.zig+11-28
......@@ -19,7 +19,6 @@ const Air = @import("../../Air.zig");
1919const Mir = @import("Mir.zig");
2020const Emit = @import("Emit.zig");
2121const Type = @import("../../Type.zig");
22const CodeGenError = codegen.CodeGenError;
2322const Endian = std.lang.Endian;
2423const Alignment = InternPool.Alignment;
2524
......@@ -39,7 +38,7 @@ const gp = abi.RegisterClass.gp;
3938
4039const Self = @This();
4140
42const InnerError = CodeGenError || error{OutOfRegisters};
41const InnerError = codegen.Error || error{OutOfRegisters};
4342
4443pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features {
4544 return null;
......@@ -57,12 +56,10 @@ liveness: Air.Liveness,
5756bin_file: *link.File,
5857target: *const std.Target,
5958func_index: InternPool.Index,
60err_msg: ?*ErrorMsg,
6159args: []MCValue,
6260ret_mcv: MCValue,
6361fn_type: Type,
6462arg_index: usize,
65src_loc: Zcu.LazySrcLoc,
6663stack_align: Alignment,
6764
6865/// MIR Instructions
......@@ -264,11 +261,10 @@ const BigTomb = struct {
264261pub fn generate(
265262 lf: *link.File,
266263 pt: Zcu.PerThread,
267 src_loc: Zcu.LazySrcLoc,
268264 func_index: InternPool.Index,
269265 air: *const Air,
270266 liveness: *const ?Air.Liveness,
271) CodeGenError!Mir {
267) codegen.Error!Mir {
272268 const zcu = pt.zcu;
273269 const gpa = zcu.gpa;
274270 const func = zcu.funcInfo(func_index);
......@@ -292,13 +288,11 @@ pub fn generate(
292288 .target = target,
293289 .bin_file = lf,
294290 .func_index = func_index,
295 .err_msg = null,
296291 .args = undefined, // populated after `resolveCallingConventionValues`
297292 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
298293 .fn_type = func_ty,
299294 .arg_index = 0,
300295 .branch_stack = &branch_stack,
301 .src_loc = src_loc,
302296 .stack_align = undefined,
303297 .end_di_line = func.rbrace_line,
304298 .end_di_column = func.rbrace_column,
......@@ -307,10 +301,7 @@ pub fn generate(
307301 defer function.blocks.deinit(gpa);
308302 defer function.exitlude_jump_relocs.deinit(gpa);
309303
310 var call_info = function.resolveCallingConventionValues(func_ty, .callee) catch |err| switch (err) {
311 error.CodegenFail => |e| return e,
312 else => |e| return e,
313 };
304 var call_info = try function.resolveCallingConventionValues(func_ty, .callee);
314305 defer call_info.deinit(&function);
315306
316307 function.args = call_info.args;
......@@ -319,7 +310,6 @@ pub fn generate(
319310 function.max_end_stack = call_info.stack_byte_count;
320311
321312 function.gen() catch |err| switch (err) {
322 error.CodegenFail => |e| return e,
323313 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
324314 else => |e| return e,
325315 };
......@@ -3446,15 +3436,15 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type)
34463436 }
34473437}
34483438
3449fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
3439fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } {
34503440 @branchHint(.cold);
34513441 const zcu = self.pt.zcu;
34523442 const func = zcu.funcInfo(self.func_index);
3453 const msg = try ErrorMsg.create(zcu.gpa, self.src_loc, format, args);
3443 const msg = try ErrorMsg.create(zcu.gpa, zcu.navSrcLoc(func.owner_nav), format, args);
34543444 return zcu.codegenFailMsg(func.owner_nav, msg);
34553445}
34563446
3457fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } {
3447fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, AlreadyReported } {
34583448 @branchHint(.cold);
34593449 const zcu = self.pt.zcu;
34603450 const func = zcu.funcInfo(self.func_index);
......@@ -4036,21 +4026,14 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
40364026 const mcv: MCValue = switch (try codegen.genTypedValue(
40374027 self.bin_file,
40384028 pt,
4039 self.src_loc,
40404029 val,
40414030 self.target,
40424031 )) {
4043 .mcv => |mcv| switch (mcv) {
4044 .none => .none,
4045 .undef => .undef,
4046 .load_got, .load_symbol, .load_direct, .lea_symbol, .lea_direct => unreachable, // TODO
4047 .immediate => |imm| .{ .immediate = imm },
4048 .memory => |addr| .{ .memory = addr },
4049 },
4050 .fail => |msg| {
4051 self.err_msg = msg;
4052 return error.CodegenFail;
4053 },
4032 .none => .none,
4033 .undef => .undef,
4034 .load_got, .load_symbol, .load_direct, .lea_symbol, .lea_direct => unreachable, // TODO
4035 .immediate => |imm| .{ .immediate = imm },
4036 .memory => |addr| .{ .memory = addr },
40544037 };
40554038 return mcv;
40564039}
src/codegen/sparc64/Mir.zig+2-3
......@@ -378,12 +378,11 @@ pub fn emit(
378378 mir: Mir,
379379 lf: *link.File,
380380 pt: Zcu.PerThread,
381 src_loc: Zcu.LazySrcLoc,
382381 func_index: InternPool.Index,
383382 atom_index: link.File.AtomId,
384383 w: *std.Io.Writer,
385384 debug_output: link.File.DebugInfoOutput,
386) (codegen.CodeGenError || std.Io.Writer.Error)!void {
385) (codegen.Error || std.Io.Writer.Error)!void {
387386 _ = atom_index;
388387 const zcu = pt.zcu;
389388 const func = zcu.funcInfo(func_index);
......@@ -394,7 +393,7 @@ pub fn emit(
394393 .bin_file = lf,
395394 .debug_output = debug_output,
396395 .target = &mod.resolved_target.result,
397 .src_loc = src_loc,
396 .src_loc = zcu.navSrcLoc(nav),
398397 .w = w,
399398 .prev_di_pc = 0,
400399 .prev_di_line = func.lbrace_line,
src/codegen/spirv/CodeGen.zig+12-16
......@@ -156,7 +156,6 @@ inst_results: std.AutoHashMapUnmanaged(Air.Inst.Index, Id) = .empty,
156156id_scratch: std.ArrayList(Id) = .empty,
157157prologue: Section = .{},
158158body: Section = .{},
159error_msg: ?*Zcu.ErrorMsg = null,
160159
161160pub fn deinit(cg: *CodeGen) void {
162161 const gpa = cg.module.gpa;
......@@ -168,7 +167,7 @@ pub fn deinit(cg: *CodeGen) void {
168167 cg.body.deinit(gpa);
169168}
170169
171const Error = error{ CodegenFail, OutOfMemory };
170const Error = error{ AlreadyReported, OutOfMemory };
172171
173172pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
174173 const gpa = cg.module.gpa;
......@@ -363,11 +362,7 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void {
363362
364363pub fn fail(cg: *CodeGen, comptime format: []const u8, args: anytype) Error {
365364 @branchHint(.cold);
366 const zcu = cg.module.zcu;
367 const src_loc = zcu.navSrcLoc(cg.owner_nav);
368 assert(cg.error_msg == null);
369 cg.error_msg = try Zcu.ErrorMsg.create(zcu.gpa, src_loc, format, args);
370 return error.CodegenFail;
365 return cg.module.zcu.codegenFail(cg.owner_nav, format, args);
371366}
372367
373368pub fn todo(cg: *CodeGen, comptime format: []const u8, args: anytype) Error {
......@@ -5934,14 +5929,14 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
59345929 // them as notes here.
59355930 // TODO: Translate proper error locations.
59365931 assert(ass.errors.items.len != 0);
5937 assert(cg.error_msg == null);
5938 const src_loc = zcu.navSrcLoc(cg.owner_nav);
5939 cg.error_msg = try Zcu.ErrorMsg.create(zcu.gpa, src_loc, "failed to assemble SPIR-V inline assembly", .{});
5940 const notes = try zcu.gpa.alloc(Zcu.ErrorMsg, ass.errors.items.len);
5932 const msg: *Zcu.ErrorMsg = msg: {
5933 const src_loc = zcu.navSrcLoc(cg.owner_nav);
5934 var msg: *Zcu.ErrorMsg = try .create(zcu.gpa, src_loc, "failed to assemble SPIR-V inline assembly", .{});
5935 errdefer msg.destroy(zcu.gpa);
59415936
5942 // Sub-scope to prevent `return error.CodegenFail` from running the errdefers.
5943 {
5937 const notes = try zcu.gpa.alloc(Zcu.ErrorMsg, ass.errors.items.len);
59445938 errdefer zcu.gpa.free(notes);
5939
59455940 var i: usize = 0;
59465941 errdefer for (notes[0..i]) |*note| {
59475942 note.deinit(zcu.gpa);
......@@ -5950,9 +5945,10 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) !?Id {
59505945 while (i < ass.errors.items.len) : (i += 1) {
59515946 notes[i] = try Zcu.ErrorMsg.init(zcu.gpa, src_loc, "{s}", .{ass.errors.items[i].msg});
59525947 }
5953 }
5954 cg.error_msg.?.notes = notes;
5955 return error.CodegenFail;
5948
5949 break :msg msg;
5950 };
5951 return zcu.codegenFailMsg(cg.owner_nav, msg);
59565952 },
59575953 else => |others| return others,
59585954 };
src/codegen/wasm/CodeGen.zig+4-9
......@@ -329,7 +329,7 @@ const bookkeeping_init = if (std.debug.runtime_safety) @as(usize, 0) else {};
329329const InnerError = error{
330330 OutOfMemory,
331331 /// An error occurred when trying to lower AIR to MIR.
332 CodegenFail,
332 AlreadyReported,
333333 /// Compiler implementation could not handle a large integer.
334334 Overflow,
335335} || link.File.UpdateDebugInfoError;
......@@ -355,7 +355,7 @@ pub fn deinit(cg: *CodeGen) void {
355355 cg.* = undefined;
356356}
357357
358pub fn fail(cg: *CodeGen, comptime fmt: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
358pub fn fail(cg: *CodeGen, comptime fmt: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } {
359359 const zcu = cg.pt.zcu;
360360 const func = zcu.funcInfo(cg.func_index);
361361 return zcu.codegenFail(func.owner_nav, fmt, args);
......@@ -756,21 +756,17 @@ fn ensureAllocLocal(cg: *CodeGen, ty: Type) InnerError!WValue {
756756
757757pub const Error = error{
758758 OutOfMemory,
759 /// Compiler was asked to operate on a number larger than supported.
760 Overflow,
761759 /// Indicates the error is already stored in Zcu `failed_codegen`.
762 CodegenFail,
760 AlreadyReported,
763761};
764762
765763pub fn generate(
766764 bin_file: *link.File,
767765 pt: Zcu.PerThread,
768 src_loc: Zcu.LazySrcLoc,
769766 func_index: InternPool.Index,
770767 air: *const Air,
771768 liveness: *const ?Air.Liveness,
772769) Error!Mir {
773 _ = src_loc;
774770 _ = bin_file;
775771 const zcu = pt.zcu;
776772 const gpa = zcu.gpa;
......@@ -814,9 +810,8 @@ pub fn generate(
814810 try code_gen.mir_func_tys.putNoClobber(gpa, fn_ty.toIntern(), {});
815811
816812 return generateInner(&code_gen, any_returns) catch |err| switch (err) {
817 error.CodegenFail,
813 error.AlreadyReported,
818814 error.OutOfMemory,
819 error.Overflow,
820815 => |e| return e,
821816 else => |e| return code_gen.fail("failed to generate function: {s}", .{@errorName(e)}),
822817 };
src/codegen/x86_64/CodeGen.zig+10-17
......@@ -31,7 +31,7 @@ const RegisterManager = abi.RegisterManager;
3131const RegisterLock = RegisterManager.RegisterLock;
3232const FrameIndex = bits.FrameIndex;
3333
34const InnerError = codegen.CodeGenError || error{OutOfRegisters};
34const InnerError = codegen.Error || error{OutOfRegisters};
3535
3636pub fn legalizeFeatures(_: *const std.Target) *const Air.Legalize.Features {
3737 return comptime &.initMany(&.{
......@@ -106,7 +106,6 @@ va_info: union {
106106ret_mcv: InstTracking,
107107err_ret_trace_reg: Register,
108108fn_type: Type,
109src_loc: Zcu.LazySrcLoc,
110109
111110eflags_inst: ?Air.Inst.Index = null,
112111
......@@ -869,11 +868,10 @@ const CodeGen = @This();
869868pub fn generate(
870869 bin_file: *link.File,
871870 pt: Zcu.PerThread,
872 src_loc: Zcu.LazySrcLoc,
873871 func_index: InternPool.Index,
874872 air: *const Air,
875873 liveness: *const ?Air.Liveness,
876) codegen.CodeGenError!Mir {
874) codegen.Error!Mir {
877875 _ = bin_file;
878876 const zcu = pt.zcu;
879877 const gpa = zcu.gpa;
......@@ -898,7 +896,6 @@ pub fn generate(
898896 .ret_mcv = undefined, // populated after `resolveCallingConventionValues`
899897 .err_ret_trace_reg = undefined, // populated after `resolveCallingConventionValues`
900898 .fn_type = fn_type,
901 .src_loc = src_loc,
902899 };
903900 defer {
904901 function.frame_allocs.deinit(gpa);
......@@ -937,10 +934,7 @@ pub fn generate(
937934 );
938935
939936 const fn_info = zcu.typeToFunc(fn_type).?;
940 var call_info = function.resolveCallingConventionValues(fn_info, &.{}, .args_frame) catch |err| switch (err) {
941 error.CodegenFail => |e| return e,
942 else => |e| return e,
943 };
937 var call_info = try function.resolveCallingConventionValues(fn_info, &.{}, .args_frame);
944938 defer call_info.deinit(&function);
945939
946940 function.args = call_info.args;
......@@ -983,7 +977,6 @@ pub fn generate(
983977 }
984978
985979 function.gen(&file.zir.?, func_zir.inst, func.comptime_args, call_info.air_arg_count) catch |err| switch (err) {
986 error.CodegenFail => |e| return e,
987980 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
988981 else => |e| return e,
989982 };
......@@ -1027,12 +1020,11 @@ pub fn getTmpMir(cg: *CodeGen) Mir {
10271020pub fn generateLazy(
10281021 bin_file: *link.File,
10291022 pt: Zcu.PerThread,
1030 src_loc: Zcu.LazySrcLoc,
10311023 lazy_sym: link.File.LazySymbol,
10321024 atom_id: link.File.AtomId,
10331025 w: *std.Io.Writer,
10341026 debug_output: link.File.DebugInfoOutput,
1035) codegen.CodeGenError!void {
1027) codegen.Error!void {
10361028 const gpa = pt.zcu.gpa;
10371029 // This function is for generating global code, so we use the root module.
10381030 const mod = pt.zcu.comp.root_mod;
......@@ -1050,7 +1042,6 @@ pub fn generateLazy(
10501042 .ret_mcv = undefined,
10511043 .err_ret_trace_reg = undefined,
10521044 .fn_type = undefined,
1053 .src_loc = src_loc,
10541045 };
10551046 defer {
10561047 function.inst_tracking.deinit(gpa);
......@@ -1068,12 +1059,11 @@ pub fn generateLazy(
10681059 }
10691060
10701061 function.genLazy(lazy_sym) catch |err| switch (err) {
1071 error.CodegenFail => |e| return e,
10721062 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
10731063 else => |e| return e,
10741064 };
10751065
1076 try function.getTmpMir().emitLazy(bin_file, pt, src_loc, lazy_sym, atom_id, w, debug_output);
1066 try function.getTmpMir().emitLazy(bin_file, pt, lazy_sym, atom_id, w, debug_output);
10771067}
10781068
10791069const FormatNavData = struct {
......@@ -1111,7 +1101,10 @@ fn formatWipMir(data: FormatWipMirData, w: *Writer) Writer.Error!void {
11111101 .allocator = data.self.gpa,
11121102 .mir = data.self.getTmpMir(),
11131103 .cc = .auto,
1114 .src_loc = data.self.src_loc,
1104 .src_loc = switch (data.self.owner) {
1105 .nav_index => |nav| data.self.pt.zcu.navSrcLoc(nav),
1106 .lazy_sym => |lazy_sym| Type.fromInterned(lazy_sym.ty).srcLocOrNull(data.self.pt.zcu) orelse .unneeded,
1107 },
11151108 };
11161109 var first = true;
11171110 for ((lower.lowerMir(data.inst) catch |err| switch (err) {
......@@ -181508,7 +181501,7 @@ fn resolveCallingConventionValues(
181508181501 return result;
181509181502}
181510181503
181511fn fail(cg: *CodeGen, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
181504fn fail(cg: *CodeGen, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } {
181512181505 @branchHint(.cold);
181513181506 const zcu = cg.pt.zcu;
181514181507 return switch (cg.owner) {
src/codegen/x86_64/Emit.zig+13-57
......@@ -17,6 +17,7 @@ relocs: std.ArrayList(Reloc),
1717table_relocs: std.ArrayList(TableReloc),
1818
1919pub const Error = Lower.Error || error{
20 AlreadyReported,
2021 EmitFail,
2122 NotFile,
2223} || std.posix.MMapError || std.posix.MRemapError || link.File.UpdateDebugInfoError;
......@@ -101,20 +102,11 @@ pub fn emitMir(emit: *Emit) Error!void {
101102 .inst => |inst| .{ .inst = inst },
102103 .table => .table,
103104 .nav => |nav| {
104 const symbol_id = switch (try codegen.genNavRef(
105 const symbol_id = try codegen.genNavRef(
105106 emit.bin_file,
106107 emit.pt,
107 emit.lower.src_loc,
108108 nav,
109 emit.lower.target,
110 )) {
111 .sym_index => |symbol_id| symbol_id,
112 .fail => |em| {
113 assert(emit.lower.err_msg == null);
114 emit.lower.err_msg = em;
115 return error.EmitFail;
116 },
117 };
109 );
118110 const target_symbol: RelocInfo.Target.Symbol = if (ip.getNav(nav).getExtern(ip)) |@"extern"| .{
119111 .symbol = symbol_id,
120112 .is_extern = switch (@"extern".visibility) {
......@@ -133,19 +125,11 @@ pub fn emitMir(emit: *Emit) Error!void {
133125 }
134126 },
135127 .uav => |uav| .{ .symbol = .{
136 .symbol = switch (try emit.bin_file.lowerUav(
128 .symbol = try emit.bin_file.lowerUav(
137129 emit.pt,
138130 uav.val,
139131 Type.fromInterned(uav.orig_ty).ptrAlignment(emit.pt.zcu),
140 emit.lower.src_loc,
141 )) {
142 .sym_index => |symbol_id| symbol_id,
143 .fail => |em| {
144 assert(emit.lower.err_msg == null);
145 emit.lower.err_msg = em;
146 return error.EmitFail;
147 },
148 },
132 ),
149133 .is_extern = false,
150134 } },
151135 .lazy_sym => |lazy_sym| .{ .symbol = .{
......@@ -168,17 +152,14 @@ pub fn emitMir(emit: *Emit) Error!void {
168152 .extern_func => |extern_func| .{ .symbol = .{
169153 .symbol = if (emit.bin_file.cast(.elf)) |elf_file|
170154 @enumFromInt(try elf_file.getGlobalSymbol(extern_func.toSlice(&emit.lower.mir).?, null))
171 else if (emit.bin_file.cast(.elf2)) |elf| elf.externSymbol(.{
155 else if (emit.bin_file.cast(.elf2)) |elf| try elf.externSymbol(.{
172156 .name = extern_func.toSlice(&emit.lower.mir).?,
173157 .lib_name = switch (comp.compiler_rt_strat) {
174158 .none, .lib, .obj, .zcu => null,
175159 .dyn_lib => "compiler_rt",
176160 },
177161 .type = .FUNC,
178 }) catch |err| switch (err) {
179 error.LinkOnceUnsupported => unreachable,
180 else => |e| return e,
181 } else if (emit.bin_file.cast(.macho)) |macho_file|
162 }) else if (emit.bin_file.cast(.macho)) |macho_file|
182163 @enumFromInt(try macho_file.getGlobalSymbol(extern_func.toSlice(&emit.lower.mir).?, null))
183164 else if (emit.bin_file.cast(.coff2)) |coff| @enumFromInt(@intFromEnum(try coff.globalSymbol(
184165 extern_func.toSlice(&emit.lower.mir).?,
......@@ -313,14 +294,11 @@ pub fn emitMir(emit: *Emit) Error!void {
313294 .symbol = if (emit.bin_file.cast(.elf)) |elf_file| @enumFromInt(try elf_file.getGlobalSymbol(
314295 "__tls_get_addr",
315296 if (comp.config.link_libc) "c" else null,
316 )) else if (emit.bin_file.cast(.elf2)) |elf| elf.externSymbol(.{
297 )) else if (emit.bin_file.cast(.elf2)) |elf| try elf.externSymbol(.{
317298 .name = "__tls_get_addr",
318299 .lib_name = if (comp.config.link_libc) "c" else null,
319300 .type = .FUNC,
320 }) catch |err| switch (err) {
321 error.LinkOnceUnsupported => unreachable,
322 else => |e| return e,
323 } else unreachable,
301 }) else unreachable,
324302 .is_extern = true,
325303 } },
326304 }});
......@@ -584,37 +562,16 @@ pub fn emitMir(emit: *Emit) Error!void {
584562 .none => .{ .constu = 0 },
585563 .reg => |reg| .{ .breg = reg.dwarfNum() },
586564 .frame, .table, .rip_inst => unreachable,
587 .nav => |nav| .{ .addr_reloc = switch (codegen.genNavRef(
565 .nav => |nav| .{ .addr_reloc = try codegen.genNavRef(
588566 emit.bin_file,
589567 emit.pt,
590 emit.lower.src_loc,
591568 nav,
592 emit.lower.target,
593 ) catch |err| switch (err) {
594 error.CodegenFail,
595 => return emit.fail("unable to codegen: {s}", .{@errorName(err)}),
596 else => |e| return e,
597 }) {
598 .sym_index => |sym_index| sym_index,
599 .fail => |em| {
600 assert(emit.lower.err_msg == null);
601 emit.lower.err_msg = em;
602 return error.EmitFail;
603 },
604 } },
605 .uav => |uav| .{ .addr_reloc = switch (try emit.bin_file.lowerUav(
569 ) },
570 .uav => |uav| .{ .addr_reloc = try emit.bin_file.lowerUav(
606571 emit.pt,
607572 uav.val,
608573 Type.fromInterned(uav.orig_ty).ptrAlignment(emit.pt.zcu),
609 emit.lower.src_loc,
610 )) {
611 .sym_index => |sym_index| sym_index,
612 .fail => |em| {
613 assert(emit.lower.err_msg == null);
614 emit.lower.err_msg = em;
615 return error.EmitFail;
616 },
617 } },
574 ) },
618575 .lazy_sym, .extern_func => unreachable,
619576 };
620577 break :base &loc_buf[0];
......@@ -666,7 +623,6 @@ pub fn emitMir(emit: *Emit) Error!void {
666623 const local = &emit.lower.mir.locals[local_index];
667624 local_index += 1;
668625 try dwarf.genLocalConstDebugInfo(
669 emit.lower.src_loc,
670626 switch (mir_inst.ops) {
671627 else => unreachable,
672628 .pseudo_dbg_arg_val => .comptime_arg,
src/codegen/x86_64/Lower.zig+2-2
......@@ -49,8 +49,8 @@ pub const Error = error{
4949 LowerFail,
5050 InvalidInstruction,
5151 CannotEncode,
52 CodegenFail,
53} || codegen.GenerateSymbolError;
52 AlreadyReported,
53} || link.Error;
5454
5555pub const Reloc = struct {
5656 lowered_inst_index: ResultInstIndex,
src/codegen/x86_64/Mir.zig+4-6
......@@ -1974,12 +1974,11 @@ pub fn emit(
19741974 mir: Mir,
19751975 lf: *link.File,
19761976 pt: Zcu.PerThread,
1977 src_loc: Zcu.LazySrcLoc,
19781977 func_index: InternPool.Index,
19791978 atom_id: link.File.AtomId,
19801979 w: *std.Io.Writer,
19811980 debug_output: link.File.DebugInfoOutput,
1982) codegen.CodeGenError!void {
1981) codegen.Error!void {
19831982 const zcu = pt.zcu;
19841983 const comp = zcu.comp;
19851984 const gpa = comp.gpa;
......@@ -1993,7 +1992,7 @@ pub fn emit(
19931992 .allocator = gpa,
19941993 .mir = mir,
19951994 .cc = fn_info.cc,
1996 .src_loc = src_loc,
1995 .src_loc = zcu.navSrcLoc(nav),
19971996 },
19981997 .bin_file = lf,
19991998 .pt = pt,
......@@ -2028,12 +2027,11 @@ pub fn emitLazy(
20282027 mir: Mir,
20292028 lf: *link.File,
20302029 pt: Zcu.PerThread,
2031 src_loc: Zcu.LazySrcLoc,
20322030 lazy_sym: link.File.LazySymbol,
20332031 atom_id: link.File.AtomId,
20342032 w: *std.Io.Writer,
20352033 debug_output: link.File.DebugInfoOutput,
2036) codegen.CodeGenError!void {
2034) codegen.Error!void {
20372035 const zcu = pt.zcu;
20382036 const comp = zcu.comp;
20392037 const gpa = comp.gpa;
......@@ -2044,7 +2042,7 @@ pub fn emitLazy(
20442042 .allocator = gpa,
20452043 .mir = mir,
20462044 .cc = .auto,
2047 .src_loc = src_loc,
2045 .src_loc = Zcu.Type.fromInterned(lazy_sym.ty).srcLocOrNull(zcu) orelse .unneeded,
20482046 },
20492047 .bin_file = lf,
20502048 .pt = pt,
src/link.zig+57-90
......@@ -31,6 +31,12 @@ pub const LdScript = @import("link/LdScript.zig");
3131pub const Queue = @import("link/Queue.zig");
3232pub const ConstPool = @import("link/ConstPool.zig");
3333
34pub const Error = Allocator.Error || Io.Cancelable || error{
35 /// An error message has already been stored in persistent state on `Compilation` or `Zcu`, for
36 /// instance in `Compilation.link_diags`.
37 AlreadyReported,
38};
39
3440pub const Diags = struct {
3541 /// Stored here so that function definitions can distinguish between
3642 /// needing an allocator for things besides error reporting.
......@@ -112,7 +118,7 @@ pub const Diags = struct {
112118 err: ErrorWithNotes,
113119 comptime format: []const u8,
114120 args: anytype,
115 ) error{OutOfMemory}!void {
121 ) Allocator.Error!void {
116122 const gpa = err.diags.gpa;
117123 const err_msg = &err.diags.msgs.items[err.index];
118124 err_msg.msg = try std.fmt.allocPrint(gpa, format, args);
......@@ -212,16 +218,16 @@ pub const Diags = struct {
212218 }
213219 }
214220
215 pub fn fail(diags: *Diags, comptime format: []const u8, args: anytype) error{LinkFailure} {
221 pub fn fail(diags: *Diags, comptime format: []const u8, args: anytype) error{AlreadyReported} {
216222 @branchHint(.cold);
217223 addError(diags, format, args);
218 return error.LinkFailure;
224 return error.AlreadyReported;
219225 }
220226
221 pub fn failSourceLocation(diags: *Diags, sl: SourceLocation, comptime format: []const u8, args: anytype) error{LinkFailure} {
227 pub fn failSourceLocation(diags: *Diags, sl: SourceLocation, comptime format: []const u8, args: anytype) error{AlreadyReported} {
222228 @branchHint(.cold);
223229 addErrorSourceLocation(diags, sl, format, args);
224 return error.LinkFailure;
230 return error.AlreadyReported;
225231 }
226232
227233 pub fn addError(diags: *Diags, comptime format: []const u8, args: anytype) void {
......@@ -251,7 +257,7 @@ pub const Diags = struct {
251257 });
252258 }
253259
254 pub fn addErrorWithNotes(diags: *Diags, note_count: usize) error{OutOfMemory}!ErrorWithNotes {
260 pub fn addErrorWithNotes(diags: *Diags, note_count: usize) Allocator.Error!ErrorWithNotes {
255261 @branchHint(.cold);
256262 const gpa = diags.gpa;
257263 const io = diags.io;
......@@ -261,7 +267,7 @@ pub const Diags = struct {
261267 return addErrorWithNotesAssumeCapacity(diags, note_count);
262268 }
263269
264 pub fn addErrorWithNotesAssumeCapacity(diags: *Diags, note_count: usize) error{OutOfMemory}!ErrorWithNotes {
270 pub fn addErrorWithNotesAssumeCapacity(diags: *Diags, note_count: usize) Allocator.Error!ErrorWithNotes {
265271 @branchHint(.cold);
266272 const gpa = diags.gpa;
267273 const index = diags.msgs.items.len;
......@@ -351,10 +357,10 @@ pub const Diags = struct {
351357 path: Path,
352358 comptime format: []const u8,
353359 args: anytype,
354 ) error{LinkFailure} {
360 ) error{AlreadyReported} {
355361 @branchHint(.cold);
356362 addParseError(diags, path, format, args);
357 return error.LinkFailure;
363 return error.AlreadyReported;
358364 }
359365
360366 pub fn setAllocFailure(diags: *Diags) void {
......@@ -752,11 +758,6 @@ pub const File = struct {
752758 none,
753759 };
754760 pub const UpdateDebugInfoError = Dwarf.UpdateError;
755 pub const FlushDebugInfoError = Dwarf.FlushError;
756
757 /// Note that `LinkFailure` is not a member of this error set because the error message
758 /// must be attached to `Zcu.failed_codegen` rather than `Compilation.link_diags`.
759 pub const UpdateNavError = codegen.CodeGenError;
760761
761762 /// Opaque identifier for a function currently being emitted.
762763 ///
......@@ -775,7 +776,7 @@ pub const File = struct {
775776 /// be created. This symbol may get resolved once all relocatables are (re-)linked.
776777 /// Optionally, it is possible to specify where to expect the symbol defined if it
777778 /// is an import.
778 pub fn getGlobalSymbol(base: *File, name: []const u8, lib_name: ?[]const u8) UpdateNavError!SymbolId {
779 pub fn getGlobalSymbol(base: *File, name: []const u8, lib_name: ?[]const u8) Error!SymbolId {
779780 log.debug("getGlobalSymbol '{s}' (expected in '{?s}')", .{ name, lib_name });
780781 switch (base.tag) {
781782 .lld => unreachable,
......@@ -790,7 +791,7 @@ pub const File = struct {
790791
791792 /// May be called before or after updateExports for any given Nav.
792793 /// Asserts that the ZCU is not using the LLVM backend.
793 fn updateNav(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) UpdateNavError!void {
794 fn updateNav(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) Error!void {
794795 assert(base.comp.zcu.?.llvm_object == null);
795796 const nav = pt.zcu.intern_pool.getNav(nav_index);
796797 assert(nav.resolved.?.value != .none);
......@@ -804,14 +805,8 @@ pub const File = struct {
804805 }
805806 }
806807
807 pub const UpdateContainerTypeError = error{
808 OutOfMemory,
809 /// `Zcu.failed_types` is already populated with the error message.
810 TypeFailureReported,
811 };
812
813808 /// Never called when LLVM is codegenning the ZCU.
814 fn updateContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index, success: bool) UpdateContainerTypeError!void {
809 fn updateContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index, success: bool) Error!void {
815810 assert(base.comp.zcu.?.llvm_object == null);
816811 switch (base.tag) {
817812 .lld => unreachable,
......@@ -824,7 +819,7 @@ pub const File = struct {
824819 }
825820
826821 /// Never called when LLVM is codegenning the ZCU.
827 fn clearContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index) UpdateContainerTypeError!void {
822 fn clearContainerType(base: *File, pt: Zcu.PerThread, ty: InternPool.Index) Error!void {
828823 assert(base.comp.zcu.?.llvm_object == null);
829824 switch (base.tag) {
830825 .lld => unreachable,
......@@ -847,7 +842,7 @@ pub const File = struct {
847842 /// that `mir.deinit` remains legal for the caller. For instance, the callee can
848843 /// take ownership of an embedded slice and replace it with `&.{}` in `mir`.
849844 mir: *codegen.AnyMir,
850 ) UpdateNavError!void {
845 ) Error!void {
851846 assert(base.comp.zcu.?.llvm_object == null);
852847 switch (base.tag) {
853848 .lld => unreachable,
......@@ -860,16 +855,10 @@ pub const File = struct {
860855 }
861856 }
862857
863 pub const UpdateLineNumberError = error{
864 OutOfMemory,
865 Overflow,
866 LinkFailure,
867 };
868
869858 /// On an incremental update, fixup the line number of all `Nav`s at the given `TrackedInst`, because
870859 /// its line number has changed. The ZIR instruction `ti_id` has tag `.declaration`.
871860 /// Never called when LLVM is codegenning the ZCU.
872 fn updateLineNumber(base: *File, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) UpdateLineNumberError!void {
861 fn updateLineNumber(base: *File, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) Error!void {
873862 assert(base.comp.zcu.?.llvm_object == null);
874863 {
875864 const ti = ti_id.resolveFull(&pt.zcu.intern_pool).?;
......@@ -918,7 +907,7 @@ pub const File = struct {
918907 }
919908 }
920909
921 pub fn idle(base: *File, tid: Zcu.PerThread.Id) !bool {
910 pub fn idle(base: *File, tid: Zcu.PerThread.Id) Error!bool {
922911 switch (base.tag) {
923912 else => return false,
924913 inline .elf2, .coff2 => |tag| {
......@@ -928,7 +917,7 @@ pub const File = struct {
928917 }
929918 }
930919
931 pub fn updateErrorData(base: *File, pt: Zcu.PerThread) !void {
920 pub fn updateErrorData(base: *File, pt: Zcu.PerThread) Error!void {
932921 switch (base.tag) {
933922 else => {},
934923 inline .elf2, .coff2 => |tag| {
......@@ -938,14 +927,9 @@ pub const File = struct {
938927 }
939928 }
940929
941 pub const FlushError = Io.Cancelable || Allocator.Error || error{
942 /// Indicates an error will be present in `Compilation.link_diags`.
943 LinkFailure,
944 };
945
946930 /// Commit pending changes and write headers. Takes into account final output mode.
947931 /// `arena` has the lifetime of the call to `Compilation.update`.
948 pub fn flush(base: *File, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) FlushError!void {
932 pub fn flush(base: *File, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) Error!void {
949933 const comp = base.comp;
950934 const io = comp.io;
951935 if (comp.clang_preprocessor_mode == .yes or comp.clang_preprocessor_mode == .pch) {
......@@ -985,11 +969,6 @@ pub const File = struct {
985969 }
986970 }
987971
988 pub const UpdateExportsError = error{
989 OutOfMemory,
990 AnalysisFail,
991 };
992
993972 /// This is called for every exported thing. `exports` is almost always
994973 /// a list of size 1, meaning that `exported` is exported once. However, it is possible
995974 /// to export the same thing with multiple different symbol names (aliases).
......@@ -1000,7 +979,7 @@ pub const File = struct {
1000979 pt: Zcu.PerThread,
1001980 exported: Zcu.Exported,
1002981 export_indices: []const Zcu.Export.Index,
1003 ) UpdateExportsError!void {
982 ) Error!void {
1004983 assert(base.comp.zcu.?.llvm_object == null);
1005984 switch (base.tag) {
1006985 .lld => unreachable,
......@@ -1031,7 +1010,7 @@ pub const File = struct {
10311010 /// May be called before or after updateFunc/updateNav therefore it is up to the linker to allocate
10321011 /// the block/atom.
10331012 /// Never called when LLVM is codegenning the ZCU.
1034 pub fn getNavVAddr(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: RelocInfo) !u64 {
1013 pub fn getNavVAddr(base: *File, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index, reloc_info: RelocInfo) Error!u64 {
10351014 assert(base.comp.zcu.?.llvm_object == null);
10361015 switch (base.tag) {
10371016 .lld => unreachable,
......@@ -1052,8 +1031,7 @@ pub const File = struct {
10521031 pt: Zcu.PerThread,
10531032 decl_val: InternPool.Index,
10541033 decl_align: InternPool.Alignment,
1055 src_loc: Zcu.LazySrcLoc,
1056 ) !codegen.SymbolResult {
1034 ) Error!SymbolId {
10571035 assert(base.comp.zcu.?.llvm_object == null);
10581036 switch (base.tag) {
10591037 .lld => unreachable,
......@@ -1063,13 +1041,13 @@ pub const File = struct {
10631041 .plan9 => unreachable,
10641042 inline else => |tag| {
10651043 dev.check(tag.devFeature());
1066 return @as(*tag.Type(), @fieldParentPtr("base", base)).lowerUav(pt, decl_val, decl_align, src_loc);
1044 return @as(*tag.Type(), @fieldParentPtr("base", base)).lowerUav(pt, decl_val, decl_align);
10671045 },
10681046 }
10691047 }
10701048
10711049 /// Never called when LLVM is codegenning the ZCU.
1072 pub fn getUavVAddr(base: *File, decl_val: InternPool.Index, reloc_info: RelocInfo) !u64 {
1050 pub fn getUavVAddr(base: *File, decl_val: InternPool.Index, reloc_info: RelocInfo) Error!u64 {
10731051 assert(base.comp.zcu.?.llvm_object == null);
10741052 switch (base.tag) {
10751053 .lld => unreachable,
......@@ -1217,7 +1195,7 @@ pub const File = struct {
12171195
12181196 /// Called when all linker inputs have been sent via `loadInput`. After
12191197 /// this, `loadInput` will not be called anymore.
1220 pub fn prelink(base: *File) FlushError!void {
1198 pub fn prelink(base: *File) Error!void {
12211199 assert(!base.post_prelink);
12221200
12231201 // In this case, an object file is created by the LLVM backend, so
......@@ -1251,7 +1229,11 @@ pub const File = struct {
12511229 file_writer.pos = new_offset;
12521230 const size_u = std.math.cast(usize, size) orelse return error.Overflow;
12531231 const n = file_writer.interface.sendFileAll(&file_reader, .limited(size_u)) catch |err| switch (err) {
1254 error.ReadFailed => return file_reader.err.?,
1232 error.ReadFailed => switch (file_reader.err.?) {
1233 error.ConnectionResetByPeer => return error.Unexpected, // not a socket
1234 error.SocketUnconnected => return error.Unexpected, // not a socket
1235 else => |e| return e,
1236 },
12551237 error.WriteFailed => return file_writer.err.?,
12561238 };
12571239 assert(n == size_u);
......@@ -1367,7 +1349,7 @@ pub const File = struct {
13671349 nav_index: InternPool.Nav.Index,
13681350 comptime format: []const u8,
13691351 args: anytype,
1370 ) error{ CodegenFail, OutOfMemory } {
1352 ) Zcu.CodegenFailError {
13711353 @branchHint(.cold);
13721354 return base.comp.zcu.?.codegenFail(nav_index, format, args);
13731355 }
......@@ -1440,7 +1422,7 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void {
14401422 defer prog_node.end();
14411423 for (comp.link_inputs) |input| {
14421424 base.loadInput(input) catch |err| switch (err) {
1443 error.LinkFailure => return, // error reported via diags
1425 error.AlreadyReported => return, // error reported via diags
14441426 else => |e| switch (input) {
14451427 .dso => |dso| diags.addParseError(dso.path, "failed to parse shared library: {s}", .{@errorName(e)}),
14461428 .object => |obj| diags.addParseError(obj.path, "failed to parse object: {s}", .{@errorName(e)}),
......@@ -1485,11 +1467,11 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void {
14851467 .preferred_mode = .dynamic,
14861468 .search_strategy = .paths_first,
14871469 }) catch |archive_err| switch (archive_err) {
1488 error.LinkFailure => return, // error reported via diags
1470 error.AlreadyReported => return, // error reported via diags
14891471 else => |e| diags.addParseError(dso_path, "failed to parse archive {f}: {s}", .{ archive_path, @errorName(e) }),
14901472 };
14911473 },
1492 error.LinkFailure => return, // error reported via diags
1474 error.AlreadyReported => return, // error reported via diags
14931475 else => |e| diags.addParseError(dso_path, "failed to parse shared library: {s}", .{@errorName(e)}),
14941476 };
14951477 },
......@@ -1504,7 +1486,7 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void {
15041486 .preferred_mode = .static,
15051487 .search_strategy = .no_fallback,
15061488 }) catch |err| switch (err) {
1507 error.LinkFailure => return, // error reported via diags
1489 error.AlreadyReported => return, // error reported via diags
15081490 else => |e| diags.addParseError(path, "failed to parse archive: {s}", .{@errorName(e)}),
15091491 };
15101492 },
......@@ -1515,7 +1497,7 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void {
15151497 const prog_node = comp.link_prog_node.start("Parse Object", 0);
15161498 defer prog_node.end();
15171499 base.openLoadObject(path) catch |err| switch (err) {
1518 error.LinkFailure => return, // error reported via diags
1500 error.AlreadyReported => return, // error reported via diags
15191501 else => |e| diags.addParseError(path, "failed to parse object: {s}", .{@errorName(e)}),
15201502 };
15211503 },
......@@ -1523,7 +1505,7 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void {
15231505 const prog_node = comp.link_prog_node.start("Parse Archive", 0);
15241506 defer prog_node.end();
15251507 base.openLoadArchive(load_archive.path, load_archive.must_link) catch |err| switch (err) {
1526 error.LinkFailure => return, // error reported via link_diags
1508 error.AlreadyReported => return, // error reported via link_diags
15271509 else => |e| diags.addParseError(load_archive.path, "failed to parse archive: {s}", .{@errorName(e)}),
15281510 };
15291511 },
......@@ -1534,7 +1516,7 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void {
15341516 .preferred_mode = .dynamic,
15351517 .search_strategy = .paths_first,
15361518 }) catch |err| switch (err) {
1537 error.LinkFailure => return, // error reported via link_diags
1519 error.AlreadyReported => return, // error reported via link_diags
15381520 else => |e| diags.addParseError(path, "failed to parse shared library: {s}", .{@errorName(e)}),
15391521 };
15401522 },
......@@ -1561,15 +1543,9 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void
15611543 };
15621544 } else if (comp.bin_file) |lf| {
15631545 lf.updateNav(pt, nav_index) catch |err| switch (err) {
1546 error.Canceled => io.recancel(),
1547 error.AlreadyReported => return,
15641548 error.OutOfMemory => diags.setAllocFailure(),
1565 error.CodegenFail => zcu.assertCodegenFailed(nav_index),
1566 error.Overflow, error.RelocationNotByteAligned => {
1567 switch (zcu.codegenFail(nav_index, "unable to codegen: {s}", .{@errorName(err)})) {
1568 error.CodegenFail => return,
1569 error.OutOfMemory => return diags.setAllocFailure(),
1570 }
1571 // Not a retryable failure.
1572 },
15731549 };
15741550 }
15751551 break :nav nav_index;
......@@ -1594,14 +1570,9 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void
15941570 assert(zcu.llvm_object == null); // LLVM codegen doesn't produce MIR
15951571 if (comp.bin_file) |lf| {
15961572 lf.updateFunc(pt, func, &mir) catch |err| switch (err) {
1573 error.Canceled => io.recancel(),
1574 error.AlreadyReported => return,
15971575 error.OutOfMemory => return diags.setAllocFailure(),
1598 error.CodegenFail => return zcu.assertCodegenFailed(nav),
1599 error.Overflow, error.RelocationNotByteAligned => {
1600 switch (zcu.codegenFail(nav, "unable to codegen: {s}", .{@errorName(err)})) {
1601 error.OutOfMemory => return diags.setAllocFailure(),
1602 error.CodegenFail => return,
1603 }
1604 },
16051576 };
16061577 }
16071578 break :nav ip.indexToKey(func).func.owner_nav;
......@@ -1618,7 +1589,8 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void
16181589 if (comp.bin_file) |lf| {
16191590 lf.updateContainerType(pt, container_update.ty, container_update.success) catch |err| switch (err) {
16201591 error.OutOfMemory => diags.setAllocFailure(),
1621 error.TypeFailureReported => assert(zcu.failed_types.contains(container_update.ty)),
1592 error.Canceled => io.recancel(),
1593 error.AlreadyReported => {},
16221594 };
16231595 }
16241596 }
......@@ -1657,7 +1629,7 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void
16571629 }
16581630 }
16591631}
1660pub fn doIdleTask(comp: *Compilation, tid: Zcu.PerThread.Id) error{ OutOfMemory, LinkFailure }!bool {
1632pub fn doIdleTask(comp: *Compilation, tid: Zcu.PerThread.Id) Error!bool {
16611633 return if (comp.bin_file) |lf| lf.idle(tid) else false;
16621634}
16631635/// After the main pipeline is done, but before flush, the compilation may need to link one final
......@@ -1673,15 +1645,9 @@ pub fn linkTestFunctionsNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index)
16731645 };
16741646 } else if (comp.bin_file) |lf| {
16751647 lf.updateNav(pt, nav_index) catch |err| switch (err) {
1648 error.Canceled => comp.io.recancel(),
1649 error.AlreadyReported => return,
16761650 error.OutOfMemory => diags.setAllocFailure(),
1677 error.CodegenFail => zcu.assertCodegenFailed(nav_index),
1678 error.Overflow, error.RelocationNotByteAligned => {
1679 switch (zcu.codegenFail(nav_index, "unable to codegen: {s}", .{@errorName(err)})) {
1680 error.CodegenFail => return,
1681 error.OutOfMemory => return diags.setAllocFailure(),
1682 }
1683 // Not a retryable failure.
1684 },
16851651 };
16861652 }
16871653}
......@@ -1689,7 +1655,8 @@ pub fn updateErrorData(pt: Zcu.PerThread) void {
16891655 const comp = pt.zcu.comp;
16901656 if (comp.bin_file) |lf| lf.updateErrorData(pt) catch |err| switch (err) {
16911657 error.OutOfMemory => comp.link_diags.setAllocFailure(),
1692 error.LinkFailure => {},
1658 error.Canceled => comp.io.recancel(),
1659 error.AlreadyReported => {},
16931660 };
16941661}
16951662
......@@ -2428,19 +2395,19 @@ pub fn openDso(io: Io, path: Path, needed: bool, weak: bool, reexport: bool) !In
24282395 };
24292396}
24302397
2431pub fn openObjectInput(io: Io, diags: *Diags, path: Path) error{LinkFailure}!Input {
2398pub fn openObjectInput(io: Io, diags: *Diags, path: Path) error{AlreadyReported}!Input {
24322399 return .{ .object = openObject(io, path, false, false) catch |err| {
24332400 return diags.failParse(path, "failed to open {f}: {s}", .{ path, @errorName(err) });
24342401 } };
24352402}
24362403
2437pub fn openArchiveInput(io: Io, diags: *Diags, path: Path, must_link: bool, hidden: bool) error{LinkFailure}!Input {
2404pub fn openArchiveInput(io: Io, diags: *Diags, path: Path, must_link: bool, hidden: bool) error{AlreadyReported}!Input {
24382405 return .{ .archive = openObject(io, path, must_link, hidden) catch |err| {
24392406 return diags.failParse(path, "failed to open {f}: {s}", .{ path, @errorName(err) });
24402407 } };
24412408}
24422409
2443pub fn openDsoInput(io: Io, diags: *Diags, path: Path, needed: bool, weak: bool, reexport: bool) error{LinkFailure}!Input {
2410pub fn openDsoInput(io: Io, diags: *Diags, path: Path, needed: bool, weak: bool, reexport: bool) error{AlreadyReported}!Input {
24442411 return .{ .dso = openDso(io, path, needed, weak, reexport) catch |err| {
24452412 return diags.failParse(path, "failed to open {f}: {s}", .{ path, @errorName(err) });
24462413 } };
src/link/C.zig+8-22
......@@ -474,7 +474,7 @@ pub fn updateContainerType(
474474 pt: Zcu.PerThread,
475475 ty: InternPool.Index,
476476 success: bool,
477) link.File.UpdateContainerTypeError!void {
477) link.Error!void {
478478 try c.type_pool.updateContainerType(pt, .{ .c = c }, ty, success);
479479}
480480
......@@ -570,7 +570,6 @@ pub fn updateNav(
570570 .arena = arena.allocator(),
571571 .pt = pt,
572572 .mod = zcu.navFileScope(nav_index).mod.?,
573 .error_msg = null,
574573 .owner_nav = nav_index.toOptional(),
575574 .is_naked_fn = false,
576575 .expected_block = null,
......@@ -588,10 +587,7 @@ pub fn updateNav(
588587 defer c.string_bytes = aw.toArrayList();
589588 const start = aw.written().len;
590589 codegen.genDeclFwd(&dg, &aw.writer) catch |err| switch (err) {
591 error.AnalysisFail => switch (zcu.codegenFailMsg(nav_index, dg.error_msg.?)) {
592 error.CodegenFail => return,
593 error.OutOfMemory => |e| return e,
594 },
590 error.AlreadyReported => return,
595591 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,
596592 };
597593 break :fwd_decl .{
......@@ -605,10 +601,7 @@ pub fn updateNav(
605601 defer c.string_bytes = aw.toArrayList();
606602 const start = aw.written().len;
607603 codegen.genDecl(&dg, &aw.writer) catch |err| switch (err) {
608 error.AnalysisFail => switch (zcu.codegenFailMsg(nav_index, dg.error_msg.?)) {
609 error.CodegenFail => return,
610 error.OutOfMemory => |e| return e,
611 },
604 error.AlreadyReported => return,
612605 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,
613606 };
614607 break :code .{
......@@ -661,7 +654,6 @@ fn updateUav(
661654 .arena = arena.allocator(),
662655 .pt = pt,
663656 .mod = pt.zcu.root_mod,
664 .error_msg = null,
665657 .owner_nav = .none,
666658 .is_naked_fn = false,
667659 .expected_block = null,
......@@ -683,9 +675,7 @@ fn updateUav(
683675 .@"threadlocal" = false,
684676 .init_val = val,
685677 }) catch |err| switch (err) {
686 error.AnalysisFail => {
687 @panic("TODO: CBE error.AnalysisFail on uav");
688 },
678 error.AlreadyReported => return,
689679 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,
690680 };
691681 break :fwd_decl .{
......@@ -704,9 +694,7 @@ fn updateUav(
704694 .@"threadlocal" = false,
705695 .init_val = val,
706696 }) catch |err| switch (err) {
707 error.AnalysisFail => {
708 @panic("TODO: CBE error.AnalysisFail on uav");
709 },
697 error.AlreadyReported => return,
710698 error.WriteFailed, error.OutOfMemory => return error.OutOfMemory,
711699 };
712700 break :code .{
......@@ -726,7 +714,7 @@ pub fn updateLineNumber(c: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.
726714 _ = ti_id;
727715}
728716
729pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
717pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.Error!void {
730718 const tracy = trace(@src());
731719 defer tracy.end();
732720
......@@ -1112,7 +1100,6 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
11121100 .owner_nav = .none,
11131101 .is_naked_fn = false,
11141102 .expected_block = null,
1115 .error_msg = null,
11161103 .ctype_deps = .empty,
11171104 .uavs = .empty,
11181105 };
......@@ -1156,14 +1143,14 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog
11561143 codegen.genLazyCallModifierFn(&lazy_dg, fn_nav, .never_tail, &lazy_decls_aw.writer) catch |err| switch (err) {
11571144 error.WriteFailed => return error.OutOfMemory,
11581145 error.OutOfMemory => |e| return e,
1159 error.AnalysisFail => unreachable,
1146 error.AlreadyReported => unreachable,
11601147 };
11611148 }
11621149 for (need_never_inline_funcs.keys()) |fn_nav| {
11631150 codegen.genLazyCallModifierFn(&lazy_dg, fn_nav, .never_inline, &lazy_decls_aw.writer) catch |err| switch (err) {
11641151 error.WriteFailed => return error.OutOfMemory,
11651152 error.OutOfMemory => |e| return e,
1166 error.AnalysisFail => unreachable,
1153 error.AlreadyReported => unreachable,
11671154 };
11681155 }
11691156 }
......@@ -1256,7 +1243,6 @@ pub fn updateExports(
12561243 .owner_nav = .none,
12571244 .is_naked_fn = false,
12581245 .expected_block = null,
1259 .error_msg = null,
12601246 .ctype_deps = .empty,
12611247 .uavs = .empty,
12621248 };
src/link/Coff.zig+31-60
......@@ -43,7 +43,6 @@ lazy: std.EnumArray(link.File.LazySymbol.Kind, struct {
4343}),
4444pending_uavs: std.AutoArrayHashMapUnmanaged(Node.UavMapIndex, struct {
4545 alignment: InternPool.Alignment,
46 src_loc: Zcu.LazySrcLoc,
4746}),
4847relocs: std.ArrayList(Reloc),
4948const_prog_node: std.Progress.Node,
......@@ -1532,11 +1531,8 @@ pub fn prelink(coff: *Coff, prog_node: std.Progress.Node) void {
15321531
15331532pub fn updateNav(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
15341533 coff.updateNavInner(pt, nav_index) catch |err| switch (err) {
1535 error.OutOfMemory,
1536 error.Overflow,
1537 error.RelocationNotByteAligned,
1538 => |e| return e,
1539 else => |e| return coff.base.cgFail(nav_index, "linker failed to update variable: {t}", .{e}),
1534 else => |e| return e,
1535 error.MappedFileIo => return coff.base.cgFail(nav_index, "linker failed to update variable: {t}", .{coff.mf.io_err.?}),
15401536 };
15411537}
15421538fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
......@@ -1579,12 +1575,11 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde
15791575 codegen.generateSymbol(
15801576 &coff.base,
15811577 pt,
1582 zcu.navSrcLoc(nav_index),
15831578 .fromInterned(nav.resolved.?.value),
15841579 &nw.interface,
15851580 .{ .atom_index = @enumFromInt(@intFromEnum(si)) },
15861581 ) catch |err| switch (err) {
1587 error.WriteFailed => return error.OutOfMemory,
1582 error.WriteFailed => return nw.err.?,
15881583 else => |e| return e,
15891584 };
15901585 si.get(coff).size = @intCast(nw.interface.end);
......@@ -1615,8 +1610,7 @@ pub fn lowerUav(
16151610 pt: Zcu.PerThread,
16161611 uav_val: InternPool.Index,
16171612 uav_align: InternPool.Alignment,
1618 src_loc: Zcu.LazySrcLoc,
1619) !codegen.SymbolResult {
1613) !link.File.SymbolId {
16201614 const zcu = pt.zcu;
16211615 const gpa = zcu.gpa;
16221616
......@@ -1633,12 +1627,11 @@ pub fn lowerUav(
16331627 } else {
16341628 gop.value_ptr.* = .{
16351629 .alignment = uav_align,
1636 .src_loc = src_loc,
16371630 };
16381631 coff.const_prog_node.increaseEstimatedTotalItems(1);
16391632 }
16401633 }
1641 return .{ .sym_index = @enumFromInt(@intFromEnum(si)) };
1634 return @enumFromInt(@intFromEnum(si));
16421635}
16431636
16441637pub fn updateFunc(
......@@ -1648,15 +1641,11 @@ pub fn updateFunc(
16481641 mir: *const codegen.AnyMir,
16491642) !void {
16501643 coff.updateFuncInner(pt, func_index, mir) catch |err| switch (err) {
1651 error.OutOfMemory,
1652 error.Overflow,
1653 error.RelocationNotByteAligned,
1654 error.CodegenFail,
1655 => |e| return e,
1656 else => |e| return coff.base.cgFail(
1644 else => |e| return e,
1645 error.MappedFileIo => return coff.base.cgFail(
16571646 pt.zcu.funcInfo(func_index).owner_nav,
1658 "linker failed to update function: {s}",
1659 .{@errorName(e)},
1647 "linker failed to update function: {t}",
1648 .{coff.mf.io_err.?},
16601649 ),
16611650 };
16621651}
......@@ -1714,7 +1703,6 @@ fn updateFuncInner(
17141703 codegen.emitFunction(
17151704 &coff.base,
17161705 pt,
1717 zcu.navSrcLoc(func.owner_nav),
17181706 func_index,
17191707 @enumFromInt(@intFromEnum(si)),
17201708 mir,
......@@ -1733,9 +1721,11 @@ pub fn updateErrorData(coff: *Coff, pt: Zcu.PerThread) !void {
17331721 .kind = .const_data,
17341722 .index = @intCast(coff.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return),
17351723 }) catch |err| switch (err) {
1736 error.OutOfMemory => |e| return e,
1737 error.CodegenFail => return error.LinkFailure,
1738 else => |e| return coff.base.comp.link_diags.fail("updateErrorData failed {t}", .{e}),
1724 else => |e| return e,
1725 error.MappedFileIo => return coff.base.comp.link_diags.fail(
1726 "updateErrorData failed: {t}",
1727 .{coff.mf.io_err.?},
1728 ),
17391729 };
17401730}
17411731
......@@ -1780,12 +1770,11 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool {
17801770 .{ .zcu = comp.zcu.?, .tid = tid },
17811771 pending_uav.key,
17821772 pending_uav.value.alignment,
1783 pending_uav.value.src_loc,
17841773 ) catch |err| switch (err) {
1785 error.OutOfMemory => |e| return e,
1786 else => |e| return comp.link_diags.fail(
1774 else => |e| return e,
1775 error.MappedFileIo => return comp.link_diags.fail(
17871776 "linker failed to lower constant: {t}",
1788 .{e},
1777 .{coff.mf.io_err.?},
17891778 ),
17901779 };
17911780 break :task;
......@@ -1800,10 +1789,10 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool {
18001789 );
18011790 defer sub_prog_node.end();
18021791 coff.flushGlobal(pt, gmi) catch |err| switch (err) {
1803 error.OutOfMemory => |e| return e,
1804 else => |e| return comp.link_diags.fail(
1792 else => |e| return e,
1793 error.MappedFileIo => return comp.link_diags.fail(
18051794 "linker failed to lower constant: {t}",
1806 .{e},
1795 .{coff.mf.io_err.?},
18071796 ),
18081797 };
18091798 break :task;
......@@ -1827,10 +1816,10 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool {
18271816 );
18281817 defer sub_prog_node.end();
18291818 coff.flushLazy(pt, lmr) catch |err| switch (err) {
1830 error.OutOfMemory => |e| return e,
1831 else => |e| return comp.link_diags.fail(
1819 else => |e| return e,
1820 error.MappedFileIo => return comp.link_diags.fail(
18321821 "linker failed to lower lazy {s}: {t}",
1833 .{ kind, e },
1822 .{ kind, coff.mf.io_err.? },
18341823 ),
18351824 };
18361825 break :task;
......@@ -1885,7 +1874,6 @@ fn flushUav(
18851874 pt: Zcu.PerThread,
18861875 umi: Node.UavMapIndex,
18871876 uav_align: InternPool.Alignment,
1888 src_loc: Zcu.LazySrcLoc,
18891877) !void {
18901878 const zcu = pt.zcu;
18911879 const gpa = zcu.gpa;
......@@ -1928,12 +1916,11 @@ fn flushUav(
19281916 codegen.generateSymbol(
19291917 &coff.base,
19301918 pt,
1931 src_loc,
19321919 .fromInterned(uav_val),
19331920 &nw.interface,
19341921 .{ .atom_index = @enumFromInt(@intFromEnum(si)) },
19351922 ) catch |err| switch (err) {
1936 error.WriteFailed => return error.OutOfMemory,
1923 error.WriteFailed => return nw.err.?,
19371924 else => |e| return e,
19381925 };
19391926 si.get(coff).size = @intCast(nw.interface.end);
......@@ -2139,16 +2126,18 @@ fn flushLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
21392126 var nw: MappedFile.Node.Writer = undefined;
21402127 ni.writer(&coff.mf, gpa, &nw);
21412128 defer nw.deinit();
2142 try codegen.generateLazySymbol(
2129 codegen.generateLazySymbol(
21432130 &coff.base,
21442131 pt,
2145 Type.fromInterned(lazy.ty).srcLocOrNull(pt.zcu) orelse .unneeded,
21462132 lazy,
21472133 &required_alignment,
21482134 &nw.interface,
21492135 .none,
21502136 .{ .atom_index = @enumFromInt(@intFromEnum(si)) },
2151 );
2137 ) catch |err| switch (err) {
2138 error.WriteFailed => return nw.err.?,
2139 else => |e| return e,
2140 };
21522141 si.get(coff).size = @intCast(nw.interface.end);
21532142 si.applyLocationRelocs(coff);
21542143}
......@@ -2314,17 +2303,6 @@ pub fn updateExports(
23142303 pt: Zcu.PerThread,
23152304 exported: Zcu.Exported,
23162305 export_indices: []const Zcu.Export.Index,
2317) !void {
2318 return coff.updateExportsInner(pt, exported, export_indices) catch |err| switch (err) {
2319 error.OutOfMemory => error.OutOfMemory,
2320 error.LinkFailure => error.AnalysisFail,
2321 };
2322}
2323fn updateExportsInner(
2324 coff: *Coff,
2325 pt: Zcu.PerThread,
2326 exported: Zcu.Exported,
2327 export_indices: []const Zcu.Export.Index,
23282306) !void {
23292307 const zcu = pt.zcu;
23302308 const gpa = zcu.gpa;
......@@ -2340,18 +2318,11 @@ fn updateExportsInner(
23402318 try coff.symbol_table.ensureUnusedCapacity(gpa, export_indices.len);
23412319 const exported_si: Symbol.Index = switch (exported) {
23422320 .nav => |nav| try coff.navSymbol(zcu, nav),
2343 .uav => |uav| @enumFromInt(@intFromEnum(switch (try coff.lowerUav(
2321 .uav => |uav| @enumFromInt(@intFromEnum(try coff.lowerUav(
23442322 pt,
23452323 uav,
23462324 Type.fromInterned(ip.typeOf(uav)).abiAlignment(zcu),
2347 export_indices[0].ptr(zcu).src,
2348 )) {
2349 .sym_index => |si| si,
2350 .fail => |em| {
2351 defer em.destroy(gpa);
2352 return coff.base.comp.link_diags.fail("{s}", .{em.msg});
2353 },
2354 })),
2325 ))),
23552326 };
23562327 while (try coff.idle(pt.tid)) {}
23572328 const exported_ni = exported_si.node(coff);
src/link/Dwarf.zig+24-48
......@@ -51,21 +51,15 @@ pub const UpdateError = error{
5151 Underflow,
5252 UnexpectedEndOfFile,
5353 NonResizable,
54 /// TODO why is this in the error set?
55 ConnectionResetByPeer,
56 /// TODO why is this in the error set?
57 SocketUnconnected,
54 Overflow,
5855} ||
59 codegen.GenerateSymbolError ||
56 link.Error ||
6057 Io.File.OpenError ||
6158 Io.File.LengthError ||
6259 Io.File.ReadPositionalError ||
6360 Io.File.WritePositionalError;
6461
65pub const FlushError = UpdateError;
66
67pub const RelocError =
68 Io.File.PWriteError;
62pub const RelocError = Io.File.PWriteError;
6963
7064pub const AddressSize = enum(u8) {
7165 @"32" = 4,
......@@ -1579,19 +1573,17 @@ pub const WipNav = struct {
15791573 pub const LocalConstTag = enum { comptime_arg, local_const };
15801574 pub fn genLocalConstDebugInfo(
15811575 wip_nav: *WipNav,
1582 src_loc: Zcu.LazySrcLoc,
15831576 tag: LocalConstTag,
15841577 opt_name: ?[]const u8,
15851578 val: Value,
15861579 ) UpdateError!void {
1587 return wip_nav.genLocalConstDebugInfoWriterError(src_loc, tag, opt_name, val) catch |err| switch (err) {
1580 return wip_nav.genLocalConstDebugInfoWriterError(tag, opt_name, val) catch |err| switch (err) {
15881581 error.WriteFailed => error.OutOfMemory,
15891582 else => |e| e,
15901583 };
15911584 }
15921585 fn genLocalConstDebugInfoWriterError(
15931586 wip_nav: *WipNav,
1594 src_loc: Zcu.LazySrcLoc,
15951587 tag: LocalConstTag,
15961588 opt_name: ?[]const u8,
15971589 val: Value,
......@@ -1617,7 +1609,7 @@ pub const WipNav = struct {
16171609 });
16181610 if (opt_name) |name| try wip_nav.strp(name);
16191611 try wip_nav.refType(ty);
1620 if (has_runtime_bits) try wip_nav.blockValue(src_loc, val);
1612 if (has_runtime_bits) try wip_nav.blockValue(val);
16211613 if (has_comptime_state) try wip_nav.refValue(val);
16221614 wip_nav.any_children = true;
16231615 }
......@@ -2106,7 +2098,6 @@ pub const WipNav = struct {
21062098
21072099 fn blockValue(
21082100 wip_nav: *WipNav,
2109 src_loc: Zcu.LazySrcLoc,
21102101 val: Value,
21112102 ) (UpdateError || Writer.Error)!void {
21122103 const ty = val.typeOf(wip_nav.pt.zcu);
......@@ -2118,7 +2109,6 @@ pub const WipNav = struct {
21182109 try codegen.generateSymbol(
21192110 wip_nav.dwarf.bin_file,
21202111 wip_nav.pt,
2121 src_loc,
21222112 val,
21232113 &wip_nav.debug_info.writer,
21242114 .{ .debug_output = .{ .dwarf = wip_nav } },
......@@ -2592,7 +2582,7 @@ pub fn initWipNav(
25922582 pt: Zcu.PerThread,
25932583 nav_index: InternPool.Nav.Index,
25942584 sym_index: link.File.SymbolId,
2595) error{ OutOfMemory, CodegenFail }!WipNav {
2585) error{ OutOfMemory, AlreadyReported }!WipNav {
25962586 return initWipNavInner(dwarf, pt, nav_index, sym_index) catch |err| switch (err) {
25972587 error.OutOfMemory => error.OutOfMemory,
25982588 else => |e| pt.zcu.codegenFail(nav_index, "failed to init dwarf: {s}", .{@errorName(e)}),
......@@ -3017,7 +3007,7 @@ fn finishWipNavWriterError(
30173007 try dwarf.const_pool.flushPending(pt, .{ .dwarf = dwarf });
30183008}
30193009
3020pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error{ OutOfMemory, CodegenFail }!void {
3010pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error{ OutOfMemory, AlreadyReported }!void {
30213011 return updateComptimeNavInner(dwarf, pt, nav_index) catch |err| switch (err) {
30223012 error.OutOfMemory => error.OutOfMemory,
30233013 else => |e| pt.zcu.codegenFail(nav_index, "failed to update dwarf: {s}", .{@errorName(e)}),
......@@ -3027,7 +3017,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool
30273017fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
30283018 const zcu = pt.zcu;
30293019 const ip = &zcu.intern_pool;
3030 const nav_src_loc = zcu.navSrcLoc(nav_index);
30313020
30323021 const nav = ip.getNav(nav_index);
30333022 const inst_info = nav.srcInst(ip).resolveFull(ip).?;
......@@ -3207,7 +3196,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
32073196 }.toSlice(ip));
32083197 const nav_ty = nav_val.typeOf(zcu);
32093198 try wip_nav.refType(nav_ty);
3210 try wip_nav.blockValue(nav_src_loc, nav_val);
3199 try wip_nav.blockValue(nav_val);
32113200 try diw.writeUleb128(nav.resolved.?.@"align".toByteUnits() orelse
32123201 nav_ty.abiAlignment(zcu).toByteUnits().?);
32133202 try diw.writeByte(@intFromBool(decl.linkage != .normal));
......@@ -3241,7 +3230,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
32413230 try diw.writeUleb128(nav.resolved.?.@"align".toByteUnits() orelse
32423231 nav_ty.abiAlignment(zcu).toByteUnits().?);
32433232 try diw.writeByte(@intFromBool(decl.linkage != .normal));
3244 if (has_runtime_bits) try wip_nav.blockValue(nav_src_loc, nav_val);
3233 if (has_runtime_bits) try wip_nav.blockValue(nav_val);
32453234 if (has_comptime_state) try wip_nav.refValue(nav_val);
32463235 wip_nav.finishForward(nav_ty_reloc_index);
32473236 try wip_nav.abbrevCode(.is_const);
......@@ -3551,19 +3540,6 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
35513540 };
35523541 defer wip_nav.deinit();
35533542
3554 // TODO: we really shouldn't need source locations at this point in the pipeline: we've lost
3555 // that information by now. If the linker fundamentally cannot lower certain values, that needs
3556 // to be caught in the frontend; if it can only hit transient failures, they should be reported
3557 // without trying to tie them to a bogus source location.
3558 const src_loc: Zcu.LazySrcLoc = .{
3559 .base_node_inst = inst: {
3560 const mod_root_file_index = zcu.module_roots.get(zcu.std_mod).?.unwrap().?;
3561 const mod_root_type_index = zcu.fileRootType(mod_root_file_index);
3562 break :inst ip.loadStructType(mod_root_type_index).zir_index;
3563 },
3564 .offset = .{ .byte_abs = 0 },
3565 };
3566
35673543 const diw = &wip_nav.debug_info.writer;
35683544 var big_int_space: Value.BigIntSpace = undefined;
35693545 switch (value_ip_key) {
......@@ -3588,7 +3564,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
35883564 else => if (ptr_type.sentinel == .none) .ptr_aligned_type else .ptr_aligned_sentinel_type,
35893565 });
35903566 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
3591 if (ptr_type.sentinel != .none) try wip_nav.blockValue(src_loc, .fromInterned(ptr_type.sentinel));
3567 if (ptr_type.sentinel != .none) try wip_nav.blockValue(.fromInterned(ptr_type.sentinel));
35923568 if (ptr_type.flags.alignment.toByteUnits()) |a| try diw.writeUleb128(a);
35933569 try diw.writeByte(@intFromEnum(ptr_type.flags.address_space));
35943570 if (ptr_type.flags.is_const or ptr_type.flags.is_volatile) try wip_nav.infoSectionOffset(
......@@ -3633,7 +3609,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
36333609 const array_child_type: Type = .fromInterned(array_type.child);
36343610 try wip_nav.abbrevCode(if (array_type.sentinel == .none) .array_type else .array_sentinel_type);
36353611 try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)});
3636 if (array_type.sentinel != .none) try wip_nav.blockValue(src_loc, .fromInterned(array_type.sentinel));
3612 if (array_type.sentinel != .none) try wip_nav.blockValue(.fromInterned(array_type.sentinel));
36373613 try wip_nav.refType(array_child_type);
36383614 try wip_nav.abbrevCode(.array_len);
36393615 try wip_nav.refType(.usize);
......@@ -3880,7 +3856,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
38803856 if (has_comptime_state)
38813857 try wip_nav.refValue(.fromInterned(comptime_value))
38823858 else if (has_runtime_bits)
3883 try wip_nav.blockValue(src_loc, .fromInterned(comptime_value));
3859 try wip_nav.blockValue(.fromInterned(comptime_value));
38843860 }
38853861 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
38863862 },
......@@ -3967,7 +3943,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
39673943 if (has_comptime_state)
39683944 try wip_nav.refValue(.fromInterned(field_init))
39693945 else if (has_runtime_bits)
3970 try wip_nav.blockValue(ty.srcLoc(zcu), .fromInterned(field_init));
3946 try wip_nav.blockValue(.fromInterned(field_init));
39713947 }
39723948 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
39733949 }
......@@ -4332,7 +4308,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
43324308 if (has_comptime_state)
43334309 try wip_nav.refValue(.fromInterned(payload_val))
43344310 else
4335 try wip_nav.blockValue(src_loc, .fromInterned(payload_val));
4311 try wip_nav.blockValue(.fromInterned(payload_val));
43364312 },
43374313 }
43384314 {
......@@ -4500,7 +4476,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
45004476 {
45014477 try wip_nav.abbrevCode(.comptime_value_field_runtime_bits);
45024478 try wip_nav.strp("len");
4503 try wip_nav.blockValue(src_loc, .fromInterned(slice.len));
4479 try wip_nav.blockValue(.fromInterned(slice.len));
45044480 }
45054481 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
45064482 },
......@@ -4513,8 +4489,8 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
45134489 try wip_nav.strp("has_value");
45144490 switch (optRepr(opt_child_type, zcu)) {
45154491 .opv_null => try diw.writeUleb128(0),
4516 .unpacked => try wip_nav.blockValue(src_loc, .makeBool(opt.val != .none)),
4517 .error_set, .pointer => try wip_nav.blockValue(src_loc, .fromInterned(value_index)),
4492 .unpacked => try wip_nav.blockValue(.makeBool(opt.val != .none)),
4493 .error_set, .pointer => try wip_nav.blockValue(.fromInterned(value_index)),
45184494 }
45194495 }
45204496 if (opt.val != .none) child_field: {
......@@ -4530,7 +4506,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
45304506 if (has_comptime_state)
45314507 try wip_nav.refValue(.fromInterned(opt.val))
45324508 else
4533 try wip_nav.blockValue(src_loc, .fromInterned(opt.val));
4509 try wip_nav.blockValue(.fromInterned(opt.val));
45344510 }
45354511 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
45364512 },
......@@ -4561,7 +4537,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
45614537 if (has_comptime_state)
45624538 try wip_nav.refValue(field_value)
45634539 else
4564 try wip_nav.blockValue(src_loc, field_value);
4540 try wip_nav.blockValue(field_value);
45654541 }
45664542 },
45674543 .tuple_type => |tuple_type| for (0..tuple_type.types.len) |field_index| {
......@@ -4588,7 +4564,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
45884564 if (has_comptime_state)
45894565 try wip_nav.refValue(field_value)
45904566 else
4591 try wip_nav.blockValue(src_loc, field_value);
4567 try wip_nav.blockValue(field_value);
45924568 },
45934569 inline .array_type, .vector_type => |sequence_type| {
45944570 const child_type: Type = .fromInterned(sequence_type.child);
......@@ -4608,7 +4584,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
46084584 if (has_comptime_state)
46094585 try wip_nav.refValue(.fromInterned(elem))
46104586 else
4611 try wip_nav.blockValue(src_loc, .fromInterned(elem));
4587 try wip_nav.blockValue(.fromInterned(elem));
46124588 }
46134589 },
46144590 else => unreachable,
......@@ -4636,7 +4612,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co
46364612 if (has_comptime_state)
46374613 try wip_nav.refValue(.fromInterned(un.val))
46384614 else
4639 try wip_nav.blockValue(src_loc, .fromInterned(un.val));
4615 try wip_nav.blockValue(.fromInterned(un.val));
46404616 }
46414617 try diw.writeUleb128(@intFromEnum(AbbrevCode.null));
46424618 },
......@@ -4708,13 +4684,13 @@ fn refAbbrevCode(
47084684 return @intFromEnum(abbrev_code);
47094685}
47104686
4711pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void {
4687pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) UpdateError!void {
47124688 return dwarf.flushWriterError(pt) catch |err| switch (err) {
47134689 error.WriteFailed => error.OutOfMemory,
47144690 else => |e| e,
47154691 };
47164692}
4717fn flushWriterError(dwarf: *Dwarf, pt: Zcu.PerThread) (FlushError || Writer.Error)!void {
4693fn flushWriterError(dwarf: *Dwarf, pt: Zcu.PerThread) (UpdateError || Writer.Error)!void {
47184694 const zcu = pt.zcu;
47194695 const ip = &zcu.intern_pool;
47204696 const comp = dwarf.bin_file.comp;
src/link/Elf.zig+32-33
......@@ -476,9 +476,8 @@ pub fn lowerUav(
476476 pt: Zcu.PerThread,
477477 uav: InternPool.Index,
478478 explicit_alignment: InternPool.Alignment,
479 src_loc: Zcu.LazySrcLoc,
480) !codegen.SymbolResult {
481 return self.zigObjectPtr().?.lowerUav(self, pt, uav, explicit_alignment, src_loc);
479) !link.File.SymbolId {
480 return self.zigObjectPtr().?.lowerUav(self, pt, uav, explicit_alignment);
482481}
483482
484483pub fn getUavVAddr(self: *Elf, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
......@@ -743,7 +742,7 @@ pub fn loadInput(self: *Elf, input: link.Input) !void {
743742 }
744743}
745744
746pub fn flush(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void {
745pub fn flush(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.Error!void {
747746 const tracy = trace(@src());
748747 defer tracy.end();
749748
......@@ -757,7 +756,7 @@ pub fn flush(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std
757756 defer sub_prog_node.end();
758757
759758 return flushInner(self, arena, tid) catch |err| switch (err) {
760 error.OutOfMemory, error.LinkFailure => |e| return e,
759 error.OutOfMemory, error.AlreadyReported => |e| return e,
761760 else => |e| return diags.fail("ELF flush failed: {t}", .{e}),
762761 };
763762}
......@@ -784,7 +783,7 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void {
784783 .Exe => {},
785784 }
786785
787 if (diags.hasErrors()) return error.LinkFailure;
786 if (diags.hasErrors()) return error.AlreadyReported;
788787
789788 // If we haven't already, create a linker-generated input file comprising of
790789 // linker-defined synthetic symbols only such as `_DYNAMIC`, etc.
......@@ -816,7 +815,7 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void {
816815 }
817816
818817 self.checkDuplicates() catch |err| switch (err) {
819 error.HasDuplicates => return error.LinkFailure,
818 error.HasDuplicates => return error.AlreadyReported,
820819 else => |e| return e,
821820 };
822821
......@@ -903,7 +902,7 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void {
903902 error.RelocFailure, error.RelaxFailure => has_reloc_errors = true,
904903 error.UnsupportedCpuArch => {
905904 try self.reportUnsupportedCpuArch();
906 return error.LinkFailure;
905 return error.AlreadyReported;
907906 },
908907 else => |e| return e,
909908 };
......@@ -912,7 +911,7 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void {
912911
913912 try self.reportUndefinedSymbols(&undefs);
914913
915 if (has_reloc_errors) return error.LinkFailure;
914 if (has_reloc_errors) return error.AlreadyReported;
916915 }
917916
918917 try self.writePhdrTable();
......@@ -921,10 +920,10 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void {
921920 try self.writeMergeSections();
922921
923922 self.writeSyntheticSections() catch |err| switch (err) {
924 error.RelocFailure => return error.LinkFailure,
923 error.RelocFailure => return error.AlreadyReported,
925924 error.UnsupportedCpuArch => {
926925 try self.reportUnsupportedCpuArch();
927 return error.LinkFailure;
926 return error.AlreadyReported;
928927 },
929928 else => |e| return e,
930929 };
......@@ -938,7 +937,7 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void {
938937 try self.writeElfHeader();
939938 }
940939
941 if (diags.hasErrors()) return error.LinkFailure;
940 if (diags.hasErrors()) return error.AlreadyReported;
942941}
943942
944943fn dumpArgvInit(self: *Elf, arena: Allocator) !void {
......@@ -1053,7 +1052,7 @@ pub fn openParseObjectReportingFailure(self: *Elf, path: Path) void {
10531052 const diags = &comp.link_diags;
10541053 const obj = link.openObject(io, path, false, false) catch |err| {
10551054 switch (diags.failParse(path, "failed to open object: {t}", .{err})) {
1056 error.LinkFailure => return,
1055 error.AlreadyReported => return,
10571056 }
10581057 };
10591058 self.parseObjectReportingFailure(obj);
......@@ -1063,7 +1062,7 @@ fn parseObjectReportingFailure(self: *Elf, obj: link.Input.Object) void {
10631062 const comp = self.base.comp;
10641063 const diags = &comp.link_diags;
10651064 self.parseObject(obj) catch |err| switch (err) {
1066 error.LinkFailure => return, // already reported
1065 error.AlreadyReported => return, // already reported
10671066 else => |e| diags.addParseError(obj.path, "failed to parse object: {t}", .{e}),
10681067 };
10691068}
......@@ -1343,7 +1342,7 @@ fn scanRelocs(self: *Elf) !void {
13431342 error.RelaxFailure => unreachable,
13441343 error.UnsupportedCpuArch => {
13451344 try self.reportUnsupportedCpuArch();
1346 return error.LinkFailure;
1345 return error.AlreadyReported;
13471346 },
13481347 error.RelocFailure => has_reloc_errors = true,
13491348 else => |e| return e,
......@@ -1354,7 +1353,7 @@ fn scanRelocs(self: *Elf) !void {
13541353 error.RelaxFailure => unreachable,
13551354 error.UnsupportedCpuArch => {
13561355 try self.reportUnsupportedCpuArch();
1357 return error.LinkFailure;
1356 return error.AlreadyReported;
13581357 },
13591358 error.RelocFailure => has_reloc_errors = true,
13601359 else => |e| return e,
......@@ -1363,7 +1362,7 @@ fn scanRelocs(self: *Elf) !void {
13631362
13641363 try self.reportUndefinedSymbols(&undefs);
13651364
1366 if (has_reloc_errors) return error.LinkFailure;
1365 if (has_reloc_errors) return error.AlreadyReported;
13671366
13681367 if (self.zigObjectPtr()) |zo| {
13691368 try zo.asFile().createSymbolIndirection(self);
......@@ -1690,7 +1689,7 @@ pub fn updateFunc(
16901689 pt: Zcu.PerThread,
16911690 func_index: InternPool.Index,
16921691 mir: *const codegen.AnyMir,
1693) link.File.UpdateNavError!void {
1692) link.Error!void {
16941693 return self.zigObjectPtr().?.updateFunc(self, pt, func_index, mir);
16951694}
16961695
......@@ -1698,7 +1697,7 @@ pub fn updateNav(
16981697 self: *Elf,
16991698 pt: Zcu.PerThread,
17001699 nav: InternPool.Nav.Index,
1701) link.File.UpdateNavError!void {
1700) link.Error!void {
17021701 return self.zigObjectPtr().?.updateNav(self, pt, nav);
17031702}
17041703
......@@ -1707,7 +1706,7 @@ pub fn updateContainerType(
17071706 pt: Zcu.PerThread,
17081707 ty: InternPool.Index,
17091708 success: bool,
1710) link.File.UpdateContainerTypeError!void {
1709) link.Error!void {
17111710 return self.zigObjectPtr().?.updateContainerType(pt, ty, success) catch |err| switch (err) {
17121711 error.OutOfMemory => |e| return e,
17131712 };
......@@ -1718,11 +1717,11 @@ pub fn updateExports(
17181717 pt: Zcu.PerThread,
17191718 exported: Zcu.Exported,
17201719 export_indices: []const Zcu.Export.Index,
1721) link.File.UpdateExportsError!void {
1720) link.Error!void {
17221721 return self.zigObjectPtr().?.updateExports(self, pt, exported, export_indices);
17231722}
17241723
1725pub fn updateLineNumber(self: *Elf, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
1724pub fn updateLineNumber(self: *Elf, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) link.Error!void {
17261725 return self.zigObjectPtr().?.updateLineNumber(pt, ti_id);
17271726}
17281727
......@@ -1784,12 +1783,12 @@ pub fn resolveMergeSections(self: *Elf) !void {
17841783 if (!object.alive) continue;
17851784 if (!object.dirty) continue;
17861785 object.initInputMergeSections(self) catch |err| switch (err) {
1787 error.LinkFailure => has_errors = true,
1786 error.AlreadyReported => has_errors = true,
17881787 else => |e| return e,
17891788 };
17901789 }
17911790
1792 if (has_errors) return error.LinkFailure;
1791 if (has_errors) return error.AlreadyReported;
17931792
17941793 for (self.objects.items) |index| {
17951794 const object = self.file(index).?.object;
......@@ -1803,12 +1802,12 @@ pub fn resolveMergeSections(self: *Elf) !void {
18031802 if (!object.alive) continue;
18041803 if (!object.dirty) continue;
18051804 object.resolveMergeSubsections(self) catch |err| switch (err) {
1806 error.LinkFailure => has_errors = true,
1805 error.AlreadyReported => has_errors = true,
18071806 else => |e| return e,
18081807 };
18091808 }
18101809
1811 if (has_errors) return error.LinkFailure;
1810 if (has_errors) return error.AlreadyReported;
18121811}
18131812
18141813pub fn finalizeMergeSections(self: *Elf) !void {
......@@ -2998,7 +2997,7 @@ fn writeAtoms(self: *Elf) !void {
29982997 atom_list.write(&buffer, &undefs, self) catch |err| switch (err) {
29992998 error.UnsupportedCpuArch => {
30002999 try self.reportUnsupportedCpuArch();
3001 return error.LinkFailure;
3000 return error.AlreadyReported;
30023001 },
30033002 error.RelocFailure, error.RelaxFailure => has_reloc_errors = true,
30043003 else => |e| return e,
......@@ -3006,7 +3005,7 @@ fn writeAtoms(self: *Elf) !void {
30063005 }
30073006
30083007 try self.reportUndefinedSymbols(&undefs);
3009 if (has_reloc_errors) return error.LinkFailure;
3008 if (has_reloc_errors) return error.AlreadyReported;
30103009
30113010 if (self.requiresThunks()) {
30123011 for (self.thunks.items) |th| {
......@@ -3838,9 +3837,9 @@ pub fn failFile(
38383837 file_index: File.Index,
38393838 comptime format: []const u8,
38403839 args: anytype,
3841) error{ OutOfMemory, LinkFailure } {
3840) error{ OutOfMemory, AlreadyReported } {
38423841 try addFileError(self, file_index, format, args);
3843 return error.LinkFailure;
3842 return error.AlreadyReported;
38443843}
38453844
38463845const FormatShdr = struct {
......@@ -4409,7 +4408,7 @@ pub fn stringTableLookup(strtab: []const u8, off: u32) [:0]const u8 {
44094408 return slice[0..mem.indexOfScalar(u8, slice, 0).? :0];
44104409}
44114410
4412pub fn pwriteAll(elf_file: *Elf, bytes: []const u8, offset: u64) error{LinkFailure}!void {
4411pub fn pwriteAll(elf_file: *Elf, bytes: []const u8, offset: u64) error{AlreadyReported}!void {
44134412 const comp = elf_file.base.comp;
44144413 const io = comp.io;
44154414 const diags = &comp.link_diags;
......@@ -4417,7 +4416,7 @@ pub fn pwriteAll(elf_file: *Elf, bytes: []const u8, offset: u64) error{LinkFailu
44174416 return diags.fail("failed to write: {t}", .{err});
44184417}
44194418
4420pub fn setLength(elf_file: *Elf, length: u64) error{LinkFailure}!void {
4419pub fn setLength(elf_file: *Elf, length: u64) error{AlreadyReported}!void {
44214420 const comp = elf_file.base.comp;
44224421 const io = comp.i;
44234422 const diags = &comp.link_diags;
......@@ -4426,7 +4425,7 @@ pub fn setLength(elf_file: *Elf, length: u64) error{LinkFailure}!void {
44264425 };
44274426}
44284427
4429pub fn cast(elf_file: *Elf, comptime T: type, x: anytype) error{LinkFailure}!T {
4428pub fn cast(elf_file: *Elf, comptime T: type, x: anytype) error{AlreadyReported}!T {
44304429 return std.math.cast(T, x) orelse {
44314430 const comp = elf_file.base.comp;
44324431 const diags = &comp.link_diags;
src/link/Elf/Object.zig+6-6
......@@ -282,7 +282,7 @@ pub fn validateEFlags(
282282 );
283283 }
284284
285 if (any_errors) return error.LinkFailure;
285 if (any_errors) return error.AlreadyReported;
286286 },
287287 else => {},
288288 }
......@@ -829,7 +829,7 @@ pub fn initInputMergeSections(self: *Object, elf_file: *Elf) !void {
829829 var err = try diags.addErrorWithNotes(1);
830830 try err.addMsg("string not null terminated", .{});
831831 err.addNote("in {f}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) });
832 return error.LinkFailure;
832 return error.AlreadyReported;
833833 }
834834 end += sh_entsize;
835835 const string = data[start..end];
......@@ -844,7 +844,7 @@ pub fn initInputMergeSections(self: *Object, elf_file: *Elf) !void {
844844 var err = try diags.addErrorWithNotes(1);
845845 try err.addMsg("size not a multiple of sh_entsize", .{});
846846 err.addNote("in {f}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) });
847 return error.LinkFailure;
847 return error.AlreadyReported;
848848 }
849849
850850 var pos: u32 = 0;
......@@ -873,7 +873,7 @@ pub fn initOutputMergeSections(self: *Object, elf_file: *Elf) !void {
873873}
874874
875875pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) error{
876 LinkFailure,
876 AlreadyReported,
877877 OutOfMemory,
878878 /// TODO report the error and remove this
879879 Overflow,
......@@ -925,7 +925,7 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) error{
925925 try err.addMsg("invalid symbol value: {x}", .{esym.st_value});
926926 err.addNote("for symbol {s}", .{sym.name(elf_file)});
927927 err.addNote("in {f}", .{self.fmtPath()});
928 return error.LinkFailure;
928 return error.AlreadyReported;
929929 };
930930
931931 sym.ref = .{ .index = res.msub_index, .file = imsec.merge_section_index };
......@@ -950,7 +950,7 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) error{
950950 var err = try diags.addErrorWithNotes(1);
951951 try err.addMsg("invalid relocation at offset 0x{x}", .{rel.r_offset});
952952 err.addNote("in {f}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) });
953 return error.LinkFailure;
953 return error.AlreadyReported;
954954 };
955955
956956 const sym_index = try self.addSymbol(gpa);
src/link/Elf/ZigObject.zig+28-57
......@@ -272,24 +272,18 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void {
272272
273273 // Most lazy symbols can be updated on first use, but
274274 // anyerror needs to wait for everything to be flushed.
275 if (metadata.text_state != .unused) self.updateLazySymbol(
275 if (metadata.text_state != .unused) try self.updateLazySymbol(
276276 elf_file,
277277 pt,
278278 .{ .kind = .code, .ty = .anyerror_type },
279279 metadata.text_symbol_index,
280 ) catch |err| switch (err) {
281 error.CodegenFail => return error.LinkFailure,
282 else => |e| return e,
283 };
284 if (metadata.rodata_state != .unused) self.updateLazySymbol(
280 );
281 if (metadata.rodata_state != .unused) try self.updateLazySymbol(
285282 elf_file,
286283 pt,
287284 .{ .kind = .const_data, .ty = .anyerror_type },
288285 metadata.rodata_symbol_index,
289 ) catch |err| switch (err) {
290 error.CodegenFail => return error.LinkFailure,
291 else => |e| return e,
292 };
286 );
293287 }
294288 for (self.lazy_syms.values()) |*metadata| {
295289 if (metadata.text_state != .unused) metadata.text_state = .flushed;
......@@ -999,8 +993,7 @@ pub fn lowerUav(
999993 pt: Zcu.PerThread,
1000994 uav: InternPool.Index,
1001995 explicit_alignment: InternPool.Alignment,
1002 src_loc: Zcu.LazySrcLoc,
1003) !codegen.SymbolResult {
996) !link.File.SymbolId {
1004997 const zcu = pt.zcu;
1005998 const gpa = zcu.gpa;
1006999 const val = Value.fromInterned(uav);
......@@ -1013,7 +1006,7 @@ pub fn lowerUav(
10131006 const sym = self.symbol(metadata.symbol_index);
10141007 const existing_alignment = sym.atom(elf_file).?.alignment;
10151008 if (uav_alignment.order(existing_alignment).compare(.lte))
1016 return .{ .sym_index = @enumFromInt(metadata.symbol_index) };
1009 return @enumFromInt(metadata.symbol_index);
10171010 }
10181011
10191012 const osec = if (self.data_relro_index) |sym_index|
......@@ -1033,31 +1026,25 @@ pub fn lowerUav(
10331026 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
10341027 @intFromEnum(uav),
10351028 }) catch unreachable;
1036 const res = self.lowerConst(
1029 const sym_index = self.lowerConst(
10371030 elf_file,
10381031 pt,
10391032 name,
10401033 val,
10411034 uav_alignment,
10421035 osec,
1043 src_loc,
10441036 ) catch |err| switch (err) {
10451037 error.OutOfMemory => |e| return e,
1046 else => |e| return .{ .fail = try Zcu.ErrorMsg.create(
1047 gpa,
1048 src_loc,
1049 "unable to lower constant value: {s}",
1050 .{@errorName(e)},
1051 ) },
1038 else => |e| return elf_file.base.comp.link_diags.fail(
1039 "failed to lower constant value: {t}",
1040 .{e},
1041 ),
10521042 };
1053 switch (res) {
1054 .sym_index => |sym_index| try self.uavs.put(gpa, uav, .{
1055 .symbol_index = @intFromEnum(sym_index),
1056 .allocated = true,
1057 }),
1058 .fail => {},
1059 }
1060 return res;
1043 try self.uavs.put(gpa, uav, .{
1044 .symbol_index = @intFromEnum(sym_index),
1045 .allocated = true,
1046 });
1047 return sym_index;
10611048}
10621049
10631050pub fn getOrCreateMetadataForLazySymbol(
......@@ -1370,7 +1357,7 @@ fn updateNavCode(
13701357 shdr_index: u32,
13711358 code: []const u8,
13721359 stt_bits: u8,
1373) link.File.UpdateNavError!void {
1360) link.Error!void {
13741361 const zcu = pt.zcu;
13751362 const gpa = zcu.gpa;
13761363 const comp = elf_file.base.comp;
......@@ -1473,7 +1460,7 @@ fn updateTlv(
14731460 sym_index: Symbol.Index,
14741461 shndx: u32,
14751462 code: []const u8,
1476) link.File.UpdateNavError!void {
1463) link.Error!void {
14771464 const zcu = pt.zcu;
14781465 const ip = &zcu.intern_pool;
14791466 const gpa = zcu.gpa;
......@@ -1531,7 +1518,7 @@ pub fn updateFunc(
15311518 pt: Zcu.PerThread,
15321519 func_index: InternPool.Index,
15331520 mir: *const codegen.AnyMir,
1534) link.File.UpdateNavError!void {
1521) link.Error!void {
15351522 const tracy = trace(@src());
15361523 defer tracy.end();
15371524
......@@ -1558,7 +1545,6 @@ pub fn updateFunc(
15581545 codegen.emitFunction(
15591546 &elf_file.base,
15601547 pt,
1561 zcu.navSrcLoc(func.owner_nav),
15621548 func_index,
15631549 @enumFromInt(sym_index),
15641550 mir,
......@@ -1645,7 +1631,7 @@ pub fn updateNav(
16451631 elf_file: *Elf,
16461632 pt: Zcu.PerThread,
16471633 nav_index: InternPool.Nav.Index,
1648) link.File.UpdateNavError!void {
1634) link.Error!void {
16491635 const tracy = trace(@src());
16501636 defer tracy.end();
16511637
......@@ -1670,7 +1656,7 @@ pub fn updateNav(
16701656 var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, @enumFromInt(sym_index));
16711657 defer debug_wip_nav.deinit();
16721658 dwarf.finishWipNav(pt, nav_index, &debug_wip_nav) catch |err| switch (err) {
1673 error.OutOfMemory, error.Overflow => |e| return e,
1659 error.OutOfMemory, error.Canceled, error.AlreadyReported => |e| return e,
16741660 else => |e| return elf_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}),
16751661 };
16761662 }
......@@ -1691,7 +1677,6 @@ pub fn updateNav(
16911677 codegen.generateSymbol(
16921678 &elf_file.base,
16931679 pt,
1694 zcu.navSrcLoc(nav_index),
16951680 .fromInterned(nav.resolved.?.value),
16961681 &aw.writer,
16971682 .{ .atom_index = @enumFromInt(sym_index) },
......@@ -1713,7 +1698,7 @@ pub fn updateNav(
17131698 try self.updateNavCode(elf_file, pt, nav_index, sym_index, shndx, code, elf.STT_OBJECT);
17141699
17151700 if (debug_wip_nav) |*wip_nav| self.dwarf.?.finishWipNav(pt, nav_index, wip_nav) catch |err| switch (err) {
1716 error.OutOfMemory, error.Overflow => |e| return e,
1701 error.OutOfMemory, error.Canceled, error.AlreadyReported => |e| return e,
17171702 else => |e| return elf_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}),
17181703 };
17191704 } else if (self.dwarf) |*dwarf| try dwarf.updateComptimeNav(pt, nav_index);
......@@ -1759,7 +1744,6 @@ fn updateLazySymbol(
17591744 codegen.generateLazySymbol(
17601745 &elf_file.base,
17611746 pt,
1762 Type.fromInterned(sym.ty).srcLocOrNull(zcu) orelse .unneeded,
17631747 sym,
17641748 &required_alignment,
17651749 &aw.writer,
......@@ -1827,8 +1811,7 @@ fn lowerConst(
18271811 val: Value,
18281812 required_alignment: InternPool.Alignment,
18291813 output_section_index: u32,
1830 src_loc: Zcu.LazySrcLoc,
1831) !codegen.SymbolResult {
1814) !link.File.SymbolId {
18321815 const gpa = pt.zcu.gpa;
18331816
18341817 var aw: std.Io.Writer.Allocating = .init(gpa);
......@@ -1840,7 +1823,6 @@ fn lowerConst(
18401823 codegen.generateSymbol(
18411824 &elf_file.base,
18421825 pt,
1843 src_loc,
18441826 val,
18451827 &aw.writer,
18461828 .{ .atom_index = @enumFromInt(sym_index) },
......@@ -1865,7 +1847,7 @@ fn lowerConst(
18651847
18661848 try elf_file.pwriteAll(code, atom_ptr.offset(elf_file));
18671849
1868 return .{ .sym_index = @enumFromInt(sym_index) };
1850 return @enumFromInt(sym_index);
18691851}
18701852
18711853pub fn updateExports(
......@@ -1874,7 +1856,7 @@ pub fn updateExports(
18741856 pt: Zcu.PerThread,
18751857 exported: Zcu.Exported,
18761858 export_indices: []const Zcu.Export.Index,
1877) link.File.UpdateExportsError!void {
1859) link.Error!void {
18781860 const tracy = trace(@src());
18791861 defer tracy.end();
18801862
......@@ -1886,18 +1868,7 @@ pub fn updateExports(
18861868 break :blk self.navs.getPtr(nav).?;
18871869 },
18881870 .uav => |uav| self.uavs.getPtr(uav) orelse blk: {
1889 const first_exp = export_indices[0].ptr(zcu);
1890 const res = try self.lowerUav(elf_file, pt, uav, .none, first_exp.src);
1891 switch (res) {
1892 .sym_index => {},
1893 .fail => |em| {
1894 // TODO maybe it's enough to return an error here and let Zcu.processExportsInner
1895 // handle the error?
1896 try zcu.failed_exports.ensureUnusedCapacity(zcu.gpa, 1);
1897 zcu.failed_exports.putAssumeCapacityNoClobber(export_indices[0], em);
1898 return;
1899 },
1900 }
1871 _ = try self.lowerUav(elf_file, pt, uav, .none);
19011872 break :blk self.uavs.getPtr(uav).?;
19021873 },
19031874 };
......@@ -1962,12 +1933,12 @@ pub fn updateExports(
19621933 }
19631934}
19641935
1965pub fn updateLineNumber(self: *ZigObject, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
1936pub fn updateLineNumber(self: *ZigObject, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) link.Error!void {
19661937 if (self.dwarf) |*dwarf| {
19671938 const comp = dwarf.bin_file.comp;
19681939 const diags = &comp.link_diags;
19691940 dwarf.updateLineNumber(pt.zcu, ti_id) catch |err| switch (err) {
1970 error.Overflow, error.OutOfMemory => |e| return e,
1941 error.OutOfMemory, error.Canceled, error.AlreadyReported => |e| return e,
19711942 else => |e| return diags.fail("failed to update dwarf line numbers: {s}", .{@errorName(e)}),
19721943 };
19731944 }
src/link/Elf/relocatable.zig+4-4
......@@ -23,7 +23,7 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void {
2323 const io = comp.io;
2424 const diags = &comp.link_diags;
2525
26 if (diags.hasErrors()) return error.LinkFailure;
26 if (diags.hasErrors()) return error.AlreadyReported;
2727
2828 // First, we flush relocatable object file generated with our backends.
2929 if (elf_file.zigObjectPtr()) |zig_object| {
......@@ -151,13 +151,13 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void {
151151 try elf_file.base.file.?.setLength(io, total_size);
152152 try elf_file.base.file.?.writePositionalAll(io, writer.buffered(), 0);
153153
154 if (diags.hasErrors()) return error.LinkFailure;
154 if (diags.hasErrors()) return error.AlreadyReported;
155155}
156156
157157pub fn flushObject(elf_file: *Elf, comp: *Compilation) !void {
158158 const diags = &comp.link_diags;
159159
160 if (diags.hasErrors()) return error.LinkFailure;
160 if (diags.hasErrors()) return error.AlreadyReported;
161161
162162 // Now, we are ready to resolve the symbols across all input files.
163163 // We will first resolve the files in the ZigObject, next in the parsed
......@@ -203,7 +203,7 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation) !void {
203203 try elf_file.writeShdrTable();
204204 try elf_file.writeElfHeader();
205205
206 if (diags.hasErrors()) return error.LinkFailure;
206 if (diags.hasErrors()) return error.AlreadyReported;
207207}
208208
209209fn claimUnresolved(elf_file: *Elf) void {
src/link/Elf2.zig+295-212
......@@ -162,6 +162,8 @@ const_prog_node: std.Progress.Node,
162162synth_prog_node: std.Progress.Node,
163163input_prog_node: std.Progress.Node,
164164
165const Error = link.Error || error{MappedFileIo};
166
165167const Node = union(enum) {
166168 file,
167169 ehdr,
......@@ -478,7 +480,7 @@ const Section = struct {
478480 };
479481 }
480482
481 fn rename(shndx: Index, elf: *Elf, new_name: []const u8) !void {
483 fn rename(shndx: Index, elf: *Elf, new_name: []const u8) Error!void {
482484 const shstrtab_entry = try elf.string(.shstrtab, new_name);
483485 switch (elf.shdrPtr(shndx)) {
484486 inline else => |shdr| elf.targetStore(&shdr.name, @intFromEnum(shstrtab_entry)),
......@@ -487,7 +489,7 @@ const Section = struct {
487489
488490 /// Asserts that `shndx` is a `SHT_RELA` section and ensures that its node has enough unused
489491 /// space to hold `n` additional `ElfN.Rela` entries.
490 fn relaEnsureAdditionalCapacity(rela_shndx: Index, elf: *Elf, n: usize) !void {
492 fn relaEnsureAdditionalCapacity(rela_shndx: Index, elf: *Elf, n: usize) Error!void {
491493 const node = rela_shndx.get(elf).ni;
492494 const need_size: u64 = switch (elf.shdrPtr(rela_shndx)) {
493495 inline else => |shdr, class| need_size: {
......@@ -509,11 +511,7 @@ const Section = struct {
509511 break :need_size cur_size + need_additional * ent_size;
510512 },
511513 };
512 _, const cur_node_size = node.location(&elf.mf).resolve(&elf.mf);
513 if (need_size > cur_node_size) {
514 const gpa = elf.base.comp.gpa;
515 try node.resize(&elf.mf, gpa, need_size +| need_size / MappedFile.growth_factor);
516 }
514 try elf.ensureNodeSize(node, need_size);
517515 }
518516
519517 /// Asserts that `shndx` is a `SHT_RELA` section and deletes the `ElfN.Rela` entry at the
......@@ -1192,7 +1190,7 @@ const SymbolReloc = struct {
11921190 }
11931191};
11941192
1195fn ensureUnusedSymbolCapacity(elf: *Elf, len: u32, kind: enum { all_local, maybe_global }) !void {
1193fn ensureUnusedSymbolCapacity(elf: *Elf, len: u32, kind: enum { all_local, maybe_global }) Error!void {
11961194 const gpa = elf.base.comp.gpa;
11971195
11981196 try elf.symtab.ensureUnusedCapacity(gpa, len);
......@@ -1210,11 +1208,7 @@ fn ensureUnusedSymbolCapacity(elf: *Elf, len: u32, kind: enum { all_local, maybe
12101208 const need_node_size: u64 = switch (elf.shdrPtr(.symtab)) {
12111209 inline else => |shdr, class| elf.targetLoad(&shdr.size) + len * @sizeOf(class.ElfN().Sym),
12121210 };
1213 _, const cur_node_size = Section.Index.symtab.get(elf).ni.location(&elf.mf).resolve(&elf.mf);
1214 if (cur_node_size < need_node_size) {
1215 const new_node_size = need_node_size +| need_node_size / MappedFile.growth_factor;
1216 try Section.Index.symtab.get(elf).ni.resize(&elf.mf, gpa, new_node_size);
1217 }
1211 try elf.ensureNodeSize(Section.Index.symtab.get(elf).ni, need_node_size);
12181212 }
12191213
12201214 switch (kind) {
......@@ -1232,18 +1226,14 @@ fn ensureUnusedSymbolCapacity(elf: *Elf, len: u32, kind: enum { all_local, maybe
12321226 const dynsym_need_size: u64 = switch (elf.shdrPtr(elf.shndx.dynsym)) {
12331227 inline else => |shdr, class| elf.targetLoad(&shdr.size) + len * @sizeOf(class.ElfN().Sym),
12341228 };
1235 _, const dynsym_cur_size = elf.shndx.dynsym.get(elf).ni.location(&elf.mf).resolve(&elf.mf);
1236 if (dynsym_cur_size < dynsym_need_size) {
1237 const new_size = dynsym_need_size +| dynsym_need_size / MappedFile.growth_factor;
1238 try elf.shndx.dynsym.get(elf).ni.resize(&elf.mf, gpa, new_size);
1239 }
1229 try elf.ensureNodeSize(elf.shndx.dynsym.get(elf).ni, dynsym_need_size);
12401230
12411231 try elf.ensureUnusedPltCapacity(len);
12421232 }
12431233 },
12441234 }
12451235}
1246fn ensureUnusedPltCapacity(elf: *Elf, len: u32) !void {
1236fn ensureUnusedPltCapacity(elf: *Elf, len: u32) Error!void {
12471237 const gpa = elf.base.comp.gpa;
12481238
12491239 try elf.shndx.rela_plt.relaEnsureAdditionalCapacity(elf, len);
......@@ -1256,30 +1246,18 @@ fn ensureUnusedPltCapacity(elf: *Elf, len: u32) !void {
12561246 .X86_64 => {
12571247 // Ensure the `.plt` section's node is big enough
12581248 const plt_need_size: usize = 16 * (1 + need_plt_capacity);
1259 _, const plt_cur_size = elf.shndx.plt.get(elf).ni.location(&elf.mf).resolve(&elf.mf);
1260 if (plt_cur_size < plt_need_size) {
1261 const new_size = plt_need_size +| plt_need_size / MappedFile.growth_factor;
1262 try elf.shndx.plt.get(elf).ni.resize(&elf.mf, gpa, new_size);
1263 }
1249 try elf.ensureNodeSize(elf.shndx.plt.get(elf).ni, plt_need_size);
12641250
12651251 // Ensure the `.got.plt` section's node is big enough
12661252 const got_plt_need_size: usize = switch (elf.identClass()) {
12671253 .NONE, _ => unreachable,
12681254 inline else => |class| @sizeOf(class.ElfN().Addr) * (3 + need_plt_capacity),
12691255 };
1270 _, const got_plt_cur_size = elf.shndx.got_plt.get(elf).ni.location(&elf.mf).resolve(&elf.mf);
1271 if (got_plt_cur_size < got_plt_need_size) {
1272 const new_size = got_plt_need_size +| got_plt_need_size / MappedFile.growth_factor;
1273 try elf.shndx.got_plt.get(elf).ni.resize(&elf.mf, gpa, new_size);
1274 }
1256 try elf.ensureNodeSize(elf.shndx.got_plt.get(elf).ni, got_plt_need_size);
12751257
12761258 // Ensure the `.plt.sec` section's node is big enough
12771259 const plt_sec_need_size: usize = 16 * need_plt_capacity;
1278 _, const plt_sec_cur_size = elf.shndx.plt_sec.get(elf).ni.location(&elf.mf).resolve(&elf.mf);
1279 if (plt_sec_cur_size < plt_sec_need_size) {
1280 const new_size = plt_sec_need_size +| plt_sec_need_size / MappedFile.growth_factor;
1281 try elf.shndx.plt_sec.get(elf).ni.resize(&elf.mf, gpa, new_size);
1282 }
1260 try elf.ensureNodeSize(elf.shndx.plt_sec.get(elf).ni, plt_sec_need_size);
12831261 },
12841262 }
12851263}
......@@ -1375,7 +1353,7 @@ const AddGlobalSymbolOptions = struct {
13751353 const Name = struct {
13761354 strtab: String(.strtab),
13771355 dynstr: String(.dynstr),
1378 fn string(elf: *Elf, slice: []const u8) !Name {
1356 fn string(elf: *Elf, slice: []const u8) Error!Name {
13791357 return .{
13801358 .strtab = try elf.string(.strtab, slice),
13811359 .dynstr = switch (elf.shndx.dynsym) {
......@@ -2205,7 +2183,14 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId {
22052183 const s: Symbol.Id = .local(lsi);
22062184 return s.toTypeErased();
22072185}
2208pub fn lazySymbol(elf: *Elf, lazy: link.File.LazySymbol) !link.File.SymbolId {
2186pub fn lazySymbol(elf: *Elf, lazy: link.File.LazySymbol) link.Error!link.File.SymbolId {
2187 const diags = &elf.base.comp.link_diags;
2188 return elf.lazySymbolInner(lazy) catch |err| switch (err) {
2189 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
2190 else => |e| return e,
2191 };
2192}
2193fn lazySymbolInner(elf: *Elf, lazy: link.File.LazySymbol) Error!link.File.SymbolId {
22092194 const gpa = elf.base.comp.gpa;
22102195
22112196 try elf.ensureUnusedSymbolCapacity(1, .all_local);
......@@ -2246,13 +2231,21 @@ pub fn lazySymbol(elf: *Elf, lazy: link.File.LazySymbol) !link.File.SymbolId {
22462231 const s: Symbol.Id = .local(gop.value_ptr.lsi);
22472232 return s.toTypeErased();
22482233}
2249pub fn externSymbol(elf: *Elf, opts: struct {
2234pub const ExternSymbolOpts = struct {
22502235 name: []const u8,
22512236 lib_name: ?[]const u8,
22522237 type: std.elf.STT,
22532238 linkage: std.lang.GlobalLinkage = .strong,
22542239 visibility: std.lang.SymbolVisibility = .default,
2255}) !link.File.SymbolId {
2240};
2241pub fn externSymbol(elf: *Elf, opts: ExternSymbolOpts) link.Error!link.File.SymbolId {
2242 const diags = &elf.base.comp.link_diags;
2243 return elf.externSymbolInner(opts) catch |err| switch (err) {
2244 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
2245 else => |e| return e,
2246 };
2247}
2248fn externSymbolInner(elf: *Elf, opts: ExternSymbolOpts) Error!link.File.SymbolId {
22562249 try elf.ensureUnusedSymbolCapacity(1, .maybe_global);
22572250 const symbol = elf.addGlobalSymbolAssumeCapacity(.{
22582251 .node = .none,
......@@ -2265,7 +2258,7 @@ pub fn externSymbol(elf: *Elf, opts: struct {
22652258 .internal => @panic("TODO internal extern symbol"),
22662259 .strong => .strong,
22672260 .weak => .weak,
2268 .link_once => return error.LinkOnceUnsupported,
2261 .link_once => return elf.base.comp.link_diags.fail("TODO(Elf2): link_once is not supported", .{}),
22692262 },
22702263 .visibility = switch (opts.visibility) {
22712264 .default => .DEFAULT,
......@@ -2285,12 +2278,20 @@ pub fn addReloc(
22852278 target: link.File.SymbolId,
22862279 addend: i64,
22872280 @"type": MachineRelocType,
2288) !void {
2281) link.Error!void {
22892282 const node: MappedFile.Node.Index = Node.fromAtom(atom);
2290 try elf.ensureUnusedRelocCapacity(node, 1);
2291 try elf.addRelocAssumeCapacity(node, offset, .fromTypeErased(target), addend, @"type");
2283 const diags = &elf.base.comp.link_diags;
2284 elf.ensureUnusedRelocCapacity(node, 1) catch |err| switch (err) {
2285 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
2286 else => |e| return e,
2287 };
2288 elf.addRelocAssumeCapacity(node, offset, .fromTypeErased(target), addend, @"type") catch |err| switch (err) {
2289 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
2290 else => |e| return e,
2291 };
22922292}
2293pub fn navSymbol(elf: *Elf, nav_index: InternPool.Nav.Index) !link.File.SymbolId {
2293pub fn navSymbol(elf: *Elf, nav_index: InternPool.Nav.Index) link.Error!link.File.SymbolId {
2294 const diags = &elf.base.comp.link_diags;
22942295 const zcu = elf.base.comp.zcu.?;
22952296 const ip = &zcu.intern_pool;
22962297 const nav = ip.getNav(nav_index);
......@@ -2303,7 +2304,10 @@ pub fn navSymbol(elf: *Elf, nav_index: InternPool.Nav.Index) !link.File.SymbolId
23032304 .visibility = @"extern".visibility,
23042305 });
23052306 }
2306 const nmi = try elf.navMapIndex(zcu, nav_index);
2307 const nmi = elf.navMapIndex(zcu, nav_index) catch |err| switch (err) {
2308 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
2309 else => |e| return e,
2310 };
23072311 const s: Symbol.Id = .local(nmi.symbol(elf));
23082312 return s.toTypeErased();
23092313}
......@@ -2311,8 +2315,12 @@ pub fn uavSymbol(
23112315 elf: *Elf,
23122316 uav_val: InternPool.Index,
23132317 uav_align: InternPool.Alignment,
2314) !link.File.SymbolId {
2315 const umi = try elf.uavMapIndex(uav_val, uav_align);
2318) link.Error!link.File.SymbolId {
2319 const diags = &elf.base.comp.link_diags;
2320 const umi = elf.uavMapIndex(uav_val, uav_align) catch |err| switch (err) {
2321 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
2322 else => |e| return e,
2323 };
23162324 const s: Symbol.Id = .local(umi.symbol(elf));
23172325 return s.toTypeErased();
23182326}
......@@ -2321,7 +2329,7 @@ pub fn getNavVAddr(
23212329 pt: Zcu.PerThread,
23222330 nav: InternPool.Nav.Index,
23232331 reloc_info: link.File.RelocInfo,
2324) !u64 {
2332) link.Error!u64 {
23252333 _ = pt;
23262334 return elf.getVAddr(reloc_info, try elf.navSymbol(nav));
23272335}
......@@ -2329,41 +2337,33 @@ pub fn getUavVAddr(
23292337 elf: *Elf,
23302338 uav_val: InternPool.Index,
23312339 reloc_info: link.File.RelocInfo,
2332) !u64 {
2340) link.Error!u64 {
23332341 return elf.getVAddr(reloc_info, try elf.uavSymbol(uav_val, .none));
23342342}
2335pub fn getVAddr(elf: *Elf, reloc_info: link.File.RelocInfo, target: link.File.SymbolId) !u64 {
2336 const node: MappedFile.Node.Index = Node.fromAtom(reloc_info.parent.atom_index);
2337 const target_sym: Symbol.Id = .fromTypeErased(target);
2338 try elf.ensureUnusedRelocCapacity(node, 1);
2339 try elf.addRelocAssumeCapacity(
2340 node,
2343pub fn getVAddr(elf: *Elf, reloc_info: link.File.RelocInfo, target: link.File.SymbolId) link.Error!u64 {
2344 try elf.addReloc(
2345 reloc_info.parent.atom_index,
23412346 reloc_info.offset,
2342 target_sym,
2347 target,
23432348 reloc_info.addend,
23442349 .absAddr(elf),
23452350 );
2346 return target_sym.value(elf);
2351 return Symbol.Id.fromTypeErased(target).value(elf);
23472352}
23482353pub fn lowerUav(
23492354 elf: *Elf,
23502355 pt: Zcu.PerThread,
23512356 uav_val: InternPool.Index,
23522357 uav_align: InternPool.Alignment,
2353 src_loc: Zcu.LazySrcLoc,
2354) !codegen.SymbolResult {
2358) link.Error!link.File.SymbolId {
23552359 _ = pt;
2360 const diags = &elf.base.comp.link_diags;
23562361 const umi = elf.uavMapIndex(uav_val, uav_align) catch |err| switch (err) {
2357 error.OutOfMemory => |e| return e,
2358 else => |e| return .{ .fail = try Zcu.ErrorMsg.create(
2359 elf.base.comp.gpa,
2360 src_loc,
2361 "linker failed to update constant: {s}",
2362 .{@errorName(e)},
2363 ) },
2362 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
2363 else => |e| return e,
23642364 };
23652365 const s: Symbol.Id = .local(umi.symbol(elf));
2366 return .{ .sym_index = s.toTypeErased() };
2366 return s.toTypeErased();
23672367}
23682368
23692369const StringSection = enum {
......@@ -2390,7 +2390,7 @@ fn String(section: StringSection) type {
23902390 }
23912391 };
23922392}
2393fn string(elf: *Elf, comptime section: StringSection, key: []const u8) !String(section) {
2393fn string(elf: *Elf, comptime section: StringSection, key: []const u8) Error!String(section) {
23942394 const st: *StringTable = &@field(elf, @tagName(section));
23952395 return @enumFromInt(try st.get(elf, section.shndx(elf), key));
23962396}
......@@ -2424,7 +2424,7 @@ const StringTable = struct {
24242424 }
24252425 };
24262426
2427 pub fn get(st: *StringTable, elf: *Elf, shndx: Section.Index, key: []const u8) !u32 {
2427 pub fn get(st: *StringTable, elf: *Elf, shndx: Section.Index, key: []const u8) Error!u32 {
24282428 // If we are in `initHeaders` the strtab might not be initalized yet, so we need to special
24292429 // case the empty string.
24302430 if (key.len == 0) return 0;
......@@ -2450,9 +2450,7 @@ const StringTable = struct {
24502450 if (shndx == elf.shndx.dynstr) {
24512451 elf.updateDynamicEntry(std.elf.DT_STRSZ, new_size);
24522452 }
2453 _, const node_size = ni.location(&elf.mf).resolve(&elf.mf);
2454 if (new_size > node_size)
2455 try ni.resize(&elf.mf, gpa, new_size +| new_size / MappedFile.growth_factor);
2453 try elf.ensureNodeSize(ni, new_size);
24562454 const slice = ni.slice(&elf.mf)[old_size..];
24572455 @memcpy(slice[0..key.len], key);
24582456 slice[key.len] = 0;
......@@ -3615,7 +3613,13 @@ fn mapInputSection(elf: *Elf, opts: struct {
36153613 flags: std.elf.SHF,
36163614 addralign: std.elf.Xword,
36173615 entsize: std.elf.Xword,
3618}) !Section.Index {
3616}) (Error || error{
3617 UnsupportedSectionFlags,
3618 TlsSectionUnavailable,
3619 StripSection,
3620 SectionFlagsConflict,
3621 SectionTypeConflict,
3622})!Section.Index {
36193623 const gpa = elf.base.comp.gpa;
36203624 if (opts.flags.INFO_LINK or
36213625 opts.flags.LINK_ORDER or
......@@ -3733,7 +3737,7 @@ fn mapInputSection(elf: *Elf, opts: struct {
37333737 }
37343738 return existing_shndx;
37353739}
3736fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Node.NavMapIndex {
3740fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) Error!Node.NavMapIndex {
37373741 const gpa = zcu.gpa;
37383742 const ip = &zcu.intern_pool;
37393743 const nav = ip.getNav(nav_index);
......@@ -3826,7 +3830,7 @@ fn uavMapIndex(
38263830 elf: *Elf,
38273831 uav_val: InternPool.Index,
38283832 uav_align: InternPool.Alignment,
3829) !Node.UavMapIndex {
3833) Error!Node.UavMapIndex {
38303834 const gpa = elf.base.comp.gpa;
38313835 const zcu = elf.base.comp.zcu.?;
38323836
......@@ -3878,26 +3882,78 @@ fn uavMapIndex(
38783882 return umi;
38793883}
38803884
3881pub fn loadInput(elf: *Elf, input: link.Input) (Io.File.Reader.SizeError ||
3882 Io.File.Reader.Error || MappedFile.Error || error{ EndOfStream, BadMagic, LinkFailure })!void {
3883 const io = elf.base.comp.io;
3885/// Internal error set used by input parsing functions `loadObject`, `loadArchive`, `loadDso`.
3886const LoadParseInputError = Error || Io.File.SeekError || Io.Reader.Error;
3887
3888/// Returns `error.BadMagic` if a DSO or static archive has an incorrect magic number, which
3889/// indicates to the frontend that the input could be a GNU ld script instead.
3890pub fn loadInput(elf: *Elf, input: link.Input) (link.Error || error{BadMagic})!void {
3891 const diags = &elf.base.comp.link_diags;
3892 return elf.loadInputInner(input) catch |err| switch (err) {
3893 else => |e| return e,
3894 error.MappedFileIo => return diags.fail(
3895 "failed to write output file: {t}",
3896 .{elf.mf.io_err.?},
3897 ),
3898 };
3899}
3900fn loadInputInner(elf: *Elf, input: link.Input) (Error || error{BadMagic})!void {
3901 const comp = elf.base.comp;
3902 const diags = &comp.link_diags;
3903 const io = comp.io;
38843904 var buf: [4096]u8 = undefined;
38853905 switch (input) {
38863906 .object => |object| {
38873907 var fr = object.file.reader(io, &buf);
38883908 elf.loadObject(object.path, null, &fr, .{
38893909 .offset = fr.logicalPos(),
3890 .size = try fr.getSize(),
3910 .size = fr.getSize() catch |err| switch (err) {
3911 error.Canceled => |e| return e,
3912 else => |e| return diags.fail(
3913 "failed to stat \"{f}\": {t}",
3914 .{ object.path.fmtEscapeString(), e },
3915 ),
3916 },
38913917 }) catch |err| switch (err) {
3892 error.ReadFailed => return fr.err.?,
38933918 else => |e| return e,
3919 error.EndOfStream => return diags.failParse(
3920 object.path,
3921 "unexpected eof",
3922 .{},
3923 ),
3924 error.AccessDenied, error.Unexpected, error.Unseekable => |e| return diags.fail(
3925 "failed to read \"{f}\": {t}",
3926 .{ object.path.fmtEscapeString(), e },
3927 ),
3928 error.ReadFailed => switch (fr.err.?) {
3929 error.Canceled => |e| return e,
3930 else => |e| return diags.fail(
3931 "failed to read \"{f}\": {t}",
3932 .{ object.path.fmtEscapeString(), e },
3933 ),
3934 },
38943935 };
38953936 },
38963937 .archive => |archive| {
38973938 var fr = archive.file.reader(io, &buf);
38983939 elf.loadArchive(archive.path, &fr) catch |err| switch (err) {
3899 error.ReadFailed => return fr.err.?,
39003940 else => |e| return e,
3941 error.EndOfStream => return diags.failParse(
3942 archive.path,
3943 "unexpected eof",
3944 .{},
3945 ),
3946 error.AccessDenied, error.Unexpected, error.Unseekable => |e| return diags.fail(
3947 "failed to read \"{f}\": {t}",
3948 .{ archive.path.fmtEscapeString(), e },
3949 ),
3950 error.ReadFailed => switch (fr.err.?) {
3951 error.Canceled => |e| return e,
3952 else => |e| return diags.fail(
3953 "failed to read \"{f}\": {t}",
3954 .{ archive.path.fmtEscapeString(), e },
3955 ),
3956 },
39013957 };
39023958 },
39033959 .res => unreachable,
......@@ -3905,8 +3961,23 @@ pub fn loadInput(elf: *Elf, input: link.Input) (Io.File.Reader.SizeError ||
39053961 try elf.needed.ensureUnusedCapacity(elf.base.comp.gpa, 1);
39063962 var fr = dso.file.reader(io, &buf);
39073963 elf.loadDso(dso.path, &fr) catch |err| switch (err) {
3908 error.ReadFailed => return fr.err.?,
39093964 else => |e| return e,
3965 error.EndOfStream => return diags.failParse(
3966 dso.path,
3967 "unexpected eof",
3968 .{},
3969 ),
3970 error.AccessDenied, error.Unexpected, error.Unseekable => |e| return diags.fail(
3971 "failed to read \"{f}\": {t}",
3972 .{ dso.path.fmtEscapeString(), e },
3973 ),
3974 error.ReadFailed => switch (fr.err.?) {
3975 error.Canceled => |e| return e,
3976 else => |e| return diags.fail(
3977 "failed to read \"{f}\": {t}",
3978 .{ dso.path.fmtEscapeString(), e },
3979 ),
3980 },
39103981 };
39113982 },
39123983 .dso_exact => |dso_exact| {
......@@ -3919,14 +3990,22 @@ pub fn loadInput(elf: *Elf, input: link.Input) (Io.File.Reader.SizeError ||
39193990 },
39203991 }
39213992}
3922fn loadArchive(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) !void {
3993fn loadArchive(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) (LoadParseInputError || error{BadMagic})!void {
39233994 const comp = elf.base.comp;
39243995 const gpa = comp.gpa;
39253996 const diags = &comp.link_diags;
39263997 const r = &fr.interface;
39273998
39283999 log.debug("loadArchive({f})", .{path.fmtEscapeString()});
3929 if (!std.mem.eql(u8, try r.take(std.elf.ARMAG.len), std.elf.ARMAG)) return error.BadMagic;
4000 {
4001 const magic = r.take(std.elf.ARMAG.len) catch |err| switch (err) {
4002 error.ReadFailed => |e| return e,
4003 error.EndOfStream => return error.BadMagic,
4004 };
4005 if (!std.mem.eql(u8, magic, std.elf.ARMAG)) {
4006 return error.BadMagic;
4007 }
4008 }
39304009 var strtab: std.Io.Writer.Allocating = .init(gpa);
39314010 defer strtab.deinit();
39324011 while (r.takeStruct(std.elf.ar_hdr, native_endian)) |header| {
......@@ -3987,7 +4066,7 @@ fn loadObject(
39874066 member: ?[]const u8,
39884067 fr: *Io.File.Reader,
39894068 fl: MappedFile.Node.FileLocation,
3990) !void {
4069) LoadParseInputError!void {
39914070 const comp = elf.base.comp;
39924071 const gpa = comp.gpa;
39934072 const diags = &comp.link_diags;
......@@ -3995,7 +4074,14 @@ fn loadObject(
39954074
39964075 const input_index: Node.InputIndex = @enumFromInt(elf.inputs.items.len);
39974076 log.debug("loadObject({f}{f})", .{ path.fmtEscapeString(), fmtMemberString(member) });
3998 try elf.checkInputIdent(path, r);
4077 elf.checkInputIdent(path, r) catch |err| switch (err) {
4078 else => |e| return e,
4079 error.BadMagic => return diags.failParse(
4080 path,
4081 "bad ELF magic",
4082 .{},
4083 ),
4084 };
39994085 try elf.ensureUnusedSymbolCapacity(1, .all_local);
40004086 try elf.inputs.ensureUnusedCapacity(gpa, 1);
40014087 const file_symbol = elf.addLocalSymbolAssumeCapacity(.{
......@@ -4376,7 +4462,7 @@ fn loadObject(
43764462 },
43774463 }
43784464}
4379fn loadDso(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) !void {
4465fn loadDso(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) (LoadParseInputError || error{BadMagic})!void {
43804466 const comp = elf.base.comp;
43814467 const gpa = comp.gpa;
43824468 const diags = &comp.link_diags;
......@@ -4593,23 +4679,29 @@ fn loadDso(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) !void {
45934679
45944680/// Validates that the `std.elf.Ident` present at the start of `r` is a compatible link input.
45954681///
4596/// Returns an error if it is incompatible, or if the ident is broken or missing.
4682/// Returns an error if it is incompatible, or if the ident is broken or missing---usually
4683/// `error.AlreadyReported`, but if the magic number is missing or incorrect, returns
4684/// `error.BadMagic` instead.
45974685///
45984686/// Does not advance the position of `r`. Requires `r` to have a 16-byte buffer.
45994687fn checkInputIdent(
46004688 elf: *const Elf,
46014689 path: std.Build.Cache.Path,
46024690 r: *Io.Reader,
4603) !void {
4691) error{ BadMagic, EndOfStream, AlreadyReported, ReadFailed }!void {
46044692 const diags = &elf.base.comp.link_diags;
46054693
4606 const ident = try r.peekStructPointer(std.elf.Ident);
4607 const target: *const std.elf.Ident = @ptrCast(elf.mf.memory_map.memory[0..@sizeOf(std.elf.Ident)]);
4608
4609 if (!std.mem.eql(u8, &ident.magic, std.elf.MAGIC)) {
4694 const magic = r.peek(std.elf.MAGIC.len) catch |err| switch (err) {
4695 error.ReadFailed => |e| return e,
4696 error.EndOfStream => return error.BadMagic,
4697 };
4698 if (!std.mem.eql(u8, magic, std.elf.MAGIC)) {
46104699 return error.BadMagic;
46114700 }
46124701
4702 const ident = try r.peekStructPointer(std.elf.Ident);
4703 const target: *const std.elf.Ident = @ptrCast(elf.mf.memory_map.memory[0..@sizeOf(std.elf.Ident)]);
4704
46134705 if (ident.class != target.class) return diags.failParse(
46144706 path,
46154707 "bad ELF class ({?s})",
......@@ -4649,7 +4741,7 @@ fn createInitFiniArraySection(
46494741 shndx: *Section.Index,
46504742 comptime name: []const u8,
46514743 @"type": std.elf.SHT,
4652) !void {
4744) Error!void {
46534745 assert(shndx.* == .UNDEF);
46544746 const gpa = elf.base.comp.gpa;
46554747 const addr_align: std.mem.Alignment = switch (elf.identClass()) {
......@@ -4722,14 +4814,15 @@ fn updateInitFiniArraySectionSize(
47224814 Symbol.Id.global(end_sym_name).flushMoved(elf, end_vaddr);
47234815}
47244816
4725pub fn prelink(elf: *Elf, prog_node: std.Progress.Node) !void {
4817pub fn prelink(elf: *Elf, prog_node: std.Progress.Node) link.Error!void {
47264818 _ = prog_node;
4819 const diags = &elf.base.comp.link_diags;
47274820 elf.prelinkInner() catch |err| switch (err) {
4728 error.OutOfMemory => |e| return e,
4729 else => |e| return elf.base.comp.link_diags.fail("prelink failed: {t}", .{e}),
4821 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
4822 else => |e| return e,
47304823 };
47314824}
4732fn prelinkInner(elf: *Elf) !void {
4825fn prelinkInner(elf: *Elf) Error!void {
47334826 const comp = elf.base.comp;
47344827 const gpa = comp.gpa;
47354828 try elf.ensureUnusedSymbolCapacity(1, .all_local);
......@@ -4954,7 +5047,7 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct {
49545047 entsize: std.elf.Word = 0,
49555048 node_align: std.mem.Alignment = .@"1",
49565049 fixed: bool = false,
4957}) !Section.Index {
5050}) Error!Section.Index {
49585051 switch (opts.type) {
49595052 .NULL => assert(opts.size == 0),
49605053 .PROGBITS => assert(opts.size > 0),
......@@ -4996,9 +5089,7 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct {
49965089 break :shndx .{ @enumFromInt(shndx), @as(u64, elf.targetLoad(&ehdr.shentsize)) * @as(u64, shnum) };
49975090 },
49985091 };
4999 _, const shdr_node_size = elf.ni.shdr.location(&elf.mf).resolve(&elf.mf);
5000 if (new_shdr_size > shdr_node_size)
5001 try elf.ni.shdr.resize(&elf.mf, gpa, new_shdr_size +| new_shdr_size / MappedFile.growth_factor);
5092 try elf.ensureNodeSize(elf.ni.shdr, new_shdr_size);
50025093 const ni = try elf.mf.addLastChildNode(gpa, switch (elf.ehdrField(.type)) {
50035094 .NONE, .CORE, _ => unreachable,
50045095 .REL => elf.ni.file,
......@@ -5045,7 +5136,7 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct {
50455136 return shndx;
50465137}
50475138
5048fn ensureUnusedRelocCapacity(elf: *Elf, node: MappedFile.Node.Index, len: usize) !void {
5139fn ensureUnusedRelocCapacity(elf: *Elf, node: MappedFile.Node.Index, len: usize) Error!void {
50495140 if (len == 0) return;
50505141 const gpa = elf.base.comp.gpa;
50515142 try elf.symbol_relocs.ensureUnusedCapacity(gpa, len);
......@@ -5090,14 +5181,11 @@ fn ensureUnusedRelocCapacity(elf: *Elf, node: MappedFile.Node.Index, len: usize)
50905181 try elf.tls_size_symbol_relocs.ensureUnusedCapacity(gpa, len);
50915182 const new_got_entries = len * 2; // at worst, every reloc is a new TLSGD
50925183 try elf.got.ensureUnusedCapacity(gpa, new_got_entries);
5093 const got_ni = elf.shndx.got.get(elf).ni;
5094 _, const got_node_size = got_ni.location(&elf.mf).resolve(&elf.mf);
50955184 const need_got_size = switch (class) {
50965185 .NONE, _ => unreachable,
50975186 inline else => |ct_class| (elf.got.count() + new_got_entries) * @sizeOf(ct_class.ElfN().Addr),
50985187 };
5099 if (need_got_size > got_node_size)
5100 try got_ni.resize(&elf.mf, gpa, need_got_size +| need_got_size / MappedFile.growth_factor);
5188 try elf.ensureNodeSize(elf.shndx.got.get(elf).ni, need_got_size);
51015189
51025190 if (elf.shndx.dynamic != .UNDEF) {
51035191 try elf.shndx.rela_dyn.relaEnsureAdditionalCapacity(elf, new_got_entries);
......@@ -5114,7 +5202,7 @@ fn addRelocAssumeCapacity(
51145202 target: Symbol.Id,
51155203 addend: i64,
51165204 @"type": MachineRelocType,
5117) !void {
5205) Error!void {
51185206 assert(node != .none);
51195207 switch (elf.ehdrField(.type)) {
51205208 .NONE, .CORE, _ => unreachable,
......@@ -5233,7 +5321,7 @@ fn addSymbolRelocAssumeCapacity(
52335321 target: Symbol.Id,
52345322 addend: i64,
52355323 @"type": SymbolReloc.Type,
5236) !void {
5324) Error!void {
52375325 assert(elf.ehdrField(.type) != .REL);
52385326
52395327 const rela_index: Section.RelaIndex.Optional = r: {
......@@ -5594,7 +5682,7 @@ fn nodeWantsDsoRelocation(elf: *Elf, node: MappedFile.Node.Index) enum { yes, ye
55945682/// global where needed---the caller does not need to do this.
55955683///
55965684/// Asserts that `elf.shndx.dynamic != .UNDEF` and that `global_name` refers to an *undefined* global.
5597fn maybeAddCopyRelocation(elf: *Elf, global_name: String(.strtab)) !bool {
5685fn maybeAddCopyRelocation(elf: *Elf, global_name: String(.strtab)) Error!bool {
55985686 assert(elf.shndx.dynamic != .UNDEF);
55995687
56005688 const gpa = elf.base.comp.gpa;
......@@ -5657,16 +5745,14 @@ fn maybeAddCopyRelocation(elf: *Elf, global_name: String(.strtab)) !bool {
56575745 return true;
56585746}
56595747
5660pub fn updateNav(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
5748pub fn updateNav(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) link.Error!void {
5749 const diags = &elf.base.comp.link_diags;
56615750 elf.updateNavInner(pt, nav_index) catch |err| switch (err) {
5662 error.OutOfMemory,
5663 error.Overflow,
5664 error.RelocationNotByteAligned,
5665 => |e| return e,
5666 else => |e| return elf.base.cgFail(nav_index, "linker failed to update variable: {t}", .{e}),
5751 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
5752 else => |e| return e,
56675753 };
56685754}
5669fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void {
5755fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) Error!void {
56705756 const zcu = pt.zcu;
56715757 const gpa = zcu.gpa;
56725758 const ip = &zcu.intern_pool;
......@@ -5689,12 +5775,11 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index)
56895775 codegen.generateSymbol(
56905776 &elf.base,
56915777 pt,
5692 zcu.navSrcLoc(nav_index),
56935778 .fromInterned(nav.resolved.?.value),
56945779 &nw.interface,
56955780 .{ .atom_index = Node.toAtom(ni) },
56965781 ) catch |err| switch (err) {
5697 error.WriteFailed => return error.OutOfMemory,
5782 error.WriteFailed => return nw.err.?,
56985783 else => |e| return e,
56995784 };
57005785 switch (elf.symPtr(nmi.symbol(elf).index())) {
......@@ -5707,18 +5792,11 @@ pub fn updateFunc(
57075792 pt: Zcu.PerThread,
57085793 func_index: InternPool.Index,
57095794 mir: *const codegen.AnyMir,
5710) !void {
5795) link.Error!void {
5796 const diags = &elf.base.comp.link_diags;
57115797 elf.updateFuncInner(pt, func_index, mir) catch |err| switch (err) {
5712 error.OutOfMemory,
5713 error.Overflow,
5714 error.RelocationNotByteAligned,
5715 error.CodegenFail,
5716 => |e| return e,
5717 else => |e| return elf.base.cgFail(
5718 pt.zcu.funcInfo(func_index).owner_nav,
5719 "linker failed to update function: {s}",
5720 .{@errorName(e)},
5721 ),
5798 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
5799 else => |e| return e,
57225800 };
57235801}
57245802fn updateFuncInner(
......@@ -5726,7 +5804,7 @@ fn updateFuncInner(
57265804 pt: Zcu.PerThread,
57275805 func_index: InternPool.Index,
57285806 mir: *const codegen.AnyMir,
5729) !void {
5807) Error!void {
57305808 const zcu = pt.zcu;
57315809 const gpa = zcu.gpa;
57325810 const ip = &zcu.intern_pool;
......@@ -5748,7 +5826,6 @@ fn updateFuncInner(
57485826 codegen.emitFunction(
57495827 &elf.base,
57505828 pt,
5751 zcu.navSrcLoc(func.owner_nav),
57525829 func_index,
57535830 Node.toAtom(ni),
57545831 mir,
......@@ -5763,14 +5840,14 @@ fn updateFuncInner(
57635840 }
57645841}
57655842
5766pub fn updateErrorData(elf: *Elf, pt: Zcu.PerThread) !void {
5843pub fn updateErrorData(elf: *Elf, pt: Zcu.PerThread) link.Error!void {
5844 const diags = &elf.base.comp.link_diags;
57675845 elf.flushLazy(pt, .{
57685846 .kind = .const_data,
57695847 .index = @intCast(elf.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return),
57705848 }) catch |err| switch (err) {
5771 error.OutOfMemory => |e| return e,
5772 error.CodegenFail => return error.LinkFailure,
5773 else => |e| return elf.base.comp.link_diags.fail("updateErrorData failed: {t}", .{e}),
5849 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
5850 else => |e| return e,
57745851 };
57755852}
57765853
......@@ -5779,8 +5856,9 @@ pub fn flush(
57795856 arena: std.mem.Allocator,
57805857 tid: Zcu.PerThread.Id,
57815858 prog_node: std.Progress.Node,
5782) !void {
5859) link.Error!void {
57835860 const comp = elf.base.comp;
5861 const diags = &comp.link_diags;
57845862 _ = arena;
57855863 _ = prog_node;
57865864
......@@ -5791,12 +5869,12 @@ pub fn flush(
57915869 any_undef = true;
57925870 comp.link_diags.addError("undefined global symbol '{s}'", .{name.slice(elf)});
57935871 }
5794 if (any_undef) return error.LinkFailure;
5872 if (any_undef) return error.AlreadyReported;
57955873 }
57965874
57975875 elf.updateDynamicTextrel() catch |err| switch (err) {
5798 error.OutOfMemory => |e| return e,
5799 else => |e| return elf.base.comp.link_diags.fail("updateDynamicTextrel failed: {t}", .{e}),
5876 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
5877 else => |e| return e,
58005878 };
58015879
58025880 while (try elf.idle(tid)) {}
......@@ -5812,8 +5890,8 @@ pub fn flush(
58125890 .named => |named| named,
58135891 };
58145892 const sym_name_strtab = elf.string(.strtab, sym_name_slice) catch |err| switch (err) {
5815 error.Canceled => |e| return e,
5816 else => |e| return comp.link_diags.fail("flush write failed: {t}", .{e}),
5893 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
5894 else => |e| return e,
58175895 };
58185896 if (elf.globalByName(sym_name_strtab) == null) break :entry 0;
58195897 break :entry Symbol.Id.global(sym_name_strtab).value(elf);
......@@ -5823,11 +5901,11 @@ pub fn flush(
58235901 }
58245902
58255903 elf.mf.flush() catch |err| switch (err) {
5826 error.Canceled => |e| return e,
5827 else => |e| return comp.link_diags.fail("flush write failed: {t}", .{e}),
5904 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
5905 else => |e| return e,
58285906 };
58295907}
5830fn updateDynamicTextrel(elf: *Elf) !void {
5908fn updateDynamicTextrel(elf: *Elf) Error!void {
58315909 if (elf.shndx.dynamic == .UNDEF) return;
58325910 const dynamic_ni = elf.shndx.dynamic.get(elf).ni;
58335911 switch (elf.shdrPtr(elf.shndx.dynamic)) {
......@@ -5844,10 +5922,7 @@ fn updateDynamicTextrel(elf: *Elf) !void {
58445922 if (!has_textrel) {
58455923 // Add a DT_TEXTREL entry before the final DT_NULL entry.
58465924 const new_size = cur_size + @sizeOf([2]class.ElfN().Addr);
5847 _, const node_size = dynamic_ni.location(&elf.mf).resolve(&elf.mf);
5848 if (node_size < new_size) {
5849 try dynamic_ni.resize(&elf.mf, elf.base.comp.gpa, new_size);
5850 }
5925 try elf.ensureNodeSize(dynamic_ni, new_size);
58515926 elf.targetStore(&shdr.size, new_size);
58525927 const new_entries: [][2]class.ElfN().Addr = @ptrCast(@alignCast(
58535928 dynamic_ni.slice(&elf.mf)[0..@intCast(new_size)],
......@@ -5869,18 +5944,16 @@ fn updateDynamicTextrel(elf: *Elf) !void {
58695944 }
58705945}
58715946
5872pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) !bool {
5947pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool {
58735948 const comp = elf.base.comp;
5949 const diags = &comp.link_diags;
58745950 task: {
58755951 while (elf.pending_uavs.pop()) |umi| {
58765952 const sub_prog_node = elf.idleProgNode(tid, elf.const_prog_node, .{ .uav = umi });
58775953 defer sub_prog_node.end();
58785954 elf.flushUav(.{ .zcu = comp.zcu.?, .tid = tid }, umi) catch |err| switch (err) {
5879 error.OutOfMemory => |e| return e,
5880 else => |e| return comp.link_diags.fail(
5881 "linker failed to lower constant: {t}",
5882 .{e},
5883 ),
5955 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
5956 else => |e| return e,
58845957 };
58855958 break :task;
58865959 }
......@@ -5903,11 +5976,8 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) !bool {
59035976 );
59045977 defer sub_prog_node.end();
59055978 elf.flushLazy(pt, lmr) catch |err| switch (err) {
5906 error.OutOfMemory => |e| return e,
5907 else => |e| return comp.link_diags.fail(
5908 "linker failed to lower lazy {s}: {t}",
5909 .{ kind, e },
5910 ),
5979 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
5980 else => |e| return e,
59115981 };
59125982 break :task;
59135983 };
......@@ -5917,18 +5987,8 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) !bool {
59175987 const sub_prog_node = elf.idleProgNode(tid, elf.input_prog_node, elf.getNode(isi.node(elf)));
59185988 defer sub_prog_node.end();
59195989 elf.flushInputSection(isi) catch |err| switch (err) {
5920 else => |e| {
5921 const ii = isi.input(elf);
5922 return comp.link_diags.fail(
5923 "linker failed to read input section '{s}' from \"{f}{f}\": {t}",
5924 .{
5925 elf.getNode(isi.node(elf).parent(&elf.mf)).section.name(elf).slice(elf),
5926 ii.path(elf).fmtEscapeString(),
5927 fmtMemberString(ii.member(elf)),
5928 e,
5929 },
5930 );
5931 },
5990 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
5991 else => |e| return e,
59325992 };
59335993 break :task;
59345994 }
......@@ -6005,10 +6065,9 @@ fn flushUav(
60056065 elf: *Elf,
60066066 pt: Zcu.PerThread,
60076067 umi: Node.UavMapIndex,
6008) !void {
6068) Error!void {
60096069 const comp = elf.base.comp;
60106070 const gpa = comp.gpa;
6011 const zcu = pt.zcu;
60126071
60136072 const uav_val = umi.uavValue(elf);
60146073 const ni = umi.symbol(elf).index().ptr(elf).node;
......@@ -6017,23 +6076,14 @@ fn flushUav(
60176076 var nw: MappedFile.Node.Writer = undefined;
60186077 ni.writer(&elf.mf, gpa, &nw);
60196078 defer nw.deinit();
6020 // TODO: UAV lowering should never require source locations.
6021 const dummy_src_loc: Zcu.LazySrcLoc = .{
6022 .base_node_inst = try zcu.intern_pool.trackZir(gpa, comp.io, pt.tid, .{
6023 .file = zcu.module_roots.get(zcu.std_mod).?.unwrap().?,
6024 .inst = .main_struct_inst,
6025 }),
6026 .offset = .{ .byte_abs = 0 },
6027 };
60286079 codegen.generateSymbol(
60296080 &elf.base,
60306081 pt,
6031 dummy_src_loc,
60326082 .fromInterned(uav_val),
60336083 &nw.interface,
60346084 .{ .atom_index = Node.toAtom(ni) },
60356085 ) catch |err| switch (err) {
6036 error.WriteFailed => return error.OutOfMemory,
6086 error.WriteFailed => return nw.err.?,
60376087 else => |e| return e,
60386088 };
60396089 switch (elf.symPtr(umi.symbol(elf).index())) {
......@@ -6044,7 +6094,7 @@ fn flushUav(
60446094 assert(ni.hasMoved(&elf.mf));
60456095}
60466096
6047fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
6097fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) Error!void {
60486098 const zcu = pt.zcu;
60496099 const gpa = zcu.gpa;
60506100
......@@ -6060,44 +6110,70 @@ fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void {
60606110 var nw: MappedFile.Node.Writer = undefined;
60616111 ni.writer(&elf.mf, gpa, &nw);
60626112 defer nw.deinit();
6063 try codegen.generateLazySymbol(
6113 codegen.generateLazySymbol(
60646114 &elf.base,
60656115 pt,
6066 Type.fromInterned(lazy.ty).srcLocOrNull(pt.zcu) orelse .unneeded,
60676116 lazy,
60686117 &required_alignment,
60696118 &nw.interface,
60706119 .none,
60716120 .{ .atom_index = Node.toAtom(ni) },
6072 );
6121 ) catch |err| switch (err) {
6122 error.WriteFailed => return nw.err.?,
6123 else => |e| return e,
6124 };
60736125 switch (elf.symPtr(lmr.symbol(elf).index())) {
60746126 inline else => |sym| elf.targetStore(&sym.size, @intCast(nw.interface.end)),
60756127 }
60766128}
60776129
6078fn flushInputSection(elf: *Elf, isi: InputSection.Index) !void {
6130fn flushInputSection(elf: *Elf, isi: InputSection.Index) Error!void {
60796131 const file_loc = isi.fileLocation(elf);
60806132 if (file_loc.size == 0) return;
60816133 const comp = elf.base.comp;
60826134 const io = comp.io;
60836135 const gpa = comp.gpa;
6136 const diags = &comp.link_diags;
60846137 const ii = isi.input(elf);
60856138 const path = ii.path(elf);
6086 const file = try path.root_dir.handle.openFile(io, path.sub_path, .{});
6139 const file = path.root_dir.handle.openFile(io, path.sub_path, .{}) catch |err| switch (err) {
6140 error.Canceled => |e| return e,
6141 else => |e| return diags.fail("failed to open input file \"{f}\": {t}", .{ path.fmtEscapeString(), e }),
6142 };
60876143 defer file.close(io);
60886144 var fr = file.reader(io, &.{});
6089 try fr.seekTo(file_loc.offset);
6145 fr.seekTo(file_loc.offset) catch |err| switch (err) {
6146 error.Canceled => |e| return e,
6147 else => |e| return diags.fail("failed to read input section '{s}' from \"{f}{f}\": {t}", .{
6148 elf.getNode(isi.node(elf).parent(&elf.mf)).section.name(elf).slice(elf),
6149 path.fmtEscapeString(),
6150 fmtMemberString(ii.member(elf)),
6151 e,
6152 }),
6153 };
60906154 var nw: MappedFile.Node.Writer = undefined;
60916155 isi.node(elf).writer(&elf.mf, gpa, &nw);
60926156 defer nw.deinit();
6093 if (try nw.interface.sendFileAll(&fr, .limited(@intCast(file_loc.size))) != file_loc.size)
6094 return error.EndOfStream;
6157 const n_bytes = nw.interface.sendFileAll(&fr, .limited(@intCast(file_loc.size))) catch |err| switch (err) {
6158 error.ReadFailed => return diags.fail("failed to read input section '{s}' from \"{f}{f}\": {t}", .{
6159 elf.getNode(isi.node(elf).parent(&elf.mf)).section.name(elf).slice(elf),
6160 path.fmtEscapeString(),
6161 fmtMemberString(ii.member(elf)),
6162 fr.err orelse (fr.seek_err orelse fr.size_err.?),
6163 }),
6164 error.WriteFailed => return nw.err.?,
6165 };
6166 if (n_bytes != file_loc.size) return diags.fail("failed to read input section '{s}' from \"{f}{f}\": unexpected eof", .{
6167 elf.getNode(isi.node(elf).parent(&elf.mf)).section.name(elf).slice(elf),
6168 path.fmtEscapeString(),
6169 fmtMemberString(ii.member(elf)),
6170 });
60956171 // The input section should already be considered to have moved, because it is created as moved
60966172 // and pending calls to `flushInputSection` always happen before pending calls to `flushMoved`.
60976173 assert(isi.node(elf).hasMoved(&elf.mf));
60986174}
60996175
6100fn flushFileOffset(elf: *Elf, ni: MappedFile.Node.Index) !void {
6176fn flushFileOffset(elf: *Elf, ni: MappedFile.Node.Index) void {
61016177 switch (elf.getNode(ni)) {
61026178 else => unreachable,
61036179 .ehdr => assert(ni.fileLocation(&elf.mf, false).offset == 0),
......@@ -6118,7 +6194,7 @@ fn flushFileOffset(elf: *Elf, ni: MappedFile.Node.Index) !void {
61186194 },
61196195 }
61206196 var child_it = ni.children(&elf.mf);
6121 while (child_it.next()) |child_ni| try elf.flushFileOffset(child_ni);
6197 while (child_it.next()) |child_ni| elf.flushFileOffset(child_ni);
61226198 },
61236199 .section => |shndx| switch (elf.shdrPtr(shndx)) {
61246200 inline else => |shdr| elf.targetStore(&shdr.offset, @intCast(
......@@ -6128,14 +6204,14 @@ fn flushFileOffset(elf: *Elf, ni: MappedFile.Node.Index) !void {
61286204 }
61296205}
61306206
6131fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) !void {
6207fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void {
61326208 const trace = tracy.trace(@src());
61336209 defer trace.end();
61346210 switch (elf.getNode(ni)) {
61356211 .file => unreachable,
6136 .ehdr, .shdr => try elf.flushFileOffset(ni),
6212 .ehdr, .shdr => elf.flushFileOffset(ni),
61376213 .segment => |phndx| {
6138 try elf.flushFileOffset(ni);
6214 elf.flushFileOffset(ni);
61396215 switch (elf.phdrSlice()) {
61406216 inline else => |phdr| {
61416217 const ph = &phdr[phndx];
......@@ -6156,7 +6232,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) !void {
61566232 }
61576233 },
61586234 .section => |shndx| {
6159 try elf.flushFileOffset(ni);
6235 elf.flushFileOffset(ni);
61606236 const addr = elf.computeNodeVAddr(ni);
61616237 const old_addr: u64, const flags: std.elf.SHF = switch (elf.shdrPtr(shndx)) {
61626238 inline else => |shdr| .{
......@@ -6293,7 +6369,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) !void {
62936369 try ni.childrenMoved(elf.base.comp.gpa, &elf.mf);
62946370}
62956371
6296fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) !void {
6372fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void {
62976373 const trace = tracy.trace(@src());
62986374 defer trace.end();
62996375 _, const size = ni.location(&elf.mf).resolve(&elf.mf);
......@@ -6486,16 +6562,11 @@ pub fn updateExports(
64866562 pt: Zcu.PerThread,
64876563 exported: Zcu.Exported,
64886564 export_indices: []const Zcu.Export.Index,
6489) !void {
6565) link.Error!void {
6566 const diags = &elf.base.comp.link_diags;
64906567 return elf.updateExportsInner(pt, exported, export_indices) catch |err| switch (err) {
6491 error.OutOfMemory => error.OutOfMemory,
6492 error.LinkFailure => error.AnalysisFail,
6493 else => |e| switch (elf.base.comp.link_diags.fail(
6494 "linker failed to update exports: {t}",
6495 .{e},
6496 )) {
6497 error.LinkFailure => return error.AnalysisFail,
6498 },
6568 else => |e| return e,
6569 error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}),
64996570 };
65006571}
65016572fn updateExportsInner(
......@@ -6503,7 +6574,7 @@ fn updateExportsInner(
65036574 pt: Zcu.PerThread,
65046575 exported: Zcu.Exported,
65056576 export_indices: []const Zcu.Export.Index,
6506) !void {
6577) Error!void {
65076578 const zcu = pt.zcu;
65086579 const ip = &zcu.intern_pool;
65096580
......@@ -6543,7 +6614,7 @@ fn updateExportsInner(
65436614 .internal => @panic("TODO internal linkage"),
65446615 .strong => .strong,
65456616 .weak => .weak,
6546 .link_once => return error.LinkOnceUnsupported,
6617 .link_once => return elf.base.comp.link_diags.fail("TODO(Elf2): link_once is not supported", .{}),
65476618 },
65486619 .visibility = switch (@"export".opts.visibility) {
65496620 .default => .DEFAULT,
......@@ -6591,10 +6662,10 @@ pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) Io.Cancelable!void {
65916662pub fn printNode(
65926663 elf: *Elf,
65936664 tid: Zcu.PerThread.Id,
6594 w: *std.Io.Writer,
6665 w: *Io.Writer,
65956666 ni: MappedFile.Node.Index,
65966667 indent: usize,
6597) !void {
6668) Io.Writer.Error!void {
65986669 const node = elf.getNode(ni);
65996670 try w.splatByteAll(' ', indent);
66006671 try w.writeAll(@tagName(node));
......@@ -6698,3 +6769,15 @@ pub fn printNode(
66986769 try w.writeByte('\n');
66996770 }
67006771}
6772
6773fn ensureNodeSize(
6774 elf: *Elf,
6775 node: MappedFile.Node.Index,
6776 need_size: u64,
6777) Error!void {
6778 _, const node_size = node.location(&elf.mf).resolve(&elf.mf);
6779 if (need_size <= node_size) return;
6780 const gpa = elf.base.comp.gpa;
6781 const new_size = need_size + need_size / MappedFile.growth_factor;
6782 try node.resize(&elf.mf, gpa, new_size);
6783}
src/link/LdScript.zig+1-1
......@@ -13,7 +13,7 @@ pub fn deinit(ls: *LdScript, gpa: Allocator) void {
1313}
1414
1515pub const Error = error{
16 LinkFailure,
16 AlreadyReported,
1717 UnknownCpuArch,
1818 OutOfMemory,
1919};
src/link/Lld.zig+4-4
......@@ -255,7 +255,7 @@ pub fn flush(
255255 arena: Allocator,
256256 tid: Zcu.PerThread.Id,
257257 prog_node: std.Progress.Node,
258) link.File.FlushError!void {
258) link.Error!void {
259259 dev.check(.lld_linker);
260260 _ = tid;
261261
......@@ -277,7 +277,7 @@ pub fn flush(
277277 .wasm => wasmLink(lld, arena),
278278 };
279279 result catch |err| switch (err) {
280 error.OutOfMemory, error.LinkFailure => |e| return e,
280 error.OutOfMemory, error.AlreadyReported => |e| return e,
281281 else => |e| return lld.base.comp.link_diags.fail("failed to link with LLD: {t}", .{e}),
282282 };
283283}
......@@ -1620,7 +1620,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi
16201620 const exit_code = try lldMain(arena, argv, false);
16211621 if (exit_code == 0) return;
16221622 if (comp.clang_passthrough_mode) std.process.exit(exit_code);
1623 return error.LinkFailure;
1623 return error.AlreadyReported;
16241624 }
16251625
16261626 var stderr: []u8 = &.{};
......@@ -1720,7 +1720,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi
17201720 .exited => |code| if (code != 0) {
17211721 if (comp.clang_passthrough_mode) std.process.exit(code);
17221722 diags.lockAndParseLldStderr(argv[1], stderr);
1723 return error.LinkFailure;
1723 return error.AlreadyReported;
17241724 },
17251725 .signal => |sig| {
17261726 if (comp.clang_passthrough_mode) std.process.abort();
src/link/MachO.zig+32-29
......@@ -341,7 +341,7 @@ pub fn flush(
341341 arena: Allocator,
342342 tid: Zcu.PerThread.Id,
343343 prog_node: std.Progress.Node,
344) link.File.FlushError!void {
344) link.Error!void {
345345 const tracy = trace(@src());
346346 defer tracy.end();
347347
......@@ -490,7 +490,7 @@ pub fn flush(
490490 }
491491 };
492492
493 if (diags.hasErrors()) return error.LinkFailure;
493 if (diags.hasErrors()) return error.AlreadyReported;
494494
495495 {
496496 const index = @as(File.Index, @intCast(try self.files.addOne(gpa)));
......@@ -504,7 +504,7 @@ pub fn flush(
504504 try self.resolveSymbols();
505505 try self.convertTentativeDefsAndResolveSpecialSymbols();
506506 self.dedupLiterals() catch |err| switch (err) {
507 error.LinkFailure => |e| return e,
507 error.AlreadyReported => |e| return e,
508508 else => |e| return diags.fail("failed to deduplicate literals: {s}", .{@errorName(e)}),
509509 };
510510
......@@ -513,7 +513,7 @@ pub fn flush(
513513 }
514514
515515 self.checkDuplicates() catch |err| switch (err) {
516 error.HasDuplicates => return error.LinkFailure,
516 error.HasDuplicates => return error.AlreadyReported,
517517 else => |e| return diags.fail("failed to check for duplicate symbol definitions: {s}", .{@errorName(e)}),
518518 };
519519
......@@ -528,7 +528,7 @@ pub fn flush(
528528 self.claimUnresolved();
529529
530530 self.scanRelocs() catch |err| switch (err) {
531 error.HasUndefinedSymbols => return error.LinkFailure,
531 error.HasUndefinedSymbols => return error.AlreadyReported,
532532 else => |e| return diags.fail("failed to scan relocations: {s}", .{@errorName(e)}),
533533 };
534534
......@@ -542,7 +542,7 @@ pub fn flush(
542542
543543 try self.initSegments();
544544 self.allocateSections() catch |err| switch (err) {
545 error.LinkFailure => |e| return e,
545 error.AlreadyReported => |e| return e,
546546 else => |e| return diags.fail("failed to allocate sections: {s}", .{@errorName(e)}),
547547 };
548548 self.allocateSegments();
......@@ -558,7 +558,7 @@ pub fn flush(
558558
559559 if (self.getZigObject()) |zo| {
560560 zo.resolveRelocs(self) catch |err| switch (err) {
561 error.ResolveFailed => return error.LinkFailure,
561 error.ResolveFailed => return error.AlreadyReported,
562562 else => |e| return e,
563563 };
564564 }
......@@ -567,7 +567,7 @@ pub fn flush(
567567 try self.writeSectionsToFile();
568568 try self.allocateLinkeditSegment();
569569 self.writeLinkeditSectionsToFile() catch |err| switch (err) {
570 error.OutOfMemory, error.LinkFailure => |e| return e,
570 error.OutOfMemory, error.AlreadyReported => |e| return e,
571571 else => |e| return diags.fail("failed to write linkedit sections to file: {t}", .{e}),
572572 };
573573
......@@ -594,11 +594,11 @@ pub fn flush(
594594
595595 const ncmds, const sizeofcmds, const uuid_cmd_offset = self.writeLoadCommands() catch |err| switch (err) {
596596 error.WriteFailed => unreachable,
597 error.OutOfMemory, error.LinkFailure => |e| return e,
597 error.OutOfMemory, error.AlreadyReported => |e| return e,
598598 };
599599 try self.writeHeader(ncmds, sizeofcmds);
600600 self.writeUuid(uuid_cmd_offset, self.requiresCodeSig()) catch |err| switch (err) {
601 error.OutOfMemory, error.LinkFailure => |e| return e,
601 error.OutOfMemory, error.AlreadyReported => |e| return e,
602602 else => |e| return diags.fail("failed to calculate and write uuid: {s}", .{@errorName(e)}),
603603 };
604604 if (self.getDebugSymbols()) |dsym| dsym.flush(self) catch |err| switch (err) {
......@@ -609,7 +609,7 @@ pub fn flush(
609609 // Code signing always comes last.
610610 if (codesig) |*csig| {
611611 self.writeCodeSignature(csig) catch |err| switch (err) {
612 error.OutOfMemory, error.LinkFailure => |e| return e,
612 error.OutOfMemory, error.AlreadyReported => |e| return e,
613613 else => |e| return diags.fail("failed to write code signature: {s}", .{@errorName(e)}),
614614 };
615615 const emit = self.base.emit;
......@@ -968,7 +968,7 @@ pub fn parseInputFiles(self: *MachO) !void {
968968 }
969969 }
970970
971 if (diags.hasErrors()) return error.LinkFailure;
971 if (diags.hasErrors()) return error.AlreadyReported;
972972}
973973
974974fn parseInputFileWorker(self: *MachO, file: File) void {
......@@ -1365,7 +1365,7 @@ fn convertTentativeDefsAndResolveSpecialSymbols(self: *MachO) !void {
13651365 resolveSpecialSymbolsWorker(self, obj);
13661366 }
13671367 }
1368 if (diags.hasErrors()) return error.LinkFailure;
1368 if (diags.hasErrors()) return error.AlreadyReported;
13691369}
13701370
13711371fn convertTentativeDefinitionsWorker(self: *MachO, object: *Object) void {
......@@ -1450,7 +1450,7 @@ fn checkDuplicates(self: *MachO) !void {
14501450 }
14511451 }
14521452
1453 if (diags.hasErrors()) return error.LinkFailure;
1453 if (diags.hasErrors()) return error.AlreadyReported;
14541454
14551455 try self.reportDuplicates();
14561456}
......@@ -1517,7 +1517,7 @@ fn scanRelocs(self: *MachO) !void {
15171517 }
15181518 }
15191519
1520 if (diags.hasErrors()) return error.LinkFailure;
1520 if (diags.hasErrors()) return error.AlreadyReported;
15211521
15221522 if (self.getInternalObject()) |obj| {
15231523 try obj.checkUndefs(self);
......@@ -1990,7 +1990,7 @@ fn calcSectionSizes(self: *MachO) !void {
19901990 }
19911991 }
19921992
1993 if (diags.hasErrors()) return error.LinkFailure;
1993 if (diags.hasErrors()) return error.AlreadyReported;
19941994
19951995 try self.calcSymtabSize();
19961996
......@@ -2527,7 +2527,7 @@ fn writeSectionsAndUpdateLinkeditSizes(self: *MachO) !void {
25272527 };
25282528 }
25292529
2530 if (diags.hasErrors()) return error.LinkFailure;
2530 if (diags.hasErrors()) return error.AlreadyReported;
25312531}
25322532
25332533fn writeAtomsWorker(self: *MachO, file: File) void {
......@@ -3074,15 +3074,15 @@ pub fn updateFunc(
30743074 pt: Zcu.PerThread,
30753075 func_index: InternPool.Index,
30763076 mir: *const codegen.AnyMir,
3077) link.File.UpdateNavError!void {
3077) link.Error!void {
30783078 return self.getZigObject().?.updateFunc(self, pt, func_index, mir);
30793079}
30803080
3081pub fn updateNav(self: *MachO, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void {
3081pub fn updateNav(self: *MachO, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.Error!void {
30823082 return self.getZigObject().?.updateNav(self, pt, nav);
30833083}
30843084
3085pub fn updateLineNumber(self: *MachO, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
3085pub fn updateLineNumber(self: *MachO, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) link.Error!void {
30863086 return self.getZigObject().?.updateLineNumber(pt, ti_id);
30873087}
30883088
......@@ -3091,7 +3091,7 @@ pub fn updateExports(
30913091 pt: Zcu.PerThread,
30923092 exported: Zcu.Exported,
30933093 export_indices: []const Zcu.Export.Index,
3094) link.File.UpdateExportsError!void {
3094) link.Error!void {
30953095 return self.getZigObject().?.updateExports(self, pt, exported, export_indices);
30963096}
30973097
......@@ -3116,9 +3116,8 @@ pub fn lowerUav(
31163116 pt: Zcu.PerThread,
31173117 uav: InternPool.Index,
31183118 explicit_alignment: InternPool.Alignment,
3119 src_loc: Zcu.LazySrcLoc,
3120) !codegen.SymbolResult {
3121 return self.getZigObject().?.lowerUav(self, pt, uav, explicit_alignment, src_loc);
3119) !link.File.SymbolId {
3120 return self.getZigObject().?.lowerUav(self, pt, uav, explicit_alignment);
31223121}
31233122
31243123pub fn getUavVAddr(self: *MachO, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
......@@ -3265,7 +3264,11 @@ fn copyRangeAllZeroOut(self: *MachO, old_offset: u64, new_offset: u64, size: u64
32653264 file_writer.pos = new_offset;
32663265 const size_u = math.cast(usize, size) orelse return error.Overflow;
32673266 const n = file_writer.interface.sendFileAll(&file_reader, .limited(size_u)) catch |err| switch (err) {
3268 error.ReadFailed => return file_reader.err.?,
3267 error.ReadFailed => switch (file_reader.err.?) {
3268 error.ConnectionResetByPeer => return error.Unexpected, // not a socket
3269 error.SocketUnconnected => return error.Unexpected, // not a socket
3270 else => |e| return e,
3271 },
32693272 error.WriteFailed => return file_writer.err.?,
32703273 };
32713274 assert(n == size_u);
......@@ -5373,7 +5376,7 @@ fn isReachable(atom: *const Atom, rel: Relocation, macho_file: *MachO) bool {
53735376 return true;
53745377}
53755378
5376pub fn pwriteAll(macho_file: *MachO, bytes: []const u8, offset: u64) error{LinkFailure}!void {
5379pub fn pwriteAll(macho_file: *MachO, bytes: []const u8, offset: u64) error{AlreadyReported}!void {
53775380 const comp = macho_file.base.comp;
53785381 const io = comp.io;
53795382 const diags = &comp.link_diags;
......@@ -5381,7 +5384,7 @@ pub fn pwriteAll(macho_file: *MachO, bytes: []const u8, offset: u64) error{LinkF
53815384 return diags.fail("failed to write: {t}", .{err});
53825385}
53835386
5384pub fn setLength(macho_file: *MachO, length: u64) error{LinkFailure}!void {
5387pub fn setLength(macho_file: *MachO, length: u64) error{AlreadyReported}!void {
53855388 const comp = macho_file.base.comp;
53865389 const io = comp.io;
53875390 const diags = &comp.link_diags;
......@@ -5389,7 +5392,7 @@ pub fn setLength(macho_file: *MachO, length: u64) error{LinkFailure}!void {
53895392 return diags.fail("failed to set file end pos: {t}", .{err});
53905393}
53915394
5392pub fn cast(macho_file: *MachO, comptime T: type, x: anytype) error{LinkFailure}!T {
5395pub fn cast(macho_file: *MachO, comptime T: type, x: anytype) error{AlreadyReported}!T {
53935396 return std.math.cast(T, x) orelse {
53945397 const comp = macho_file.base.comp;
53955398 const diags = &comp.link_diags;
......@@ -5397,7 +5400,7 @@ pub fn cast(macho_file: *MachO, comptime T: type, x: anytype) error{LinkFailure}
53975400 };
53985401}
53995402
5400pub fn alignPow(macho_file: *MachO, x: u32) error{LinkFailure}!u32 {
5403pub fn alignPow(macho_file: *MachO, x: u32) error{AlreadyReported}!u32 {
54015404 const result, const ov = @shlWithOverflow(@as(u32, 1), try cast(macho_file, u5, x));
54025405 if (ov != 0) {
54035406 const comp = macho_file.base.comp;
src/link/MachO/Atom.zig+1-1
......@@ -930,7 +930,7 @@ pub fn calcNumRelocs(self: Atom, macho_file: *MachO) u32 {
930930 }
931931}
932932
933pub fn writeRelocs(self: Atom, macho_file: *MachO, code: []u8, buffer: []macho.relocation_info) error{ LinkFailure, OutOfMemory }!void {
933pub fn writeRelocs(self: Atom, macho_file: *MachO, code: []u8, buffer: []macho.relocation_info) error{ AlreadyReported, OutOfMemory }!void {
934934 const tracy = trace(@src());
935935 defer tracy.end();
936936
src/link/MachO/InternalObject.zig+1-1
......@@ -648,7 +648,7 @@ fn addSection(self: *InternalObject, allocator: Allocator, segname: []const u8,
648648 return n_sect;
649649}
650650
651fn getSectionData(self: *const InternalObject, index: u32, macho_file: *MachO) error{LinkFailure}![]const u8 {
651fn getSectionData(self: *const InternalObject, index: u32, macho_file: *MachO) error{AlreadyReported}![]const u8 {
652652 const slice = self.sections.slice();
653653 assert(index < slice.items(.header).len);
654654 const sect = slice.items(.header)[index];
src/link/MachO/ZigObject.zig+24-48
......@@ -427,7 +427,7 @@ pub fn calcNumRelocs(self: *ZigObject, macho_file: *MachO) void {
427427 }
428428}
429429
430pub fn writeRelocs(self: *ZigObject, macho_file: *MachO) error{ LinkFailure, OutOfMemory }!void {
430pub fn writeRelocs(self: *ZigObject, macho_file: *MachO) error{ AlreadyReported, OutOfMemory }!void {
431431 const gpa = macho_file.base.comp.gpa;
432432 const diags = &macho_file.base.comp.link_diags;
433433
......@@ -555,7 +555,7 @@ pub fn getInputSection(self: ZigObject, atom: Atom, macho_file: *MachO) macho.se
555555 return sect;
556556}
557557
558pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.File.FlushError!void {
558pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.Error!void {
559559 const diags = &macho_file.base.comp.link_diags;
560560
561561 // Handle any lazy symbols that were emitted by incremental compilation.
......@@ -571,7 +571,7 @@ pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.F
571571 .{ .kind = .code, .ty = .anyerror_type },
572572 metadata.text_symbol_index,
573573 ) catch |err| switch (err) {
574 error.OutOfMemory, error.LinkFailure => |e| return e,
574 error.OutOfMemory, error.AlreadyReported => |e| return e,
575575 else => |e| return diags.fail("failed to update lazy symbol: {s}", .{@errorName(e)}),
576576 };
577577 if (metadata.const_state != .unused) self.updateLazySymbol(
......@@ -580,7 +580,7 @@ pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.F
580580 .{ .kind = .const_data, .ty = .anyerror_type },
581581 metadata.const_symbol_index,
582582 ) catch |err| switch (err) {
583 error.OutOfMemory, error.LinkFailure => |e| return e,
583 error.OutOfMemory, error.AlreadyReported => |e| return e,
584584 else => |e| return diags.fail("failed to update lazy symbol: {s}", .{@errorName(e)}),
585585 };
586586 }
......@@ -704,8 +704,7 @@ pub fn lowerUav(
704704 pt: Zcu.PerThread,
705705 uav: InternPool.Index,
706706 explicit_alignment: Atom.Alignment,
707 src_loc: Zcu.LazySrcLoc,
708) !codegen.SymbolResult {
707) !link.File.SymbolId {
709708 const zcu = pt.zcu;
710709 const gpa = zcu.gpa;
711710 const val = Value.fromInterned(uav);
......@@ -717,35 +716,29 @@ pub fn lowerUav(
717716 const sym = self.symbols.items[metadata.symbol_index];
718717 const existing_alignment = sym.getAtom(macho_file).?.alignment;
719718 if (uav_alignment.order(existing_alignment).compare(.lte))
720 return .{ .sym_index = @enumFromInt(metadata.symbol_index) };
719 return @enumFromInt(metadata.symbol_index);
721720 }
722721
723722 var name_buf: [32]u8 = undefined;
724723 const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{
725724 @intFromEnum(uav),
726725 }) catch unreachable;
727 const res = self.lowerConst(
726 const sym_index = self.lowerConst(
728727 macho_file,
729728 pt,
730729 name,
731730 val,
732731 uav_alignment,
733732 macho_file.zig_const_sect_index.?,
734 src_loc,
735733 ) catch |err| switch (err) {
736734 error.OutOfMemory => |e| return e,
737 else => |e| return .{ .fail = try Zcu.ErrorMsg.create(
738 gpa,
739 src_loc,
740 "unable to lower constant value: {s}",
741 .{@errorName(e)},
742 ) },
735 else => |e| return macho_file.base.comp.link_diags.fail(
736 "failed to lower constant value: {t}",
737 .{e},
738 ),
743739 };
744 switch (res) {
745 .sym_index => |sym_index| try self.uavs.put(gpa, uav, .{ .symbol_index = @intFromEnum(sym_index) }),
746 .fail => {},
747 }
748 return res;
740 try self.uavs.put(gpa, uav, .{ .symbol_index = @intFromEnum(sym_index) });
741 return sym_index;
749742}
750743
751744fn freeNavMetadata(self: *ZigObject, macho_file: *MachO, sym_index: Symbol.Index) void {
......@@ -776,7 +769,7 @@ pub fn updateFunc(
776769 pt: Zcu.PerThread,
777770 func_index: InternPool.Index,
778771 mir: *const codegen.AnyMir,
779) link.File.UpdateNavError!void {
772) link.Error!void {
780773 const tracy = trace(@src());
781774 defer tracy.end();
782775
......@@ -796,7 +789,6 @@ pub fn updateFunc(
796789 codegen.emitFunction(
797790 &macho_file.base,
798791 pt,
799 zcu.navSrcLoc(func.owner_nav),
800792 func_index,
801793 @enumFromInt(sym_index),
802794 mir,
......@@ -867,7 +859,7 @@ pub fn updateNav(
867859 macho_file: *MachO,
868860 pt: Zcu.PerThread,
869861 nav_index: InternPool.Nav.Index,
870) link.File.UpdateNavError!void {
862) link.Error!void {
871863 const tracy = trace(@src());
872864 defer tracy.end();
873865
......@@ -887,7 +879,7 @@ pub fn updateNav(
887879 var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, @enumFromInt(sym_index));
888880 defer debug_wip_nav.deinit();
889881 dwarf.finishWipNav(pt, nav_index, &debug_wip_nav) catch |err| switch (err) {
890 error.OutOfMemory, error.Overflow => |e| return e,
882 error.OutOfMemory, error.Canceled, error.AlreadyReported => |e| return e,
891883 else => |e| return macho_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}),
892884 };
893885 }
......@@ -908,7 +900,6 @@ pub fn updateNav(
908900 codegen.generateSymbol(
909901 &macho_file.base,
910902 pt,
911 zcu.navSrcLoc(nav_index),
912903 .fromInterned(nav.resolved.?.value),
913904 &aw.writer,
914905 .{ .atom_index = @enumFromInt(sym_index) },
......@@ -925,7 +916,7 @@ pub fn updateNav(
925916 try self.updateNavCode(macho_file, pt, nav_index, sym_index, sect_index, code);
926917
927918 if (debug_wip_nav) |*wip_nav| self.dwarf.?.finishWipNav(pt, nav_index, wip_nav) catch |err| switch (err) {
928 error.OutOfMemory, error.Overflow => |e| return e,
919 error.OutOfMemory, error.Canceled, error.AlreadyReported => |e| return e,
929920 else => |e| return macho_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}),
930921 };
931922 } else if (self.dwarf) |*dwarf| try dwarf.updateComptimeNav(pt, nav_index);
......@@ -941,7 +932,7 @@ fn updateNavCode(
941932 sym_index: Symbol.Index,
942933 sect_index: u8,
943934 code: []const u8,
944) link.File.UpdateNavError!void {
935) link.Error!void {
945936 const zcu = pt.zcu;
946937 const gpa = zcu.gpa;
947938 const comp = zcu.comp;
......@@ -1198,8 +1189,7 @@ fn lowerConst(
11981189 val: Value,
11991190 required_alignment: Atom.Alignment,
12001191 output_section_index: u8,
1201 src_loc: Zcu.LazySrcLoc,
1202) !codegen.SymbolResult {
1192) !link.File.SymbolId {
12031193 const gpa = macho_file.base.comp.gpa;
12041194
12051195 var aw: std.Io.Writer.Allocating = .init(gpa);
......@@ -1211,7 +1201,6 @@ fn lowerConst(
12111201 codegen.generateSymbol(
12121202 &macho_file.base,
12131203 pt,
1214 src_loc,
12151204 val,
12161205 &aw.writer,
12171206 .{ .atom_index = @enumFromInt(sym_index) },
......@@ -1242,7 +1231,7 @@ fn lowerConst(
12421231 const file_offset = sect.offset + atom.value;
12431232 try macho_file.pwriteAll(code, file_offset);
12441233
1245 return .{ .sym_index = @enumFromInt(sym_index) };
1234 return @enumFromInt(sym_index);
12461235}
12471236
12481237pub fn updateExports(
......@@ -1251,7 +1240,7 @@ pub fn updateExports(
12511240 pt: Zcu.PerThread,
12521241 exported: Zcu.Exported,
12531242 export_indices: []const Zcu.Export.Index,
1254) link.File.UpdateExportsError!void {
1243) link.Error!void {
12551244 const tracy = trace(@src());
12561245 defer tracy.end();
12571246
......@@ -1263,18 +1252,7 @@ pub fn updateExports(
12631252 break :blk self.navs.getPtr(nav).?;
12641253 },
12651254 .uav => |uav| self.uavs.getPtr(uav) orelse blk: {
1266 const first_exp = export_indices[0].ptr(zcu);
1267 const res = try self.lowerUav(macho_file, pt, uav, .none, first_exp.src);
1268 switch (res) {
1269 .sym_index => {},
1270 .fail => |em| {
1271 // TODO maybe it's enough to return an error here and let Zcu.processExportsInner
1272 // handle the error?
1273 try zcu.failed_exports.ensureUnusedCapacity(zcu.gpa, 1);
1274 zcu.failed_exports.putAssumeCapacityNoClobber(export_indices[0], em);
1275 return;
1276 },
1277 }
1255 _ = try self.lowerUav(macho_file, pt, uav, .none);
12781256 break :blk self.uavs.getPtr(uav).?;
12791257 },
12801258 };
......@@ -1368,11 +1346,9 @@ fn updateLazySymbol(
13681346 break :blk try self.addString(gpa, name);
13691347 };
13701348
1371 const src = Type.fromInterned(lazy_sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded;
13721349 try codegen.generateLazySymbol(
13731350 &macho_file.base,
13741351 pt,
1375 src,
13761352 lazy_sym,
13771353 &required_alignment,
13781354 &aw.writer,
......@@ -1413,12 +1389,12 @@ fn updateLazySymbol(
14131389 try macho_file.pwriteAll(code, file_offset);
14141390}
14151391
1416pub fn updateLineNumber(self: *ZigObject, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
1392pub fn updateLineNumber(self: *ZigObject, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) link.Error!void {
14171393 if (self.dwarf) |*dwarf| {
14181394 const comp = dwarf.bin_file.comp;
14191395 const diags = &comp.link_diags;
14201396 dwarf.updateLineNumber(pt.zcu, ti_id) catch |err| switch (err) {
1421 error.Overflow, error.OutOfMemory => |e| return e,
1397 error.OutOfMemory, error.Canceled, error.AlreadyReported => |e| return e,
14221398 else => |e| return diags.fail("failed to update dwarf line numbers: {s}", .{@errorName(e)}),
14231399 };
14241400 }
src/link/MachO/relocatable.zig+13-13
......@@ -1,4 +1,4 @@
1pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Path) link.File.FlushError!void {
1pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Path) link.Error!void {
22 const gpa = comp.gpa;
33 const io = comp.io;
44 const diags = &comp.link_diags;
......@@ -34,15 +34,15 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat
3434 diags.addParseError(link_input.path().?, "failed to read input file: {s}", .{@errorName(err)});
3535 }
3636
37 if (diags.hasErrors()) return error.LinkFailure;
37 if (diags.hasErrors()) return error.AlreadyReported;
3838
3939 try macho_file.parseInputFiles();
4040
41 if (diags.hasErrors()) return error.LinkFailure;
41 if (diags.hasErrors()) return error.AlreadyReported;
4242
4343 try macho_file.resolveSymbols();
4444 macho_file.dedupLiterals() catch |err| switch (err) {
45 error.OutOfMemory, error.LinkFailure => |e| return e,
45 error.OutOfMemory, error.AlreadyReported => |e| return e,
4646 else => |e| return diags.fail("failed to update ar size: {s}", .{@errorName(e)}),
4747 };
4848 markExports(macho_file);
......@@ -54,7 +54,7 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat
5454
5555 try createSegment(macho_file);
5656 allocateSections(macho_file) catch |err| switch (err) {
57 error.LinkFailure => |e| return e,
57 error.AlreadyReported => |e| return e,
5858 else => |e| return diags.fail("failed to allocate sections: {s}", .{@errorName(e)}),
5959 };
6060 allocateSegment(macho_file);
......@@ -75,7 +75,7 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat
7575 try writeHeader(macho_file, ncmds, sizeofcmds);
7676}
7777
78pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Path) link.File.FlushError!void {
78pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Path) link.Error!void {
7979 const gpa = comp.gpa;
8080 const io = comp.io;
8181 const diags = &macho_file.base.comp.link_diags;
......@@ -105,11 +105,11 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?
105105 diags.addParseError(link_input.path().?, "failed to read input file: {s}", .{@errorName(err)});
106106 }
107107
108 if (diags.hasErrors()) return error.LinkFailure;
108 if (diags.hasErrors()) return error.AlreadyReported;
109109
110110 try parseInputFilesAr(macho_file);
111111
112 if (diags.hasErrors()) return error.LinkFailure;
112 if (diags.hasErrors()) return error.AlreadyReported;
113113
114114 // First, we flush relocatable object file generated with our backends.
115115 if (macho_file.getZigObject()) |zo| {
......@@ -231,7 +231,7 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?
231231 try macho_file.setLength(total_size);
232232 try macho_file.pwriteAll(writer.buffered(), 0);
233233
234 if (diags.hasErrors()) return error.LinkFailure;
234 if (diags.hasErrors()) return error.AlreadyReported;
235235}
236236
237237fn parseInputFilesAr(macho_file: *MachO) !void {
......@@ -339,7 +339,7 @@ fn calcSectionSizes(macho_file: *MachO) !void {
339339 }
340340 try calcSymtabSize(macho_file);
341341
342 if (diags.hasErrors()) return error.LinkFailure;
342 if (diags.hasErrors()) return error.AlreadyReported;
343343}
344344
345345fn calcSectionSizeWorker(macho_file: *MachO, sect_id: u8) void {
......@@ -586,7 +586,7 @@ fn sortRelocs(macho_file: *MachO) void {
586586 }
587587}
588588
589fn writeSections(macho_file: *MachO) link.File.FlushError!void {
589fn writeSections(macho_file: *MachO) link.Error!void {
590590 const tracy = trace(@src());
591591 defer tracy.end();
592592
......@@ -632,7 +632,7 @@ fn writeSections(macho_file: *MachO) link.File.FlushError!void {
632632 }
633633 }
634634
635 if (diags.hasErrors()) return error.LinkFailure;
635 if (diags.hasErrors()) return error.AlreadyReported;
636636
637637 if (macho_file.getZigObject()) |zo| {
638638 try zo.writeRelocs(macho_file);
......@@ -685,7 +685,7 @@ fn writeSectionsToFile(macho_file: *MachO) !void {
685685 try macho_file.pwriteAll(macho_file.strtab.items, macho_file.symtab_cmd.stroff);
686686}
687687
688fn writeLoadCommands(macho_file: *MachO) error{ LinkFailure, OutOfMemory }!struct { usize, usize } {
688fn writeLoadCommands(macho_file: *MachO) error{ AlreadyReported, OutOfMemory }!struct { usize, usize } {
689689 const gpa = macho_file.base.comp.gpa;
690690 const needed_size = load_commands.calcLoadCommandsSizeObject(macho_file);
691691 const buffer = try gpa.alloc(u8, needed_size);
src/link/MappedFile.zig+154-45
......@@ -5,6 +5,7 @@ const is_linux = builtin.os.tag == .linux;
55const is_windows = builtin.os.tag == .windows;
66
77const std = @import("std");
8const Allocator = std.mem.Allocator;
89const Io = std.Io;
910const assert = std.debug.assert;
1011const linux = std.os.linux;
......@@ -24,14 +25,40 @@ large: std.ArrayList(u64),
2425updates: std.ArrayList(Node.Index),
2526update_prog_node: std.Progress.Node,
2627writers: std.SinglyLinkedList,
28io_err: ?IoError,
2729
2830pub const growth_factor = 4;
2931
30pub const Error = error{
32pub const IoError = Io.UnexpectedError || error{
33 DiskQuota,
34 FileTooBig,
35 InputOutput,
36 NoSpaceLeft,
37 AccessDenied,
38 PermissionDenied,
39 SystemResources,
40 LockViolation,
41 LockedMemoryLimitExceeded,
42 ProcessFdQuotaExceeded,
43 SystemFdQuotaExceeded,
44 FileBusy,
45 DeviceBusy,
46 NoDevice,
47 PathAlreadyExists,
48 IsDir,
3149 NotFile,
32} || Io.File.MemoryMap.CreateError || Io.File.MemoryMap.SetLengthError || Io.File.WritePositionalError;
50 BrokenPipe,
51 NonResizable,
52 Unseekable,
53};
54
55pub const Error = Allocator.Error || Io.Cancelable || error{
56 /// Some I/O operation on the memory-mapped file failed. The underlying error is available in
57 /// the `MappedFile.io_err` field.
58 MappedFileIo,
59};
3360
34pub fn init(file: Io.File, gpa: std.mem.Allocator, io: Io) !MappedFile {
61pub fn init(file: Io.File, gpa: std.mem.Allocator, io: Io) (Allocator.Error || Io.Cancelable || IoError)!MappedFile {
3562 var mf: MappedFile = .{
3663 .io = io,
3764 .flags = undefined,
......@@ -47,10 +74,14 @@ pub fn init(file: Io.File, gpa: std.mem.Allocator, io: Io) !MappedFile {
4774 .updates = .empty,
4875 .update_prog_node = .none,
4976 .writers = .{},
77 .io_err = null,
5078 };
5179 errdefer mf.deinit(gpa);
5280 const size: u64, const block_size = stat: {
53 const stat = try file.stat(io);
81 const stat = file.stat(io) catch |err| switch (err) {
82 error.Streaming => return error.PathAlreadyExists,
83 else => |e| return e,
84 };
5485 if (stat.kind != .file) return error.PathAlreadyExists;
5586 break :stat .{ stat.size, @max(std.heap.pageSize(), stat.block_size) };
5687 };
......@@ -61,14 +92,16 @@ pub fn init(file: Io.File, gpa: std.mem.Allocator, io: Io) !MappedFile {
6192 .fallocate_punch_hole_unsupported = false,
6293 };
6394 try mf.nodes.ensureUnusedCapacity(gpa, 1);
64 assert(try mf.addNode(gpa, .{
65 .add_node = .{
66 .size = size,
67 .alignment = mf.flags.block_size,
68 .fixed = true,
69 },
70 }) == Node.Index.root);
71 try mf.ensureTotalCapacity(@intCast(size));
95 const root_ni = mf.addNode(gpa, .{ .add_node = .{
96 .size = size,
97 .alignment = mf.flags.block_size,
98 .fixed = true,
99 } }) catch |err| switch (err) {
100 error.MappedFileIo => return mf.io_err.?,
101 else => |e| return e,
102 };
103 assert(root_ni == Node.Index.root);
104 try mf.ensureTotalCapacityInner(@intCast(size));
72105 return mf;
73106}
74107
......@@ -174,7 +207,7 @@ pub const Node = extern struct {
174207 return .{ .mf = mf, .ni = ni.get(mf).last };
175208 }
176209
177 pub fn childrenMoved(ni: Node.Index, gpa: std.mem.Allocator, mf: *MappedFile) !void {
210 pub fn childrenMoved(ni: Node.Index, gpa: std.mem.Allocator, mf: *MappedFile) Allocator.Error!void {
178211 var child_ni = ni.get(mf).last;
179212 while (child_ni != .none) {
180213 try child_ni.moved(gpa, mf);
......@@ -192,7 +225,7 @@ pub const Node = extern struct {
192225 }
193226 return false;
194227 }
195 pub fn moved(ni: Node.Index, gpa: std.mem.Allocator, mf: *MappedFile) !void {
228 pub fn moved(ni: Node.Index, gpa: std.mem.Allocator, mf: *MappedFile) Allocator.Error!void {
196229 try mf.updates.ensureUnusedCapacity(gpa, 1);
197230 ni.movedAssumeCapacity(mf);
198231 }
......@@ -213,7 +246,7 @@ pub const Node = extern struct {
213246 pub fn hasResized(ni: Node.Index, mf: *const MappedFile) bool {
214247 return ni.get(mf).flags.resized;
215248 }
216 pub fn resized(ni: Node.Index, gpa: std.mem.Allocator, mf: *MappedFile) !void {
249 pub fn resized(ni: Node.Index, gpa: std.mem.Allocator, mf: *MappedFile) Allocator.Error!void {
217250 try mf.updates.ensureUnusedCapacity(gpa, 1);
218251 ni.resizedAssumeCapacity(mf);
219252 }
......@@ -296,8 +329,16 @@ pub const Node = extern struct {
296329 return mf.memory_map.memory[@intCast(file_loc.offset)..][0..@intCast(file_loc.size)];
297330 }
298331
299 pub fn resize(ni: Node.Index, mf: *MappedFile, gpa: std.mem.Allocator, size: u64) !void {
300 try mf.resizeNode(gpa, ni, size);
332 pub fn resize(ni: Node.Index, mf: *MappedFile, gpa: std.mem.Allocator, size: u64) Error!void {
333 mf.resizeNode(gpa, ni, size) catch |err| switch (err) {
334 error.OutOfMemory,
335 error.Canceled,
336 => |e| return e,
337 else => |e| {
338 mf.io_err = e;
339 return error.MappedFileIo;
340 },
341 };
301342 var writers_it = mf.writers.first;
302343 while (writers_it) |writer_node| : (writers_it = writer_node.next) {
303344 const w: *Node.Writer = @fieldParentPtr("writer_node", writer_node);
......@@ -313,8 +354,16 @@ pub const Node = extern struct {
313354 mf: *MappedFile,
314355 gpa: std.mem.Allocator,
315356 new_alignment: std.mem.Alignment,
316 ) !void {
317 try mf.realignNode(gpa, ni, new_alignment);
357 ) Error!void {
358 mf.realignNode(gpa, ni, new_alignment) catch |err| switch (err) {
359 error.OutOfMemory,
360 error.Canceled,
361 => |e| return e,
362 else => |e| {
363 mf.io_err = e;
364 return error.MappedFileIo;
365 },
366 };
318367 var writers_it = mf.writers.first;
319368 while (writers_it) |writer_node| : (writers_it = writer_node.next) {
320369 const w: *Node.Writer = @fieldParentPtr("writer_node", writer_node);
......@@ -422,9 +471,16 @@ pub const Node = extern struct {
422471 file_reader.pos,
423472 w.ni.fileLocation(w.mf, true).offset + interface.end,
424473 limit.minInt(interface.unusedCapacityLen()),
425 ) catch |err| {
426 w.err = err;
427 return error.WriteFailed;
474 ) catch |err| switch (err) {
475 error.Canceled => |e| {
476 w.err = e;
477 return error.WriteFailed;
478 },
479 else => |e| {
480 w.mf.io_err = e;
481 w.err = error.MappedFileIo;
482 return error.WriteFailed;
483 },
428484 });
429485 if (n == 0) return error.Unimplemented;
430486 file_reader.pos += n;
......@@ -472,7 +528,7 @@ fn addNode(mf: *MappedFile, gpa: std.mem.Allocator, opts: struct {
472528 next: Node.Index = .none,
473529 offset: u64 = 0,
474530 add_node: AddNodeOptions,
475}) !Node.Index {
531}) Error!Node.Index {
476532 if (opts.add_node.moved or opts.add_node.resized) try mf.updates.ensureUnusedCapacity(gpa, 1);
477533 const offset = opts.add_node.alignment.forward(@intCast(opts.offset));
478534 const location_tag: Node.Location.Tag, const location_payload: Node.Location.Payload = location: {
......@@ -544,7 +600,7 @@ pub fn addOnlyChildNode(
544600 gpa: std.mem.Allocator,
545601 parent_ni: Node.Index,
546602 opts: AddNodeOptions,
547) !Node.Index {
603) Error!Node.Index {
548604 try mf.nodes.ensureUnusedCapacity(gpa, 1);
549605 const parent = parent_ni.get(mf);
550606 assert(parent.first == .none and parent.last == .none);
......@@ -559,7 +615,7 @@ pub fn addFirstChildNode(
559615 gpa: std.mem.Allocator,
560616 parent_ni: Node.Index,
561617 opts: AddNodeOptions,
562) !Node.Index {
618) Error!Node.Index {
563619 try mf.nodes.ensureUnusedCapacity(gpa, 1);
564620 const parent = parent_ni.get(mf);
565621 return mf.addNode(gpa, .{
......@@ -574,7 +630,7 @@ pub fn addLastChildNode(
574630 gpa: std.mem.Allocator,
575631 parent_ni: Node.Index,
576632 opts: AddNodeOptions,
577) !Node.Index {
633) Error!Node.Index {
578634 try mf.nodes.ensureUnusedCapacity(gpa, 1);
579635 const parent = parent_ni.get(mf);
580636 return mf.addNode(gpa, .{
......@@ -596,7 +652,7 @@ pub fn addNodeAfter(
596652 gpa: std.mem.Allocator,
597653 prev_ni: Node.Index,
598654 opts: AddNodeOptions,
599) !Node.Index {
655) Error!Node.Index {
600656 assert(prev_ni != .none);
601657 try mf.nodes.ensureUnusedCapacity(gpa, 1);
602658 const prev = prev_ni.get(mf);
......@@ -610,7 +666,7 @@ pub fn addNodeAfter(
610666 });
611667}
612668
613fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested_size: u64) !void {
669fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested_size: u64) (Allocator.Error || Io.Cancelable || IoError)!void {
614670 const io = mf.io;
615671 const node = ni.get(mf);
616672 const old_offset, const old_size = node.location().resolve(mf);
......@@ -618,9 +674,13 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested
618674 // Resize the entire file
619675 if (ni == Node.Index.root) {
620676 try mf.ensureCapacityForSetLocation(gpa);
621 try mf.memory_map.write(io);
677 mf.memory_map.write(io) catch |err| switch (err) {
678 error.WouldBlock => return error.Unexpected, // file was not opened as non-blocking
679 error.NotOpenForWriting => return error.Unexpected, // we definitely opened the file for writing
680 else => |e| return e,
681 };
622682 try mf.memory_map.file.setLength(io, new_size);
623 try mf.ensureTotalCapacity(@intCast(new_size));
683 try mf.ensureTotalCapacityInner(@intCast(new_size));
624684 ni.setLocationAssumeCapacity(mf, old_offset, new_size);
625685 return;
626686 }
......@@ -643,7 +703,11 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested
643703 if (is_linux and !mf.flags.fallocate_insert_range_unsupported and
644704 node.flags.alignment.order(mf.flags.block_size).compare(.gte))
645705 insert_range: {
646 try mf.memory_map.write(io);
706 mf.memory_map.write(io) catch |err| switch (err) {
707 error.WouldBlock => return error.Unexpected, // file was not opened as non-blocking
708 error.NotOpenForWriting => return error.Unexpected, // we definitely opened the file for writing
709 else => |e| return e,
710 };
647711 // Ask the filesystem driver to insert extents into the file without copying any data
648712 const last_offset, const last_size = parent.last.location(mf).resolve(mf);
649713 const last_end = last_offset + last_size;
......@@ -674,7 +738,7 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested
674738 enclosing_ni.setLocationAssumeCapacity(mf, enclosing_offset, new_enclosing_size);
675739 if (enclosing_ni == Node.Index.root) {
676740 assert(enclosing_offset == 0);
677 try mf.ensureTotalCapacity(@intCast(new_enclosing_size));
741 try mf.ensureTotalCapacityInner(@intCast(new_enclosing_size));
678742 break;
679743 }
680744 var after_ni = enclosing.next;
......@@ -865,7 +929,7 @@ fn realignNode(
865929 gpa: std.mem.Allocator,
866930 ni: Node.Index,
867931 new_alignment: std.mem.Alignment,
868) !void {
932) (Allocator.Error || Io.Cancelable || IoError)!void {
869933 assert(ni != Node.Index.root); // currently unsupported
870934
871935 const node = ni.get(mf);
......@@ -936,7 +1000,7 @@ fn realignNode(
9361000 }
9371001}
9381002
939fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size: u64) !void {
1003fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size: u64) (Io.Cancelable || IoError)!void {
9401004 // make a copy of this node at the new location
9411005 try mf.copyRange(old_file_offset, new_file_offset, size);
9421006 // delete the copy of this node at the old location
......@@ -966,7 +1030,7 @@ fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size:
9661030 @memset(mf.memory_map.memory[@intCast(old_file_offset)..][0..@intCast(size)], 0);
9671031}
9681032
969fn copyRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size: u64) !void {
1033fn copyRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size: u64) (Io.Cancelable || IoError)!void {
9701034 const copy_size = try mf.copyFileRange(mf.memory_map.file, old_file_offset, new_file_offset, size);
9711035 if (copy_size < size) @memcpy(
9721036 mf.memory_map.memory[@intCast(new_file_offset + copy_size)..][0..@intCast(size - copy_size)],
......@@ -980,9 +1044,13 @@ fn copyFileRange(
9801044 old_file_offset: u64,
9811045 new_file_offset: u64,
9821046 size: u64,
983) !u64 {
1047) (Io.Cancelable || IoError)!u64 {
9841048 const io = mf.io;
985 try mf.memory_map.write(io);
1049 mf.memory_map.write(io) catch |err| switch (err) {
1050 error.WouldBlock => return error.Unexpected, // file was not opened as non-blocking
1051 error.NotOpenForWriting => return error.Unexpected, // we definitely opened the file for writing
1052 else => |e| return e,
1053 };
9861054 var remaining_size = size;
9871055 if (is_linux and !mf.flags.copy_file_range_unsupported) {
9881056 var old_file_offset_mut: i64 = @intCast(old_file_offset);
......@@ -1021,17 +1089,41 @@ fn copyFileRange(
10211089 return size - remaining_size;
10221090}
10231091
1024fn ensureCapacityForSetLocation(mf: *MappedFile, gpa: std.mem.Allocator) !void {
1092fn ensureCapacityForSetLocation(mf: *MappedFile, gpa: std.mem.Allocator) Allocator.Error!void {
10251093 try mf.large.ensureUnusedCapacity(gpa, 2);
10261094 try mf.updates.ensureUnusedCapacity(gpa, 1);
10271095}
10281096
1029pub fn ensureTotalCapacity(mf: *MappedFile, new_capacity: usize) !void {
1097pub fn ensureTotalCapacity(mf: *MappedFile, new_capacity: usize) Error!void {
1098 mf.ensureTotalCapacityInner(new_capacity) catch |err| switch (err) {
1099 error.OutOfMemory,
1100 error.Canceled,
1101 => |e| return e,
1102
1103 else => |e| {
1104 mf.io_err = e;
1105 return error.MappedFileIo;
1106 },
1107 };
1108}
1109fn ensureTotalCapacityInner(mf: *MappedFile, new_capacity: usize) (Allocator.Error || Io.Cancelable || IoError)!void {
10301110 if (mf.memory_map.memory.len >= new_capacity) return;
1031 try mf.ensureTotalCapacityPrecise(new_capacity +| new_capacity / growth_factor);
1111 try mf.ensureTotalCapacityPreciseInner(new_capacity +| new_capacity / growth_factor);
10321112}
10331113
1034pub fn ensureTotalCapacityPrecise(mf: *MappedFile, new_capacity: usize) !void {
1114pub fn ensureTotalCapacityPrecise(mf: *MappedFile, new_capacity: usize) Error!void {
1115 mf.ensureTotalCapacityPreciseInner(new_capacity) catch |err| switch (err) {
1116 error.OutOfMemory,
1117 error.Canceled,
1118 => |e| return e,
1119
1120 else => |e| {
1121 mf.io_err = e;
1122 return error.MappedFileIo;
1123 },
1124 };
1125}
1126fn ensureTotalCapacityPreciseInner(mf: *MappedFile, new_capacity: usize) (Allocator.Error || Io.Cancelable || IoError)!void {
10351127 if (mf.memory_map.memory.len >= new_capacity) return;
10361128 const io = mf.io;
10371129 const aligned_capacity = mf.flags.block_size.forward(new_capacity);
......@@ -1047,7 +1139,11 @@ pub fn ensureTotalCapacityPrecise(mf: *MappedFile, new_capacity: usize) !void {
10471139 }
10481140
10491141 const file = mf.memory_map.file;
1050 mf.memory_map = try .create(io, file, .{ .len = aligned_capacity });
1142 mf.memory_map = Io.File.MemoryMap.create(io, file, .{ .len = aligned_capacity }) catch |err| switch (err) {
1143 error.WouldBlock => return error.Unexpected, // file was not opened as non-blocking
1144 error.NotOpenForReading => return error.Unexpected, // we definitely opened the file for writing
1145 else => |e| return e,
1146 };
10511147}
10521148
10531149pub fn unmap(mf: *MappedFile) void {
......@@ -1059,9 +1155,22 @@ pub fn unmap(mf: *MappedFile) void {
10591155 mf.memory_map.file = file;
10601156}
10611157
1062pub fn flush(mf: *MappedFile) Io.File.WritePositionalError!void {
1063 const io = mf.io;
1064 try mf.memory_map.write(io);
1158pub fn flush(mf: *MappedFile) (Io.Cancelable || error{MappedFileIo})!void {
1159 mf.memory_map.write(mf.io) catch |err| switch (err) {
1160 error.Canceled => |e| return e,
1161
1162 error.WouldBlock, // file was not opened as non-blocking
1163 error.NotOpenForWriting, // we definitely opened the file for writing
1164 => {
1165 mf.io_err = error.Unexpected;
1166 return error.MappedFileIo;
1167 },
1168
1169 else => |e| {
1170 mf.io_err = e;
1171 return error.MappedFileIo;
1172 },
1173 };
10651174}
10661175
10671176fn verify(mf: *MappedFile) void {
src/link/Queue.zig+7-3
......@@ -135,7 +135,7 @@ pub fn finishPrelinkQueue(q: *Queue, comp: *Compilation) Io.Cancelable!void {
135135 lf.post_prelink = true;
136136 } else |err| switch (err) {
137137 error.OutOfMemory => comp.link_diags.setAllocFailure(),
138 error.LinkFailure => {},
138 error.AlreadyReported => {},
139139 error.Canceled => |e| return e,
140140 }
141141 }
......@@ -178,7 +178,7 @@ fn runLinkTasks(q: *Queue, comp: *Compilation) void {
178178 } else |err| switch (err) {
179179 error.OutOfMemory => comp.link_diags.setAllocFailure(),
180180 error.Canceled => @panic("TODO"),
181 error.LinkFailure => {},
181 error.AlreadyReported => {},
182182 }
183183 }
184184 }
......@@ -205,7 +205,11 @@ fn runIdleTask(comp: *Compilation, tid: Zcu.PerThread.Id) bool {
205205 comp.link_diags.setAllocFailure();
206206 break :have_more false;
207207 },
208 error.LinkFailure => false,
208 error.AlreadyReported => false,
209 error.Canceled => {
210 comp.io.recancel();
211 return false;
212 },
209213 };
210214}
211215
src/link/SpirV.zig+4-15
......@@ -140,19 +140,8 @@ fn generate(
140140 };
141141
142142 linker.cg.genNav(do_codegen) catch |err| switch (err) {
143 error.CodegenFail => switch (zcu.codegenFailMsg(nav_index, linker.cg.error_msg.?)) {
144 error.CodegenFail => {},
145 error.OutOfMemory => |e| return e,
146 },
147 else => |other| {
148 // There might be an error that happened *after* linker.error_msg
149 // was already allocated, so be sure to free it.
150 if (linker.cg.error_msg) |error_msg| {
151 error_msg.deinit(gpa);
152 }
153
154 return other;
155 },
143 error.AlreadyReported => return,
144 else => |e| return e,
156145 };
157146}
158147
......@@ -168,7 +157,7 @@ pub fn updateFunc(
168157 try linker.generate(pt, nav, air.*, liveness.*.?, true);
169158}
170159
171pub fn updateNav(linker: *Linker, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void {
160pub fn updateNav(linker: *Linker, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.Error!void {
172161 const ip = &pt.zcu.intern_pool;
173162 log.debug("lowering nav {f}({d})", .{ ip.getNav(nav).fqn.fmt(ip), nav });
174163 try linker.generate(pt, nav, undefined, undefined, false);
......@@ -231,7 +220,7 @@ pub fn flush(
231220 arena: Allocator,
232221 tid: Zcu.PerThread.Id,
233222 prog_node: std.Progress.Node,
234) link.File.FlushError!void {
223) link.Error!void {
235224 // The goal is to never use this because it's only needed if we need to
236225 // write to InternPool, but flush is too late to be writing to the
237226 // InternPool.
src/link/Wasm.zig+19-19
......@@ -568,7 +568,7 @@ pub const SourceLocation = enum(u32) {
568568 err_msg.notes[err.note_slot - 1].source_location = .{ .wasm = sl };
569569 }
570570
571 pub fn fail(sl: SourceLocation, diags: *link.Diags, comptime format: []const u8, args: anytype) error{LinkFailure} {
571 pub fn fail(sl: SourceLocation, diags: *link.Diags, comptime format: []const u8, args: anytype) error{AlreadyReported} {
572572 return diags.failSourceLocation(.{ .wasm = sl }, format, args);
573573 }
574574
......@@ -3027,12 +3027,12 @@ fn openParseObjectReportingFailure(wasm: *Wasm, path: Path) void {
30273027 const diags = &comp.link_diags;
30283028 const obj = link.openObject(io, path, false, false) catch |err| {
30293029 switch (diags.failParse(path, "failed to open object: {t}", .{err})) {
3030 error.LinkFailure => return,
3030 error.AlreadyReported => return,
30313031 }
30323032 };
30333033 wasm.parseObject(obj) catch |err| {
30343034 switch (diags.failParse(path, "failed to parse object: {t}", .{err})) {
3035 error.LinkFailure => return,
3035 error.AlreadyReported => return,
30363036 }
30373037 };
30383038}
......@@ -3336,12 +3336,12 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index
33363336 }
33373337}
33383338
3339pub fn updateLineNumber(wasm: *Wasm, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void {
3339pub fn updateLineNumber(wasm: *Wasm, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) link.Error!void {
33403340 const comp = wasm.base.comp;
33413341 const diags = &comp.link_diags;
33423342 if (wasm.dwarf) |*dw| {
33433343 dw.updateLineNumber(pt.zcu, ti_id) catch |err| switch (err) {
3344 error.Overflow, error.OutOfMemory => |e| return e,
3344 error.OutOfMemory, error.Canceled, error.AlreadyReported => |e| return e,
33453345 else => |e| return diags.fail("failed to update dwarf line numbers: {s}", .{@errorName(e)}),
33463346 };
33473347 }
......@@ -3417,7 +3417,7 @@ pub fn loadInput(wasm: *Wasm, input: link.Input) !void {
34173417 }
34183418}
34193419
3420pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.File.FlushError!void {
3420pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.Error!void {
34213421 const tracy = trace(@src());
34223422 defer tracy.end();
34233423
......@@ -3526,7 +3526,7 @@ pub fn markFunctionImport(
35263526 name: String,
35273527 import: *FunctionImport,
35283528 func_index: FunctionImport.Index,
3529) link.File.FlushError!void {
3529) link.Error!void {
35303530 // import.flags.alive might be already true from a previous update. In such
35313531 // case, we must still run the logic in this function, in case the item
35323532 // being marked was reverted by the `flush` logic that resets the hash
......@@ -3557,7 +3557,7 @@ pub fn markFunctionImport(
35573557}
35583558
35593559/// Recursively mark alive everything referenced by the function.
3560fn markFunction(wasm: *Wasm, i: ObjectFunctionIndex, override_export: bool) link.File.FlushError!void {
3560fn markFunction(wasm: *Wasm, i: ObjectFunctionIndex, override_export: bool) link.Error!void {
35613561 const comp = wasm.base.comp;
35623562 const gpa = comp.gpa;
35633563 const gop = try wasm.functions.getOrPut(gpa, .fromObjectFunction(wasm, i));
......@@ -3590,7 +3590,7 @@ fn markGlobalImport(
35903590 name: String,
35913591 import: *GlobalImport,
35923592 global_index: GlobalImport.Index,
3593) link.File.FlushError!void {
3593) link.Error!void {
35943594 // import.flags.alive might be already true from a previous update. In such
35953595 // case, we must still run the logic in this function, in case the item
35963596 // being marked was reverted by the `flush` logic that resets the hash
......@@ -3630,7 +3630,7 @@ fn markGlobalImport(
36303630 }
36313631}
36323632
3633fn markGlobal(wasm: *Wasm, i: ObjectGlobalIndex, override_export: bool) link.File.FlushError!void {
3633fn markGlobal(wasm: *Wasm, i: ObjectGlobalIndex, override_export: bool) link.Error!void {
36343634 const comp = wasm.base.comp;
36353635 const gpa = comp.gpa;
36363636 const gop = try wasm.globals.getOrPut(gpa, .fromObjectGlobal(wasm, i));
......@@ -3653,7 +3653,7 @@ fn markTableImport(
36533653 name: String,
36543654 import: *TableImport,
36553655 table_index: TableImport.Index,
3656) link.File.FlushError!void {
3656) link.Error!void {
36573657 if (import.flags.alive) return;
36583658 import.flags.alive = true;
36593659
......@@ -3675,7 +3675,7 @@ fn markTableImport(
36753675 }
36763676}
36773677
3678fn markDataSegment(wasm: *Wasm, segment_index: ObjectDataSegment.Index) link.File.FlushError!void {
3678fn markDataSegment(wasm: *Wasm, segment_index: ObjectDataSegment.Index) link.Error!void {
36793679 const comp = wasm.base.comp;
36803680 const segment = segment_index.ptr(wasm);
36813681 if (segment.flags.alive) return;
......@@ -3693,7 +3693,7 @@ pub fn markDataImport(
36933693 name: String,
36943694 import: *ObjectDataImport,
36953695 data_index: ObjectDataImport.Index,
3696) link.File.FlushError!void {
3696) link.Error!void {
36973697 if (import.flags.alive) return;
36983698 import.flags.alive = true;
36993699
......@@ -3715,7 +3715,7 @@ pub fn markDataImport(
37153715 }
37163716}
37173717
3718fn markRelocations(wasm: *Wasm, relocs: ObjectRelocation.IterableSlice) link.File.FlushError!void {
3718fn markRelocations(wasm: *Wasm, relocs: ObjectRelocation.IterableSlice) link.Error!void {
37193719 const gpa = wasm.base.comp.gpa;
37203720 for (relocs.slice.tags(wasm), relocs.slice.pointees(wasm), relocs.slice.offsets(wasm)) |tag, pointee, offset| {
37213721 if (offset >= relocs.end) break;
......@@ -3812,7 +3812,7 @@ fn markRelocations(wasm: *Wasm, relocs: ObjectRelocation.IterableSlice) link.Fil
38123812 }
38133813}
38143814
3815fn markTable(wasm: *Wasm, i: ObjectTableIndex) link.File.FlushError!void {
3815fn markTable(wasm: *Wasm, i: ObjectTableIndex) link.Error!void {
38163816 try wasm.tables.put(wasm.base.comp.gpa, .fromObjectTable(i), {});
38173817}
38183818
......@@ -3821,7 +3821,7 @@ pub fn flush(
38213821 arena: Allocator,
38223822 tid: Zcu.PerThread.Id,
38233823 prog_node: std.Progress.Node,
3824) link.File.FlushError!void {
3824) link.Error!void {
38253825 // The goal is to never use this because it's only needed if we need to
38263826 // write to InternPool, but flush is too late to be writing to the
38273827 // InternPool.
......@@ -3864,7 +3864,7 @@ pub fn flush(
38643864 try wasm.flush_buffer.data_imports.reinit(gpa, wasm.data_imports.keys(), wasm.data_imports.values());
38653865
38663866 return wasm.flush_buffer.finish(wasm) catch |err| switch (err) {
3867 error.OutOfMemory, error.LinkFailure => |e| return e,
3867 error.OutOfMemory, error.AlreadyReported => |e| return e,
38683868 else => |e| return diags.fail("failed to flush wasm: {s}", .{@errorName(e)}),
38693869 };
38703870}
......@@ -4275,7 +4275,7 @@ fn lowerZcuData(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !Zcu
42754275 {
42764276 var aw: std.Io.Writer.Allocating = .fromArrayList(wasm.base.comp.gpa, &wasm.string_bytes);
42774277 defer wasm.string_bytes = aw.toArrayList();
4278 codegen.generateSymbol(&wasm.base, pt, .unneeded, .fromInterned(ip_index), &aw.writer, .none) catch |err| switch (err) {
4278 codegen.generateSymbol(&wasm.base, pt, .fromInterned(ip_index), &aw.writer, .none) catch |err| switch (err) {
42794279 error.WriteFailed => return error.OutOfMemory,
42804280 else => |e| return e,
42814281 };
......@@ -4349,7 +4349,7 @@ fn resolveFunctionSynthetic(
43494349 res: FunctionImport.Resolution,
43504350 params: []const std.wasm.Valtype,
43514351 returns: []const std.wasm.Valtype,
4352) link.File.FlushError!void {
4352) link.Error!void {
43534353 import.resolution = res;
43544354 wasm.functions.putAssumeCapacity(res, {});
43554355 // This is not only used for type-checking but also ensures the function
src/link/Wasm/Flush.zig+3-3
......@@ -274,7 +274,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
274274 }
275275 }
276276
277 if (diags.hasErrors()) return error.LinkFailure;
277 if (diags.hasErrors()) return error.AlreadyReported;
278278
279279 // Merge indirect function tables.
280280 try f.indirect_function_table.ensureUnusedCapacity(gpa, wasm.zcu_indirect_function_set.entries.len +
......@@ -513,7 +513,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
513513 if (initial_memory > std.math.maxInt(u32)) {
514514 diags.addError("initial memory value {d} exceeds 32-bit address space", .{initial_memory});
515515 }
516 if (diags.hasErrors()) return error.LinkFailure;
516 if (diags.hasErrors()) return error.AlreadyReported;
517517 memory_ptr = initial_memory;
518518 } else {
519519 memory_ptr = mem.alignForward(u64, memory_ptr, std.wasm.page_size);
......@@ -535,7 +535,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
535535 if (max_memory > std.math.maxInt(u32)) {
536536 diags.addError("maximum memory value {d} exceeds 32-bit address space", .{max_memory});
537537 }
538 if (diags.hasErrors()) return error.LinkFailure;
538 if (diags.hasErrors()) return error.AlreadyReported;
539539 wasm.memories.limits.max = @intCast(max_memory / page_size);
540540 wasm.memories.limits.flags.has_max = true;
541541 if (shared_memory) wasm.memories.limits.flags.is_shared = true;
src/link/Wasm/Object.zig+1-1
......@@ -1431,7 +1431,7 @@ fn parseFeatures(
14311431 bytes: []const u8,
14321432 start_pos: usize,
14331433 path: Path,
1434) error{ OutOfMemory, LinkFailure }!struct { Wasm.Feature.Set, usize } {
1434) error{ OutOfMemory, AlreadyReported }!struct { Wasm.Feature.Set, usize } {
14351435 const gpa = wasm.base.comp.gpa;
14361436 const diags = &wasm.base.comp.link_diags;
14371437 const features_len, var pos = readLeb(u32, bytes, start_pos);
src/register_manager.zig+1-1
......@@ -14,7 +14,7 @@ const link = @import("link.zig");
1414
1515const log = std.log.scoped(.register_manager);
1616
17pub const AllocationError = @import("codegen.zig").CodeGenError || error{OutOfRegisters};
17pub const AllocationError = @import("codegen.zig").Error || error{OutOfRegisters};
1818
1919pub fn RegisterManager(
2020 comptime Function: type,