| author | |
| committer | |
| log | 8fe1ec0cc9cfd0f3cf85b97889b4b9735e906926 |
| tree | 0bd86634dd23d30464e0d75cd3e168945a169dda |
| parent | 748e7c5e39fcba3ed6b2b6e4cc4c01e1d442acbe |
| signature |
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 |
| 3376 | 3376 | .fuzz = comp.config.any_fuzz, |
| 3377 | 3377 | .lto = comp.config.lto, |
| 3378 | 3378 | }) catch |err| switch (err) { |
| 3379 | error.LinkFailure => {}, // Already reported. | |
| 3379 | error.AlreadyReported => {}, | |
| 3380 | 3380 | error.OutOfMemory => |e| return e, |
| 3381 | 3381 | }; |
| 3382 | 3382 | } |
| ... | ... | @@ -3390,7 +3390,7 @@ fn flush(comp: *Compilation, arena: Allocator, tid: Zcu.PerThread.Id) (Io.Cancel |
| 3390 | 3390 | }; |
| 3391 | 3391 | // This is needed before reading the error flags. |
| 3392 | 3392 | lf.flush(arena, tid, comp.link_prog_node) catch |err| switch (err) { |
| 3393 | error.LinkFailure => {}, // Already reported. | |
| 3393 | error.AlreadyReported => {}, | |
| 3394 | 3394 | error.OutOfMemory, error.Canceled => |e| return e, |
| 3395 | 3395 | }; |
| 3396 | 3396 | } |
| ... | ... | @@ -5249,7 +5249,7 @@ fn workerUpdateCObject( |
| 5249 | 5249 | progress_node: std.Progress.Node, |
| 5250 | 5250 | ) void { |
| 5251 | 5251 | comp.updateCObject(c_object, progress_node) catch |err| switch (err) { |
| 5252 | error.AnalysisFail => return, | |
| 5252 | error.AlreadyReported => return, | |
| 5253 | 5253 | else => { |
| 5254 | 5254 | comp.reportRetryableCObjectError(c_object, err) catch |oom| switch (oom) { |
| 5255 | 5255 | // Swallowing this error is OK because it's implied to be OOM when |
| ... | ... | @@ -5266,7 +5266,7 @@ fn workerUpdateWin32Resource( |
| 5266 | 5266 | progress_node: std.Progress.Node, |
| 5267 | 5267 | ) void { |
| 5268 | 5268 | comp.updateWin32Resource(win32_resource, progress_node) catch |err| switch (err) { |
| 5269 | error.AnalysisFail => return, | |
| 5269 | error.AlreadyReported => return, | |
| 5270 | 5270 | else => { |
| 5271 | 5271 | comp.reportRetryableWin32ResourceError(win32_resource, err) catch |oom| switch (oom) { |
| 5272 | 5272 | // 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 |
| 5489 | 5489 | c_object.status = .failure_retryable; |
| 5490 | 5490 | |
| 5491 | 5491 | switch (comp.failCObj(c_object, "{t}", .{err})) { |
| 5492 | error.AnalysisFail => return, | |
| 5492 | error.AlreadyReported => return, | |
| 5493 | 5493 | else => |e| return e, |
| 5494 | 5494 | } |
| 5495 | 5495 | } |
| ... | ... | @@ -6852,7 +6852,7 @@ fn failCObj( |
| 6852 | 6852 | c_object: *CObject, |
| 6853 | 6853 | comptime format: []const u8, |
| 6854 | 6854 | args: anytype, |
| 6855 | ) error{ OutOfMemory, AnalysisFail } { | |
| 6855 | ) error{ OutOfMemory, AlreadyReported } { | |
| 6856 | 6856 | @branchHint(.cold); |
| 6857 | 6857 | const diag_bundle = blk: { |
| 6858 | 6858 | const diag_bundle = try comp.gpa.create(CObject.Diag.Bundle); |
| ... | ... | @@ -6876,7 +6876,7 @@ fn failCObjWithOwnedDiagBundle( |
| 6876 | 6876 | comp: *Compilation, |
| 6877 | 6877 | c_object: *CObject, |
| 6878 | 6878 | diag_bundle: *CObject.Diag.Bundle, |
| 6879 | ) error{ OutOfMemory, AnalysisFail } { | |
| 6879 | ) error{ OutOfMemory, AlreadyReported } { | |
| 6880 | 6880 | @branchHint(.cold); |
| 6881 | 6881 | assert(diag_bundle.diags.len > 0); |
| 6882 | 6882 | { |
| ... | ... | @@ -6890,10 +6890,10 @@ fn failCObjWithOwnedDiagBundle( |
| 6890 | 6890 | comp.failed_c_objects.putAssumeCapacityNoClobber(c_object, diag_bundle); |
| 6891 | 6891 | } |
| 6892 | 6892 | c_object.status = .failure; |
| 6893 | return error.AnalysisFail; | |
| 6893 | return error.AlreadyReported; | |
| 6894 | 6894 | } |
| 6895 | 6895 | |
| 6896 | fn failWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, comptime format: []const u8, args: anytype) error{ OutOfMemory, AnalysisFail } { | |
| 6896 | fn failWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } { | |
| 6897 | 6897 | @branchHint(.cold); |
| 6898 | 6898 | var bundle: ErrorBundle.Wip = undefined; |
| 6899 | 6899 | try bundle.init(comp.gpa); |
| ... | ... | @@ -6920,7 +6920,7 @@ fn failWin32ResourceWithOwnedBundle( |
| 6920 | 6920 | comp: *Compilation, |
| 6921 | 6921 | win32_resource: *Win32Resource, |
| 6922 | 6922 | err_bundle: ErrorBundle, |
| 6923 | ) error{ OutOfMemory, AnalysisFail } { | |
| 6923 | ) error{ OutOfMemory, AlreadyReported } { | |
| 6924 | 6924 | @branchHint(.cold); |
| 6925 | 6925 | { |
| 6926 | 6926 | const io = comp.io; |
| ... | ... | @@ -6929,7 +6929,7 @@ fn failWin32ResourceWithOwnedBundle( |
| 6929 | 6929 | try comp.failed_win32_resources.putNoClobber(comp.gpa, win32_resource, err_bundle); |
| 6930 | 6930 | } |
| 6931 | 6931 | win32_resource.status = .failure; |
| 6932 | return error.AnalysisFail; | |
| 6932 | return error.AlreadyReported; | |
| 6933 | 6933 | } |
| 6934 | 6934 | |
| 6935 | 6935 | pub const FileExt = enum { |
src/Zcu.zig+8-17| ... | ... | @@ -3912,12 +3912,12 @@ pub fn getTarget(zcu: *const Zcu) *const Target { |
| 3912 | 3912 | pub fn handleUpdateExports( |
| 3913 | 3913 | zcu: *Zcu, |
| 3914 | 3914 | 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 { | |
| 3917 | 3917 | const gpa = zcu.gpa; |
| 3918 | 3918 | result catch |err| switch (err) { |
| 3919 | error.OutOfMemory => |e| return e, | |
| 3920 | error.AnalysisFail => { | |
| 3919 | else => |e| return e, | |
| 3920 | error.AlreadyReported => { | |
| 3921 | 3921 | const export_idx = export_indices[0]; |
| 3922 | 3922 | const new_export = export_idx.ptr(zcu); |
| 3923 | 3923 | new_export.status = .failed_retryable; |
| ... | ... | @@ -4688,7 +4688,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum) |
| 4688 | 4688 | |
| 4689 | 4689 | pub const CodegenFailError = error{ |
| 4690 | 4690 | /// Indicates the error message has been already stored at `Zcu.failed_codegen`. |
| 4691 | CodegenFail, | |
| 4691 | AlreadyReported, | |
| 4692 | 4692 | OutOfMemory, |
| 4693 | 4693 | }; |
| 4694 | 4694 | |
| ... | ... | @@ -4713,16 +4713,7 @@ pub fn codegenFailMsg(zcu: *Zcu, nav_index: InternPool.Nav.Index, msg: *ErrorMsg |
| 4713 | 4713 | errdefer msg.deinit(gpa); |
| 4714 | 4714 | try zcu.failed_codegen.putNoClobber(gpa, nav_index, msg); |
| 4715 | 4715 | } |
| 4716 | return error.CodegenFail; | |
| 4717 | } | |
| 4718 | ||
| 4719 | /// Asserts that `zcu.failed_codegen` contains the key `nav`, with the necessary lock held. | |
| 4720 | pub 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; | |
| 4726 | 4717 | } |
| 4727 | 4718 | |
| 4728 | 4719 | pub fn codegenFailType( |
| ... | ... | @@ -4735,7 +4726,7 @@ pub fn codegenFailType( |
| 4735 | 4726 | try zcu.failed_types.ensureUnusedCapacity(gpa, 1); |
| 4736 | 4727 | const msg = try Zcu.ErrorMsg.create(gpa, zcu.typeSrcLoc(ty_index), format, args); |
| 4737 | 4728 | zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg); |
| 4738 | return error.CodegenFail; | |
| 4729 | return error.AlreadyReported; | |
| 4739 | 4730 | } |
| 4740 | 4731 | |
| 4741 | 4732 | pub 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) |
| 4745 | 4736 | try zcu.failed_types.ensureUnusedCapacity(gpa, 1); |
| 4746 | 4737 | } |
| 4747 | 4738 | zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg); |
| 4748 | return error.CodegenFail; | |
| 4739 | return error.AlreadyReported; | |
| 4749 | 4740 | } |
| 4750 | 4741 | |
| 4751 | 4742 | /// Asserts that `zcu.multi_module_err != null`. |
src/Zcu/PerThread.zig+5-12| ... | ... | @@ -3700,7 +3700,7 @@ fn processExportsInner( |
| 3700 | 3700 | exported: Zcu.Exported, |
| 3701 | 3701 | export_indices: []const Zcu.Export.Index, |
| 3702 | 3702 | skip_linker_work: bool, |
| 3703 | ) error{OutOfMemory}!void { | |
| 3703 | ) error{ OutOfMemory, Canceled }!void { | |
| 3704 | 3704 | const zcu = pt.zcu; |
| 3705 | 3705 | const gpa = zcu.gpa; |
| 3706 | 3706 | const ip = &zcu.intern_pool; |
| ... | ... | @@ -4533,7 +4533,7 @@ pub fn runCodegen(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) Ru |
| 4533 | 4533 | return codegen_result catch |err| { |
| 4534 | 4534 | switch (err) { |
| 4535 | 4535 | error.OutOfMemory => comp.setAllocFailure(), |
| 4536 | error.CodegenFail => zcu.assertCodegenFailed(zcu.funcInfo(func_index).owner_nav), | |
| 4536 | error.AlreadyReported => {}, | |
| 4537 | 4537 | error.NoLinkFile => assert(comp.bin_file == null), |
| 4538 | 4538 | error.BackendDoesNotProduceMir => switch (target_util.zigBackend( |
| 4539 | 4539 | &zcu.root_mod.resolved_target.result, |
| ... | ... | @@ -4552,7 +4552,7 @@ pub fn runCodegen(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) Ru |
| 4552 | 4552 | fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) error{ |
| 4553 | 4553 | OutOfMemory, |
| 4554 | 4554 | Canceled, |
| 4555 | CodegenFail, | |
| 4555 | AlreadyReported, | |
| 4556 | 4556 | NoLinkFile, |
| 4557 | 4557 | BackendDoesNotProduceMir, |
| 4558 | 4558 | }!codegen.AnyMir { |
| ... | ... | @@ -4628,19 +4628,12 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e |
| 4628 | 4628 | switch (err) { |
| 4629 | 4629 | error.OutOfMemory => comp.link_diags.setAllocFailure(), |
| 4630 | 4630 | } |
| 4631 | return error.CodegenFail; | |
| 4631 | return error.AlreadyReported; | |
| 4632 | 4632 | }; |
| 4633 | 4633 | return error.BackendDoesNotProduceMir; |
| 4634 | 4634 | } |
| 4635 | 4635 | |
| 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); | |
| 4644 | 4637 | } |
| 4645 | 4638 | |
| 4646 | 4639 | fn printVerboseAir( |
src/codegen.zig+99-154| ... | ... | @@ -24,10 +24,7 @@ const dev = @import("dev.zig"); |
| 24 | 24 | |
| 25 | 25 | pub const aarch64 = @import("codegen/aarch64.zig"); |
| 26 | 26 | |
| 27 | pub const CodeGenError = GenerateSymbolError || error{ | |
| 28 | /// Indicates the error is already stored in Zcu `failed_codegen`. | |
| 29 | CodegenFail, | |
| 30 | }; | |
| 27 | pub const Error = link.Error; | |
| 31 | 28 | |
| 32 | 29 | fn devFeatureForBackend(backend: std.lang.CompilerBackend) dev.Feature { |
| 33 | 30 | return switch (backend) { |
| ... | ... | @@ -141,11 +138,10 @@ pub const AnyMir = union { |
| 141 | 138 | pub fn generateFunction( |
| 142 | 139 | lf: *link.File, |
| 143 | 140 | pt: Zcu.PerThread, |
| 144 | src_loc: Zcu.LazySrcLoc, | |
| 145 | 141 | func_index: InternPool.Index, |
| 146 | 142 | air: *const Air, |
| 147 | 143 | liveness: *const ?Air.Liveness, |
| 148 | ) CodeGenError!AnyMir { | |
| 144 | ) Error!AnyMir { | |
| 149 | 145 | const zcu = pt.zcu; |
| 150 | 146 | const func = zcu.funcInfo(func_index); |
| 151 | 147 | const target = &zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result; |
| ... | ... | @@ -160,7 +156,7 @@ pub fn generateFunction( |
| 160 | 156 | => |backend| { |
| 161 | 157 | dev.check(devFeatureForBackend(backend)); |
| 162 | 158 | 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); | |
| 164 | 160 | return @unionInit(AnyMir, AnyMir.tag(backend), mir); |
| 165 | 161 | }, |
| 166 | 162 | } |
| ... | ... | @@ -176,13 +172,12 @@ pub fn generateFunction( |
| 176 | 172 | pub fn emitFunction( |
| 177 | 173 | lf: *link.File, |
| 178 | 174 | pt: Zcu.PerThread, |
| 179 | src_loc: Zcu.LazySrcLoc, | |
| 180 | 175 | func_index: InternPool.Index, |
| 181 | 176 | atom_id: link.File.AtomId, |
| 182 | 177 | any_mir: *const AnyMir, |
| 183 | 178 | w: *std.Io.Writer, |
| 184 | 179 | debug_output: link.File.DebugInfoOutput, |
| 185 | ) (CodeGenError || std.Io.Writer.Error)!void { | |
| 180 | ) (Error || std.Io.Writer.Error)!void { | |
| 186 | 181 | const zcu = pt.zcu; |
| 187 | 182 | const func = zcu.funcInfo(func_index); |
| 188 | 183 | const target = &zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result; |
| ... | ... | @@ -201,7 +196,7 @@ pub fn emitFunction( |
| 201 | 196 | => |backend| { |
| 202 | 197 | dev.check(devFeatureForBackend(backend)); |
| 203 | 198 | 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); | |
| 205 | 200 | }, |
| 206 | 201 | } |
| 207 | 202 | } |
| ... | ... | @@ -209,12 +204,11 @@ pub fn emitFunction( |
| 209 | 204 | pub fn generateLazyFunction( |
| 210 | 205 | lf: *link.File, |
| 211 | 206 | pt: Zcu.PerThread, |
| 212 | src_loc: Zcu.LazySrcLoc, | |
| 213 | 207 | lazy_sym: link.File.LazySymbol, |
| 214 | 208 | atom_id: link.File.AtomId, |
| 215 | 209 | w: *std.Io.Writer, |
| 216 | 210 | debug_output: link.File.DebugInfoOutput, |
| 217 | ) (CodeGenError || std.Io.Writer.Error)!void { | |
| 211 | ) (Error || std.Io.Writer.Error)!void { | |
| 218 | 212 | const zcu = pt.zcu; |
| 219 | 213 | const target = if (Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu)) |inst_index| |
| 220 | 214 | &zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.?.resolved_target.result |
| ... | ... | @@ -224,7 +218,7 @@ pub fn generateLazyFunction( |
| 224 | 218 | else => unreachable, |
| 225 | 219 | inline .stage2_riscv64, .stage2_x86_64 => |backend| { |
| 226 | 220 | 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); | |
| 228 | 222 | }, |
| 229 | 223 | } |
| 230 | 224 | } |
| ... | ... | @@ -232,14 +226,13 @@ pub fn generateLazyFunction( |
| 232 | 226 | pub fn generateLazySymbol( |
| 233 | 227 | bin_file: *link.File, |
| 234 | 228 | pt: Zcu.PerThread, |
| 235 | src_loc: Zcu.LazySrcLoc, | |
| 236 | 229 | lazy_sym: link.File.LazySymbol, |
| 237 | 230 | // TODO don't use an "out" parameter like this; put it in the result instead |
| 238 | 231 | alignment: *Alignment, |
| 239 | 232 | w: *std.Io.Writer, |
| 240 | 233 | debug_output: link.File.DebugInfoOutput, |
| 241 | 234 | reloc_parent: link.File.RelocInfo.Parent, |
| 242 | ) (CodeGenError || std.Io.Writer.Error)!void { | |
| 235 | ) (Error || std.Io.Writer.Error)!void { | |
| 243 | 236 | const tracy = trace(@src()); |
| 244 | 237 | defer tracy.end(); |
| 245 | 238 | tracy.addTextFmt("{t}, {f}", .{ lazy_sym.kind, Type.fromInterned(lazy_sym.ty).fmt(pt) }); |
| ... | ... | @@ -257,7 +250,7 @@ pub fn generateLazySymbol( |
| 257 | 250 | |
| 258 | 251 | if (lazy_sym.kind == .code) { |
| 259 | 252 | 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); | |
| 261 | 254 | } |
| 262 | 255 | |
| 263 | 256 | if (lazy_sym.ty == .anyerror_type) { |
| ... | ... | @@ -295,22 +288,13 @@ pub fn generateLazySymbol( |
| 295 | 288 | } |
| 296 | 289 | } |
| 297 | 290 | |
| 298 | pub 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 | ||
| 306 | 291 | pub fn generateSymbol( |
| 307 | 292 | bin_file: *link.File, |
| 308 | 293 | pt: Zcu.PerThread, |
| 309 | src_loc: Zcu.LazySrcLoc, | |
| 310 | 294 | val: Value, |
| 311 | 295 | w: *std.Io.Writer, |
| 312 | 296 | reloc_parent: link.File.RelocInfo.Parent, |
| 313 | ) (GenerateSymbolError || std.Io.Writer.Error)!void { | |
| 297 | ) (Error || std.Io.Writer.Error)!void { | |
| 314 | 298 | const tracy = trace(@src()); |
| 315 | 299 | defer tracy.end(); |
| 316 | 300 | |
| ... | ... | @@ -323,8 +307,11 @@ pub fn generateSymbol( |
| 323 | 307 | |
| 324 | 308 | log.debug("generateSymbol: val = {f}", .{val.fmtValue(pt)}); |
| 325 | 309 | |
| 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 | ||
| 326 | 314 | if (val.isUndef(zcu)) { |
| 327 | const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; | |
| 328 | 315 | try w.splatByteAll(0xaa, abi_size); |
| 329 | 316 | return; |
| 330 | 317 | } |
| ... | ... | @@ -364,7 +351,6 @@ pub fn generateSymbol( |
| 364 | 351 | .enum_literal, |
| 365 | 352 | => unreachable, // non-runtime values |
| 366 | 353 | .int => { |
| 367 | const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; | |
| 368 | 354 | var space: Value.BigIntSpace = undefined; |
| 369 | 355 | const int_val = val.toBigInt(&space, zcu); |
| 370 | 356 | int_val.writeTwosComplement(try w.writableSlice(abi_size), endian); |
| ... | ... | @@ -397,13 +383,13 @@ pub fn generateSymbol( |
| 397 | 383 | // emit payload part of the error union |
| 398 | 384 | { |
| 399 | 385 | 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) { | |
| 401 | 387 | .err_name => try pt.intern(.{ .undef = payload_ty.toIntern() }), |
| 402 | 388 | .payload => |payload| payload, |
| 403 | 389 | }), w, reloc_parent); |
| 404 | 390 | const unpadded_end = w.end - begin; |
| 405 | 391 | 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); | |
| 407 | 393 | |
| 408 | 394 | if (padding > 0) { |
| 409 | 395 | try w.splatByteAll(0, padding); |
| ... | ... | @@ -416,7 +402,7 @@ pub fn generateSymbol( |
| 416 | 402 | try w.writeInt(u16, err_val, endian); |
| 417 | 403 | const unpadded_end = w.end - begin; |
| 418 | 404 | 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); | |
| 420 | 406 | |
| 421 | 407 | if (padding > 0) { |
| 422 | 408 | try w.splatByteAll(0, padding); |
| ... | ... | @@ -425,7 +411,7 @@ pub fn generateSymbol( |
| 425 | 411 | }, |
| 426 | 412 | .enum_tag => |enum_tag| { |
| 427 | 413 | 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); | |
| 429 | 415 | }, |
| 430 | 416 | .float => |float| storage: switch (float.storage) { |
| 431 | 417 | .f16 => |f16_val| try w.writeInt(u16, @bitCast(f16_val), endian), |
| ... | ... | @@ -433,7 +419,6 @@ pub fn generateSymbol( |
| 433 | 419 | .f64 => |f64_val| try w.writeInt(u64, @bitCast(f64_val), endian), |
| 434 | 420 | .f80 => |f80_val| { |
| 435 | 421 | try w.writeInt(u80, @bitCast(f80_val), endian); |
| 436 | const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; | |
| 437 | 422 | try w.splatByteAll(0, abi_size - 10); |
| 438 | 423 | }, |
| 439 | 424 | .f128 => |f128_val| switch (Type.fromInterned(float.ty).floatBits(target)) { |
| ... | ... | @@ -444,29 +429,28 @@ pub fn generateSymbol( |
| 444 | 429 | 128 => try w.writeInt(u128, @bitCast(f128_val), endian), |
| 445 | 430 | }, |
| 446 | 431 | }, |
| 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), | |
| 448 | 433 | .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); | |
| 451 | 436 | }, |
| 452 | 437 | .opt => { |
| 453 | 438 | const payload_type = ty.optionalChild(zcu); |
| 454 | 439 | const payload_val = val.optionalValue(zcu); |
| 455 | const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; | |
| 456 | 440 | |
| 457 | 441 | if (ty.optionalReprIsPayload(zcu)) { |
| 458 | 442 | 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); | |
| 460 | 444 | } else { |
| 461 | 445 | try w.splatByteAll(0, abi_size); |
| 462 | 446 | } |
| 463 | 447 | } 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; | |
| 465 | 449 | if (payload_type.hasRuntimeBits(zcu)) { |
| 466 | 450 | const value = payload_val orelse Value.fromInterned(try pt.intern(.{ |
| 467 | 451 | .undef = payload_type.toIntern(), |
| 468 | 452 | })); |
| 469 | try generateSymbol(bin_file, pt, src_loc, value, w, reloc_parent); | |
| 453 | try generateSymbol(bin_file, pt, value, w, reloc_parent); | |
| 470 | 454 | } |
| 471 | 455 | try w.writeByte(@intFromBool(payload_val != null)); |
| 472 | 456 | try w.splatByteAll(0, padding); |
| ... | ... | @@ -478,7 +462,7 @@ pub fn generateSymbol( |
| 478 | 462 | .elems, .repeated_elem => { |
| 479 | 463 | var index: u64 = 0; |
| 480 | 464 | 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) { | |
| 482 | 466 | .bytes => unreachable, |
| 483 | 467 | .elems => |elems| elems[@intCast(index)], |
| 484 | 468 | .repeated_elem => |elem| if (index < array_type.len) |
| ... | ... | @@ -490,7 +474,6 @@ pub fn generateSymbol( |
| 490 | 474 | }, |
| 491 | 475 | }, |
| 492 | 476 | .vector_type => |vector_type| { |
| 493 | const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; | |
| 494 | 477 | const vector_bool_bitpacked = switch (zcu.comp.getZigBackend()) { |
| 495 | 478 | .stage2_wasm => false, |
| 496 | 479 | else => true, |
| ... | ... | @@ -499,7 +482,9 @@ pub fn generateSymbol( |
| 499 | 482 | const bytes = try w.writableSlice(abi_size); |
| 500 | 483 | @memset(bytes, 0xaa); |
| 501 | 484 | 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 | }; | |
| 503 | 488 | while (index < len) : (index += 1) { |
| 504 | 489 | const bit_index = switch (endian) { |
| 505 | 490 | .big => len - 1 - index, |
| ... | ... | @@ -539,18 +524,16 @@ pub fn generateSymbol( |
| 539 | 524 | .elems, .repeated_elem => { |
| 540 | 525 | var index: u64 = 0; |
| 541 | 526 | 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) { | |
| 543 | 528 | .bytes => unreachable, |
| 544 | .elems => |elems| elems[math.cast(usize, index) orelse return error.Overflow], | |
| 529 | .elems => |elems| elems[@intCast(index)], | |
| 545 | 530 | .repeated_elem => |elem| elem, |
| 546 | 531 | }), w, reloc_parent); |
| 547 | 532 | } |
| 548 | 533 | }, |
| 549 | 534 | } |
| 550 | 535 | |
| 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)); | |
| 554 | 537 | if (padding > 0) try w.splatByteAll(0, padding); |
| 555 | 538 | } |
| 556 | 539 | }, |
| ... | ... | @@ -560,10 +543,9 @@ pub fn generateSymbol( |
| 560 | 543 | if (field_val != .none) continue; |
| 561 | 544 | if (!Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue; |
| 562 | 545 | |
| 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) { | |
| 567 | 549 | .bytes => |bytes| try pt.intern(.{ .int = .{ |
| 568 | 550 | .ty = field_ty, |
| 569 | 551 | .storage = .{ .u64 = bytes.at(field_index, ip) }, |
| ... | ... | @@ -572,8 +554,7 @@ pub fn generateSymbol( |
| 572 | 554 | .repeated_elem => |elem| elem, |
| 573 | 555 | }), w, reloc_parent); |
| 574 | 556 | } |
| 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)); | |
| 577 | 558 | }, |
| 578 | 559 | .struct_type => { |
| 579 | 560 | const struct_type = ip.loadStructType(ty.toIntern()); |
| ... | ... | @@ -598,20 +579,15 @@ pub fn generateSymbol( |
| 598 | 579 | .repeated_elem => |elem| elem, |
| 599 | 580 | }; |
| 600 | 581 | |
| 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)); | |
| 605 | 583 | if (padding > 0) try w.splatByteAll(0, padding); |
| 606 | 584 | |
| 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); | |
| 608 | 586 | } |
| 609 | 587 | |
| 610 | 588 | assert(struct_type.alignment.check(struct_type.size)); |
| 611 | 589 | |
| 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)); | |
| 615 | 591 | if (padding > 0) try w.splatByteAll(0, padding); |
| 616 | 592 | }, |
| 617 | 593 | } |
| ... | ... | @@ -622,12 +598,12 @@ pub fn generateSymbol( |
| 622 | 598 | const layout = ty.unionGetLayout(zcu); |
| 623 | 599 | |
| 624 | 600 | 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); | |
| 626 | 602 | } |
| 627 | 603 | |
| 628 | 604 | // Check if we should store the tag first. |
| 629 | 605 | 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); | |
| 631 | 607 | } |
| 632 | 608 | |
| 633 | 609 | const union_obj = zcu.typeToUnion(ty).?; |
| ... | ... | @@ -635,28 +611,28 @@ pub fn generateSymbol( |
| 635 | 611 | const field_index = ty.unionTagFieldIndex(Value.fromInterned(un.tag), zcu).?; |
| 636 | 612 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 637 | 613 | 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)); | |
| 639 | 615 | } 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); | |
| 641 | 617 | |
| 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)); | |
| 643 | 619 | if (padding > 0) { |
| 644 | 620 | try w.splatByteAll(0, padding); |
| 645 | 621 | } |
| 646 | 622 | } |
| 647 | 623 | } 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); | |
| 649 | 625 | } |
| 650 | 626 | |
| 651 | 627 | 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); | |
| 653 | 629 | |
| 654 | 630 | if (layout.padding > 0) { |
| 655 | 631 | try w.splatByteAll(0, layout.padding); |
| 656 | 632 | } |
| 657 | 633 | } |
| 658 | 634 | }, |
| 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), | |
| 660 | 636 | .memoized_call => unreachable, |
| 661 | 637 | } |
| 662 | 638 | } |
| ... | ... | @@ -664,23 +640,21 @@ pub fn generateSymbol( |
| 664 | 640 | fn lowerPtr( |
| 665 | 641 | bin_file: *link.File, |
| 666 | 642 | pt: Zcu.PerThread, |
| 667 | src_loc: Zcu.LazySrcLoc, | |
| 668 | 643 | ptr_val: InternPool.Index, |
| 669 | 644 | w: *std.Io.Writer, |
| 670 | 645 | reloc_parent: link.File.RelocInfo.Parent, |
| 671 | 646 | prev_offset: u64, |
| 672 | ) (GenerateSymbolError || std.Io.Writer.Error)!void { | |
| 647 | ) (Error || std.Io.Writer.Error)!void { | |
| 673 | 648 | const zcu = pt.zcu; |
| 674 | 649 | const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; |
| 675 | 650 | const offset: u64 = prev_offset + ptr.byte_offset; |
| 676 | 651 | return switch (ptr.base_addr) { |
| 677 | 652 | .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), | |
| 680 | 655 | .eu_payload => |eu_ptr| try lowerPtr( |
| 681 | 656 | bin_file, |
| 682 | 657 | pt, |
| 683 | src_loc, | |
| 684 | 658 | eu_ptr, |
| 685 | 659 | w, |
| 686 | 660 | reloc_parent, |
| ... | ... | @@ -689,7 +663,7 @@ fn lowerPtr( |
| 689 | 663 | zcu, |
| 690 | 664 | ), |
| 691 | 665 | ), |
| 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), | |
| 693 | 667 | .field => |field| { |
| 694 | 668 | const base_ptr = Value.fromInterned(field.base); |
| 695 | 669 | const base_ty = base_ptr.typeOf(zcu).childType(zcu); |
| ... | ... | @@ -708,13 +682,13 @@ fn lowerPtr( |
| 708 | 682 | }, |
| 709 | 683 | else => unreachable, |
| 710 | 684 | }; |
| 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); | |
| 712 | 686 | }, |
| 713 | 687 | .arr_elem => |arr_elem| { |
| 714 | 688 | const base_ptr_ty = Value.fromInterned(arr_elem.base).typeOf(zcu); |
| 715 | 689 | assert(base_ptr_ty.ptrSize(zcu) == .many); |
| 716 | 690 | 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); | |
| 718 | 692 | }, |
| 719 | 693 | .comptime_alloc => unreachable, |
| 720 | 694 | .comptime_field => unreachable, |
| ... | ... | @@ -724,12 +698,11 @@ fn lowerPtr( |
| 724 | 698 | fn lowerUavRef( |
| 725 | 699 | lf: *link.File, |
| 726 | 700 | pt: Zcu.PerThread, |
| 727 | src_loc: Zcu.LazySrcLoc, | |
| 728 | 701 | uav: InternPool.Key.Ptr.BaseAddr.Uav, |
| 729 | 702 | w: *std.Io.Writer, |
| 730 | 703 | reloc_parent: link.File.RelocInfo.Parent, |
| 731 | 704 | offset: u64, |
| 732 | ) (GenerateSymbolError || std.Io.Writer.Error)!void { | |
| 705 | ) (Error || std.Io.Writer.Error)!void { | |
| 733 | 706 | const zcu = pt.zcu; |
| 734 | 707 | const ip = &zcu.intern_pool; |
| 735 | 708 | const comp = lf.comp; |
| ... | ... | @@ -761,10 +734,7 @@ fn lowerUavRef( |
| 761 | 734 | } |
| 762 | 735 | |
| 763 | 736 | 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); | |
| 768 | 738 | |
| 769 | 739 | const vaddr = lf.getUavVAddr(uav_val, .{ |
| 770 | 740 | .parent = reloc_parent, |
| ... | ... | @@ -790,7 +760,7 @@ fn lowerNavRef( |
| 790 | 760 | w: *std.Io.Writer, |
| 791 | 761 | reloc_parent: link.File.RelocInfo.Parent, |
| 792 | 762 | offset: u64, |
| 793 | ) (GenerateSymbolError || std.Io.Writer.Error)!void { | |
| 763 | ) (Error || std.Io.Writer.Error)!void { | |
| 794 | 764 | const zcu = pt.zcu; |
| 795 | 765 | const gpa = zcu.gpa; |
| 796 | 766 | const ip = &zcu.intern_pool; |
| ... | ... | @@ -859,15 +829,11 @@ fn lowerNavRef( |
| 859 | 829 | } |
| 860 | 830 | } |
| 861 | 831 | |
| 862 | pub const SymbolResult = union(enum) { sym_index: link.File.SymbolId, fail: *ErrorMsg }; | |
| 863 | ||
| 864 | 832 | pub fn genNavRef( |
| 865 | 833 | lf: *link.File, |
| 866 | 834 | pt: Zcu.PerThread, |
| 867 | src_loc: Zcu.LazySrcLoc, | |
| 868 | 835 | nav_index: InternPool.Nav.Index, |
| 869 | target: *const std.Target, | |
| 870 | ) CodeGenError!SymbolResult { | |
| 836 | ) Error!link.File.SymbolId { | |
| 871 | 837 | const zcu = pt.zcu; |
| 872 | 838 | const ip = &zcu.intern_pool; |
| 873 | 839 | const nav = ip.getNav(nav_index); |
| ... | ... | @@ -884,7 +850,7 @@ pub fn genNavRef( |
| 884 | 850 | .internal => { |
| 885 | 851 | const sym_index = try zo.getOrCreateMetadataForNav(zcu, nav_index); |
| 886 | 852 | if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true; |
| 887 | return .{ .sym_index = @enumFromInt(sym_index) }; | |
| 853 | return @enumFromInt(sym_index); | |
| 888 | 854 | }, |
| 889 | 855 | .strong, .weak => { |
| 890 | 856 | const sym_index = try elf_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip)); |
| ... | ... | @@ -895,27 +861,19 @@ pub fn genNavRef( |
| 895 | 861 | .link_once => unreachable, |
| 896 | 862 | } |
| 897 | 863 | if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true; |
| 898 | return .{ .sym_index = @enumFromInt(sym_index) }; | |
| 864 | return @enumFromInt(sym_index); | |
| 899 | 865 | }, |
| 900 | 866 | .link_once => unreachable, |
| 901 | 867 | } |
| 902 | 868 | } 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); | |
| 912 | 870 | } else if (lf.cast(.macho)) |macho_file| { |
| 913 | 871 | const zo = macho_file.getZigObject().?; |
| 914 | 872 | switch (linkage) { |
| 915 | 873 | .internal => { |
| 916 | 874 | const sym_index = try zo.getOrCreateMetadataForNav(macho_file, nav_index); |
| 917 | 875 | if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true; |
| 918 | return .{ .sym_index = @enumFromInt(sym_index) }; | |
| 876 | return @enumFromInt(sym_index); | |
| 919 | 877 | }, |
| 920 | 878 | .strong, .weak => { |
| 921 | 879 | const sym_index = try macho_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip)); |
| ... | ... | @@ -926,80 +884,67 @@ pub fn genNavRef( |
| 926 | 884 | .link_once => unreachable, |
| 927 | 885 | } |
| 928 | 886 | if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true; |
| 929 | return .{ .sym_index = @enumFromInt(sym_index) }; | |
| 887 | return @enumFromInt(sym_index); | |
| 930 | 888 | }, |
| 931 | 889 | .link_once => unreachable, |
| 932 | 890 | } |
| 933 | 891 | } 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))); | |
| 935 | 893 | } 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}); | |
| 938 | 895 | } |
| 939 | 896 | } |
| 940 | 897 | |
| 941 | 898 | /// deprecated legacy type |
| 942 | pub 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 | }; | |
| 899 | pub 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, | |
| 971 | 923 | }; |
| 972 | 924 | |
| 973 | 925 | /// deprecated legacy code path |
| 974 | 926 | pub fn genTypedValue( |
| 975 | 927 | lf: *link.File, |
| 976 | 928 | pt: Zcu.PerThread, |
| 977 | src_loc: Zcu.LazySrcLoc, | |
| 978 | 929 | val: Value, |
| 979 | 930 | target: *const std.Target, |
| 980 | ) CodeGenError!GenResult { | |
| 931 | ) Error!MCValue { | |
| 981 | 932 | const res = try lowerValue(pt, val, target); |
| 982 | 933 | 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( | |
| 991 | 939 | pt, |
| 992 | 940 | uav.val, |
| 993 | 941 | 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 | ) }, | |
| 1003 | 948 | }; |
| 1004 | 949 | } |
| 1005 | 950 |
src/codegen/aarch64.zig-1| ... | ... | @@ -12,7 +12,6 @@ pub fn legalizeFeatures(_: *const std.Target) ?*Air.Legalize.Features { |
| 12 | 12 | pub fn generate( |
| 13 | 13 | _: *link.File, |
| 14 | 14 | pt: Zcu.PerThread, |
| 15 | _: Zcu.LazySrcLoc, | |
| 16 | 15 | func_index: InternPool.Index, |
| 17 | 16 | air: *const Air, |
| 18 | 17 | liveness: *const ?Air.Liveness, |
src/codegen/aarch64/Mir.zig+4-14| ... | ... | @@ -54,7 +54,6 @@ pub fn emit( |
| 54 | 54 | mir: Mir, |
| 55 | 55 | lf: *link.File, |
| 56 | 56 | pt: Zcu.PerThread, |
| 57 | src_loc: Zcu.LazySrcLoc, | |
| 58 | 57 | func_index: InternPool.Index, |
| 59 | 58 | atom_index: link.File.AtomId, |
| 60 | 59 | w: *std.Io.Writer, |
| ... | ... | @@ -94,16 +93,11 @@ pub fn emit( |
| 94 | 93 | lf, |
| 95 | 94 | zcu, |
| 96 | 95 | atom_index, |
| 97 | switch (try @import("../../codegen.zig").genNavRef( | |
| 96 | try @import("../../codegen.zig").genNavRef( | |
| 98 | 97 | lf, |
| 99 | 98 | pt, |
| 100 | src_loc, | |
| 101 | 99 | 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 | ), | |
| 107 | 101 | mir.body[nav_reloc.reloc.label], |
| 108 | 102 | body_end - Instruction.size * (1 + nav_reloc.reloc.label), |
| 109 | 103 | nav_reloc.reloc.addend, |
| ... | ... | @@ -113,15 +107,11 @@ pub fn emit( |
| 113 | 107 | lf, |
| 114 | 108 | zcu, |
| 115 | 109 | atom_index, |
| 116 | switch (try lf.lowerUav( | |
| 110 | try lf.lowerUav( | |
| 117 | 111 | pt, |
| 118 | 112 | uav_reloc.uav.val, |
| 119 | 113 | 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 | ), | |
| 125 | 115 | mir.body[uav_reloc.reloc.label], |
| 126 | 116 | body_end - Instruction.size * (1 + uav_reloc.reloc.label), |
| 127 | 117 | uav_reloc.reloc.addend, |
src/codegen/aarch64/Select.zig+5-5| ... | ... | @@ -883,7 +883,7 @@ pub fn finishAnalysis(isel: *Select) !void { |
| 883 | 883 | } |
| 884 | 884 | } |
| 885 | 885 | |
| 886 | pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, CodegenFail }!void { | |
| 886 | pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory, AlreadyReported }!void { | |
| 887 | 887 | const zcu = isel.pt.zcu; |
| 888 | 888 | const ip = &zcu.intern_pool; |
| 889 | 889 | const gpa = zcu.gpa; |
| ... | ... | @@ -8001,7 +8001,7 @@ fn emitLiteral(isel: *Select, bytes: []const u8) !void { |
| 8001 | 8001 | } |
| 8002 | 8002 | } |
| 8003 | 8003 | |
| 8004 | fn fail(isel: *Select, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { | |
| 8004 | fn fail(isel: *Select, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } { | |
| 8005 | 8005 | @branchHint(.cold); |
| 8006 | 8006 | return isel.pt.zcu.codegenFail(isel.nav_index, format, args); |
| 8007 | 8007 | } |
| ... | ... | @@ -10595,7 +10595,7 @@ pub const Value = struct { |
| 10595 | 10595 | vi: Value.Index, |
| 10596 | 10596 | ra: Register.Alias, |
| 10597 | 10597 | |
| 10598 | fn finish(mat: Value.Materialize, isel: *Select) error{ OutOfMemory, CodegenFail }!void { | |
| 10598 | fn finish(mat: Value.Materialize, isel: *Select) error{ OutOfMemory, AlreadyReported }!void { | |
| 10599 | 10599 | const live_vi = isel.live_registers.getPtr(mat.ra); |
| 10600 | 10600 | assert(live_vi.* == .allocating); |
| 10601 | 10601 | var vi = mat.vi; |
| ... | ... | @@ -11636,7 +11636,7 @@ fn use(isel: *Select, air_ref: Air.Inst.Ref) !Value.Index { |
| 11636 | 11636 | return vi; |
| 11637 | 11637 | } |
| 11638 | 11638 | |
| 11639 | fn fill(isel: *Select, dst_ra: Register.Alias) error{ OutOfMemory, CodegenFail }!bool { | |
| 11639 | fn fill(isel: *Select, dst_ra: Register.Alias) error{ OutOfMemory, AlreadyReported }!bool { | |
| 11640 | 11640 | switch (dst_ra) { |
| 11641 | 11641 | else => {}, |
| 11642 | 11642 | 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 } |
| 11669 | 11669 | return true; |
| 11670 | 11670 | } |
| 11671 | 11671 | |
| 11672 | fn fillMemory(isel: *Select, dst_ra: Register.Alias) error{ OutOfMemory, CodegenFail }!bool { | |
| 11672 | fn fillMemory(isel: *Select, dst_ra: Register.Alias) error{ OutOfMemory, AlreadyReported }!bool { | |
| 11673 | 11673 | const dst_live_vi = isel.live_registers.getPtr(dst_ra); |
| 11674 | 11674 | const dst_vi = switch (dst_live_vi.*) { |
| 11675 | 11675 | _ => |dst_vi| dst_vi, |
src/codegen/c.zig+4-12| ... | ... | @@ -80,7 +80,7 @@ pub const Mir = struct { |
| 80 | 80 | } |
| 81 | 81 | }; |
| 82 | 82 | |
| 83 | pub const Error = Writer.Error || Allocator.Error || error{AnalysisFail}; | |
| 83 | pub const Error = Writer.Error || Allocator.Error || error{AlreadyReported}; | |
| 84 | 84 | |
| 85 | 85 | pub const CType = @import("c/type.zig").CType; |
| 86 | 86 | |
| ... | ... | @@ -637,7 +637,6 @@ pub const DeclGen = struct { |
| 637 | 637 | owner_nav: InternPool.Nav.Index.Optional, |
| 638 | 638 | is_naked_fn: bool, |
| 639 | 639 | expected_block: ?u32, |
| 640 | error_msg: ?*Zcu.ErrorMsg, | |
| 641 | 640 | ctype_deps: CType.Dependencies, |
| 642 | 641 | /// This map contains all the UAVs we saw generating this function. |
| 643 | 642 | /// `link.C` will merge them into its `uavs`/`aligned_uavs` fields. |
| ... | ... | @@ -648,10 +647,7 @@ pub const DeclGen = struct { |
| 648 | 647 | |
| 649 | 648 | fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) Error { |
| 650 | 649 | @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); | |
| 655 | 651 | } |
| 656 | 652 | |
| 657 | 653 | fn renderUav( |
| ... | ... | @@ -2184,15 +2180,13 @@ pub fn genLazyCallModifierFn( |
| 2184 | 2180 | pub fn generate( |
| 2185 | 2181 | lf: *link.File, |
| 2186 | 2182 | pt: Zcu.PerThread, |
| 2187 | src_loc: Zcu.LazySrcLoc, | |
| 2188 | 2183 | func_index: InternPool.Index, |
| 2189 | 2184 | air: *const Air, |
| 2190 | 2185 | liveness: *const ?Air.Liveness, |
| 2191 | ) @import("../codegen.zig").CodeGenError!Mir { | |
| 2186 | ) @import("../codegen.zig").Error!Mir { | |
| 2192 | 2187 | const zcu = pt.zcu; |
| 2193 | 2188 | const gpa = zcu.gpa; |
| 2194 | 2189 | |
| 2195 | _ = src_loc; | |
| 2196 | 2190 | assert(lf.tag == .c); |
| 2197 | 2191 | |
| 2198 | 2192 | const func = zcu.funcInfo(func_index); |
| ... | ... | @@ -2210,7 +2204,6 @@ pub fn generate( |
| 2210 | 2204 | .arena = arena.allocator(), |
| 2211 | 2205 | .pt = pt, |
| 2212 | 2206 | .mod = zcu.navFileScope(func.owner_nav).mod.?, |
| 2213 | .error_msg = null, | |
| 2214 | 2207 | .owner_nav = func.owner_nav.toOptional(), |
| 2215 | 2208 | .is_naked_fn = Type.fromInterned(func.ty).fnCallingConvention(zcu) == .naked, |
| 2216 | 2209 | .expected_block = null, |
| ... | ... | @@ -2237,9 +2230,8 @@ pub fn generate( |
| 2237 | 2230 | defer code_header.deinit(); |
| 2238 | 2231 | |
| 2239 | 2232 | 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.?), | |
| 2241 | 2233 | error.WriteFailed => return error.OutOfMemory, |
| 2242 | error.OutOfMemory => |e| return e, | |
| 2234 | else => |e| return e, | |
| 2243 | 2235 | }; |
| 2244 | 2236 | |
| 2245 | 2237 | var mir: Mir = .{ |
src/codegen/llvm.zig+3-3| ... | ... | @@ -771,7 +771,7 @@ pub const Object = struct { |
| 771 | 771 | lto: std.zig.LtoMode, |
| 772 | 772 | }; |
| 773 | 773 | |
| 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 { | |
| 775 | 775 | const zcu = o.zcu; |
| 776 | 776 | const comp = zcu.comp; |
| 777 | 777 | const io = comp.io; |
| ... | ... | @@ -1705,7 +1705,7 @@ pub const Object = struct { |
| 1705 | 1705 | o: *Object, |
| 1706 | 1706 | exported: Zcu.Exported, |
| 1707 | 1707 | export_indices: []const Zcu.Export.Index, |
| 1708 | ) link.File.UpdateExportsError!void { | |
| 1708 | ) link.Error!void { | |
| 1709 | 1709 | const zcu = o.zcu; |
| 1710 | 1710 | const ip = &zcu.intern_pool; |
| 1711 | 1711 | const ty: Type, const llvm_ptr: Builder.Constant = switch (exported) { |
| ... | ... | @@ -1735,7 +1735,7 @@ pub const Object = struct { |
| 1735 | 1735 | global_index: Builder.Global.Index, |
| 1736 | 1736 | ty: Type, |
| 1737 | 1737 | export_indices: []const Zcu.Export.Index, |
| 1738 | ) link.File.UpdateExportsError!void { | |
| 1738 | ) link.Error!void { | |
| 1739 | 1739 | const zcu = o.zcu; |
| 1740 | 1740 | const comp = zcu.comp; |
| 1741 | 1741 | 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); |
| 30 | 30 | const wip_mir_log = std.log.scoped(.wip_mir); |
| 31 | 31 | const Alignment = InternPool.Alignment; |
| 32 | 32 | |
| 33 | const CodeGenError = codegen.CodeGenError; | |
| 34 | ||
| 35 | 33 | const bits = @import("bits.zig"); |
| 36 | 34 | const abi = @import("abi.zig"); |
| 37 | 35 | const Lower = @import("Lower.zig"); |
| ... | ... | @@ -49,7 +47,7 @@ const RegisterManager = abi.RegisterManager; |
| 49 | 47 | const RegisterLock = RegisterManager.RegisterLock; |
| 50 | 48 | const Instruction = encoding.Instruction; |
| 51 | 49 | |
| 52 | const InnerError = CodeGenError || error{OutOfRegisters}; | |
| 50 | const InnerError = codegen.Error || error{OutOfRegisters}; | |
| 53 | 51 | |
| 54 | 52 | pub fn legalizeFeatures(_: *const std.Target) *const Air.Legalize.Features { |
| 55 | 53 | return comptime &.initMany(&.{ |
| ... | ... | @@ -75,7 +73,6 @@ ret_mcv: InstTracking, |
| 75 | 73 | func_index: InternPool.Index, |
| 76 | 74 | fn_type: Type, |
| 77 | 75 | arg_index: usize, |
| 78 | src_loc: Zcu.LazySrcLoc, | |
| 79 | 76 | |
| 80 | 77 | mir_instructions: std.MultiArrayList(Mir.Inst) = .{}, |
| 81 | 78 | |
| ... | ... | @@ -742,11 +739,10 @@ const CallView = enum(u1) { |
| 742 | 739 | pub fn generate( |
| 743 | 740 | bin_file: *link.File, |
| 744 | 741 | pt: Zcu.PerThread, |
| 745 | src_loc: Zcu.LazySrcLoc, | |
| 746 | 742 | func_index: InternPool.Index, |
| 747 | 743 | air: *const Air, |
| 748 | 744 | liveness: *const ?Air.Liveness, |
| 749 | ) CodeGenError!Mir { | |
| 745 | ) codegen.Error!Mir { | |
| 750 | 746 | const zcu = pt.zcu; |
| 751 | 747 | const gpa = zcu.gpa; |
| 752 | 748 | const ip = &zcu.intern_pool; |
| ... | ... | @@ -777,7 +773,6 @@ pub fn generate( |
| 777 | 773 | .fn_type = fn_type, |
| 778 | 774 | .arg_index = 0, |
| 779 | 775 | .branch_stack = &branch_stack, |
| 780 | .src_loc = src_loc, | |
| 781 | 776 | .end_di_line = func.rbrace_line, |
| 782 | 777 | .end_di_column = func.rbrace_column, |
| 783 | 778 | .scope_generation = 0, |
| ... | ... | @@ -811,10 +806,7 @@ pub fn generate( |
| 811 | 806 | ); |
| 812 | 807 | |
| 813 | 808 | 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, &.{}); | |
| 818 | 810 | |
| 819 | 811 | defer call_info.deinit(&function); |
| 820 | 812 | |
| ... | ... | @@ -841,7 +833,6 @@ pub fn generate( |
| 841 | 833 | })); |
| 842 | 834 | |
| 843 | 835 | function.gen() catch |err| switch (err) { |
| 844 | error.CodegenFail => |e| return e, | |
| 845 | 836 | error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), |
| 846 | 837 | else => |e| return e, |
| 847 | 838 | }; |
| ... | ... | @@ -857,12 +848,11 @@ pub fn generate( |
| 857 | 848 | pub fn generateLazy( |
| 858 | 849 | bin_file: *link.File, |
| 859 | 850 | pt: Zcu.PerThread, |
| 860 | src_loc: Zcu.LazySrcLoc, | |
| 861 | 851 | lazy_sym: link.File.LazySymbol, |
| 862 | 852 | atom_index: link.File.AtomId, |
| 863 | 853 | w: *std.Io.Writer, |
| 864 | 854 | debug_output: link.File.DebugInfoOutput, |
| 865 | ) (CodeGenError || std.Io.Writer.Error)!void { | |
| 855 | ) (codegen.Error || std.Io.Writer.Error)!void { | |
| 866 | 856 | _ = atom_index; |
| 867 | 857 | const comp = bin_file.comp; |
| 868 | 858 | const gpa = comp.gpa; |
| ... | ... | @@ -883,7 +873,6 @@ pub fn generateLazy( |
| 883 | 873 | .fn_type = undefined, |
| 884 | 874 | .arg_index = 0, |
| 885 | 875 | .branch_stack = undefined, |
| 886 | .src_loc = src_loc, | |
| 887 | 876 | .end_di_line = undefined, |
| 888 | 877 | .end_di_column = undefined, |
| 889 | 878 | .scope_generation = 0, |
| ... | ... | @@ -893,7 +882,6 @@ pub fn generateLazy( |
| 893 | 882 | defer function.mir_instructions.deinit(gpa); |
| 894 | 883 | |
| 895 | 884 | function.genLazy(lazy_sym) catch |err| switch (err) { |
| 896 | error.CodegenFail => |e| return e, | |
| 897 | 885 | error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), |
| 898 | 886 | else => |e| return e, |
| 899 | 887 | }; |
| ... | ... | @@ -910,7 +898,7 @@ pub fn generateLazy( |
| 910 | 898 | .allocator = gpa, |
| 911 | 899 | .mir = mir, |
| 912 | 900 | .cc = .auto, |
| 913 | .src_loc = src_loc, | |
| 901 | .src_loc = Type.fromInterned(lazy_sym.ty).srcLocOrNull(pt.zcu) orelse .unneeded, | |
| 914 | 902 | .output_mode = comp.config.output_mode, |
| 915 | 903 | .link_mode = comp.config.link_mode, |
| 916 | 904 | .pic = mod.pic, |
| ... | ... | @@ -946,7 +934,10 @@ fn formatWipMir(data: FormatWipMirData, writer: *std.Io.Writer) std.Io.Writer.Er |
| 946 | 934 | .frame_locs = data.func.frame_locs.slice(), |
| 947 | 935 | }, |
| 948 | 936 | .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 | }, | |
| 950 | 941 | .output_mode = comp.config.output_mode, |
| 951 | 942 | .link_mode = comp.config.link_mode, |
| 952 | 943 | .pic = comp.root_mod.pic, |
| ... | ... | @@ -8144,28 +8135,21 @@ fn genTypedValue(func: *Func, val: Value) InnerError!MCValue { |
| 8144 | 8135 | const pt = func.pt; |
| 8145 | 8136 | |
| 8146 | 8137 | const lf = func.bin_file; |
| 8147 | const src_loc = func.src_loc; | |
| 8148 | 8138 | |
| 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) } | |
| 8154 | 8141 | else |
| 8155 | try codegen.genTypedValue(lf, pt, src_loc, val, func.target); | |
| 8142 | try codegen.genTypedValue(lf, pt, val, func.target); | |
| 8156 | 8143 | 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)}); | |
| 8167 | 8152 | }, |
| 8168 | .fail => |msg| return func.failMsg(msg), | |
| 8169 | 8153 | }; |
| 8170 | 8154 | return mcv; |
| 8171 | 8155 | } |
| ... | ... | @@ -8353,24 +8337,24 @@ fn wantSafety(func: *Func) bool { |
| 8353 | 8337 | }; |
| 8354 | 8338 | } |
| 8355 | 8339 | |
| 8356 | fn fail(func: *const Func, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { | |
| 8340 | fn fail(func: *const Func, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } { | |
| 8357 | 8341 | @branchHint(.cold); |
| 8358 | 8342 | const zcu = func.pt.zcu; |
| 8359 | 8343 | switch (func.owner) { |
| 8360 | 8344 | .nav_index => |i| return zcu.codegenFail(i, format, args), |
| 8361 | 8345 | .lazy_sym => |s| return zcu.codegenFailType(s.ty, format, args), |
| 8362 | 8346 | } |
| 8363 | return error.CodegenFail; | |
| 8347 | return error.AlreadyReported; | |
| 8364 | 8348 | } |
| 8365 | 8349 | |
| 8366 | fn failMsg(func: *const Func, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } { | |
| 8350 | fn failMsg(func: *const Func, msg: *ErrorMsg) error{ OutOfMemory, AlreadyReported } { | |
| 8367 | 8351 | @branchHint(.cold); |
| 8368 | 8352 | const zcu = func.pt.zcu; |
| 8369 | 8353 | switch (func.owner) { |
| 8370 | 8354 | .nav_index => |i| return zcu.codegenFailMsg(i, msg), |
| 8371 | 8355 | .lazy_sym => |s| return zcu.codegenFailTypeMsg(s.ty, msg), |
| 8372 | 8356 | } |
| 8373 | return error.CodegenFail; | |
| 8357 | return error.AlreadyReported; | |
| 8374 | 8358 | } |
| 8375 | 8359 | |
| 8376 | 8360 | fn parseRegName(name: []const u8) ?Register { |
src/codegen/riscv64/Mir.zig+2-3| ... | ... | @@ -107,12 +107,11 @@ pub fn emit( |
| 107 | 107 | mir: Mir, |
| 108 | 108 | lf: *link.File, |
| 109 | 109 | pt: Zcu.PerThread, |
| 110 | src_loc: Zcu.LazySrcLoc, | |
| 111 | 110 | func_index: InternPool.Index, |
| 112 | 111 | atom_index: link.File.AtomId, |
| 113 | 112 | w: *std.Io.Writer, |
| 114 | 113 | debug_output: link.File.DebugInfoOutput, |
| 115 | ) (codegen.CodeGenError || std.Io.Writer.Error)!void { | |
| 114 | ) (codegen.Error || std.Io.Writer.Error)!void { | |
| 116 | 115 | _ = atom_index; |
| 117 | 116 | const zcu = pt.zcu; |
| 118 | 117 | const comp = zcu.comp; |
| ... | ... | @@ -127,7 +126,7 @@ pub fn emit( |
| 127 | 126 | .allocator = gpa, |
| 128 | 127 | .mir = mir, |
| 129 | 128 | .cc = fn_info.cc, |
| 130 | .src_loc = src_loc, | |
| 129 | .src_loc = zcu.navSrcLoc(nav), | |
| 131 | 130 | .output_mode = comp.config.output_mode, |
| 132 | 131 | .link_mode = comp.config.link_mode, |
| 133 | 132 | .pic = mod.pic, |
src/codegen/sparc64/CodeGen.zig+11-28| ... | ... | @@ -19,7 +19,6 @@ const Air = @import("../../Air.zig"); |
| 19 | 19 | const Mir = @import("Mir.zig"); |
| 20 | 20 | const Emit = @import("Emit.zig"); |
| 21 | 21 | const Type = @import("../../Type.zig"); |
| 22 | const CodeGenError = codegen.CodeGenError; | |
| 23 | 22 | const Endian = std.lang.Endian; |
| 24 | 23 | const Alignment = InternPool.Alignment; |
| 25 | 24 | |
| ... | ... | @@ -39,7 +38,7 @@ const gp = abi.RegisterClass.gp; |
| 39 | 38 | |
| 40 | 39 | const Self = @This(); |
| 41 | 40 | |
| 42 | const InnerError = CodeGenError || error{OutOfRegisters}; | |
| 41 | const InnerError = codegen.Error || error{OutOfRegisters}; | |
| 43 | 42 | |
| 44 | 43 | pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features { |
| 45 | 44 | return null; |
| ... | ... | @@ -57,12 +56,10 @@ liveness: Air.Liveness, |
| 57 | 56 | bin_file: *link.File, |
| 58 | 57 | target: *const std.Target, |
| 59 | 58 | func_index: InternPool.Index, |
| 60 | err_msg: ?*ErrorMsg, | |
| 61 | 59 | args: []MCValue, |
| 62 | 60 | ret_mcv: MCValue, |
| 63 | 61 | fn_type: Type, |
| 64 | 62 | arg_index: usize, |
| 65 | src_loc: Zcu.LazySrcLoc, | |
| 66 | 63 | stack_align: Alignment, |
| 67 | 64 | |
| 68 | 65 | /// MIR Instructions |
| ... | ... | @@ -264,11 +261,10 @@ const BigTomb = struct { |
| 264 | 261 | pub fn generate( |
| 265 | 262 | lf: *link.File, |
| 266 | 263 | pt: Zcu.PerThread, |
| 267 | src_loc: Zcu.LazySrcLoc, | |
| 268 | 264 | func_index: InternPool.Index, |
| 269 | 265 | air: *const Air, |
| 270 | 266 | liveness: *const ?Air.Liveness, |
| 271 | ) CodeGenError!Mir { | |
| 267 | ) codegen.Error!Mir { | |
| 272 | 268 | const zcu = pt.zcu; |
| 273 | 269 | const gpa = zcu.gpa; |
| 274 | 270 | const func = zcu.funcInfo(func_index); |
| ... | ... | @@ -292,13 +288,11 @@ pub fn generate( |
| 292 | 288 | .target = target, |
| 293 | 289 | .bin_file = lf, |
| 294 | 290 | .func_index = func_index, |
| 295 | .err_msg = null, | |
| 296 | 291 | .args = undefined, // populated after `resolveCallingConventionValues` |
| 297 | 292 | .ret_mcv = undefined, // populated after `resolveCallingConventionValues` |
| 298 | 293 | .fn_type = func_ty, |
| 299 | 294 | .arg_index = 0, |
| 300 | 295 | .branch_stack = &branch_stack, |
| 301 | .src_loc = src_loc, | |
| 302 | 296 | .stack_align = undefined, |
| 303 | 297 | .end_di_line = func.rbrace_line, |
| 304 | 298 | .end_di_column = func.rbrace_column, |
| ... | ... | @@ -307,10 +301,7 @@ pub fn generate( |
| 307 | 301 | defer function.blocks.deinit(gpa); |
| 308 | 302 | defer function.exitlude_jump_relocs.deinit(gpa); |
| 309 | 303 | |
| 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); | |
| 314 | 305 | defer call_info.deinit(&function); |
| 315 | 306 | |
| 316 | 307 | function.args = call_info.args; |
| ... | ... | @@ -319,7 +310,6 @@ pub fn generate( |
| 319 | 310 | function.max_end_stack = call_info.stack_byte_count; |
| 320 | 311 | |
| 321 | 312 | function.gen() catch |err| switch (err) { |
| 322 | error.CodegenFail => |e| return e, | |
| 323 | 313 | error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), |
| 324 | 314 | else => |e| return e, |
| 325 | 315 | }; |
| ... | ... | @@ -3446,15 +3436,15 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) |
| 3446 | 3436 | } |
| 3447 | 3437 | } |
| 3448 | 3438 | |
| 3449 | fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { | |
| 3439 | fn fail(self: *Self, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } { | |
| 3450 | 3440 | @branchHint(.cold); |
| 3451 | 3441 | const zcu = self.pt.zcu; |
| 3452 | 3442 | 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); | |
| 3454 | 3444 | return zcu.codegenFailMsg(func.owner_nav, msg); |
| 3455 | 3445 | } |
| 3456 | 3446 | |
| 3457 | fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, CodegenFail } { | |
| 3447 | fn failMsg(self: *Self, msg: *ErrorMsg) error{ OutOfMemory, AlreadyReported } { | |
| 3458 | 3448 | @branchHint(.cold); |
| 3459 | 3449 | const zcu = self.pt.zcu; |
| 3460 | 3450 | const func = zcu.funcInfo(self.func_index); |
| ... | ... | @@ -4036,21 +4026,14 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { |
| 4036 | 4026 | const mcv: MCValue = switch (try codegen.genTypedValue( |
| 4037 | 4027 | self.bin_file, |
| 4038 | 4028 | pt, |
| 4039 | self.src_loc, | |
| 4040 | 4029 | val, |
| 4041 | 4030 | self.target, |
| 4042 | 4031 | )) { |
| 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 }, | |
| 4054 | 4037 | }; |
| 4055 | 4038 | return mcv; |
| 4056 | 4039 | } |
src/codegen/sparc64/Mir.zig+2-3| ... | ... | @@ -378,12 +378,11 @@ pub fn emit( |
| 378 | 378 | mir: Mir, |
| 379 | 379 | lf: *link.File, |
| 380 | 380 | pt: Zcu.PerThread, |
| 381 | src_loc: Zcu.LazySrcLoc, | |
| 382 | 381 | func_index: InternPool.Index, |
| 383 | 382 | atom_index: link.File.AtomId, |
| 384 | 383 | w: *std.Io.Writer, |
| 385 | 384 | debug_output: link.File.DebugInfoOutput, |
| 386 | ) (codegen.CodeGenError || std.Io.Writer.Error)!void { | |
| 385 | ) (codegen.Error || std.Io.Writer.Error)!void { | |
| 387 | 386 | _ = atom_index; |
| 388 | 387 | const zcu = pt.zcu; |
| 389 | 388 | const func = zcu.funcInfo(func_index); |
| ... | ... | @@ -394,7 +393,7 @@ pub fn emit( |
| 394 | 393 | .bin_file = lf, |
| 395 | 394 | .debug_output = debug_output, |
| 396 | 395 | .target = &mod.resolved_target.result, |
| 397 | .src_loc = src_loc, | |
| 396 | .src_loc = zcu.navSrcLoc(nav), | |
| 398 | 397 | .w = w, |
| 399 | 398 | .prev_di_pc = 0, |
| 400 | 399 | .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, |
| 156 | 156 | id_scratch: std.ArrayList(Id) = .empty, |
| 157 | 157 | prologue: Section = .{}, |
| 158 | 158 | body: Section = .{}, |
| 159 | error_msg: ?*Zcu.ErrorMsg = null, | |
| 160 | 159 | |
| 161 | 160 | pub fn deinit(cg: *CodeGen) void { |
| 162 | 161 | const gpa = cg.module.gpa; |
| ... | ... | @@ -168,7 +167,7 @@ pub fn deinit(cg: *CodeGen) void { |
| 168 | 167 | cg.body.deinit(gpa); |
| 169 | 168 | } |
| 170 | 169 | |
| 171 | const Error = error{ CodegenFail, OutOfMemory }; | |
| 170 | const Error = error{ AlreadyReported, OutOfMemory }; | |
| 172 | 171 | |
| 173 | 172 | pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void { |
| 174 | 173 | const gpa = cg.module.gpa; |
| ... | ... | @@ -363,11 +362,7 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void { |
| 363 | 362 | |
| 364 | 363 | pub fn fail(cg: *CodeGen, comptime format: []const u8, args: anytype) Error { |
| 365 | 364 | @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); | |
| 371 | 366 | } |
| 372 | 367 | |
| 373 | 368 | pub fn todo(cg: *CodeGen, comptime format: []const u8, args: anytype) Error { |
| ... | ... | @@ -5934,14 +5929,14 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) !?Id { |
| 5934 | 5929 | // them as notes here. |
| 5935 | 5930 | // TODO: Translate proper error locations. |
| 5936 | 5931 | 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); | |
| 5941 | 5936 | |
| 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); | |
| 5944 | 5938 | errdefer zcu.gpa.free(notes); |
| 5939 | ||
| 5945 | 5940 | var i: usize = 0; |
| 5946 | 5941 | errdefer for (notes[0..i]) |*note| { |
| 5947 | 5942 | note.deinit(zcu.gpa); |
| ... | ... | @@ -5950,9 +5945,10 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) !?Id { |
| 5950 | 5945 | while (i < ass.errors.items.len) : (i += 1) { |
| 5951 | 5946 | notes[i] = try Zcu.ErrorMsg.init(zcu.gpa, src_loc, "{s}", .{ass.errors.items[i].msg}); |
| 5952 | 5947 | } |
| 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); | |
| 5956 | 5952 | }, |
| 5957 | 5953 | else => |others| return others, |
| 5958 | 5954 | }; |
src/codegen/wasm/CodeGen.zig+4-9| ... | ... | @@ -329,7 +329,7 @@ const bookkeeping_init = if (std.debug.runtime_safety) @as(usize, 0) else {}; |
| 329 | 329 | const InnerError = error{ |
| 330 | 330 | OutOfMemory, |
| 331 | 331 | /// An error occurred when trying to lower AIR to MIR. |
| 332 | CodegenFail, | |
| 332 | AlreadyReported, | |
| 333 | 333 | /// Compiler implementation could not handle a large integer. |
| 334 | 334 | Overflow, |
| 335 | 335 | } || link.File.UpdateDebugInfoError; |
| ... | ... | @@ -355,7 +355,7 @@ pub fn deinit(cg: *CodeGen) void { |
| 355 | 355 | cg.* = undefined; |
| 356 | 356 | } |
| 357 | 357 | |
| 358 | pub fn fail(cg: *CodeGen, comptime fmt: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { | |
| 358 | pub fn fail(cg: *CodeGen, comptime fmt: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } { | |
| 359 | 359 | const zcu = cg.pt.zcu; |
| 360 | 360 | const func = zcu.funcInfo(cg.func_index); |
| 361 | 361 | return zcu.codegenFail(func.owner_nav, fmt, args); |
| ... | ... | @@ -756,21 +756,17 @@ fn ensureAllocLocal(cg: *CodeGen, ty: Type) InnerError!WValue { |
| 756 | 756 | |
| 757 | 757 | pub const Error = error{ |
| 758 | 758 | OutOfMemory, |
| 759 | /// Compiler was asked to operate on a number larger than supported. | |
| 760 | Overflow, | |
| 761 | 759 | /// Indicates the error is already stored in Zcu `failed_codegen`. |
| 762 | CodegenFail, | |
| 760 | AlreadyReported, | |
| 763 | 761 | }; |
| 764 | 762 | |
| 765 | 763 | pub fn generate( |
| 766 | 764 | bin_file: *link.File, |
| 767 | 765 | pt: Zcu.PerThread, |
| 768 | src_loc: Zcu.LazySrcLoc, | |
| 769 | 766 | func_index: InternPool.Index, |
| 770 | 767 | air: *const Air, |
| 771 | 768 | liveness: *const ?Air.Liveness, |
| 772 | 769 | ) Error!Mir { |
| 773 | _ = src_loc; | |
| 774 | 770 | _ = bin_file; |
| 775 | 771 | const zcu = pt.zcu; |
| 776 | 772 | const gpa = zcu.gpa; |
| ... | ... | @@ -814,9 +810,8 @@ pub fn generate( |
| 814 | 810 | try code_gen.mir_func_tys.putNoClobber(gpa, fn_ty.toIntern(), {}); |
| 815 | 811 | |
| 816 | 812 | return generateInner(&code_gen, any_returns) catch |err| switch (err) { |
| 817 | error.CodegenFail, | |
| 813 | error.AlreadyReported, | |
| 818 | 814 | error.OutOfMemory, |
| 819 | error.Overflow, | |
| 820 | 815 | => |e| return e, |
| 821 | 816 | else => |e| return code_gen.fail("failed to generate function: {s}", .{@errorName(e)}), |
| 822 | 817 | }; |
src/codegen/x86_64/CodeGen.zig+10-17| ... | ... | @@ -31,7 +31,7 @@ const RegisterManager = abi.RegisterManager; |
| 31 | 31 | const RegisterLock = RegisterManager.RegisterLock; |
| 32 | 32 | const FrameIndex = bits.FrameIndex; |
| 33 | 33 | |
| 34 | const InnerError = codegen.CodeGenError || error{OutOfRegisters}; | |
| 34 | const InnerError = codegen.Error || error{OutOfRegisters}; | |
| 35 | 35 | |
| 36 | 36 | pub fn legalizeFeatures(_: *const std.Target) *const Air.Legalize.Features { |
| 37 | 37 | return comptime &.initMany(&.{ |
| ... | ... | @@ -106,7 +106,6 @@ va_info: union { |
| 106 | 106 | ret_mcv: InstTracking, |
| 107 | 107 | err_ret_trace_reg: Register, |
| 108 | 108 | fn_type: Type, |
| 109 | src_loc: Zcu.LazySrcLoc, | |
| 110 | 109 | |
| 111 | 110 | eflags_inst: ?Air.Inst.Index = null, |
| 112 | 111 | |
| ... | ... | @@ -869,11 +868,10 @@ const CodeGen = @This(); |
| 869 | 868 | pub fn generate( |
| 870 | 869 | bin_file: *link.File, |
| 871 | 870 | pt: Zcu.PerThread, |
| 872 | src_loc: Zcu.LazySrcLoc, | |
| 873 | 871 | func_index: InternPool.Index, |
| 874 | 872 | air: *const Air, |
| 875 | 873 | liveness: *const ?Air.Liveness, |
| 876 | ) codegen.CodeGenError!Mir { | |
| 874 | ) codegen.Error!Mir { | |
| 877 | 875 | _ = bin_file; |
| 878 | 876 | const zcu = pt.zcu; |
| 879 | 877 | const gpa = zcu.gpa; |
| ... | ... | @@ -898,7 +896,6 @@ pub fn generate( |
| 898 | 896 | .ret_mcv = undefined, // populated after `resolveCallingConventionValues` |
| 899 | 897 | .err_ret_trace_reg = undefined, // populated after `resolveCallingConventionValues` |
| 900 | 898 | .fn_type = fn_type, |
| 901 | .src_loc = src_loc, | |
| 902 | 899 | }; |
| 903 | 900 | defer { |
| 904 | 901 | function.frame_allocs.deinit(gpa); |
| ... | ... | @@ -937,10 +934,7 @@ pub fn generate( |
| 937 | 934 | ); |
| 938 | 935 | |
| 939 | 936 | 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); | |
| 944 | 938 | defer call_info.deinit(&function); |
| 945 | 939 | |
| 946 | 940 | function.args = call_info.args; |
| ... | ... | @@ -983,7 +977,6 @@ pub fn generate( |
| 983 | 977 | } |
| 984 | 978 | |
| 985 | 979 | 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, | |
| 987 | 980 | error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), |
| 988 | 981 | else => |e| return e, |
| 989 | 982 | }; |
| ... | ... | @@ -1027,12 +1020,11 @@ pub fn getTmpMir(cg: *CodeGen) Mir { |
| 1027 | 1020 | pub fn generateLazy( |
| 1028 | 1021 | bin_file: *link.File, |
| 1029 | 1022 | pt: Zcu.PerThread, |
| 1030 | src_loc: Zcu.LazySrcLoc, | |
| 1031 | 1023 | lazy_sym: link.File.LazySymbol, |
| 1032 | 1024 | atom_id: link.File.AtomId, |
| 1033 | 1025 | w: *std.Io.Writer, |
| 1034 | 1026 | debug_output: link.File.DebugInfoOutput, |
| 1035 | ) codegen.CodeGenError!void { | |
| 1027 | ) codegen.Error!void { | |
| 1036 | 1028 | const gpa = pt.zcu.gpa; |
| 1037 | 1029 | // This function is for generating global code, so we use the root module. |
| 1038 | 1030 | const mod = pt.zcu.comp.root_mod; |
| ... | ... | @@ -1050,7 +1042,6 @@ pub fn generateLazy( |
| 1050 | 1042 | .ret_mcv = undefined, |
| 1051 | 1043 | .err_ret_trace_reg = undefined, |
| 1052 | 1044 | .fn_type = undefined, |
| 1053 | .src_loc = src_loc, | |
| 1054 | 1045 | }; |
| 1055 | 1046 | defer { |
| 1056 | 1047 | function.inst_tracking.deinit(gpa); |
| ... | ... | @@ -1068,12 +1059,11 @@ pub fn generateLazy( |
| 1068 | 1059 | } |
| 1069 | 1060 | |
| 1070 | 1061 | function.genLazy(lazy_sym) catch |err| switch (err) { |
| 1071 | error.CodegenFail => |e| return e, | |
| 1072 | 1062 | error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), |
| 1073 | 1063 | else => |e| return e, |
| 1074 | 1064 | }; |
| 1075 | 1065 | |
| 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); | |
| 1077 | 1067 | } |
| 1078 | 1068 | |
| 1079 | 1069 | const FormatNavData = struct { |
| ... | ... | @@ -1111,7 +1101,10 @@ fn formatWipMir(data: FormatWipMirData, w: *Writer) Writer.Error!void { |
| 1111 | 1101 | .allocator = data.self.gpa, |
| 1112 | 1102 | .mir = data.self.getTmpMir(), |
| 1113 | 1103 | .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 | }, | |
| 1115 | 1108 | }; |
| 1116 | 1109 | var first = true; |
| 1117 | 1110 | for ((lower.lowerMir(data.inst) catch |err| switch (err) { |
| ... | ... | @@ -181508,7 +181501,7 @@ fn resolveCallingConventionValues( |
| 181508 | 181501 | return result; |
| 181509 | 181502 | } |
| 181510 | 181503 | |
| 181511 | fn fail(cg: *CodeGen, comptime format: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { | |
| 181504 | fn fail(cg: *CodeGen, comptime format: []const u8, args: anytype) error{ OutOfMemory, AlreadyReported } { | |
| 181512 | 181505 | @branchHint(.cold); |
| 181513 | 181506 | const zcu = cg.pt.zcu; |
| 181514 | 181507 | return switch (cg.owner) { |
src/codegen/x86_64/Emit.zig+13-57| ... | ... | @@ -17,6 +17,7 @@ relocs: std.ArrayList(Reloc), |
| 17 | 17 | table_relocs: std.ArrayList(TableReloc), |
| 18 | 18 | |
| 19 | 19 | pub const Error = Lower.Error || error{ |
| 20 | AlreadyReported, | |
| 20 | 21 | EmitFail, |
| 21 | 22 | NotFile, |
| 22 | 23 | } || std.posix.MMapError || std.posix.MRemapError || link.File.UpdateDebugInfoError; |
| ... | ... | @@ -101,20 +102,11 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 101 | 102 | .inst => |inst| .{ .inst = inst }, |
| 102 | 103 | .table => .table, |
| 103 | 104 | .nav => |nav| { |
| 104 | const symbol_id = switch (try codegen.genNavRef( | |
| 105 | const symbol_id = try codegen.genNavRef( | |
| 105 | 106 | emit.bin_file, |
| 106 | 107 | emit.pt, |
| 107 | emit.lower.src_loc, | |
| 108 | 108 | 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 | ); | |
| 118 | 110 | const target_symbol: RelocInfo.Target.Symbol = if (ip.getNav(nav).getExtern(ip)) |@"extern"| .{ |
| 119 | 111 | .symbol = symbol_id, |
| 120 | 112 | .is_extern = switch (@"extern".visibility) { |
| ... | ... | @@ -133,19 +125,11 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 133 | 125 | } |
| 134 | 126 | }, |
| 135 | 127 | .uav => |uav| .{ .symbol = .{ |
| 136 | .symbol = switch (try emit.bin_file.lowerUav( | |
| 128 | .symbol = try emit.bin_file.lowerUav( | |
| 137 | 129 | emit.pt, |
| 138 | 130 | uav.val, |
| 139 | 131 | 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 | ), | |
| 149 | 133 | .is_extern = false, |
| 150 | 134 | } }, |
| 151 | 135 | .lazy_sym => |lazy_sym| .{ .symbol = .{ |
| ... | ... | @@ -168,17 +152,14 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 168 | 152 | .extern_func => |extern_func| .{ .symbol = .{ |
| 169 | 153 | .symbol = if (emit.bin_file.cast(.elf)) |elf_file| |
| 170 | 154 | @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(.{ | |
| 172 | 156 | .name = extern_func.toSlice(&emit.lower.mir).?, |
| 173 | 157 | .lib_name = switch (comp.compiler_rt_strat) { |
| 174 | 158 | .none, .lib, .obj, .zcu => null, |
| 175 | 159 | .dyn_lib => "compiler_rt", |
| 176 | 160 | }, |
| 177 | 161 | .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| | |
| 182 | 163 | @enumFromInt(try macho_file.getGlobalSymbol(extern_func.toSlice(&emit.lower.mir).?, null)) |
| 183 | 164 | else if (emit.bin_file.cast(.coff2)) |coff| @enumFromInt(@intFromEnum(try coff.globalSymbol( |
| 184 | 165 | extern_func.toSlice(&emit.lower.mir).?, |
| ... | ... | @@ -313,14 +294,11 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 313 | 294 | .symbol = if (emit.bin_file.cast(.elf)) |elf_file| @enumFromInt(try elf_file.getGlobalSymbol( |
| 314 | 295 | "__tls_get_addr", |
| 315 | 296 | 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(.{ | |
| 317 | 298 | .name = "__tls_get_addr", |
| 318 | 299 | .lib_name = if (comp.config.link_libc) "c" else null, |
| 319 | 300 | .type = .FUNC, |
| 320 | }) catch |err| switch (err) { | |
| 321 | error.LinkOnceUnsupported => unreachable, | |
| 322 | else => |e| return e, | |
| 323 | } else unreachable, | |
| 301 | }) else unreachable, | |
| 324 | 302 | .is_extern = true, |
| 325 | 303 | } }, |
| 326 | 304 | }}); |
| ... | ... | @@ -584,37 +562,16 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 584 | 562 | .none => .{ .constu = 0 }, |
| 585 | 563 | .reg => |reg| .{ .breg = reg.dwarfNum() }, |
| 586 | 564 | .frame, .table, .rip_inst => unreachable, |
| 587 | .nav => |nav| .{ .addr_reloc = switch (codegen.genNavRef( | |
| 565 | .nav => |nav| .{ .addr_reloc = try codegen.genNavRef( | |
| 588 | 566 | emit.bin_file, |
| 589 | 567 | emit.pt, |
| 590 | emit.lower.src_loc, | |
| 591 | 568 | 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( | |
| 606 | 571 | emit.pt, |
| 607 | 572 | uav.val, |
| 608 | 573 | 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 | ) }, | |
| 618 | 575 | .lazy_sym, .extern_func => unreachable, |
| 619 | 576 | }; |
| 620 | 577 | break :base &loc_buf[0]; |
| ... | ... | @@ -666,7 +623,6 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 666 | 623 | const local = &emit.lower.mir.locals[local_index]; |
| 667 | 624 | local_index += 1; |
| 668 | 625 | try dwarf.genLocalConstDebugInfo( |
| 669 | emit.lower.src_loc, | |
| 670 | 626 | switch (mir_inst.ops) { |
| 671 | 627 | else => unreachable, |
| 672 | 628 | .pseudo_dbg_arg_val => .comptime_arg, |
src/codegen/x86_64/Lower.zig+2-2| ... | ... | @@ -49,8 +49,8 @@ pub const Error = error{ |
| 49 | 49 | LowerFail, |
| 50 | 50 | InvalidInstruction, |
| 51 | 51 | CannotEncode, |
| 52 | CodegenFail, | |
| 53 | } || codegen.GenerateSymbolError; | |
| 52 | AlreadyReported, | |
| 53 | } || link.Error; | |
| 54 | 54 | |
| 55 | 55 | pub const Reloc = struct { |
| 56 | 56 | lowered_inst_index: ResultInstIndex, |
src/codegen/x86_64/Mir.zig+4-6| ... | ... | @@ -1974,12 +1974,11 @@ pub fn emit( |
| 1974 | 1974 | mir: Mir, |
| 1975 | 1975 | lf: *link.File, |
| 1976 | 1976 | pt: Zcu.PerThread, |
| 1977 | src_loc: Zcu.LazySrcLoc, | |
| 1978 | 1977 | func_index: InternPool.Index, |
| 1979 | 1978 | atom_id: link.File.AtomId, |
| 1980 | 1979 | w: *std.Io.Writer, |
| 1981 | 1980 | debug_output: link.File.DebugInfoOutput, |
| 1982 | ) codegen.CodeGenError!void { | |
| 1981 | ) codegen.Error!void { | |
| 1983 | 1982 | const zcu = pt.zcu; |
| 1984 | 1983 | const comp = zcu.comp; |
| 1985 | 1984 | const gpa = comp.gpa; |
| ... | ... | @@ -1993,7 +1992,7 @@ pub fn emit( |
| 1993 | 1992 | .allocator = gpa, |
| 1994 | 1993 | .mir = mir, |
| 1995 | 1994 | .cc = fn_info.cc, |
| 1996 | .src_loc = src_loc, | |
| 1995 | .src_loc = zcu.navSrcLoc(nav), | |
| 1997 | 1996 | }, |
| 1998 | 1997 | .bin_file = lf, |
| 1999 | 1998 | .pt = pt, |
| ... | ... | @@ -2028,12 +2027,11 @@ pub fn emitLazy( |
| 2028 | 2027 | mir: Mir, |
| 2029 | 2028 | lf: *link.File, |
| 2030 | 2029 | pt: Zcu.PerThread, |
| 2031 | src_loc: Zcu.LazySrcLoc, | |
| 2032 | 2030 | lazy_sym: link.File.LazySymbol, |
| 2033 | 2031 | atom_id: link.File.AtomId, |
| 2034 | 2032 | w: *std.Io.Writer, |
| 2035 | 2033 | debug_output: link.File.DebugInfoOutput, |
| 2036 | ) codegen.CodeGenError!void { | |
| 2034 | ) codegen.Error!void { | |
| 2037 | 2035 | const zcu = pt.zcu; |
| 2038 | 2036 | const comp = zcu.comp; |
| 2039 | 2037 | const gpa = comp.gpa; |
| ... | ... | @@ -2044,7 +2042,7 @@ pub fn emitLazy( |
| 2044 | 2042 | .allocator = gpa, |
| 2045 | 2043 | .mir = mir, |
| 2046 | 2044 | .cc = .auto, |
| 2047 | .src_loc = src_loc, | |
| 2045 | .src_loc = Zcu.Type.fromInterned(lazy_sym.ty).srcLocOrNull(zcu) orelse .unneeded, | |
| 2048 | 2046 | }, |
| 2049 | 2047 | .bin_file = lf, |
| 2050 | 2048 | .pt = pt, |
src/link.zig+57-90| ... | ... | @@ -31,6 +31,12 @@ pub const LdScript = @import("link/LdScript.zig"); |
| 31 | 31 | pub const Queue = @import("link/Queue.zig"); |
| 32 | 32 | pub const ConstPool = @import("link/ConstPool.zig"); |
| 33 | 33 | |
| 34 | pub 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 | ||
| 34 | 40 | pub const Diags = struct { |
| 35 | 41 | /// Stored here so that function definitions can distinguish between |
| 36 | 42 | /// needing an allocator for things besides error reporting. |
| ... | ... | @@ -112,7 +118,7 @@ pub const Diags = struct { |
| 112 | 118 | err: ErrorWithNotes, |
| 113 | 119 | comptime format: []const u8, |
| 114 | 120 | args: anytype, |
| 115 | ) error{OutOfMemory}!void { | |
| 121 | ) Allocator.Error!void { | |
| 116 | 122 | const gpa = err.diags.gpa; |
| 117 | 123 | const err_msg = &err.diags.msgs.items[err.index]; |
| 118 | 124 | err_msg.msg = try std.fmt.allocPrint(gpa, format, args); |
| ... | ... | @@ -212,16 +218,16 @@ pub const Diags = struct { |
| 212 | 218 | } |
| 213 | 219 | } |
| 214 | 220 | |
| 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} { | |
| 216 | 222 | @branchHint(.cold); |
| 217 | 223 | addError(diags, format, args); |
| 218 | return error.LinkFailure; | |
| 224 | return error.AlreadyReported; | |
| 219 | 225 | } |
| 220 | 226 | |
| 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} { | |
| 222 | 228 | @branchHint(.cold); |
| 223 | 229 | addErrorSourceLocation(diags, sl, format, args); |
| 224 | return error.LinkFailure; | |
| 230 | return error.AlreadyReported; | |
| 225 | 231 | } |
| 226 | 232 | |
| 227 | 233 | pub fn addError(diags: *Diags, comptime format: []const u8, args: anytype) void { |
| ... | ... | @@ -251,7 +257,7 @@ pub const Diags = struct { |
| 251 | 257 | }); |
| 252 | 258 | } |
| 253 | 259 | |
| 254 | pub fn addErrorWithNotes(diags: *Diags, note_count: usize) error{OutOfMemory}!ErrorWithNotes { | |
| 260 | pub fn addErrorWithNotes(diags: *Diags, note_count: usize) Allocator.Error!ErrorWithNotes { | |
| 255 | 261 | @branchHint(.cold); |
| 256 | 262 | const gpa = diags.gpa; |
| 257 | 263 | const io = diags.io; |
| ... | ... | @@ -261,7 +267,7 @@ pub const Diags = struct { |
| 261 | 267 | return addErrorWithNotesAssumeCapacity(diags, note_count); |
| 262 | 268 | } |
| 263 | 269 | |
| 264 | pub fn addErrorWithNotesAssumeCapacity(diags: *Diags, note_count: usize) error{OutOfMemory}!ErrorWithNotes { | |
| 270 | pub fn addErrorWithNotesAssumeCapacity(diags: *Diags, note_count: usize) Allocator.Error!ErrorWithNotes { | |
| 265 | 271 | @branchHint(.cold); |
| 266 | 272 | const gpa = diags.gpa; |
| 267 | 273 | const index = diags.msgs.items.len; |
| ... | ... | @@ -351,10 +357,10 @@ pub const Diags = struct { |
| 351 | 357 | path: Path, |
| 352 | 358 | comptime format: []const u8, |
| 353 | 359 | args: anytype, |
| 354 | ) error{LinkFailure} { | |
| 360 | ) error{AlreadyReported} { | |
| 355 | 361 | @branchHint(.cold); |
| 356 | 362 | addParseError(diags, path, format, args); |
| 357 | return error.LinkFailure; | |
| 363 | return error.AlreadyReported; | |
| 358 | 364 | } |
| 359 | 365 | |
| 360 | 366 | pub fn setAllocFailure(diags: *Diags) void { |
| ... | ... | @@ -752,11 +758,6 @@ pub const File = struct { |
| 752 | 758 | none, |
| 753 | 759 | }; |
| 754 | 760 | 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; | |
| 760 | 761 | |
| 761 | 762 | /// Opaque identifier for a function currently being emitted. |
| 762 | 763 | /// |
| ... | ... | @@ -775,7 +776,7 @@ pub const File = struct { |
| 775 | 776 | /// be created. This symbol may get resolved once all relocatables are (re-)linked. |
| 776 | 777 | /// Optionally, it is possible to specify where to expect the symbol defined if it |
| 777 | 778 | /// 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 { | |
| 779 | 780 | log.debug("getGlobalSymbol '{s}' (expected in '{?s}')", .{ name, lib_name }); |
| 780 | 781 | switch (base.tag) { |
| 781 | 782 | .lld => unreachable, |
| ... | ... | @@ -790,7 +791,7 @@ pub const File = struct { |
| 790 | 791 | |
| 791 | 792 | /// May be called before or after updateExports for any given Nav. |
| 792 | 793 | /// 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 { | |
| 794 | 795 | assert(base.comp.zcu.?.llvm_object == null); |
| 795 | 796 | const nav = pt.zcu.intern_pool.getNav(nav_index); |
| 796 | 797 | assert(nav.resolved.?.value != .none); |
| ... | ... | @@ -804,14 +805,8 @@ pub const File = struct { |
| 804 | 805 | } |
| 805 | 806 | } |
| 806 | 807 | |
| 807 | pub const UpdateContainerTypeError = error{ | |
| 808 | OutOfMemory, | |
| 809 | /// `Zcu.failed_types` is already populated with the error message. | |
| 810 | TypeFailureReported, | |
| 811 | }; | |
| 812 | ||
| 813 | 808 | /// 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 { | |
| 815 | 810 | assert(base.comp.zcu.?.llvm_object == null); |
| 816 | 811 | switch (base.tag) { |
| 817 | 812 | .lld => unreachable, |
| ... | ... | @@ -824,7 +819,7 @@ pub const File = struct { |
| 824 | 819 | } |
| 825 | 820 | |
| 826 | 821 | /// 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 { | |
| 828 | 823 | assert(base.comp.zcu.?.llvm_object == null); |
| 829 | 824 | switch (base.tag) { |
| 830 | 825 | .lld => unreachable, |
| ... | ... | @@ -847,7 +842,7 @@ pub const File = struct { |
| 847 | 842 | /// that `mir.deinit` remains legal for the caller. For instance, the callee can |
| 848 | 843 | /// take ownership of an embedded slice and replace it with `&.{}` in `mir`. |
| 849 | 844 | mir: *codegen.AnyMir, |
| 850 | ) UpdateNavError!void { | |
| 845 | ) Error!void { | |
| 851 | 846 | assert(base.comp.zcu.?.llvm_object == null); |
| 852 | 847 | switch (base.tag) { |
| 853 | 848 | .lld => unreachable, |
| ... | ... | @@ -860,16 +855,10 @@ pub const File = struct { |
| 860 | 855 | } |
| 861 | 856 | } |
| 862 | 857 | |
| 863 | pub const UpdateLineNumberError = error{ | |
| 864 | OutOfMemory, | |
| 865 | Overflow, | |
| 866 | LinkFailure, | |
| 867 | }; | |
| 868 | ||
| 869 | 858 | /// On an incremental update, fixup the line number of all `Nav`s at the given `TrackedInst`, because |
| 870 | 859 | /// its line number has changed. The ZIR instruction `ti_id` has tag `.declaration`. |
| 871 | 860 | /// 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 { | |
| 873 | 862 | assert(base.comp.zcu.?.llvm_object == null); |
| 874 | 863 | { |
| 875 | 864 | const ti = ti_id.resolveFull(&pt.zcu.intern_pool).?; |
| ... | ... | @@ -918,7 +907,7 @@ pub const File = struct { |
| 918 | 907 | } |
| 919 | 908 | } |
| 920 | 909 | |
| 921 | pub fn idle(base: *File, tid: Zcu.PerThread.Id) !bool { | |
| 910 | pub fn idle(base: *File, tid: Zcu.PerThread.Id) Error!bool { | |
| 922 | 911 | switch (base.tag) { |
| 923 | 912 | else => return false, |
| 924 | 913 | inline .elf2, .coff2 => |tag| { |
| ... | ... | @@ -928,7 +917,7 @@ pub const File = struct { |
| 928 | 917 | } |
| 929 | 918 | } |
| 930 | 919 | |
| 931 | pub fn updateErrorData(base: *File, pt: Zcu.PerThread) !void { | |
| 920 | pub fn updateErrorData(base: *File, pt: Zcu.PerThread) Error!void { | |
| 932 | 921 | switch (base.tag) { |
| 933 | 922 | else => {}, |
| 934 | 923 | inline .elf2, .coff2 => |tag| { |
| ... | ... | @@ -938,14 +927,9 @@ pub const File = struct { |
| 938 | 927 | } |
| 939 | 928 | } |
| 940 | 929 | |
| 941 | pub const FlushError = Io.Cancelable || Allocator.Error || error{ | |
| 942 | /// Indicates an error will be present in `Compilation.link_diags`. | |
| 943 | LinkFailure, | |
| 944 | }; | |
| 945 | ||
| 946 | 930 | /// Commit pending changes and write headers. Takes into account final output mode. |
| 947 | 931 | /// `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 { | |
| 949 | 933 | const comp = base.comp; |
| 950 | 934 | const io = comp.io; |
| 951 | 935 | if (comp.clang_preprocessor_mode == .yes or comp.clang_preprocessor_mode == .pch) { |
| ... | ... | @@ -985,11 +969,6 @@ pub const File = struct { |
| 985 | 969 | } |
| 986 | 970 | } |
| 987 | 971 | |
| 988 | pub const UpdateExportsError = error{ | |
| 989 | OutOfMemory, | |
| 990 | AnalysisFail, | |
| 991 | }; | |
| 992 | ||
| 993 | 972 | /// This is called for every exported thing. `exports` is almost always |
| 994 | 973 | /// a list of size 1, meaning that `exported` is exported once. However, it is possible |
| 995 | 974 | /// to export the same thing with multiple different symbol names (aliases). |
| ... | ... | @@ -1000,7 +979,7 @@ pub const File = struct { |
| 1000 | 979 | pt: Zcu.PerThread, |
| 1001 | 980 | exported: Zcu.Exported, |
| 1002 | 981 | export_indices: []const Zcu.Export.Index, |
| 1003 | ) UpdateExportsError!void { | |
| 982 | ) Error!void { | |
| 1004 | 983 | assert(base.comp.zcu.?.llvm_object == null); |
| 1005 | 984 | switch (base.tag) { |
| 1006 | 985 | .lld => unreachable, |
| ... | ... | @@ -1031,7 +1010,7 @@ pub const File = struct { |
| 1031 | 1010 | /// May be called before or after updateFunc/updateNav therefore it is up to the linker to allocate |
| 1032 | 1011 | /// the block/atom. |
| 1033 | 1012 | /// 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 { | |
| 1035 | 1014 | assert(base.comp.zcu.?.llvm_object == null); |
| 1036 | 1015 | switch (base.tag) { |
| 1037 | 1016 | .lld => unreachable, |
| ... | ... | @@ -1052,8 +1031,7 @@ pub const File = struct { |
| 1052 | 1031 | pt: Zcu.PerThread, |
| 1053 | 1032 | decl_val: InternPool.Index, |
| 1054 | 1033 | decl_align: InternPool.Alignment, |
| 1055 | src_loc: Zcu.LazySrcLoc, | |
| 1056 | ) !codegen.SymbolResult { | |
| 1034 | ) Error!SymbolId { | |
| 1057 | 1035 | assert(base.comp.zcu.?.llvm_object == null); |
| 1058 | 1036 | switch (base.tag) { |
| 1059 | 1037 | .lld => unreachable, |
| ... | ... | @@ -1063,13 +1041,13 @@ pub const File = struct { |
| 1063 | 1041 | .plan9 => unreachable, |
| 1064 | 1042 | inline else => |tag| { |
| 1065 | 1043 | 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); | |
| 1067 | 1045 | }, |
| 1068 | 1046 | } |
| 1069 | 1047 | } |
| 1070 | 1048 | |
| 1071 | 1049 | /// 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 { | |
| 1073 | 1051 | assert(base.comp.zcu.?.llvm_object == null); |
| 1074 | 1052 | switch (base.tag) { |
| 1075 | 1053 | .lld => unreachable, |
| ... | ... | @@ -1217,7 +1195,7 @@ pub const File = struct { |
| 1217 | 1195 | |
| 1218 | 1196 | /// Called when all linker inputs have been sent via `loadInput`. After |
| 1219 | 1197 | /// this, `loadInput` will not be called anymore. |
| 1220 | pub fn prelink(base: *File) FlushError!void { | |
| 1198 | pub fn prelink(base: *File) Error!void { | |
| 1221 | 1199 | assert(!base.post_prelink); |
| 1222 | 1200 | |
| 1223 | 1201 | // In this case, an object file is created by the LLVM backend, so |
| ... | ... | @@ -1251,7 +1229,11 @@ pub const File = struct { |
| 1251 | 1229 | file_writer.pos = new_offset; |
| 1252 | 1230 | const size_u = std.math.cast(usize, size) orelse return error.Overflow; |
| 1253 | 1231 | 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 | }, | |
| 1255 | 1237 | error.WriteFailed => return file_writer.err.?, |
| 1256 | 1238 | }; |
| 1257 | 1239 | assert(n == size_u); |
| ... | ... | @@ -1367,7 +1349,7 @@ pub const File = struct { |
| 1367 | 1349 | nav_index: InternPool.Nav.Index, |
| 1368 | 1350 | comptime format: []const u8, |
| 1369 | 1351 | args: anytype, |
| 1370 | ) error{ CodegenFail, OutOfMemory } { | |
| 1352 | ) Zcu.CodegenFailError { | |
| 1371 | 1353 | @branchHint(.cold); |
| 1372 | 1354 | return base.comp.zcu.?.codegenFail(nav_index, format, args); |
| 1373 | 1355 | } |
| ... | ... | @@ -1440,7 +1422,7 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void { |
| 1440 | 1422 | defer prog_node.end(); |
| 1441 | 1423 | for (comp.link_inputs) |input| { |
| 1442 | 1424 | base.loadInput(input) catch |err| switch (err) { |
| 1443 | error.LinkFailure => return, // error reported via diags | |
| 1425 | error.AlreadyReported => return, // error reported via diags | |
| 1444 | 1426 | else => |e| switch (input) { |
| 1445 | 1427 | .dso => |dso| diags.addParseError(dso.path, "failed to parse shared library: {s}", .{@errorName(e)}), |
| 1446 | 1428 | .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 { |
| 1485 | 1467 | .preferred_mode = .dynamic, |
| 1486 | 1468 | .search_strategy = .paths_first, |
| 1487 | 1469 | }) catch |archive_err| switch (archive_err) { |
| 1488 | error.LinkFailure => return, // error reported via diags | |
| 1470 | error.AlreadyReported => return, // error reported via diags | |
| 1489 | 1471 | else => |e| diags.addParseError(dso_path, "failed to parse archive {f}: {s}", .{ archive_path, @errorName(e) }), |
| 1490 | 1472 | }; |
| 1491 | 1473 | }, |
| 1492 | error.LinkFailure => return, // error reported via diags | |
| 1474 | error.AlreadyReported => return, // error reported via diags | |
| 1493 | 1475 | else => |e| diags.addParseError(dso_path, "failed to parse shared library: {s}", .{@errorName(e)}), |
| 1494 | 1476 | }; |
| 1495 | 1477 | }, |
| ... | ... | @@ -1504,7 +1486,7 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void { |
| 1504 | 1486 | .preferred_mode = .static, |
| 1505 | 1487 | .search_strategy = .no_fallback, |
| 1506 | 1488 | }) catch |err| switch (err) { |
| 1507 | error.LinkFailure => return, // error reported via diags | |
| 1489 | error.AlreadyReported => return, // error reported via diags | |
| 1508 | 1490 | else => |e| diags.addParseError(path, "failed to parse archive: {s}", .{@errorName(e)}), |
| 1509 | 1491 | }; |
| 1510 | 1492 | }, |
| ... | ... | @@ -1515,7 +1497,7 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void { |
| 1515 | 1497 | const prog_node = comp.link_prog_node.start("Parse Object", 0); |
| 1516 | 1498 | defer prog_node.end(); |
| 1517 | 1499 | base.openLoadObject(path) catch |err| switch (err) { |
| 1518 | error.LinkFailure => return, // error reported via diags | |
| 1500 | error.AlreadyReported => return, // error reported via diags | |
| 1519 | 1501 | else => |e| diags.addParseError(path, "failed to parse object: {s}", .{@errorName(e)}), |
| 1520 | 1502 | }; |
| 1521 | 1503 | }, |
| ... | ... | @@ -1523,7 +1505,7 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void { |
| 1523 | 1505 | const prog_node = comp.link_prog_node.start("Parse Archive", 0); |
| 1524 | 1506 | defer prog_node.end(); |
| 1525 | 1507 | 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 | |
| 1527 | 1509 | else => |e| diags.addParseError(load_archive.path, "failed to parse archive: {s}", .{@errorName(e)}), |
| 1528 | 1510 | }; |
| 1529 | 1511 | }, |
| ... | ... | @@ -1534,7 +1516,7 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void { |
| 1534 | 1516 | .preferred_mode = .dynamic, |
| 1535 | 1517 | .search_strategy = .paths_first, |
| 1536 | 1518 | }) catch |err| switch (err) { |
| 1537 | error.LinkFailure => return, // error reported via link_diags | |
| 1519 | error.AlreadyReported => return, // error reported via link_diags | |
| 1538 | 1520 | else => |e| diags.addParseError(path, "failed to parse shared library: {s}", .{@errorName(e)}), |
| 1539 | 1521 | }; |
| 1540 | 1522 | }, |
| ... | ... | @@ -1561,15 +1543,9 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void |
| 1561 | 1543 | }; |
| 1562 | 1544 | } else if (comp.bin_file) |lf| { |
| 1563 | 1545 | lf.updateNav(pt, nav_index) catch |err| switch (err) { |
| 1546 | error.Canceled => io.recancel(), | |
| 1547 | error.AlreadyReported => return, | |
| 1564 | 1548 | 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 | }, | |
| 1573 | 1549 | }; |
| 1574 | 1550 | } |
| 1575 | 1551 | break :nav nav_index; |
| ... | ... | @@ -1594,14 +1570,9 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void |
| 1594 | 1570 | assert(zcu.llvm_object == null); // LLVM codegen doesn't produce MIR |
| 1595 | 1571 | if (comp.bin_file) |lf| { |
| 1596 | 1572 | lf.updateFunc(pt, func, &mir) catch |err| switch (err) { |
| 1573 | error.Canceled => io.recancel(), | |
| 1574 | error.AlreadyReported => return, | |
| 1597 | 1575 | 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 | }, | |
| 1605 | 1576 | }; |
| 1606 | 1577 | } |
| 1607 | 1578 | break :nav ip.indexToKey(func).func.owner_nav; |
| ... | ... | @@ -1618,7 +1589,8 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void |
| 1618 | 1589 | if (comp.bin_file) |lf| { |
| 1619 | 1590 | lf.updateContainerType(pt, container_update.ty, container_update.success) catch |err| switch (err) { |
| 1620 | 1591 | error.OutOfMemory => diags.setAllocFailure(), |
| 1621 | error.TypeFailureReported => assert(zcu.failed_types.contains(container_update.ty)), | |
| 1592 | error.Canceled => io.recancel(), | |
| 1593 | error.AlreadyReported => {}, | |
| 1622 | 1594 | }; |
| 1623 | 1595 | } |
| 1624 | 1596 | } |
| ... | ... | @@ -1657,7 +1629,7 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void |
| 1657 | 1629 | } |
| 1658 | 1630 | } |
| 1659 | 1631 | } |
| 1660 | pub fn doIdleTask(comp: *Compilation, tid: Zcu.PerThread.Id) error{ OutOfMemory, LinkFailure }!bool { | |
| 1632 | pub fn doIdleTask(comp: *Compilation, tid: Zcu.PerThread.Id) Error!bool { | |
| 1661 | 1633 | return if (comp.bin_file) |lf| lf.idle(tid) else false; |
| 1662 | 1634 | } |
| 1663 | 1635 | /// 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) |
| 1673 | 1645 | }; |
| 1674 | 1646 | } else if (comp.bin_file) |lf| { |
| 1675 | 1647 | lf.updateNav(pt, nav_index) catch |err| switch (err) { |
| 1648 | error.Canceled => comp.io.recancel(), | |
| 1649 | error.AlreadyReported => return, | |
| 1676 | 1650 | 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 | }, | |
| 1685 | 1651 | }; |
| 1686 | 1652 | } |
| 1687 | 1653 | } |
| ... | ... | @@ -1689,7 +1655,8 @@ pub fn updateErrorData(pt: Zcu.PerThread) void { |
| 1689 | 1655 | const comp = pt.zcu.comp; |
| 1690 | 1656 | if (comp.bin_file) |lf| lf.updateErrorData(pt) catch |err| switch (err) { |
| 1691 | 1657 | error.OutOfMemory => comp.link_diags.setAllocFailure(), |
| 1692 | error.LinkFailure => {}, | |
| 1658 | error.Canceled => comp.io.recancel(), | |
| 1659 | error.AlreadyReported => {}, | |
| 1693 | 1660 | }; |
| 1694 | 1661 | } |
| 1695 | 1662 | |
| ... | ... | @@ -2428,19 +2395,19 @@ pub fn openDso(io: Io, path: Path, needed: bool, weak: bool, reexport: bool) !In |
| 2428 | 2395 | }; |
| 2429 | 2396 | } |
| 2430 | 2397 | |
| 2431 | pub fn openObjectInput(io: Io, diags: *Diags, path: Path) error{LinkFailure}!Input { | |
| 2398 | pub fn openObjectInput(io: Io, diags: *Diags, path: Path) error{AlreadyReported}!Input { | |
| 2432 | 2399 | return .{ .object = openObject(io, path, false, false) catch |err| { |
| 2433 | 2400 | return diags.failParse(path, "failed to open {f}: {s}", .{ path, @errorName(err) }); |
| 2434 | 2401 | } }; |
| 2435 | 2402 | } |
| 2436 | 2403 | |
| 2437 | pub fn openArchiveInput(io: Io, diags: *Diags, path: Path, must_link: bool, hidden: bool) error{LinkFailure}!Input { | |
| 2404 | pub fn openArchiveInput(io: Io, diags: *Diags, path: Path, must_link: bool, hidden: bool) error{AlreadyReported}!Input { | |
| 2438 | 2405 | return .{ .archive = openObject(io, path, must_link, hidden) catch |err| { |
| 2439 | 2406 | return diags.failParse(path, "failed to open {f}: {s}", .{ path, @errorName(err) }); |
| 2440 | 2407 | } }; |
| 2441 | 2408 | } |
| 2442 | 2409 | |
| 2443 | pub fn openDsoInput(io: Io, diags: *Diags, path: Path, needed: bool, weak: bool, reexport: bool) error{LinkFailure}!Input { | |
| 2410 | pub fn openDsoInput(io: Io, diags: *Diags, path: Path, needed: bool, weak: bool, reexport: bool) error{AlreadyReported}!Input { | |
| 2444 | 2411 | return .{ .dso = openDso(io, path, needed, weak, reexport) catch |err| { |
| 2445 | 2412 | return diags.failParse(path, "failed to open {f}: {s}", .{ path, @errorName(err) }); |
| 2446 | 2413 | } }; |
src/link/C.zig+8-22| ... | ... | @@ -474,7 +474,7 @@ pub fn updateContainerType( |
| 474 | 474 | pt: Zcu.PerThread, |
| 475 | 475 | ty: InternPool.Index, |
| 476 | 476 | success: bool, |
| 477 | ) link.File.UpdateContainerTypeError!void { | |
| 477 | ) link.Error!void { | |
| 478 | 478 | try c.type_pool.updateContainerType(pt, .{ .c = c }, ty, success); |
| 479 | 479 | } |
| 480 | 480 | |
| ... | ... | @@ -570,7 +570,6 @@ pub fn updateNav( |
| 570 | 570 | .arena = arena.allocator(), |
| 571 | 571 | .pt = pt, |
| 572 | 572 | .mod = zcu.navFileScope(nav_index).mod.?, |
| 573 | .error_msg = null, | |
| 574 | 573 | .owner_nav = nav_index.toOptional(), |
| 575 | 574 | .is_naked_fn = false, |
| 576 | 575 | .expected_block = null, |
| ... | ... | @@ -588,10 +587,7 @@ pub fn updateNav( |
| 588 | 587 | defer c.string_bytes = aw.toArrayList(); |
| 589 | 588 | const start = aw.written().len; |
| 590 | 589 | 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, | |
| 595 | 591 | error.WriteFailed, error.OutOfMemory => return error.OutOfMemory, |
| 596 | 592 | }; |
| 597 | 593 | break :fwd_decl .{ |
| ... | ... | @@ -605,10 +601,7 @@ pub fn updateNav( |
| 605 | 601 | defer c.string_bytes = aw.toArrayList(); |
| 606 | 602 | const start = aw.written().len; |
| 607 | 603 | 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, | |
| 612 | 605 | error.WriteFailed, error.OutOfMemory => return error.OutOfMemory, |
| 613 | 606 | }; |
| 614 | 607 | break :code .{ |
| ... | ... | @@ -661,7 +654,6 @@ fn updateUav( |
| 661 | 654 | .arena = arena.allocator(), |
| 662 | 655 | .pt = pt, |
| 663 | 656 | .mod = pt.zcu.root_mod, |
| 664 | .error_msg = null, | |
| 665 | 657 | .owner_nav = .none, |
| 666 | 658 | .is_naked_fn = false, |
| 667 | 659 | .expected_block = null, |
| ... | ... | @@ -683,9 +675,7 @@ fn updateUav( |
| 683 | 675 | .@"threadlocal" = false, |
| 684 | 676 | .init_val = val, |
| 685 | 677 | }) catch |err| switch (err) { |
| 686 | error.AnalysisFail => { | |
| 687 | @panic("TODO: CBE error.AnalysisFail on uav"); | |
| 688 | }, | |
| 678 | error.AlreadyReported => return, | |
| 689 | 679 | error.WriteFailed, error.OutOfMemory => return error.OutOfMemory, |
| 690 | 680 | }; |
| 691 | 681 | break :fwd_decl .{ |
| ... | ... | @@ -704,9 +694,7 @@ fn updateUav( |
| 704 | 694 | .@"threadlocal" = false, |
| 705 | 695 | .init_val = val, |
| 706 | 696 | }) catch |err| switch (err) { |
| 707 | error.AnalysisFail => { | |
| 708 | @panic("TODO: CBE error.AnalysisFail on uav"); | |
| 709 | }, | |
| 697 | error.AlreadyReported => return, | |
| 710 | 698 | error.WriteFailed, error.OutOfMemory => return error.OutOfMemory, |
| 711 | 699 | }; |
| 712 | 700 | break :code .{ |
| ... | ... | @@ -726,7 +714,7 @@ pub fn updateLineNumber(c: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst. |
| 726 | 714 | _ = ti_id; |
| 727 | 715 | } |
| 728 | 716 | |
| 729 | pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { | |
| 717 | pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.Error!void { | |
| 730 | 718 | const tracy = trace(@src()); |
| 731 | 719 | defer tracy.end(); |
| 732 | 720 | |
| ... | ... | @@ -1112,7 +1100,6 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog |
| 1112 | 1100 | .owner_nav = .none, |
| 1113 | 1101 | .is_naked_fn = false, |
| 1114 | 1102 | .expected_block = null, |
| 1115 | .error_msg = null, | |
| 1116 | 1103 | .ctype_deps = .empty, |
| 1117 | 1104 | .uavs = .empty, |
| 1118 | 1105 | }; |
| ... | ... | @@ -1156,14 +1143,14 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog |
| 1156 | 1143 | codegen.genLazyCallModifierFn(&lazy_dg, fn_nav, .never_tail, &lazy_decls_aw.writer) catch |err| switch (err) { |
| 1157 | 1144 | error.WriteFailed => return error.OutOfMemory, |
| 1158 | 1145 | error.OutOfMemory => |e| return e, |
| 1159 | error.AnalysisFail => unreachable, | |
| 1146 | error.AlreadyReported => unreachable, | |
| 1160 | 1147 | }; |
| 1161 | 1148 | } |
| 1162 | 1149 | for (need_never_inline_funcs.keys()) |fn_nav| { |
| 1163 | 1150 | codegen.genLazyCallModifierFn(&lazy_dg, fn_nav, .never_inline, &lazy_decls_aw.writer) catch |err| switch (err) { |
| 1164 | 1151 | error.WriteFailed => return error.OutOfMemory, |
| 1165 | 1152 | error.OutOfMemory => |e| return e, |
| 1166 | error.AnalysisFail => unreachable, | |
| 1153 | error.AlreadyReported => unreachable, | |
| 1167 | 1154 | }; |
| 1168 | 1155 | } |
| 1169 | 1156 | } |
| ... | ... | @@ -1256,7 +1243,6 @@ pub fn updateExports( |
| 1256 | 1243 | .owner_nav = .none, |
| 1257 | 1244 | .is_naked_fn = false, |
| 1258 | 1245 | .expected_block = null, |
| 1259 | .error_msg = null, | |
| 1260 | 1246 | .ctype_deps = .empty, |
| 1261 | 1247 | .uavs = .empty, |
| 1262 | 1248 | }; |
src/link/Coff.zig+31-60| ... | ... | @@ -43,7 +43,6 @@ lazy: std.EnumArray(link.File.LazySymbol.Kind, struct { |
| 43 | 43 | }), |
| 44 | 44 | pending_uavs: std.AutoArrayHashMapUnmanaged(Node.UavMapIndex, struct { |
| 45 | 45 | alignment: InternPool.Alignment, |
| 46 | src_loc: Zcu.LazySrcLoc, | |
| 47 | 46 | }), |
| 48 | 47 | relocs: std.ArrayList(Reloc), |
| 49 | 48 | const_prog_node: std.Progress.Node, |
| ... | ... | @@ -1532,11 +1531,8 @@ pub fn prelink(coff: *Coff, prog_node: std.Progress.Node) void { |
| 1532 | 1531 | |
| 1533 | 1532 | pub fn updateNav(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void { |
| 1534 | 1533 | 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.?}), | |
| 1540 | 1536 | }; |
| 1541 | 1537 | } |
| 1542 | 1538 | fn 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 |
| 1579 | 1575 | codegen.generateSymbol( |
| 1580 | 1576 | &coff.base, |
| 1581 | 1577 | pt, |
| 1582 | zcu.navSrcLoc(nav_index), | |
| 1583 | 1578 | .fromInterned(nav.resolved.?.value), |
| 1584 | 1579 | &nw.interface, |
| 1585 | 1580 | .{ .atom_index = @enumFromInt(@intFromEnum(si)) }, |
| 1586 | 1581 | ) catch |err| switch (err) { |
| 1587 | error.WriteFailed => return error.OutOfMemory, | |
| 1582 | error.WriteFailed => return nw.err.?, | |
| 1588 | 1583 | else => |e| return e, |
| 1589 | 1584 | }; |
| 1590 | 1585 | si.get(coff).size = @intCast(nw.interface.end); |
| ... | ... | @@ -1615,8 +1610,7 @@ pub fn lowerUav( |
| 1615 | 1610 | pt: Zcu.PerThread, |
| 1616 | 1611 | uav_val: InternPool.Index, |
| 1617 | 1612 | uav_align: InternPool.Alignment, |
| 1618 | src_loc: Zcu.LazySrcLoc, | |
| 1619 | ) !codegen.SymbolResult { | |
| 1613 | ) !link.File.SymbolId { | |
| 1620 | 1614 | const zcu = pt.zcu; |
| 1621 | 1615 | const gpa = zcu.gpa; |
| 1622 | 1616 | |
| ... | ... | @@ -1633,12 +1627,11 @@ pub fn lowerUav( |
| 1633 | 1627 | } else { |
| 1634 | 1628 | gop.value_ptr.* = .{ |
| 1635 | 1629 | .alignment = uav_align, |
| 1636 | .src_loc = src_loc, | |
| 1637 | 1630 | }; |
| 1638 | 1631 | coff.const_prog_node.increaseEstimatedTotalItems(1); |
| 1639 | 1632 | } |
| 1640 | 1633 | } |
| 1641 | return .{ .sym_index = @enumFromInt(@intFromEnum(si)) }; | |
| 1634 | return @enumFromInt(@intFromEnum(si)); | |
| 1642 | 1635 | } |
| 1643 | 1636 | |
| 1644 | 1637 | pub fn updateFunc( |
| ... | ... | @@ -1648,15 +1641,11 @@ pub fn updateFunc( |
| 1648 | 1641 | mir: *const codegen.AnyMir, |
| 1649 | 1642 | ) !void { |
| 1650 | 1643 | 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( | |
| 1657 | 1646 | 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.?}, | |
| 1660 | 1649 | ), |
| 1661 | 1650 | }; |
| 1662 | 1651 | } |
| ... | ... | @@ -1714,7 +1703,6 @@ fn updateFuncInner( |
| 1714 | 1703 | codegen.emitFunction( |
| 1715 | 1704 | &coff.base, |
| 1716 | 1705 | pt, |
| 1717 | zcu.navSrcLoc(func.owner_nav), | |
| 1718 | 1706 | func_index, |
| 1719 | 1707 | @enumFromInt(@intFromEnum(si)), |
| 1720 | 1708 | mir, |
| ... | ... | @@ -1733,9 +1721,11 @@ pub fn updateErrorData(coff: *Coff, pt: Zcu.PerThread) !void { |
| 1733 | 1721 | .kind = .const_data, |
| 1734 | 1722 | .index = @intCast(coff.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return), |
| 1735 | 1723 | }) 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 | ), | |
| 1739 | 1729 | }; |
| 1740 | 1730 | } |
| 1741 | 1731 | |
| ... | ... | @@ -1780,12 +1770,11 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 1780 | 1770 | .{ .zcu = comp.zcu.?, .tid = tid }, |
| 1781 | 1771 | pending_uav.key, |
| 1782 | 1772 | pending_uav.value.alignment, |
| 1783 | pending_uav.value.src_loc, | |
| 1784 | 1773 | ) 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( | |
| 1787 | 1776 | "linker failed to lower constant: {t}", |
| 1788 | .{e}, | |
| 1777 | .{coff.mf.io_err.?}, | |
| 1789 | 1778 | ), |
| 1790 | 1779 | }; |
| 1791 | 1780 | break :task; |
| ... | ... | @@ -1800,10 +1789,10 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 1800 | 1789 | ); |
| 1801 | 1790 | defer sub_prog_node.end(); |
| 1802 | 1791 | 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( | |
| 1805 | 1794 | "linker failed to lower constant: {t}", |
| 1806 | .{e}, | |
| 1795 | .{coff.mf.io_err.?}, | |
| 1807 | 1796 | ), |
| 1808 | 1797 | }; |
| 1809 | 1798 | break :task; |
| ... | ... | @@ -1827,10 +1816,10 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 1827 | 1816 | ); |
| 1828 | 1817 | defer sub_prog_node.end(); |
| 1829 | 1818 | 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( | |
| 1832 | 1821 | "linker failed to lower lazy {s}: {t}", |
| 1833 | .{ kind, e }, | |
| 1822 | .{ kind, coff.mf.io_err.? }, | |
| 1834 | 1823 | ), |
| 1835 | 1824 | }; |
| 1836 | 1825 | break :task; |
| ... | ... | @@ -1885,7 +1874,6 @@ fn flushUav( |
| 1885 | 1874 | pt: Zcu.PerThread, |
| 1886 | 1875 | umi: Node.UavMapIndex, |
| 1887 | 1876 | uav_align: InternPool.Alignment, |
| 1888 | src_loc: Zcu.LazySrcLoc, | |
| 1889 | 1877 | ) !void { |
| 1890 | 1878 | const zcu = pt.zcu; |
| 1891 | 1879 | const gpa = zcu.gpa; |
| ... | ... | @@ -1928,12 +1916,11 @@ fn flushUav( |
| 1928 | 1916 | codegen.generateSymbol( |
| 1929 | 1917 | &coff.base, |
| 1930 | 1918 | pt, |
| 1931 | src_loc, | |
| 1932 | 1919 | .fromInterned(uav_val), |
| 1933 | 1920 | &nw.interface, |
| 1934 | 1921 | .{ .atom_index = @enumFromInt(@intFromEnum(si)) }, |
| 1935 | 1922 | ) catch |err| switch (err) { |
| 1936 | error.WriteFailed => return error.OutOfMemory, | |
| 1923 | error.WriteFailed => return nw.err.?, | |
| 1937 | 1924 | else => |e| return e, |
| 1938 | 1925 | }; |
| 1939 | 1926 | si.get(coff).size = @intCast(nw.interface.end); |
| ... | ... | @@ -2139,16 +2126,18 @@ fn flushLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void { |
| 2139 | 2126 | var nw: MappedFile.Node.Writer = undefined; |
| 2140 | 2127 | ni.writer(&coff.mf, gpa, &nw); |
| 2141 | 2128 | defer nw.deinit(); |
| 2142 | try codegen.generateLazySymbol( | |
| 2129 | codegen.generateLazySymbol( | |
| 2143 | 2130 | &coff.base, |
| 2144 | 2131 | pt, |
| 2145 | Type.fromInterned(lazy.ty).srcLocOrNull(pt.zcu) orelse .unneeded, | |
| 2146 | 2132 | lazy, |
| 2147 | 2133 | &required_alignment, |
| 2148 | 2134 | &nw.interface, |
| 2149 | 2135 | .none, |
| 2150 | 2136 | .{ .atom_index = @enumFromInt(@intFromEnum(si)) }, |
| 2151 | ); | |
| 2137 | ) catch |err| switch (err) { | |
| 2138 | error.WriteFailed => return nw.err.?, | |
| 2139 | else => |e| return e, | |
| 2140 | }; | |
| 2152 | 2141 | si.get(coff).size = @intCast(nw.interface.end); |
| 2153 | 2142 | si.applyLocationRelocs(coff); |
| 2154 | 2143 | } |
| ... | ... | @@ -2314,17 +2303,6 @@ pub fn updateExports( |
| 2314 | 2303 | pt: Zcu.PerThread, |
| 2315 | 2304 | exported: Zcu.Exported, |
| 2316 | 2305 | 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 | } | |
| 2323 | fn updateExportsInner( | |
| 2324 | coff: *Coff, | |
| 2325 | pt: Zcu.PerThread, | |
| 2326 | exported: Zcu.Exported, | |
| 2327 | export_indices: []const Zcu.Export.Index, | |
| 2328 | 2306 | ) !void { |
| 2329 | 2307 | const zcu = pt.zcu; |
| 2330 | 2308 | const gpa = zcu.gpa; |
| ... | ... | @@ -2340,18 +2318,11 @@ fn updateExportsInner( |
| 2340 | 2318 | try coff.symbol_table.ensureUnusedCapacity(gpa, export_indices.len); |
| 2341 | 2319 | const exported_si: Symbol.Index = switch (exported) { |
| 2342 | 2320 | .nav => |nav| try coff.navSymbol(zcu, nav), |
| 2343 | .uav => |uav| @enumFromInt(@intFromEnum(switch (try coff.lowerUav( | |
| 2321 | .uav => |uav| @enumFromInt(@intFromEnum(try coff.lowerUav( | |
| 2344 | 2322 | pt, |
| 2345 | 2323 | uav, |
| 2346 | 2324 | 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 | ))), | |
| 2355 | 2326 | }; |
| 2356 | 2327 | while (try coff.idle(pt.tid)) {} |
| 2357 | 2328 | const exported_ni = exported_si.node(coff); |
src/link/Dwarf.zig+24-48| ... | ... | @@ -51,21 +51,15 @@ pub const UpdateError = error{ |
| 51 | 51 | Underflow, |
| 52 | 52 | UnexpectedEndOfFile, |
| 53 | 53 | 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, | |
| 58 | 55 | } || |
| 59 | codegen.GenerateSymbolError || | |
| 56 | link.Error || | |
| 60 | 57 | Io.File.OpenError || |
| 61 | 58 | Io.File.LengthError || |
| 62 | 59 | Io.File.ReadPositionalError || |
| 63 | 60 | Io.File.WritePositionalError; |
| 64 | 61 | |
| 65 | pub const FlushError = UpdateError; | |
| 66 | ||
| 67 | pub const RelocError = | |
| 68 | Io.File.PWriteError; | |
| 62 | pub const RelocError = Io.File.PWriteError; | |
| 69 | 63 | |
| 70 | 64 | pub const AddressSize = enum(u8) { |
| 71 | 65 | @"32" = 4, |
| ... | ... | @@ -1579,19 +1573,17 @@ pub const WipNav = struct { |
| 1579 | 1573 | pub const LocalConstTag = enum { comptime_arg, local_const }; |
| 1580 | 1574 | pub fn genLocalConstDebugInfo( |
| 1581 | 1575 | wip_nav: *WipNav, |
| 1582 | src_loc: Zcu.LazySrcLoc, | |
| 1583 | 1576 | tag: LocalConstTag, |
| 1584 | 1577 | opt_name: ?[]const u8, |
| 1585 | 1578 | val: Value, |
| 1586 | 1579 | ) 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) { | |
| 1588 | 1581 | error.WriteFailed => error.OutOfMemory, |
| 1589 | 1582 | else => |e| e, |
| 1590 | 1583 | }; |
| 1591 | 1584 | } |
| 1592 | 1585 | fn genLocalConstDebugInfoWriterError( |
| 1593 | 1586 | wip_nav: *WipNav, |
| 1594 | src_loc: Zcu.LazySrcLoc, | |
| 1595 | 1587 | tag: LocalConstTag, |
| 1596 | 1588 | opt_name: ?[]const u8, |
| 1597 | 1589 | val: Value, |
| ... | ... | @@ -1617,7 +1609,7 @@ pub const WipNav = struct { |
| 1617 | 1609 | }); |
| 1618 | 1610 | if (opt_name) |name| try wip_nav.strp(name); |
| 1619 | 1611 | 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); | |
| 1621 | 1613 | if (has_comptime_state) try wip_nav.refValue(val); |
| 1622 | 1614 | wip_nav.any_children = true; |
| 1623 | 1615 | } |
| ... | ... | @@ -2106,7 +2098,6 @@ pub const WipNav = struct { |
| 2106 | 2098 | |
| 2107 | 2099 | fn blockValue( |
| 2108 | 2100 | wip_nav: *WipNav, |
| 2109 | src_loc: Zcu.LazySrcLoc, | |
| 2110 | 2101 | val: Value, |
| 2111 | 2102 | ) (UpdateError || Writer.Error)!void { |
| 2112 | 2103 | const ty = val.typeOf(wip_nav.pt.zcu); |
| ... | ... | @@ -2118,7 +2109,6 @@ pub const WipNav = struct { |
| 2118 | 2109 | try codegen.generateSymbol( |
| 2119 | 2110 | wip_nav.dwarf.bin_file, |
| 2120 | 2111 | wip_nav.pt, |
| 2121 | src_loc, | |
| 2122 | 2112 | val, |
| 2123 | 2113 | &wip_nav.debug_info.writer, |
| 2124 | 2114 | .{ .debug_output = .{ .dwarf = wip_nav } }, |
| ... | ... | @@ -2592,7 +2582,7 @@ pub fn initWipNav( |
| 2592 | 2582 | pt: Zcu.PerThread, |
| 2593 | 2583 | nav_index: InternPool.Nav.Index, |
| 2594 | 2584 | sym_index: link.File.SymbolId, |
| 2595 | ) error{ OutOfMemory, CodegenFail }!WipNav { | |
| 2585 | ) error{ OutOfMemory, AlreadyReported }!WipNav { | |
| 2596 | 2586 | return initWipNavInner(dwarf, pt, nav_index, sym_index) catch |err| switch (err) { |
| 2597 | 2587 | error.OutOfMemory => error.OutOfMemory, |
| 2598 | 2588 | else => |e| pt.zcu.codegenFail(nav_index, "failed to init dwarf: {s}", .{@errorName(e)}), |
| ... | ... | @@ -3017,7 +3007,7 @@ fn finishWipNavWriterError( |
| 3017 | 3007 | try dwarf.const_pool.flushPending(pt, .{ .dwarf = dwarf }); |
| 3018 | 3008 | } |
| 3019 | 3009 | |
| 3020 | pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error{ OutOfMemory, CodegenFail }!void { | |
| 3010 | pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) error{ OutOfMemory, AlreadyReported }!void { | |
| 3021 | 3011 | return updateComptimeNavInner(dwarf, pt, nav_index) catch |err| switch (err) { |
| 3022 | 3012 | error.OutOfMemory => error.OutOfMemory, |
| 3023 | 3013 | 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 |
| 3027 | 3017 | fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void { |
| 3028 | 3018 | const zcu = pt.zcu; |
| 3029 | 3019 | const ip = &zcu.intern_pool; |
| 3030 | const nav_src_loc = zcu.navSrcLoc(nav_index); | |
| 3031 | 3020 | |
| 3032 | 3021 | const nav = ip.getNav(nav_index); |
| 3033 | 3022 | const inst_info = nav.srcInst(ip).resolveFull(ip).?; |
| ... | ... | @@ -3207,7 +3196,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 3207 | 3196 | }.toSlice(ip)); |
| 3208 | 3197 | const nav_ty = nav_val.typeOf(zcu); |
| 3209 | 3198 | try wip_nav.refType(nav_ty); |
| 3210 | try wip_nav.blockValue(nav_src_loc, nav_val); | |
| 3199 | try wip_nav.blockValue(nav_val); | |
| 3211 | 3200 | try diw.writeUleb128(nav.resolved.?.@"align".toByteUnits() orelse |
| 3212 | 3201 | nav_ty.abiAlignment(zcu).toByteUnits().?); |
| 3213 | 3202 | try diw.writeByte(@intFromBool(decl.linkage != .normal)); |
| ... | ... | @@ -3241,7 +3230,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 3241 | 3230 | try diw.writeUleb128(nav.resolved.?.@"align".toByteUnits() orelse |
| 3242 | 3231 | nav_ty.abiAlignment(zcu).toByteUnits().?); |
| 3243 | 3232 | 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); | |
| 3245 | 3234 | if (has_comptime_state) try wip_nav.refValue(nav_val); |
| 3246 | 3235 | wip_nav.finishForward(nav_ty_reloc_index); |
| 3247 | 3236 | try wip_nav.abbrevCode(.is_const); |
| ... | ... | @@ -3551,19 +3540,6 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 3551 | 3540 | }; |
| 3552 | 3541 | defer wip_nav.deinit(); |
| 3553 | 3542 | |
| 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 | ||
| 3567 | 3543 | const diw = &wip_nav.debug_info.writer; |
| 3568 | 3544 | var big_int_space: Value.BigIntSpace = undefined; |
| 3569 | 3545 | switch (value_ip_key) { |
| ... | ... | @@ -3588,7 +3564,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 3588 | 3564 | else => if (ptr_type.sentinel == .none) .ptr_aligned_type else .ptr_aligned_sentinel_type, |
| 3589 | 3565 | }); |
| 3590 | 3566 | 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)); | |
| 3592 | 3568 | if (ptr_type.flags.alignment.toByteUnits()) |a| try diw.writeUleb128(a); |
| 3593 | 3569 | try diw.writeByte(@intFromEnum(ptr_type.flags.address_space)); |
| 3594 | 3570 | 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 |
| 3633 | 3609 | const array_child_type: Type = .fromInterned(array_type.child); |
| 3634 | 3610 | try wip_nav.abbrevCode(if (array_type.sentinel == .none) .array_type else .array_sentinel_type); |
| 3635 | 3611 | 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)); | |
| 3637 | 3613 | try wip_nav.refType(array_child_type); |
| 3638 | 3614 | try wip_nav.abbrevCode(.array_len); |
| 3639 | 3615 | try wip_nav.refType(.usize); |
| ... | ... | @@ -3880,7 +3856,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 3880 | 3856 | if (has_comptime_state) |
| 3881 | 3857 | try wip_nav.refValue(.fromInterned(comptime_value)) |
| 3882 | 3858 | else if (has_runtime_bits) |
| 3883 | try wip_nav.blockValue(src_loc, .fromInterned(comptime_value)); | |
| 3859 | try wip_nav.blockValue(.fromInterned(comptime_value)); | |
| 3884 | 3860 | } |
| 3885 | 3861 | try diw.writeUleb128(@intFromEnum(AbbrevCode.null)); |
| 3886 | 3862 | }, |
| ... | ... | @@ -3967,7 +3943,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 3967 | 3943 | if (has_comptime_state) |
| 3968 | 3944 | try wip_nav.refValue(.fromInterned(field_init)) |
| 3969 | 3945 | else if (has_runtime_bits) |
| 3970 | try wip_nav.blockValue(ty.srcLoc(zcu), .fromInterned(field_init)); | |
| 3946 | try wip_nav.blockValue(.fromInterned(field_init)); | |
| 3971 | 3947 | } |
| 3972 | 3948 | try diw.writeUleb128(@intFromEnum(AbbrevCode.null)); |
| 3973 | 3949 | } |
| ... | ... | @@ -4332,7 +4308,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4332 | 4308 | if (has_comptime_state) |
| 4333 | 4309 | try wip_nav.refValue(.fromInterned(payload_val)) |
| 4334 | 4310 | else |
| 4335 | try wip_nav.blockValue(src_loc, .fromInterned(payload_val)); | |
| 4311 | try wip_nav.blockValue(.fromInterned(payload_val)); | |
| 4336 | 4312 | }, |
| 4337 | 4313 | } |
| 4338 | 4314 | { |
| ... | ... | @@ -4500,7 +4476,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4500 | 4476 | { |
| 4501 | 4477 | try wip_nav.abbrevCode(.comptime_value_field_runtime_bits); |
| 4502 | 4478 | try wip_nav.strp("len"); |
| 4503 | try wip_nav.blockValue(src_loc, .fromInterned(slice.len)); | |
| 4479 | try wip_nav.blockValue(.fromInterned(slice.len)); | |
| 4504 | 4480 | } |
| 4505 | 4481 | try diw.writeUleb128(@intFromEnum(AbbrevCode.null)); |
| 4506 | 4482 | }, |
| ... | ... | @@ -4513,8 +4489,8 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4513 | 4489 | try wip_nav.strp("has_value"); |
| 4514 | 4490 | switch (optRepr(opt_child_type, zcu)) { |
| 4515 | 4491 | .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)), | |
| 4518 | 4494 | } |
| 4519 | 4495 | } |
| 4520 | 4496 | if (opt.val != .none) child_field: { |
| ... | ... | @@ -4530,7 +4506,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4530 | 4506 | if (has_comptime_state) |
| 4531 | 4507 | try wip_nav.refValue(.fromInterned(opt.val)) |
| 4532 | 4508 | else |
| 4533 | try wip_nav.blockValue(src_loc, .fromInterned(opt.val)); | |
| 4509 | try wip_nav.blockValue(.fromInterned(opt.val)); | |
| 4534 | 4510 | } |
| 4535 | 4511 | try diw.writeUleb128(@intFromEnum(AbbrevCode.null)); |
| 4536 | 4512 | }, |
| ... | ... | @@ -4561,7 +4537,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4561 | 4537 | if (has_comptime_state) |
| 4562 | 4538 | try wip_nav.refValue(field_value) |
| 4563 | 4539 | else |
| 4564 | try wip_nav.blockValue(src_loc, field_value); | |
| 4540 | try wip_nav.blockValue(field_value); | |
| 4565 | 4541 | } |
| 4566 | 4542 | }, |
| 4567 | 4543 | .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 |
| 4588 | 4564 | if (has_comptime_state) |
| 4589 | 4565 | try wip_nav.refValue(field_value) |
| 4590 | 4566 | else |
| 4591 | try wip_nav.blockValue(src_loc, field_value); | |
| 4567 | try wip_nav.blockValue(field_value); | |
| 4592 | 4568 | }, |
| 4593 | 4569 | inline .array_type, .vector_type => |sequence_type| { |
| 4594 | 4570 | const child_type: Type = .fromInterned(sequence_type.child); |
| ... | ... | @@ -4608,7 +4584,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4608 | 4584 | if (has_comptime_state) |
| 4609 | 4585 | try wip_nav.refValue(.fromInterned(elem)) |
| 4610 | 4586 | else |
| 4611 | try wip_nav.blockValue(src_loc, .fromInterned(elem)); | |
| 4587 | try wip_nav.blockValue(.fromInterned(elem)); | |
| 4612 | 4588 | } |
| 4613 | 4589 | }, |
| 4614 | 4590 | else => unreachable, |
| ... | ... | @@ -4636,7 +4612,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4636 | 4612 | if (has_comptime_state) |
| 4637 | 4613 | try wip_nav.refValue(.fromInterned(un.val)) |
| 4638 | 4614 | else |
| 4639 | try wip_nav.blockValue(src_loc, .fromInterned(un.val)); | |
| 4615 | try wip_nav.blockValue(.fromInterned(un.val)); | |
| 4640 | 4616 | } |
| 4641 | 4617 | try diw.writeUleb128(@intFromEnum(AbbrevCode.null)); |
| 4642 | 4618 | }, |
| ... | ... | @@ -4708,13 +4684,13 @@ fn refAbbrevCode( |
| 4708 | 4684 | return @intFromEnum(abbrev_code); |
| 4709 | 4685 | } |
| 4710 | 4686 | |
| 4711 | pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) FlushError!void { | |
| 4687 | pub fn flush(dwarf: *Dwarf, pt: Zcu.PerThread) UpdateError!void { | |
| 4712 | 4688 | return dwarf.flushWriterError(pt) catch |err| switch (err) { |
| 4713 | 4689 | error.WriteFailed => error.OutOfMemory, |
| 4714 | 4690 | else => |e| e, |
| 4715 | 4691 | }; |
| 4716 | 4692 | } |
| 4717 | fn flushWriterError(dwarf: *Dwarf, pt: Zcu.PerThread) (FlushError || Writer.Error)!void { | |
| 4693 | fn flushWriterError(dwarf: *Dwarf, pt: Zcu.PerThread) (UpdateError || Writer.Error)!void { | |
| 4718 | 4694 | const zcu = pt.zcu; |
| 4719 | 4695 | const ip = &zcu.intern_pool; |
| 4720 | 4696 | const comp = dwarf.bin_file.comp; |
src/link/Elf.zig+32-33| ... | ... | @@ -476,9 +476,8 @@ pub fn lowerUav( |
| 476 | 476 | pt: Zcu.PerThread, |
| 477 | 477 | uav: InternPool.Index, |
| 478 | 478 | 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); | |
| 482 | 481 | } |
| 483 | 482 | |
| 484 | 483 | pub 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 { |
| 743 | 742 | } |
| 744 | 743 | } |
| 745 | 744 | |
| 746 | pub fn flush(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.File.FlushError!void { | |
| 745 | pub fn flush(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Progress.Node) link.Error!void { | |
| 747 | 746 | const tracy = trace(@src()); |
| 748 | 747 | defer tracy.end(); |
| 749 | 748 | |
| ... | ... | @@ -757,7 +756,7 @@ pub fn flush(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std |
| 757 | 756 | defer sub_prog_node.end(); |
| 758 | 757 | |
| 759 | 758 | 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, | |
| 761 | 760 | else => |e| return diags.fail("ELF flush failed: {t}", .{e}), |
| 762 | 761 | }; |
| 763 | 762 | } |
| ... | ... | @@ -784,7 +783,7 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { |
| 784 | 783 | .Exe => {}, |
| 785 | 784 | } |
| 786 | 785 | |
| 787 | if (diags.hasErrors()) return error.LinkFailure; | |
| 786 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 788 | 787 | |
| 789 | 788 | // If we haven't already, create a linker-generated input file comprising of |
| 790 | 789 | // linker-defined synthetic symbols only such as `_DYNAMIC`, etc. |
| ... | ... | @@ -816,7 +815,7 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { |
| 816 | 815 | } |
| 817 | 816 | |
| 818 | 817 | self.checkDuplicates() catch |err| switch (err) { |
| 819 | error.HasDuplicates => return error.LinkFailure, | |
| 818 | error.HasDuplicates => return error.AlreadyReported, | |
| 820 | 819 | else => |e| return e, |
| 821 | 820 | }; |
| 822 | 821 | |
| ... | ... | @@ -903,7 +902,7 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { |
| 903 | 902 | error.RelocFailure, error.RelaxFailure => has_reloc_errors = true, |
| 904 | 903 | error.UnsupportedCpuArch => { |
| 905 | 904 | try self.reportUnsupportedCpuArch(); |
| 906 | return error.LinkFailure; | |
| 905 | return error.AlreadyReported; | |
| 907 | 906 | }, |
| 908 | 907 | else => |e| return e, |
| 909 | 908 | }; |
| ... | ... | @@ -912,7 +911,7 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { |
| 912 | 911 | |
| 913 | 912 | try self.reportUndefinedSymbols(&undefs); |
| 914 | 913 | |
| 915 | if (has_reloc_errors) return error.LinkFailure; | |
| 914 | if (has_reloc_errors) return error.AlreadyReported; | |
| 916 | 915 | } |
| 917 | 916 | |
| 918 | 917 | try self.writePhdrTable(); |
| ... | ... | @@ -921,10 +920,10 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { |
| 921 | 920 | try self.writeMergeSections(); |
| 922 | 921 | |
| 923 | 922 | self.writeSyntheticSections() catch |err| switch (err) { |
| 924 | error.RelocFailure => return error.LinkFailure, | |
| 923 | error.RelocFailure => return error.AlreadyReported, | |
| 925 | 924 | error.UnsupportedCpuArch => { |
| 926 | 925 | try self.reportUnsupportedCpuArch(); |
| 927 | return error.LinkFailure; | |
| 926 | return error.AlreadyReported; | |
| 928 | 927 | }, |
| 929 | 928 | else => |e| return e, |
| 930 | 929 | }; |
| ... | ... | @@ -938,7 +937,7 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { |
| 938 | 937 | try self.writeElfHeader(); |
| 939 | 938 | } |
| 940 | 939 | |
| 941 | if (diags.hasErrors()) return error.LinkFailure; | |
| 940 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 942 | 941 | } |
| 943 | 942 | |
| 944 | 943 | fn dumpArgvInit(self: *Elf, arena: Allocator) !void { |
| ... | ... | @@ -1053,7 +1052,7 @@ pub fn openParseObjectReportingFailure(self: *Elf, path: Path) void { |
| 1053 | 1052 | const diags = &comp.link_diags; |
| 1054 | 1053 | const obj = link.openObject(io, path, false, false) catch |err| { |
| 1055 | 1054 | switch (diags.failParse(path, "failed to open object: {t}", .{err})) { |
| 1056 | error.LinkFailure => return, | |
| 1055 | error.AlreadyReported => return, | |
| 1057 | 1056 | } |
| 1058 | 1057 | }; |
| 1059 | 1058 | self.parseObjectReportingFailure(obj); |
| ... | ... | @@ -1063,7 +1062,7 @@ fn parseObjectReportingFailure(self: *Elf, obj: link.Input.Object) void { |
| 1063 | 1062 | const comp = self.base.comp; |
| 1064 | 1063 | const diags = &comp.link_diags; |
| 1065 | 1064 | self.parseObject(obj) catch |err| switch (err) { |
| 1066 | error.LinkFailure => return, // already reported | |
| 1065 | error.AlreadyReported => return, // already reported | |
| 1067 | 1066 | else => |e| diags.addParseError(obj.path, "failed to parse object: {t}", .{e}), |
| 1068 | 1067 | }; |
| 1069 | 1068 | } |
| ... | ... | @@ -1343,7 +1342,7 @@ fn scanRelocs(self: *Elf) !void { |
| 1343 | 1342 | error.RelaxFailure => unreachable, |
| 1344 | 1343 | error.UnsupportedCpuArch => { |
| 1345 | 1344 | try self.reportUnsupportedCpuArch(); |
| 1346 | return error.LinkFailure; | |
| 1345 | return error.AlreadyReported; | |
| 1347 | 1346 | }, |
| 1348 | 1347 | error.RelocFailure => has_reloc_errors = true, |
| 1349 | 1348 | else => |e| return e, |
| ... | ... | @@ -1354,7 +1353,7 @@ fn scanRelocs(self: *Elf) !void { |
| 1354 | 1353 | error.RelaxFailure => unreachable, |
| 1355 | 1354 | error.UnsupportedCpuArch => { |
| 1356 | 1355 | try self.reportUnsupportedCpuArch(); |
| 1357 | return error.LinkFailure; | |
| 1356 | return error.AlreadyReported; | |
| 1358 | 1357 | }, |
| 1359 | 1358 | error.RelocFailure => has_reloc_errors = true, |
| 1360 | 1359 | else => |e| return e, |
| ... | ... | @@ -1363,7 +1362,7 @@ fn scanRelocs(self: *Elf) !void { |
| 1363 | 1362 | |
| 1364 | 1363 | try self.reportUndefinedSymbols(&undefs); |
| 1365 | 1364 | |
| 1366 | if (has_reloc_errors) return error.LinkFailure; | |
| 1365 | if (has_reloc_errors) return error.AlreadyReported; | |
| 1367 | 1366 | |
| 1368 | 1367 | if (self.zigObjectPtr()) |zo| { |
| 1369 | 1368 | try zo.asFile().createSymbolIndirection(self); |
| ... | ... | @@ -1690,7 +1689,7 @@ pub fn updateFunc( |
| 1690 | 1689 | pt: Zcu.PerThread, |
| 1691 | 1690 | func_index: InternPool.Index, |
| 1692 | 1691 | mir: *const codegen.AnyMir, |
| 1693 | ) link.File.UpdateNavError!void { | |
| 1692 | ) link.Error!void { | |
| 1694 | 1693 | return self.zigObjectPtr().?.updateFunc(self, pt, func_index, mir); |
| 1695 | 1694 | } |
| 1696 | 1695 | |
| ... | ... | @@ -1698,7 +1697,7 @@ pub fn updateNav( |
| 1698 | 1697 | self: *Elf, |
| 1699 | 1698 | pt: Zcu.PerThread, |
| 1700 | 1699 | nav: InternPool.Nav.Index, |
| 1701 | ) link.File.UpdateNavError!void { | |
| 1700 | ) link.Error!void { | |
| 1702 | 1701 | return self.zigObjectPtr().?.updateNav(self, pt, nav); |
| 1703 | 1702 | } |
| 1704 | 1703 | |
| ... | ... | @@ -1707,7 +1706,7 @@ pub fn updateContainerType( |
| 1707 | 1706 | pt: Zcu.PerThread, |
| 1708 | 1707 | ty: InternPool.Index, |
| 1709 | 1708 | success: bool, |
| 1710 | ) link.File.UpdateContainerTypeError!void { | |
| 1709 | ) link.Error!void { | |
| 1711 | 1710 | return self.zigObjectPtr().?.updateContainerType(pt, ty, success) catch |err| switch (err) { |
| 1712 | 1711 | error.OutOfMemory => |e| return e, |
| 1713 | 1712 | }; |
| ... | ... | @@ -1718,11 +1717,11 @@ pub fn updateExports( |
| 1718 | 1717 | pt: Zcu.PerThread, |
| 1719 | 1718 | exported: Zcu.Exported, |
| 1720 | 1719 | export_indices: []const Zcu.Export.Index, |
| 1721 | ) link.File.UpdateExportsError!void { | |
| 1720 | ) link.Error!void { | |
| 1722 | 1721 | return self.zigObjectPtr().?.updateExports(self, pt, exported, export_indices); |
| 1723 | 1722 | } |
| 1724 | 1723 | |
| 1725 | pub fn updateLineNumber(self: *Elf, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void { | |
| 1724 | pub fn updateLineNumber(self: *Elf, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) link.Error!void { | |
| 1726 | 1725 | return self.zigObjectPtr().?.updateLineNumber(pt, ti_id); |
| 1727 | 1726 | } |
| 1728 | 1727 | |
| ... | ... | @@ -1784,12 +1783,12 @@ pub fn resolveMergeSections(self: *Elf) !void { |
| 1784 | 1783 | if (!object.alive) continue; |
| 1785 | 1784 | if (!object.dirty) continue; |
| 1786 | 1785 | object.initInputMergeSections(self) catch |err| switch (err) { |
| 1787 | error.LinkFailure => has_errors = true, | |
| 1786 | error.AlreadyReported => has_errors = true, | |
| 1788 | 1787 | else => |e| return e, |
| 1789 | 1788 | }; |
| 1790 | 1789 | } |
| 1791 | 1790 | |
| 1792 | if (has_errors) return error.LinkFailure; | |
| 1791 | if (has_errors) return error.AlreadyReported; | |
| 1793 | 1792 | |
| 1794 | 1793 | for (self.objects.items) |index| { |
| 1795 | 1794 | const object = self.file(index).?.object; |
| ... | ... | @@ -1803,12 +1802,12 @@ pub fn resolveMergeSections(self: *Elf) !void { |
| 1803 | 1802 | if (!object.alive) continue; |
| 1804 | 1803 | if (!object.dirty) continue; |
| 1805 | 1804 | object.resolveMergeSubsections(self) catch |err| switch (err) { |
| 1806 | error.LinkFailure => has_errors = true, | |
| 1805 | error.AlreadyReported => has_errors = true, | |
| 1807 | 1806 | else => |e| return e, |
| 1808 | 1807 | }; |
| 1809 | 1808 | } |
| 1810 | 1809 | |
| 1811 | if (has_errors) return error.LinkFailure; | |
| 1810 | if (has_errors) return error.AlreadyReported; | |
| 1812 | 1811 | } |
| 1813 | 1812 | |
| 1814 | 1813 | pub fn finalizeMergeSections(self: *Elf) !void { |
| ... | ... | @@ -2998,7 +2997,7 @@ fn writeAtoms(self: *Elf) !void { |
| 2998 | 2997 | atom_list.write(&buffer, &undefs, self) catch |err| switch (err) { |
| 2999 | 2998 | error.UnsupportedCpuArch => { |
| 3000 | 2999 | try self.reportUnsupportedCpuArch(); |
| 3001 | return error.LinkFailure; | |
| 3000 | return error.AlreadyReported; | |
| 3002 | 3001 | }, |
| 3003 | 3002 | error.RelocFailure, error.RelaxFailure => has_reloc_errors = true, |
| 3004 | 3003 | else => |e| return e, |
| ... | ... | @@ -3006,7 +3005,7 @@ fn writeAtoms(self: *Elf) !void { |
| 3006 | 3005 | } |
| 3007 | 3006 | |
| 3008 | 3007 | try self.reportUndefinedSymbols(&undefs); |
| 3009 | if (has_reloc_errors) return error.LinkFailure; | |
| 3008 | if (has_reloc_errors) return error.AlreadyReported; | |
| 3010 | 3009 | |
| 3011 | 3010 | if (self.requiresThunks()) { |
| 3012 | 3011 | for (self.thunks.items) |th| { |
| ... | ... | @@ -3838,9 +3837,9 @@ pub fn failFile( |
| 3838 | 3837 | file_index: File.Index, |
| 3839 | 3838 | comptime format: []const u8, |
| 3840 | 3839 | args: anytype, |
| 3841 | ) error{ OutOfMemory, LinkFailure } { | |
| 3840 | ) error{ OutOfMemory, AlreadyReported } { | |
| 3842 | 3841 | try addFileError(self, file_index, format, args); |
| 3843 | return error.LinkFailure; | |
| 3842 | return error.AlreadyReported; | |
| 3844 | 3843 | } |
| 3845 | 3844 | |
| 3846 | 3845 | const FormatShdr = struct { |
| ... | ... | @@ -4409,7 +4408,7 @@ pub fn stringTableLookup(strtab: []const u8, off: u32) [:0]const u8 { |
| 4409 | 4408 | return slice[0..mem.indexOfScalar(u8, slice, 0).? :0]; |
| 4410 | 4409 | } |
| 4411 | 4410 | |
| 4412 | pub fn pwriteAll(elf_file: *Elf, bytes: []const u8, offset: u64) error{LinkFailure}!void { | |
| 4411 | pub fn pwriteAll(elf_file: *Elf, bytes: []const u8, offset: u64) error{AlreadyReported}!void { | |
| 4413 | 4412 | const comp = elf_file.base.comp; |
| 4414 | 4413 | const io = comp.io; |
| 4415 | 4414 | const diags = &comp.link_diags; |
| ... | ... | @@ -4417,7 +4416,7 @@ pub fn pwriteAll(elf_file: *Elf, bytes: []const u8, offset: u64) error{LinkFailu |
| 4417 | 4416 | return diags.fail("failed to write: {t}", .{err}); |
| 4418 | 4417 | } |
| 4419 | 4418 | |
| 4420 | pub fn setLength(elf_file: *Elf, length: u64) error{LinkFailure}!void { | |
| 4419 | pub fn setLength(elf_file: *Elf, length: u64) error{AlreadyReported}!void { | |
| 4421 | 4420 | const comp = elf_file.base.comp; |
| 4422 | 4421 | const io = comp.i; |
| 4423 | 4422 | const diags = &comp.link_diags; |
| ... | ... | @@ -4426,7 +4425,7 @@ pub fn setLength(elf_file: *Elf, length: u64) error{LinkFailure}!void { |
| 4426 | 4425 | }; |
| 4427 | 4426 | } |
| 4428 | 4427 | |
| 4429 | pub fn cast(elf_file: *Elf, comptime T: type, x: anytype) error{LinkFailure}!T { | |
| 4428 | pub fn cast(elf_file: *Elf, comptime T: type, x: anytype) error{AlreadyReported}!T { | |
| 4430 | 4429 | return std.math.cast(T, x) orelse { |
| 4431 | 4430 | const comp = elf_file.base.comp; |
| 4432 | 4431 | const diags = &comp.link_diags; |
src/link/Elf/Object.zig+6-6| ... | ... | @@ -282,7 +282,7 @@ pub fn validateEFlags( |
| 282 | 282 | ); |
| 283 | 283 | } |
| 284 | 284 | |
| 285 | if (any_errors) return error.LinkFailure; | |
| 285 | if (any_errors) return error.AlreadyReported; | |
| 286 | 286 | }, |
| 287 | 287 | else => {}, |
| 288 | 288 | } |
| ... | ... | @@ -829,7 +829,7 @@ pub fn initInputMergeSections(self: *Object, elf_file: *Elf) !void { |
| 829 | 829 | var err = try diags.addErrorWithNotes(1); |
| 830 | 830 | try err.addMsg("string not null terminated", .{}); |
| 831 | 831 | err.addNote("in {f}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) }); |
| 832 | return error.LinkFailure; | |
| 832 | return error.AlreadyReported; | |
| 833 | 833 | } |
| 834 | 834 | end += sh_entsize; |
| 835 | 835 | const string = data[start..end]; |
| ... | ... | @@ -844,7 +844,7 @@ pub fn initInputMergeSections(self: *Object, elf_file: *Elf) !void { |
| 844 | 844 | var err = try diags.addErrorWithNotes(1); |
| 845 | 845 | try err.addMsg("size not a multiple of sh_entsize", .{}); |
| 846 | 846 | err.addNote("in {f}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) }); |
| 847 | return error.LinkFailure; | |
| 847 | return error.AlreadyReported; | |
| 848 | 848 | } |
| 849 | 849 | |
| 850 | 850 | var pos: u32 = 0; |
| ... | ... | @@ -873,7 +873,7 @@ pub fn initOutputMergeSections(self: *Object, elf_file: *Elf) !void { |
| 873 | 873 | } |
| 874 | 874 | |
| 875 | 875 | pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) error{ |
| 876 | LinkFailure, | |
| 876 | AlreadyReported, | |
| 877 | 877 | OutOfMemory, |
| 878 | 878 | /// TODO report the error and remove this |
| 879 | 879 | Overflow, |
| ... | ... | @@ -925,7 +925,7 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) error{ |
| 925 | 925 | try err.addMsg("invalid symbol value: {x}", .{esym.st_value}); |
| 926 | 926 | err.addNote("for symbol {s}", .{sym.name(elf_file)}); |
| 927 | 927 | err.addNote("in {f}", .{self.fmtPath()}); |
| 928 | return error.LinkFailure; | |
| 928 | return error.AlreadyReported; | |
| 929 | 929 | }; |
| 930 | 930 | |
| 931 | 931 | sym.ref = .{ .index = res.msub_index, .file = imsec.merge_section_index }; |
| ... | ... | @@ -950,7 +950,7 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) error{ |
| 950 | 950 | var err = try diags.addErrorWithNotes(1); |
| 951 | 951 | try err.addMsg("invalid relocation at offset 0x{x}", .{rel.r_offset}); |
| 952 | 952 | err.addNote("in {f}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) }); |
| 953 | return error.LinkFailure; | |
| 953 | return error.AlreadyReported; | |
| 954 | 954 | }; |
| 955 | 955 | |
| 956 | 956 | 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 { |
| 272 | 272 | |
| 273 | 273 | // Most lazy symbols can be updated on first use, but |
| 274 | 274 | // 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( | |
| 276 | 276 | elf_file, |
| 277 | 277 | pt, |
| 278 | 278 | .{ .kind = .code, .ty = .anyerror_type }, |
| 279 | 279 | 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( | |
| 285 | 282 | elf_file, |
| 286 | 283 | pt, |
| 287 | 284 | .{ .kind = .const_data, .ty = .anyerror_type }, |
| 288 | 285 | metadata.rodata_symbol_index, |
| 289 | ) catch |err| switch (err) { | |
| 290 | error.CodegenFail => return error.LinkFailure, | |
| 291 | else => |e| return e, | |
| 292 | }; | |
| 286 | ); | |
| 293 | 287 | } |
| 294 | 288 | for (self.lazy_syms.values()) |*metadata| { |
| 295 | 289 | if (metadata.text_state != .unused) metadata.text_state = .flushed; |
| ... | ... | @@ -999,8 +993,7 @@ pub fn lowerUav( |
| 999 | 993 | pt: Zcu.PerThread, |
| 1000 | 994 | uav: InternPool.Index, |
| 1001 | 995 | explicit_alignment: InternPool.Alignment, |
| 1002 | src_loc: Zcu.LazySrcLoc, | |
| 1003 | ) !codegen.SymbolResult { | |
| 996 | ) !link.File.SymbolId { | |
| 1004 | 997 | const zcu = pt.zcu; |
| 1005 | 998 | const gpa = zcu.gpa; |
| 1006 | 999 | const val = Value.fromInterned(uav); |
| ... | ... | @@ -1013,7 +1006,7 @@ pub fn lowerUav( |
| 1013 | 1006 | const sym = self.symbol(metadata.symbol_index); |
| 1014 | 1007 | const existing_alignment = sym.atom(elf_file).?.alignment; |
| 1015 | 1008 | if (uav_alignment.order(existing_alignment).compare(.lte)) |
| 1016 | return .{ .sym_index = @enumFromInt(metadata.symbol_index) }; | |
| 1009 | return @enumFromInt(metadata.symbol_index); | |
| 1017 | 1010 | } |
| 1018 | 1011 | |
| 1019 | 1012 | const osec = if (self.data_relro_index) |sym_index| |
| ... | ... | @@ -1033,31 +1026,25 @@ pub fn lowerUav( |
| 1033 | 1026 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ |
| 1034 | 1027 | @intFromEnum(uav), |
| 1035 | 1028 | }) catch unreachable; |
| 1036 | const res = self.lowerConst( | |
| 1029 | const sym_index = self.lowerConst( | |
| 1037 | 1030 | elf_file, |
| 1038 | 1031 | pt, |
| 1039 | 1032 | name, |
| 1040 | 1033 | val, |
| 1041 | 1034 | uav_alignment, |
| 1042 | 1035 | osec, |
| 1043 | src_loc, | |
| 1044 | 1036 | ) catch |err| switch (err) { |
| 1045 | 1037 | 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 | ), | |
| 1052 | 1042 | }; |
| 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; | |
| 1061 | 1048 | } |
| 1062 | 1049 | |
| 1063 | 1050 | pub fn getOrCreateMetadataForLazySymbol( |
| ... | ... | @@ -1370,7 +1357,7 @@ fn updateNavCode( |
| 1370 | 1357 | shdr_index: u32, |
| 1371 | 1358 | code: []const u8, |
| 1372 | 1359 | stt_bits: u8, |
| 1373 | ) link.File.UpdateNavError!void { | |
| 1360 | ) link.Error!void { | |
| 1374 | 1361 | const zcu = pt.zcu; |
| 1375 | 1362 | const gpa = zcu.gpa; |
| 1376 | 1363 | const comp = elf_file.base.comp; |
| ... | ... | @@ -1473,7 +1460,7 @@ fn updateTlv( |
| 1473 | 1460 | sym_index: Symbol.Index, |
| 1474 | 1461 | shndx: u32, |
| 1475 | 1462 | code: []const u8, |
| 1476 | ) link.File.UpdateNavError!void { | |
| 1463 | ) link.Error!void { | |
| 1477 | 1464 | const zcu = pt.zcu; |
| 1478 | 1465 | const ip = &zcu.intern_pool; |
| 1479 | 1466 | const gpa = zcu.gpa; |
| ... | ... | @@ -1531,7 +1518,7 @@ pub fn updateFunc( |
| 1531 | 1518 | pt: Zcu.PerThread, |
| 1532 | 1519 | func_index: InternPool.Index, |
| 1533 | 1520 | mir: *const codegen.AnyMir, |
| 1534 | ) link.File.UpdateNavError!void { | |
| 1521 | ) link.Error!void { | |
| 1535 | 1522 | const tracy = trace(@src()); |
| 1536 | 1523 | defer tracy.end(); |
| 1537 | 1524 | |
| ... | ... | @@ -1558,7 +1545,6 @@ pub fn updateFunc( |
| 1558 | 1545 | codegen.emitFunction( |
| 1559 | 1546 | &elf_file.base, |
| 1560 | 1547 | pt, |
| 1561 | zcu.navSrcLoc(func.owner_nav), | |
| 1562 | 1548 | func_index, |
| 1563 | 1549 | @enumFromInt(sym_index), |
| 1564 | 1550 | mir, |
| ... | ... | @@ -1645,7 +1631,7 @@ pub fn updateNav( |
| 1645 | 1631 | elf_file: *Elf, |
| 1646 | 1632 | pt: Zcu.PerThread, |
| 1647 | 1633 | nav_index: InternPool.Nav.Index, |
| 1648 | ) link.File.UpdateNavError!void { | |
| 1634 | ) link.Error!void { | |
| 1649 | 1635 | const tracy = trace(@src()); |
| 1650 | 1636 | defer tracy.end(); |
| 1651 | 1637 | |
| ... | ... | @@ -1670,7 +1656,7 @@ pub fn updateNav( |
| 1670 | 1656 | var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, @enumFromInt(sym_index)); |
| 1671 | 1657 | defer debug_wip_nav.deinit(); |
| 1672 | 1658 | 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, | |
| 1674 | 1660 | else => |e| return elf_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}), |
| 1675 | 1661 | }; |
| 1676 | 1662 | } |
| ... | ... | @@ -1691,7 +1677,6 @@ pub fn updateNav( |
| 1691 | 1677 | codegen.generateSymbol( |
| 1692 | 1678 | &elf_file.base, |
| 1693 | 1679 | pt, |
| 1694 | zcu.navSrcLoc(nav_index), | |
| 1695 | 1680 | .fromInterned(nav.resolved.?.value), |
| 1696 | 1681 | &aw.writer, |
| 1697 | 1682 | .{ .atom_index = @enumFromInt(sym_index) }, |
| ... | ... | @@ -1713,7 +1698,7 @@ pub fn updateNav( |
| 1713 | 1698 | try self.updateNavCode(elf_file, pt, nav_index, sym_index, shndx, code, elf.STT_OBJECT); |
| 1714 | 1699 | |
| 1715 | 1700 | 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, | |
| 1717 | 1702 | else => |e| return elf_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}), |
| 1718 | 1703 | }; |
| 1719 | 1704 | } else if (self.dwarf) |*dwarf| try dwarf.updateComptimeNav(pt, nav_index); |
| ... | ... | @@ -1759,7 +1744,6 @@ fn updateLazySymbol( |
| 1759 | 1744 | codegen.generateLazySymbol( |
| 1760 | 1745 | &elf_file.base, |
| 1761 | 1746 | pt, |
| 1762 | Type.fromInterned(sym.ty).srcLocOrNull(zcu) orelse .unneeded, | |
| 1763 | 1747 | sym, |
| 1764 | 1748 | &required_alignment, |
| 1765 | 1749 | &aw.writer, |
| ... | ... | @@ -1827,8 +1811,7 @@ fn lowerConst( |
| 1827 | 1811 | val: Value, |
| 1828 | 1812 | required_alignment: InternPool.Alignment, |
| 1829 | 1813 | output_section_index: u32, |
| 1830 | src_loc: Zcu.LazySrcLoc, | |
| 1831 | ) !codegen.SymbolResult { | |
| 1814 | ) !link.File.SymbolId { | |
| 1832 | 1815 | const gpa = pt.zcu.gpa; |
| 1833 | 1816 | |
| 1834 | 1817 | var aw: std.Io.Writer.Allocating = .init(gpa); |
| ... | ... | @@ -1840,7 +1823,6 @@ fn lowerConst( |
| 1840 | 1823 | codegen.generateSymbol( |
| 1841 | 1824 | &elf_file.base, |
| 1842 | 1825 | pt, |
| 1843 | src_loc, | |
| 1844 | 1826 | val, |
| 1845 | 1827 | &aw.writer, |
| 1846 | 1828 | .{ .atom_index = @enumFromInt(sym_index) }, |
| ... | ... | @@ -1865,7 +1847,7 @@ fn lowerConst( |
| 1865 | 1847 | |
| 1866 | 1848 | try elf_file.pwriteAll(code, atom_ptr.offset(elf_file)); |
| 1867 | 1849 | |
| 1868 | return .{ .sym_index = @enumFromInt(sym_index) }; | |
| 1850 | return @enumFromInt(sym_index); | |
| 1869 | 1851 | } |
| 1870 | 1852 | |
| 1871 | 1853 | pub fn updateExports( |
| ... | ... | @@ -1874,7 +1856,7 @@ pub fn updateExports( |
| 1874 | 1856 | pt: Zcu.PerThread, |
| 1875 | 1857 | exported: Zcu.Exported, |
| 1876 | 1858 | export_indices: []const Zcu.Export.Index, |
| 1877 | ) link.File.UpdateExportsError!void { | |
| 1859 | ) link.Error!void { | |
| 1878 | 1860 | const tracy = trace(@src()); |
| 1879 | 1861 | defer tracy.end(); |
| 1880 | 1862 | |
| ... | ... | @@ -1886,18 +1868,7 @@ pub fn updateExports( |
| 1886 | 1868 | break :blk self.navs.getPtr(nav).?; |
| 1887 | 1869 | }, |
| 1888 | 1870 | .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); | |
| 1901 | 1872 | break :blk self.uavs.getPtr(uav).?; |
| 1902 | 1873 | }, |
| 1903 | 1874 | }; |
| ... | ... | @@ -1962,12 +1933,12 @@ pub fn updateExports( |
| 1962 | 1933 | } |
| 1963 | 1934 | } |
| 1964 | 1935 | |
| 1965 | pub fn updateLineNumber(self: *ZigObject, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void { | |
| 1936 | pub fn updateLineNumber(self: *ZigObject, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) link.Error!void { | |
| 1966 | 1937 | if (self.dwarf) |*dwarf| { |
| 1967 | 1938 | const comp = dwarf.bin_file.comp; |
| 1968 | 1939 | const diags = &comp.link_diags; |
| 1969 | 1940 | 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, | |
| 1971 | 1942 | else => |e| return diags.fail("failed to update dwarf line numbers: {s}", .{@errorName(e)}), |
| 1972 | 1943 | }; |
| 1973 | 1944 | } |
src/link/Elf/relocatable.zig+4-4| ... | ... | @@ -23,7 +23,7 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void { |
| 23 | 23 | const io = comp.io; |
| 24 | 24 | const diags = &comp.link_diags; |
| 25 | 25 | |
| 26 | if (diags.hasErrors()) return error.LinkFailure; | |
| 26 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 27 | 27 | |
| 28 | 28 | // First, we flush relocatable object file generated with our backends. |
| 29 | 29 | if (elf_file.zigObjectPtr()) |zig_object| { |
| ... | ... | @@ -151,13 +151,13 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void { |
| 151 | 151 | try elf_file.base.file.?.setLength(io, total_size); |
| 152 | 152 | try elf_file.base.file.?.writePositionalAll(io, writer.buffered(), 0); |
| 153 | 153 | |
| 154 | if (diags.hasErrors()) return error.LinkFailure; | |
| 154 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 155 | 155 | } |
| 156 | 156 | |
| 157 | 157 | pub fn flushObject(elf_file: *Elf, comp: *Compilation) !void { |
| 158 | 158 | const diags = &comp.link_diags; |
| 159 | 159 | |
| 160 | if (diags.hasErrors()) return error.LinkFailure; | |
| 160 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 161 | 161 | |
| 162 | 162 | // Now, we are ready to resolve the symbols across all input files. |
| 163 | 163 | // 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 { |
| 203 | 203 | try elf_file.writeShdrTable(); |
| 204 | 204 | try elf_file.writeElfHeader(); |
| 205 | 205 | |
| 206 | if (diags.hasErrors()) return error.LinkFailure; | |
| 206 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 207 | 207 | } |
| 208 | 208 | |
| 209 | 209 | fn claimUnresolved(elf_file: *Elf) void { |
src/link/Elf2.zig+295-212| ... | ... | @@ -162,6 +162,8 @@ const_prog_node: std.Progress.Node, |
| 162 | 162 | synth_prog_node: std.Progress.Node, |
| 163 | 163 | input_prog_node: std.Progress.Node, |
| 164 | 164 | |
| 165 | const Error = link.Error || error{MappedFileIo}; | |
| 166 | ||
| 165 | 167 | const Node = union(enum) { |
| 166 | 168 | file, |
| 167 | 169 | ehdr, |
| ... | ... | @@ -478,7 +480,7 @@ const Section = struct { |
| 478 | 480 | }; |
| 479 | 481 | } |
| 480 | 482 | |
| 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 { | |
| 482 | 484 | const shstrtab_entry = try elf.string(.shstrtab, new_name); |
| 483 | 485 | switch (elf.shdrPtr(shndx)) { |
| 484 | 486 | inline else => |shdr| elf.targetStore(&shdr.name, @intFromEnum(shstrtab_entry)), |
| ... | ... | @@ -487,7 +489,7 @@ const Section = struct { |
| 487 | 489 | |
| 488 | 490 | /// Asserts that `shndx` is a `SHT_RELA` section and ensures that its node has enough unused |
| 489 | 491 | /// 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 { | |
| 491 | 493 | const node = rela_shndx.get(elf).ni; |
| 492 | 494 | const need_size: u64 = switch (elf.shdrPtr(rela_shndx)) { |
| 493 | 495 | inline else => |shdr, class| need_size: { |
| ... | ... | @@ -509,11 +511,7 @@ const Section = struct { |
| 509 | 511 | break :need_size cur_size + need_additional * ent_size; |
| 510 | 512 | }, |
| 511 | 513 | }; |
| 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); | |
| 517 | 515 | } |
| 518 | 516 | |
| 519 | 517 | /// Asserts that `shndx` is a `SHT_RELA` section and deletes the `ElfN.Rela` entry at the |
| ... | ... | @@ -1192,7 +1190,7 @@ const SymbolReloc = struct { |
| 1192 | 1190 | } |
| 1193 | 1191 | }; |
| 1194 | 1192 | |
| 1195 | fn ensureUnusedSymbolCapacity(elf: *Elf, len: u32, kind: enum { all_local, maybe_global }) !void { | |
| 1193 | fn ensureUnusedSymbolCapacity(elf: *Elf, len: u32, kind: enum { all_local, maybe_global }) Error!void { | |
| 1196 | 1194 | const gpa = elf.base.comp.gpa; |
| 1197 | 1195 | |
| 1198 | 1196 | try elf.symtab.ensureUnusedCapacity(gpa, len); |
| ... | ... | @@ -1210,11 +1208,7 @@ fn ensureUnusedSymbolCapacity(elf: *Elf, len: u32, kind: enum { all_local, maybe |
| 1210 | 1208 | const need_node_size: u64 = switch (elf.shdrPtr(.symtab)) { |
| 1211 | 1209 | inline else => |shdr, class| elf.targetLoad(&shdr.size) + len * @sizeOf(class.ElfN().Sym), |
| 1212 | 1210 | }; |
| 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); | |
| 1218 | 1212 | } |
| 1219 | 1213 | |
| 1220 | 1214 | switch (kind) { |
| ... | ... | @@ -1232,18 +1226,14 @@ fn ensureUnusedSymbolCapacity(elf: *Elf, len: u32, kind: enum { all_local, maybe |
| 1232 | 1226 | const dynsym_need_size: u64 = switch (elf.shdrPtr(elf.shndx.dynsym)) { |
| 1233 | 1227 | inline else => |shdr, class| elf.targetLoad(&shdr.size) + len * @sizeOf(class.ElfN().Sym), |
| 1234 | 1228 | }; |
| 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); | |
| 1240 | 1230 | |
| 1241 | 1231 | try elf.ensureUnusedPltCapacity(len); |
| 1242 | 1232 | } |
| 1243 | 1233 | }, |
| 1244 | 1234 | } |
| 1245 | 1235 | } |
| 1246 | fn ensureUnusedPltCapacity(elf: *Elf, len: u32) !void { | |
| 1236 | fn ensureUnusedPltCapacity(elf: *Elf, len: u32) Error!void { | |
| 1247 | 1237 | const gpa = elf.base.comp.gpa; |
| 1248 | 1238 | |
| 1249 | 1239 | try elf.shndx.rela_plt.relaEnsureAdditionalCapacity(elf, len); |
| ... | ... | @@ -1256,30 +1246,18 @@ fn ensureUnusedPltCapacity(elf: *Elf, len: u32) !void { |
| 1256 | 1246 | .X86_64 => { |
| 1257 | 1247 | // Ensure the `.plt` section's node is big enough |
| 1258 | 1248 | 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); | |
| 1264 | 1250 | |
| 1265 | 1251 | // Ensure the `.got.plt` section's node is big enough |
| 1266 | 1252 | const got_plt_need_size: usize = switch (elf.identClass()) { |
| 1267 | 1253 | .NONE, _ => unreachable, |
| 1268 | 1254 | inline else => |class| @sizeOf(class.ElfN().Addr) * (3 + need_plt_capacity), |
| 1269 | 1255 | }; |
| 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); | |
| 1275 | 1257 | |
| 1276 | 1258 | // Ensure the `.plt.sec` section's node is big enough |
| 1277 | 1259 | 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); | |
| 1283 | 1261 | }, |
| 1284 | 1262 | } |
| 1285 | 1263 | } |
| ... | ... | @@ -1375,7 +1353,7 @@ const AddGlobalSymbolOptions = struct { |
| 1375 | 1353 | const Name = struct { |
| 1376 | 1354 | strtab: String(.strtab), |
| 1377 | 1355 | dynstr: String(.dynstr), |
| 1378 | fn string(elf: *Elf, slice: []const u8) !Name { | |
| 1356 | fn string(elf: *Elf, slice: []const u8) Error!Name { | |
| 1379 | 1357 | return .{ |
| 1380 | 1358 | .strtab = try elf.string(.strtab, slice), |
| 1381 | 1359 | .dynstr = switch (elf.shndx.dynsym) { |
| ... | ... | @@ -2205,7 +2183,14 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId { |
| 2205 | 2183 | const s: Symbol.Id = .local(lsi); |
| 2206 | 2184 | return s.toTypeErased(); |
| 2207 | 2185 | } |
| 2208 | pub fn lazySymbol(elf: *Elf, lazy: link.File.LazySymbol) !link.File.SymbolId { | |
| 2186 | pub 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 | } | |
| 2193 | fn lazySymbolInner(elf: *Elf, lazy: link.File.LazySymbol) Error!link.File.SymbolId { | |
| 2209 | 2194 | const gpa = elf.base.comp.gpa; |
| 2210 | 2195 | |
| 2211 | 2196 | try elf.ensureUnusedSymbolCapacity(1, .all_local); |
| ... | ... | @@ -2246,13 +2231,21 @@ pub fn lazySymbol(elf: *Elf, lazy: link.File.LazySymbol) !link.File.SymbolId { |
| 2246 | 2231 | const s: Symbol.Id = .local(gop.value_ptr.lsi); |
| 2247 | 2232 | return s.toTypeErased(); |
| 2248 | 2233 | } |
| 2249 | pub fn externSymbol(elf: *Elf, opts: struct { | |
| 2234 | pub const ExternSymbolOpts = struct { | |
| 2250 | 2235 | name: []const u8, |
| 2251 | 2236 | lib_name: ?[]const u8, |
| 2252 | 2237 | type: std.elf.STT, |
| 2253 | 2238 | linkage: std.lang.GlobalLinkage = .strong, |
| 2254 | 2239 | visibility: std.lang.SymbolVisibility = .default, |
| 2255 | }) !link.File.SymbolId { | |
| 2240 | }; | |
| 2241 | pub 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 | } | |
| 2248 | fn externSymbolInner(elf: *Elf, opts: ExternSymbolOpts) Error!link.File.SymbolId { | |
| 2256 | 2249 | try elf.ensureUnusedSymbolCapacity(1, .maybe_global); |
| 2257 | 2250 | const symbol = elf.addGlobalSymbolAssumeCapacity(.{ |
| 2258 | 2251 | .node = .none, |
| ... | ... | @@ -2265,7 +2258,7 @@ pub fn externSymbol(elf: *Elf, opts: struct { |
| 2265 | 2258 | .internal => @panic("TODO internal extern symbol"), |
| 2266 | 2259 | .strong => .strong, |
| 2267 | 2260 | .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", .{}), | |
| 2269 | 2262 | }, |
| 2270 | 2263 | .visibility = switch (opts.visibility) { |
| 2271 | 2264 | .default => .DEFAULT, |
| ... | ... | @@ -2285,12 +2278,20 @@ pub fn addReloc( |
| 2285 | 2278 | target: link.File.SymbolId, |
| 2286 | 2279 | addend: i64, |
| 2287 | 2280 | @"type": MachineRelocType, |
| 2288 | ) !void { | |
| 2281 | ) link.Error!void { | |
| 2289 | 2282 | 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 | }; | |
| 2292 | 2292 | } |
| 2293 | pub fn navSymbol(elf: *Elf, nav_index: InternPool.Nav.Index) !link.File.SymbolId { | |
| 2293 | pub fn navSymbol(elf: *Elf, nav_index: InternPool.Nav.Index) link.Error!link.File.SymbolId { | |
| 2294 | const diags = &elf.base.comp.link_diags; | |
| 2294 | 2295 | const zcu = elf.base.comp.zcu.?; |
| 2295 | 2296 | const ip = &zcu.intern_pool; |
| 2296 | 2297 | const nav = ip.getNav(nav_index); |
| ... | ... | @@ -2303,7 +2304,10 @@ pub fn navSymbol(elf: *Elf, nav_index: InternPool.Nav.Index) !link.File.SymbolId |
| 2303 | 2304 | .visibility = @"extern".visibility, |
| 2304 | 2305 | }); |
| 2305 | 2306 | } |
| 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 | }; | |
| 2307 | 2311 | const s: Symbol.Id = .local(nmi.symbol(elf)); |
| 2308 | 2312 | return s.toTypeErased(); |
| 2309 | 2313 | } |
| ... | ... | @@ -2311,8 +2315,12 @@ pub fn uavSymbol( |
| 2311 | 2315 | elf: *Elf, |
| 2312 | 2316 | uav_val: InternPool.Index, |
| 2313 | 2317 | 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 | }; | |
| 2316 | 2324 | const s: Symbol.Id = .local(umi.symbol(elf)); |
| 2317 | 2325 | return s.toTypeErased(); |
| 2318 | 2326 | } |
| ... | ... | @@ -2321,7 +2329,7 @@ pub fn getNavVAddr( |
| 2321 | 2329 | pt: Zcu.PerThread, |
| 2322 | 2330 | nav: InternPool.Nav.Index, |
| 2323 | 2331 | reloc_info: link.File.RelocInfo, |
| 2324 | ) !u64 { | |
| 2332 | ) link.Error!u64 { | |
| 2325 | 2333 | _ = pt; |
| 2326 | 2334 | return elf.getVAddr(reloc_info, try elf.navSymbol(nav)); |
| 2327 | 2335 | } |
| ... | ... | @@ -2329,41 +2337,33 @@ pub fn getUavVAddr( |
| 2329 | 2337 | elf: *Elf, |
| 2330 | 2338 | uav_val: InternPool.Index, |
| 2331 | 2339 | reloc_info: link.File.RelocInfo, |
| 2332 | ) !u64 { | |
| 2340 | ) link.Error!u64 { | |
| 2333 | 2341 | return elf.getVAddr(reloc_info, try elf.uavSymbol(uav_val, .none)); |
| 2334 | 2342 | } |
| 2335 | pub 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, | |
| 2343 | pub 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, | |
| 2341 | 2346 | reloc_info.offset, |
| 2342 | target_sym, | |
| 2347 | target, | |
| 2343 | 2348 | reloc_info.addend, |
| 2344 | 2349 | .absAddr(elf), |
| 2345 | 2350 | ); |
| 2346 | return target_sym.value(elf); | |
| 2351 | return Symbol.Id.fromTypeErased(target).value(elf); | |
| 2347 | 2352 | } |
| 2348 | 2353 | pub fn lowerUav( |
| 2349 | 2354 | elf: *Elf, |
| 2350 | 2355 | pt: Zcu.PerThread, |
| 2351 | 2356 | uav_val: InternPool.Index, |
| 2352 | 2357 | uav_align: InternPool.Alignment, |
| 2353 | src_loc: Zcu.LazySrcLoc, | |
| 2354 | ) !codegen.SymbolResult { | |
| 2358 | ) link.Error!link.File.SymbolId { | |
| 2355 | 2359 | _ = pt; |
| 2360 | const diags = &elf.base.comp.link_diags; | |
| 2356 | 2361 | 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, | |
| 2364 | 2364 | }; |
| 2365 | 2365 | const s: Symbol.Id = .local(umi.symbol(elf)); |
| 2366 | return .{ .sym_index = s.toTypeErased() }; | |
| 2366 | return s.toTypeErased(); | |
| 2367 | 2367 | } |
| 2368 | 2368 | |
| 2369 | 2369 | const StringSection = enum { |
| ... | ... | @@ -2390,7 +2390,7 @@ fn String(section: StringSection) type { |
| 2390 | 2390 | } |
| 2391 | 2391 | }; |
| 2392 | 2392 | } |
| 2393 | fn string(elf: *Elf, comptime section: StringSection, key: []const u8) !String(section) { | |
| 2393 | fn string(elf: *Elf, comptime section: StringSection, key: []const u8) Error!String(section) { | |
| 2394 | 2394 | const st: *StringTable = &@field(elf, @tagName(section)); |
| 2395 | 2395 | return @enumFromInt(try st.get(elf, section.shndx(elf), key)); |
| 2396 | 2396 | } |
| ... | ... | @@ -2424,7 +2424,7 @@ const StringTable = struct { |
| 2424 | 2424 | } |
| 2425 | 2425 | }; |
| 2426 | 2426 | |
| 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 { | |
| 2428 | 2428 | // If we are in `initHeaders` the strtab might not be initalized yet, so we need to special |
| 2429 | 2429 | // case the empty string. |
| 2430 | 2430 | if (key.len == 0) return 0; |
| ... | ... | @@ -2450,9 +2450,7 @@ const StringTable = struct { |
| 2450 | 2450 | if (shndx == elf.shndx.dynstr) { |
| 2451 | 2451 | elf.updateDynamicEntry(std.elf.DT_STRSZ, new_size); |
| 2452 | 2452 | } |
| 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); | |
| 2456 | 2454 | const slice = ni.slice(&elf.mf)[old_size..]; |
| 2457 | 2455 | @memcpy(slice[0..key.len], key); |
| 2458 | 2456 | slice[key.len] = 0; |
| ... | ... | @@ -3615,7 +3613,13 @@ fn mapInputSection(elf: *Elf, opts: struct { |
| 3615 | 3613 | flags: std.elf.SHF, |
| 3616 | 3614 | addralign: std.elf.Xword, |
| 3617 | 3615 | entsize: std.elf.Xword, |
| 3618 | }) !Section.Index { | |
| 3616 | }) (Error || error{ | |
| 3617 | UnsupportedSectionFlags, | |
| 3618 | TlsSectionUnavailable, | |
| 3619 | StripSection, | |
| 3620 | SectionFlagsConflict, | |
| 3621 | SectionTypeConflict, | |
| 3622 | })!Section.Index { | |
| 3619 | 3623 | const gpa = elf.base.comp.gpa; |
| 3620 | 3624 | if (opts.flags.INFO_LINK or |
| 3621 | 3625 | opts.flags.LINK_ORDER or |
| ... | ... | @@ -3733,7 +3737,7 @@ fn mapInputSection(elf: *Elf, opts: struct { |
| 3733 | 3737 | } |
| 3734 | 3738 | return existing_shndx; |
| 3735 | 3739 | } |
| 3736 | fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) !Node.NavMapIndex { | |
| 3740 | fn navMapIndex(elf: *Elf, zcu: *Zcu, nav_index: InternPool.Nav.Index) Error!Node.NavMapIndex { | |
| 3737 | 3741 | const gpa = zcu.gpa; |
| 3738 | 3742 | const ip = &zcu.intern_pool; |
| 3739 | 3743 | const nav = ip.getNav(nav_index); |
| ... | ... | @@ -3826,7 +3830,7 @@ fn uavMapIndex( |
| 3826 | 3830 | elf: *Elf, |
| 3827 | 3831 | uav_val: InternPool.Index, |
| 3828 | 3832 | uav_align: InternPool.Alignment, |
| 3829 | ) !Node.UavMapIndex { | |
| 3833 | ) Error!Node.UavMapIndex { | |
| 3830 | 3834 | const gpa = elf.base.comp.gpa; |
| 3831 | 3835 | const zcu = elf.base.comp.zcu.?; |
| 3832 | 3836 | |
| ... | ... | @@ -3878,26 +3882,78 @@ fn uavMapIndex( |
| 3878 | 3882 | return umi; |
| 3879 | 3883 | } |
| 3880 | 3884 | |
| 3881 | pub 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`. | |
| 3886 | const 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. | |
| 3890 | pub 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 | } | |
| 3900 | fn 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; | |
| 3884 | 3904 | var buf: [4096]u8 = undefined; |
| 3885 | 3905 | switch (input) { |
| 3886 | 3906 | .object => |object| { |
| 3887 | 3907 | var fr = object.file.reader(io, &buf); |
| 3888 | 3908 | elf.loadObject(object.path, null, &fr, .{ |
| 3889 | 3909 | .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 | }, | |
| 3891 | 3917 | }) catch |err| switch (err) { |
| 3892 | error.ReadFailed => return fr.err.?, | |
| 3893 | 3918 | 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 | }, | |
| 3894 | 3935 | }; |
| 3895 | 3936 | }, |
| 3896 | 3937 | .archive => |archive| { |
| 3897 | 3938 | var fr = archive.file.reader(io, &buf); |
| 3898 | 3939 | elf.loadArchive(archive.path, &fr) catch |err| switch (err) { |
| 3899 | error.ReadFailed => return fr.err.?, | |
| 3900 | 3940 | 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 | }, | |
| 3901 | 3957 | }; |
| 3902 | 3958 | }, |
| 3903 | 3959 | .res => unreachable, |
| ... | ... | @@ -3905,8 +3961,23 @@ pub fn loadInput(elf: *Elf, input: link.Input) (Io.File.Reader.SizeError || |
| 3905 | 3961 | try elf.needed.ensureUnusedCapacity(elf.base.comp.gpa, 1); |
| 3906 | 3962 | var fr = dso.file.reader(io, &buf); |
| 3907 | 3963 | elf.loadDso(dso.path, &fr) catch |err| switch (err) { |
| 3908 | error.ReadFailed => return fr.err.?, | |
| 3909 | 3964 | 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 | }, | |
| 3910 | 3981 | }; |
| 3911 | 3982 | }, |
| 3912 | 3983 | .dso_exact => |dso_exact| { |
| ... | ... | @@ -3919,14 +3990,22 @@ pub fn loadInput(elf: *Elf, input: link.Input) (Io.File.Reader.SizeError || |
| 3919 | 3990 | }, |
| 3920 | 3991 | } |
| 3921 | 3992 | } |
| 3922 | fn loadArchive(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) !void { | |
| 3993 | fn loadArchive(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) (LoadParseInputError || error{BadMagic})!void { | |
| 3923 | 3994 | const comp = elf.base.comp; |
| 3924 | 3995 | const gpa = comp.gpa; |
| 3925 | 3996 | const diags = &comp.link_diags; |
| 3926 | 3997 | const r = &fr.interface; |
| 3927 | 3998 | |
| 3928 | 3999 | 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 | } | |
| 3930 | 4009 | var strtab: std.Io.Writer.Allocating = .init(gpa); |
| 3931 | 4010 | defer strtab.deinit(); |
| 3932 | 4011 | while (r.takeStruct(std.elf.ar_hdr, native_endian)) |header| { |
| ... | ... | @@ -3987,7 +4066,7 @@ fn loadObject( |
| 3987 | 4066 | member: ?[]const u8, |
| 3988 | 4067 | fr: *Io.File.Reader, |
| 3989 | 4068 | fl: MappedFile.Node.FileLocation, |
| 3990 | ) !void { | |
| 4069 | ) LoadParseInputError!void { | |
| 3991 | 4070 | const comp = elf.base.comp; |
| 3992 | 4071 | const gpa = comp.gpa; |
| 3993 | 4072 | const diags = &comp.link_diags; |
| ... | ... | @@ -3995,7 +4074,14 @@ fn loadObject( |
| 3995 | 4074 | |
| 3996 | 4075 | const input_index: Node.InputIndex = @enumFromInt(elf.inputs.items.len); |
| 3997 | 4076 | 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 | }; | |
| 3999 | 4085 | try elf.ensureUnusedSymbolCapacity(1, .all_local); |
| 4000 | 4086 | try elf.inputs.ensureUnusedCapacity(gpa, 1); |
| 4001 | 4087 | const file_symbol = elf.addLocalSymbolAssumeCapacity(.{ |
| ... | ... | @@ -4376,7 +4462,7 @@ fn loadObject( |
| 4376 | 4462 | }, |
| 4377 | 4463 | } |
| 4378 | 4464 | } |
| 4379 | fn loadDso(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) !void { | |
| 4465 | fn loadDso(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) (LoadParseInputError || error{BadMagic})!void { | |
| 4380 | 4466 | const comp = elf.base.comp; |
| 4381 | 4467 | const gpa = comp.gpa; |
| 4382 | 4468 | const diags = &comp.link_diags; |
| ... | ... | @@ -4593,23 +4679,29 @@ fn loadDso(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) !void { |
| 4593 | 4679 | |
| 4594 | 4680 | /// Validates that the `std.elf.Ident` present at the start of `r` is a compatible link input. |
| 4595 | 4681 | /// |
| 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. | |
| 4597 | 4685 | /// |
| 4598 | 4686 | /// Does not advance the position of `r`. Requires `r` to have a 16-byte buffer. |
| 4599 | 4687 | fn checkInputIdent( |
| 4600 | 4688 | elf: *const Elf, |
| 4601 | 4689 | path: std.Build.Cache.Path, |
| 4602 | 4690 | r: *Io.Reader, |
| 4603 | ) !void { | |
| 4691 | ) error{ BadMagic, EndOfStream, AlreadyReported, ReadFailed }!void { | |
| 4604 | 4692 | const diags = &elf.base.comp.link_diags; |
| 4605 | 4693 | |
| 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)) { | |
| 4610 | 4699 | return error.BadMagic; |
| 4611 | 4700 | } |
| 4612 | 4701 | |
| 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 | ||
| 4613 | 4705 | if (ident.class != target.class) return diags.failParse( |
| 4614 | 4706 | path, |
| 4615 | 4707 | "bad ELF class ({?s})", |
| ... | ... | @@ -4649,7 +4741,7 @@ fn createInitFiniArraySection( |
| 4649 | 4741 | shndx: *Section.Index, |
| 4650 | 4742 | comptime name: []const u8, |
| 4651 | 4743 | @"type": std.elf.SHT, |
| 4652 | ) !void { | |
| 4744 | ) Error!void { | |
| 4653 | 4745 | assert(shndx.* == .UNDEF); |
| 4654 | 4746 | const gpa = elf.base.comp.gpa; |
| 4655 | 4747 | const addr_align: std.mem.Alignment = switch (elf.identClass()) { |
| ... | ... | @@ -4722,14 +4814,15 @@ fn updateInitFiniArraySectionSize( |
| 4722 | 4814 | Symbol.Id.global(end_sym_name).flushMoved(elf, end_vaddr); |
| 4723 | 4815 | } |
| 4724 | 4816 | |
| 4725 | pub fn prelink(elf: *Elf, prog_node: std.Progress.Node) !void { | |
| 4817 | pub fn prelink(elf: *Elf, prog_node: std.Progress.Node) link.Error!void { | |
| 4726 | 4818 | _ = prog_node; |
| 4819 | const diags = &elf.base.comp.link_diags; | |
| 4727 | 4820 | 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, | |
| 4730 | 4823 | }; |
| 4731 | 4824 | } |
| 4732 | fn prelinkInner(elf: *Elf) !void { | |
| 4825 | fn prelinkInner(elf: *Elf) Error!void { | |
| 4733 | 4826 | const comp = elf.base.comp; |
| 4734 | 4827 | const gpa = comp.gpa; |
| 4735 | 4828 | try elf.ensureUnusedSymbolCapacity(1, .all_local); |
| ... | ... | @@ -4954,7 +5047,7 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { |
| 4954 | 5047 | entsize: std.elf.Word = 0, |
| 4955 | 5048 | node_align: std.mem.Alignment = .@"1", |
| 4956 | 5049 | fixed: bool = false, |
| 4957 | }) !Section.Index { | |
| 5050 | }) Error!Section.Index { | |
| 4958 | 5051 | switch (opts.type) { |
| 4959 | 5052 | .NULL => assert(opts.size == 0), |
| 4960 | 5053 | .PROGBITS => assert(opts.size > 0), |
| ... | ... | @@ -4996,9 +5089,7 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { |
| 4996 | 5089 | break :shndx .{ @enumFromInt(shndx), @as(u64, elf.targetLoad(&ehdr.shentsize)) * @as(u64, shnum) }; |
| 4997 | 5090 | }, |
| 4998 | 5091 | }; |
| 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); | |
| 5002 | 5093 | const ni = try elf.mf.addLastChildNode(gpa, switch (elf.ehdrField(.type)) { |
| 5003 | 5094 | .NONE, .CORE, _ => unreachable, |
| 5004 | 5095 | .REL => elf.ni.file, |
| ... | ... | @@ -5045,7 +5136,7 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { |
| 5045 | 5136 | return shndx; |
| 5046 | 5137 | } |
| 5047 | 5138 | |
| 5048 | fn ensureUnusedRelocCapacity(elf: *Elf, node: MappedFile.Node.Index, len: usize) !void { | |
| 5139 | fn ensureUnusedRelocCapacity(elf: *Elf, node: MappedFile.Node.Index, len: usize) Error!void { | |
| 5049 | 5140 | if (len == 0) return; |
| 5050 | 5141 | const gpa = elf.base.comp.gpa; |
| 5051 | 5142 | try elf.symbol_relocs.ensureUnusedCapacity(gpa, len); |
| ... | ... | @@ -5090,14 +5181,11 @@ fn ensureUnusedRelocCapacity(elf: *Elf, node: MappedFile.Node.Index, len: usize) |
| 5090 | 5181 | try elf.tls_size_symbol_relocs.ensureUnusedCapacity(gpa, len); |
| 5091 | 5182 | const new_got_entries = len * 2; // at worst, every reloc is a new TLSGD |
| 5092 | 5183 | 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); | |
| 5095 | 5184 | const need_got_size = switch (class) { |
| 5096 | 5185 | .NONE, _ => unreachable, |
| 5097 | 5186 | inline else => |ct_class| (elf.got.count() + new_got_entries) * @sizeOf(ct_class.ElfN().Addr), |
| 5098 | 5187 | }; |
| 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); | |
| 5101 | 5189 | |
| 5102 | 5190 | if (elf.shndx.dynamic != .UNDEF) { |
| 5103 | 5191 | try elf.shndx.rela_dyn.relaEnsureAdditionalCapacity(elf, new_got_entries); |
| ... | ... | @@ -5114,7 +5202,7 @@ fn addRelocAssumeCapacity( |
| 5114 | 5202 | target: Symbol.Id, |
| 5115 | 5203 | addend: i64, |
| 5116 | 5204 | @"type": MachineRelocType, |
| 5117 | ) !void { | |
| 5205 | ) Error!void { | |
| 5118 | 5206 | assert(node != .none); |
| 5119 | 5207 | switch (elf.ehdrField(.type)) { |
| 5120 | 5208 | .NONE, .CORE, _ => unreachable, |
| ... | ... | @@ -5233,7 +5321,7 @@ fn addSymbolRelocAssumeCapacity( |
| 5233 | 5321 | target: Symbol.Id, |
| 5234 | 5322 | addend: i64, |
| 5235 | 5323 | @"type": SymbolReloc.Type, |
| 5236 | ) !void { | |
| 5324 | ) Error!void { | |
| 5237 | 5325 | assert(elf.ehdrField(.type) != .REL); |
| 5238 | 5326 | |
| 5239 | 5327 | const rela_index: Section.RelaIndex.Optional = r: { |
| ... | ... | @@ -5594,7 +5682,7 @@ fn nodeWantsDsoRelocation(elf: *Elf, node: MappedFile.Node.Index) enum { yes, ye |
| 5594 | 5682 | /// global where needed---the caller does not need to do this. |
| 5595 | 5683 | /// |
| 5596 | 5684 | /// Asserts that `elf.shndx.dynamic != .UNDEF` and that `global_name` refers to an *undefined* global. |
| 5597 | fn maybeAddCopyRelocation(elf: *Elf, global_name: String(.strtab)) !bool { | |
| 5685 | fn maybeAddCopyRelocation(elf: *Elf, global_name: String(.strtab)) Error!bool { | |
| 5598 | 5686 | assert(elf.shndx.dynamic != .UNDEF); |
| 5599 | 5687 | |
| 5600 | 5688 | const gpa = elf.base.comp.gpa; |
| ... | ... | @@ -5657,16 +5745,14 @@ fn maybeAddCopyRelocation(elf: *Elf, global_name: String(.strtab)) !bool { |
| 5657 | 5745 | return true; |
| 5658 | 5746 | } |
| 5659 | 5747 | |
| 5660 | pub fn updateNav(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void { | |
| 5748 | pub fn updateNav(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) link.Error!void { | |
| 5749 | const diags = &elf.base.comp.link_diags; | |
| 5661 | 5750 | 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, | |
| 5667 | 5753 | }; |
| 5668 | 5754 | } |
| 5669 | fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void { | |
| 5755 | fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) Error!void { | |
| 5670 | 5756 | const zcu = pt.zcu; |
| 5671 | 5757 | const gpa = zcu.gpa; |
| 5672 | 5758 | const ip = &zcu.intern_pool; |
| ... | ... | @@ -5689,12 +5775,11 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) |
| 5689 | 5775 | codegen.generateSymbol( |
| 5690 | 5776 | &elf.base, |
| 5691 | 5777 | pt, |
| 5692 | zcu.navSrcLoc(nav_index), | |
| 5693 | 5778 | .fromInterned(nav.resolved.?.value), |
| 5694 | 5779 | &nw.interface, |
| 5695 | 5780 | .{ .atom_index = Node.toAtom(ni) }, |
| 5696 | 5781 | ) catch |err| switch (err) { |
| 5697 | error.WriteFailed => return error.OutOfMemory, | |
| 5782 | error.WriteFailed => return nw.err.?, | |
| 5698 | 5783 | else => |e| return e, |
| 5699 | 5784 | }; |
| 5700 | 5785 | switch (elf.symPtr(nmi.symbol(elf).index())) { |
| ... | ... | @@ -5707,18 +5792,11 @@ pub fn updateFunc( |
| 5707 | 5792 | pt: Zcu.PerThread, |
| 5708 | 5793 | func_index: InternPool.Index, |
| 5709 | 5794 | mir: *const codegen.AnyMir, |
| 5710 | ) !void { | |
| 5795 | ) link.Error!void { | |
| 5796 | const diags = &elf.base.comp.link_diags; | |
| 5711 | 5797 | 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, | |
| 5722 | 5800 | }; |
| 5723 | 5801 | } |
| 5724 | 5802 | fn updateFuncInner( |
| ... | ... | @@ -5726,7 +5804,7 @@ fn updateFuncInner( |
| 5726 | 5804 | pt: Zcu.PerThread, |
| 5727 | 5805 | func_index: InternPool.Index, |
| 5728 | 5806 | mir: *const codegen.AnyMir, |
| 5729 | ) !void { | |
| 5807 | ) Error!void { | |
| 5730 | 5808 | const zcu = pt.zcu; |
| 5731 | 5809 | const gpa = zcu.gpa; |
| 5732 | 5810 | const ip = &zcu.intern_pool; |
| ... | ... | @@ -5748,7 +5826,6 @@ fn updateFuncInner( |
| 5748 | 5826 | codegen.emitFunction( |
| 5749 | 5827 | &elf.base, |
| 5750 | 5828 | pt, |
| 5751 | zcu.navSrcLoc(func.owner_nav), | |
| 5752 | 5829 | func_index, |
| 5753 | 5830 | Node.toAtom(ni), |
| 5754 | 5831 | mir, |
| ... | ... | @@ -5763,14 +5840,14 @@ fn updateFuncInner( |
| 5763 | 5840 | } |
| 5764 | 5841 | } |
| 5765 | 5842 | |
| 5766 | pub fn updateErrorData(elf: *Elf, pt: Zcu.PerThread) !void { | |
| 5843 | pub fn updateErrorData(elf: *Elf, pt: Zcu.PerThread) link.Error!void { | |
| 5844 | const diags = &elf.base.comp.link_diags; | |
| 5767 | 5845 | elf.flushLazy(pt, .{ |
| 5768 | 5846 | .kind = .const_data, |
| 5769 | 5847 | .index = @intCast(elf.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return), |
| 5770 | 5848 | }) 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, | |
| 5774 | 5851 | }; |
| 5775 | 5852 | } |
| 5776 | 5853 | |
| ... | ... | @@ -5779,8 +5856,9 @@ pub fn flush( |
| 5779 | 5856 | arena: std.mem.Allocator, |
| 5780 | 5857 | tid: Zcu.PerThread.Id, |
| 5781 | 5858 | prog_node: std.Progress.Node, |
| 5782 | ) !void { | |
| 5859 | ) link.Error!void { | |
| 5783 | 5860 | const comp = elf.base.comp; |
| 5861 | const diags = &comp.link_diags; | |
| 5784 | 5862 | _ = arena; |
| 5785 | 5863 | _ = prog_node; |
| 5786 | 5864 | |
| ... | ... | @@ -5791,12 +5869,12 @@ pub fn flush( |
| 5791 | 5869 | any_undef = true; |
| 5792 | 5870 | comp.link_diags.addError("undefined global symbol '{s}'", .{name.slice(elf)}); |
| 5793 | 5871 | } |
| 5794 | if (any_undef) return error.LinkFailure; | |
| 5872 | if (any_undef) return error.AlreadyReported; | |
| 5795 | 5873 | } |
| 5796 | 5874 | |
| 5797 | 5875 | 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, | |
| 5800 | 5878 | }; |
| 5801 | 5879 | |
| 5802 | 5880 | while (try elf.idle(tid)) {} |
| ... | ... | @@ -5812,8 +5890,8 @@ pub fn flush( |
| 5812 | 5890 | .named => |named| named, |
| 5813 | 5891 | }; |
| 5814 | 5892 | 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, | |
| 5817 | 5895 | }; |
| 5818 | 5896 | if (elf.globalByName(sym_name_strtab) == null) break :entry 0; |
| 5819 | 5897 | break :entry Symbol.Id.global(sym_name_strtab).value(elf); |
| ... | ... | @@ -5823,11 +5901,11 @@ pub fn flush( |
| 5823 | 5901 | } |
| 5824 | 5902 | |
| 5825 | 5903 | 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, | |
| 5828 | 5906 | }; |
| 5829 | 5907 | } |
| 5830 | fn updateDynamicTextrel(elf: *Elf) !void { | |
| 5908 | fn updateDynamicTextrel(elf: *Elf) Error!void { | |
| 5831 | 5909 | if (elf.shndx.dynamic == .UNDEF) return; |
| 5832 | 5910 | const dynamic_ni = elf.shndx.dynamic.get(elf).ni; |
| 5833 | 5911 | switch (elf.shdrPtr(elf.shndx.dynamic)) { |
| ... | ... | @@ -5844,10 +5922,7 @@ fn updateDynamicTextrel(elf: *Elf) !void { |
| 5844 | 5922 | if (!has_textrel) { |
| 5845 | 5923 | // Add a DT_TEXTREL entry before the final DT_NULL entry. |
| 5846 | 5924 | 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); | |
| 5851 | 5926 | elf.targetStore(&shdr.size, new_size); |
| 5852 | 5927 | const new_entries: [][2]class.ElfN().Addr = @ptrCast(@alignCast( |
| 5853 | 5928 | dynamic_ni.slice(&elf.mf)[0..@intCast(new_size)], |
| ... | ... | @@ -5869,18 +5944,16 @@ fn updateDynamicTextrel(elf: *Elf) !void { |
| 5869 | 5944 | } |
| 5870 | 5945 | } |
| 5871 | 5946 | |
| 5872 | pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) !bool { | |
| 5947 | pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) link.Error!bool { | |
| 5873 | 5948 | const comp = elf.base.comp; |
| 5949 | const diags = &comp.link_diags; | |
| 5874 | 5950 | task: { |
| 5875 | 5951 | while (elf.pending_uavs.pop()) |umi| { |
| 5876 | 5952 | const sub_prog_node = elf.idleProgNode(tid, elf.const_prog_node, .{ .uav = umi }); |
| 5877 | 5953 | defer sub_prog_node.end(); |
| 5878 | 5954 | 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, | |
| 5884 | 5957 | }; |
| 5885 | 5958 | break :task; |
| 5886 | 5959 | } |
| ... | ... | @@ -5903,11 +5976,8 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) !bool { |
| 5903 | 5976 | ); |
| 5904 | 5977 | defer sub_prog_node.end(); |
| 5905 | 5978 | 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, | |
| 5911 | 5981 | }; |
| 5912 | 5982 | break :task; |
| 5913 | 5983 | }; |
| ... | ... | @@ -5917,18 +5987,8 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) !bool { |
| 5917 | 5987 | const sub_prog_node = elf.idleProgNode(tid, elf.input_prog_node, elf.getNode(isi.node(elf))); |
| 5918 | 5988 | defer sub_prog_node.end(); |
| 5919 | 5989 | 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, | |
| 5932 | 5992 | }; |
| 5933 | 5993 | break :task; |
| 5934 | 5994 | } |
| ... | ... | @@ -6005,10 +6065,9 @@ fn flushUav( |
| 6005 | 6065 | elf: *Elf, |
| 6006 | 6066 | pt: Zcu.PerThread, |
| 6007 | 6067 | umi: Node.UavMapIndex, |
| 6008 | ) !void { | |
| 6068 | ) Error!void { | |
| 6009 | 6069 | const comp = elf.base.comp; |
| 6010 | 6070 | const gpa = comp.gpa; |
| 6011 | const zcu = pt.zcu; | |
| 6012 | 6071 | |
| 6013 | 6072 | const uav_val = umi.uavValue(elf); |
| 6014 | 6073 | const ni = umi.symbol(elf).index().ptr(elf).node; |
| ... | ... | @@ -6017,23 +6076,14 @@ fn flushUav( |
| 6017 | 6076 | var nw: MappedFile.Node.Writer = undefined; |
| 6018 | 6077 | ni.writer(&elf.mf, gpa, &nw); |
| 6019 | 6078 | 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 | }; | |
| 6028 | 6079 | codegen.generateSymbol( |
| 6029 | 6080 | &elf.base, |
| 6030 | 6081 | pt, |
| 6031 | dummy_src_loc, | |
| 6032 | 6082 | .fromInterned(uav_val), |
| 6033 | 6083 | &nw.interface, |
| 6034 | 6084 | .{ .atom_index = Node.toAtom(ni) }, |
| 6035 | 6085 | ) catch |err| switch (err) { |
| 6036 | error.WriteFailed => return error.OutOfMemory, | |
| 6086 | error.WriteFailed => return nw.err.?, | |
| 6037 | 6087 | else => |e| return e, |
| 6038 | 6088 | }; |
| 6039 | 6089 | switch (elf.symPtr(umi.symbol(elf).index())) { |
| ... | ... | @@ -6044,7 +6094,7 @@ fn flushUav( |
| 6044 | 6094 | assert(ni.hasMoved(&elf.mf)); |
| 6045 | 6095 | } |
| 6046 | 6096 | |
| 6047 | fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void { | |
| 6097 | fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) Error!void { | |
| 6048 | 6098 | const zcu = pt.zcu; |
| 6049 | 6099 | const gpa = zcu.gpa; |
| 6050 | 6100 | |
| ... | ... | @@ -6060,44 +6110,70 @@ fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void { |
| 6060 | 6110 | var nw: MappedFile.Node.Writer = undefined; |
| 6061 | 6111 | ni.writer(&elf.mf, gpa, &nw); |
| 6062 | 6112 | defer nw.deinit(); |
| 6063 | try codegen.generateLazySymbol( | |
| 6113 | codegen.generateLazySymbol( | |
| 6064 | 6114 | &elf.base, |
| 6065 | 6115 | pt, |
| 6066 | Type.fromInterned(lazy.ty).srcLocOrNull(pt.zcu) orelse .unneeded, | |
| 6067 | 6116 | lazy, |
| 6068 | 6117 | &required_alignment, |
| 6069 | 6118 | &nw.interface, |
| 6070 | 6119 | .none, |
| 6071 | 6120 | .{ .atom_index = Node.toAtom(ni) }, |
| 6072 | ); | |
| 6121 | ) catch |err| switch (err) { | |
| 6122 | error.WriteFailed => return nw.err.?, | |
| 6123 | else => |e| return e, | |
| 6124 | }; | |
| 6073 | 6125 | switch (elf.symPtr(lmr.symbol(elf).index())) { |
| 6074 | 6126 | inline else => |sym| elf.targetStore(&sym.size, @intCast(nw.interface.end)), |
| 6075 | 6127 | } |
| 6076 | 6128 | } |
| 6077 | 6129 | |
| 6078 | fn flushInputSection(elf: *Elf, isi: InputSection.Index) !void { | |
| 6130 | fn flushInputSection(elf: *Elf, isi: InputSection.Index) Error!void { | |
| 6079 | 6131 | const file_loc = isi.fileLocation(elf); |
| 6080 | 6132 | if (file_loc.size == 0) return; |
| 6081 | 6133 | const comp = elf.base.comp; |
| 6082 | 6134 | const io = comp.io; |
| 6083 | 6135 | const gpa = comp.gpa; |
| 6136 | const diags = &comp.link_diags; | |
| 6084 | 6137 | const ii = isi.input(elf); |
| 6085 | 6138 | 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 | }; | |
| 6087 | 6143 | defer file.close(io); |
| 6088 | 6144 | 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 | }; | |
| 6090 | 6154 | var nw: MappedFile.Node.Writer = undefined; |
| 6091 | 6155 | isi.node(elf).writer(&elf.mf, gpa, &nw); |
| 6092 | 6156 | 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 | }); | |
| 6095 | 6171 | // The input section should already be considered to have moved, because it is created as moved |
| 6096 | 6172 | // and pending calls to `flushInputSection` always happen before pending calls to `flushMoved`. |
| 6097 | 6173 | assert(isi.node(elf).hasMoved(&elf.mf)); |
| 6098 | 6174 | } |
| 6099 | 6175 | |
| 6100 | fn flushFileOffset(elf: *Elf, ni: MappedFile.Node.Index) !void { | |
| 6176 | fn flushFileOffset(elf: *Elf, ni: MappedFile.Node.Index) void { | |
| 6101 | 6177 | switch (elf.getNode(ni)) { |
| 6102 | 6178 | else => unreachable, |
| 6103 | 6179 | .ehdr => assert(ni.fileLocation(&elf.mf, false).offset == 0), |
| ... | ... | @@ -6118,7 +6194,7 @@ fn flushFileOffset(elf: *Elf, ni: MappedFile.Node.Index) !void { |
| 6118 | 6194 | }, |
| 6119 | 6195 | } |
| 6120 | 6196 | 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); | |
| 6122 | 6198 | }, |
| 6123 | 6199 | .section => |shndx| switch (elf.shdrPtr(shndx)) { |
| 6124 | 6200 | inline else => |shdr| elf.targetStore(&shdr.offset, @intCast( |
| ... | ... | @@ -6128,14 +6204,14 @@ fn flushFileOffset(elf: *Elf, ni: MappedFile.Node.Index) !void { |
| 6128 | 6204 | } |
| 6129 | 6205 | } |
| 6130 | 6206 | |
| 6131 | fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) !void { | |
| 6207 | fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void { | |
| 6132 | 6208 | const trace = tracy.trace(@src()); |
| 6133 | 6209 | defer trace.end(); |
| 6134 | 6210 | switch (elf.getNode(ni)) { |
| 6135 | 6211 | .file => unreachable, |
| 6136 | .ehdr, .shdr => try elf.flushFileOffset(ni), | |
| 6212 | .ehdr, .shdr => elf.flushFileOffset(ni), | |
| 6137 | 6213 | .segment => |phndx| { |
| 6138 | try elf.flushFileOffset(ni); | |
| 6214 | elf.flushFileOffset(ni); | |
| 6139 | 6215 | switch (elf.phdrSlice()) { |
| 6140 | 6216 | inline else => |phdr| { |
| 6141 | 6217 | const ph = &phdr[phndx]; |
| ... | ... | @@ -6156,7 +6232,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) !void { |
| 6156 | 6232 | } |
| 6157 | 6233 | }, |
| 6158 | 6234 | .section => |shndx| { |
| 6159 | try elf.flushFileOffset(ni); | |
| 6235 | elf.flushFileOffset(ni); | |
| 6160 | 6236 | const addr = elf.computeNodeVAddr(ni); |
| 6161 | 6237 | const old_addr: u64, const flags: std.elf.SHF = switch (elf.shdrPtr(shndx)) { |
| 6162 | 6238 | inline else => |shdr| .{ |
| ... | ... | @@ -6293,7 +6369,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) !void { |
| 6293 | 6369 | try ni.childrenMoved(elf.base.comp.gpa, &elf.mf); |
| 6294 | 6370 | } |
| 6295 | 6371 | |
| 6296 | fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) !void { | |
| 6372 | fn flushResized(elf: *Elf, ni: MappedFile.Node.Index) std.mem.Allocator.Error!void { | |
| 6297 | 6373 | const trace = tracy.trace(@src()); |
| 6298 | 6374 | defer trace.end(); |
| 6299 | 6375 | _, const size = ni.location(&elf.mf).resolve(&elf.mf); |
| ... | ... | @@ -6486,16 +6562,11 @@ pub fn updateExports( |
| 6486 | 6562 | pt: Zcu.PerThread, |
| 6487 | 6563 | exported: Zcu.Exported, |
| 6488 | 6564 | export_indices: []const Zcu.Export.Index, |
| 6489 | ) !void { | |
| 6565 | ) link.Error!void { | |
| 6566 | const diags = &elf.base.comp.link_diags; | |
| 6490 | 6567 | 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.?}), | |
| 6499 | 6570 | }; |
| 6500 | 6571 | } |
| 6501 | 6572 | fn updateExportsInner( |
| ... | ... | @@ -6503,7 +6574,7 @@ fn updateExportsInner( |
| 6503 | 6574 | pt: Zcu.PerThread, |
| 6504 | 6575 | exported: Zcu.Exported, |
| 6505 | 6576 | export_indices: []const Zcu.Export.Index, |
| 6506 | ) !void { | |
| 6577 | ) Error!void { | |
| 6507 | 6578 | const zcu = pt.zcu; |
| 6508 | 6579 | const ip = &zcu.intern_pool; |
| 6509 | 6580 | |
| ... | ... | @@ -6543,7 +6614,7 @@ fn updateExportsInner( |
| 6543 | 6614 | .internal => @panic("TODO internal linkage"), |
| 6544 | 6615 | .strong => .strong, |
| 6545 | 6616 | .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", .{}), | |
| 6547 | 6618 | }, |
| 6548 | 6619 | .visibility = switch (@"export".opts.visibility) { |
| 6549 | 6620 | .default => .DEFAULT, |
| ... | ... | @@ -6591,10 +6662,10 @@ pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) Io.Cancelable!void { |
| 6591 | 6662 | pub fn printNode( |
| 6592 | 6663 | elf: *Elf, |
| 6593 | 6664 | tid: Zcu.PerThread.Id, |
| 6594 | w: *std.Io.Writer, | |
| 6665 | w: *Io.Writer, | |
| 6595 | 6666 | ni: MappedFile.Node.Index, |
| 6596 | 6667 | indent: usize, |
| 6597 | ) !void { | |
| 6668 | ) Io.Writer.Error!void { | |
| 6598 | 6669 | const node = elf.getNode(ni); |
| 6599 | 6670 | try w.splatByteAll(' ', indent); |
| 6600 | 6671 | try w.writeAll(@tagName(node)); |
| ... | ... | @@ -6698,3 +6769,15 @@ pub fn printNode( |
| 6698 | 6769 | try w.writeByte('\n'); |
| 6699 | 6770 | } |
| 6700 | 6771 | } |
| 6772 | ||
| 6773 | fn 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 { |
| 13 | 13 | } |
| 14 | 14 | |
| 15 | 15 | pub const Error = error{ |
| 16 | LinkFailure, | |
| 16 | AlreadyReported, | |
| 17 | 17 | UnknownCpuArch, |
| 18 | 18 | OutOfMemory, |
| 19 | 19 | }; |
src/link/Lld.zig+4-4| ... | ... | @@ -255,7 +255,7 @@ pub fn flush( |
| 255 | 255 | arena: Allocator, |
| 256 | 256 | tid: Zcu.PerThread.Id, |
| 257 | 257 | prog_node: std.Progress.Node, |
| 258 | ) link.File.FlushError!void { | |
| 258 | ) link.Error!void { | |
| 259 | 259 | dev.check(.lld_linker); |
| 260 | 260 | _ = tid; |
| 261 | 261 | |
| ... | ... | @@ -277,7 +277,7 @@ pub fn flush( |
| 277 | 277 | .wasm => wasmLink(lld, arena), |
| 278 | 278 | }; |
| 279 | 279 | result catch |err| switch (err) { |
| 280 | error.OutOfMemory, error.LinkFailure => |e| return e, | |
| 280 | error.OutOfMemory, error.AlreadyReported => |e| return e, | |
| 281 | 281 | else => |e| return lld.base.comp.link_diags.fail("failed to link with LLD: {t}", .{e}), |
| 282 | 282 | }; |
| 283 | 283 | } |
| ... | ... | @@ -1620,7 +1620,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi |
| 1620 | 1620 | const exit_code = try lldMain(arena, argv, false); |
| 1621 | 1621 | if (exit_code == 0) return; |
| 1622 | 1622 | if (comp.clang_passthrough_mode) std.process.exit(exit_code); |
| 1623 | return error.LinkFailure; | |
| 1623 | return error.AlreadyReported; | |
| 1624 | 1624 | } |
| 1625 | 1625 | |
| 1626 | 1626 | var stderr: []u8 = &.{}; |
| ... | ... | @@ -1720,7 +1720,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi |
| 1720 | 1720 | .exited => |code| if (code != 0) { |
| 1721 | 1721 | if (comp.clang_passthrough_mode) std.process.exit(code); |
| 1722 | 1722 | diags.lockAndParseLldStderr(argv[1], stderr); |
| 1723 | return error.LinkFailure; | |
| 1723 | return error.AlreadyReported; | |
| 1724 | 1724 | }, |
| 1725 | 1725 | .signal => |sig| { |
| 1726 | 1726 | if (comp.clang_passthrough_mode) std.process.abort(); |
src/link/MachO.zig+32-29| ... | ... | @@ -341,7 +341,7 @@ pub fn flush( |
| 341 | 341 | arena: Allocator, |
| 342 | 342 | tid: Zcu.PerThread.Id, |
| 343 | 343 | prog_node: std.Progress.Node, |
| 344 | ) link.File.FlushError!void { | |
| 344 | ) link.Error!void { | |
| 345 | 345 | const tracy = trace(@src()); |
| 346 | 346 | defer tracy.end(); |
| 347 | 347 | |
| ... | ... | @@ -490,7 +490,7 @@ pub fn flush( |
| 490 | 490 | } |
| 491 | 491 | }; |
| 492 | 492 | |
| 493 | if (diags.hasErrors()) return error.LinkFailure; | |
| 493 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 494 | 494 | |
| 495 | 495 | { |
| 496 | 496 | const index = @as(File.Index, @intCast(try self.files.addOne(gpa))); |
| ... | ... | @@ -504,7 +504,7 @@ pub fn flush( |
| 504 | 504 | try self.resolveSymbols(); |
| 505 | 505 | try self.convertTentativeDefsAndResolveSpecialSymbols(); |
| 506 | 506 | self.dedupLiterals() catch |err| switch (err) { |
| 507 | error.LinkFailure => |e| return e, | |
| 507 | error.AlreadyReported => |e| return e, | |
| 508 | 508 | else => |e| return diags.fail("failed to deduplicate literals: {s}", .{@errorName(e)}), |
| 509 | 509 | }; |
| 510 | 510 | |
| ... | ... | @@ -513,7 +513,7 @@ pub fn flush( |
| 513 | 513 | } |
| 514 | 514 | |
| 515 | 515 | self.checkDuplicates() catch |err| switch (err) { |
| 516 | error.HasDuplicates => return error.LinkFailure, | |
| 516 | error.HasDuplicates => return error.AlreadyReported, | |
| 517 | 517 | else => |e| return diags.fail("failed to check for duplicate symbol definitions: {s}", .{@errorName(e)}), |
| 518 | 518 | }; |
| 519 | 519 | |
| ... | ... | @@ -528,7 +528,7 @@ pub fn flush( |
| 528 | 528 | self.claimUnresolved(); |
| 529 | 529 | |
| 530 | 530 | self.scanRelocs() catch |err| switch (err) { |
| 531 | error.HasUndefinedSymbols => return error.LinkFailure, | |
| 531 | error.HasUndefinedSymbols => return error.AlreadyReported, | |
| 532 | 532 | else => |e| return diags.fail("failed to scan relocations: {s}", .{@errorName(e)}), |
| 533 | 533 | }; |
| 534 | 534 | |
| ... | ... | @@ -542,7 +542,7 @@ pub fn flush( |
| 542 | 542 | |
| 543 | 543 | try self.initSegments(); |
| 544 | 544 | self.allocateSections() catch |err| switch (err) { |
| 545 | error.LinkFailure => |e| return e, | |
| 545 | error.AlreadyReported => |e| return e, | |
| 546 | 546 | else => |e| return diags.fail("failed to allocate sections: {s}", .{@errorName(e)}), |
| 547 | 547 | }; |
| 548 | 548 | self.allocateSegments(); |
| ... | ... | @@ -558,7 +558,7 @@ pub fn flush( |
| 558 | 558 | |
| 559 | 559 | if (self.getZigObject()) |zo| { |
| 560 | 560 | zo.resolveRelocs(self) catch |err| switch (err) { |
| 561 | error.ResolveFailed => return error.LinkFailure, | |
| 561 | error.ResolveFailed => return error.AlreadyReported, | |
| 562 | 562 | else => |e| return e, |
| 563 | 563 | }; |
| 564 | 564 | } |
| ... | ... | @@ -567,7 +567,7 @@ pub fn flush( |
| 567 | 567 | try self.writeSectionsToFile(); |
| 568 | 568 | try self.allocateLinkeditSegment(); |
| 569 | 569 | self.writeLinkeditSectionsToFile() catch |err| switch (err) { |
| 570 | error.OutOfMemory, error.LinkFailure => |e| return e, | |
| 570 | error.OutOfMemory, error.AlreadyReported => |e| return e, | |
| 571 | 571 | else => |e| return diags.fail("failed to write linkedit sections to file: {t}", .{e}), |
| 572 | 572 | }; |
| 573 | 573 | |
| ... | ... | @@ -594,11 +594,11 @@ pub fn flush( |
| 594 | 594 | |
| 595 | 595 | const ncmds, const sizeofcmds, const uuid_cmd_offset = self.writeLoadCommands() catch |err| switch (err) { |
| 596 | 596 | error.WriteFailed => unreachable, |
| 597 | error.OutOfMemory, error.LinkFailure => |e| return e, | |
| 597 | error.OutOfMemory, error.AlreadyReported => |e| return e, | |
| 598 | 598 | }; |
| 599 | 599 | try self.writeHeader(ncmds, sizeofcmds); |
| 600 | 600 | 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, | |
| 602 | 602 | else => |e| return diags.fail("failed to calculate and write uuid: {s}", .{@errorName(e)}), |
| 603 | 603 | }; |
| 604 | 604 | if (self.getDebugSymbols()) |dsym| dsym.flush(self) catch |err| switch (err) { |
| ... | ... | @@ -609,7 +609,7 @@ pub fn flush( |
| 609 | 609 | // Code signing always comes last. |
| 610 | 610 | if (codesig) |*csig| { |
| 611 | 611 | self.writeCodeSignature(csig) catch |err| switch (err) { |
| 612 | error.OutOfMemory, error.LinkFailure => |e| return e, | |
| 612 | error.OutOfMemory, error.AlreadyReported => |e| return e, | |
| 613 | 613 | else => |e| return diags.fail("failed to write code signature: {s}", .{@errorName(e)}), |
| 614 | 614 | }; |
| 615 | 615 | const emit = self.base.emit; |
| ... | ... | @@ -968,7 +968,7 @@ pub fn parseInputFiles(self: *MachO) !void { |
| 968 | 968 | } |
| 969 | 969 | } |
| 970 | 970 | |
| 971 | if (diags.hasErrors()) return error.LinkFailure; | |
| 971 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 972 | 972 | } |
| 973 | 973 | |
| 974 | 974 | fn parseInputFileWorker(self: *MachO, file: File) void { |
| ... | ... | @@ -1365,7 +1365,7 @@ fn convertTentativeDefsAndResolveSpecialSymbols(self: *MachO) !void { |
| 1365 | 1365 | resolveSpecialSymbolsWorker(self, obj); |
| 1366 | 1366 | } |
| 1367 | 1367 | } |
| 1368 | if (diags.hasErrors()) return error.LinkFailure; | |
| 1368 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 1369 | 1369 | } |
| 1370 | 1370 | |
| 1371 | 1371 | fn convertTentativeDefinitionsWorker(self: *MachO, object: *Object) void { |
| ... | ... | @@ -1450,7 +1450,7 @@ fn checkDuplicates(self: *MachO) !void { |
| 1450 | 1450 | } |
| 1451 | 1451 | } |
| 1452 | 1452 | |
| 1453 | if (diags.hasErrors()) return error.LinkFailure; | |
| 1453 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 1454 | 1454 | |
| 1455 | 1455 | try self.reportDuplicates(); |
| 1456 | 1456 | } |
| ... | ... | @@ -1517,7 +1517,7 @@ fn scanRelocs(self: *MachO) !void { |
| 1517 | 1517 | } |
| 1518 | 1518 | } |
| 1519 | 1519 | |
| 1520 | if (diags.hasErrors()) return error.LinkFailure; | |
| 1520 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 1521 | 1521 | |
| 1522 | 1522 | if (self.getInternalObject()) |obj| { |
| 1523 | 1523 | try obj.checkUndefs(self); |
| ... | ... | @@ -1990,7 +1990,7 @@ fn calcSectionSizes(self: *MachO) !void { |
| 1990 | 1990 | } |
| 1991 | 1991 | } |
| 1992 | 1992 | |
| 1993 | if (diags.hasErrors()) return error.LinkFailure; | |
| 1993 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 1994 | 1994 | |
| 1995 | 1995 | try self.calcSymtabSize(); |
| 1996 | 1996 | |
| ... | ... | @@ -2527,7 +2527,7 @@ fn writeSectionsAndUpdateLinkeditSizes(self: *MachO) !void { |
| 2527 | 2527 | }; |
| 2528 | 2528 | } |
| 2529 | 2529 | |
| 2530 | if (diags.hasErrors()) return error.LinkFailure; | |
| 2530 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 2531 | 2531 | } |
| 2532 | 2532 | |
| 2533 | 2533 | fn writeAtomsWorker(self: *MachO, file: File) void { |
| ... | ... | @@ -3074,15 +3074,15 @@ pub fn updateFunc( |
| 3074 | 3074 | pt: Zcu.PerThread, |
| 3075 | 3075 | func_index: InternPool.Index, |
| 3076 | 3076 | mir: *const codegen.AnyMir, |
| 3077 | ) link.File.UpdateNavError!void { | |
| 3077 | ) link.Error!void { | |
| 3078 | 3078 | return self.getZigObject().?.updateFunc(self, pt, func_index, mir); |
| 3079 | 3079 | } |
| 3080 | 3080 | |
| 3081 | pub fn updateNav(self: *MachO, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void { | |
| 3081 | pub fn updateNav(self: *MachO, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.Error!void { | |
| 3082 | 3082 | return self.getZigObject().?.updateNav(self, pt, nav); |
| 3083 | 3083 | } |
| 3084 | 3084 | |
| 3085 | pub fn updateLineNumber(self: *MachO, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void { | |
| 3085 | pub fn updateLineNumber(self: *MachO, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) link.Error!void { | |
| 3086 | 3086 | return self.getZigObject().?.updateLineNumber(pt, ti_id); |
| 3087 | 3087 | } |
| 3088 | 3088 | |
| ... | ... | @@ -3091,7 +3091,7 @@ pub fn updateExports( |
| 3091 | 3091 | pt: Zcu.PerThread, |
| 3092 | 3092 | exported: Zcu.Exported, |
| 3093 | 3093 | export_indices: []const Zcu.Export.Index, |
| 3094 | ) link.File.UpdateExportsError!void { | |
| 3094 | ) link.Error!void { | |
| 3095 | 3095 | return self.getZigObject().?.updateExports(self, pt, exported, export_indices); |
| 3096 | 3096 | } |
| 3097 | 3097 | |
| ... | ... | @@ -3116,9 +3116,8 @@ pub fn lowerUav( |
| 3116 | 3116 | pt: Zcu.PerThread, |
| 3117 | 3117 | uav: InternPool.Index, |
| 3118 | 3118 | 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); | |
| 3122 | 3121 | } |
| 3123 | 3122 | |
| 3124 | 3123 | pub 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 |
| 3265 | 3264 | file_writer.pos = new_offset; |
| 3266 | 3265 | const size_u = math.cast(usize, size) orelse return error.Overflow; |
| 3267 | 3266 | 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 | }, | |
| 3269 | 3272 | error.WriteFailed => return file_writer.err.?, |
| 3270 | 3273 | }; |
| 3271 | 3274 | assert(n == size_u); |
| ... | ... | @@ -5373,7 +5376,7 @@ fn isReachable(atom: *const Atom, rel: Relocation, macho_file: *MachO) bool { |
| 5373 | 5376 | return true; |
| 5374 | 5377 | } |
| 5375 | 5378 | |
| 5376 | pub fn pwriteAll(macho_file: *MachO, bytes: []const u8, offset: u64) error{LinkFailure}!void { | |
| 5379 | pub fn pwriteAll(macho_file: *MachO, bytes: []const u8, offset: u64) error{AlreadyReported}!void { | |
| 5377 | 5380 | const comp = macho_file.base.comp; |
| 5378 | 5381 | const io = comp.io; |
| 5379 | 5382 | const diags = &comp.link_diags; |
| ... | ... | @@ -5381,7 +5384,7 @@ pub fn pwriteAll(macho_file: *MachO, bytes: []const u8, offset: u64) error{LinkF |
| 5381 | 5384 | return diags.fail("failed to write: {t}", .{err}); |
| 5382 | 5385 | } |
| 5383 | 5386 | |
| 5384 | pub fn setLength(macho_file: *MachO, length: u64) error{LinkFailure}!void { | |
| 5387 | pub fn setLength(macho_file: *MachO, length: u64) error{AlreadyReported}!void { | |
| 5385 | 5388 | const comp = macho_file.base.comp; |
| 5386 | 5389 | const io = comp.io; |
| 5387 | 5390 | const diags = &comp.link_diags; |
| ... | ... | @@ -5389,7 +5392,7 @@ pub fn setLength(macho_file: *MachO, length: u64) error{LinkFailure}!void { |
| 5389 | 5392 | return diags.fail("failed to set file end pos: {t}", .{err}); |
| 5390 | 5393 | } |
| 5391 | 5394 | |
| 5392 | pub fn cast(macho_file: *MachO, comptime T: type, x: anytype) error{LinkFailure}!T { | |
| 5395 | pub fn cast(macho_file: *MachO, comptime T: type, x: anytype) error{AlreadyReported}!T { | |
| 5393 | 5396 | return std.math.cast(T, x) orelse { |
| 5394 | 5397 | const comp = macho_file.base.comp; |
| 5395 | 5398 | const diags = &comp.link_diags; |
| ... | ... | @@ -5397,7 +5400,7 @@ pub fn cast(macho_file: *MachO, comptime T: type, x: anytype) error{LinkFailure} |
| 5397 | 5400 | }; |
| 5398 | 5401 | } |
| 5399 | 5402 | |
| 5400 | pub fn alignPow(macho_file: *MachO, x: u32) error{LinkFailure}!u32 { | |
| 5403 | pub fn alignPow(macho_file: *MachO, x: u32) error{AlreadyReported}!u32 { | |
| 5401 | 5404 | const result, const ov = @shlWithOverflow(@as(u32, 1), try cast(macho_file, u5, x)); |
| 5402 | 5405 | if (ov != 0) { |
| 5403 | 5406 | 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 { |
| 930 | 930 | } |
| 931 | 931 | } |
| 932 | 932 | |
| 933 | pub fn writeRelocs(self: Atom, macho_file: *MachO, code: []u8, buffer: []macho.relocation_info) error{ LinkFailure, OutOfMemory }!void { | |
| 933 | pub fn writeRelocs(self: Atom, macho_file: *MachO, code: []u8, buffer: []macho.relocation_info) error{ AlreadyReported, OutOfMemory }!void { | |
| 934 | 934 | const tracy = trace(@src()); |
| 935 | 935 | defer tracy.end(); |
| 936 | 936 |
src/link/MachO/InternalObject.zig+1-1| ... | ... | @@ -648,7 +648,7 @@ fn addSection(self: *InternalObject, allocator: Allocator, segname: []const u8, |
| 648 | 648 | return n_sect; |
| 649 | 649 | } |
| 650 | 650 | |
| 651 | fn getSectionData(self: *const InternalObject, index: u32, macho_file: *MachO) error{LinkFailure}![]const u8 { | |
| 651 | fn getSectionData(self: *const InternalObject, index: u32, macho_file: *MachO) error{AlreadyReported}![]const u8 { | |
| 652 | 652 | const slice = self.sections.slice(); |
| 653 | 653 | assert(index < slice.items(.header).len); |
| 654 | 654 | 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 { |
| 427 | 427 | } |
| 428 | 428 | } |
| 429 | 429 | |
| 430 | pub fn writeRelocs(self: *ZigObject, macho_file: *MachO) error{ LinkFailure, OutOfMemory }!void { | |
| 430 | pub fn writeRelocs(self: *ZigObject, macho_file: *MachO) error{ AlreadyReported, OutOfMemory }!void { | |
| 431 | 431 | const gpa = macho_file.base.comp.gpa; |
| 432 | 432 | const diags = &macho_file.base.comp.link_diags; |
| 433 | 433 | |
| ... | ... | @@ -555,7 +555,7 @@ pub fn getInputSection(self: ZigObject, atom: Atom, macho_file: *MachO) macho.se |
| 555 | 555 | return sect; |
| 556 | 556 | } |
| 557 | 557 | |
| 558 | pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.File.FlushError!void { | |
| 558 | pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.Error!void { | |
| 559 | 559 | const diags = &macho_file.base.comp.link_diags; |
| 560 | 560 | |
| 561 | 561 | // 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 |
| 571 | 571 | .{ .kind = .code, .ty = .anyerror_type }, |
| 572 | 572 | metadata.text_symbol_index, |
| 573 | 573 | ) catch |err| switch (err) { |
| 574 | error.OutOfMemory, error.LinkFailure => |e| return e, | |
| 574 | error.OutOfMemory, error.AlreadyReported => |e| return e, | |
| 575 | 575 | else => |e| return diags.fail("failed to update lazy symbol: {s}", .{@errorName(e)}), |
| 576 | 576 | }; |
| 577 | 577 | 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 |
| 580 | 580 | .{ .kind = .const_data, .ty = .anyerror_type }, |
| 581 | 581 | metadata.const_symbol_index, |
| 582 | 582 | ) catch |err| switch (err) { |
| 583 | error.OutOfMemory, error.LinkFailure => |e| return e, | |
| 583 | error.OutOfMemory, error.AlreadyReported => |e| return e, | |
| 584 | 584 | else => |e| return diags.fail("failed to update lazy symbol: {s}", .{@errorName(e)}), |
| 585 | 585 | }; |
| 586 | 586 | } |
| ... | ... | @@ -704,8 +704,7 @@ pub fn lowerUav( |
| 704 | 704 | pt: Zcu.PerThread, |
| 705 | 705 | uav: InternPool.Index, |
| 706 | 706 | explicit_alignment: Atom.Alignment, |
| 707 | src_loc: Zcu.LazySrcLoc, | |
| 708 | ) !codegen.SymbolResult { | |
| 707 | ) !link.File.SymbolId { | |
| 709 | 708 | const zcu = pt.zcu; |
| 710 | 709 | const gpa = zcu.gpa; |
| 711 | 710 | const val = Value.fromInterned(uav); |
| ... | ... | @@ -717,35 +716,29 @@ pub fn lowerUav( |
| 717 | 716 | const sym = self.symbols.items[metadata.symbol_index]; |
| 718 | 717 | const existing_alignment = sym.getAtom(macho_file).?.alignment; |
| 719 | 718 | if (uav_alignment.order(existing_alignment).compare(.lte)) |
| 720 | return .{ .sym_index = @enumFromInt(metadata.symbol_index) }; | |
| 719 | return @enumFromInt(metadata.symbol_index); | |
| 721 | 720 | } |
| 722 | 721 | |
| 723 | 722 | var name_buf: [32]u8 = undefined; |
| 724 | 723 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ |
| 725 | 724 | @intFromEnum(uav), |
| 726 | 725 | }) catch unreachable; |
| 727 | const res = self.lowerConst( | |
| 726 | const sym_index = self.lowerConst( | |
| 728 | 727 | macho_file, |
| 729 | 728 | pt, |
| 730 | 729 | name, |
| 731 | 730 | val, |
| 732 | 731 | uav_alignment, |
| 733 | 732 | macho_file.zig_const_sect_index.?, |
| 734 | src_loc, | |
| 735 | 733 | ) catch |err| switch (err) { |
| 736 | 734 | 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 | ), | |
| 743 | 739 | }; |
| 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; | |
| 749 | 742 | } |
| 750 | 743 | |
| 751 | 744 | fn freeNavMetadata(self: *ZigObject, macho_file: *MachO, sym_index: Symbol.Index) void { |
| ... | ... | @@ -776,7 +769,7 @@ pub fn updateFunc( |
| 776 | 769 | pt: Zcu.PerThread, |
| 777 | 770 | func_index: InternPool.Index, |
| 778 | 771 | mir: *const codegen.AnyMir, |
| 779 | ) link.File.UpdateNavError!void { | |
| 772 | ) link.Error!void { | |
| 780 | 773 | const tracy = trace(@src()); |
| 781 | 774 | defer tracy.end(); |
| 782 | 775 | |
| ... | ... | @@ -796,7 +789,6 @@ pub fn updateFunc( |
| 796 | 789 | codegen.emitFunction( |
| 797 | 790 | &macho_file.base, |
| 798 | 791 | pt, |
| 799 | zcu.navSrcLoc(func.owner_nav), | |
| 800 | 792 | func_index, |
| 801 | 793 | @enumFromInt(sym_index), |
| 802 | 794 | mir, |
| ... | ... | @@ -867,7 +859,7 @@ pub fn updateNav( |
| 867 | 859 | macho_file: *MachO, |
| 868 | 860 | pt: Zcu.PerThread, |
| 869 | 861 | nav_index: InternPool.Nav.Index, |
| 870 | ) link.File.UpdateNavError!void { | |
| 862 | ) link.Error!void { | |
| 871 | 863 | const tracy = trace(@src()); |
| 872 | 864 | defer tracy.end(); |
| 873 | 865 | |
| ... | ... | @@ -887,7 +879,7 @@ pub fn updateNav( |
| 887 | 879 | var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, @enumFromInt(sym_index)); |
| 888 | 880 | defer debug_wip_nav.deinit(); |
| 889 | 881 | 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, | |
| 891 | 883 | else => |e| return macho_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}), |
| 892 | 884 | }; |
| 893 | 885 | } |
| ... | ... | @@ -908,7 +900,6 @@ pub fn updateNav( |
| 908 | 900 | codegen.generateSymbol( |
| 909 | 901 | &macho_file.base, |
| 910 | 902 | pt, |
| 911 | zcu.navSrcLoc(nav_index), | |
| 912 | 903 | .fromInterned(nav.resolved.?.value), |
| 913 | 904 | &aw.writer, |
| 914 | 905 | .{ .atom_index = @enumFromInt(sym_index) }, |
| ... | ... | @@ -925,7 +916,7 @@ pub fn updateNav( |
| 925 | 916 | try self.updateNavCode(macho_file, pt, nav_index, sym_index, sect_index, code); |
| 926 | 917 | |
| 927 | 918 | 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, | |
| 929 | 920 | else => |e| return macho_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}), |
| 930 | 921 | }; |
| 931 | 922 | } else if (self.dwarf) |*dwarf| try dwarf.updateComptimeNav(pt, nav_index); |
| ... | ... | @@ -941,7 +932,7 @@ fn updateNavCode( |
| 941 | 932 | sym_index: Symbol.Index, |
| 942 | 933 | sect_index: u8, |
| 943 | 934 | code: []const u8, |
| 944 | ) link.File.UpdateNavError!void { | |
| 935 | ) link.Error!void { | |
| 945 | 936 | const zcu = pt.zcu; |
| 946 | 937 | const gpa = zcu.gpa; |
| 947 | 938 | const comp = zcu.comp; |
| ... | ... | @@ -1198,8 +1189,7 @@ fn lowerConst( |
| 1198 | 1189 | val: Value, |
| 1199 | 1190 | required_alignment: Atom.Alignment, |
| 1200 | 1191 | output_section_index: u8, |
| 1201 | src_loc: Zcu.LazySrcLoc, | |
| 1202 | ) !codegen.SymbolResult { | |
| 1192 | ) !link.File.SymbolId { | |
| 1203 | 1193 | const gpa = macho_file.base.comp.gpa; |
| 1204 | 1194 | |
| 1205 | 1195 | var aw: std.Io.Writer.Allocating = .init(gpa); |
| ... | ... | @@ -1211,7 +1201,6 @@ fn lowerConst( |
| 1211 | 1201 | codegen.generateSymbol( |
| 1212 | 1202 | &macho_file.base, |
| 1213 | 1203 | pt, |
| 1214 | src_loc, | |
| 1215 | 1204 | val, |
| 1216 | 1205 | &aw.writer, |
| 1217 | 1206 | .{ .atom_index = @enumFromInt(sym_index) }, |
| ... | ... | @@ -1242,7 +1231,7 @@ fn lowerConst( |
| 1242 | 1231 | const file_offset = sect.offset + atom.value; |
| 1243 | 1232 | try macho_file.pwriteAll(code, file_offset); |
| 1244 | 1233 | |
| 1245 | return .{ .sym_index = @enumFromInt(sym_index) }; | |
| 1234 | return @enumFromInt(sym_index); | |
| 1246 | 1235 | } |
| 1247 | 1236 | |
| 1248 | 1237 | pub fn updateExports( |
| ... | ... | @@ -1251,7 +1240,7 @@ pub fn updateExports( |
| 1251 | 1240 | pt: Zcu.PerThread, |
| 1252 | 1241 | exported: Zcu.Exported, |
| 1253 | 1242 | export_indices: []const Zcu.Export.Index, |
| 1254 | ) link.File.UpdateExportsError!void { | |
| 1243 | ) link.Error!void { | |
| 1255 | 1244 | const tracy = trace(@src()); |
| 1256 | 1245 | defer tracy.end(); |
| 1257 | 1246 | |
| ... | ... | @@ -1263,18 +1252,7 @@ pub fn updateExports( |
| 1263 | 1252 | break :blk self.navs.getPtr(nav).?; |
| 1264 | 1253 | }, |
| 1265 | 1254 | .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); | |
| 1278 | 1256 | break :blk self.uavs.getPtr(uav).?; |
| 1279 | 1257 | }, |
| 1280 | 1258 | }; |
| ... | ... | @@ -1368,11 +1346,9 @@ fn updateLazySymbol( |
| 1368 | 1346 | break :blk try self.addString(gpa, name); |
| 1369 | 1347 | }; |
| 1370 | 1348 | |
| 1371 | const src = Type.fromInterned(lazy_sym.ty).srcLocOrNull(zcu) orelse Zcu.LazySrcLoc.unneeded; | |
| 1372 | 1349 | try codegen.generateLazySymbol( |
| 1373 | 1350 | &macho_file.base, |
| 1374 | 1351 | pt, |
| 1375 | src, | |
| 1376 | 1352 | lazy_sym, |
| 1377 | 1353 | &required_alignment, |
| 1378 | 1354 | &aw.writer, |
| ... | ... | @@ -1413,12 +1389,12 @@ fn updateLazySymbol( |
| 1413 | 1389 | try macho_file.pwriteAll(code, file_offset); |
| 1414 | 1390 | } |
| 1415 | 1391 | |
| 1416 | pub fn updateLineNumber(self: *ZigObject, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void { | |
| 1392 | pub fn updateLineNumber(self: *ZigObject, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) link.Error!void { | |
| 1417 | 1393 | if (self.dwarf) |*dwarf| { |
| 1418 | 1394 | const comp = dwarf.bin_file.comp; |
| 1419 | 1395 | const diags = &comp.link_diags; |
| 1420 | 1396 | 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, | |
| 1422 | 1398 | else => |e| return diags.fail("failed to update dwarf line numbers: {s}", .{@errorName(e)}), |
| 1423 | 1399 | }; |
| 1424 | 1400 | } |
src/link/MachO/relocatable.zig+13-13| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Path) link.File.FlushError!void { | |
| 1 | pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Path) link.Error!void { | |
| 2 | 2 | const gpa = comp.gpa; |
| 3 | 3 | const io = comp.io; |
| 4 | 4 | const diags = &comp.link_diags; |
| ... | ... | @@ -34,15 +34,15 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat |
| 34 | 34 | diags.addParseError(link_input.path().?, "failed to read input file: {s}", .{@errorName(err)}); |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | if (diags.hasErrors()) return error.LinkFailure; | |
| 37 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 38 | 38 | |
| 39 | 39 | try macho_file.parseInputFiles(); |
| 40 | 40 | |
| 41 | if (diags.hasErrors()) return error.LinkFailure; | |
| 41 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 42 | 42 | |
| 43 | 43 | try macho_file.resolveSymbols(); |
| 44 | 44 | macho_file.dedupLiterals() catch |err| switch (err) { |
| 45 | error.OutOfMemory, error.LinkFailure => |e| return e, | |
| 45 | error.OutOfMemory, error.AlreadyReported => |e| return e, | |
| 46 | 46 | else => |e| return diags.fail("failed to update ar size: {s}", .{@errorName(e)}), |
| 47 | 47 | }; |
| 48 | 48 | markExports(macho_file); |
| ... | ... | @@ -54,7 +54,7 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat |
| 54 | 54 | |
| 55 | 55 | try createSegment(macho_file); |
| 56 | 56 | allocateSections(macho_file) catch |err| switch (err) { |
| 57 | error.LinkFailure => |e| return e, | |
| 57 | error.AlreadyReported => |e| return e, | |
| 58 | 58 | else => |e| return diags.fail("failed to allocate sections: {s}", .{@errorName(e)}), |
| 59 | 59 | }; |
| 60 | 60 | allocateSegment(macho_file); |
| ... | ... | @@ -75,7 +75,7 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat |
| 75 | 75 | try writeHeader(macho_file, ncmds, sizeofcmds); |
| 76 | 76 | } |
| 77 | 77 | |
| 78 | pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Path) link.File.FlushError!void { | |
| 78 | pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Path) link.Error!void { | |
| 79 | 79 | const gpa = comp.gpa; |
| 80 | 80 | const io = comp.io; |
| 81 | 81 | const diags = &macho_file.base.comp.link_diags; |
| ... | ... | @@ -105,11 +105,11 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ? |
| 105 | 105 | diags.addParseError(link_input.path().?, "failed to read input file: {s}", .{@errorName(err)}); |
| 106 | 106 | } |
| 107 | 107 | |
| 108 | if (diags.hasErrors()) return error.LinkFailure; | |
| 108 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 109 | 109 | |
| 110 | 110 | try parseInputFilesAr(macho_file); |
| 111 | 111 | |
| 112 | if (diags.hasErrors()) return error.LinkFailure; | |
| 112 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 113 | 113 | |
| 114 | 114 | // First, we flush relocatable object file generated with our backends. |
| 115 | 115 | if (macho_file.getZigObject()) |zo| { |
| ... | ... | @@ -231,7 +231,7 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ? |
| 231 | 231 | try macho_file.setLength(total_size); |
| 232 | 232 | try macho_file.pwriteAll(writer.buffered(), 0); |
| 233 | 233 | |
| 234 | if (diags.hasErrors()) return error.LinkFailure; | |
| 234 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 235 | 235 | } |
| 236 | 236 | |
| 237 | 237 | fn parseInputFilesAr(macho_file: *MachO) !void { |
| ... | ... | @@ -339,7 +339,7 @@ fn calcSectionSizes(macho_file: *MachO) !void { |
| 339 | 339 | } |
| 340 | 340 | try calcSymtabSize(macho_file); |
| 341 | 341 | |
| 342 | if (diags.hasErrors()) return error.LinkFailure; | |
| 342 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 343 | 343 | } |
| 344 | 344 | |
| 345 | 345 | fn calcSectionSizeWorker(macho_file: *MachO, sect_id: u8) void { |
| ... | ... | @@ -586,7 +586,7 @@ fn sortRelocs(macho_file: *MachO) void { |
| 586 | 586 | } |
| 587 | 587 | } |
| 588 | 588 | |
| 589 | fn writeSections(macho_file: *MachO) link.File.FlushError!void { | |
| 589 | fn writeSections(macho_file: *MachO) link.Error!void { | |
| 590 | 590 | const tracy = trace(@src()); |
| 591 | 591 | defer tracy.end(); |
| 592 | 592 | |
| ... | ... | @@ -632,7 +632,7 @@ fn writeSections(macho_file: *MachO) link.File.FlushError!void { |
| 632 | 632 | } |
| 633 | 633 | } |
| 634 | 634 | |
| 635 | if (diags.hasErrors()) return error.LinkFailure; | |
| 635 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 636 | 636 | |
| 637 | 637 | if (macho_file.getZigObject()) |zo| { |
| 638 | 638 | try zo.writeRelocs(macho_file); |
| ... | ... | @@ -685,7 +685,7 @@ fn writeSectionsToFile(macho_file: *MachO) !void { |
| 685 | 685 | try macho_file.pwriteAll(macho_file.strtab.items, macho_file.symtab_cmd.stroff); |
| 686 | 686 | } |
| 687 | 687 | |
| 688 | fn writeLoadCommands(macho_file: *MachO) error{ LinkFailure, OutOfMemory }!struct { usize, usize } { | |
| 688 | fn writeLoadCommands(macho_file: *MachO) error{ AlreadyReported, OutOfMemory }!struct { usize, usize } { | |
| 689 | 689 | const gpa = macho_file.base.comp.gpa; |
| 690 | 690 | const needed_size = load_commands.calcLoadCommandsSizeObject(macho_file); |
| 691 | 691 | 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; |
| 5 | 5 | const is_windows = builtin.os.tag == .windows; |
| 6 | 6 | |
| 7 | 7 | const std = @import("std"); |
| 8 | const Allocator = std.mem.Allocator; | |
| 8 | 9 | const Io = std.Io; |
| 9 | 10 | const assert = std.debug.assert; |
| 10 | 11 | const linux = std.os.linux; |
| ... | ... | @@ -24,14 +25,40 @@ large: std.ArrayList(u64), |
| 24 | 25 | updates: std.ArrayList(Node.Index), |
| 25 | 26 | update_prog_node: std.Progress.Node, |
| 26 | 27 | writers: std.SinglyLinkedList, |
| 28 | io_err: ?IoError, | |
| 27 | 29 | |
| 28 | 30 | pub const growth_factor = 4; |
| 29 | 31 | |
| 30 | pub const Error = error{ | |
| 32 | pub 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, | |
| 31 | 49 | NotFile, |
| 32 | } || Io.File.MemoryMap.CreateError || Io.File.MemoryMap.SetLengthError || Io.File.WritePositionalError; | |
| 50 | BrokenPipe, | |
| 51 | NonResizable, | |
| 52 | Unseekable, | |
| 53 | }; | |
| 54 | ||
| 55 | pub 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 | }; | |
| 33 | 60 | |
| 34 | pub fn init(file: Io.File, gpa: std.mem.Allocator, io: Io) !MappedFile { | |
| 61 | pub fn init(file: Io.File, gpa: std.mem.Allocator, io: Io) (Allocator.Error || Io.Cancelable || IoError)!MappedFile { | |
| 35 | 62 | var mf: MappedFile = .{ |
| 36 | 63 | .io = io, |
| 37 | 64 | .flags = undefined, |
| ... | ... | @@ -47,10 +74,14 @@ pub fn init(file: Io.File, gpa: std.mem.Allocator, io: Io) !MappedFile { |
| 47 | 74 | .updates = .empty, |
| 48 | 75 | .update_prog_node = .none, |
| 49 | 76 | .writers = .{}, |
| 77 | .io_err = null, | |
| 50 | 78 | }; |
| 51 | 79 | errdefer mf.deinit(gpa); |
| 52 | 80 | 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 | }; | |
| 54 | 85 | if (stat.kind != .file) return error.PathAlreadyExists; |
| 55 | 86 | break :stat .{ stat.size, @max(std.heap.pageSize(), stat.block_size) }; |
| 56 | 87 | }; |
| ... | ... | @@ -61,14 +92,16 @@ pub fn init(file: Io.File, gpa: std.mem.Allocator, io: Io) !MappedFile { |
| 61 | 92 | .fallocate_punch_hole_unsupported = false, |
| 62 | 93 | }; |
| 63 | 94 | 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)); | |
| 72 | 105 | return mf; |
| 73 | 106 | } |
| 74 | 107 | |
| ... | ... | @@ -174,7 +207,7 @@ pub const Node = extern struct { |
| 174 | 207 | return .{ .mf = mf, .ni = ni.get(mf).last }; |
| 175 | 208 | } |
| 176 | 209 | |
| 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 { | |
| 178 | 211 | var child_ni = ni.get(mf).last; |
| 179 | 212 | while (child_ni != .none) { |
| 180 | 213 | try child_ni.moved(gpa, mf); |
| ... | ... | @@ -192,7 +225,7 @@ pub const Node = extern struct { |
| 192 | 225 | } |
| 193 | 226 | return false; |
| 194 | 227 | } |
| 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 { | |
| 196 | 229 | try mf.updates.ensureUnusedCapacity(gpa, 1); |
| 197 | 230 | ni.movedAssumeCapacity(mf); |
| 198 | 231 | } |
| ... | ... | @@ -213,7 +246,7 @@ pub const Node = extern struct { |
| 213 | 246 | pub fn hasResized(ni: Node.Index, mf: *const MappedFile) bool { |
| 214 | 247 | return ni.get(mf).flags.resized; |
| 215 | 248 | } |
| 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 { | |
| 217 | 250 | try mf.updates.ensureUnusedCapacity(gpa, 1); |
| 218 | 251 | ni.resizedAssumeCapacity(mf); |
| 219 | 252 | } |
| ... | ... | @@ -296,8 +329,16 @@ pub const Node = extern struct { |
| 296 | 329 | return mf.memory_map.memory[@intCast(file_loc.offset)..][0..@intCast(file_loc.size)]; |
| 297 | 330 | } |
| 298 | 331 | |
| 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 | }; | |
| 301 | 342 | var writers_it = mf.writers.first; |
| 302 | 343 | while (writers_it) |writer_node| : (writers_it = writer_node.next) { |
| 303 | 344 | const w: *Node.Writer = @fieldParentPtr("writer_node", writer_node); |
| ... | ... | @@ -313,8 +354,16 @@ pub const Node = extern struct { |
| 313 | 354 | mf: *MappedFile, |
| 314 | 355 | gpa: std.mem.Allocator, |
| 315 | 356 | 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 | }; | |
| 318 | 367 | var writers_it = mf.writers.first; |
| 319 | 368 | while (writers_it) |writer_node| : (writers_it = writer_node.next) { |
| 320 | 369 | const w: *Node.Writer = @fieldParentPtr("writer_node", writer_node); |
| ... | ... | @@ -422,9 +471,16 @@ pub const Node = extern struct { |
| 422 | 471 | file_reader.pos, |
| 423 | 472 | w.ni.fileLocation(w.mf, true).offset + interface.end, |
| 424 | 473 | 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 | }, | |
| 428 | 484 | }); |
| 429 | 485 | if (n == 0) return error.Unimplemented; |
| 430 | 486 | file_reader.pos += n; |
| ... | ... | @@ -472,7 +528,7 @@ fn addNode(mf: *MappedFile, gpa: std.mem.Allocator, opts: struct { |
| 472 | 528 | next: Node.Index = .none, |
| 473 | 529 | offset: u64 = 0, |
| 474 | 530 | add_node: AddNodeOptions, |
| 475 | }) !Node.Index { | |
| 531 | }) Error!Node.Index { | |
| 476 | 532 | if (opts.add_node.moved or opts.add_node.resized) try mf.updates.ensureUnusedCapacity(gpa, 1); |
| 477 | 533 | const offset = opts.add_node.alignment.forward(@intCast(opts.offset)); |
| 478 | 534 | const location_tag: Node.Location.Tag, const location_payload: Node.Location.Payload = location: { |
| ... | ... | @@ -544,7 +600,7 @@ pub fn addOnlyChildNode( |
| 544 | 600 | gpa: std.mem.Allocator, |
| 545 | 601 | parent_ni: Node.Index, |
| 546 | 602 | opts: AddNodeOptions, |
| 547 | ) !Node.Index { | |
| 603 | ) Error!Node.Index { | |
| 548 | 604 | try mf.nodes.ensureUnusedCapacity(gpa, 1); |
| 549 | 605 | const parent = parent_ni.get(mf); |
| 550 | 606 | assert(parent.first == .none and parent.last == .none); |
| ... | ... | @@ -559,7 +615,7 @@ pub fn addFirstChildNode( |
| 559 | 615 | gpa: std.mem.Allocator, |
| 560 | 616 | parent_ni: Node.Index, |
| 561 | 617 | opts: AddNodeOptions, |
| 562 | ) !Node.Index { | |
| 618 | ) Error!Node.Index { | |
| 563 | 619 | try mf.nodes.ensureUnusedCapacity(gpa, 1); |
| 564 | 620 | const parent = parent_ni.get(mf); |
| 565 | 621 | return mf.addNode(gpa, .{ |
| ... | ... | @@ -574,7 +630,7 @@ pub fn addLastChildNode( |
| 574 | 630 | gpa: std.mem.Allocator, |
| 575 | 631 | parent_ni: Node.Index, |
| 576 | 632 | opts: AddNodeOptions, |
| 577 | ) !Node.Index { | |
| 633 | ) Error!Node.Index { | |
| 578 | 634 | try mf.nodes.ensureUnusedCapacity(gpa, 1); |
| 579 | 635 | const parent = parent_ni.get(mf); |
| 580 | 636 | return mf.addNode(gpa, .{ |
| ... | ... | @@ -596,7 +652,7 @@ pub fn addNodeAfter( |
| 596 | 652 | gpa: std.mem.Allocator, |
| 597 | 653 | prev_ni: Node.Index, |
| 598 | 654 | opts: AddNodeOptions, |
| 599 | ) !Node.Index { | |
| 655 | ) Error!Node.Index { | |
| 600 | 656 | assert(prev_ni != .none); |
| 601 | 657 | try mf.nodes.ensureUnusedCapacity(gpa, 1); |
| 602 | 658 | const prev = prev_ni.get(mf); |
| ... | ... | @@ -610,7 +666,7 @@ pub fn addNodeAfter( |
| 610 | 666 | }); |
| 611 | 667 | } |
| 612 | 668 | |
| 613 | fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested_size: u64) !void { | |
| 669 | fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested_size: u64) (Allocator.Error || Io.Cancelable || IoError)!void { | |
| 614 | 670 | const io = mf.io; |
| 615 | 671 | const node = ni.get(mf); |
| 616 | 672 | 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 |
| 618 | 674 | // Resize the entire file |
| 619 | 675 | if (ni == Node.Index.root) { |
| 620 | 676 | 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 | }; | |
| 622 | 682 | try mf.memory_map.file.setLength(io, new_size); |
| 623 | try mf.ensureTotalCapacity(@intCast(new_size)); | |
| 683 | try mf.ensureTotalCapacityInner(@intCast(new_size)); | |
| 624 | 684 | ni.setLocationAssumeCapacity(mf, old_offset, new_size); |
| 625 | 685 | return; |
| 626 | 686 | } |
| ... | ... | @@ -643,7 +703,11 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested |
| 643 | 703 | if (is_linux and !mf.flags.fallocate_insert_range_unsupported and |
| 644 | 704 | node.flags.alignment.order(mf.flags.block_size).compare(.gte)) |
| 645 | 705 | 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 | }; | |
| 647 | 711 | // Ask the filesystem driver to insert extents into the file without copying any data |
| 648 | 712 | const last_offset, const last_size = parent.last.location(mf).resolve(mf); |
| 649 | 713 | const last_end = last_offset + last_size; |
| ... | ... | @@ -674,7 +738,7 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested |
| 674 | 738 | enclosing_ni.setLocationAssumeCapacity(mf, enclosing_offset, new_enclosing_size); |
| 675 | 739 | if (enclosing_ni == Node.Index.root) { |
| 676 | 740 | assert(enclosing_offset == 0); |
| 677 | try mf.ensureTotalCapacity(@intCast(new_enclosing_size)); | |
| 741 | try mf.ensureTotalCapacityInner(@intCast(new_enclosing_size)); | |
| 678 | 742 | break; |
| 679 | 743 | } |
| 680 | 744 | var after_ni = enclosing.next; |
| ... | ... | @@ -865,7 +929,7 @@ fn realignNode( |
| 865 | 929 | gpa: std.mem.Allocator, |
| 866 | 930 | ni: Node.Index, |
| 867 | 931 | new_alignment: std.mem.Alignment, |
| 868 | ) !void { | |
| 932 | ) (Allocator.Error || Io.Cancelable || IoError)!void { | |
| 869 | 933 | assert(ni != Node.Index.root); // currently unsupported |
| 870 | 934 | |
| 871 | 935 | const node = ni.get(mf); |
| ... | ... | @@ -936,7 +1000,7 @@ fn realignNode( |
| 936 | 1000 | } |
| 937 | 1001 | } |
| 938 | 1002 | |
| 939 | fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size: u64) !void { | |
| 1003 | fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size: u64) (Io.Cancelable || IoError)!void { | |
| 940 | 1004 | // make a copy of this node at the new location |
| 941 | 1005 | try mf.copyRange(old_file_offset, new_file_offset, size); |
| 942 | 1006 | // 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: |
| 966 | 1030 | @memset(mf.memory_map.memory[@intCast(old_file_offset)..][0..@intCast(size)], 0); |
| 967 | 1031 | } |
| 968 | 1032 | |
| 969 | fn copyRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size: u64) !void { | |
| 1033 | fn copyRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size: u64) (Io.Cancelable || IoError)!void { | |
| 970 | 1034 | const copy_size = try mf.copyFileRange(mf.memory_map.file, old_file_offset, new_file_offset, size); |
| 971 | 1035 | if (copy_size < size) @memcpy( |
| 972 | 1036 | mf.memory_map.memory[@intCast(new_file_offset + copy_size)..][0..@intCast(size - copy_size)], |
| ... | ... | @@ -980,9 +1044,13 @@ fn copyFileRange( |
| 980 | 1044 | old_file_offset: u64, |
| 981 | 1045 | new_file_offset: u64, |
| 982 | 1046 | size: u64, |
| 983 | ) !u64 { | |
| 1047 | ) (Io.Cancelable || IoError)!u64 { | |
| 984 | 1048 | 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 | }; | |
| 986 | 1054 | var remaining_size = size; |
| 987 | 1055 | if (is_linux and !mf.flags.copy_file_range_unsupported) { |
| 988 | 1056 | var old_file_offset_mut: i64 = @intCast(old_file_offset); |
| ... | ... | @@ -1021,17 +1089,41 @@ fn copyFileRange( |
| 1021 | 1089 | return size - remaining_size; |
| 1022 | 1090 | } |
| 1023 | 1091 | |
| 1024 | fn ensureCapacityForSetLocation(mf: *MappedFile, gpa: std.mem.Allocator) !void { | |
| 1092 | fn ensureCapacityForSetLocation(mf: *MappedFile, gpa: std.mem.Allocator) Allocator.Error!void { | |
| 1025 | 1093 | try mf.large.ensureUnusedCapacity(gpa, 2); |
| 1026 | 1094 | try mf.updates.ensureUnusedCapacity(gpa, 1); |
| 1027 | 1095 | } |
| 1028 | 1096 | |
| 1029 | pub fn ensureTotalCapacity(mf: *MappedFile, new_capacity: usize) !void { | |
| 1097 | pub 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 | } | |
| 1109 | fn ensureTotalCapacityInner(mf: *MappedFile, new_capacity: usize) (Allocator.Error || Io.Cancelable || IoError)!void { | |
| 1030 | 1110 | 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); | |
| 1032 | 1112 | } |
| 1033 | 1113 | |
| 1034 | pub fn ensureTotalCapacityPrecise(mf: *MappedFile, new_capacity: usize) !void { | |
| 1114 | pub 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 | } | |
| 1126 | fn ensureTotalCapacityPreciseInner(mf: *MappedFile, new_capacity: usize) (Allocator.Error || Io.Cancelable || IoError)!void { | |
| 1035 | 1127 | if (mf.memory_map.memory.len >= new_capacity) return; |
| 1036 | 1128 | const io = mf.io; |
| 1037 | 1129 | const aligned_capacity = mf.flags.block_size.forward(new_capacity); |
| ... | ... | @@ -1047,7 +1139,11 @@ pub fn ensureTotalCapacityPrecise(mf: *MappedFile, new_capacity: usize) !void { |
| 1047 | 1139 | } |
| 1048 | 1140 | |
| 1049 | 1141 | 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 | }; | |
| 1051 | 1147 | } |
| 1052 | 1148 | |
| 1053 | 1149 | pub fn unmap(mf: *MappedFile) void { |
| ... | ... | @@ -1059,9 +1155,22 @@ pub fn unmap(mf: *MappedFile) void { |
| 1059 | 1155 | mf.memory_map.file = file; |
| 1060 | 1156 | } |
| 1061 | 1157 | |
| 1062 | pub fn flush(mf: *MappedFile) Io.File.WritePositionalError!void { | |
| 1063 | const io = mf.io; | |
| 1064 | try mf.memory_map.write(io); | |
| 1158 | pub 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 | }; | |
| 1065 | 1174 | } |
| 1066 | 1175 | |
| 1067 | 1176 | fn verify(mf: *MappedFile) void { |
src/link/Queue.zig+7-3| ... | ... | @@ -135,7 +135,7 @@ pub fn finishPrelinkQueue(q: *Queue, comp: *Compilation) Io.Cancelable!void { |
| 135 | 135 | lf.post_prelink = true; |
| 136 | 136 | } else |err| switch (err) { |
| 137 | 137 | error.OutOfMemory => comp.link_diags.setAllocFailure(), |
| 138 | error.LinkFailure => {}, | |
| 138 | error.AlreadyReported => {}, | |
| 139 | 139 | error.Canceled => |e| return e, |
| 140 | 140 | } |
| 141 | 141 | } |
| ... | ... | @@ -178,7 +178,7 @@ fn runLinkTasks(q: *Queue, comp: *Compilation) void { |
| 178 | 178 | } else |err| switch (err) { |
| 179 | 179 | error.OutOfMemory => comp.link_diags.setAllocFailure(), |
| 180 | 180 | error.Canceled => @panic("TODO"), |
| 181 | error.LinkFailure => {}, | |
| 181 | error.AlreadyReported => {}, | |
| 182 | 182 | } |
| 183 | 183 | } |
| 184 | 184 | } |
| ... | ... | @@ -205,7 +205,11 @@ fn runIdleTask(comp: *Compilation, tid: Zcu.PerThread.Id) bool { |
| 205 | 205 | comp.link_diags.setAllocFailure(); |
| 206 | 206 | break :have_more false; |
| 207 | 207 | }, |
| 208 | error.LinkFailure => false, | |
| 208 | error.AlreadyReported => false, | |
| 209 | error.Canceled => { | |
| 210 | comp.io.recancel(); | |
| 211 | return false; | |
| 212 | }, | |
| 209 | 213 | }; |
| 210 | 214 | } |
| 211 | 215 |
src/link/SpirV.zig+4-15| ... | ... | @@ -140,19 +140,8 @@ fn generate( |
| 140 | 140 | }; |
| 141 | 141 | |
| 142 | 142 | 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, | |
| 156 | 145 | }; |
| 157 | 146 | } |
| 158 | 147 | |
| ... | ... | @@ -168,7 +157,7 @@ pub fn updateFunc( |
| 168 | 157 | try linker.generate(pt, nav, air.*, liveness.*.?, true); |
| 169 | 158 | } |
| 170 | 159 | |
| 171 | pub fn updateNav(linker: *Linker, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.File.UpdateNavError!void { | |
| 160 | pub fn updateNav(linker: *Linker, pt: Zcu.PerThread, nav: InternPool.Nav.Index) link.Error!void { | |
| 172 | 161 | const ip = &pt.zcu.intern_pool; |
| 173 | 162 | log.debug("lowering nav {f}({d})", .{ ip.getNav(nav).fqn.fmt(ip), nav }); |
| 174 | 163 | try linker.generate(pt, nav, undefined, undefined, false); |
| ... | ... | @@ -231,7 +220,7 @@ pub fn flush( |
| 231 | 220 | arena: Allocator, |
| 232 | 221 | tid: Zcu.PerThread.Id, |
| 233 | 222 | prog_node: std.Progress.Node, |
| 234 | ) link.File.FlushError!void { | |
| 223 | ) link.Error!void { | |
| 235 | 224 | // The goal is to never use this because it's only needed if we need to |
| 236 | 225 | // write to InternPool, but flush is too late to be writing to the |
| 237 | 226 | // InternPool. |
src/link/Wasm.zig+19-19| ... | ... | @@ -568,7 +568,7 @@ pub const SourceLocation = enum(u32) { |
| 568 | 568 | err_msg.notes[err.note_slot - 1].source_location = .{ .wasm = sl }; |
| 569 | 569 | } |
| 570 | 570 | |
| 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} { | |
| 572 | 572 | return diags.failSourceLocation(.{ .wasm = sl }, format, args); |
| 573 | 573 | } |
| 574 | 574 | |
| ... | ... | @@ -3027,12 +3027,12 @@ fn openParseObjectReportingFailure(wasm: *Wasm, path: Path) void { |
| 3027 | 3027 | const diags = &comp.link_diags; |
| 3028 | 3028 | const obj = link.openObject(io, path, false, false) catch |err| { |
| 3029 | 3029 | switch (diags.failParse(path, "failed to open object: {t}", .{err})) { |
| 3030 | error.LinkFailure => return, | |
| 3030 | error.AlreadyReported => return, | |
| 3031 | 3031 | } |
| 3032 | 3032 | }; |
| 3033 | 3033 | wasm.parseObject(obj) catch |err| { |
| 3034 | 3034 | switch (diags.failParse(path, "failed to parse object: {t}", .{err})) { |
| 3035 | error.LinkFailure => return, | |
| 3035 | error.AlreadyReported => return, | |
| 3036 | 3036 | } |
| 3037 | 3037 | }; |
| 3038 | 3038 | } |
| ... | ... | @@ -3336,12 +3336,12 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index |
| 3336 | 3336 | } |
| 3337 | 3337 | } |
| 3338 | 3338 | |
| 3339 | pub fn updateLineNumber(wasm: *Wasm, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) !void { | |
| 3339 | pub fn updateLineNumber(wasm: *Wasm, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst.Index) link.Error!void { | |
| 3340 | 3340 | const comp = wasm.base.comp; |
| 3341 | 3341 | const diags = &comp.link_diags; |
| 3342 | 3342 | if (wasm.dwarf) |*dw| { |
| 3343 | 3343 | 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, | |
| 3345 | 3345 | else => |e| return diags.fail("failed to update dwarf line numbers: {s}", .{@errorName(e)}), |
| 3346 | 3346 | }; |
| 3347 | 3347 | } |
| ... | ... | @@ -3417,7 +3417,7 @@ pub fn loadInput(wasm: *Wasm, input: link.Input) !void { |
| 3417 | 3417 | } |
| 3418 | 3418 | } |
| 3419 | 3419 | |
| 3420 | pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.File.FlushError!void { | |
| 3420 | pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.Error!void { | |
| 3421 | 3421 | const tracy = trace(@src()); |
| 3422 | 3422 | defer tracy.end(); |
| 3423 | 3423 | |
| ... | ... | @@ -3526,7 +3526,7 @@ pub fn markFunctionImport( |
| 3526 | 3526 | name: String, |
| 3527 | 3527 | import: *FunctionImport, |
| 3528 | 3528 | func_index: FunctionImport.Index, |
| 3529 | ) link.File.FlushError!void { | |
| 3529 | ) link.Error!void { | |
| 3530 | 3530 | // import.flags.alive might be already true from a previous update. In such |
| 3531 | 3531 | // case, we must still run the logic in this function, in case the item |
| 3532 | 3532 | // being marked was reverted by the `flush` logic that resets the hash |
| ... | ... | @@ -3557,7 +3557,7 @@ pub fn markFunctionImport( |
| 3557 | 3557 | } |
| 3558 | 3558 | |
| 3559 | 3559 | /// Recursively mark alive everything referenced by the function. |
| 3560 | fn markFunction(wasm: *Wasm, i: ObjectFunctionIndex, override_export: bool) link.File.FlushError!void { | |
| 3560 | fn markFunction(wasm: *Wasm, i: ObjectFunctionIndex, override_export: bool) link.Error!void { | |
| 3561 | 3561 | const comp = wasm.base.comp; |
| 3562 | 3562 | const gpa = comp.gpa; |
| 3563 | 3563 | const gop = try wasm.functions.getOrPut(gpa, .fromObjectFunction(wasm, i)); |
| ... | ... | @@ -3590,7 +3590,7 @@ fn markGlobalImport( |
| 3590 | 3590 | name: String, |
| 3591 | 3591 | import: *GlobalImport, |
| 3592 | 3592 | global_index: GlobalImport.Index, |
| 3593 | ) link.File.FlushError!void { | |
| 3593 | ) link.Error!void { | |
| 3594 | 3594 | // import.flags.alive might be already true from a previous update. In such |
| 3595 | 3595 | // case, we must still run the logic in this function, in case the item |
| 3596 | 3596 | // being marked was reverted by the `flush` logic that resets the hash |
| ... | ... | @@ -3630,7 +3630,7 @@ fn markGlobalImport( |
| 3630 | 3630 | } |
| 3631 | 3631 | } |
| 3632 | 3632 | |
| 3633 | fn markGlobal(wasm: *Wasm, i: ObjectGlobalIndex, override_export: bool) link.File.FlushError!void { | |
| 3633 | fn markGlobal(wasm: *Wasm, i: ObjectGlobalIndex, override_export: bool) link.Error!void { | |
| 3634 | 3634 | const comp = wasm.base.comp; |
| 3635 | 3635 | const gpa = comp.gpa; |
| 3636 | 3636 | const gop = try wasm.globals.getOrPut(gpa, .fromObjectGlobal(wasm, i)); |
| ... | ... | @@ -3653,7 +3653,7 @@ fn markTableImport( |
| 3653 | 3653 | name: String, |
| 3654 | 3654 | import: *TableImport, |
| 3655 | 3655 | table_index: TableImport.Index, |
| 3656 | ) link.File.FlushError!void { | |
| 3656 | ) link.Error!void { | |
| 3657 | 3657 | if (import.flags.alive) return; |
| 3658 | 3658 | import.flags.alive = true; |
| 3659 | 3659 | |
| ... | ... | @@ -3675,7 +3675,7 @@ fn markTableImport( |
| 3675 | 3675 | } |
| 3676 | 3676 | } |
| 3677 | 3677 | |
| 3678 | fn markDataSegment(wasm: *Wasm, segment_index: ObjectDataSegment.Index) link.File.FlushError!void { | |
| 3678 | fn markDataSegment(wasm: *Wasm, segment_index: ObjectDataSegment.Index) link.Error!void { | |
| 3679 | 3679 | const comp = wasm.base.comp; |
| 3680 | 3680 | const segment = segment_index.ptr(wasm); |
| 3681 | 3681 | if (segment.flags.alive) return; |
| ... | ... | @@ -3693,7 +3693,7 @@ pub fn markDataImport( |
| 3693 | 3693 | name: String, |
| 3694 | 3694 | import: *ObjectDataImport, |
| 3695 | 3695 | data_index: ObjectDataImport.Index, |
| 3696 | ) link.File.FlushError!void { | |
| 3696 | ) link.Error!void { | |
| 3697 | 3697 | if (import.flags.alive) return; |
| 3698 | 3698 | import.flags.alive = true; |
| 3699 | 3699 | |
| ... | ... | @@ -3715,7 +3715,7 @@ pub fn markDataImport( |
| 3715 | 3715 | } |
| 3716 | 3716 | } |
| 3717 | 3717 | |
| 3718 | fn markRelocations(wasm: *Wasm, relocs: ObjectRelocation.IterableSlice) link.File.FlushError!void { | |
| 3718 | fn markRelocations(wasm: *Wasm, relocs: ObjectRelocation.IterableSlice) link.Error!void { | |
| 3719 | 3719 | const gpa = wasm.base.comp.gpa; |
| 3720 | 3720 | for (relocs.slice.tags(wasm), relocs.slice.pointees(wasm), relocs.slice.offsets(wasm)) |tag, pointee, offset| { |
| 3721 | 3721 | if (offset >= relocs.end) break; |
| ... | ... | @@ -3812,7 +3812,7 @@ fn markRelocations(wasm: *Wasm, relocs: ObjectRelocation.IterableSlice) link.Fil |
| 3812 | 3812 | } |
| 3813 | 3813 | } |
| 3814 | 3814 | |
| 3815 | fn markTable(wasm: *Wasm, i: ObjectTableIndex) link.File.FlushError!void { | |
| 3815 | fn markTable(wasm: *Wasm, i: ObjectTableIndex) link.Error!void { | |
| 3816 | 3816 | try wasm.tables.put(wasm.base.comp.gpa, .fromObjectTable(i), {}); |
| 3817 | 3817 | } |
| 3818 | 3818 | |
| ... | ... | @@ -3821,7 +3821,7 @@ pub fn flush( |
| 3821 | 3821 | arena: Allocator, |
| 3822 | 3822 | tid: Zcu.PerThread.Id, |
| 3823 | 3823 | prog_node: std.Progress.Node, |
| 3824 | ) link.File.FlushError!void { | |
| 3824 | ) link.Error!void { | |
| 3825 | 3825 | // The goal is to never use this because it's only needed if we need to |
| 3826 | 3826 | // write to InternPool, but flush is too late to be writing to the |
| 3827 | 3827 | // InternPool. |
| ... | ... | @@ -3864,7 +3864,7 @@ pub fn flush( |
| 3864 | 3864 | try wasm.flush_buffer.data_imports.reinit(gpa, wasm.data_imports.keys(), wasm.data_imports.values()); |
| 3865 | 3865 | |
| 3866 | 3866 | 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, | |
| 3868 | 3868 | else => |e| return diags.fail("failed to flush wasm: {s}", .{@errorName(e)}), |
| 3869 | 3869 | }; |
| 3870 | 3870 | } |
| ... | ... | @@ -4275,7 +4275,7 @@ fn lowerZcuData(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !Zcu |
| 4275 | 4275 | { |
| 4276 | 4276 | var aw: std.Io.Writer.Allocating = .fromArrayList(wasm.base.comp.gpa, &wasm.string_bytes); |
| 4277 | 4277 | 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) { | |
| 4279 | 4279 | error.WriteFailed => return error.OutOfMemory, |
| 4280 | 4280 | else => |e| return e, |
| 4281 | 4281 | }; |
| ... | ... | @@ -4349,7 +4349,7 @@ fn resolveFunctionSynthetic( |
| 4349 | 4349 | res: FunctionImport.Resolution, |
| 4350 | 4350 | params: []const std.wasm.Valtype, |
| 4351 | 4351 | returns: []const std.wasm.Valtype, |
| 4352 | ) link.File.FlushError!void { | |
| 4352 | ) link.Error!void { | |
| 4353 | 4353 | import.resolution = res; |
| 4354 | 4354 | wasm.functions.putAssumeCapacity(res, {}); |
| 4355 | 4355 | // 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 { |
| 274 | 274 | } |
| 275 | 275 | } |
| 276 | 276 | |
| 277 | if (diags.hasErrors()) return error.LinkFailure; | |
| 277 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 278 | 278 | |
| 279 | 279 | // Merge indirect function tables. |
| 280 | 280 | 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 { |
| 513 | 513 | if (initial_memory > std.math.maxInt(u32)) { |
| 514 | 514 | diags.addError("initial memory value {d} exceeds 32-bit address space", .{initial_memory}); |
| 515 | 515 | } |
| 516 | if (diags.hasErrors()) return error.LinkFailure; | |
| 516 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 517 | 517 | memory_ptr = initial_memory; |
| 518 | 518 | } else { |
| 519 | 519 | memory_ptr = mem.alignForward(u64, memory_ptr, std.wasm.page_size); |
| ... | ... | @@ -535,7 +535,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 535 | 535 | if (max_memory > std.math.maxInt(u32)) { |
| 536 | 536 | diags.addError("maximum memory value {d} exceeds 32-bit address space", .{max_memory}); |
| 537 | 537 | } |
| 538 | if (diags.hasErrors()) return error.LinkFailure; | |
| 538 | if (diags.hasErrors()) return error.AlreadyReported; | |
| 539 | 539 | wasm.memories.limits.max = @intCast(max_memory / page_size); |
| 540 | 540 | wasm.memories.limits.flags.has_max = true; |
| 541 | 541 | if (shared_memory) wasm.memories.limits.flags.is_shared = true; |
src/link/Wasm/Object.zig+1-1| ... | ... | @@ -1431,7 +1431,7 @@ fn parseFeatures( |
| 1431 | 1431 | bytes: []const u8, |
| 1432 | 1432 | start_pos: usize, |
| 1433 | 1433 | path: Path, |
| 1434 | ) error{ OutOfMemory, LinkFailure }!struct { Wasm.Feature.Set, usize } { | |
| 1434 | ) error{ OutOfMemory, AlreadyReported }!struct { Wasm.Feature.Set, usize } { | |
| 1435 | 1435 | const gpa = wasm.base.comp.gpa; |
| 1436 | 1436 | const diags = &wasm.base.comp.link_diags; |
| 1437 | 1437 | 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"); |
| 14 | 14 | |
| 15 | 15 | const log = std.log.scoped(.register_manager); |
| 16 | 16 | |
| 17 | pub const AllocationError = @import("codegen.zig").CodeGenError || error{OutOfRegisters}; | |
| 17 | pub const AllocationError = @import("codegen.zig").Error || error{OutOfRegisters}; | |
| 18 | 18 | |
| 19 | 19 | pub fn RegisterManager( |
| 20 | 20 | comptime Function: type, |