| 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,7 +3376,7 @@ fn flush(comp: *Compilation, arena: Allocator, tid: Zcu.PerThread.Id) (Io.Cancel |
| 3376 | .fuzz = comp.config.any_fuzz, | 3376 | .fuzz = comp.config.any_fuzz, |
| 3377 | .lto = comp.config.lto, | 3377 | .lto = comp.config.lto, |
| 3378 | }) catch |err| switch (err) { | 3378 | }) catch |err| switch (err) { |
| 3379 | error.LinkFailure => {}, // Already reported. | 3379 | error.AlreadyReported => {}, |
| 3380 | error.OutOfMemory => |e| return e, | 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,7 +3390,7 @@ fn flush(comp: *Compilation, arena: Allocator, tid: Zcu.PerThread.Id) (Io.Cancel |
| 3390 | }; | 3390 | }; |
| 3391 | // This is needed before reading the error flags. | 3391 | // This is needed before reading the error flags. |
| 3392 | lf.flush(arena, tid, comp.link_prog_node) catch |err| switch (err) { | 3392 | lf.flush(arena, tid, comp.link_prog_node) catch |err| switch (err) { |
| 3393 | error.LinkFailure => {}, // Already reported. | 3393 | error.AlreadyReported => {}, |
| 3394 | error.OutOfMemory, error.Canceled => |e| return e, | 3394 | error.OutOfMemory, error.Canceled => |e| return e, |
| 3395 | }; | 3395 | }; |
| 3396 | } | 3396 | } |
| ... | @@ -5249,7 +5249,7 @@ fn workerUpdateCObject( | ... | @@ -5249,7 +5249,7 @@ fn workerUpdateCObject( |
| 5249 | progress_node: std.Progress.Node, | 5249 | progress_node: std.Progress.Node, |
| 5250 | ) void { | 5250 | ) void { |
| 5251 | comp.updateCObject(c_object, progress_node) catch |err| switch (err) { | 5251 | comp.updateCObject(c_object, progress_node) catch |err| switch (err) { |
| 5252 | error.AnalysisFail => return, | 5252 | error.AlreadyReported => return, |
| 5253 | else => { | 5253 | else => { |
| 5254 | comp.reportRetryableCObjectError(c_object, err) catch |oom| switch (oom) { | 5254 | comp.reportRetryableCObjectError(c_object, err) catch |oom| switch (oom) { |
| 5255 | // Swallowing this error is OK because it's implied to be OOM when | 5255 | // Swallowing this error is OK because it's implied to be OOM when |
| ... | @@ -5266,7 +5266,7 @@ fn workerUpdateWin32Resource( | ... | @@ -5266,7 +5266,7 @@ fn workerUpdateWin32Resource( |
| 5266 | progress_node: std.Progress.Node, | 5266 | progress_node: std.Progress.Node, |
| 5267 | ) void { | 5267 | ) void { |
| 5268 | comp.updateWin32Resource(win32_resource, progress_node) catch |err| switch (err) { | 5268 | comp.updateWin32Resource(win32_resource, progress_node) catch |err| switch (err) { |
| 5269 | error.AnalysisFail => return, | 5269 | error.AlreadyReported => return, |
| 5270 | else => { | 5270 | else => { |
| 5271 | comp.reportRetryableWin32ResourceError(win32_resource, err) catch |oom| switch (oom) { | 5271 | comp.reportRetryableWin32ResourceError(win32_resource, err) catch |oom| switch (oom) { |
| 5272 | // Swallowing this error is OK because it's implied to be OOM when | 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,7 +5489,7 @@ fn reportRetryableCObjectError(comp: *Compilation, c_object: *CObject, err: anye |
| 5489 | c_object.status = .failure_retryable; | 5489 | c_object.status = .failure_retryable; |
| 5490 | 5490 | ||
| 5491 | switch (comp.failCObj(c_object, "{t}", .{err})) { | 5491 | switch (comp.failCObj(c_object, "{t}", .{err})) { |
| 5492 | error.AnalysisFail => return, | 5492 | error.AlreadyReported => return, |
| 5493 | else => |e| return e, | 5493 | else => |e| return e, |
| 5494 | } | 5494 | } |
| 5495 | } | 5495 | } |
| ... | @@ -6852,7 +6852,7 @@ fn failCObj( | ... | @@ -6852,7 +6852,7 @@ fn failCObj( |
| 6852 | c_object: *CObject, | 6852 | c_object: *CObject, |
| 6853 | comptime format: []const u8, | 6853 | comptime format: []const u8, |
| 6854 | args: anytype, | 6854 | args: anytype, |
| 6855 | ) error{ OutOfMemory, AnalysisFail } { | 6855 | ) error{ OutOfMemory, AlreadyReported } { |
| 6856 | @branchHint(.cold); | 6856 | @branchHint(.cold); |
| 6857 | const diag_bundle = blk: { | 6857 | const diag_bundle = blk: { |
| 6858 | const diag_bundle = try comp.gpa.create(CObject.Diag.Bundle); | 6858 | const diag_bundle = try comp.gpa.create(CObject.Diag.Bundle); |
| ... | @@ -6876,7 +6876,7 @@ fn failCObjWithOwnedDiagBundle( | ... | @@ -6876,7 +6876,7 @@ fn failCObjWithOwnedDiagBundle( |
| 6876 | comp: *Compilation, | 6876 | comp: *Compilation, |
| 6877 | c_object: *CObject, | 6877 | c_object: *CObject, |
| 6878 | diag_bundle: *CObject.Diag.Bundle, | 6878 | diag_bundle: *CObject.Diag.Bundle, |
| 6879 | ) error{ OutOfMemory, AnalysisFail } { | 6879 | ) error{ OutOfMemory, AlreadyReported } { |
| 6880 | @branchHint(.cold); | 6880 | @branchHint(.cold); |
| 6881 | assert(diag_bundle.diags.len > 0); | 6881 | assert(diag_bundle.diags.len > 0); |
| 6882 | { | 6882 | { |
| ... | @@ -6890,10 +6890,10 @@ fn failCObjWithOwnedDiagBundle( | ... | @@ -6890,10 +6890,10 @@ fn failCObjWithOwnedDiagBundle( |
| 6890 | comp.failed_c_objects.putAssumeCapacityNoClobber(c_object, diag_bundle); | 6890 | comp.failed_c_objects.putAssumeCapacityNoClobber(c_object, diag_bundle); |
| 6891 | } | 6891 | } |
| 6892 | c_object.status = .failure; | 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 | @branchHint(.cold); | 6897 | @branchHint(.cold); |
| 6898 | var bundle: ErrorBundle.Wip = undefined; | 6898 | var bundle: ErrorBundle.Wip = undefined; |
| 6899 | try bundle.init(comp.gpa); | 6899 | try bundle.init(comp.gpa); |
| ... | @@ -6920,7 +6920,7 @@ fn failWin32ResourceWithOwnedBundle( | ... | @@ -6920,7 +6920,7 @@ fn failWin32ResourceWithOwnedBundle( |
| 6920 | comp: *Compilation, | 6920 | comp: *Compilation, |
| 6921 | win32_resource: *Win32Resource, | 6921 | win32_resource: *Win32Resource, |
| 6922 | err_bundle: ErrorBundle, | 6922 | err_bundle: ErrorBundle, |
| 6923 | ) error{ OutOfMemory, AnalysisFail } { | 6923 | ) error{ OutOfMemory, AlreadyReported } { |
| 6924 | @branchHint(.cold); | 6924 | @branchHint(.cold); |
| 6925 | { | 6925 | { |
| 6926 | const io = comp.io; | 6926 | const io = comp.io; |
| ... | @@ -6929,7 +6929,7 @@ fn failWin32ResourceWithOwnedBundle( | ... | @@ -6929,7 +6929,7 @@ fn failWin32ResourceWithOwnedBundle( |
| 6929 | try comp.failed_win32_resources.putNoClobber(comp.gpa, win32_resource, err_bundle); | 6929 | try comp.failed_win32_resources.putNoClobber(comp.gpa, win32_resource, err_bundle); |
| 6930 | } | 6930 | } |
| 6931 | win32_resource.status = .failure; | 6931 | win32_resource.status = .failure; |
| 6932 | return error.AnalysisFail; | 6932 | return error.AlreadyReported; |
| 6933 | } | 6933 | } |
| 6934 | 6934 | ||
| 6935 | pub const FileExt = enum { | 6935 | pub const FileExt = enum { |
src/Zcu.zig+8-17| ... | @@ -3912,12 +3912,12 @@ pub fn getTarget(zcu: *const Zcu) *const Target { | ... | @@ -3912,12 +3912,12 @@ pub fn getTarget(zcu: *const Zcu) *const Target { |
| 3912 | pub fn handleUpdateExports( | 3912 | pub fn handleUpdateExports( |
| 3913 | zcu: *Zcu, | 3913 | zcu: *Zcu, |
| 3914 | export_indices: []const Export.Index, | 3914 | export_indices: []const Export.Index, |
| 3915 | result: link.File.UpdateExportsError!void, | 3915 | result: link.Error!void, |
| 3916 | ) Allocator.Error!void { | 3916 | ) (Allocator.Error || Io.Cancelable)!void { |
| 3917 | const gpa = zcu.gpa; | 3917 | const gpa = zcu.gpa; |
| 3918 | result catch |err| switch (err) { | 3918 | result catch |err| switch (err) { |
| 3919 | error.OutOfMemory => |e| return e, | 3919 | else => |e| return e, |
| 3920 | error.AnalysisFail => { | 3920 | error.AlreadyReported => { |
| 3921 | const export_idx = export_indices[0]; | 3921 | const export_idx = export_indices[0]; |
| 3922 | const new_export = export_idx.ptr(zcu); | 3922 | const new_export = export_idx.ptr(zcu); |
| 3923 | new_export.status = .failed_retryable; | 3923 | new_export.status = .failed_retryable; |
| ... | @@ -4688,7 +4688,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum) | ... | @@ -4688,7 +4688,7 @@ pub fn callconvSupported(zcu: *Zcu, cc: std.lang.CallingConvention) union(enum) |
| 4688 | 4688 | ||
| 4689 | pub const CodegenFailError = error{ | 4689 | pub const CodegenFailError = error{ |
| 4690 | /// Indicates the error message has been already stored at `Zcu.failed_codegen`. | 4690 | /// Indicates the error message has been already stored at `Zcu.failed_codegen`. |
| 4691 | CodegenFail, | 4691 | AlreadyReported, |
| 4692 | OutOfMemory, | 4692 | OutOfMemory, |
| 4693 | }; | 4693 | }; |
| 4694 | 4694 | ||
| ... | @@ -4713,16 +4713,7 @@ pub fn codegenFailMsg(zcu: *Zcu, nav_index: InternPool.Nav.Index, msg: *ErrorMsg | ... | @@ -4713,16 +4713,7 @@ pub fn codegenFailMsg(zcu: *Zcu, nav_index: InternPool.Nav.Index, msg: *ErrorMsg |
| 4713 | errdefer msg.deinit(gpa); | 4713 | errdefer msg.deinit(gpa); |
| 4714 | try zcu.failed_codegen.putNoClobber(gpa, nav_index, msg); | 4714 | try zcu.failed_codegen.putNoClobber(gpa, nav_index, msg); |
| 4715 | } | 4715 | } |
| 4716 | return error.CodegenFail; | 4716 | return error.AlreadyReported; |
| 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)); | ||
| 4726 | } | 4717 | } |
| 4727 | 4718 | ||
| 4728 | pub fn codegenFailType( | 4719 | pub fn codegenFailType( |
| ... | @@ -4735,7 +4726,7 @@ pub fn codegenFailType( | ... | @@ -4735,7 +4726,7 @@ pub fn codegenFailType( |
| 4735 | try zcu.failed_types.ensureUnusedCapacity(gpa, 1); | 4726 | try zcu.failed_types.ensureUnusedCapacity(gpa, 1); |
| 4736 | const msg = try Zcu.ErrorMsg.create(gpa, zcu.typeSrcLoc(ty_index), format, args); | 4727 | const msg = try Zcu.ErrorMsg.create(gpa, zcu.typeSrcLoc(ty_index), format, args); |
| 4737 | zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg); | 4728 | zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg); |
| 4738 | return error.CodegenFail; | 4729 | return error.AlreadyReported; |
| 4739 | } | 4730 | } |
| 4740 | 4731 | ||
| 4741 | pub fn codegenFailTypeMsg(zcu: *Zcu, ty_index: InternPool.Index, msg: *ErrorMsg) CodegenFailError { | 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,7 +4736,7 @@ pub fn codegenFailTypeMsg(zcu: *Zcu, ty_index: InternPool.Index, msg: *ErrorMsg) |
| 4745 | try zcu.failed_types.ensureUnusedCapacity(gpa, 1); | 4736 | try zcu.failed_types.ensureUnusedCapacity(gpa, 1); |
| 4746 | } | 4737 | } |
| 4747 | zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg); | 4738 | zcu.failed_types.putAssumeCapacityNoClobber(ty_index, msg); |
| 4748 | return error.CodegenFail; | 4739 | return error.AlreadyReported; |
| 4749 | } | 4740 | } |
| 4750 | 4741 | ||
| 4751 | /// Asserts that `zcu.multi_module_err != null`. | 4742 | /// Asserts that `zcu.multi_module_err != null`. |
src/Zcu/PerThread.zig+5-12| ... | @@ -3700,7 +3700,7 @@ fn processExportsInner( | ... | @@ -3700,7 +3700,7 @@ fn processExportsInner( |
| 3700 | exported: Zcu.Exported, | 3700 | exported: Zcu.Exported, |
| 3701 | export_indices: []const Zcu.Export.Index, | 3701 | export_indices: []const Zcu.Export.Index, |
| 3702 | skip_linker_work: bool, | 3702 | skip_linker_work: bool, |
| 3703 | ) error{OutOfMemory}!void { | 3703 | ) error{ OutOfMemory, Canceled }!void { |
| 3704 | const zcu = pt.zcu; | 3704 | const zcu = pt.zcu; |
| 3705 | const gpa = zcu.gpa; | 3705 | const gpa = zcu.gpa; |
| 3706 | const ip = &zcu.intern_pool; | 3706 | const ip = &zcu.intern_pool; |
| ... | @@ -4533,7 +4533,7 @@ pub fn runCodegen(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) Ru | ... | @@ -4533,7 +4533,7 @@ pub fn runCodegen(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) Ru |
| 4533 | return codegen_result catch |err| { | 4533 | return codegen_result catch |err| { |
| 4534 | switch (err) { | 4534 | switch (err) { |
| 4535 | error.OutOfMemory => comp.setAllocFailure(), | 4535 | error.OutOfMemory => comp.setAllocFailure(), |
| 4536 | error.CodegenFail => zcu.assertCodegenFailed(zcu.funcInfo(func_index).owner_nav), | 4536 | error.AlreadyReported => {}, |
| 4537 | error.NoLinkFile => assert(comp.bin_file == null), | 4537 | error.NoLinkFile => assert(comp.bin_file == null), |
| 4538 | error.BackendDoesNotProduceMir => switch (target_util.zigBackend( | 4538 | error.BackendDoesNotProduceMir => switch (target_util.zigBackend( |
| 4539 | &zcu.root_mod.resolved_target.result, | 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,7 +4552,7 @@ pub fn runCodegen(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) Ru |
| 4552 | fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) error{ | 4552 | fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) error{ |
| 4553 | OutOfMemory, | 4553 | OutOfMemory, |
| 4554 | Canceled, | 4554 | Canceled, |
| 4555 | CodegenFail, | 4555 | AlreadyReported, |
| 4556 | NoLinkFile, | 4556 | NoLinkFile, |
| 4557 | BackendDoesNotProduceMir, | 4557 | BackendDoesNotProduceMir, |
| 4558 | }!codegen.AnyMir { | 4558 | }!codegen.AnyMir { |
| ... | @@ -4628,19 +4628,12 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e | ... | @@ -4628,19 +4628,12 @@ fn runCodegenInner(pt: Zcu.PerThread, func_index: InternPool.Index, air: *Air) e |
| 4628 | switch (err) { | 4628 | switch (err) { |
| 4629 | error.OutOfMemory => comp.link_diags.setAllocFailure(), | 4629 | error.OutOfMemory => comp.link_diags.setAllocFailure(), |
| 4630 | } | 4630 | } |
| 4631 | return error.CodegenFail; | 4631 | return error.AlreadyReported; |
| 4632 | }; | 4632 | }; |
| 4633 | return error.BackendDoesNotProduceMir; | 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) { | 4636 | return codegen.generateFunction(lf, pt, func_index, air, &liveness); |
| 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 | }; | ||
| 4644 | } | 4637 | } |
| 4645 | 4638 | ||
| 4646 | fn printVerboseAir( | 4639 | fn printVerboseAir( |
src/codegen.zig+99-154| ... | @@ -24,10 +24,7 @@ const dev = @import("dev.zig"); | ... | @@ -24,10 +24,7 @@ const dev = @import("dev.zig"); |
| 24 | 24 | ||
| 25 | pub const aarch64 = @import("codegen/aarch64.zig"); | 25 | pub const aarch64 = @import("codegen/aarch64.zig"); |
| 26 | 26 | ||
| 27 | pub const CodeGenError = GenerateSymbolError || error{ | 27 | pub const Error = link.Error; |
| 28 | /// Indicates the error is already stored in Zcu `failed_codegen`. | ||
| 29 | CodegenFail, | ||
| 30 | }; | ||
| 31 | 28 | ||
| 32 | fn devFeatureForBackend(backend: std.lang.CompilerBackend) dev.Feature { | 29 | fn devFeatureForBackend(backend: std.lang.CompilerBackend) dev.Feature { |
| 33 | return switch (backend) { | 30 | return switch (backend) { |
| ... | @@ -141,11 +138,10 @@ pub const AnyMir = union { | ... | @@ -141,11 +138,10 @@ pub const AnyMir = union { |
| 141 | pub fn generateFunction( | 138 | pub fn generateFunction( |
| 142 | lf: *link.File, | 139 | lf: *link.File, |
| 143 | pt: Zcu.PerThread, | 140 | pt: Zcu.PerThread, |
| 144 | src_loc: Zcu.LazySrcLoc, | ||
| 145 | func_index: InternPool.Index, | 141 | func_index: InternPool.Index, |
| 146 | air: *const Air, | 142 | air: *const Air, |
| 147 | liveness: *const ?Air.Liveness, | 143 | liveness: *const ?Air.Liveness, |
| 148 | ) CodeGenError!AnyMir { | 144 | ) Error!AnyMir { |
| 149 | const zcu = pt.zcu; | 145 | const zcu = pt.zcu; |
| 150 | const func = zcu.funcInfo(func_index); | 146 | const func = zcu.funcInfo(func_index); |
| 151 | const target = &zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result; | 147 | const target = &zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result; |
| ... | @@ -160,7 +156,7 @@ pub fn generateFunction( | ... | @@ -160,7 +156,7 @@ pub fn generateFunction( |
| 160 | => |backend| { | 156 | => |backend| { |
| 161 | dev.check(devFeatureForBackend(backend)); | 157 | dev.check(devFeatureForBackend(backend)); |
| 162 | const CodeGen = importBackend(backend); | 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 | return @unionInit(AnyMir, AnyMir.tag(backend), mir); | 160 | return @unionInit(AnyMir, AnyMir.tag(backend), mir); |
| 165 | }, | 161 | }, |
| 166 | } | 162 | } |
| ... | @@ -176,13 +172,12 @@ pub fn generateFunction( | ... | @@ -176,13 +172,12 @@ pub fn generateFunction( |
| 176 | pub fn emitFunction( | 172 | pub fn emitFunction( |
| 177 | lf: *link.File, | 173 | lf: *link.File, |
| 178 | pt: Zcu.PerThread, | 174 | pt: Zcu.PerThread, |
| 179 | src_loc: Zcu.LazySrcLoc, | ||
| 180 | func_index: InternPool.Index, | 175 | func_index: InternPool.Index, |
| 181 | atom_id: link.File.AtomId, | 176 | atom_id: link.File.AtomId, |
| 182 | any_mir: *const AnyMir, | 177 | any_mir: *const AnyMir, |
| 183 | w: *std.Io.Writer, | 178 | w: *std.Io.Writer, |
| 184 | debug_output: link.File.DebugInfoOutput, | 179 | debug_output: link.File.DebugInfoOutput, |
| 185 | ) (CodeGenError || std.Io.Writer.Error)!void { | 180 | ) (Error || std.Io.Writer.Error)!void { |
| 186 | const zcu = pt.zcu; | 181 | const zcu = pt.zcu; |
| 187 | const func = zcu.funcInfo(func_index); | 182 | const func = zcu.funcInfo(func_index); |
| 188 | const target = &zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result; | 183 | const target = &zcu.navFileScope(func.owner_nav).mod.?.resolved_target.result; |
| ... | @@ -201,7 +196,7 @@ pub fn emitFunction( | ... | @@ -201,7 +196,7 @@ pub fn emitFunction( |
| 201 | => |backend| { | 196 | => |backend| { |
| 202 | dev.check(devFeatureForBackend(backend)); | 197 | dev.check(devFeatureForBackend(backend)); |
| 203 | const mir = &@field(any_mir, AnyMir.tag(backend)); | 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,12 +204,11 @@ pub fn emitFunction( |
| 209 | pub fn generateLazyFunction( | 204 | pub fn generateLazyFunction( |
| 210 | lf: *link.File, | 205 | lf: *link.File, |
| 211 | pt: Zcu.PerThread, | 206 | pt: Zcu.PerThread, |
| 212 | src_loc: Zcu.LazySrcLoc, | ||
| 213 | lazy_sym: link.File.LazySymbol, | 207 | lazy_sym: link.File.LazySymbol, |
| 214 | atom_id: link.File.AtomId, | 208 | atom_id: link.File.AtomId, |
| 215 | w: *std.Io.Writer, | 209 | w: *std.Io.Writer, |
| 216 | debug_output: link.File.DebugInfoOutput, | 210 | debug_output: link.File.DebugInfoOutput, |
| 217 | ) (CodeGenError || std.Io.Writer.Error)!void { | 211 | ) (Error || std.Io.Writer.Error)!void { |
| 218 | const zcu = pt.zcu; | 212 | const zcu = pt.zcu; |
| 219 | const target = if (Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu)) |inst_index| | 213 | const target = if (Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu)) |inst_index| |
| 220 | &zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.?.resolved_target.result | 214 | &zcu.fileByIndex(inst_index.resolveFile(&zcu.intern_pool)).mod.?.resolved_target.result |
| ... | @@ -224,7 +218,7 @@ pub fn generateLazyFunction( | ... | @@ -224,7 +218,7 @@ pub fn generateLazyFunction( |
| 224 | else => unreachable, | 218 | else => unreachable, |
| 225 | inline .stage2_riscv64, .stage2_x86_64 => |backend| { | 219 | inline .stage2_riscv64, .stage2_x86_64 => |backend| { |
| 226 | dev.check(devFeatureForBackend(backend)); | 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,14 +226,13 @@ pub fn generateLazyFunction( |
| 232 | pub fn generateLazySymbol( | 226 | pub fn generateLazySymbol( |
| 233 | bin_file: *link.File, | 227 | bin_file: *link.File, |
| 234 | pt: Zcu.PerThread, | 228 | pt: Zcu.PerThread, |
| 235 | src_loc: Zcu.LazySrcLoc, | ||
| 236 | lazy_sym: link.File.LazySymbol, | 229 | lazy_sym: link.File.LazySymbol, |
| 237 | // TODO don't use an "out" parameter like this; put it in the result instead | 230 | // TODO don't use an "out" parameter like this; put it in the result instead |
| 238 | alignment: *Alignment, | 231 | alignment: *Alignment, |
| 239 | w: *std.Io.Writer, | 232 | w: *std.Io.Writer, |
| 240 | debug_output: link.File.DebugInfoOutput, | 233 | debug_output: link.File.DebugInfoOutput, |
| 241 | reloc_parent: link.File.RelocInfo.Parent, | 234 | reloc_parent: link.File.RelocInfo.Parent, |
| 242 | ) (CodeGenError || std.Io.Writer.Error)!void { | 235 | ) (Error || std.Io.Writer.Error)!void { |
| 243 | const tracy = trace(@src()); | 236 | const tracy = trace(@src()); |
| 244 | defer tracy.end(); | 237 | defer tracy.end(); |
| 245 | tracy.addTextFmt("{t}, {f}", .{ lazy_sym.kind, Type.fromInterned(lazy_sym.ty).fmt(pt) }); | 238 | tracy.addTextFmt("{t}, {f}", .{ lazy_sym.kind, Type.fromInterned(lazy_sym.ty).fmt(pt) }); |
| ... | @@ -257,7 +250,7 @@ pub fn generateLazySymbol( | ... | @@ -257,7 +250,7 @@ pub fn generateLazySymbol( |
| 257 | 250 | ||
| 258 | if (lazy_sym.kind == .code) { | 251 | if (lazy_sym.kind == .code) { |
| 259 | alignment.* = target_util.defaultFunctionAlignment(target); | 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 | if (lazy_sym.ty == .anyerror_type) { | 256 | if (lazy_sym.ty == .anyerror_type) { |
| ... | @@ -295,22 +288,13 @@ pub fn generateLazySymbol( | ... | @@ -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 | pub fn generateSymbol( | 291 | pub fn generateSymbol( |
| 307 | bin_file: *link.File, | 292 | bin_file: *link.File, |
| 308 | pt: Zcu.PerThread, | 293 | pt: Zcu.PerThread, |
| 309 | src_loc: Zcu.LazySrcLoc, | ||
| 310 | val: Value, | 294 | val: Value, |
| 311 | w: *std.Io.Writer, | 295 | w: *std.Io.Writer, |
| 312 | reloc_parent: link.File.RelocInfo.Parent, | 296 | reloc_parent: link.File.RelocInfo.Parent, |
| 313 | ) (GenerateSymbolError || std.Io.Writer.Error)!void { | 297 | ) (Error || std.Io.Writer.Error)!void { |
| 314 | const tracy = trace(@src()); | 298 | const tracy = trace(@src()); |
| 315 | defer tracy.end(); | 299 | defer tracy.end(); |
| 316 | 300 | ||
| ... | @@ -323,8 +307,11 @@ pub fn generateSymbol( | ... | @@ -323,8 +307,11 @@ pub fn generateSymbol( |
| 323 | 307 | ||
| 324 | log.debug("generateSymbol: val = {f}", .{val.fmtValue(pt)}); | 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 | if (val.isUndef(zcu)) { | 314 | if (val.isUndef(zcu)) { |
| 327 | const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; | ||
| 328 | try w.splatByteAll(0xaa, abi_size); | 315 | try w.splatByteAll(0xaa, abi_size); |
| 329 | return; | 316 | return; |
| 330 | } | 317 | } |
| ... | @@ -364,7 +351,6 @@ pub fn generateSymbol( | ... | @@ -364,7 +351,6 @@ pub fn generateSymbol( |
| 364 | .enum_literal, | 351 | .enum_literal, |
| 365 | => unreachable, // non-runtime values | 352 | => unreachable, // non-runtime values |
| 366 | .int => { | 353 | .int => { |
| 367 | const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; | ||
| 368 | var space: Value.BigIntSpace = undefined; | 354 | var space: Value.BigIntSpace = undefined; |
| 369 | const int_val = val.toBigInt(&space, zcu); | 355 | const int_val = val.toBigInt(&space, zcu); |
| 370 | int_val.writeTwosComplement(try w.writableSlice(abi_size), endian); | 356 | int_val.writeTwosComplement(try w.writableSlice(abi_size), endian); |
| ... | @@ -397,13 +383,13 @@ pub fn generateSymbol( | ... | @@ -397,13 +383,13 @@ pub fn generateSymbol( |
| 397 | // emit payload part of the error union | 383 | // emit payload part of the error union |
| 398 | { | 384 | { |
| 399 | const begin = w.end; | 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 | .err_name => try pt.intern(.{ .undef = payload_ty.toIntern() }), | 387 | .err_name => try pt.intern(.{ .undef = payload_ty.toIntern() }), |
| 402 | .payload => |payload| payload, | 388 | .payload => |payload| payload, |
| 403 | }), w, reloc_parent); | 389 | }), w, reloc_parent); |
| 404 | const unpadded_end = w.end - begin; | 390 | const unpadded_end = w.end - begin; |
| 405 | const padded_end = abi_align.forward(unpadded_end); | 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 | if (padding > 0) { | 394 | if (padding > 0) { |
| 409 | try w.splatByteAll(0, padding); | 395 | try w.splatByteAll(0, padding); |
| ... | @@ -416,7 +402,7 @@ pub fn generateSymbol( | ... | @@ -416,7 +402,7 @@ pub fn generateSymbol( |
| 416 | try w.writeInt(u16, err_val, endian); | 402 | try w.writeInt(u16, err_val, endian); |
| 417 | const unpadded_end = w.end - begin; | 403 | const unpadded_end = w.end - begin; |
| 418 | const padded_end = abi_align.forward(unpadded_end); | 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 | if (padding > 0) { | 407 | if (padding > 0) { |
| 422 | try w.splatByteAll(0, padding); | 408 | try w.splatByteAll(0, padding); |
| ... | @@ -425,7 +411,7 @@ pub fn generateSymbol( | ... | @@ -425,7 +411,7 @@ pub fn generateSymbol( |
| 425 | }, | 411 | }, |
| 426 | .enum_tag => |enum_tag| { | 412 | .enum_tag => |enum_tag| { |
| 427 | const int_tag_ty = ty.intTagType(zcu); | 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 | .float => |float| storage: switch (float.storage) { | 416 | .float => |float| storage: switch (float.storage) { |
| 431 | .f16 => |f16_val| try w.writeInt(u16, @bitCast(f16_val), endian), | 417 | .f16 => |f16_val| try w.writeInt(u16, @bitCast(f16_val), endian), |
| ... | @@ -433,7 +419,6 @@ pub fn generateSymbol( | ... | @@ -433,7 +419,6 @@ pub fn generateSymbol( |
| 433 | .f64 => |f64_val| try w.writeInt(u64, @bitCast(f64_val), endian), | 419 | .f64 => |f64_val| try w.writeInt(u64, @bitCast(f64_val), endian), |
| 434 | .f80 => |f80_val| { | 420 | .f80 => |f80_val| { |
| 435 | try w.writeInt(u80, @bitCast(f80_val), endian); | 421 | try w.writeInt(u80, @bitCast(f80_val), endian); |
| 436 | const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; | ||
| 437 | try w.splatByteAll(0, abi_size - 10); | 422 | try w.splatByteAll(0, abi_size - 10); |
| 438 | }, | 423 | }, |
| 439 | .f128 => |f128_val| switch (Type.fromInterned(float.ty).floatBits(target)) { | 424 | .f128 => |f128_val| switch (Type.fromInterned(float.ty).floatBits(target)) { |
| ... | @@ -444,29 +429,28 @@ pub fn generateSymbol( | ... | @@ -444,29 +429,28 @@ pub fn generateSymbol( |
| 444 | 128 => try w.writeInt(u128, @bitCast(f128_val), endian), | 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 | .slice => |slice| { | 433 | .slice => |slice| { |
| 449 | try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), w, reloc_parent); | 434 | try generateSymbol(bin_file, pt, Value.fromInterned(slice.ptr), w, reloc_parent); |
| 450 | try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), w, reloc_parent); | 435 | try generateSymbol(bin_file, pt, Value.fromInterned(slice.len), w, reloc_parent); |
| 451 | }, | 436 | }, |
| 452 | .opt => { | 437 | .opt => { |
| 453 | const payload_type = ty.optionalChild(zcu); | 438 | const payload_type = ty.optionalChild(zcu); |
| 454 | const payload_val = val.optionalValue(zcu); | 439 | const payload_val = val.optionalValue(zcu); |
| 455 | const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; | ||
| 456 | 440 | ||
| 457 | if (ty.optionalReprIsPayload(zcu)) { | 441 | if (ty.optionalReprIsPayload(zcu)) { |
| 458 | if (payload_val) |value| { | 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 | } else { | 444 | } else { |
| 461 | try w.splatByteAll(0, abi_size); | 445 | try w.splatByteAll(0, abi_size); |
| 462 | } | 446 | } |
| 463 | } else { | 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 | if (payload_type.hasRuntimeBits(zcu)) { | 449 | if (payload_type.hasRuntimeBits(zcu)) { |
| 466 | const value = payload_val orelse Value.fromInterned(try pt.intern(.{ | 450 | const value = payload_val orelse Value.fromInterned(try pt.intern(.{ |
| 467 | .undef = payload_type.toIntern(), | 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 | try w.writeByte(@intFromBool(payload_val != null)); | 455 | try w.writeByte(@intFromBool(payload_val != null)); |
| 472 | try w.splatByteAll(0, padding); | 456 | try w.splatByteAll(0, padding); |
| ... | @@ -478,7 +462,7 @@ pub fn generateSymbol( | ... | @@ -478,7 +462,7 @@ pub fn generateSymbol( |
| 478 | .elems, .repeated_elem => { | 462 | .elems, .repeated_elem => { |
| 479 | var index: u64 = 0; | 463 | var index: u64 = 0; |
| 480 | while (index < array_type.lenIncludingSentinel()) : (index += 1) { | 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 | .bytes => unreachable, | 466 | .bytes => unreachable, |
| 483 | .elems => |elems| elems[@intCast(index)], | 467 | .elems => |elems| elems[@intCast(index)], |
| 484 | .repeated_elem => |elem| if (index < array_type.len) | 468 | .repeated_elem => |elem| if (index < array_type.len) |
| ... | @@ -490,7 +474,6 @@ pub fn generateSymbol( | ... | @@ -490,7 +474,6 @@ pub fn generateSymbol( |
| 490 | }, | 474 | }, |
| 491 | }, | 475 | }, |
| 492 | .vector_type => |vector_type| { | 476 | .vector_type => |vector_type| { |
| 493 | const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; | ||
| 494 | const vector_bool_bitpacked = switch (zcu.comp.getZigBackend()) { | 477 | const vector_bool_bitpacked = switch (zcu.comp.getZigBackend()) { |
| 495 | .stage2_wasm => false, | 478 | .stage2_wasm => false, |
| 496 | else => true, | 479 | else => true, |
| ... | @@ -499,7 +482,9 @@ pub fn generateSymbol( | ... | @@ -499,7 +482,9 @@ pub fn generateSymbol( |
| 499 | const bytes = try w.writableSlice(abi_size); | 482 | const bytes = try w.writableSlice(abi_size); |
| 500 | @memset(bytes, 0xaa); | 483 | @memset(bytes, 0xaa); |
| 501 | var index: usize = 0; | 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 | while (index < len) : (index += 1) { | 488 | while (index < len) : (index += 1) { |
| 504 | const bit_index = switch (endian) { | 489 | const bit_index = switch (endian) { |
| 505 | .big => len - 1 - index, | 490 | .big => len - 1 - index, |
| ... | @@ -539,18 +524,16 @@ pub fn generateSymbol( | ... | @@ -539,18 +524,16 @@ pub fn generateSymbol( |
| 539 | .elems, .repeated_elem => { | 524 | .elems, .repeated_elem => { |
| 540 | var index: u64 = 0; | 525 | var index: u64 = 0; |
| 541 | while (index < vector_type.len) : (index += 1) { | 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 | .bytes => unreachable, | 528 | .bytes => unreachable, |
| 544 | .elems => |elems| elems[math.cast(usize, index) orelse return error.Overflow], | 529 | .elems => |elems| elems[@intCast(index)], |
| 545 | .repeated_elem => |elem| elem, | 530 | .repeated_elem => |elem| elem, |
| 546 | }), w, reloc_parent); | 531 | }), w, reloc_parent); |
| 547 | } | 532 | } |
| 548 | }, | 533 | }, |
| 549 | } | 534 | } |
| 550 | 535 | ||
| 551 | const padding = abi_size - | 536 | const padding = abi_size - @as(usize, @intCast(Type.fromInterned(vector_type.child).abiSize(zcu) * vector_type.len)); |
| 552 | (math.cast(usize, Type.fromInterned(vector_type.child).abiSize(zcu) * vector_type.len) orelse | ||
| 553 | return error.Overflow); | ||
| 554 | if (padding > 0) try w.splatByteAll(0, padding); | 537 | if (padding > 0) try w.splatByteAll(0, padding); |
| 555 | } | 538 | } |
| 556 | }, | 539 | }, |
| ... | @@ -560,10 +543,9 @@ pub fn generateSymbol( | ... | @@ -560,10 +543,9 @@ pub fn generateSymbol( |
| 560 | if (field_val != .none) continue; | 543 | if (field_val != .none) continue; |
| 561 | if (!Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue; | 544 | if (!Type.fromInterned(field_ty).hasRuntimeBits(zcu)) continue; |
| 562 | 545 | ||
| 563 | try w.splatByteAll(0, math.cast(usize, struct_begin + | 546 | try w.splatByteAll(0, @intCast(struct_begin + |
| 564 | Type.fromInterned(field_ty).abiAlignment(zcu).forward(w.end - struct_begin) - w.end) orelse | 547 | Type.fromInterned(field_ty).abiAlignment(zcu).forward(w.end - struct_begin) - w.end)); |
| 565 | return error.Overflow); | 548 | try generateSymbol(bin_file, pt, .fromInterned(switch (aggregate.storage) { |
| 566 | try generateSymbol(bin_file, pt, src_loc, .fromInterned(switch (aggregate.storage) { | ||
| 567 | .bytes => |bytes| try pt.intern(.{ .int = .{ | 549 | .bytes => |bytes| try pt.intern(.{ .int = .{ |
| 568 | .ty = field_ty, | 550 | .ty = field_ty, |
| 569 | .storage = .{ .u64 = bytes.at(field_index, ip) }, | 551 | .storage = .{ .u64 = bytes.at(field_index, ip) }, |
| ... | @@ -572,8 +554,7 @@ pub fn generateSymbol( | ... | @@ -572,8 +554,7 @@ pub fn generateSymbol( |
| 572 | .repeated_elem => |elem| elem, | 554 | .repeated_elem => |elem| elem, |
| 573 | }), w, reloc_parent); | 555 | }), w, reloc_parent); |
| 574 | } | 556 | } |
| 575 | try w.splatByteAll(0, math.cast(usize, struct_begin + ty.abiSize(zcu) - w.end) orelse | 557 | try w.splatByteAll(0, @intCast(struct_begin + ty.abiSize(zcu) - w.end)); |
| 576 | return error.Overflow); | ||
| 577 | }, | 558 | }, |
| 578 | .struct_type => { | 559 | .struct_type => { |
| 579 | const struct_type = ip.loadStructType(ty.toIntern()); | 560 | const struct_type = ip.loadStructType(ty.toIntern()); |
| ... | @@ -598,20 +579,15 @@ pub fn generateSymbol( | ... | @@ -598,20 +579,15 @@ pub fn generateSymbol( |
| 598 | .repeated_elem => |elem| elem, | 579 | .repeated_elem => |elem| elem, |
| 599 | }; | 580 | }; |
| 600 | 581 | ||
| 601 | const padding = math.cast( | 582 | const padding: usize = @intCast(offsets[field_index] - (w.end - struct_begin)); |
| 602 | usize, | ||
| 603 | offsets[field_index] - (w.end - struct_begin), | ||
| 604 | ) orelse return error.Overflow; | ||
| 605 | if (padding > 0) try w.splatByteAll(0, padding); | 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 | assert(struct_type.alignment.check(struct_type.size)); | 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 { | 590 | const padding: usize = @intCast(struct_type.size - (w.end - struct_begin)); |
| 613 | return error.Overflow; | ||
| 614 | }; | ||
| 615 | if (padding > 0) try w.splatByteAll(0, padding); | 591 | if (padding > 0) try w.splatByteAll(0, padding); |
| 616 | }, | 592 | }, |
| 617 | } | 593 | } |
| ... | @@ -622,12 +598,12 @@ pub fn generateSymbol( | ... | @@ -622,12 +598,12 @@ pub fn generateSymbol( |
| 622 | const layout = ty.unionGetLayout(zcu); | 598 | const layout = ty.unionGetLayout(zcu); |
| 623 | 599 | ||
| 624 | if (layout.payload_size == 0) { | 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 | // Check if we should store the tag first. | 604 | // Check if we should store the tag first. |
| 629 | if (layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) { | 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 | const union_obj = zcu.typeToUnion(ty).?; | 609 | const union_obj = zcu.typeToUnion(ty).?; |
| ... | @@ -635,28 +611,28 @@ pub fn generateSymbol( | ... | @@ -635,28 +611,28 @@ pub fn generateSymbol( |
| 635 | const field_index = ty.unionTagFieldIndex(Value.fromInterned(un.tag), zcu).?; | 611 | const field_index = ty.unionTagFieldIndex(Value.fromInterned(un.tag), zcu).?; |
| 636 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); | 612 | const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]); |
| 637 | if (!field_ty.hasRuntimeBits(zcu)) { | 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 | } else { | 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 | if (padding > 0) { | 619 | if (padding > 0) { |
| 644 | try w.splatByteAll(0, padding); | 620 | try w.splatByteAll(0, padding); |
| 645 | } | 621 | } |
| 646 | } | 622 | } |
| 647 | } else { | 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 | if (layout.tag_size > 0 and layout.tag_align.compare(.lt, layout.payload_align)) { | 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 | if (layout.padding > 0) { | 630 | if (layout.padding > 0) { |
| 655 | try w.splatByteAll(0, layout.padding); | 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 | .memoized_call => unreachable, | 636 | .memoized_call => unreachable, |
| 661 | } | 637 | } |
| 662 | } | 638 | } |
| ... | @@ -664,23 +640,21 @@ pub fn generateSymbol( | ... | @@ -664,23 +640,21 @@ pub fn generateSymbol( |
| 664 | fn lowerPtr( | 640 | fn lowerPtr( |
| 665 | bin_file: *link.File, | 641 | bin_file: *link.File, |
| 666 | pt: Zcu.PerThread, | 642 | pt: Zcu.PerThread, |
| 667 | src_loc: Zcu.LazySrcLoc, | ||
| 668 | ptr_val: InternPool.Index, | 643 | ptr_val: InternPool.Index, |
| 669 | w: *std.Io.Writer, | 644 | w: *std.Io.Writer, |
| 670 | reloc_parent: link.File.RelocInfo.Parent, | 645 | reloc_parent: link.File.RelocInfo.Parent, |
| 671 | prev_offset: u64, | 646 | prev_offset: u64, |
| 672 | ) (GenerateSymbolError || std.Io.Writer.Error)!void { | 647 | ) (Error || std.Io.Writer.Error)!void { |
| 673 | const zcu = pt.zcu; | 648 | const zcu = pt.zcu; |
| 674 | const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; | 649 | const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; |
| 675 | const offset: u64 = prev_offset + ptr.byte_offset; | 650 | const offset: u64 = prev_offset + ptr.byte_offset; |
| 676 | return switch (ptr.base_addr) { | 651 | return switch (ptr.base_addr) { |
| 677 | .nav => |nav| try lowerNavRef(bin_file, pt, nav, w, reloc_parent, offset), | 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), | 653 | .uav => |uav| try lowerUavRef(bin_file, pt, uav, w, reloc_parent, offset), |
| 679 | .int => try generateSymbol(bin_file, pt, src_loc, try pt.intValue(Type.usize, offset), w, reloc_parent), | 654 | .int => try generateSymbol(bin_file, pt, try pt.intValue(Type.usize, offset), w, reloc_parent), |
| 680 | .eu_payload => |eu_ptr| try lowerPtr( | 655 | .eu_payload => |eu_ptr| try lowerPtr( |
| 681 | bin_file, | 656 | bin_file, |
| 682 | pt, | 657 | pt, |
| 683 | src_loc, | ||
| 684 | eu_ptr, | 658 | eu_ptr, |
| 685 | w, | 659 | w, |
| 686 | reloc_parent, | 660 | reloc_parent, |
| ... | @@ -689,7 +663,7 @@ fn lowerPtr( | ... | @@ -689,7 +663,7 @@ fn lowerPtr( |
| 689 | zcu, | 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 | .field => |field| { | 667 | .field => |field| { |
| 694 | const base_ptr = Value.fromInterned(field.base); | 668 | const base_ptr = Value.fromInterned(field.base); |
| 695 | const base_ty = base_ptr.typeOf(zcu).childType(zcu); | 669 | const base_ty = base_ptr.typeOf(zcu).childType(zcu); |
| ... | @@ -708,13 +682,13 @@ fn lowerPtr( | ... | @@ -708,13 +682,13 @@ fn lowerPtr( |
| 708 | }, | 682 | }, |
| 709 | else => unreachable, | 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 | .arr_elem => |arr_elem| { | 687 | .arr_elem => |arr_elem| { |
| 714 | const base_ptr_ty = Value.fromInterned(arr_elem.base).typeOf(zcu); | 688 | const base_ptr_ty = Value.fromInterned(arr_elem.base).typeOf(zcu); |
| 715 | assert(base_ptr_ty.ptrSize(zcu) == .many); | 689 | assert(base_ptr_ty.ptrSize(zcu) == .many); |
| 716 | const elem_size = base_ptr_ty.childType(zcu).abiSize(zcu); | 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 | .comptime_alloc => unreachable, | 693 | .comptime_alloc => unreachable, |
| 720 | .comptime_field => unreachable, | 694 | .comptime_field => unreachable, |
| ... | @@ -724,12 +698,11 @@ fn lowerPtr( | ... | @@ -724,12 +698,11 @@ fn lowerPtr( |
| 724 | fn lowerUavRef( | 698 | fn lowerUavRef( |
| 725 | lf: *link.File, | 699 | lf: *link.File, |
| 726 | pt: Zcu.PerThread, | 700 | pt: Zcu.PerThread, |
| 727 | src_loc: Zcu.LazySrcLoc, | ||
| 728 | uav: InternPool.Key.Ptr.BaseAddr.Uav, | 701 | uav: InternPool.Key.Ptr.BaseAddr.Uav, |
| 729 | w: *std.Io.Writer, | 702 | w: *std.Io.Writer, |
| 730 | reloc_parent: link.File.RelocInfo.Parent, | 703 | reloc_parent: link.File.RelocInfo.Parent, |
| 731 | offset: u64, | 704 | offset: u64, |
| 732 | ) (GenerateSymbolError || std.Io.Writer.Error)!void { | 705 | ) (Error || std.Io.Writer.Error)!void { |
| 733 | const zcu = pt.zcu; | 706 | const zcu = pt.zcu; |
| 734 | const ip = &zcu.intern_pool; | 707 | const ip = &zcu.intern_pool; |
| 735 | const comp = lf.comp; | 708 | const comp = lf.comp; |
| ... | @@ -761,10 +734,7 @@ fn lowerUavRef( | ... | @@ -761,10 +734,7 @@ fn lowerUavRef( |
| 761 | } | 734 | } |
| 762 | 735 | ||
| 763 | const uav_align = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu); | 736 | const uav_align = Type.fromInterned(uav.orig_ty).ptrAlignment(zcu); |
| 764 | switch (try lf.lowerUav(pt, uav_val, uav_align, src_loc)) { | 737 | _ = try lf.lowerUav(pt, uav_val, uav_align); |
| 765 | .sym_index => {}, | ||
| 766 | .fail => |em| std.debug.panic("TODO rework lowerUav. internal error: {s}", .{em.msg}), | ||
| 767 | } | ||
| 768 | 738 | ||
| 769 | const vaddr = lf.getUavVAddr(uav_val, .{ | 739 | const vaddr = lf.getUavVAddr(uav_val, .{ |
| 770 | .parent = reloc_parent, | 740 | .parent = reloc_parent, |
| ... | @@ -790,7 +760,7 @@ fn lowerNavRef( | ... | @@ -790,7 +760,7 @@ fn lowerNavRef( |
| 790 | w: *std.Io.Writer, | 760 | w: *std.Io.Writer, |
| 791 | reloc_parent: link.File.RelocInfo.Parent, | 761 | reloc_parent: link.File.RelocInfo.Parent, |
| 792 | offset: u64, | 762 | offset: u64, |
| 793 | ) (GenerateSymbolError || std.Io.Writer.Error)!void { | 763 | ) (Error || std.Io.Writer.Error)!void { |
| 794 | const zcu = pt.zcu; | 764 | const zcu = pt.zcu; |
| 795 | const gpa = zcu.gpa; | 765 | const gpa = zcu.gpa; |
| 796 | const ip = &zcu.intern_pool; | 766 | const ip = &zcu.intern_pool; |
| ... | @@ -859,15 +829,11 @@ fn lowerNavRef( | ... | @@ -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 | pub fn genNavRef( | 832 | pub fn genNavRef( |
| 865 | lf: *link.File, | 833 | lf: *link.File, |
| 866 | pt: Zcu.PerThread, | 834 | pt: Zcu.PerThread, |
| 867 | src_loc: Zcu.LazySrcLoc, | ||
| 868 | nav_index: InternPool.Nav.Index, | 835 | nav_index: InternPool.Nav.Index, |
| 869 | target: *const std.Target, | 836 | ) Error!link.File.SymbolId { |
| 870 | ) CodeGenError!SymbolResult { | ||
| 871 | const zcu = pt.zcu; | 837 | const zcu = pt.zcu; |
| 872 | const ip = &zcu.intern_pool; | 838 | const ip = &zcu.intern_pool; |
| 873 | const nav = ip.getNav(nav_index); | 839 | const nav = ip.getNav(nav_index); |
| ... | @@ -884,7 +850,7 @@ pub fn genNavRef( | ... | @@ -884,7 +850,7 @@ pub fn genNavRef( |
| 884 | .internal => { | 850 | .internal => { |
| 885 | const sym_index = try zo.getOrCreateMetadataForNav(zcu, nav_index); | 851 | const sym_index = try zo.getOrCreateMetadataForNav(zcu, nav_index); |
| 886 | if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true; | 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 | .strong, .weak => { | 855 | .strong, .weak => { |
| 890 | const sym_index = try elf_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip)); | 856 | const sym_index = try elf_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip)); |
| ... | @@ -895,27 +861,19 @@ pub fn genNavRef( | ... | @@ -895,27 +861,19 @@ pub fn genNavRef( |
| 895 | .link_once => unreachable, | 861 | .link_once => unreachable, |
| 896 | } | 862 | } |
| 897 | if (is_threadlocal) zo.symbol(sym_index).flags.is_tls = true; | 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 | .link_once => unreachable, | 866 | .link_once => unreachable, |
| 901 | } | 867 | } |
| 902 | } else if (lf.cast(.elf2)) |elf| { | 868 | } else if (lf.cast(.elf2)) |elf| { |
| 903 | return .{ .sym_index = elf.navSymbol(nav_index) catch |err| switch (err) { | 869 | return elf.navSymbol(nav_index); |
| 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 | } }; | ||
| 912 | } else if (lf.cast(.macho)) |macho_file| { | 870 | } else if (lf.cast(.macho)) |macho_file| { |
| 913 | const zo = macho_file.getZigObject().?; | 871 | const zo = macho_file.getZigObject().?; |
| 914 | switch (linkage) { | 872 | switch (linkage) { |
| 915 | .internal => { | 873 | .internal => { |
| 916 | const sym_index = try zo.getOrCreateMetadataForNav(macho_file, nav_index); | 874 | const sym_index = try zo.getOrCreateMetadataForNav(macho_file, nav_index); |
| 917 | if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true; | 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 | .strong, .weak => { | 878 | .strong, .weak => { |
| 921 | const sym_index = try macho_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip)); | 879 | const sym_index = try macho_file.getGlobalSymbol(nav.name.toSlice(ip), lib_name.toSlice(ip)); |
| ... | @@ -926,80 +884,67 @@ pub fn genNavRef( | ... | @@ -926,80 +884,67 @@ pub fn genNavRef( |
| 926 | .link_once => unreachable, | 884 | .link_once => unreachable, |
| 927 | } | 885 | } |
| 928 | if (is_threadlocal) zo.symbols.items[sym_index].flags.tlv = true; | 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 | .link_once => unreachable, | 889 | .link_once => unreachable, |
| 932 | } | 890 | } |
| 933 | } else if (lf.cast(.coff2)) |coff| { | 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 | } else { | 893 | } else { |
| 936 | const msg = try ErrorMsg.create(zcu.gpa, src_loc, "TODO genNavRef for target {}", .{target}); | 894 | std.debug.panic("TODO genNavRef for '{t}'", .{lf.tag}); |
| 937 | return .{ .fail = msg }; | ||
| 938 | } | 895 | } |
| 939 | } | 896 | } |
| 940 | 897 | ||
| 941 | /// deprecated legacy type | 898 | /// deprecated legacy type |
| 942 | pub const GenResult = union(enum) { | 899 | pub const MCValue = union(enum) { |
| 943 | mcv: MCValue, | 900 | none, |
| 944 | fail: *ErrorMsg, | 901 | undef, |
| 945 | 902 | /// The bit-width of the immediate may be smaller than `u64`. For example, on 32-bit targets | |
| 946 | const MCValue = union(enum) { | 903 | /// such as ARM, the immediate will never exceed 32-bits. |
| 947 | none, | 904 | immediate: u64, |
| 948 | undef, | 905 | /// Decl with address deferred until the linker allocates everything in virtual memory. |
| 949 | /// The bit-width of the immediate may be smaller than `u64`. For example, on 32-bit targets | 906 | /// Payload is a symbol index. |
| 950 | /// such as ARM, the immediate will never exceed 32-bits. | 907 | load_direct: link.File.SymbolId, |
| 951 | immediate: u64, | 908 | /// Decl with address deferred until the linker allocates everything in virtual memory. |
| 952 | /// Decl with address deferred until the linker allocates everything in virtual memory. | 909 | /// Payload is a symbol index. |
| 953 | /// Payload is a symbol index. | 910 | lea_direct: link.File.SymbolId, |
| 954 | load_direct: link.File.SymbolId, | 911 | /// Decl referenced via GOT with address deferred until the linker allocates |
| 955 | /// Decl with address deferred until the linker allocates everything in virtual memory. | 912 | /// everything in virtual memory. |
| 956 | /// Payload is a symbol index. | 913 | /// Payload is a symbol index. |
| 957 | lea_direct: link.File.SymbolId, | 914 | load_got: link.File.SymbolId, |
| 958 | /// Decl referenced via GOT with address deferred until the linker allocates | 915 | /// Direct by-address reference to memory location. |
| 959 | /// everything in virtual memory. | 916 | memory: u64, |
| 960 | /// Payload is a symbol index. | 917 | /// Reference to memory location but deferred until linker allocated the Decl in memory. |
| 961 | load_got: link.File.SymbolId, | 918 | /// Traditionally, this corresponds to emitting a relocation in a relocatable object file. |
| 962 | /// Direct by-address reference to memory location. | 919 | load_symbol: link.File.SymbolId, |
| 963 | memory: u64, | 920 | /// Reference to memory location but deferred until linker allocated the Decl in memory. |
| 964 | /// 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. |
| 965 | /// Traditionally, this corresponds to emitting a relocation in a relocatable object file. | 922 | lea_symbol: link.File.SymbolId, |
| 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 | }; | ||
| 971 | }; | 923 | }; |
| 972 | 924 | ||
| 973 | /// deprecated legacy code path | 925 | /// deprecated legacy code path |
| 974 | pub fn genTypedValue( | 926 | pub fn genTypedValue( |
| 975 | lf: *link.File, | 927 | lf: *link.File, |
| 976 | pt: Zcu.PerThread, | 928 | pt: Zcu.PerThread, |
| 977 | src_loc: Zcu.LazySrcLoc, | ||
| 978 | val: Value, | 929 | val: Value, |
| 979 | target: *const std.Target, | 930 | target: *const std.Target, |
| 980 | ) CodeGenError!GenResult { | 931 | ) Error!MCValue { |
| 981 | const res = try lowerValue(pt, val, target); | 932 | const res = try lowerValue(pt, val, target); |
| 982 | return switch (res) { | 933 | return switch (res) { |
| 983 | .none => .{ .mcv = .none }, | 934 | .none => .none, |
| 984 | .undef => .{ .mcv = .undef }, | 935 | .undef => .undef, |
| 985 | .immediate => |imm| .{ .mcv = .{ .immediate = imm } }, | 936 | .immediate => |imm| .{ .immediate = imm }, |
| 986 | .lea_nav => |nav| switch (try genNavRef(lf, pt, src_loc, nav, target)) { | 937 | .lea_nav => |nav| .{ .lea_symbol = try genNavRef(lf, pt, nav) }, |
| 987 | .sym_index => |sym_index| .{ .mcv = .{ .lea_symbol = sym_index } }, | 938 | .load_uav => |uav| .{ .load_symbol = try lf.lowerUav( |
| 988 | .fail => |em| .{ .fail = em }, | ||
| 989 | }, | ||
| 990 | .load_uav, .lea_uav => |uav| switch (try lf.lowerUav( | ||
| 991 | pt, | 939 | pt, |
| 992 | uav.val, | 940 | uav.val, |
| 993 | Type.fromInterned(uav.orig_ty).ptrAlignment(pt.zcu), | 941 | Type.fromInterned(uav.orig_ty).ptrAlignment(pt.zcu), |
| 994 | src_loc, | 942 | ) }, |
| 995 | )) { | 943 | .lea_uav => |uav| .{ .lea_symbol = try lf.lowerUav( |
| 996 | .sym_index => |sym_index| .{ .mcv = switch (res) { | 944 | pt, |
| 997 | else => unreachable, | 945 | uav.val, |
| 998 | .load_uav => .{ .load_symbol = sym_index }, | 946 | Type.fromInterned(uav.orig_ty).ptrAlignment(pt.zcu), |
| 999 | .lea_uav => .{ .lea_symbol = sym_index }, | 947 | ) }, |
| 1000 | } }, | ||
| 1001 | .fail => |em| .{ .fail = em }, | ||
| 1002 | }, | ||
| 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,7 +12,6 @@ pub fn legalizeFeatures(_: *const std.Target) ?*Air.Legalize.Features { |
| 12 | pub fn generate( | 12 | pub fn generate( |
| 13 | _: *link.File, | 13 | _: *link.File, |
| 14 | pt: Zcu.PerThread, | 14 | pt: Zcu.PerThread, |
| 15 | _: Zcu.LazySrcLoc, | ||
| 16 | func_index: InternPool.Index, | 15 | func_index: InternPool.Index, |
| 17 | air: *const Air, | 16 | air: *const Air, |
| 18 | liveness: *const ?Air.Liveness, | 17 | liveness: *const ?Air.Liveness, |
src/codegen/aarch64/Mir.zig+4-14| ... | @@ -54,7 +54,6 @@ pub fn emit( | ... | @@ -54,7 +54,6 @@ pub fn emit( |
| 54 | mir: Mir, | 54 | mir: Mir, |
| 55 | lf: *link.File, | 55 | lf: *link.File, |
| 56 | pt: Zcu.PerThread, | 56 | pt: Zcu.PerThread, |
| 57 | src_loc: Zcu.LazySrcLoc, | ||
| 58 | func_index: InternPool.Index, | 57 | func_index: InternPool.Index, |
| 59 | atom_index: link.File.AtomId, | 58 | atom_index: link.File.AtomId, |
| 60 | w: *std.Io.Writer, | 59 | w: *std.Io.Writer, |
| ... | @@ -94,16 +93,11 @@ pub fn emit( | ... | @@ -94,16 +93,11 @@ pub fn emit( |
| 94 | lf, | 93 | lf, |
| 95 | zcu, | 94 | zcu, |
| 96 | atom_index, | 95 | atom_index, |
| 97 | switch (try @import("../../codegen.zig").genNavRef( | 96 | try @import("../../codegen.zig").genNavRef( |
| 98 | lf, | 97 | lf, |
| 99 | pt, | 98 | pt, |
| 100 | src_loc, | ||
| 101 | nav_reloc.nav, | 99 | nav_reloc.nav, |
| 102 | &mod.resolved_target.result, | 100 | ), |
| 103 | )) { | ||
| 104 | .sym_index => |sym_index| sym_index, | ||
| 105 | .fail => |em| return zcu.codegenFailMsg(func.owner_nav, em), | ||
| 106 | }, | ||
| 107 | mir.body[nav_reloc.reloc.label], | 101 | mir.body[nav_reloc.reloc.label], |
| 108 | body_end - Instruction.size * (1 + nav_reloc.reloc.label), | 102 | body_end - Instruction.size * (1 + nav_reloc.reloc.label), |
| 109 | nav_reloc.reloc.addend, | 103 | nav_reloc.reloc.addend, |
| ... | @@ -113,15 +107,11 @@ pub fn emit( | ... | @@ -113,15 +107,11 @@ pub fn emit( |
| 113 | lf, | 107 | lf, |
| 114 | zcu, | 108 | zcu, |
| 115 | atom_index, | 109 | atom_index, |
| 116 | switch (try lf.lowerUav( | 110 | try lf.lowerUav( |
| 117 | pt, | 111 | pt, |
| 118 | uav_reloc.uav.val, | 112 | uav_reloc.uav.val, |
| 119 | ZigType.fromInterned(uav_reloc.uav.orig_ty).ptrAlignment(zcu), | 113 | ZigType.fromInterned(uav_reloc.uav.orig_ty).ptrAlignment(zcu), |
| 120 | src_loc, | 114 | ), |
| 121 | )) { | ||
| 122 | .sym_index => |sym_index| sym_index, | ||
| 123 | .fail => |em| return zcu.codegenFailMsg(func.owner_nav, em), | ||
| 124 | }, | ||
| 125 | mir.body[uav_reloc.reloc.label], | 115 | mir.body[uav_reloc.reloc.label], |
| 126 | body_end - Instruction.size * (1 + uav_reloc.reloc.label), | 116 | body_end - Instruction.size * (1 + uav_reloc.reloc.label), |
| 127 | uav_reloc.reloc.addend, | 117 | uav_reloc.reloc.addend, |
src/codegen/aarch64/Select.zig+5-5| ... | @@ -883,7 +883,7 @@ pub fn finishAnalysis(isel: *Select) !void { | ... | @@ -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 | const zcu = isel.pt.zcu; | 887 | const zcu = isel.pt.zcu; |
| 888 | const ip = &zcu.intern_pool; | 888 | const ip = &zcu.intern_pool; |
| 889 | const gpa = zcu.gpa; | 889 | const gpa = zcu.gpa; |
| ... | @@ -8001,7 +8001,7 @@ fn emitLiteral(isel: *Select, bytes: []const u8) !void { | ... | @@ -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 | @branchHint(.cold); | 8005 | @branchHint(.cold); |
| 8006 | return isel.pt.zcu.codegenFail(isel.nav_index, format, args); | 8006 | return isel.pt.zcu.codegenFail(isel.nav_index, format, args); |
| 8007 | } | 8007 | } |
| ... | @@ -10595,7 +10595,7 @@ pub const Value = struct { | ... | @@ -10595,7 +10595,7 @@ pub const Value = struct { |
| 10595 | vi: Value.Index, | 10595 | vi: Value.Index, |
| 10596 | ra: Register.Alias, | 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 | const live_vi = isel.live_registers.getPtr(mat.ra); | 10599 | const live_vi = isel.live_registers.getPtr(mat.ra); |
| 10600 | assert(live_vi.* == .allocating); | 10600 | assert(live_vi.* == .allocating); |
| 10601 | var vi = mat.vi; | 10601 | var vi = mat.vi; |
| ... | @@ -11636,7 +11636,7 @@ fn use(isel: *Select, air_ref: Air.Inst.Ref) !Value.Index { | ... | @@ -11636,7 +11636,7 @@ fn use(isel: *Select, air_ref: Air.Inst.Ref) !Value.Index { |
| 11636 | return vi; | 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 | switch (dst_ra) { | 11640 | switch (dst_ra) { |
| 11641 | else => {}, | 11641 | else => {}, |
| 11642 | Register.Alias.fp, .zr, .sp, .pc, .fpcr, .fpsr, .ffr => return false, | 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,7 +11669,7 @@ fn fill(isel: *Select, dst_ra: Register.Alias) error{ OutOfMemory, CodegenFail } |
| 11669 | return true; | 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 | const dst_live_vi = isel.live_registers.getPtr(dst_ra); | 11673 | const dst_live_vi = isel.live_registers.getPtr(dst_ra); |
| 11674 | const dst_vi = switch (dst_live_vi.*) { | 11674 | const dst_vi = switch (dst_live_vi.*) { |
| 11675 | _ => |dst_vi| dst_vi, | 11675 | _ => |dst_vi| dst_vi, |
src/codegen/c.zig+4-12| ... | @@ -80,7 +80,7 @@ pub const Mir = struct { | ... | @@ -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 | pub const CType = @import("c/type.zig").CType; | 85 | pub const CType = @import("c/type.zig").CType; |
| 86 | 86 | ||
| ... | @@ -637,7 +637,6 @@ pub const DeclGen = struct { | ... | @@ -637,7 +637,6 @@ pub const DeclGen = struct { |
| 637 | owner_nav: InternPool.Nav.Index.Optional, | 637 | owner_nav: InternPool.Nav.Index.Optional, |
| 638 | is_naked_fn: bool, | 638 | is_naked_fn: bool, |
| 639 | expected_block: ?u32, | 639 | expected_block: ?u32, |
| 640 | error_msg: ?*Zcu.ErrorMsg, | ||
| 641 | ctype_deps: CType.Dependencies, | 640 | ctype_deps: CType.Dependencies, |
| 642 | /// This map contains all the UAVs we saw generating this function. | 641 | /// This map contains all the UAVs we saw generating this function. |
| 643 | /// `link.C` will merge them into its `uavs`/`aligned_uavs` fields. | 642 | /// `link.C` will merge them into its `uavs`/`aligned_uavs` fields. |
| ... | @@ -648,10 +647,7 @@ pub const DeclGen = struct { | ... | @@ -648,10 +647,7 @@ pub const DeclGen = struct { |
| 648 | 647 | ||
| 649 | fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) Error { | 648 | fn fail(dg: *DeclGen, comptime format: []const u8, args: anytype) Error { |
| 650 | @branchHint(.cold); | 649 | @branchHint(.cold); |
| 651 | const zcu = dg.pt.zcu; | 650 | return dg.pt.zcu.codegenFail(dg.owner_nav.unwrap().?, format, args); |
| 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; | ||
| 655 | } | 651 | } |
| 656 | 652 | ||
| 657 | fn renderUav( | 653 | fn renderUav( |
| ... | @@ -2184,15 +2180,13 @@ pub fn genLazyCallModifierFn( | ... | @@ -2184,15 +2180,13 @@ pub fn genLazyCallModifierFn( |
| 2184 | pub fn generate( | 2180 | pub fn generate( |
| 2185 | lf: *link.File, | 2181 | lf: *link.File, |
| 2186 | pt: Zcu.PerThread, | 2182 | pt: Zcu.PerThread, |
| 2187 | src_loc: Zcu.LazySrcLoc, | ||
| 2188 | func_index: InternPool.Index, | 2183 | func_index: InternPool.Index, |
| 2189 | air: *const Air, | 2184 | air: *const Air, |
| 2190 | liveness: *const ?Air.Liveness, | 2185 | liveness: *const ?Air.Liveness, |
| 2191 | ) @import("../codegen.zig").CodeGenError!Mir { | 2186 | ) @import("../codegen.zig").Error!Mir { |
| 2192 | const zcu = pt.zcu; | 2187 | const zcu = pt.zcu; |
| 2193 | const gpa = zcu.gpa; | 2188 | const gpa = zcu.gpa; |
| 2194 | 2189 | ||
| 2195 | _ = src_loc; | ||
| 2196 | assert(lf.tag == .c); | 2190 | assert(lf.tag == .c); |
| 2197 | 2191 | ||
| 2198 | const func = zcu.funcInfo(func_index); | 2192 | const func = zcu.funcInfo(func_index); |
| ... | @@ -2210,7 +2204,6 @@ pub fn generate( | ... | @@ -2210,7 +2204,6 @@ pub fn generate( |
| 2210 | .arena = arena.allocator(), | 2204 | .arena = arena.allocator(), |
| 2211 | .pt = pt, | 2205 | .pt = pt, |
| 2212 | .mod = zcu.navFileScope(func.owner_nav).mod.?, | 2206 | .mod = zcu.navFileScope(func.owner_nav).mod.?, |
| 2213 | .error_msg = null, | ||
| 2214 | .owner_nav = func.owner_nav.toOptional(), | 2207 | .owner_nav = func.owner_nav.toOptional(), |
| 2215 | .is_naked_fn = Type.fromInterned(func.ty).fnCallingConvention(zcu) == .naked, | 2208 | .is_naked_fn = Type.fromInterned(func.ty).fnCallingConvention(zcu) == .naked, |
| 2216 | .expected_block = null, | 2209 | .expected_block = null, |
| ... | @@ -2237,9 +2230,8 @@ pub fn generate( | ... | @@ -2237,9 +2230,8 @@ pub fn generate( |
| 2237 | defer code_header.deinit(); | 2230 | defer code_header.deinit(); |
| 2238 | 2231 | ||
| 2239 | genFunc(&function, &fwd_decl.writer, &code_header.writer) catch |err| switch (err) { | 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 | error.WriteFailed => return error.OutOfMemory, | 2233 | error.WriteFailed => return error.OutOfMemory, |
| 2242 | error.OutOfMemory => |e| return e, | 2234 | else => |e| return e, |
| 2243 | }; | 2235 | }; |
| 2244 | 2236 | ||
| 2245 | var mir: Mir = .{ | 2237 | var mir: Mir = .{ |
src/codegen/llvm.zig+3-3| ... | @@ -771,7 +771,7 @@ pub const Object = struct { | ... | @@ -771,7 +771,7 @@ pub const Object = struct { |
| 771 | lto: std.zig.LtoMode, | 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 | const zcu = o.zcu; | 775 | const zcu = o.zcu; |
| 776 | const comp = zcu.comp; | 776 | const comp = zcu.comp; |
| 777 | const io = comp.io; | 777 | const io = comp.io; |
| ... | @@ -1705,7 +1705,7 @@ pub const Object = struct { | ... | @@ -1705,7 +1705,7 @@ pub const Object = struct { |
| 1705 | o: *Object, | 1705 | o: *Object, |
| 1706 | exported: Zcu.Exported, | 1706 | exported: Zcu.Exported, |
| 1707 | export_indices: []const Zcu.Export.Index, | 1707 | export_indices: []const Zcu.Export.Index, |
| 1708 | ) link.File.UpdateExportsError!void { | 1708 | ) link.Error!void { |
| 1709 | const zcu = o.zcu; | 1709 | const zcu = o.zcu; |
| 1710 | const ip = &zcu.intern_pool; | 1710 | const ip = &zcu.intern_pool; |
| 1711 | const ty: Type, const llvm_ptr: Builder.Constant = switch (exported) { | 1711 | const ty: Type, const llvm_ptr: Builder.Constant = switch (exported) { |
| ... | @@ -1735,7 +1735,7 @@ pub const Object = struct { | ... | @@ -1735,7 +1735,7 @@ pub const Object = struct { |
| 1735 | global_index: Builder.Global.Index, | 1735 | global_index: Builder.Global.Index, |
| 1736 | ty: Type, | 1736 | ty: Type, |
| 1737 | export_indices: []const Zcu.Export.Index, | 1737 | export_indices: []const Zcu.Export.Index, |
| 1738 | ) link.File.UpdateExportsError!void { | 1738 | ) link.Error!void { |
| 1739 | const zcu = o.zcu; | 1739 | const zcu = o.zcu; |
| 1740 | const comp = zcu.comp; | 1740 | const comp = zcu.comp; |
| 1741 | const ip = &zcu.intern_pool; | 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,8 +30,6 @@ const verbose_tracking_log = std.log.scoped(.verbose_tracking); |
| 30 | const wip_mir_log = std.log.scoped(.wip_mir); | 30 | const wip_mir_log = std.log.scoped(.wip_mir); |
| 31 | const Alignment = InternPool.Alignment; | 31 | const Alignment = InternPool.Alignment; |
| 32 | 32 | ||
| 33 | const CodeGenError = codegen.CodeGenError; | ||
| 34 | |||
| 35 | const bits = @import("bits.zig"); | 33 | const bits = @import("bits.zig"); |
| 36 | const abi = @import("abi.zig"); | 34 | const abi = @import("abi.zig"); |
| 37 | const Lower = @import("Lower.zig"); | 35 | const Lower = @import("Lower.zig"); |
| ... | @@ -49,7 +47,7 @@ const RegisterManager = abi.RegisterManager; | ... | @@ -49,7 +47,7 @@ const RegisterManager = abi.RegisterManager; |
| 49 | const RegisterLock = RegisterManager.RegisterLock; | 47 | const RegisterLock = RegisterManager.RegisterLock; |
| 50 | const Instruction = encoding.Instruction; | 48 | const Instruction = encoding.Instruction; |
| 51 | 49 | ||
| 52 | const InnerError = CodeGenError || error{OutOfRegisters}; | 50 | const InnerError = codegen.Error || error{OutOfRegisters}; |
| 53 | 51 | ||
| 54 | pub fn legalizeFeatures(_: *const std.Target) *const Air.Legalize.Features { | 52 | pub fn legalizeFeatures(_: *const std.Target) *const Air.Legalize.Features { |
| 55 | return comptime &.initMany(&.{ | 53 | return comptime &.initMany(&.{ |
| ... | @@ -75,7 +73,6 @@ ret_mcv: InstTracking, | ... | @@ -75,7 +73,6 @@ ret_mcv: InstTracking, |
| 75 | func_index: InternPool.Index, | 73 | func_index: InternPool.Index, |
| 76 | fn_type: Type, | 74 | fn_type: Type, |
| 77 | arg_index: usize, | 75 | arg_index: usize, |
| 78 | src_loc: Zcu.LazySrcLoc, | ||
| 79 | 76 | ||
| 80 | mir_instructions: std.MultiArrayList(Mir.Inst) = .{}, | 77 | mir_instructions: std.MultiArrayList(Mir.Inst) = .{}, |
| 81 | 78 | ||
| ... | @@ -742,11 +739,10 @@ const CallView = enum(u1) { | ... | @@ -742,11 +739,10 @@ const CallView = enum(u1) { |
| 742 | pub fn generate( | 739 | pub fn generate( |
| 743 | bin_file: *link.File, | 740 | bin_file: *link.File, |
| 744 | pt: Zcu.PerThread, | 741 | pt: Zcu.PerThread, |
| 745 | src_loc: Zcu.LazySrcLoc, | ||
| 746 | func_index: InternPool.Index, | 742 | func_index: InternPool.Index, |
| 747 | air: *const Air, | 743 | air: *const Air, |
| 748 | liveness: *const ?Air.Liveness, | 744 | liveness: *const ?Air.Liveness, |
| 749 | ) CodeGenError!Mir { | 745 | ) codegen.Error!Mir { |
| 750 | const zcu = pt.zcu; | 746 | const zcu = pt.zcu; |
| 751 | const gpa = zcu.gpa; | 747 | const gpa = zcu.gpa; |
| 752 | const ip = &zcu.intern_pool; | 748 | const ip = &zcu.intern_pool; |
| ... | @@ -777,7 +773,6 @@ pub fn generate( | ... | @@ -777,7 +773,6 @@ pub fn generate( |
| 777 | .fn_type = fn_type, | 773 | .fn_type = fn_type, |
| 778 | .arg_index = 0, | 774 | .arg_index = 0, |
| 779 | .branch_stack = &branch_stack, | 775 | .branch_stack = &branch_stack, |
| 780 | .src_loc = src_loc, | ||
| 781 | .end_di_line = func.rbrace_line, | 776 | .end_di_line = func.rbrace_line, |
| 782 | .end_di_column = func.rbrace_column, | 777 | .end_di_column = func.rbrace_column, |
| 783 | .scope_generation = 0, | 778 | .scope_generation = 0, |
| ... | @@ -811,10 +806,7 @@ pub fn generate( | ... | @@ -811,10 +806,7 @@ pub fn generate( |
| 811 | ); | 806 | ); |
| 812 | 807 | ||
| 813 | const fn_info = zcu.typeToFunc(fn_type).?; | 808 | const fn_info = zcu.typeToFunc(fn_type).?; |
| 814 | var call_info = function.resolveCallingConventionValues(fn_info, &.{}) catch |err| switch (err) { | 809 | var call_info = try function.resolveCallingConventionValues(fn_info, &.{}); |
| 815 | error.CodegenFail => |e| return e, | ||
| 816 | else => |e| return e, | ||
| 817 | }; | ||
| 818 | 810 | ||
| 819 | defer call_info.deinit(&function); | 811 | defer call_info.deinit(&function); |
| 820 | 812 | ||
| ... | @@ -841,7 +833,6 @@ pub fn generate( | ... | @@ -841,7 +833,6 @@ pub fn generate( |
| 841 | })); | 833 | })); |
| 842 | 834 | ||
| 843 | function.gen() catch |err| switch (err) { | 835 | function.gen() catch |err| switch (err) { |
| 844 | error.CodegenFail => |e| return e, | ||
| 845 | error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), | 836 | error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), |
| 846 | else => |e| return e, | 837 | else => |e| return e, |
| 847 | }; | 838 | }; |
| ... | @@ -857,12 +848,11 @@ pub fn generate( | ... | @@ -857,12 +848,11 @@ pub fn generate( |
| 857 | pub fn generateLazy( | 848 | pub fn generateLazy( |
| 858 | bin_file: *link.File, | 849 | bin_file: *link.File, |
| 859 | pt: Zcu.PerThread, | 850 | pt: Zcu.PerThread, |
| 860 | src_loc: Zcu.LazySrcLoc, | ||
| 861 | lazy_sym: link.File.LazySymbol, | 851 | lazy_sym: link.File.LazySymbol, |
| 862 | atom_index: link.File.AtomId, | 852 | atom_index: link.File.AtomId, |
| 863 | w: *std.Io.Writer, | 853 | w: *std.Io.Writer, |
| 864 | debug_output: link.File.DebugInfoOutput, | 854 | debug_output: link.File.DebugInfoOutput, |
| 865 | ) (CodeGenError || std.Io.Writer.Error)!void { | 855 | ) (codegen.Error || std.Io.Writer.Error)!void { |
| 866 | _ = atom_index; | 856 | _ = atom_index; |
| 867 | const comp = bin_file.comp; | 857 | const comp = bin_file.comp; |
| 868 | const gpa = comp.gpa; | 858 | const gpa = comp.gpa; |
| ... | @@ -883,7 +873,6 @@ pub fn generateLazy( | ... | @@ -883,7 +873,6 @@ pub fn generateLazy( |
| 883 | .fn_type = undefined, | 873 | .fn_type = undefined, |
| 884 | .arg_index = 0, | 874 | .arg_index = 0, |
| 885 | .branch_stack = undefined, | 875 | .branch_stack = undefined, |
| 886 | .src_loc = src_loc, | ||
| 887 | .end_di_line = undefined, | 876 | .end_di_line = undefined, |
| 888 | .end_di_column = undefined, | 877 | .end_di_column = undefined, |
| 889 | .scope_generation = 0, | 878 | .scope_generation = 0, |
| ... | @@ -893,7 +882,6 @@ pub fn generateLazy( | ... | @@ -893,7 +882,6 @@ pub fn generateLazy( |
| 893 | defer function.mir_instructions.deinit(gpa); | 882 | defer function.mir_instructions.deinit(gpa); |
| 894 | 883 | ||
| 895 | function.genLazy(lazy_sym) catch |err| switch (err) { | 884 | function.genLazy(lazy_sym) catch |err| switch (err) { |
| 896 | error.CodegenFail => |e| return e, | ||
| 897 | error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), | 885 | error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), |
| 898 | else => |e| return e, | 886 | else => |e| return e, |
| 899 | }; | 887 | }; |
| ... | @@ -910,7 +898,7 @@ pub fn generateLazy( | ... | @@ -910,7 +898,7 @@ pub fn generateLazy( |
| 910 | .allocator = gpa, | 898 | .allocator = gpa, |
| 911 | .mir = mir, | 899 | .mir = mir, |
| 912 | .cc = .auto, | 900 | .cc = .auto, |
| 913 | .src_loc = src_loc, | 901 | .src_loc = Type.fromInterned(lazy_sym.ty).srcLocOrNull(pt.zcu) orelse .unneeded, |
| 914 | .output_mode = comp.config.output_mode, | 902 | .output_mode = comp.config.output_mode, |
| 915 | .link_mode = comp.config.link_mode, | 903 | .link_mode = comp.config.link_mode, |
| 916 | .pic = mod.pic, | 904 | .pic = mod.pic, |
| ... | @@ -946,7 +934,10 @@ fn formatWipMir(data: FormatWipMirData, writer: *std.Io.Writer) std.Io.Writer.Er | ... | @@ -946,7 +934,10 @@ fn formatWipMir(data: FormatWipMirData, writer: *std.Io.Writer) std.Io.Writer.Er |
| 946 | .frame_locs = data.func.frame_locs.slice(), | 934 | .frame_locs = data.func.frame_locs.slice(), |
| 947 | }, | 935 | }, |
| 948 | .cc = .auto, | 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 | .output_mode = comp.config.output_mode, | 941 | .output_mode = comp.config.output_mode, |
| 951 | .link_mode = comp.config.link_mode, | 942 | .link_mode = comp.config.link_mode, |
| 952 | .pic = comp.root_mod.pic, | 943 | .pic = comp.root_mod.pic, |
| ... | @@ -8144,28 +8135,21 @@ fn genTypedValue(func: *Func, val: Value) InnerError!MCValue { | ... | @@ -8144,28 +8135,21 @@ fn genTypedValue(func: *Func, val: Value) InnerError!MCValue { |
| 8144 | const pt = func.pt; | 8135 | const pt = func.pt; |
| 8145 | 8136 | ||
| 8146 | const lf = func.bin_file; | 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)) | 8139 | const result: codegen.MCValue = if (val.isUndef(pt.zcu)) |
| 8150 | switch (try lf.lowerUav(pt, val.toIntern(), .none, src_loc)) { | 8140 | .{ .load_symbol = try lf.lowerUav(pt, val.toIntern(), .none) } |
| 8151 | .sym_index => |sym_index| .{ .mcv = .{ .load_symbol = sym_index } }, | ||
| 8152 | .fail => |em| .{ .fail = em }, | ||
| 8153 | } | ||
| 8154 | else | 8141 | else |
| 8155 | try codegen.genTypedValue(lf, pt, src_loc, val, func.target); | 8142 | try codegen.genTypedValue(lf, pt, val, func.target); |
| 8156 | const mcv: MCValue = switch (result) { | 8143 | const mcv: MCValue = switch (result) { |
| 8157 | .mcv => |mcv| switch (mcv) { | 8144 | .none => .none, |
| 8158 | .none => .none, | 8145 | .undef => unreachable, |
| 8159 | .undef => unreachable, | 8146 | .lea_symbol => |sym_index| .{ .lea_symbol = .{ .sym = sym_index } }, |
| 8160 | .lea_symbol => |sym_index| .{ .lea_symbol = .{ .sym = sym_index } }, | 8147 | .load_symbol => |sym_index| .{ .load_symbol = .{ .sym = sym_index } }, |
| 8161 | .load_symbol => |sym_index| .{ .load_symbol = .{ .sym = sym_index } }, | 8148 | .immediate => |imm| .{ .immediate = imm }, |
| 8162 | .immediate => |imm| .{ .immediate = imm }, | 8149 | .memory => |addr| .{ .memory = addr }, |
| 8163 | .memory => |addr| .{ .memory = addr }, | 8150 | .load_got, .load_direct, .lea_direct => { |
| 8164 | .load_got, .load_direct, .lea_direct => { | 8151 | return func.fail("TODO: genTypedValue {s}", .{@tagName(result)}); |
| 8165 | return func.fail("TODO: genTypedValue {s}", .{@tagName(mcv)}); | ||
| 8166 | }, | ||
| 8167 | }, | 8152 | }, |
| 8168 | .fail => |msg| return func.failMsg(msg), | ||
| 8169 | }; | 8153 | }; |
| 8170 | return mcv; | 8154 | return mcv; |
| 8171 | } | 8155 | } |
| ... | @@ -8353,24 +8337,24 @@ fn wantSafety(func: *Func) bool { | ... | @@ -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 | @branchHint(.cold); | 8341 | @branchHint(.cold); |
| 8358 | const zcu = func.pt.zcu; | 8342 | const zcu = func.pt.zcu; |
| 8359 | switch (func.owner) { | 8343 | switch (func.owner) { |
| 8360 | .nav_index => |i| return zcu.codegenFail(i, format, args), | 8344 | .nav_index => |i| return zcu.codegenFail(i, format, args), |
| 8361 | .lazy_sym => |s| return zcu.codegenFailType(s.ty, format, args), | 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 | @branchHint(.cold); | 8351 | @branchHint(.cold); |
| 8368 | const zcu = func.pt.zcu; | 8352 | const zcu = func.pt.zcu; |
| 8369 | switch (func.owner) { | 8353 | switch (func.owner) { |
| 8370 | .nav_index => |i| return zcu.codegenFailMsg(i, msg), | 8354 | .nav_index => |i| return zcu.codegenFailMsg(i, msg), |
| 8371 | .lazy_sym => |s| return zcu.codegenFailTypeMsg(s.ty, msg), | 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 | fn parseRegName(name: []const u8) ?Register { | 8360 | fn parseRegName(name: []const u8) ?Register { |
src/codegen/riscv64/Mir.zig+2-3| ... | @@ -107,12 +107,11 @@ pub fn emit( | ... | @@ -107,12 +107,11 @@ pub fn emit( |
| 107 | mir: Mir, | 107 | mir: Mir, |
| 108 | lf: *link.File, | 108 | lf: *link.File, |
| 109 | pt: Zcu.PerThread, | 109 | pt: Zcu.PerThread, |
| 110 | src_loc: Zcu.LazySrcLoc, | ||
| 111 | func_index: InternPool.Index, | 110 | func_index: InternPool.Index, |
| 112 | atom_index: link.File.AtomId, | 111 | atom_index: link.File.AtomId, |
| 113 | w: *std.Io.Writer, | 112 | w: *std.Io.Writer, |
| 114 | debug_output: link.File.DebugInfoOutput, | 113 | debug_output: link.File.DebugInfoOutput, |
| 115 | ) (codegen.CodeGenError || std.Io.Writer.Error)!void { | 114 | ) (codegen.Error || std.Io.Writer.Error)!void { |
| 116 | _ = atom_index; | 115 | _ = atom_index; |
| 117 | const zcu = pt.zcu; | 116 | const zcu = pt.zcu; |
| 118 | const comp = zcu.comp; | 117 | const comp = zcu.comp; |
| ... | @@ -127,7 +126,7 @@ pub fn emit( | ... | @@ -127,7 +126,7 @@ pub fn emit( |
| 127 | .allocator = gpa, | 126 | .allocator = gpa, |
| 128 | .mir = mir, | 127 | .mir = mir, |
| 129 | .cc = fn_info.cc, | 128 | .cc = fn_info.cc, |
| 130 | .src_loc = src_loc, | 129 | .src_loc = zcu.navSrcLoc(nav), |
| 131 | .output_mode = comp.config.output_mode, | 130 | .output_mode = comp.config.output_mode, |
| 132 | .link_mode = comp.config.link_mode, | 131 | .link_mode = comp.config.link_mode, |
| 133 | .pic = mod.pic, | 132 | .pic = mod.pic, |
src/codegen/sparc64/CodeGen.zig+11-28| ... | @@ -19,7 +19,6 @@ const Air = @import("../../Air.zig"); | ... | @@ -19,7 +19,6 @@ const Air = @import("../../Air.zig"); |
| 19 | const Mir = @import("Mir.zig"); | 19 | const Mir = @import("Mir.zig"); |
| 20 | const Emit = @import("Emit.zig"); | 20 | const Emit = @import("Emit.zig"); |
| 21 | const Type = @import("../../Type.zig"); | 21 | const Type = @import("../../Type.zig"); |
| 22 | const CodeGenError = codegen.CodeGenError; | ||
| 23 | const Endian = std.lang.Endian; | 22 | const Endian = std.lang.Endian; |
| 24 | const Alignment = InternPool.Alignment; | 23 | const Alignment = InternPool.Alignment; |
| 25 | 24 | ||
| ... | @@ -39,7 +38,7 @@ const gp = abi.RegisterClass.gp; | ... | @@ -39,7 +38,7 @@ const gp = abi.RegisterClass.gp; |
| 39 | 38 | ||
| 40 | const Self = @This(); | 39 | const Self = @This(); |
| 41 | 40 | ||
| 42 | const InnerError = CodeGenError || error{OutOfRegisters}; | 41 | const InnerError = codegen.Error || error{OutOfRegisters}; |
| 43 | 42 | ||
| 44 | pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features { | 43 | pub fn legalizeFeatures(_: *const std.Target) ?*const Air.Legalize.Features { |
| 45 | return null; | 44 | return null; |
| ... | @@ -57,12 +56,10 @@ liveness: Air.Liveness, | ... | @@ -57,12 +56,10 @@ liveness: Air.Liveness, |
| 57 | bin_file: *link.File, | 56 | bin_file: *link.File, |
| 58 | target: *const std.Target, | 57 | target: *const std.Target, |
| 59 | func_index: InternPool.Index, | 58 | func_index: InternPool.Index, |
| 60 | err_msg: ?*ErrorMsg, | ||
| 61 | args: []MCValue, | 59 | args: []MCValue, |
| 62 | ret_mcv: MCValue, | 60 | ret_mcv: MCValue, |
| 63 | fn_type: Type, | 61 | fn_type: Type, |
| 64 | arg_index: usize, | 62 | arg_index: usize, |
| 65 | src_loc: Zcu.LazySrcLoc, | ||
| 66 | stack_align: Alignment, | 63 | stack_align: Alignment, |
| 67 | 64 | ||
| 68 | /// MIR Instructions | 65 | /// MIR Instructions |
| ... | @@ -264,11 +261,10 @@ const BigTomb = struct { | ... | @@ -264,11 +261,10 @@ const BigTomb = struct { |
| 264 | pub fn generate( | 261 | pub fn generate( |
| 265 | lf: *link.File, | 262 | lf: *link.File, |
| 266 | pt: Zcu.PerThread, | 263 | pt: Zcu.PerThread, |
| 267 | src_loc: Zcu.LazySrcLoc, | ||
| 268 | func_index: InternPool.Index, | 264 | func_index: InternPool.Index, |
| 269 | air: *const Air, | 265 | air: *const Air, |
| 270 | liveness: *const ?Air.Liveness, | 266 | liveness: *const ?Air.Liveness, |
| 271 | ) CodeGenError!Mir { | 267 | ) codegen.Error!Mir { |
| 272 | const zcu = pt.zcu; | 268 | const zcu = pt.zcu; |
| 273 | const gpa = zcu.gpa; | 269 | const gpa = zcu.gpa; |
| 274 | const func = zcu.funcInfo(func_index); | 270 | const func = zcu.funcInfo(func_index); |
| ... | @@ -292,13 +288,11 @@ pub fn generate( | ... | @@ -292,13 +288,11 @@ pub fn generate( |
| 292 | .target = target, | 288 | .target = target, |
| 293 | .bin_file = lf, | 289 | .bin_file = lf, |
| 294 | .func_index = func_index, | 290 | .func_index = func_index, |
| 295 | .err_msg = null, | ||
| 296 | .args = undefined, // populated after `resolveCallingConventionValues` | 291 | .args = undefined, // populated after `resolveCallingConventionValues` |
| 297 | .ret_mcv = undefined, // populated after `resolveCallingConventionValues` | 292 | .ret_mcv = undefined, // populated after `resolveCallingConventionValues` |
| 298 | .fn_type = func_ty, | 293 | .fn_type = func_ty, |
| 299 | .arg_index = 0, | 294 | .arg_index = 0, |
| 300 | .branch_stack = &branch_stack, | 295 | .branch_stack = &branch_stack, |
| 301 | .src_loc = src_loc, | ||
| 302 | .stack_align = undefined, | 296 | .stack_align = undefined, |
| 303 | .end_di_line = func.rbrace_line, | 297 | .end_di_line = func.rbrace_line, |
| 304 | .end_di_column = func.rbrace_column, | 298 | .end_di_column = func.rbrace_column, |
| ... | @@ -307,10 +301,7 @@ pub fn generate( | ... | @@ -307,10 +301,7 @@ pub fn generate( |
| 307 | defer function.blocks.deinit(gpa); | 301 | defer function.blocks.deinit(gpa); |
| 308 | defer function.exitlude_jump_relocs.deinit(gpa); | 302 | defer function.exitlude_jump_relocs.deinit(gpa); |
| 309 | 303 | ||
| 310 | var call_info = function.resolveCallingConventionValues(func_ty, .callee) catch |err| switch (err) { | 304 | var call_info = try function.resolveCallingConventionValues(func_ty, .callee); |
| 311 | error.CodegenFail => |e| return e, | ||
| 312 | else => |e| return e, | ||
| 313 | }; | ||
| 314 | defer call_info.deinit(&function); | 305 | defer call_info.deinit(&function); |
| 315 | 306 | ||
| 316 | function.args = call_info.args; | 307 | function.args = call_info.args; |
| ... | @@ -319,7 +310,6 @@ pub fn generate( | ... | @@ -319,7 +310,6 @@ pub fn generate( |
| 319 | function.max_end_stack = call_info.stack_byte_count; | 310 | function.max_end_stack = call_info.stack_byte_count; |
| 320 | 311 | ||
| 321 | function.gen() catch |err| switch (err) { | 312 | function.gen() catch |err| switch (err) { |
| 322 | error.CodegenFail => |e| return e, | ||
| 323 | error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), | 313 | error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), |
| 324 | else => |e| return e, | 314 | else => |e| return e, |
| 325 | }; | 315 | }; |
| ... | @@ -3446,15 +3436,15 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) | ... | @@ -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 | @branchHint(.cold); | 3440 | @branchHint(.cold); |
| 3451 | const zcu = self.pt.zcu; | 3441 | const zcu = self.pt.zcu; |
| 3452 | const func = zcu.funcInfo(self.func_index); | 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 | return zcu.codegenFailMsg(func.owner_nav, msg); | 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 | @branchHint(.cold); | 3448 | @branchHint(.cold); |
| 3459 | const zcu = self.pt.zcu; | 3449 | const zcu = self.pt.zcu; |
| 3460 | const func = zcu.funcInfo(self.func_index); | 3450 | const func = zcu.funcInfo(self.func_index); |
| ... | @@ -4036,21 +4026,14 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { | ... | @@ -4036,21 +4026,14 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue { |
| 4036 | const mcv: MCValue = switch (try codegen.genTypedValue( | 4026 | const mcv: MCValue = switch (try codegen.genTypedValue( |
| 4037 | self.bin_file, | 4027 | self.bin_file, |
| 4038 | pt, | 4028 | pt, |
| 4039 | self.src_loc, | ||
| 4040 | val, | 4029 | val, |
| 4041 | self.target, | 4030 | self.target, |
| 4042 | )) { | 4031 | )) { |
| 4043 | .mcv => |mcv| switch (mcv) { | 4032 | .none => .none, |
| 4044 | .none => .none, | 4033 | .undef => .undef, |
| 4045 | .undef => .undef, | 4034 | .load_got, .load_symbol, .load_direct, .lea_symbol, .lea_direct => unreachable, // TODO |
| 4046 | .load_got, .load_symbol, .load_direct, .lea_symbol, .lea_direct => unreachable, // TODO | 4035 | .immediate => |imm| .{ .immediate = imm }, |
| 4047 | .immediate => |imm| .{ .immediate = imm }, | 4036 | .memory => |addr| .{ .memory = addr }, |
| 4048 | .memory => |addr| .{ .memory = addr }, | ||
| 4049 | }, | ||
| 4050 | .fail => |msg| { | ||
| 4051 | self.err_msg = msg; | ||
| 4052 | return error.CodegenFail; | ||
| 4053 | }, | ||
| 4054 | }; | 4037 | }; |
| 4055 | return mcv; | 4038 | return mcv; |
| 4056 | } | 4039 | } |
src/codegen/sparc64/Mir.zig+2-3| ... | @@ -378,12 +378,11 @@ pub fn emit( | ... | @@ -378,12 +378,11 @@ pub fn emit( |
| 378 | mir: Mir, | 378 | mir: Mir, |
| 379 | lf: *link.File, | 379 | lf: *link.File, |
| 380 | pt: Zcu.PerThread, | 380 | pt: Zcu.PerThread, |
| 381 | src_loc: Zcu.LazySrcLoc, | ||
| 382 | func_index: InternPool.Index, | 381 | func_index: InternPool.Index, |
| 383 | atom_index: link.File.AtomId, | 382 | atom_index: link.File.AtomId, |
| 384 | w: *std.Io.Writer, | 383 | w: *std.Io.Writer, |
| 385 | debug_output: link.File.DebugInfoOutput, | 384 | debug_output: link.File.DebugInfoOutput, |
| 386 | ) (codegen.CodeGenError || std.Io.Writer.Error)!void { | 385 | ) (codegen.Error || std.Io.Writer.Error)!void { |
| 387 | _ = atom_index; | 386 | _ = atom_index; |
| 388 | const zcu = pt.zcu; | 387 | const zcu = pt.zcu; |
| 389 | const func = zcu.funcInfo(func_index); | 388 | const func = zcu.funcInfo(func_index); |
| ... | @@ -394,7 +393,7 @@ pub fn emit( | ... | @@ -394,7 +393,7 @@ pub fn emit( |
| 394 | .bin_file = lf, | 393 | .bin_file = lf, |
| 395 | .debug_output = debug_output, | 394 | .debug_output = debug_output, |
| 396 | .target = &mod.resolved_target.result, | 395 | .target = &mod.resolved_target.result, |
| 397 | .src_loc = src_loc, | 396 | .src_loc = zcu.navSrcLoc(nav), |
| 398 | .w = w, | 397 | .w = w, |
| 399 | .prev_di_pc = 0, | 398 | .prev_di_pc = 0, |
| 400 | .prev_di_line = func.lbrace_line, | 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,7 +156,6 @@ inst_results: std.AutoHashMapUnmanaged(Air.Inst.Index, Id) = .empty, |
| 156 | id_scratch: std.ArrayList(Id) = .empty, | 156 | id_scratch: std.ArrayList(Id) = .empty, |
| 157 | prologue: Section = .{}, | 157 | prologue: Section = .{}, |
| 158 | body: Section = .{}, | 158 | body: Section = .{}, |
| 159 | error_msg: ?*Zcu.ErrorMsg = null, | ||
| 160 | 159 | ||
| 161 | pub fn deinit(cg: *CodeGen) void { | 160 | pub fn deinit(cg: *CodeGen) void { |
| 162 | const gpa = cg.module.gpa; | 161 | const gpa = cg.module.gpa; |
| ... | @@ -168,7 +167,7 @@ pub fn deinit(cg: *CodeGen) void { | ... | @@ -168,7 +167,7 @@ pub fn deinit(cg: *CodeGen) void { |
| 168 | cg.body.deinit(gpa); | 167 | cg.body.deinit(gpa); |
| 169 | } | 168 | } |
| 170 | 169 | ||
| 171 | const Error = error{ CodegenFail, OutOfMemory }; | 170 | const Error = error{ AlreadyReported, OutOfMemory }; |
| 172 | 171 | ||
| 173 | pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void { | 172 | pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void { |
| 174 | const gpa = cg.module.gpa; | 173 | const gpa = cg.module.gpa; |
| ... | @@ -363,11 +362,7 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void { | ... | @@ -363,11 +362,7 @@ pub fn genNav(cg: *CodeGen, do_codegen: bool) Error!void { |
| 363 | 362 | ||
| 364 | pub fn fail(cg: *CodeGen, comptime format: []const u8, args: anytype) Error { | 363 | pub fn fail(cg: *CodeGen, comptime format: []const u8, args: anytype) Error { |
| 365 | @branchHint(.cold); | 364 | @branchHint(.cold); |
| 366 | const zcu = cg.module.zcu; | 365 | return cg.module.zcu.codegenFail(cg.owner_nav, format, args); |
| 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; | ||
| 371 | } | 366 | } |
| 372 | 367 | ||
| 373 | pub fn todo(cg: *CodeGen, comptime format: []const u8, args: anytype) Error { | 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,14 +5929,14 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) !?Id { |
| 5934 | // them as notes here. | 5929 | // them as notes here. |
| 5935 | // TODO: Translate proper error locations. | 5930 | // TODO: Translate proper error locations. |
| 5936 | assert(ass.errors.items.len != 0); | 5931 | assert(ass.errors.items.len != 0); |
| 5937 | assert(cg.error_msg == null); | 5932 | const msg: *Zcu.ErrorMsg = msg: { |
| 5938 | const src_loc = zcu.navSrcLoc(cg.owner_nav); | 5933 | 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", .{}); | 5934 | var msg: *Zcu.ErrorMsg = try .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); | 5935 | errdefer msg.destroy(zcu.gpa); |
| 5941 | 5936 | ||
| 5942 | // Sub-scope to prevent `return error.CodegenFail` from running the errdefers. | 5937 | const notes = try zcu.gpa.alloc(Zcu.ErrorMsg, ass.errors.items.len); |
| 5943 | { | ||
| 5944 | errdefer zcu.gpa.free(notes); | 5938 | errdefer zcu.gpa.free(notes); |
| 5939 | |||
| 5945 | var i: usize = 0; | 5940 | var i: usize = 0; |
| 5946 | errdefer for (notes[0..i]) |*note| { | 5941 | errdefer for (notes[0..i]) |*note| { |
| 5947 | note.deinit(zcu.gpa); | 5942 | note.deinit(zcu.gpa); |
| ... | @@ -5950,9 +5945,10 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) !?Id { | ... | @@ -5950,9 +5945,10 @@ fn airAssembly(cg: *CodeGen, inst: Air.Inst.Index) !?Id { |
| 5950 | while (i < ass.errors.items.len) : (i += 1) { | 5945 | while (i < ass.errors.items.len) : (i += 1) { |
| 5951 | notes[i] = try Zcu.ErrorMsg.init(zcu.gpa, src_loc, "{s}", .{ass.errors.items[i].msg}); | 5946 | notes[i] = try Zcu.ErrorMsg.init(zcu.gpa, src_loc, "{s}", .{ass.errors.items[i].msg}); |
| 5952 | } | 5947 | } |
| 5953 | } | 5948 | |
| 5954 | cg.error_msg.?.notes = notes; | 5949 | break :msg msg; |
| 5955 | return error.CodegenFail; | 5950 | }; |
| 5951 | return zcu.codegenFailMsg(cg.owner_nav, msg); | ||
| 5956 | }, | 5952 | }, |
| 5957 | else => |others| return others, | 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,7 +329,7 @@ const bookkeeping_init = if (std.debug.runtime_safety) @as(usize, 0) else {}; |
| 329 | const InnerError = error{ | 329 | const InnerError = error{ |
| 330 | OutOfMemory, | 330 | OutOfMemory, |
| 331 | /// An error occurred when trying to lower AIR to MIR. | 331 | /// An error occurred when trying to lower AIR to MIR. |
| 332 | CodegenFail, | 332 | AlreadyReported, |
| 333 | /// Compiler implementation could not handle a large integer. | 333 | /// Compiler implementation could not handle a large integer. |
| 334 | Overflow, | 334 | Overflow, |
| 335 | } || link.File.UpdateDebugInfoError; | 335 | } || link.File.UpdateDebugInfoError; |
| ... | @@ -355,7 +355,7 @@ pub fn deinit(cg: *CodeGen) void { | ... | @@ -355,7 +355,7 @@ pub fn deinit(cg: *CodeGen) void { |
| 355 | cg.* = undefined; | 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 | const zcu = cg.pt.zcu; | 359 | const zcu = cg.pt.zcu; |
| 360 | const func = zcu.funcInfo(cg.func_index); | 360 | const func = zcu.funcInfo(cg.func_index); |
| 361 | return zcu.codegenFail(func.owner_nav, fmt, args); | 361 | return zcu.codegenFail(func.owner_nav, fmt, args); |
| ... | @@ -756,21 +756,17 @@ fn ensureAllocLocal(cg: *CodeGen, ty: Type) InnerError!WValue { | ... | @@ -756,21 +756,17 @@ fn ensureAllocLocal(cg: *CodeGen, ty: Type) InnerError!WValue { |
| 756 | 756 | ||
| 757 | pub const Error = error{ | 757 | pub const Error = error{ |
| 758 | OutOfMemory, | 758 | OutOfMemory, |
| 759 | /// Compiler was asked to operate on a number larger than supported. | ||
| 760 | Overflow, | ||
| 761 | /// Indicates the error is already stored in Zcu `failed_codegen`. | 759 | /// Indicates the error is already stored in Zcu `failed_codegen`. |
| 762 | CodegenFail, | 760 | AlreadyReported, |
| 763 | }; | 761 | }; |
| 764 | 762 | ||
| 765 | pub fn generate( | 763 | pub fn generate( |
| 766 | bin_file: *link.File, | 764 | bin_file: *link.File, |
| 767 | pt: Zcu.PerThread, | 765 | pt: Zcu.PerThread, |
| 768 | src_loc: Zcu.LazySrcLoc, | ||
| 769 | func_index: InternPool.Index, | 766 | func_index: InternPool.Index, |
| 770 | air: *const Air, | 767 | air: *const Air, |
| 771 | liveness: *const ?Air.Liveness, | 768 | liveness: *const ?Air.Liveness, |
| 772 | ) Error!Mir { | 769 | ) Error!Mir { |
| 773 | _ = src_loc; | ||
| 774 | _ = bin_file; | 770 | _ = bin_file; |
| 775 | const zcu = pt.zcu; | 771 | const zcu = pt.zcu; |
| 776 | const gpa = zcu.gpa; | 772 | const gpa = zcu.gpa; |
| ... | @@ -814,9 +810,8 @@ pub fn generate( | ... | @@ -814,9 +810,8 @@ pub fn generate( |
| 814 | try code_gen.mir_func_tys.putNoClobber(gpa, fn_ty.toIntern(), {}); | 810 | try code_gen.mir_func_tys.putNoClobber(gpa, fn_ty.toIntern(), {}); |
| 815 | 811 | ||
| 816 | return generateInner(&code_gen, any_returns) catch |err| switch (err) { | 812 | return generateInner(&code_gen, any_returns) catch |err| switch (err) { |
| 817 | error.CodegenFail, | 813 | error.AlreadyReported, |
| 818 | error.OutOfMemory, | 814 | error.OutOfMemory, |
| 819 | error.Overflow, | ||
| 820 | => |e| return e, | 815 | => |e| return e, |
| 821 | else => |e| return code_gen.fail("failed to generate function: {s}", .{@errorName(e)}), | 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,7 +31,7 @@ const RegisterManager = abi.RegisterManager; |
| 31 | const RegisterLock = RegisterManager.RegisterLock; | 31 | const RegisterLock = RegisterManager.RegisterLock; |
| 32 | const FrameIndex = bits.FrameIndex; | 32 | const FrameIndex = bits.FrameIndex; |
| 33 | 33 | ||
| 34 | const InnerError = codegen.CodeGenError || error{OutOfRegisters}; | 34 | const InnerError = codegen.Error || error{OutOfRegisters}; |
| 35 | 35 | ||
| 36 | pub fn legalizeFeatures(_: *const std.Target) *const Air.Legalize.Features { | 36 | pub fn legalizeFeatures(_: *const std.Target) *const Air.Legalize.Features { |
| 37 | return comptime &.initMany(&.{ | 37 | return comptime &.initMany(&.{ |
| ... | @@ -106,7 +106,6 @@ va_info: union { | ... | @@ -106,7 +106,6 @@ va_info: union { |
| 106 | ret_mcv: InstTracking, | 106 | ret_mcv: InstTracking, |
| 107 | err_ret_trace_reg: Register, | 107 | err_ret_trace_reg: Register, |
| 108 | fn_type: Type, | 108 | fn_type: Type, |
| 109 | src_loc: Zcu.LazySrcLoc, | ||
| 110 | 109 | ||
| 111 | eflags_inst: ?Air.Inst.Index = null, | 110 | eflags_inst: ?Air.Inst.Index = null, |
| 112 | 111 | ||
| ... | @@ -869,11 +868,10 @@ const CodeGen = @This(); | ... | @@ -869,11 +868,10 @@ const CodeGen = @This(); |
| 869 | pub fn generate( | 868 | pub fn generate( |
| 870 | bin_file: *link.File, | 869 | bin_file: *link.File, |
| 871 | pt: Zcu.PerThread, | 870 | pt: Zcu.PerThread, |
| 872 | src_loc: Zcu.LazySrcLoc, | ||
| 873 | func_index: InternPool.Index, | 871 | func_index: InternPool.Index, |
| 874 | air: *const Air, | 872 | air: *const Air, |
| 875 | liveness: *const ?Air.Liveness, | 873 | liveness: *const ?Air.Liveness, |
| 876 | ) codegen.CodeGenError!Mir { | 874 | ) codegen.Error!Mir { |
| 877 | _ = bin_file; | 875 | _ = bin_file; |
| 878 | const zcu = pt.zcu; | 876 | const zcu = pt.zcu; |
| 879 | const gpa = zcu.gpa; | 877 | const gpa = zcu.gpa; |
| ... | @@ -898,7 +896,6 @@ pub fn generate( | ... | @@ -898,7 +896,6 @@ pub fn generate( |
| 898 | .ret_mcv = undefined, // populated after `resolveCallingConventionValues` | 896 | .ret_mcv = undefined, // populated after `resolveCallingConventionValues` |
| 899 | .err_ret_trace_reg = undefined, // populated after `resolveCallingConventionValues` | 897 | .err_ret_trace_reg = undefined, // populated after `resolveCallingConventionValues` |
| 900 | .fn_type = fn_type, | 898 | .fn_type = fn_type, |
| 901 | .src_loc = src_loc, | ||
| 902 | }; | 899 | }; |
| 903 | defer { | 900 | defer { |
| 904 | function.frame_allocs.deinit(gpa); | 901 | function.frame_allocs.deinit(gpa); |
| ... | @@ -937,10 +934,7 @@ pub fn generate( | ... | @@ -937,10 +934,7 @@ pub fn generate( |
| 937 | ); | 934 | ); |
| 938 | 935 | ||
| 939 | const fn_info = zcu.typeToFunc(fn_type).?; | 936 | const fn_info = zcu.typeToFunc(fn_type).?; |
| 940 | var call_info = function.resolveCallingConventionValues(fn_info, &.{}, .args_frame) catch |err| switch (err) { | 937 | var call_info = try function.resolveCallingConventionValues(fn_info, &.{}, .args_frame); |
| 941 | error.CodegenFail => |e| return e, | ||
| 942 | else => |e| return e, | ||
| 943 | }; | ||
| 944 | defer call_info.deinit(&function); | 938 | defer call_info.deinit(&function); |
| 945 | 939 | ||
| 946 | function.args = call_info.args; | 940 | function.args = call_info.args; |
| ... | @@ -983,7 +977,6 @@ pub fn generate( | ... | @@ -983,7 +977,6 @@ pub fn generate( |
| 983 | } | 977 | } |
| 984 | 978 | ||
| 985 | function.gen(&file.zir.?, func_zir.inst, func.comptime_args, call_info.air_arg_count) catch |err| switch (err) { | 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 | error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), | 980 | error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), |
| 988 | else => |e| return e, | 981 | else => |e| return e, |
| 989 | }; | 982 | }; |
| ... | @@ -1027,12 +1020,11 @@ pub fn getTmpMir(cg: *CodeGen) Mir { | ... | @@ -1027,12 +1020,11 @@ pub fn getTmpMir(cg: *CodeGen) Mir { |
| 1027 | pub fn generateLazy( | 1020 | pub fn generateLazy( |
| 1028 | bin_file: *link.File, | 1021 | bin_file: *link.File, |
| 1029 | pt: Zcu.PerThread, | 1022 | pt: Zcu.PerThread, |
| 1030 | src_loc: Zcu.LazySrcLoc, | ||
| 1031 | lazy_sym: link.File.LazySymbol, | 1023 | lazy_sym: link.File.LazySymbol, |
| 1032 | atom_id: link.File.AtomId, | 1024 | atom_id: link.File.AtomId, |
| 1033 | w: *std.Io.Writer, | 1025 | w: *std.Io.Writer, |
| 1034 | debug_output: link.File.DebugInfoOutput, | 1026 | debug_output: link.File.DebugInfoOutput, |
| 1035 | ) codegen.CodeGenError!void { | 1027 | ) codegen.Error!void { |
| 1036 | const gpa = pt.zcu.gpa; | 1028 | const gpa = pt.zcu.gpa; |
| 1037 | // This function is for generating global code, so we use the root module. | 1029 | // This function is for generating global code, so we use the root module. |
| 1038 | const mod = pt.zcu.comp.root_mod; | 1030 | const mod = pt.zcu.comp.root_mod; |
| ... | @@ -1050,7 +1042,6 @@ pub fn generateLazy( | ... | @@ -1050,7 +1042,6 @@ pub fn generateLazy( |
| 1050 | .ret_mcv = undefined, | 1042 | .ret_mcv = undefined, |
| 1051 | .err_ret_trace_reg = undefined, | 1043 | .err_ret_trace_reg = undefined, |
| 1052 | .fn_type = undefined, | 1044 | .fn_type = undefined, |
| 1053 | .src_loc = src_loc, | ||
| 1054 | }; | 1045 | }; |
| 1055 | defer { | 1046 | defer { |
| 1056 | function.inst_tracking.deinit(gpa); | 1047 | function.inst_tracking.deinit(gpa); |
| ... | @@ -1068,12 +1059,11 @@ pub fn generateLazy( | ... | @@ -1068,12 +1059,11 @@ pub fn generateLazy( |
| 1068 | } | 1059 | } |
| 1069 | 1060 | ||
| 1070 | function.genLazy(lazy_sym) catch |err| switch (err) { | 1061 | function.genLazy(lazy_sym) catch |err| switch (err) { |
| 1071 | error.CodegenFail => |e| return e, | ||
| 1072 | error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), | 1062 | error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}), |
| 1073 | else => |e| return e, | 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 | const FormatNavData = struct { | 1069 | const FormatNavData = struct { |
| ... | @@ -1111,7 +1101,10 @@ fn formatWipMir(data: FormatWipMirData, w: *Writer) Writer.Error!void { | ... | @@ -1111,7 +1101,10 @@ fn formatWipMir(data: FormatWipMirData, w: *Writer) Writer.Error!void { |
| 1111 | .allocator = data.self.gpa, | 1101 | .allocator = data.self.gpa, |
| 1112 | .mir = data.self.getTmpMir(), | 1102 | .mir = data.self.getTmpMir(), |
| 1113 | .cc = .auto, | 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 | var first = true; | 1109 | var first = true; |
| 1117 | for ((lower.lowerMir(data.inst) catch |err| switch (err) { | 1110 | for ((lower.lowerMir(data.inst) catch |err| switch (err) { |
| ... | @@ -181508,7 +181501,7 @@ fn resolveCallingConventionValues( | ... | @@ -181508,7 +181501,7 @@ fn resolveCallingConventionValues( |
| 181508 | return result; | 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 | @branchHint(.cold); | 181505 | @branchHint(.cold); |
| 181513 | const zcu = cg.pt.zcu; | 181506 | const zcu = cg.pt.zcu; |
| 181514 | return switch (cg.owner) { | 181507 | return switch (cg.owner) { |
src/codegen/x86_64/Emit.zig+13-57| ... | @@ -17,6 +17,7 @@ relocs: std.ArrayList(Reloc), | ... | @@ -17,6 +17,7 @@ relocs: std.ArrayList(Reloc), |
| 17 | table_relocs: std.ArrayList(TableReloc), | 17 | table_relocs: std.ArrayList(TableReloc), |
| 18 | 18 | ||
| 19 | pub const Error = Lower.Error || error{ | 19 | pub const Error = Lower.Error || error{ |
| 20 | AlreadyReported, | ||
| 20 | EmitFail, | 21 | EmitFail, |
| 21 | NotFile, | 22 | NotFile, |
| 22 | } || std.posix.MMapError || std.posix.MRemapError || link.File.UpdateDebugInfoError; | 23 | } || std.posix.MMapError || std.posix.MRemapError || link.File.UpdateDebugInfoError; |
| ... | @@ -101,20 +102,11 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -101,20 +102,11 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 101 | .inst => |inst| .{ .inst = inst }, | 102 | .inst => |inst| .{ .inst = inst }, |
| 102 | .table => .table, | 103 | .table => .table, |
| 103 | .nav => |nav| { | 104 | .nav => |nav| { |
| 104 | const symbol_id = switch (try codegen.genNavRef( | 105 | const symbol_id = try codegen.genNavRef( |
| 105 | emit.bin_file, | 106 | emit.bin_file, |
| 106 | emit.pt, | 107 | emit.pt, |
| 107 | emit.lower.src_loc, | ||
| 108 | nav, | 108 | nav, |
| 109 | emit.lower.target, | 109 | ); |
| 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 | }; | ||
| 118 | const target_symbol: RelocInfo.Target.Symbol = if (ip.getNav(nav).getExtern(ip)) |@"extern"| .{ | 110 | const target_symbol: RelocInfo.Target.Symbol = if (ip.getNav(nav).getExtern(ip)) |@"extern"| .{ |
| 119 | .symbol = symbol_id, | 111 | .symbol = symbol_id, |
| 120 | .is_extern = switch (@"extern".visibility) { | 112 | .is_extern = switch (@"extern".visibility) { |
| ... | @@ -133,19 +125,11 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -133,19 +125,11 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 133 | } | 125 | } |
| 134 | }, | 126 | }, |
| 135 | .uav => |uav| .{ .symbol = .{ | 127 | .uav => |uav| .{ .symbol = .{ |
| 136 | .symbol = switch (try emit.bin_file.lowerUav( | 128 | .symbol = try emit.bin_file.lowerUav( |
| 137 | emit.pt, | 129 | emit.pt, |
| 138 | uav.val, | 130 | uav.val, |
| 139 | Type.fromInterned(uav.orig_ty).ptrAlignment(emit.pt.zcu), | 131 | Type.fromInterned(uav.orig_ty).ptrAlignment(emit.pt.zcu), |
| 140 | emit.lower.src_loc, | 132 | ), |
| 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 | }, | ||
| 149 | .is_extern = false, | 133 | .is_extern = false, |
| 150 | } }, | 134 | } }, |
| 151 | .lazy_sym => |lazy_sym| .{ .symbol = .{ | 135 | .lazy_sym => |lazy_sym| .{ .symbol = .{ |
| ... | @@ -168,17 +152,14 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -168,17 +152,14 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 168 | .extern_func => |extern_func| .{ .symbol = .{ | 152 | .extern_func => |extern_func| .{ .symbol = .{ |
| 169 | .symbol = if (emit.bin_file.cast(.elf)) |elf_file| | 153 | .symbol = if (emit.bin_file.cast(.elf)) |elf_file| |
| 170 | @enumFromInt(try elf_file.getGlobalSymbol(extern_func.toSlice(&emit.lower.mir).?, null)) | 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 | .name = extern_func.toSlice(&emit.lower.mir).?, | 156 | .name = extern_func.toSlice(&emit.lower.mir).?, |
| 173 | .lib_name = switch (comp.compiler_rt_strat) { | 157 | .lib_name = switch (comp.compiler_rt_strat) { |
| 174 | .none, .lib, .obj, .zcu => null, | 158 | .none, .lib, .obj, .zcu => null, |
| 175 | .dyn_lib => "compiler_rt", | 159 | .dyn_lib => "compiler_rt", |
| 176 | }, | 160 | }, |
| 177 | .type = .FUNC, | 161 | .type = .FUNC, |
| 178 | }) catch |err| switch (err) { | 162 | }) else if (emit.bin_file.cast(.macho)) |macho_file| |
| 179 | error.LinkOnceUnsupported => unreachable, | ||
| 180 | else => |e| return e, | ||
| 181 | } else if (emit.bin_file.cast(.macho)) |macho_file| | ||
| 182 | @enumFromInt(try macho_file.getGlobalSymbol(extern_func.toSlice(&emit.lower.mir).?, null)) | 163 | @enumFromInt(try macho_file.getGlobalSymbol(extern_func.toSlice(&emit.lower.mir).?, null)) |
| 183 | else if (emit.bin_file.cast(.coff2)) |coff| @enumFromInt(@intFromEnum(try coff.globalSymbol( | 164 | else if (emit.bin_file.cast(.coff2)) |coff| @enumFromInt(@intFromEnum(try coff.globalSymbol( |
| 184 | extern_func.toSlice(&emit.lower.mir).?, | 165 | extern_func.toSlice(&emit.lower.mir).?, |
| ... | @@ -313,14 +294,11 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -313,14 +294,11 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 313 | .symbol = if (emit.bin_file.cast(.elf)) |elf_file| @enumFromInt(try elf_file.getGlobalSymbol( | 294 | .symbol = if (emit.bin_file.cast(.elf)) |elf_file| @enumFromInt(try elf_file.getGlobalSymbol( |
| 314 | "__tls_get_addr", | 295 | "__tls_get_addr", |
| 315 | if (comp.config.link_libc) "c" else null, | 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 | .name = "__tls_get_addr", | 298 | .name = "__tls_get_addr", |
| 318 | .lib_name = if (comp.config.link_libc) "c" else null, | 299 | .lib_name = if (comp.config.link_libc) "c" else null, |
| 319 | .type = .FUNC, | 300 | .type = .FUNC, |
| 320 | }) catch |err| switch (err) { | 301 | }) else unreachable, |
| 321 | error.LinkOnceUnsupported => unreachable, | ||
| 322 | else => |e| return e, | ||
| 323 | } else unreachable, | ||
| 324 | .is_extern = true, | 302 | .is_extern = true, |
| 325 | } }, | 303 | } }, |
| 326 | }}); | 304 | }}); |
| ... | @@ -584,37 +562,16 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -584,37 +562,16 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 584 | .none => .{ .constu = 0 }, | 562 | .none => .{ .constu = 0 }, |
| 585 | .reg => |reg| .{ .breg = reg.dwarfNum() }, | 563 | .reg => |reg| .{ .breg = reg.dwarfNum() }, |
| 586 | .frame, .table, .rip_inst => unreachable, | 564 | .frame, .table, .rip_inst => unreachable, |
| 587 | .nav => |nav| .{ .addr_reloc = switch (codegen.genNavRef( | 565 | .nav => |nav| .{ .addr_reloc = try codegen.genNavRef( |
| 588 | emit.bin_file, | 566 | emit.bin_file, |
| 589 | emit.pt, | 567 | emit.pt, |
| 590 | emit.lower.src_loc, | ||
| 591 | nav, | 568 | nav, |
| 592 | emit.lower.target, | 569 | ) }, |
| 593 | ) catch |err| switch (err) { | 570 | .uav => |uav| .{ .addr_reloc = try emit.bin_file.lowerUav( |
| 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( | ||
| 606 | emit.pt, | 571 | emit.pt, |
| 607 | uav.val, | 572 | uav.val, |
| 608 | Type.fromInterned(uav.orig_ty).ptrAlignment(emit.pt.zcu), | 573 | Type.fromInterned(uav.orig_ty).ptrAlignment(emit.pt.zcu), |
| 609 | emit.lower.src_loc, | 574 | ) }, |
| 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 | } }, | ||
| 618 | .lazy_sym, .extern_func => unreachable, | 575 | .lazy_sym, .extern_func => unreachable, |
| 619 | }; | 576 | }; |
| 620 | break :base &loc_buf[0]; | 577 | break :base &loc_buf[0]; |
| ... | @@ -666,7 +623,6 @@ pub fn emitMir(emit: *Emit) Error!void { | ... | @@ -666,7 +623,6 @@ pub fn emitMir(emit: *Emit) Error!void { |
| 666 | const local = &emit.lower.mir.locals[local_index]; | 623 | const local = &emit.lower.mir.locals[local_index]; |
| 667 | local_index += 1; | 624 | local_index += 1; |
| 668 | try dwarf.genLocalConstDebugInfo( | 625 | try dwarf.genLocalConstDebugInfo( |
| 669 | emit.lower.src_loc, | ||
| 670 | switch (mir_inst.ops) { | 626 | switch (mir_inst.ops) { |
| 671 | else => unreachable, | 627 | else => unreachable, |
| 672 | .pseudo_dbg_arg_val => .comptime_arg, | 628 | .pseudo_dbg_arg_val => .comptime_arg, |
src/codegen/x86_64/Lower.zig+2-2| ... | @@ -49,8 +49,8 @@ pub const Error = error{ | ... | @@ -49,8 +49,8 @@ pub const Error = error{ |
| 49 | LowerFail, | 49 | LowerFail, |
| 50 | InvalidInstruction, | 50 | InvalidInstruction, |
| 51 | CannotEncode, | 51 | CannotEncode, |
| 52 | CodegenFail, | 52 | AlreadyReported, |
| 53 | } || codegen.GenerateSymbolError; | 53 | } || link.Error; |
| 54 | 54 | ||
| 55 | pub const Reloc = struct { | 55 | pub const Reloc = struct { |
| 56 | lowered_inst_index: ResultInstIndex, | 56 | lowered_inst_index: ResultInstIndex, |
src/codegen/x86_64/Mir.zig+4-6| ... | @@ -1974,12 +1974,11 @@ pub fn emit( | ... | @@ -1974,12 +1974,11 @@ pub fn emit( |
| 1974 | mir: Mir, | 1974 | mir: Mir, |
| 1975 | lf: *link.File, | 1975 | lf: *link.File, |
| 1976 | pt: Zcu.PerThread, | 1976 | pt: Zcu.PerThread, |
| 1977 | src_loc: Zcu.LazySrcLoc, | ||
| 1978 | func_index: InternPool.Index, | 1977 | func_index: InternPool.Index, |
| 1979 | atom_id: link.File.AtomId, | 1978 | atom_id: link.File.AtomId, |
| 1980 | w: *std.Io.Writer, | 1979 | w: *std.Io.Writer, |
| 1981 | debug_output: link.File.DebugInfoOutput, | 1980 | debug_output: link.File.DebugInfoOutput, |
| 1982 | ) codegen.CodeGenError!void { | 1981 | ) codegen.Error!void { |
| 1983 | const zcu = pt.zcu; | 1982 | const zcu = pt.zcu; |
| 1984 | const comp = zcu.comp; | 1983 | const comp = zcu.comp; |
| 1985 | const gpa = comp.gpa; | 1984 | const gpa = comp.gpa; |
| ... | @@ -1993,7 +1992,7 @@ pub fn emit( | ... | @@ -1993,7 +1992,7 @@ pub fn emit( |
| 1993 | .allocator = gpa, | 1992 | .allocator = gpa, |
| 1994 | .mir = mir, | 1993 | .mir = mir, |
| 1995 | .cc = fn_info.cc, | 1994 | .cc = fn_info.cc, |
| 1996 | .src_loc = src_loc, | 1995 | .src_loc = zcu.navSrcLoc(nav), |
| 1997 | }, | 1996 | }, |
| 1998 | .bin_file = lf, | 1997 | .bin_file = lf, |
| 1999 | .pt = pt, | 1998 | .pt = pt, |
| ... | @@ -2028,12 +2027,11 @@ pub fn emitLazy( | ... | @@ -2028,12 +2027,11 @@ pub fn emitLazy( |
| 2028 | mir: Mir, | 2027 | mir: Mir, |
| 2029 | lf: *link.File, | 2028 | lf: *link.File, |
| 2030 | pt: Zcu.PerThread, | 2029 | pt: Zcu.PerThread, |
| 2031 | src_loc: Zcu.LazySrcLoc, | ||
| 2032 | lazy_sym: link.File.LazySymbol, | 2030 | lazy_sym: link.File.LazySymbol, |
| 2033 | atom_id: link.File.AtomId, | 2031 | atom_id: link.File.AtomId, |
| 2034 | w: *std.Io.Writer, | 2032 | w: *std.Io.Writer, |
| 2035 | debug_output: link.File.DebugInfoOutput, | 2033 | debug_output: link.File.DebugInfoOutput, |
| 2036 | ) codegen.CodeGenError!void { | 2034 | ) codegen.Error!void { |
| 2037 | const zcu = pt.zcu; | 2035 | const zcu = pt.zcu; |
| 2038 | const comp = zcu.comp; | 2036 | const comp = zcu.comp; |
| 2039 | const gpa = comp.gpa; | 2037 | const gpa = comp.gpa; |
| ... | @@ -2044,7 +2042,7 @@ pub fn emitLazy( | ... | @@ -2044,7 +2042,7 @@ pub fn emitLazy( |
| 2044 | .allocator = gpa, | 2042 | .allocator = gpa, |
| 2045 | .mir = mir, | 2043 | .mir = mir, |
| 2046 | .cc = .auto, | 2044 | .cc = .auto, |
| 2047 | .src_loc = src_loc, | 2045 | .src_loc = Zcu.Type.fromInterned(lazy_sym.ty).srcLocOrNull(zcu) orelse .unneeded, |
| 2048 | }, | 2046 | }, |
| 2049 | .bin_file = lf, | 2047 | .bin_file = lf, |
| 2050 | .pt = pt, | 2048 | .pt = pt, |
src/link.zig+57-90| ... | @@ -31,6 +31,12 @@ pub const LdScript = @import("link/LdScript.zig"); | ... | @@ -31,6 +31,12 @@ pub const LdScript = @import("link/LdScript.zig"); |
| 31 | pub const Queue = @import("link/Queue.zig"); | 31 | pub const Queue = @import("link/Queue.zig"); |
| 32 | pub const ConstPool = @import("link/ConstPool.zig"); | 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 | pub const Diags = struct { | 40 | pub const Diags = struct { |
| 35 | /// Stored here so that function definitions can distinguish between | 41 | /// Stored here so that function definitions can distinguish between |
| 36 | /// needing an allocator for things besides error reporting. | 42 | /// needing an allocator for things besides error reporting. |
| ... | @@ -112,7 +118,7 @@ pub const Diags = struct { | ... | @@ -112,7 +118,7 @@ pub const Diags = struct { |
| 112 | err: ErrorWithNotes, | 118 | err: ErrorWithNotes, |
| 113 | comptime format: []const u8, | 119 | comptime format: []const u8, |
| 114 | args: anytype, | 120 | args: anytype, |
| 115 | ) error{OutOfMemory}!void { | 121 | ) Allocator.Error!void { |
| 116 | const gpa = err.diags.gpa; | 122 | const gpa = err.diags.gpa; |
| 117 | const err_msg = &err.diags.msgs.items[err.index]; | 123 | const err_msg = &err.diags.msgs.items[err.index]; |
| 118 | err_msg.msg = try std.fmt.allocPrint(gpa, format, args); | 124 | err_msg.msg = try std.fmt.allocPrint(gpa, format, args); |
| ... | @@ -212,16 +218,16 @@ pub const Diags = struct { | ... | @@ -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 | @branchHint(.cold); | 222 | @branchHint(.cold); |
| 217 | addError(diags, format, args); | 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 | @branchHint(.cold); | 228 | @branchHint(.cold); |
| 223 | addErrorSourceLocation(diags, sl, format, args); | 229 | addErrorSourceLocation(diags, sl, format, args); |
| 224 | return error.LinkFailure; | 230 | return error.AlreadyReported; |
| 225 | } | 231 | } |
| 226 | 232 | ||
| 227 | pub fn addError(diags: *Diags, comptime format: []const u8, args: anytype) void { | 233 | pub fn addError(diags: *Diags, comptime format: []const u8, args: anytype) void { |
| ... | @@ -251,7 +257,7 @@ pub const Diags = struct { | ... | @@ -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 | @branchHint(.cold); | 261 | @branchHint(.cold); |
| 256 | const gpa = diags.gpa; | 262 | const gpa = diags.gpa; |
| 257 | const io = diags.io; | 263 | const io = diags.io; |
| ... | @@ -261,7 +267,7 @@ pub const Diags = struct { | ... | @@ -261,7 +267,7 @@ pub const Diags = struct { |
| 261 | return addErrorWithNotesAssumeCapacity(diags, note_count); | 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 | @branchHint(.cold); | 271 | @branchHint(.cold); |
| 266 | const gpa = diags.gpa; | 272 | const gpa = diags.gpa; |
| 267 | const index = diags.msgs.items.len; | 273 | const index = diags.msgs.items.len; |
| ... | @@ -351,10 +357,10 @@ pub const Diags = struct { | ... | @@ -351,10 +357,10 @@ pub const Diags = struct { |
| 351 | path: Path, | 357 | path: Path, |
| 352 | comptime format: []const u8, | 358 | comptime format: []const u8, |
| 353 | args: anytype, | 359 | args: anytype, |
| 354 | ) error{LinkFailure} { | 360 | ) error{AlreadyReported} { |
| 355 | @branchHint(.cold); | 361 | @branchHint(.cold); |
| 356 | addParseError(diags, path, format, args); | 362 | addParseError(diags, path, format, args); |
| 357 | return error.LinkFailure; | 363 | return error.AlreadyReported; |
| 358 | } | 364 | } |
| 359 | 365 | ||
| 360 | pub fn setAllocFailure(diags: *Diags) void { | 366 | pub fn setAllocFailure(diags: *Diags) void { |
| ... | @@ -752,11 +758,6 @@ pub const File = struct { | ... | @@ -752,11 +758,6 @@ pub const File = struct { |
| 752 | none, | 758 | none, |
| 753 | }; | 759 | }; |
| 754 | pub const UpdateDebugInfoError = Dwarf.UpdateError; | 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 | /// Opaque identifier for a function currently being emitted. | 762 | /// Opaque identifier for a function currently being emitted. |
| 762 | /// | 763 | /// |
| ... | @@ -775,7 +776,7 @@ pub const File = struct { | ... | @@ -775,7 +776,7 @@ pub const File = struct { |
| 775 | /// be created. This symbol may get resolved once all relocatables are (re-)linked. | 776 | /// be created. This symbol may get resolved once all relocatables are (re-)linked. |
| 776 | /// Optionally, it is possible to specify where to expect the symbol defined if it | 777 | /// Optionally, it is possible to specify where to expect the symbol defined if it |
| 777 | /// is an import. | 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 | log.debug("getGlobalSymbol '{s}' (expected in '{?s}')", .{ name, lib_name }); | 780 | log.debug("getGlobalSymbol '{s}' (expected in '{?s}')", .{ name, lib_name }); |
| 780 | switch (base.tag) { | 781 | switch (base.tag) { |
| 781 | .lld => unreachable, | 782 | .lld => unreachable, |
| ... | @@ -790,7 +791,7 @@ pub const File = struct { | ... | @@ -790,7 +791,7 @@ pub const File = struct { |
| 790 | 791 | ||
| 791 | /// May be called before or after updateExports for any given Nav. | 792 | /// May be called before or after updateExports for any given Nav. |
| 792 | /// Asserts that the ZCU is not using the LLVM backend. | 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 | assert(base.comp.zcu.?.llvm_object == null); | 795 | assert(base.comp.zcu.?.llvm_object == null); |
| 795 | const nav = pt.zcu.intern_pool.getNav(nav_index); | 796 | const nav = pt.zcu.intern_pool.getNav(nav_index); |
| 796 | assert(nav.resolved.?.value != .none); | 797 | assert(nav.resolved.?.value != .none); |
| ... | @@ -804,14 +805,8 @@ pub const File = struct { | ... | @@ -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 | /// Never called when LLVM is codegenning the ZCU. | 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 | assert(base.comp.zcu.?.llvm_object == null); | 810 | assert(base.comp.zcu.?.llvm_object == null); |
| 816 | switch (base.tag) { | 811 | switch (base.tag) { |
| 817 | .lld => unreachable, | 812 | .lld => unreachable, |
| ... | @@ -824,7 +819,7 @@ pub const File = struct { | ... | @@ -824,7 +819,7 @@ pub const File = struct { |
| 824 | } | 819 | } |
| 825 | 820 | ||
| 826 | /// Never called when LLVM is codegenning the ZCU. | 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 | assert(base.comp.zcu.?.llvm_object == null); | 823 | assert(base.comp.zcu.?.llvm_object == null); |
| 829 | switch (base.tag) { | 824 | switch (base.tag) { |
| 830 | .lld => unreachable, | 825 | .lld => unreachable, |
| ... | @@ -847,7 +842,7 @@ pub const File = struct { | ... | @@ -847,7 +842,7 @@ pub const File = struct { |
| 847 | /// that `mir.deinit` remains legal for the caller. For instance, the callee can | 842 | /// that `mir.deinit` remains legal for the caller. For instance, the callee can |
| 848 | /// take ownership of an embedded slice and replace it with `&.{}` in `mir`. | 843 | /// take ownership of an embedded slice and replace it with `&.{}` in `mir`. |
| 849 | mir: *codegen.AnyMir, | 844 | mir: *codegen.AnyMir, |
| 850 | ) UpdateNavError!void { | 845 | ) Error!void { |
| 851 | assert(base.comp.zcu.?.llvm_object == null); | 846 | assert(base.comp.zcu.?.llvm_object == null); |
| 852 | switch (base.tag) { | 847 | switch (base.tag) { |
| 853 | .lld => unreachable, | 848 | .lld => unreachable, |
| ... | @@ -860,16 +855,10 @@ pub const File = struct { | ... | @@ -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 | /// On an incremental update, fixup the line number of all `Nav`s at the given `TrackedInst`, because | 858 | /// On an incremental update, fixup the line number of all `Nav`s at the given `TrackedInst`, because |
| 870 | /// its line number has changed. The ZIR instruction `ti_id` has tag `.declaration`. | 859 | /// its line number has changed. The ZIR instruction `ti_id` has tag `.declaration`. |
| 871 | /// Never called when LLVM is codegenning the ZCU. | 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 | assert(base.comp.zcu.?.llvm_object == null); | 862 | assert(base.comp.zcu.?.llvm_object == null); |
| 874 | { | 863 | { |
| 875 | const ti = ti_id.resolveFull(&pt.zcu.intern_pool).?; | 864 | const ti = ti_id.resolveFull(&pt.zcu.intern_pool).?; |
| ... | @@ -918,7 +907,7 @@ pub const File = struct { | ... | @@ -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 | switch (base.tag) { | 911 | switch (base.tag) { |
| 923 | else => return false, | 912 | else => return false, |
| 924 | inline .elf2, .coff2 => |tag| { | 913 | inline .elf2, .coff2 => |tag| { |
| ... | @@ -928,7 +917,7 @@ pub const File = struct { | ... | @@ -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 | switch (base.tag) { | 921 | switch (base.tag) { |
| 933 | else => {}, | 922 | else => {}, |
| 934 | inline .elf2, .coff2 => |tag| { | 923 | inline .elf2, .coff2 => |tag| { |
| ... | @@ -938,14 +927,9 @@ pub const File = struct { | ... | @@ -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 | /// Commit pending changes and write headers. Takes into account final output mode. | 930 | /// Commit pending changes and write headers. Takes into account final output mode. |
| 947 | /// `arena` has the lifetime of the call to `Compilation.update`. | 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 | const comp = base.comp; | 933 | const comp = base.comp; |
| 950 | const io = comp.io; | 934 | const io = comp.io; |
| 951 | if (comp.clang_preprocessor_mode == .yes or comp.clang_preprocessor_mode == .pch) { | 935 | if (comp.clang_preprocessor_mode == .yes or comp.clang_preprocessor_mode == .pch) { |
| ... | @@ -985,11 +969,6 @@ pub const File = struct { | ... | @@ -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 | /// This is called for every exported thing. `exports` is almost always | 972 | /// This is called for every exported thing. `exports` is almost always |
| 994 | /// a list of size 1, meaning that `exported` is exported once. However, it is possible | 973 | /// a list of size 1, meaning that `exported` is exported once. However, it is possible |
| 995 | /// to export the same thing with multiple different symbol names (aliases). | 974 | /// to export the same thing with multiple different symbol names (aliases). |
| ... | @@ -1000,7 +979,7 @@ pub const File = struct { | ... | @@ -1000,7 +979,7 @@ pub const File = struct { |
| 1000 | pt: Zcu.PerThread, | 979 | pt: Zcu.PerThread, |
| 1001 | exported: Zcu.Exported, | 980 | exported: Zcu.Exported, |
| 1002 | export_indices: []const Zcu.Export.Index, | 981 | export_indices: []const Zcu.Export.Index, |
| 1003 | ) UpdateExportsError!void { | 982 | ) Error!void { |
| 1004 | assert(base.comp.zcu.?.llvm_object == null); | 983 | assert(base.comp.zcu.?.llvm_object == null); |
| 1005 | switch (base.tag) { | 984 | switch (base.tag) { |
| 1006 | .lld => unreachable, | 985 | .lld => unreachable, |
| ... | @@ -1031,7 +1010,7 @@ pub const File = struct { | ... | @@ -1031,7 +1010,7 @@ pub const File = struct { |
| 1031 | /// May be called before or after updateFunc/updateNav therefore it is up to the linker to allocate | 1010 | /// May be called before or after updateFunc/updateNav therefore it is up to the linker to allocate |
| 1032 | /// the block/atom. | 1011 | /// the block/atom. |
| 1033 | /// Never called when LLVM is codegenning the ZCU. | 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 | assert(base.comp.zcu.?.llvm_object == null); | 1014 | assert(base.comp.zcu.?.llvm_object == null); |
| 1036 | switch (base.tag) { | 1015 | switch (base.tag) { |
| 1037 | .lld => unreachable, | 1016 | .lld => unreachable, |
| ... | @@ -1052,8 +1031,7 @@ pub const File = struct { | ... | @@ -1052,8 +1031,7 @@ pub const File = struct { |
| 1052 | pt: Zcu.PerThread, | 1031 | pt: Zcu.PerThread, |
| 1053 | decl_val: InternPool.Index, | 1032 | decl_val: InternPool.Index, |
| 1054 | decl_align: InternPool.Alignment, | 1033 | decl_align: InternPool.Alignment, |
| 1055 | src_loc: Zcu.LazySrcLoc, | 1034 | ) Error!SymbolId { |
| 1056 | ) !codegen.SymbolResult { | ||
| 1057 | assert(base.comp.zcu.?.llvm_object == null); | 1035 | assert(base.comp.zcu.?.llvm_object == null); |
| 1058 | switch (base.tag) { | 1036 | switch (base.tag) { |
| 1059 | .lld => unreachable, | 1037 | .lld => unreachable, |
| ... | @@ -1063,13 +1041,13 @@ pub const File = struct { | ... | @@ -1063,13 +1041,13 @@ pub const File = struct { |
| 1063 | .plan9 => unreachable, | 1041 | .plan9 => unreachable, |
| 1064 | inline else => |tag| { | 1042 | inline else => |tag| { |
| 1065 | dev.check(tag.devFeature()); | 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 | /// Never called when LLVM is codegenning the ZCU. | 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 | assert(base.comp.zcu.?.llvm_object == null); | 1051 | assert(base.comp.zcu.?.llvm_object == null); |
| 1074 | switch (base.tag) { | 1052 | switch (base.tag) { |
| 1075 | .lld => unreachable, | 1053 | .lld => unreachable, |
| ... | @@ -1217,7 +1195,7 @@ pub const File = struct { | ... | @@ -1217,7 +1195,7 @@ pub const File = struct { |
| 1217 | 1195 | ||
| 1218 | /// Called when all linker inputs have been sent via `loadInput`. After | 1196 | /// Called when all linker inputs have been sent via `loadInput`. After |
| 1219 | /// this, `loadInput` will not be called anymore. | 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 | assert(!base.post_prelink); | 1199 | assert(!base.post_prelink); |
| 1222 | 1200 | ||
| 1223 | // In this case, an object file is created by the LLVM backend, so | 1201 | // In this case, an object file is created by the LLVM backend, so |
| ... | @@ -1251,7 +1229,11 @@ pub const File = struct { | ... | @@ -1251,7 +1229,11 @@ pub const File = struct { |
| 1251 | file_writer.pos = new_offset; | 1229 | file_writer.pos = new_offset; |
| 1252 | const size_u = std.math.cast(usize, size) orelse return error.Overflow; | 1230 | const size_u = std.math.cast(usize, size) orelse return error.Overflow; |
| 1253 | const n = file_writer.interface.sendFileAll(&file_reader, .limited(size_u)) catch |err| switch (err) { | 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 | error.WriteFailed => return file_writer.err.?, | 1237 | error.WriteFailed => return file_writer.err.?, |
| 1256 | }; | 1238 | }; |
| 1257 | assert(n == size_u); | 1239 | assert(n == size_u); |
| ... | @@ -1367,7 +1349,7 @@ pub const File = struct { | ... | @@ -1367,7 +1349,7 @@ pub const File = struct { |
| 1367 | nav_index: InternPool.Nav.Index, | 1349 | nav_index: InternPool.Nav.Index, |
| 1368 | comptime format: []const u8, | 1350 | comptime format: []const u8, |
| 1369 | args: anytype, | 1351 | args: anytype, |
| 1370 | ) error{ CodegenFail, OutOfMemory } { | 1352 | ) Zcu.CodegenFailError { |
| 1371 | @branchHint(.cold); | 1353 | @branchHint(.cold); |
| 1372 | return base.comp.zcu.?.codegenFail(nav_index, format, args); | 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,7 +1422,7 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void { |
| 1440 | defer prog_node.end(); | 1422 | defer prog_node.end(); |
| 1441 | for (comp.link_inputs) |input| { | 1423 | for (comp.link_inputs) |input| { |
| 1442 | base.loadInput(input) catch |err| switch (err) { | 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 | else => |e| switch (input) { | 1426 | else => |e| switch (input) { |
| 1445 | .dso => |dso| diags.addParseError(dso.path, "failed to parse shared library: {s}", .{@errorName(e)}), | 1427 | .dso => |dso| diags.addParseError(dso.path, "failed to parse shared library: {s}", .{@errorName(e)}), |
| 1446 | .object => |obj| diags.addParseError(obj.path, "failed to parse object: {s}", .{@errorName(e)}), | 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,11 +1467,11 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void { |
| 1485 | .preferred_mode = .dynamic, | 1467 | .preferred_mode = .dynamic, |
| 1486 | .search_strategy = .paths_first, | 1468 | .search_strategy = .paths_first, |
| 1487 | }) catch |archive_err| switch (archive_err) { | 1469 | }) catch |archive_err| switch (archive_err) { |
| 1488 | error.LinkFailure => return, // error reported via diags | 1470 | error.AlreadyReported => return, // error reported via diags |
| 1489 | else => |e| diags.addParseError(dso_path, "failed to parse archive {f}: {s}", .{ archive_path, @errorName(e) }), | 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 | else => |e| diags.addParseError(dso_path, "failed to parse shared library: {s}", .{@errorName(e)}), | 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,7 +1486,7 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void { |
| 1504 | .preferred_mode = .static, | 1486 | .preferred_mode = .static, |
| 1505 | .search_strategy = .no_fallback, | 1487 | .search_strategy = .no_fallback, |
| 1506 | }) catch |err| switch (err) { | 1488 | }) catch |err| switch (err) { |
| 1507 | error.LinkFailure => return, // error reported via diags | 1489 | error.AlreadyReported => return, // error reported via diags |
| 1508 | else => |e| diags.addParseError(path, "failed to parse archive: {s}", .{@errorName(e)}), | 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,7 +1497,7 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void { |
| 1515 | const prog_node = comp.link_prog_node.start("Parse Object", 0); | 1497 | const prog_node = comp.link_prog_node.start("Parse Object", 0); |
| 1516 | defer prog_node.end(); | 1498 | defer prog_node.end(); |
| 1517 | base.openLoadObject(path) catch |err| switch (err) { | 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 | else => |e| diags.addParseError(path, "failed to parse object: {s}", .{@errorName(e)}), | 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,7 +1505,7 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void { |
| 1523 | const prog_node = comp.link_prog_node.start("Parse Archive", 0); | 1505 | const prog_node = comp.link_prog_node.start("Parse Archive", 0); |
| 1524 | defer prog_node.end(); | 1506 | defer prog_node.end(); |
| 1525 | base.openLoadArchive(load_archive.path, load_archive.must_link) catch |err| switch (err) { | 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 | else => |e| diags.addParseError(load_archive.path, "failed to parse archive: {s}", .{@errorName(e)}), | 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,7 +1516,7 @@ pub fn doPrelinkTask(comp: *Compilation, task: PrelinkTask) void { |
| 1534 | .preferred_mode = .dynamic, | 1516 | .preferred_mode = .dynamic, |
| 1535 | .search_strategy = .paths_first, | 1517 | .search_strategy = .paths_first, |
| 1536 | }) catch |err| switch (err) { | 1518 | }) catch |err| switch (err) { |
| 1537 | error.LinkFailure => return, // error reported via link_diags | 1519 | error.AlreadyReported => return, // error reported via link_diags |
| 1538 | else => |e| diags.addParseError(path, "failed to parse shared library: {s}", .{@errorName(e)}), | 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,15 +1543,9 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void |
| 1561 | }; | 1543 | }; |
| 1562 | } else if (comp.bin_file) |lf| { | 1544 | } else if (comp.bin_file) |lf| { |
| 1563 | lf.updateNav(pt, nav_index) catch |err| switch (err) { | 1545 | lf.updateNav(pt, nav_index) catch |err| switch (err) { |
| 1546 | error.Canceled => io.recancel(), | ||
| 1547 | error.AlreadyReported => return, | ||
| 1564 | error.OutOfMemory => diags.setAllocFailure(), | 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 | break :nav nav_index; | 1551 | break :nav nav_index; |
| ... | @@ -1594,14 +1570,9 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void | ... | @@ -1594,14 +1570,9 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void |
| 1594 | assert(zcu.llvm_object == null); // LLVM codegen doesn't produce MIR | 1570 | assert(zcu.llvm_object == null); // LLVM codegen doesn't produce MIR |
| 1595 | if (comp.bin_file) |lf| { | 1571 | if (comp.bin_file) |lf| { |
| 1596 | lf.updateFunc(pt, func, &mir) catch |err| switch (err) { | 1572 | lf.updateFunc(pt, func, &mir) catch |err| switch (err) { |
| 1573 | error.Canceled => io.recancel(), | ||
| 1574 | error.AlreadyReported => return, | ||
| 1597 | error.OutOfMemory => return diags.setAllocFailure(), | 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 | break :nav ip.indexToKey(func).func.owner_nav; | 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,7 +1589,8 @@ pub fn doZcuTask(comp: *Compilation, tid: Zcu.PerThread.Id, task: ZcuTask) void |
| 1618 | if (comp.bin_file) |lf| { | 1589 | if (comp.bin_file) |lf| { |
| 1619 | lf.updateContainerType(pt, container_update.ty, container_update.success) catch |err| switch (err) { | 1590 | lf.updateContainerType(pt, container_update.ty, container_update.success) catch |err| switch (err) { |
| 1620 | error.OutOfMemory => diags.setAllocFailure(), | 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,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 | return if (comp.bin_file) |lf| lf.idle(tid) else false; | 1633 | return if (comp.bin_file) |lf| lf.idle(tid) else false; |
| 1662 | } | 1634 | } |
| 1663 | /// After the main pipeline is done, but before flush, the compilation may need to link one final | 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,15 +1645,9 @@ pub fn linkTestFunctionsNav(pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) |
| 1673 | }; | 1645 | }; |
| 1674 | } else if (comp.bin_file) |lf| { | 1646 | } else if (comp.bin_file) |lf| { |
| 1675 | lf.updateNav(pt, nav_index) catch |err| switch (err) { | 1647 | lf.updateNav(pt, nav_index) catch |err| switch (err) { |
| 1648 | error.Canceled => comp.io.recancel(), | ||
| 1649 | error.AlreadyReported => return, | ||
| 1676 | error.OutOfMemory => diags.setAllocFailure(), | 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,7 +1655,8 @@ pub fn updateErrorData(pt: Zcu.PerThread) void { |
| 1689 | const comp = pt.zcu.comp; | 1655 | const comp = pt.zcu.comp; |
| 1690 | if (comp.bin_file) |lf| lf.updateErrorData(pt) catch |err| switch (err) { | 1656 | if (comp.bin_file) |lf| lf.updateErrorData(pt) catch |err| switch (err) { |
| 1691 | error.OutOfMemory => comp.link_diags.setAllocFailure(), | 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,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 | return .{ .object = openObject(io, path, false, false) catch |err| { | 2399 | return .{ .object = openObject(io, path, false, false) catch |err| { |
| 2433 | return diags.failParse(path, "failed to open {f}: {s}", .{ path, @errorName(err) }); | 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 | return .{ .archive = openObject(io, path, must_link, hidden) catch |err| { | 2405 | return .{ .archive = openObject(io, path, must_link, hidden) catch |err| { |
| 2439 | return diags.failParse(path, "failed to open {f}: {s}", .{ path, @errorName(err) }); | 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 | return .{ .dso = openDso(io, path, needed, weak, reexport) catch |err| { | 2411 | return .{ .dso = openDso(io, path, needed, weak, reexport) catch |err| { |
| 2445 | return diags.failParse(path, "failed to open {f}: {s}", .{ path, @errorName(err) }); | 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,7 +474,7 @@ pub fn updateContainerType( |
| 474 | pt: Zcu.PerThread, | 474 | pt: Zcu.PerThread, |
| 475 | ty: InternPool.Index, | 475 | ty: InternPool.Index, |
| 476 | success: bool, | 476 | success: bool, |
| 477 | ) link.File.UpdateContainerTypeError!void { | 477 | ) link.Error!void { |
| 478 | try c.type_pool.updateContainerType(pt, .{ .c = c }, ty, success); | 478 | try c.type_pool.updateContainerType(pt, .{ .c = c }, ty, success); |
| 479 | } | 479 | } |
| 480 | 480 | ||
| ... | @@ -570,7 +570,6 @@ pub fn updateNav( | ... | @@ -570,7 +570,6 @@ pub fn updateNav( |
| 570 | .arena = arena.allocator(), | 570 | .arena = arena.allocator(), |
| 571 | .pt = pt, | 571 | .pt = pt, |
| 572 | .mod = zcu.navFileScope(nav_index).mod.?, | 572 | .mod = zcu.navFileScope(nav_index).mod.?, |
| 573 | .error_msg = null, | ||
| 574 | .owner_nav = nav_index.toOptional(), | 573 | .owner_nav = nav_index.toOptional(), |
| 575 | .is_naked_fn = false, | 574 | .is_naked_fn = false, |
| 576 | .expected_block = null, | 575 | .expected_block = null, |
| ... | @@ -588,10 +587,7 @@ pub fn updateNav( | ... | @@ -588,10 +587,7 @@ pub fn updateNav( |
| 588 | defer c.string_bytes = aw.toArrayList(); | 587 | defer c.string_bytes = aw.toArrayList(); |
| 589 | const start = aw.written().len; | 588 | const start = aw.written().len; |
| 590 | codegen.genDeclFwd(&dg, &aw.writer) catch |err| switch (err) { | 589 | codegen.genDeclFwd(&dg, &aw.writer) catch |err| switch (err) { |
| 591 | error.AnalysisFail => switch (zcu.codegenFailMsg(nav_index, dg.error_msg.?)) { | 590 | error.AlreadyReported => return, |
| 592 | error.CodegenFail => return, | ||
| 593 | error.OutOfMemory => |e| return e, | ||
| 594 | }, | ||
| 595 | error.WriteFailed, error.OutOfMemory => return error.OutOfMemory, | 591 | error.WriteFailed, error.OutOfMemory => return error.OutOfMemory, |
| 596 | }; | 592 | }; |
| 597 | break :fwd_decl .{ | 593 | break :fwd_decl .{ |
| ... | @@ -605,10 +601,7 @@ pub fn updateNav( | ... | @@ -605,10 +601,7 @@ pub fn updateNav( |
| 605 | defer c.string_bytes = aw.toArrayList(); | 601 | defer c.string_bytes = aw.toArrayList(); |
| 606 | const start = aw.written().len; | 602 | const start = aw.written().len; |
| 607 | codegen.genDecl(&dg, &aw.writer) catch |err| switch (err) { | 603 | codegen.genDecl(&dg, &aw.writer) catch |err| switch (err) { |
| 608 | error.AnalysisFail => switch (zcu.codegenFailMsg(nav_index, dg.error_msg.?)) { | 604 | error.AlreadyReported => return, |
| 609 | error.CodegenFail => return, | ||
| 610 | error.OutOfMemory => |e| return e, | ||
| 611 | }, | ||
| 612 | error.WriteFailed, error.OutOfMemory => return error.OutOfMemory, | 605 | error.WriteFailed, error.OutOfMemory => return error.OutOfMemory, |
| 613 | }; | 606 | }; |
| 614 | break :code .{ | 607 | break :code .{ |
| ... | @@ -661,7 +654,6 @@ fn updateUav( | ... | @@ -661,7 +654,6 @@ fn updateUav( |
| 661 | .arena = arena.allocator(), | 654 | .arena = arena.allocator(), |
| 662 | .pt = pt, | 655 | .pt = pt, |
| 663 | .mod = pt.zcu.root_mod, | 656 | .mod = pt.zcu.root_mod, |
| 664 | .error_msg = null, | ||
| 665 | .owner_nav = .none, | 657 | .owner_nav = .none, |
| 666 | .is_naked_fn = false, | 658 | .is_naked_fn = false, |
| 667 | .expected_block = null, | 659 | .expected_block = null, |
| ... | @@ -683,9 +675,7 @@ fn updateUav( | ... | @@ -683,9 +675,7 @@ fn updateUav( |
| 683 | .@"threadlocal" = false, | 675 | .@"threadlocal" = false, |
| 684 | .init_val = val, | 676 | .init_val = val, |
| 685 | }) catch |err| switch (err) { | 677 | }) catch |err| switch (err) { |
| 686 | error.AnalysisFail => { | 678 | error.AlreadyReported => return, |
| 687 | @panic("TODO: CBE error.AnalysisFail on uav"); | ||
| 688 | }, | ||
| 689 | error.WriteFailed, error.OutOfMemory => return error.OutOfMemory, | 679 | error.WriteFailed, error.OutOfMemory => return error.OutOfMemory, |
| 690 | }; | 680 | }; |
| 691 | break :fwd_decl .{ | 681 | break :fwd_decl .{ |
| ... | @@ -704,9 +694,7 @@ fn updateUav( | ... | @@ -704,9 +694,7 @@ fn updateUav( |
| 704 | .@"threadlocal" = false, | 694 | .@"threadlocal" = false, |
| 705 | .init_val = val, | 695 | .init_val = val, |
| 706 | }) catch |err| switch (err) { | 696 | }) catch |err| switch (err) { |
| 707 | error.AnalysisFail => { | 697 | error.AlreadyReported => return, |
| 708 | @panic("TODO: CBE error.AnalysisFail on uav"); | ||
| 709 | }, | ||
| 710 | error.WriteFailed, error.OutOfMemory => return error.OutOfMemory, | 698 | error.WriteFailed, error.OutOfMemory => return error.OutOfMemory, |
| 711 | }; | 699 | }; |
| 712 | break :code .{ | 700 | break :code .{ |
| ... | @@ -726,7 +714,7 @@ pub fn updateLineNumber(c: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst. | ... | @@ -726,7 +714,7 @@ pub fn updateLineNumber(c: *C, pt: Zcu.PerThread, ti_id: InternPool.TrackedInst. |
| 726 | _ = ti_id; | 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 | const tracy = trace(@src()); | 718 | const tracy = trace(@src()); |
| 731 | defer tracy.end(); | 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,7 +1100,6 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog |
| 1112 | .owner_nav = .none, | 1100 | .owner_nav = .none, |
| 1113 | .is_naked_fn = false, | 1101 | .is_naked_fn = false, |
| 1114 | .expected_block = null, | 1102 | .expected_block = null, |
| 1115 | .error_msg = null, | ||
| 1116 | .ctype_deps = .empty, | 1103 | .ctype_deps = .empty, |
| 1117 | .uavs = .empty, | 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,14 +1143,14 @@ pub fn flush(c: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.Prog |
| 1156 | codegen.genLazyCallModifierFn(&lazy_dg, fn_nav, .never_tail, &lazy_decls_aw.writer) catch |err| switch (err) { | 1143 | codegen.genLazyCallModifierFn(&lazy_dg, fn_nav, .never_tail, &lazy_decls_aw.writer) catch |err| switch (err) { |
| 1157 | error.WriteFailed => return error.OutOfMemory, | 1144 | error.WriteFailed => return error.OutOfMemory, |
| 1158 | error.OutOfMemory => |e| return e, | 1145 | error.OutOfMemory => |e| return e, |
| 1159 | error.AnalysisFail => unreachable, | 1146 | error.AlreadyReported => unreachable, |
| 1160 | }; | 1147 | }; |
| 1161 | } | 1148 | } |
| 1162 | for (need_never_inline_funcs.keys()) |fn_nav| { | 1149 | for (need_never_inline_funcs.keys()) |fn_nav| { |
| 1163 | codegen.genLazyCallModifierFn(&lazy_dg, fn_nav, .never_inline, &lazy_decls_aw.writer) catch |err| switch (err) { | 1150 | codegen.genLazyCallModifierFn(&lazy_dg, fn_nav, .never_inline, &lazy_decls_aw.writer) catch |err| switch (err) { |
| 1164 | error.WriteFailed => return error.OutOfMemory, | 1151 | error.WriteFailed => return error.OutOfMemory, |
| 1165 | error.OutOfMemory => |e| return e, | 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,7 +1243,6 @@ pub fn updateExports( |
| 1256 | .owner_nav = .none, | 1243 | .owner_nav = .none, |
| 1257 | .is_naked_fn = false, | 1244 | .is_naked_fn = false, |
| 1258 | .expected_block = null, | 1245 | .expected_block = null, |
| 1259 | .error_msg = null, | ||
| 1260 | .ctype_deps = .empty, | 1246 | .ctype_deps = .empty, |
| 1261 | .uavs = .empty, | 1247 | .uavs = .empty, |
| 1262 | }; | 1248 | }; |
src/link/Coff.zig+31-60| ... | @@ -43,7 +43,6 @@ lazy: std.EnumArray(link.File.LazySymbol.Kind, struct { | ... | @@ -43,7 +43,6 @@ lazy: std.EnumArray(link.File.LazySymbol.Kind, struct { |
| 43 | }), | 43 | }), |
| 44 | pending_uavs: std.AutoArrayHashMapUnmanaged(Node.UavMapIndex, struct { | 44 | pending_uavs: std.AutoArrayHashMapUnmanaged(Node.UavMapIndex, struct { |
| 45 | alignment: InternPool.Alignment, | 45 | alignment: InternPool.Alignment, |
| 46 | src_loc: Zcu.LazySrcLoc, | ||
| 47 | }), | 46 | }), |
| 48 | relocs: std.ArrayList(Reloc), | 47 | relocs: std.ArrayList(Reloc), |
| 49 | const_prog_node: std.Progress.Node, | 48 | const_prog_node: std.Progress.Node, |
| ... | @@ -1532,11 +1531,8 @@ pub fn prelink(coff: *Coff, prog_node: std.Progress.Node) void { | ... | @@ -1532,11 +1531,8 @@ pub fn prelink(coff: *Coff, prog_node: std.Progress.Node) void { |
| 1532 | 1531 | ||
| 1533 | pub fn updateNav(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void { | 1532 | pub fn updateNav(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void { |
| 1534 | coff.updateNavInner(pt, nav_index) catch |err| switch (err) { | 1533 | coff.updateNavInner(pt, nav_index) catch |err| switch (err) { |
| 1535 | error.OutOfMemory, | 1534 | else => |e| return e, |
| 1536 | error.Overflow, | 1535 | error.MappedFileIo => return coff.base.cgFail(nav_index, "linker failed to update variable: {t}", .{coff.mf.io_err.?}), |
| 1537 | error.RelocationNotByteAligned, | ||
| 1538 | => |e| return e, | ||
| 1539 | else => |e| return coff.base.cgFail(nav_index, "linker failed to update variable: {t}", .{e}), | ||
| 1540 | }; | 1536 | }; |
| 1541 | } | 1537 | } |
| 1542 | fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void { | 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,12 +1575,11 @@ fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Inde |
| 1579 | codegen.generateSymbol( | 1575 | codegen.generateSymbol( |
| 1580 | &coff.base, | 1576 | &coff.base, |
| 1581 | pt, | 1577 | pt, |
| 1582 | zcu.navSrcLoc(nav_index), | ||
| 1583 | .fromInterned(nav.resolved.?.value), | 1578 | .fromInterned(nav.resolved.?.value), |
| 1584 | &nw.interface, | 1579 | &nw.interface, |
| 1585 | .{ .atom_index = @enumFromInt(@intFromEnum(si)) }, | 1580 | .{ .atom_index = @enumFromInt(@intFromEnum(si)) }, |
| 1586 | ) catch |err| switch (err) { | 1581 | ) catch |err| switch (err) { |
| 1587 | error.WriteFailed => return error.OutOfMemory, | 1582 | error.WriteFailed => return nw.err.?, |
| 1588 | else => |e| return e, | 1583 | else => |e| return e, |
| 1589 | }; | 1584 | }; |
| 1590 | si.get(coff).size = @intCast(nw.interface.end); | 1585 | si.get(coff).size = @intCast(nw.interface.end); |
| ... | @@ -1615,8 +1610,7 @@ pub fn lowerUav( | ... | @@ -1615,8 +1610,7 @@ pub fn lowerUav( |
| 1615 | pt: Zcu.PerThread, | 1610 | pt: Zcu.PerThread, |
| 1616 | uav_val: InternPool.Index, | 1611 | uav_val: InternPool.Index, |
| 1617 | uav_align: InternPool.Alignment, | 1612 | uav_align: InternPool.Alignment, |
| 1618 | src_loc: Zcu.LazySrcLoc, | 1613 | ) !link.File.SymbolId { |
| 1619 | ) !codegen.SymbolResult { | ||
| 1620 | const zcu = pt.zcu; | 1614 | const zcu = pt.zcu; |
| 1621 | const gpa = zcu.gpa; | 1615 | const gpa = zcu.gpa; |
| 1622 | 1616 | ||
| ... | @@ -1633,12 +1627,11 @@ pub fn lowerUav( | ... | @@ -1633,12 +1627,11 @@ pub fn lowerUav( |
| 1633 | } else { | 1627 | } else { |
| 1634 | gop.value_ptr.* = .{ | 1628 | gop.value_ptr.* = .{ |
| 1635 | .alignment = uav_align, | 1629 | .alignment = uav_align, |
| 1636 | .src_loc = src_loc, | ||
| 1637 | }; | 1630 | }; |
| 1638 | coff.const_prog_node.increaseEstimatedTotalItems(1); | 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 | pub fn updateFunc( | 1637 | pub fn updateFunc( |
| ... | @@ -1648,15 +1641,11 @@ pub fn updateFunc( | ... | @@ -1648,15 +1641,11 @@ pub fn updateFunc( |
| 1648 | mir: *const codegen.AnyMir, | 1641 | mir: *const codegen.AnyMir, |
| 1649 | ) !void { | 1642 | ) !void { |
| 1650 | coff.updateFuncInner(pt, func_index, mir) catch |err| switch (err) { | 1643 | coff.updateFuncInner(pt, func_index, mir) catch |err| switch (err) { |
| 1651 | error.OutOfMemory, | 1644 | else => |e| return e, |
| 1652 | error.Overflow, | 1645 | error.MappedFileIo => return coff.base.cgFail( |
| 1653 | error.RelocationNotByteAligned, | ||
| 1654 | error.CodegenFail, | ||
| 1655 | => |e| return e, | ||
| 1656 | else => |e| return coff.base.cgFail( | ||
| 1657 | pt.zcu.funcInfo(func_index).owner_nav, | 1646 | pt.zcu.funcInfo(func_index).owner_nav, |
| 1658 | "linker failed to update function: {s}", | 1647 | "linker failed to update function: {t}", |
| 1659 | .{@errorName(e)}, | 1648 | .{coff.mf.io_err.?}, |
| 1660 | ), | 1649 | ), |
| 1661 | }; | 1650 | }; |
| 1662 | } | 1651 | } |
| ... | @@ -1714,7 +1703,6 @@ fn updateFuncInner( | ... | @@ -1714,7 +1703,6 @@ fn updateFuncInner( |
| 1714 | codegen.emitFunction( | 1703 | codegen.emitFunction( |
| 1715 | &coff.base, | 1704 | &coff.base, |
| 1716 | pt, | 1705 | pt, |
| 1717 | zcu.navSrcLoc(func.owner_nav), | ||
| 1718 | func_index, | 1706 | func_index, |
| 1719 | @enumFromInt(@intFromEnum(si)), | 1707 | @enumFromInt(@intFromEnum(si)), |
| 1720 | mir, | 1708 | mir, |
| ... | @@ -1733,9 +1721,11 @@ pub fn updateErrorData(coff: *Coff, pt: Zcu.PerThread) !void { | ... | @@ -1733,9 +1721,11 @@ pub fn updateErrorData(coff: *Coff, pt: Zcu.PerThread) !void { |
| 1733 | .kind = .const_data, | 1721 | .kind = .const_data, |
| 1734 | .index = @intCast(coff.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return), | 1722 | .index = @intCast(coff.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return), |
| 1735 | }) catch |err| switch (err) { | 1723 | }) catch |err| switch (err) { |
| 1736 | error.OutOfMemory => |e| return e, | 1724 | else => |e| return e, |
| 1737 | error.CodegenFail => return error.LinkFailure, | 1725 | error.MappedFileIo => return coff.base.comp.link_diags.fail( |
| 1738 | else => |e| return coff.base.comp.link_diags.fail("updateErrorData failed {t}", .{e}), | 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,12 +1770,11 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 1780 | .{ .zcu = comp.zcu.?, .tid = tid }, | 1770 | .{ .zcu = comp.zcu.?, .tid = tid }, |
| 1781 | pending_uav.key, | 1771 | pending_uav.key, |
| 1782 | pending_uav.value.alignment, | 1772 | pending_uav.value.alignment, |
| 1783 | pending_uav.value.src_loc, | ||
| 1784 | ) catch |err| switch (err) { | 1773 | ) catch |err| switch (err) { |
| 1785 | error.OutOfMemory => |e| return e, | 1774 | else => |e| return e, |
| 1786 | else => |e| return comp.link_diags.fail( | 1775 | error.MappedFileIo => return comp.link_diags.fail( |
| 1787 | "linker failed to lower constant: {t}", | 1776 | "linker failed to lower constant: {t}", |
| 1788 | .{e}, | 1777 | .{coff.mf.io_err.?}, |
| 1789 | ), | 1778 | ), |
| 1790 | }; | 1779 | }; |
| 1791 | break :task; | 1780 | break :task; |
| ... | @@ -1800,10 +1789,10 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { | ... | @@ -1800,10 +1789,10 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 1800 | ); | 1789 | ); |
| 1801 | defer sub_prog_node.end(); | 1790 | defer sub_prog_node.end(); |
| 1802 | coff.flushGlobal(pt, gmi) catch |err| switch (err) { | 1791 | coff.flushGlobal(pt, gmi) catch |err| switch (err) { |
| 1803 | error.OutOfMemory => |e| return e, | 1792 | else => |e| return e, |
| 1804 | else => |e| return comp.link_diags.fail( | 1793 | error.MappedFileIo => return comp.link_diags.fail( |
| 1805 | "linker failed to lower constant: {t}", | 1794 | "linker failed to lower constant: {t}", |
| 1806 | .{e}, | 1795 | .{coff.mf.io_err.?}, |
| 1807 | ), | 1796 | ), |
| 1808 | }; | 1797 | }; |
| 1809 | break :task; | 1798 | break :task; |
| ... | @@ -1827,10 +1816,10 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { | ... | @@ -1827,10 +1816,10 @@ pub fn idle(coff: *Coff, tid: Zcu.PerThread.Id) !bool { |
| 1827 | ); | 1816 | ); |
| 1828 | defer sub_prog_node.end(); | 1817 | defer sub_prog_node.end(); |
| 1829 | coff.flushLazy(pt, lmr) catch |err| switch (err) { | 1818 | coff.flushLazy(pt, lmr) catch |err| switch (err) { |
| 1830 | error.OutOfMemory => |e| return e, | 1819 | else => |e| return e, |
| 1831 | else => |e| return comp.link_diags.fail( | 1820 | error.MappedFileIo => return comp.link_diags.fail( |
| 1832 | "linker failed to lower lazy {s}: {t}", | 1821 | "linker failed to lower lazy {s}: {t}", |
| 1833 | .{ kind, e }, | 1822 | .{ kind, coff.mf.io_err.? }, |
| 1834 | ), | 1823 | ), |
| 1835 | }; | 1824 | }; |
| 1836 | break :task; | 1825 | break :task; |
| ... | @@ -1885,7 +1874,6 @@ fn flushUav( | ... | @@ -1885,7 +1874,6 @@ fn flushUav( |
| 1885 | pt: Zcu.PerThread, | 1874 | pt: Zcu.PerThread, |
| 1886 | umi: Node.UavMapIndex, | 1875 | umi: Node.UavMapIndex, |
| 1887 | uav_align: InternPool.Alignment, | 1876 | uav_align: InternPool.Alignment, |
| 1888 | src_loc: Zcu.LazySrcLoc, | ||
| 1889 | ) !void { | 1877 | ) !void { |
| 1890 | const zcu = pt.zcu; | 1878 | const zcu = pt.zcu; |
| 1891 | const gpa = zcu.gpa; | 1879 | const gpa = zcu.gpa; |
| ... | @@ -1928,12 +1916,11 @@ fn flushUav( | ... | @@ -1928,12 +1916,11 @@ fn flushUav( |
| 1928 | codegen.generateSymbol( | 1916 | codegen.generateSymbol( |
| 1929 | &coff.base, | 1917 | &coff.base, |
| 1930 | pt, | 1918 | pt, |
| 1931 | src_loc, | ||
| 1932 | .fromInterned(uav_val), | 1919 | .fromInterned(uav_val), |
| 1933 | &nw.interface, | 1920 | &nw.interface, |
| 1934 | .{ .atom_index = @enumFromInt(@intFromEnum(si)) }, | 1921 | .{ .atom_index = @enumFromInt(@intFromEnum(si)) }, |
| 1935 | ) catch |err| switch (err) { | 1922 | ) catch |err| switch (err) { |
| 1936 | error.WriteFailed => return error.OutOfMemory, | 1923 | error.WriteFailed => return nw.err.?, |
| 1937 | else => |e| return e, | 1924 | else => |e| return e, |
| 1938 | }; | 1925 | }; |
| 1939 | si.get(coff).size = @intCast(nw.interface.end); | 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,16 +2126,18 @@ fn flushLazy(coff: *Coff, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void { |
| 2139 | var nw: MappedFile.Node.Writer = undefined; | 2126 | var nw: MappedFile.Node.Writer = undefined; |
| 2140 | ni.writer(&coff.mf, gpa, &nw); | 2127 | ni.writer(&coff.mf, gpa, &nw); |
| 2141 | defer nw.deinit(); | 2128 | defer nw.deinit(); |
| 2142 | try codegen.generateLazySymbol( | 2129 | codegen.generateLazySymbol( |
| 2143 | &coff.base, | 2130 | &coff.base, |
| 2144 | pt, | 2131 | pt, |
| 2145 | Type.fromInterned(lazy.ty).srcLocOrNull(pt.zcu) orelse .unneeded, | ||
| 2146 | lazy, | 2132 | lazy, |
| 2147 | &required_alignment, | 2133 | &required_alignment, |
| 2148 | &nw.interface, | 2134 | &nw.interface, |
| 2149 | .none, | 2135 | .none, |
| 2150 | .{ .atom_index = @enumFromInt(@intFromEnum(si)) }, | 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 | si.get(coff).size = @intCast(nw.interface.end); | 2141 | si.get(coff).size = @intCast(nw.interface.end); |
| 2153 | si.applyLocationRelocs(coff); | 2142 | si.applyLocationRelocs(coff); |
| 2154 | } | 2143 | } |
| ... | @@ -2314,17 +2303,6 @@ pub fn updateExports( | ... | @@ -2314,17 +2303,6 @@ pub fn updateExports( |
| 2314 | pt: Zcu.PerThread, | 2303 | pt: Zcu.PerThread, |
| 2315 | exported: Zcu.Exported, | 2304 | exported: Zcu.Exported, |
| 2316 | export_indices: []const Zcu.Export.Index, | 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 | ) !void { | 2306 | ) !void { |
| 2329 | const zcu = pt.zcu; | 2307 | const zcu = pt.zcu; |
| 2330 | const gpa = zcu.gpa; | 2308 | const gpa = zcu.gpa; |
| ... | @@ -2340,18 +2318,11 @@ fn updateExportsInner( | ... | @@ -2340,18 +2318,11 @@ fn updateExportsInner( |
| 2340 | try coff.symbol_table.ensureUnusedCapacity(gpa, export_indices.len); | 2318 | try coff.symbol_table.ensureUnusedCapacity(gpa, export_indices.len); |
| 2341 | const exported_si: Symbol.Index = switch (exported) { | 2319 | const exported_si: Symbol.Index = switch (exported) { |
| 2342 | .nav => |nav| try coff.navSymbol(zcu, nav), | 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 | pt, | 2322 | pt, |
| 2345 | uav, | 2323 | uav, |
| 2346 | Type.fromInterned(ip.typeOf(uav)).abiAlignment(zcu), | 2324 | Type.fromInterned(ip.typeOf(uav)).abiAlignment(zcu), |
| 2347 | export_indices[0].ptr(zcu).src, | 2325 | ))), |
| 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 | })), | ||
| 2355 | }; | 2326 | }; |
| 2356 | while (try coff.idle(pt.tid)) {} | 2327 | while (try coff.idle(pt.tid)) {} |
| 2357 | const exported_ni = exported_si.node(coff); | 2328 | const exported_ni = exported_si.node(coff); |
src/link/Dwarf.zig+24-48| ... | @@ -51,21 +51,15 @@ pub const UpdateError = error{ | ... | @@ -51,21 +51,15 @@ pub const UpdateError = error{ |
| 51 | Underflow, | 51 | Underflow, |
| 52 | UnexpectedEndOfFile, | 52 | UnexpectedEndOfFile, |
| 53 | NonResizable, | 53 | NonResizable, |
| 54 | /// TODO why is this in the error set? | 54 | Overflow, |
| 55 | ConnectionResetByPeer, | ||
| 56 | /// TODO why is this in the error set? | ||
| 57 | SocketUnconnected, | ||
| 58 | } || | 55 | } || |
| 59 | codegen.GenerateSymbolError || | 56 | link.Error || |
| 60 | Io.File.OpenError || | 57 | Io.File.OpenError || |
| 61 | Io.File.LengthError || | 58 | Io.File.LengthError || |
| 62 | Io.File.ReadPositionalError || | 59 | Io.File.ReadPositionalError || |
| 63 | Io.File.WritePositionalError; | 60 | Io.File.WritePositionalError; |
| 64 | 61 | ||
| 65 | pub const FlushError = UpdateError; | 62 | pub const RelocError = Io.File.PWriteError; |
| 66 | |||
| 67 | pub const RelocError = | ||
| 68 | Io.File.PWriteError; | ||
| 69 | 63 | ||
| 70 | pub const AddressSize = enum(u8) { | 64 | pub const AddressSize = enum(u8) { |
| 71 | @"32" = 4, | 65 | @"32" = 4, |
| ... | @@ -1579,19 +1573,17 @@ pub const WipNav = struct { | ... | @@ -1579,19 +1573,17 @@ pub const WipNav = struct { |
| 1579 | pub const LocalConstTag = enum { comptime_arg, local_const }; | 1573 | pub const LocalConstTag = enum { comptime_arg, local_const }; |
| 1580 | pub fn genLocalConstDebugInfo( | 1574 | pub fn genLocalConstDebugInfo( |
| 1581 | wip_nav: *WipNav, | 1575 | wip_nav: *WipNav, |
| 1582 | src_loc: Zcu.LazySrcLoc, | ||
| 1583 | tag: LocalConstTag, | 1576 | tag: LocalConstTag, |
| 1584 | opt_name: ?[]const u8, | 1577 | opt_name: ?[]const u8, |
| 1585 | val: Value, | 1578 | val: Value, |
| 1586 | ) UpdateError!void { | 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 | error.WriteFailed => error.OutOfMemory, | 1581 | error.WriteFailed => error.OutOfMemory, |
| 1589 | else => |e| e, | 1582 | else => |e| e, |
| 1590 | }; | 1583 | }; |
| 1591 | } | 1584 | } |
| 1592 | fn genLocalConstDebugInfoWriterError( | 1585 | fn genLocalConstDebugInfoWriterError( |
| 1593 | wip_nav: *WipNav, | 1586 | wip_nav: *WipNav, |
| 1594 | src_loc: Zcu.LazySrcLoc, | ||
| 1595 | tag: LocalConstTag, | 1587 | tag: LocalConstTag, |
| 1596 | opt_name: ?[]const u8, | 1588 | opt_name: ?[]const u8, |
| 1597 | val: Value, | 1589 | val: Value, |
| ... | @@ -1617,7 +1609,7 @@ pub const WipNav = struct { | ... | @@ -1617,7 +1609,7 @@ pub const WipNav = struct { |
| 1617 | }); | 1609 | }); |
| 1618 | if (opt_name) |name| try wip_nav.strp(name); | 1610 | if (opt_name) |name| try wip_nav.strp(name); |
| 1619 | try wip_nav.refType(ty); | 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 | if (has_comptime_state) try wip_nav.refValue(val); | 1613 | if (has_comptime_state) try wip_nav.refValue(val); |
| 1622 | wip_nav.any_children = true; | 1614 | wip_nav.any_children = true; |
| 1623 | } | 1615 | } |
| ... | @@ -2106,7 +2098,6 @@ pub const WipNav = struct { | ... | @@ -2106,7 +2098,6 @@ pub const WipNav = struct { |
| 2106 | 2098 | ||
| 2107 | fn blockValue( | 2099 | fn blockValue( |
| 2108 | wip_nav: *WipNav, | 2100 | wip_nav: *WipNav, |
| 2109 | src_loc: Zcu.LazySrcLoc, | ||
| 2110 | val: Value, | 2101 | val: Value, |
| 2111 | ) (UpdateError || Writer.Error)!void { | 2102 | ) (UpdateError || Writer.Error)!void { |
| 2112 | const ty = val.typeOf(wip_nav.pt.zcu); | 2103 | const ty = val.typeOf(wip_nav.pt.zcu); |
| ... | @@ -2118,7 +2109,6 @@ pub const WipNav = struct { | ... | @@ -2118,7 +2109,6 @@ pub const WipNav = struct { |
| 2118 | try codegen.generateSymbol( | 2109 | try codegen.generateSymbol( |
| 2119 | wip_nav.dwarf.bin_file, | 2110 | wip_nav.dwarf.bin_file, |
| 2120 | wip_nav.pt, | 2111 | wip_nav.pt, |
| 2121 | src_loc, | ||
| 2122 | val, | 2112 | val, |
| 2123 | &wip_nav.debug_info.writer, | 2113 | &wip_nav.debug_info.writer, |
| 2124 | .{ .debug_output = .{ .dwarf = wip_nav } }, | 2114 | .{ .debug_output = .{ .dwarf = wip_nav } }, |
| ... | @@ -2592,7 +2582,7 @@ pub fn initWipNav( | ... | @@ -2592,7 +2582,7 @@ pub fn initWipNav( |
| 2592 | pt: Zcu.PerThread, | 2582 | pt: Zcu.PerThread, |
| 2593 | nav_index: InternPool.Nav.Index, | 2583 | nav_index: InternPool.Nav.Index, |
| 2594 | sym_index: link.File.SymbolId, | 2584 | sym_index: link.File.SymbolId, |
| 2595 | ) error{ OutOfMemory, CodegenFail }!WipNav { | 2585 | ) error{ OutOfMemory, AlreadyReported }!WipNav { |
| 2596 | return initWipNavInner(dwarf, pt, nav_index, sym_index) catch |err| switch (err) { | 2586 | return initWipNavInner(dwarf, pt, nav_index, sym_index) catch |err| switch (err) { |
| 2597 | error.OutOfMemory => error.OutOfMemory, | 2587 | error.OutOfMemory => error.OutOfMemory, |
| 2598 | else => |e| pt.zcu.codegenFail(nav_index, "failed to init dwarf: {s}", .{@errorName(e)}), | 2588 | else => |e| pt.zcu.codegenFail(nav_index, "failed to init dwarf: {s}", .{@errorName(e)}), |
| ... | @@ -3017,7 +3007,7 @@ fn finishWipNavWriterError( | ... | @@ -3017,7 +3007,7 @@ fn finishWipNavWriterError( |
| 3017 | try dwarf.const_pool.flushPending(pt, .{ .dwarf = dwarf }); | 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 | return updateComptimeNavInner(dwarf, pt, nav_index) catch |err| switch (err) { | 3011 | return updateComptimeNavInner(dwarf, pt, nav_index) catch |err| switch (err) { |
| 3022 | error.OutOfMemory => error.OutOfMemory, | 3012 | error.OutOfMemory => error.OutOfMemory, |
| 3023 | else => |e| pt.zcu.codegenFail(nav_index, "failed to update dwarf: {s}", .{@errorName(e)}), | 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,7 +3017,6 @@ pub fn updateComptimeNav(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool |
| 3027 | fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void { | 3017 | fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void { |
| 3028 | const zcu = pt.zcu; | 3018 | const zcu = pt.zcu; |
| 3029 | const ip = &zcu.intern_pool; | 3019 | const ip = &zcu.intern_pool; |
| 3030 | const nav_src_loc = zcu.navSrcLoc(nav_index); | ||
| 3031 | 3020 | ||
| 3032 | const nav = ip.getNav(nav_index); | 3021 | const nav = ip.getNav(nav_index); |
| 3033 | const inst_info = nav.srcInst(ip).resolveFull(ip).?; | 3022 | const inst_info = nav.srcInst(ip).resolveFull(ip).?; |
| ... | @@ -3207,7 +3196,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo | ... | @@ -3207,7 +3196,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 3207 | }.toSlice(ip)); | 3196 | }.toSlice(ip)); |
| 3208 | const nav_ty = nav_val.typeOf(zcu); | 3197 | const nav_ty = nav_val.typeOf(zcu); |
| 3209 | try wip_nav.refType(nav_ty); | 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 | try diw.writeUleb128(nav.resolved.?.@"align".toByteUnits() orelse | 3200 | try diw.writeUleb128(nav.resolved.?.@"align".toByteUnits() orelse |
| 3212 | nav_ty.abiAlignment(zcu).toByteUnits().?); | 3201 | nav_ty.abiAlignment(zcu).toByteUnits().?); |
| 3213 | try diw.writeByte(@intFromBool(decl.linkage != .normal)); | 3202 | try diw.writeByte(@intFromBool(decl.linkage != .normal)); |
| ... | @@ -3241,7 +3230,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo | ... | @@ -3241,7 +3230,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo |
| 3241 | try diw.writeUleb128(nav.resolved.?.@"align".toByteUnits() orelse | 3230 | try diw.writeUleb128(nav.resolved.?.@"align".toByteUnits() orelse |
| 3242 | nav_ty.abiAlignment(zcu).toByteUnits().?); | 3231 | nav_ty.abiAlignment(zcu).toByteUnits().?); |
| 3243 | try diw.writeByte(@intFromBool(decl.linkage != .normal)); | 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 | if (has_comptime_state) try wip_nav.refValue(nav_val); | 3234 | if (has_comptime_state) try wip_nav.refValue(nav_val); |
| 3246 | wip_nav.finishForward(nav_ty_reloc_index); | 3235 | wip_nav.finishForward(nav_ty_reloc_index); |
| 3247 | try wip_nav.abbrevCode(.is_const); | 3236 | try wip_nav.abbrevCode(.is_const); |
| ... | @@ -3551,19 +3540,6 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co | ... | @@ -3551,19 +3540,6 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 3551 | }; | 3540 | }; |
| 3552 | defer wip_nav.deinit(); | 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 | const diw = &wip_nav.debug_info.writer; | 3543 | const diw = &wip_nav.debug_info.writer; |
| 3568 | var big_int_space: Value.BigIntSpace = undefined; | 3544 | var big_int_space: Value.BigIntSpace = undefined; |
| 3569 | switch (value_ip_key) { | 3545 | switch (value_ip_key) { |
| ... | @@ -3588,7 +3564,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co | ... | @@ -3588,7 +3564,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 3588 | else => if (ptr_type.sentinel == .none) .ptr_aligned_type else .ptr_aligned_sentinel_type, | 3564 | else => if (ptr_type.sentinel == .none) .ptr_aligned_type else .ptr_aligned_sentinel_type, |
| 3589 | }); | 3565 | }); |
| 3590 | try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)}); | 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 | if (ptr_type.flags.alignment.toByteUnits()) |a| try diw.writeUleb128(a); | 3568 | if (ptr_type.flags.alignment.toByteUnits()) |a| try diw.writeUleb128(a); |
| 3593 | try diw.writeByte(@intFromEnum(ptr_type.flags.address_space)); | 3569 | try diw.writeByte(@intFromEnum(ptr_type.flags.address_space)); |
| 3594 | if (ptr_type.flags.is_const or ptr_type.flags.is_volatile) try wip_nav.infoSectionOffset( | 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,7 +3609,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 3633 | const array_child_type: Type = .fromInterned(array_type.child); | 3609 | const array_child_type: Type = .fromInterned(array_type.child); |
| 3634 | try wip_nav.abbrevCode(if (array_type.sentinel == .none) .array_type else .array_sentinel_type); | 3610 | try wip_nav.abbrevCode(if (array_type.sentinel == .none) .array_type else .array_sentinel_type); |
| 3635 | try wip_nav.strpFmt("{f}", .{val.toType().fmt(pt)}); | 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 | try wip_nav.refType(array_child_type); | 3613 | try wip_nav.refType(array_child_type); |
| 3638 | try wip_nav.abbrevCode(.array_len); | 3614 | try wip_nav.abbrevCode(.array_len); |
| 3639 | try wip_nav.refType(.usize); | 3615 | try wip_nav.refType(.usize); |
| ... | @@ -3880,7 +3856,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co | ... | @@ -3880,7 +3856,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 3880 | if (has_comptime_state) | 3856 | if (has_comptime_state) |
| 3881 | try wip_nav.refValue(.fromInterned(comptime_value)) | 3857 | try wip_nav.refValue(.fromInterned(comptime_value)) |
| 3882 | else if (has_runtime_bits) | 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 | try diw.writeUleb128(@intFromEnum(AbbrevCode.null)); | 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,7 +3943,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 3967 | if (has_comptime_state) | 3943 | if (has_comptime_state) |
| 3968 | try wip_nav.refValue(.fromInterned(field_init)) | 3944 | try wip_nav.refValue(.fromInterned(field_init)) |
| 3969 | else if (has_runtime_bits) | 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 | try diw.writeUleb128(@intFromEnum(AbbrevCode.null)); | 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,7 +4308,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4332 | if (has_comptime_state) | 4308 | if (has_comptime_state) |
| 4333 | try wip_nav.refValue(.fromInterned(payload_val)) | 4309 | try wip_nav.refValue(.fromInterned(payload_val)) |
| 4334 | else | 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,7 +4476,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4500 | { | 4476 | { |
| 4501 | try wip_nav.abbrevCode(.comptime_value_field_runtime_bits); | 4477 | try wip_nav.abbrevCode(.comptime_value_field_runtime_bits); |
| 4502 | try wip_nav.strp("len"); | 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 | try diw.writeUleb128(@intFromEnum(AbbrevCode.null)); | 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,8 +4489,8 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4513 | try wip_nav.strp("has_value"); | 4489 | try wip_nav.strp("has_value"); |
| 4514 | switch (optRepr(opt_child_type, zcu)) { | 4490 | switch (optRepr(opt_child_type, zcu)) { |
| 4515 | .opv_null => try diw.writeUleb128(0), | 4491 | .opv_null => try diw.writeUleb128(0), |
| 4516 | .unpacked => try wip_nav.blockValue(src_loc, .makeBool(opt.val != .none)), | 4492 | .unpacked => try wip_nav.blockValue(.makeBool(opt.val != .none)), |
| 4517 | .error_set, .pointer => try wip_nav.blockValue(src_loc, .fromInterned(value_index)), | 4493 | .error_set, .pointer => try wip_nav.blockValue(.fromInterned(value_index)), |
| 4518 | } | 4494 | } |
| 4519 | } | 4495 | } |
| 4520 | if (opt.val != .none) child_field: { | 4496 | if (opt.val != .none) child_field: { |
| ... | @@ -4530,7 +4506,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co | ... | @@ -4530,7 +4506,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4530 | if (has_comptime_state) | 4506 | if (has_comptime_state) |
| 4531 | try wip_nav.refValue(.fromInterned(opt.val)) | 4507 | try wip_nav.refValue(.fromInterned(opt.val)) |
| 4532 | else | 4508 | else |
| 4533 | try wip_nav.blockValue(src_loc, .fromInterned(opt.val)); | 4509 | try wip_nav.blockValue(.fromInterned(opt.val)); |
| 4534 | } | 4510 | } |
| 4535 | try diw.writeUleb128(@intFromEnum(AbbrevCode.null)); | 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,7 +4537,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4561 | if (has_comptime_state) | 4537 | if (has_comptime_state) |
| 4562 | try wip_nav.refValue(field_value) | 4538 | try wip_nav.refValue(field_value) |
| 4563 | else | 4539 | else |
| 4564 | try wip_nav.blockValue(src_loc, field_value); | 4540 | try wip_nav.blockValue(field_value); |
| 4565 | } | 4541 | } |
| 4566 | }, | 4542 | }, |
| 4567 | .tuple_type => |tuple_type| for (0..tuple_type.types.len) |field_index| { | 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,7 +4564,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4588 | if (has_comptime_state) | 4564 | if (has_comptime_state) |
| 4589 | try wip_nav.refValue(field_value) | 4565 | try wip_nav.refValue(field_value) |
| 4590 | else | 4566 | else |
| 4591 | try wip_nav.blockValue(src_loc, field_value); | 4567 | try wip_nav.blockValue(field_value); |
| 4592 | }, | 4568 | }, |
| 4593 | inline .array_type, .vector_type => |sequence_type| { | 4569 | inline .array_type, .vector_type => |sequence_type| { |
| 4594 | const child_type: Type = .fromInterned(sequence_type.child); | 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,7 +4584,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4608 | if (has_comptime_state) | 4584 | if (has_comptime_state) |
| 4609 | try wip_nav.refValue(.fromInterned(elem)) | 4585 | try wip_nav.refValue(.fromInterned(elem)) |
| 4610 | else | 4586 | else |
| 4611 | try wip_nav.blockValue(src_loc, .fromInterned(elem)); | 4587 | try wip_nav.blockValue(.fromInterned(elem)); |
| 4612 | } | 4588 | } |
| 4613 | }, | 4589 | }, |
| 4614 | else => unreachable, | 4590 | else => unreachable, |
| ... | @@ -4636,7 +4612,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co | ... | @@ -4636,7 +4612,7 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4636 | if (has_comptime_state) | 4612 | if (has_comptime_state) |
| 4637 | try wip_nav.refValue(.fromInterned(un.val)) | 4613 | try wip_nav.refValue(.fromInterned(un.val)) |
| 4638 | else | 4614 | else |
| 4639 | try wip_nav.blockValue(src_loc, .fromInterned(un.val)); | 4615 | try wip_nav.blockValue(.fromInterned(un.val)); |
| 4640 | } | 4616 | } |
| 4641 | try diw.writeUleb128(@intFromEnum(AbbrevCode.null)); | 4617 | try diw.writeUleb128(@intFromEnum(AbbrevCode.null)); |
| 4642 | }, | 4618 | }, |
| ... | @@ -4708,13 +4684,13 @@ fn refAbbrevCode( | ... | @@ -4708,13 +4684,13 @@ fn refAbbrevCode( |
| 4708 | return @intFromEnum(abbrev_code); | 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 | return dwarf.flushWriterError(pt) catch |err| switch (err) { | 4688 | return dwarf.flushWriterError(pt) catch |err| switch (err) { |
| 4713 | error.WriteFailed => error.OutOfMemory, | 4689 | error.WriteFailed => error.OutOfMemory, |
| 4714 | else => |e| e, | 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 | const zcu = pt.zcu; | 4694 | const zcu = pt.zcu; |
| 4719 | const ip = &zcu.intern_pool; | 4695 | const ip = &zcu.intern_pool; |
| 4720 | const comp = dwarf.bin_file.comp; | 4696 | const comp = dwarf.bin_file.comp; |
src/link/Elf.zig+32-33| ... | @@ -476,9 +476,8 @@ pub fn lowerUav( | ... | @@ -476,9 +476,8 @@ pub fn lowerUav( |
| 476 | pt: Zcu.PerThread, | 476 | pt: Zcu.PerThread, |
| 477 | uav: InternPool.Index, | 477 | uav: InternPool.Index, |
| 478 | explicit_alignment: InternPool.Alignment, | 478 | explicit_alignment: InternPool.Alignment, |
| 479 | src_loc: Zcu.LazySrcLoc, | 479 | ) !link.File.SymbolId { |
| 480 | ) !codegen.SymbolResult { | 480 | return self.zigObjectPtr().?.lowerUav(self, pt, uav, explicit_alignment); |
| 481 | return self.zigObjectPtr().?.lowerUav(self, pt, uav, explicit_alignment, src_loc); | ||
| 482 | } | 481 | } |
| 483 | 482 | ||
| 484 | pub fn getUavVAddr(self: *Elf, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { | 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,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 | const tracy = trace(@src()); | 746 | const tracy = trace(@src()); |
| 748 | defer tracy.end(); | 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,7 +756,7 @@ pub fn flush(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std |
| 757 | defer sub_prog_node.end(); | 756 | defer sub_prog_node.end(); |
| 758 | 757 | ||
| 759 | return flushInner(self, arena, tid) catch |err| switch (err) { | 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 | else => |e| return diags.fail("ELF flush failed: {t}", .{e}), | 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,7 +783,7 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { |
| 784 | .Exe => {}, | 783 | .Exe => {}, |
| 785 | } | 784 | } |
| 786 | 785 | ||
| 787 | if (diags.hasErrors()) return error.LinkFailure; | 786 | if (diags.hasErrors()) return error.AlreadyReported; |
| 788 | 787 | ||
| 789 | // If we haven't already, create a linker-generated input file comprising of | 788 | // If we haven't already, create a linker-generated input file comprising of |
| 790 | // linker-defined synthetic symbols only such as `_DYNAMIC`, etc. | 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,7 +815,7 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { |
| 816 | } | 815 | } |
| 817 | 816 | ||
| 818 | self.checkDuplicates() catch |err| switch (err) { | 817 | self.checkDuplicates() catch |err| switch (err) { |
| 819 | error.HasDuplicates => return error.LinkFailure, | 818 | error.HasDuplicates => return error.AlreadyReported, |
| 820 | else => |e| return e, | 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,7 +902,7 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { |
| 903 | error.RelocFailure, error.RelaxFailure => has_reloc_errors = true, | 902 | error.RelocFailure, error.RelaxFailure => has_reloc_errors = true, |
| 904 | error.UnsupportedCpuArch => { | 903 | error.UnsupportedCpuArch => { |
| 905 | try self.reportUnsupportedCpuArch(); | 904 | try self.reportUnsupportedCpuArch(); |
| 906 | return error.LinkFailure; | 905 | return error.AlreadyReported; |
| 907 | }, | 906 | }, |
| 908 | else => |e| return e, | 907 | else => |e| return e, |
| 909 | }; | 908 | }; |
| ... | @@ -912,7 +911,7 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { | ... | @@ -912,7 +911,7 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { |
| 912 | 911 | ||
| 913 | try self.reportUndefinedSymbols(&undefs); | 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 | try self.writePhdrTable(); | 917 | try self.writePhdrTable(); |
| ... | @@ -921,10 +920,10 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { | ... | @@ -921,10 +920,10 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { |
| 921 | try self.writeMergeSections(); | 920 | try self.writeMergeSections(); |
| 922 | 921 | ||
| 923 | self.writeSyntheticSections() catch |err| switch (err) { | 922 | self.writeSyntheticSections() catch |err| switch (err) { |
| 924 | error.RelocFailure => return error.LinkFailure, | 923 | error.RelocFailure => return error.AlreadyReported, |
| 925 | error.UnsupportedCpuArch => { | 924 | error.UnsupportedCpuArch => { |
| 926 | try self.reportUnsupportedCpuArch(); | 925 | try self.reportUnsupportedCpuArch(); |
| 927 | return error.LinkFailure; | 926 | return error.AlreadyReported; |
| 928 | }, | 927 | }, |
| 929 | else => |e| return e, | 928 | else => |e| return e, |
| 930 | }; | 929 | }; |
| ... | @@ -938,7 +937,7 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { | ... | @@ -938,7 +937,7 @@ fn flushInner(self: *Elf, arena: Allocator, tid: Zcu.PerThread.Id) !void { |
| 938 | try self.writeElfHeader(); | 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 | fn dumpArgvInit(self: *Elf, arena: Allocator) !void { | 943 | fn dumpArgvInit(self: *Elf, arena: Allocator) !void { |
| ... | @@ -1053,7 +1052,7 @@ pub fn openParseObjectReportingFailure(self: *Elf, path: Path) void { | ... | @@ -1053,7 +1052,7 @@ pub fn openParseObjectReportingFailure(self: *Elf, path: Path) void { |
| 1053 | const diags = &comp.link_diags; | 1052 | const diags = &comp.link_diags; |
| 1054 | const obj = link.openObject(io, path, false, false) catch |err| { | 1053 | const obj = link.openObject(io, path, false, false) catch |err| { |
| 1055 | switch (diags.failParse(path, "failed to open object: {t}", .{err})) { | 1054 | switch (diags.failParse(path, "failed to open object: {t}", .{err})) { |
| 1056 | error.LinkFailure => return, | 1055 | error.AlreadyReported => return, |
| 1057 | } | 1056 | } |
| 1058 | }; | 1057 | }; |
| 1059 | self.parseObjectReportingFailure(obj); | 1058 | self.parseObjectReportingFailure(obj); |
| ... | @@ -1063,7 +1062,7 @@ fn parseObjectReportingFailure(self: *Elf, obj: link.Input.Object) void { | ... | @@ -1063,7 +1062,7 @@ fn parseObjectReportingFailure(self: *Elf, obj: link.Input.Object) void { |
| 1063 | const comp = self.base.comp; | 1062 | const comp = self.base.comp; |
| 1064 | const diags = &comp.link_diags; | 1063 | const diags = &comp.link_diags; |
| 1065 | self.parseObject(obj) catch |err| switch (err) { | 1064 | self.parseObject(obj) catch |err| switch (err) { |
| 1066 | error.LinkFailure => return, // already reported | 1065 | error.AlreadyReported => return, // already reported |
| 1067 | else => |e| diags.addParseError(obj.path, "failed to parse object: {t}", .{e}), | 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,7 +1342,7 @@ fn scanRelocs(self: *Elf) !void { |
| 1343 | error.RelaxFailure => unreachable, | 1342 | error.RelaxFailure => unreachable, |
| 1344 | error.UnsupportedCpuArch => { | 1343 | error.UnsupportedCpuArch => { |
| 1345 | try self.reportUnsupportedCpuArch(); | 1344 | try self.reportUnsupportedCpuArch(); |
| 1346 | return error.LinkFailure; | 1345 | return error.AlreadyReported; |
| 1347 | }, | 1346 | }, |
| 1348 | error.RelocFailure => has_reloc_errors = true, | 1347 | error.RelocFailure => has_reloc_errors = true, |
| 1349 | else => |e| return e, | 1348 | else => |e| return e, |
| ... | @@ -1354,7 +1353,7 @@ fn scanRelocs(self: *Elf) !void { | ... | @@ -1354,7 +1353,7 @@ fn scanRelocs(self: *Elf) !void { |
| 1354 | error.RelaxFailure => unreachable, | 1353 | error.RelaxFailure => unreachable, |
| 1355 | error.UnsupportedCpuArch => { | 1354 | error.UnsupportedCpuArch => { |
| 1356 | try self.reportUnsupportedCpuArch(); | 1355 | try self.reportUnsupportedCpuArch(); |
| 1357 | return error.LinkFailure; | 1356 | return error.AlreadyReported; |
| 1358 | }, | 1357 | }, |
| 1359 | error.RelocFailure => has_reloc_errors = true, | 1358 | error.RelocFailure => has_reloc_errors = true, |
| 1360 | else => |e| return e, | 1359 | else => |e| return e, |
| ... | @@ -1363,7 +1362,7 @@ fn scanRelocs(self: *Elf) !void { | ... | @@ -1363,7 +1362,7 @@ fn scanRelocs(self: *Elf) !void { |
| 1363 | 1362 | ||
| 1364 | try self.reportUndefinedSymbols(&undefs); | 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 | if (self.zigObjectPtr()) |zo| { | 1367 | if (self.zigObjectPtr()) |zo| { |
| 1369 | try zo.asFile().createSymbolIndirection(self); | 1368 | try zo.asFile().createSymbolIndirection(self); |
| ... | @@ -1690,7 +1689,7 @@ pub fn updateFunc( | ... | @@ -1690,7 +1689,7 @@ pub fn updateFunc( |
| 1690 | pt: Zcu.PerThread, | 1689 | pt: Zcu.PerThread, |
| 1691 | func_index: InternPool.Index, | 1690 | func_index: InternPool.Index, |
| 1692 | mir: *const codegen.AnyMir, | 1691 | mir: *const codegen.AnyMir, |
| 1693 | ) link.File.UpdateNavError!void { | 1692 | ) link.Error!void { |
| 1694 | return self.zigObjectPtr().?.updateFunc(self, pt, func_index, mir); | 1693 | return self.zigObjectPtr().?.updateFunc(self, pt, func_index, mir); |
| 1695 | } | 1694 | } |
| 1696 | 1695 | ||
| ... | @@ -1698,7 +1697,7 @@ pub fn updateNav( | ... | @@ -1698,7 +1697,7 @@ pub fn updateNav( |
| 1698 | self: *Elf, | 1697 | self: *Elf, |
| 1699 | pt: Zcu.PerThread, | 1698 | pt: Zcu.PerThread, |
| 1700 | nav: InternPool.Nav.Index, | 1699 | nav: InternPool.Nav.Index, |
| 1701 | ) link.File.UpdateNavError!void { | 1700 | ) link.Error!void { |
| 1702 | return self.zigObjectPtr().?.updateNav(self, pt, nav); | 1701 | return self.zigObjectPtr().?.updateNav(self, pt, nav); |
| 1703 | } | 1702 | } |
| 1704 | 1703 | ||
| ... | @@ -1707,7 +1706,7 @@ pub fn updateContainerType( | ... | @@ -1707,7 +1706,7 @@ pub fn updateContainerType( |
| 1707 | pt: Zcu.PerThread, | 1706 | pt: Zcu.PerThread, |
| 1708 | ty: InternPool.Index, | 1707 | ty: InternPool.Index, |
| 1709 | success: bool, | 1708 | success: bool, |
| 1710 | ) link.File.UpdateContainerTypeError!void { | 1709 | ) link.Error!void { |
| 1711 | return self.zigObjectPtr().?.updateContainerType(pt, ty, success) catch |err| switch (err) { | 1710 | return self.zigObjectPtr().?.updateContainerType(pt, ty, success) catch |err| switch (err) { |
| 1712 | error.OutOfMemory => |e| return e, | 1711 | error.OutOfMemory => |e| return e, |
| 1713 | }; | 1712 | }; |
| ... | @@ -1718,11 +1717,11 @@ pub fn updateExports( | ... | @@ -1718,11 +1717,11 @@ pub fn updateExports( |
| 1718 | pt: Zcu.PerThread, | 1717 | pt: Zcu.PerThread, |
| 1719 | exported: Zcu.Exported, | 1718 | exported: Zcu.Exported, |
| 1720 | export_indices: []const Zcu.Export.Index, | 1719 | export_indices: []const Zcu.Export.Index, |
| 1721 | ) link.File.UpdateExportsError!void { | 1720 | ) link.Error!void { |
| 1722 | return self.zigObjectPtr().?.updateExports(self, pt, exported, export_indices); | 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 | return self.zigObjectPtr().?.updateLineNumber(pt, ti_id); | 1725 | return self.zigObjectPtr().?.updateLineNumber(pt, ti_id); |
| 1727 | } | 1726 | } |
| 1728 | 1727 | ||
| ... | @@ -1784,12 +1783,12 @@ pub fn resolveMergeSections(self: *Elf) !void { | ... | @@ -1784,12 +1783,12 @@ pub fn resolveMergeSections(self: *Elf) !void { |
| 1784 | if (!object.alive) continue; | 1783 | if (!object.alive) continue; |
| 1785 | if (!object.dirty) continue; | 1784 | if (!object.dirty) continue; |
| 1786 | object.initInputMergeSections(self) catch |err| switch (err) { | 1785 | object.initInputMergeSections(self) catch |err| switch (err) { |
| 1787 | error.LinkFailure => has_errors = true, | 1786 | error.AlreadyReported => has_errors = true, |
| 1788 | else => |e| return e, | 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 | for (self.objects.items) |index| { | 1793 | for (self.objects.items) |index| { |
| 1795 | const object = self.file(index).?.object; | 1794 | const object = self.file(index).?.object; |
| ... | @@ -1803,12 +1802,12 @@ pub fn resolveMergeSections(self: *Elf) !void { | ... | @@ -1803,12 +1802,12 @@ pub fn resolveMergeSections(self: *Elf) !void { |
| 1803 | if (!object.alive) continue; | 1802 | if (!object.alive) continue; |
| 1804 | if (!object.dirty) continue; | 1803 | if (!object.dirty) continue; |
| 1805 | object.resolveMergeSubsections(self) catch |err| switch (err) { | 1804 | object.resolveMergeSubsections(self) catch |err| switch (err) { |
| 1806 | error.LinkFailure => has_errors = true, | 1805 | error.AlreadyReported => has_errors = true, |
| 1807 | else => |e| return e, | 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 | pub fn finalizeMergeSections(self: *Elf) !void { | 1813 | pub fn finalizeMergeSections(self: *Elf) !void { |
| ... | @@ -2998,7 +2997,7 @@ fn writeAtoms(self: *Elf) !void { | ... | @@ -2998,7 +2997,7 @@ fn writeAtoms(self: *Elf) !void { |
| 2998 | atom_list.write(&buffer, &undefs, self) catch |err| switch (err) { | 2997 | atom_list.write(&buffer, &undefs, self) catch |err| switch (err) { |
| 2999 | error.UnsupportedCpuArch => { | 2998 | error.UnsupportedCpuArch => { |
| 3000 | try self.reportUnsupportedCpuArch(); | 2999 | try self.reportUnsupportedCpuArch(); |
| 3001 | return error.LinkFailure; | 3000 | return error.AlreadyReported; |
| 3002 | }, | 3001 | }, |
| 3003 | error.RelocFailure, error.RelaxFailure => has_reloc_errors = true, | 3002 | error.RelocFailure, error.RelaxFailure => has_reloc_errors = true, |
| 3004 | else => |e| return e, | 3003 | else => |e| return e, |
| ... | @@ -3006,7 +3005,7 @@ fn writeAtoms(self: *Elf) !void { | ... | @@ -3006,7 +3005,7 @@ fn writeAtoms(self: *Elf) !void { |
| 3006 | } | 3005 | } |
| 3007 | 3006 | ||
| 3008 | try self.reportUndefinedSymbols(&undefs); | 3007 | try self.reportUndefinedSymbols(&undefs); |
| 3009 | if (has_reloc_errors) return error.LinkFailure; | 3008 | if (has_reloc_errors) return error.AlreadyReported; |
| 3010 | 3009 | ||
| 3011 | if (self.requiresThunks()) { | 3010 | if (self.requiresThunks()) { |
| 3012 | for (self.thunks.items) |th| { | 3011 | for (self.thunks.items) |th| { |
| ... | @@ -3838,9 +3837,9 @@ pub fn failFile( | ... | @@ -3838,9 +3837,9 @@ pub fn failFile( |
| 3838 | file_index: File.Index, | 3837 | file_index: File.Index, |
| 3839 | comptime format: []const u8, | 3838 | comptime format: []const u8, |
| 3840 | args: anytype, | 3839 | args: anytype, |
| 3841 | ) error{ OutOfMemory, LinkFailure } { | 3840 | ) error{ OutOfMemory, AlreadyReported } { |
| 3842 | try addFileError(self, file_index, format, args); | 3841 | try addFileError(self, file_index, format, args); |
| 3843 | return error.LinkFailure; | 3842 | return error.AlreadyReported; |
| 3844 | } | 3843 | } |
| 3845 | 3844 | ||
| 3846 | const FormatShdr = struct { | 3845 | const FormatShdr = struct { |
| ... | @@ -4409,7 +4408,7 @@ pub fn stringTableLookup(strtab: []const u8, off: u32) [:0]const u8 { | ... | @@ -4409,7 +4408,7 @@ pub fn stringTableLookup(strtab: []const u8, off: u32) [:0]const u8 { |
| 4409 | return slice[0..mem.indexOfScalar(u8, slice, 0).? :0]; | 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 | const comp = elf_file.base.comp; | 4412 | const comp = elf_file.base.comp; |
| 4414 | const io = comp.io; | 4413 | const io = comp.io; |
| 4415 | const diags = &comp.link_diags; | 4414 | const diags = &comp.link_diags; |
| ... | @@ -4417,7 +4416,7 @@ pub fn pwriteAll(elf_file: *Elf, bytes: []const u8, offset: u64) error{LinkFailu | ... | @@ -4417,7 +4416,7 @@ pub fn pwriteAll(elf_file: *Elf, bytes: []const u8, offset: u64) error{LinkFailu |
| 4417 | return diags.fail("failed to write: {t}", .{err}); | 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 | const comp = elf_file.base.comp; | 4420 | const comp = elf_file.base.comp; |
| 4422 | const io = comp.i; | 4421 | const io = comp.i; |
| 4423 | const diags = &comp.link_diags; | 4422 | const diags = &comp.link_diags; |
| ... | @@ -4426,7 +4425,7 @@ pub fn setLength(elf_file: *Elf, length: u64) error{LinkFailure}!void { | ... | @@ -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 | return std.math.cast(T, x) orelse { | 4429 | return std.math.cast(T, x) orelse { |
| 4431 | const comp = elf_file.base.comp; | 4430 | const comp = elf_file.base.comp; |
| 4432 | const diags = &comp.link_diags; | 4431 | const diags = &comp.link_diags; |
src/link/Elf/Object.zig+6-6| ... | @@ -282,7 +282,7 @@ pub fn validateEFlags( | ... | @@ -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 | else => {}, | 287 | else => {}, |
| 288 | } | 288 | } |
| ... | @@ -829,7 +829,7 @@ pub fn initInputMergeSections(self: *Object, elf_file: *Elf) !void { | ... | @@ -829,7 +829,7 @@ pub fn initInputMergeSections(self: *Object, elf_file: *Elf) !void { |
| 829 | var err = try diags.addErrorWithNotes(1); | 829 | var err = try diags.addErrorWithNotes(1); |
| 830 | try err.addMsg("string not null terminated", .{}); | 830 | try err.addMsg("string not null terminated", .{}); |
| 831 | err.addNote("in {f}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) }); | 831 | err.addNote("in {f}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) }); |
| 832 | return error.LinkFailure; | 832 | return error.AlreadyReported; |
| 833 | } | 833 | } |
| 834 | end += sh_entsize; | 834 | end += sh_entsize; |
| 835 | const string = data[start..end]; | 835 | const string = data[start..end]; |
| ... | @@ -844,7 +844,7 @@ pub fn initInputMergeSections(self: *Object, elf_file: *Elf) !void { | ... | @@ -844,7 +844,7 @@ pub fn initInputMergeSections(self: *Object, elf_file: *Elf) !void { |
| 844 | var err = try diags.addErrorWithNotes(1); | 844 | var err = try diags.addErrorWithNotes(1); |
| 845 | try err.addMsg("size not a multiple of sh_entsize", .{}); | 845 | try err.addMsg("size not a multiple of sh_entsize", .{}); |
| 846 | err.addNote("in {f}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) }); | 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 | var pos: u32 = 0; | 850 | var pos: u32 = 0; |
| ... | @@ -873,7 +873,7 @@ pub fn initOutputMergeSections(self: *Object, elf_file: *Elf) !void { | ... | @@ -873,7 +873,7 @@ pub fn initOutputMergeSections(self: *Object, elf_file: *Elf) !void { |
| 873 | } | 873 | } |
| 874 | 874 | ||
| 875 | pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) error{ | 875 | pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) error{ |
| 876 | LinkFailure, | 876 | AlreadyReported, |
| 877 | OutOfMemory, | 877 | OutOfMemory, |
| 878 | /// TODO report the error and remove this | 878 | /// TODO report the error and remove this |
| 879 | Overflow, | 879 | Overflow, |
| ... | @@ -925,7 +925,7 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) error{ | ... | @@ -925,7 +925,7 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) error{ |
| 925 | try err.addMsg("invalid symbol value: {x}", .{esym.st_value}); | 925 | try err.addMsg("invalid symbol value: {x}", .{esym.st_value}); |
| 926 | err.addNote("for symbol {s}", .{sym.name(elf_file)}); | 926 | err.addNote("for symbol {s}", .{sym.name(elf_file)}); |
| 927 | err.addNote("in {f}", .{self.fmtPath()}); | 927 | err.addNote("in {f}", .{self.fmtPath()}); |
| 928 | return error.LinkFailure; | 928 | return error.AlreadyReported; |
| 929 | }; | 929 | }; |
| 930 | 930 | ||
| 931 | sym.ref = .{ .index = res.msub_index, .file = imsec.merge_section_index }; | 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,7 +950,7 @@ pub fn resolveMergeSubsections(self: *Object, elf_file: *Elf) error{ |
| 950 | var err = try diags.addErrorWithNotes(1); | 950 | var err = try diags.addErrorWithNotes(1); |
| 951 | try err.addMsg("invalid relocation at offset 0x{x}", .{rel.r_offset}); | 951 | try err.addMsg("invalid relocation at offset 0x{x}", .{rel.r_offset}); |
| 952 | err.addNote("in {f}:{s}", .{ self.fmtPath(), atom_ptr.name(elf_file) }); | 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 | const sym_index = try self.addSymbol(gpa); | 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,24 +272,18 @@ pub fn flush(self: *ZigObject, elf_file: *Elf, tid: Zcu.PerThread.Id) !void { |
| 272 | 272 | ||
| 273 | // Most lazy symbols can be updated on first use, but | 273 | // Most lazy symbols can be updated on first use, but |
| 274 | // anyerror needs to wait for everything to be flushed. | 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 | elf_file, | 276 | elf_file, |
| 277 | pt, | 277 | pt, |
| 278 | .{ .kind = .code, .ty = .anyerror_type }, | 278 | .{ .kind = .code, .ty = .anyerror_type }, |
| 279 | metadata.text_symbol_index, | 279 | metadata.text_symbol_index, |
| 280 | ) catch |err| switch (err) { | 280 | ); |
| 281 | error.CodegenFail => return error.LinkFailure, | 281 | if (metadata.rodata_state != .unused) try self.updateLazySymbol( |
| 282 | else => |e| return e, | ||
| 283 | }; | ||
| 284 | if (metadata.rodata_state != .unused) self.updateLazySymbol( | ||
| 285 | elf_file, | 282 | elf_file, |
| 286 | pt, | 283 | pt, |
| 287 | .{ .kind = .const_data, .ty = .anyerror_type }, | 284 | .{ .kind = .const_data, .ty = .anyerror_type }, |
| 288 | metadata.rodata_symbol_index, | 285 | metadata.rodata_symbol_index, |
| 289 | ) catch |err| switch (err) { | 286 | ); |
| 290 | error.CodegenFail => return error.LinkFailure, | ||
| 291 | else => |e| return e, | ||
| 292 | }; | ||
| 293 | } | 287 | } |
| 294 | for (self.lazy_syms.values()) |*metadata| { | 288 | for (self.lazy_syms.values()) |*metadata| { |
| 295 | if (metadata.text_state != .unused) metadata.text_state = .flushed; | 289 | if (metadata.text_state != .unused) metadata.text_state = .flushed; |
| ... | @@ -999,8 +993,7 @@ pub fn lowerUav( | ... | @@ -999,8 +993,7 @@ pub fn lowerUav( |
| 999 | pt: Zcu.PerThread, | 993 | pt: Zcu.PerThread, |
| 1000 | uav: InternPool.Index, | 994 | uav: InternPool.Index, |
| 1001 | explicit_alignment: InternPool.Alignment, | 995 | explicit_alignment: InternPool.Alignment, |
| 1002 | src_loc: Zcu.LazySrcLoc, | 996 | ) !link.File.SymbolId { |
| 1003 | ) !codegen.SymbolResult { | ||
| 1004 | const zcu = pt.zcu; | 997 | const zcu = pt.zcu; |
| 1005 | const gpa = zcu.gpa; | 998 | const gpa = zcu.gpa; |
| 1006 | const val = Value.fromInterned(uav); | 999 | const val = Value.fromInterned(uav); |
| ... | @@ -1013,7 +1006,7 @@ pub fn lowerUav( | ... | @@ -1013,7 +1006,7 @@ pub fn lowerUav( |
| 1013 | const sym = self.symbol(metadata.symbol_index); | 1006 | const sym = self.symbol(metadata.symbol_index); |
| 1014 | const existing_alignment = sym.atom(elf_file).?.alignment; | 1007 | const existing_alignment = sym.atom(elf_file).?.alignment; |
| 1015 | if (uav_alignment.order(existing_alignment).compare(.lte)) | 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 | const osec = if (self.data_relro_index) |sym_index| | 1012 | const osec = if (self.data_relro_index) |sym_index| |
| ... | @@ -1033,31 +1026,25 @@ pub fn lowerUav( | ... | @@ -1033,31 +1026,25 @@ pub fn lowerUav( |
| 1033 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ | 1026 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ |
| 1034 | @intFromEnum(uav), | 1027 | @intFromEnum(uav), |
| 1035 | }) catch unreachable; | 1028 | }) catch unreachable; |
| 1036 | const res = self.lowerConst( | 1029 | const sym_index = self.lowerConst( |
| 1037 | elf_file, | 1030 | elf_file, |
| 1038 | pt, | 1031 | pt, |
| 1039 | name, | 1032 | name, |
| 1040 | val, | 1033 | val, |
| 1041 | uav_alignment, | 1034 | uav_alignment, |
| 1042 | osec, | 1035 | osec, |
| 1043 | src_loc, | ||
| 1044 | ) catch |err| switch (err) { | 1036 | ) catch |err| switch (err) { |
| 1045 | error.OutOfMemory => |e| return e, | 1037 | error.OutOfMemory => |e| return e, |
| 1046 | else => |e| return .{ .fail = try Zcu.ErrorMsg.create( | 1038 | else => |e| return elf_file.base.comp.link_diags.fail( |
| 1047 | gpa, | 1039 | "failed to lower constant value: {t}", |
| 1048 | src_loc, | 1040 | .{e}, |
| 1049 | "unable to lower constant value: {s}", | 1041 | ), |
| 1050 | .{@errorName(e)}, | ||
| 1051 | ) }, | ||
| 1052 | }; | 1042 | }; |
| 1053 | switch (res) { | 1043 | try self.uavs.put(gpa, uav, .{ |
| 1054 | .sym_index => |sym_index| try self.uavs.put(gpa, uav, .{ | 1044 | .symbol_index = @intFromEnum(sym_index), |
| 1055 | .symbol_index = @intFromEnum(sym_index), | 1045 | .allocated = true, |
| 1056 | .allocated = true, | 1046 | }); |
| 1057 | }), | 1047 | return sym_index; |
| 1058 | .fail => {}, | ||
| 1059 | } | ||
| 1060 | return res; | ||
| 1061 | } | 1048 | } |
| 1062 | 1049 | ||
| 1063 | pub fn getOrCreateMetadataForLazySymbol( | 1050 | pub fn getOrCreateMetadataForLazySymbol( |
| ... | @@ -1370,7 +1357,7 @@ fn updateNavCode( | ... | @@ -1370,7 +1357,7 @@ fn updateNavCode( |
| 1370 | shdr_index: u32, | 1357 | shdr_index: u32, |
| 1371 | code: []const u8, | 1358 | code: []const u8, |
| 1372 | stt_bits: u8, | 1359 | stt_bits: u8, |
| 1373 | ) link.File.UpdateNavError!void { | 1360 | ) link.Error!void { |
| 1374 | const zcu = pt.zcu; | 1361 | const zcu = pt.zcu; |
| 1375 | const gpa = zcu.gpa; | 1362 | const gpa = zcu.gpa; |
| 1376 | const comp = elf_file.base.comp; | 1363 | const comp = elf_file.base.comp; |
| ... | @@ -1473,7 +1460,7 @@ fn updateTlv( | ... | @@ -1473,7 +1460,7 @@ fn updateTlv( |
| 1473 | sym_index: Symbol.Index, | 1460 | sym_index: Symbol.Index, |
| 1474 | shndx: u32, | 1461 | shndx: u32, |
| 1475 | code: []const u8, | 1462 | code: []const u8, |
| 1476 | ) link.File.UpdateNavError!void { | 1463 | ) link.Error!void { |
| 1477 | const zcu = pt.zcu; | 1464 | const zcu = pt.zcu; |
| 1478 | const ip = &zcu.intern_pool; | 1465 | const ip = &zcu.intern_pool; |
| 1479 | const gpa = zcu.gpa; | 1466 | const gpa = zcu.gpa; |
| ... | @@ -1531,7 +1518,7 @@ pub fn updateFunc( | ... | @@ -1531,7 +1518,7 @@ pub fn updateFunc( |
| 1531 | pt: Zcu.PerThread, | 1518 | pt: Zcu.PerThread, |
| 1532 | func_index: InternPool.Index, | 1519 | func_index: InternPool.Index, |
| 1533 | mir: *const codegen.AnyMir, | 1520 | mir: *const codegen.AnyMir, |
| 1534 | ) link.File.UpdateNavError!void { | 1521 | ) link.Error!void { |
| 1535 | const tracy = trace(@src()); | 1522 | const tracy = trace(@src()); |
| 1536 | defer tracy.end(); | 1523 | defer tracy.end(); |
| 1537 | 1524 | ||
| ... | @@ -1558,7 +1545,6 @@ pub fn updateFunc( | ... | @@ -1558,7 +1545,6 @@ pub fn updateFunc( |
| 1558 | codegen.emitFunction( | 1545 | codegen.emitFunction( |
| 1559 | &elf_file.base, | 1546 | &elf_file.base, |
| 1560 | pt, | 1547 | pt, |
| 1561 | zcu.navSrcLoc(func.owner_nav), | ||
| 1562 | func_index, | 1548 | func_index, |
| 1563 | @enumFromInt(sym_index), | 1549 | @enumFromInt(sym_index), |
| 1564 | mir, | 1550 | mir, |
| ... | @@ -1645,7 +1631,7 @@ pub fn updateNav( | ... | @@ -1645,7 +1631,7 @@ pub fn updateNav( |
| 1645 | elf_file: *Elf, | 1631 | elf_file: *Elf, |
| 1646 | pt: Zcu.PerThread, | 1632 | pt: Zcu.PerThread, |
| 1647 | nav_index: InternPool.Nav.Index, | 1633 | nav_index: InternPool.Nav.Index, |
| 1648 | ) link.File.UpdateNavError!void { | 1634 | ) link.Error!void { |
| 1649 | const tracy = trace(@src()); | 1635 | const tracy = trace(@src()); |
| 1650 | defer tracy.end(); | 1636 | defer tracy.end(); |
| 1651 | 1637 | ||
| ... | @@ -1670,7 +1656,7 @@ pub fn updateNav( | ... | @@ -1670,7 +1656,7 @@ pub fn updateNav( |
| 1670 | var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, @enumFromInt(sym_index)); | 1656 | var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, @enumFromInt(sym_index)); |
| 1671 | defer debug_wip_nav.deinit(); | 1657 | defer debug_wip_nav.deinit(); |
| 1672 | dwarf.finishWipNav(pt, nav_index, &debug_wip_nav) catch |err| switch (err) { | 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 | else => |e| return elf_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}), | 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,7 +1677,6 @@ pub fn updateNav( |
| 1691 | codegen.generateSymbol( | 1677 | codegen.generateSymbol( |
| 1692 | &elf_file.base, | 1678 | &elf_file.base, |
| 1693 | pt, | 1679 | pt, |
| 1694 | zcu.navSrcLoc(nav_index), | ||
| 1695 | .fromInterned(nav.resolved.?.value), | 1680 | .fromInterned(nav.resolved.?.value), |
| 1696 | &aw.writer, | 1681 | &aw.writer, |
| 1697 | .{ .atom_index = @enumFromInt(sym_index) }, | 1682 | .{ .atom_index = @enumFromInt(sym_index) }, |
| ... | @@ -1713,7 +1698,7 @@ pub fn updateNav( | ... | @@ -1713,7 +1698,7 @@ pub fn updateNav( |
| 1713 | try self.updateNavCode(elf_file, pt, nav_index, sym_index, shndx, code, elf.STT_OBJECT); | 1698 | try self.updateNavCode(elf_file, pt, nav_index, sym_index, shndx, code, elf.STT_OBJECT); |
| 1714 | 1699 | ||
| 1715 | if (debug_wip_nav) |*wip_nav| self.dwarf.?.finishWipNav(pt, nav_index, wip_nav) catch |err| switch (err) { | 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 | else => |e| return elf_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}), | 1702 | else => |e| return elf_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}), |
| 1718 | }; | 1703 | }; |
| 1719 | } else if (self.dwarf) |*dwarf| try dwarf.updateComptimeNav(pt, nav_index); | 1704 | } else if (self.dwarf) |*dwarf| try dwarf.updateComptimeNav(pt, nav_index); |
| ... | @@ -1759,7 +1744,6 @@ fn updateLazySymbol( | ... | @@ -1759,7 +1744,6 @@ fn updateLazySymbol( |
| 1759 | codegen.generateLazySymbol( | 1744 | codegen.generateLazySymbol( |
| 1760 | &elf_file.base, | 1745 | &elf_file.base, |
| 1761 | pt, | 1746 | pt, |
| 1762 | Type.fromInterned(sym.ty).srcLocOrNull(zcu) orelse .unneeded, | ||
| 1763 | sym, | 1747 | sym, |
| 1764 | &required_alignment, | 1748 | &required_alignment, |
| 1765 | &aw.writer, | 1749 | &aw.writer, |
| ... | @@ -1827,8 +1811,7 @@ fn lowerConst( | ... | @@ -1827,8 +1811,7 @@ fn lowerConst( |
| 1827 | val: Value, | 1811 | val: Value, |
| 1828 | required_alignment: InternPool.Alignment, | 1812 | required_alignment: InternPool.Alignment, |
| 1829 | output_section_index: u32, | 1813 | output_section_index: u32, |
| 1830 | src_loc: Zcu.LazySrcLoc, | 1814 | ) !link.File.SymbolId { |
| 1831 | ) !codegen.SymbolResult { | ||
| 1832 | const gpa = pt.zcu.gpa; | 1815 | const gpa = pt.zcu.gpa; |
| 1833 | 1816 | ||
| 1834 | var aw: std.Io.Writer.Allocating = .init(gpa); | 1817 | var aw: std.Io.Writer.Allocating = .init(gpa); |
| ... | @@ -1840,7 +1823,6 @@ fn lowerConst( | ... | @@ -1840,7 +1823,6 @@ fn lowerConst( |
| 1840 | codegen.generateSymbol( | 1823 | codegen.generateSymbol( |
| 1841 | &elf_file.base, | 1824 | &elf_file.base, |
| 1842 | pt, | 1825 | pt, |
| 1843 | src_loc, | ||
| 1844 | val, | 1826 | val, |
| 1845 | &aw.writer, | 1827 | &aw.writer, |
| 1846 | .{ .atom_index = @enumFromInt(sym_index) }, | 1828 | .{ .atom_index = @enumFromInt(sym_index) }, |
| ... | @@ -1865,7 +1847,7 @@ fn lowerConst( | ... | @@ -1865,7 +1847,7 @@ fn lowerConst( |
| 1865 | 1847 | ||
| 1866 | try elf_file.pwriteAll(code, atom_ptr.offset(elf_file)); | 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 | pub fn updateExports( | 1853 | pub fn updateExports( |
| ... | @@ -1874,7 +1856,7 @@ pub fn updateExports( | ... | @@ -1874,7 +1856,7 @@ pub fn updateExports( |
| 1874 | pt: Zcu.PerThread, | 1856 | pt: Zcu.PerThread, |
| 1875 | exported: Zcu.Exported, | 1857 | exported: Zcu.Exported, |
| 1876 | export_indices: []const Zcu.Export.Index, | 1858 | export_indices: []const Zcu.Export.Index, |
| 1877 | ) link.File.UpdateExportsError!void { | 1859 | ) link.Error!void { |
| 1878 | const tracy = trace(@src()); | 1860 | const tracy = trace(@src()); |
| 1879 | defer tracy.end(); | 1861 | defer tracy.end(); |
| 1880 | 1862 | ||
| ... | @@ -1886,18 +1868,7 @@ pub fn updateExports( | ... | @@ -1886,18 +1868,7 @@ pub fn updateExports( |
| 1886 | break :blk self.navs.getPtr(nav).?; | 1868 | break :blk self.navs.getPtr(nav).?; |
| 1887 | }, | 1869 | }, |
| 1888 | .uav => |uav| self.uavs.getPtr(uav) orelse blk: { | 1870 | .uav => |uav| self.uavs.getPtr(uav) orelse blk: { |
| 1889 | const first_exp = export_indices[0].ptr(zcu); | 1871 | _ = try self.lowerUav(elf_file, pt, uav, .none); |
| 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 | } | ||
| 1901 | break :blk self.uavs.getPtr(uav).?; | 1872 | break :blk self.uavs.getPtr(uav).?; |
| 1902 | }, | 1873 | }, |
| 1903 | }; | 1874 | }; |
| ... | @@ -1962,12 +1933,12 @@ pub fn updateExports( | ... | @@ -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 | if (self.dwarf) |*dwarf| { | 1937 | if (self.dwarf) |*dwarf| { |
| 1967 | const comp = dwarf.bin_file.comp; | 1938 | const comp = dwarf.bin_file.comp; |
| 1968 | const diags = &comp.link_diags; | 1939 | const diags = &comp.link_diags; |
| 1969 | dwarf.updateLineNumber(pt.zcu, ti_id) catch |err| switch (err) { | 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 | else => |e| return diags.fail("failed to update dwarf line numbers: {s}", .{@errorName(e)}), | 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,7 +23,7 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void { |
| 23 | const io = comp.io; | 23 | const io = comp.io; |
| 24 | const diags = &comp.link_diags; | 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 | // First, we flush relocatable object file generated with our backends. | 28 | // First, we flush relocatable object file generated with our backends. |
| 29 | if (elf_file.zigObjectPtr()) |zig_object| { | 29 | if (elf_file.zigObjectPtr()) |zig_object| { |
| ... | @@ -151,13 +151,13 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void { | ... | @@ -151,13 +151,13 @@ pub fn flushStaticLib(elf_file: *Elf, comp: *Compilation) !void { |
| 151 | try elf_file.base.file.?.setLength(io, total_size); | 151 | try elf_file.base.file.?.setLength(io, total_size); |
| 152 | try elf_file.base.file.?.writePositionalAll(io, writer.buffered(), 0); | 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 | pub fn flushObject(elf_file: *Elf, comp: *Compilation) !void { | 157 | pub fn flushObject(elf_file: *Elf, comp: *Compilation) !void { |
| 158 | const diags = &comp.link_diags; | 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 | // Now, we are ready to resolve the symbols across all input files. | 162 | // Now, we are ready to resolve the symbols across all input files. |
| 163 | // We will first resolve the files in the ZigObject, next in the parsed | 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,7 +203,7 @@ pub fn flushObject(elf_file: *Elf, comp: *Compilation) !void { |
| 203 | try elf_file.writeShdrTable(); | 203 | try elf_file.writeShdrTable(); |
| 204 | try elf_file.writeElfHeader(); | 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 | fn claimUnresolved(elf_file: *Elf) void { | 209 | fn claimUnresolved(elf_file: *Elf) void { |
src/link/Elf2.zig+295-212| ... | @@ -162,6 +162,8 @@ const_prog_node: std.Progress.Node, | ... | @@ -162,6 +162,8 @@ const_prog_node: std.Progress.Node, |
| 162 | synth_prog_node: std.Progress.Node, | 162 | synth_prog_node: std.Progress.Node, |
| 163 | input_prog_node: std.Progress.Node, | 163 | input_prog_node: std.Progress.Node, |
| 164 | 164 | ||
| 165 | const Error = link.Error || error{MappedFileIo}; | ||
| 166 | |||
| 165 | const Node = union(enum) { | 167 | const Node = union(enum) { |
| 166 | file, | 168 | file, |
| 167 | ehdr, | 169 | ehdr, |
| ... | @@ -478,7 +480,7 @@ const Section = struct { | ... | @@ -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 | const shstrtab_entry = try elf.string(.shstrtab, new_name); | 484 | const shstrtab_entry = try elf.string(.shstrtab, new_name); |
| 483 | switch (elf.shdrPtr(shndx)) { | 485 | switch (elf.shdrPtr(shndx)) { |
| 484 | inline else => |shdr| elf.targetStore(&shdr.name, @intFromEnum(shstrtab_entry)), | 486 | inline else => |shdr| elf.targetStore(&shdr.name, @intFromEnum(shstrtab_entry)), |
| ... | @@ -487,7 +489,7 @@ const Section = struct { | ... | @@ -487,7 +489,7 @@ const Section = struct { |
| 487 | 489 | ||
| 488 | /// Asserts that `shndx` is a `SHT_RELA` section and ensures that its node has enough unused | 490 | /// Asserts that `shndx` is a `SHT_RELA` section and ensures that its node has enough unused |
| 489 | /// space to hold `n` additional `ElfN.Rela` entries. | 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 | const node = rela_shndx.get(elf).ni; | 493 | const node = rela_shndx.get(elf).ni; |
| 492 | const need_size: u64 = switch (elf.shdrPtr(rela_shndx)) { | 494 | const need_size: u64 = switch (elf.shdrPtr(rela_shndx)) { |
| 493 | inline else => |shdr, class| need_size: { | 495 | inline else => |shdr, class| need_size: { |
| ... | @@ -509,11 +511,7 @@ const Section = struct { | ... | @@ -509,11 +511,7 @@ const Section = struct { |
| 509 | break :need_size cur_size + need_additional * ent_size; | 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); | 514 | try elf.ensureNodeSize(node, need_size); |
| 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 | } | ||
| 517 | } | 515 | } |
| 518 | 516 | ||
| 519 | /// Asserts that `shndx` is a `SHT_RELA` section and deletes the `ElfN.Rela` entry at the | 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,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 | const gpa = elf.base.comp.gpa; | 1194 | const gpa = elf.base.comp.gpa; |
| 1197 | 1195 | ||
| 1198 | try elf.symtab.ensureUnusedCapacity(gpa, len); | 1196 | try elf.symtab.ensureUnusedCapacity(gpa, len); |
| ... | @@ -1210,11 +1208,7 @@ fn ensureUnusedSymbolCapacity(elf: *Elf, len: u32, kind: enum { all_local, maybe | ... | @@ -1210,11 +1208,7 @@ fn ensureUnusedSymbolCapacity(elf: *Elf, len: u32, kind: enum { all_local, maybe |
| 1210 | const need_node_size: u64 = switch (elf.shdrPtr(.symtab)) { | 1208 | const need_node_size: u64 = switch (elf.shdrPtr(.symtab)) { |
| 1211 | inline else => |shdr, class| elf.targetLoad(&shdr.size) + len * @sizeOf(class.ElfN().Sym), | 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); | 1211 | try elf.ensureNodeSize(Section.Index.symtab.get(elf).ni, need_node_size); |
| 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 | } | ||
| 1218 | } | 1212 | } |
| 1219 | 1213 | ||
| 1220 | switch (kind) { | 1214 | switch (kind) { |
| ... | @@ -1232,18 +1226,14 @@ fn ensureUnusedSymbolCapacity(elf: *Elf, len: u32, kind: enum { all_local, maybe | ... | @@ -1232,18 +1226,14 @@ fn ensureUnusedSymbolCapacity(elf: *Elf, len: u32, kind: enum { all_local, maybe |
| 1232 | const dynsym_need_size: u64 = switch (elf.shdrPtr(elf.shndx.dynsym)) { | 1226 | const dynsym_need_size: u64 = switch (elf.shdrPtr(elf.shndx.dynsym)) { |
| 1233 | inline else => |shdr, class| elf.targetLoad(&shdr.size) + len * @sizeOf(class.ElfN().Sym), | 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); | 1229 | try elf.ensureNodeSize(elf.shndx.dynsym.get(elf).ni, dynsym_need_size); |
| 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 | } | ||
| 1240 | 1230 | ||
| 1241 | try elf.ensureUnusedPltCapacity(len); | 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 | const gpa = elf.base.comp.gpa; | 1237 | const gpa = elf.base.comp.gpa; |
| 1248 | 1238 | ||
| 1249 | try elf.shndx.rela_plt.relaEnsureAdditionalCapacity(elf, len); | 1239 | try elf.shndx.rela_plt.relaEnsureAdditionalCapacity(elf, len); |
| ... | @@ -1256,30 +1246,18 @@ fn ensureUnusedPltCapacity(elf: *Elf, len: u32) !void { | ... | @@ -1256,30 +1246,18 @@ fn ensureUnusedPltCapacity(elf: *Elf, len: u32) !void { |
| 1256 | .X86_64 => { | 1246 | .X86_64 => { |
| 1257 | // Ensure the `.plt` section's node is big enough | 1247 | // Ensure the `.plt` section's node is big enough |
| 1258 | const plt_need_size: usize = 16 * (1 + need_plt_capacity); | 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); | 1249 | try elf.ensureNodeSize(elf.shndx.plt.get(elf).ni, plt_need_size); |
| 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 | } | ||
| 1264 | 1250 | ||
| 1265 | // Ensure the `.got.plt` section's node is big enough | 1251 | // Ensure the `.got.plt` section's node is big enough |
| 1266 | const got_plt_need_size: usize = switch (elf.identClass()) { | 1252 | const got_plt_need_size: usize = switch (elf.identClass()) { |
| 1267 | .NONE, _ => unreachable, | 1253 | .NONE, _ => unreachable, |
| 1268 | inline else => |class| @sizeOf(class.ElfN().Addr) * (3 + need_plt_capacity), | 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); | 1256 | try elf.ensureNodeSize(elf.shndx.got_plt.get(elf).ni, got_plt_need_size); |
| 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 | } | ||
| 1275 | 1257 | ||
| 1276 | // Ensure the `.plt.sec` section's node is big enough | 1258 | // Ensure the `.plt.sec` section's node is big enough |
| 1277 | const plt_sec_need_size: usize = 16 * need_plt_capacity; | 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); | 1260 | try elf.ensureNodeSize(elf.shndx.plt_sec.get(elf).ni, plt_sec_need_size); |
| 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 | } | ||
| 1283 | }, | 1261 | }, |
| 1284 | } | 1262 | } |
| 1285 | } | 1263 | } |
| ... | @@ -1375,7 +1353,7 @@ const AddGlobalSymbolOptions = struct { | ... | @@ -1375,7 +1353,7 @@ const AddGlobalSymbolOptions = struct { |
| 1375 | const Name = struct { | 1353 | const Name = struct { |
| 1376 | strtab: String(.strtab), | 1354 | strtab: String(.strtab), |
| 1377 | dynstr: String(.dynstr), | 1355 | dynstr: String(.dynstr), |
| 1378 | fn string(elf: *Elf, slice: []const u8) !Name { | 1356 | fn string(elf: *Elf, slice: []const u8) Error!Name { |
| 1379 | return .{ | 1357 | return .{ |
| 1380 | .strtab = try elf.string(.strtab, slice), | 1358 | .strtab = try elf.string(.strtab, slice), |
| 1381 | .dynstr = switch (elf.shndx.dynsym) { | 1359 | .dynstr = switch (elf.shndx.dynsym) { |
| ... | @@ -2205,7 +2183,14 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId { | ... | @@ -2205,7 +2183,14 @@ pub fn symbolForAtom(elf: *Elf, atom: link.File.AtomId) link.File.SymbolId { |
| 2205 | const s: Symbol.Id = .local(lsi); | 2183 | const s: Symbol.Id = .local(lsi); |
| 2206 | return s.toTypeErased(); | 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 | const gpa = elf.base.comp.gpa; | 2194 | const gpa = elf.base.comp.gpa; |
| 2210 | 2195 | ||
| 2211 | try elf.ensureUnusedSymbolCapacity(1, .all_local); | 2196 | try elf.ensureUnusedSymbolCapacity(1, .all_local); |
| ... | @@ -2246,13 +2231,21 @@ pub fn lazySymbol(elf: *Elf, lazy: link.File.LazySymbol) !link.File.SymbolId { | ... | @@ -2246,13 +2231,21 @@ pub fn lazySymbol(elf: *Elf, lazy: link.File.LazySymbol) !link.File.SymbolId { |
| 2246 | const s: Symbol.Id = .local(gop.value_ptr.lsi); | 2231 | const s: Symbol.Id = .local(gop.value_ptr.lsi); |
| 2247 | return s.toTypeErased(); | 2232 | return s.toTypeErased(); |
| 2248 | } | 2233 | } |
| 2249 | pub fn externSymbol(elf: *Elf, opts: struct { | 2234 | pub const ExternSymbolOpts = struct { |
| 2250 | name: []const u8, | 2235 | name: []const u8, |
| 2251 | lib_name: ?[]const u8, | 2236 | lib_name: ?[]const u8, |
| 2252 | type: std.elf.STT, | 2237 | type: std.elf.STT, |
| 2253 | linkage: std.lang.GlobalLinkage = .strong, | 2238 | linkage: std.lang.GlobalLinkage = .strong, |
| 2254 | visibility: std.lang.SymbolVisibility = .default, | 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 | try elf.ensureUnusedSymbolCapacity(1, .maybe_global); | 2249 | try elf.ensureUnusedSymbolCapacity(1, .maybe_global); |
| 2257 | const symbol = elf.addGlobalSymbolAssumeCapacity(.{ | 2250 | const symbol = elf.addGlobalSymbolAssumeCapacity(.{ |
| 2258 | .node = .none, | 2251 | .node = .none, |
| ... | @@ -2265,7 +2258,7 @@ pub fn externSymbol(elf: *Elf, opts: struct { | ... | @@ -2265,7 +2258,7 @@ pub fn externSymbol(elf: *Elf, opts: struct { |
| 2265 | .internal => @panic("TODO internal extern symbol"), | 2258 | .internal => @panic("TODO internal extern symbol"), |
| 2266 | .strong => .strong, | 2259 | .strong => .strong, |
| 2267 | .weak => .weak, | 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 | .visibility = switch (opts.visibility) { | 2263 | .visibility = switch (opts.visibility) { |
| 2271 | .default => .DEFAULT, | 2264 | .default => .DEFAULT, |
| ... | @@ -2285,12 +2278,20 @@ pub fn addReloc( | ... | @@ -2285,12 +2278,20 @@ pub fn addReloc( |
| 2285 | target: link.File.SymbolId, | 2278 | target: link.File.SymbolId, |
| 2286 | addend: i64, | 2279 | addend: i64, |
| 2287 | @"type": MachineRelocType, | 2280 | @"type": MachineRelocType, |
| 2288 | ) !void { | 2281 | ) link.Error!void { |
| 2289 | const node: MappedFile.Node.Index = Node.fromAtom(atom); | 2282 | const node: MappedFile.Node.Index = Node.fromAtom(atom); |
| 2290 | try elf.ensureUnusedRelocCapacity(node, 1); | 2283 | const diags = &elf.base.comp.link_diags; |
| 2291 | try elf.addRelocAssumeCapacity(node, offset, .fromTypeErased(target), addend, @"type"); | 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 | const zcu = elf.base.comp.zcu.?; | 2295 | const zcu = elf.base.comp.zcu.?; |
| 2295 | const ip = &zcu.intern_pool; | 2296 | const ip = &zcu.intern_pool; |
| 2296 | const nav = ip.getNav(nav_index); | 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,7 +2304,10 @@ pub fn navSymbol(elf: *Elf, nav_index: InternPool.Nav.Index) !link.File.SymbolId |
| 2303 | .visibility = @"extern".visibility, | 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 | const s: Symbol.Id = .local(nmi.symbol(elf)); | 2311 | const s: Symbol.Id = .local(nmi.symbol(elf)); |
| 2308 | return s.toTypeErased(); | 2312 | return s.toTypeErased(); |
| 2309 | } | 2313 | } |
| ... | @@ -2311,8 +2315,12 @@ pub fn uavSymbol( | ... | @@ -2311,8 +2315,12 @@ pub fn uavSymbol( |
| 2311 | elf: *Elf, | 2315 | elf: *Elf, |
| 2312 | uav_val: InternPool.Index, | 2316 | uav_val: InternPool.Index, |
| 2313 | uav_align: InternPool.Alignment, | 2317 | uav_align: InternPool.Alignment, |
| 2314 | ) !link.File.SymbolId { | 2318 | ) link.Error!link.File.SymbolId { |
| 2315 | const umi = try elf.uavMapIndex(uav_val, uav_align); | 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 | const s: Symbol.Id = .local(umi.symbol(elf)); | 2324 | const s: Symbol.Id = .local(umi.symbol(elf)); |
| 2317 | return s.toTypeErased(); | 2325 | return s.toTypeErased(); |
| 2318 | } | 2326 | } |
| ... | @@ -2321,7 +2329,7 @@ pub fn getNavVAddr( | ... | @@ -2321,7 +2329,7 @@ pub fn getNavVAddr( |
| 2321 | pt: Zcu.PerThread, | 2329 | pt: Zcu.PerThread, |
| 2322 | nav: InternPool.Nav.Index, | 2330 | nav: InternPool.Nav.Index, |
| 2323 | reloc_info: link.File.RelocInfo, | 2331 | reloc_info: link.File.RelocInfo, |
| 2324 | ) !u64 { | 2332 | ) link.Error!u64 { |
| 2325 | _ = pt; | 2333 | _ = pt; |
| 2326 | return elf.getVAddr(reloc_info, try elf.navSymbol(nav)); | 2334 | return elf.getVAddr(reloc_info, try elf.navSymbol(nav)); |
| 2327 | } | 2335 | } |
| ... | @@ -2329,41 +2337,33 @@ pub fn getUavVAddr( | ... | @@ -2329,41 +2337,33 @@ pub fn getUavVAddr( |
| 2329 | elf: *Elf, | 2337 | elf: *Elf, |
| 2330 | uav_val: InternPool.Index, | 2338 | uav_val: InternPool.Index, |
| 2331 | reloc_info: link.File.RelocInfo, | 2339 | reloc_info: link.File.RelocInfo, |
| 2332 | ) !u64 { | 2340 | ) link.Error!u64 { |
| 2333 | return elf.getVAddr(reloc_info, try elf.uavSymbol(uav_val, .none)); | 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 { | 2343 | pub fn getVAddr(elf: *Elf, reloc_info: link.File.RelocInfo, target: link.File.SymbolId) link.Error!u64 { |
| 2336 | const node: MappedFile.Node.Index = Node.fromAtom(reloc_info.parent.atom_index); | 2344 | try elf.addReloc( |
| 2337 | const target_sym: Symbol.Id = .fromTypeErased(target); | 2345 | reloc_info.parent.atom_index, |
| 2338 | try elf.ensureUnusedRelocCapacity(node, 1); | ||
| 2339 | try elf.addRelocAssumeCapacity( | ||
| 2340 | node, | ||
| 2341 | reloc_info.offset, | 2346 | reloc_info.offset, |
| 2342 | target_sym, | 2347 | target, |
| 2343 | reloc_info.addend, | 2348 | reloc_info.addend, |
| 2344 | .absAddr(elf), | 2349 | .absAddr(elf), |
| 2345 | ); | 2350 | ); |
| 2346 | return target_sym.value(elf); | 2351 | return Symbol.Id.fromTypeErased(target).value(elf); |
| 2347 | } | 2352 | } |
| 2348 | pub fn lowerUav( | 2353 | pub fn lowerUav( |
| 2349 | elf: *Elf, | 2354 | elf: *Elf, |
| 2350 | pt: Zcu.PerThread, | 2355 | pt: Zcu.PerThread, |
| 2351 | uav_val: InternPool.Index, | 2356 | uav_val: InternPool.Index, |
| 2352 | uav_align: InternPool.Alignment, | 2357 | uav_align: InternPool.Alignment, |
| 2353 | src_loc: Zcu.LazySrcLoc, | 2358 | ) link.Error!link.File.SymbolId { |
| 2354 | ) !codegen.SymbolResult { | ||
| 2355 | _ = pt; | 2359 | _ = pt; |
| 2360 | const diags = &elf.base.comp.link_diags; | ||
| 2356 | const umi = elf.uavMapIndex(uav_val, uav_align) catch |err| switch (err) { | 2361 | const umi = elf.uavMapIndex(uav_val, uav_align) catch |err| switch (err) { |
| 2357 | error.OutOfMemory => |e| return e, | 2362 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 2358 | else => |e| return .{ .fail = try Zcu.ErrorMsg.create( | 2363 | else => |e| return e, |
| 2359 | elf.base.comp.gpa, | ||
| 2360 | src_loc, | ||
| 2361 | "linker failed to update constant: {s}", | ||
| 2362 | .{@errorName(e)}, | ||
| 2363 | ) }, | ||
| 2364 | }; | 2364 | }; |
| 2365 | const s: Symbol.Id = .local(umi.symbol(elf)); | 2365 | const s: Symbol.Id = .local(umi.symbol(elf)); |
| 2366 | return .{ .sym_index = s.toTypeErased() }; | 2366 | return s.toTypeErased(); |
| 2367 | } | 2367 | } |
| 2368 | 2368 | ||
| 2369 | const StringSection = enum { | 2369 | const StringSection = enum { |
| ... | @@ -2390,7 +2390,7 @@ fn String(section: StringSection) type { | ... | @@ -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 | const st: *StringTable = &@field(elf, @tagName(section)); | 2394 | const st: *StringTable = &@field(elf, @tagName(section)); |
| 2395 | return @enumFromInt(try st.get(elf, section.shndx(elf), key)); | 2395 | return @enumFromInt(try st.get(elf, section.shndx(elf), key)); |
| 2396 | } | 2396 | } |
| ... | @@ -2424,7 +2424,7 @@ const StringTable = struct { | ... | @@ -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 | // If we are in `initHeaders` the strtab might not be initalized yet, so we need to special | 2428 | // If we are in `initHeaders` the strtab might not be initalized yet, so we need to special |
| 2429 | // case the empty string. | 2429 | // case the empty string. |
| 2430 | if (key.len == 0) return 0; | 2430 | if (key.len == 0) return 0; |
| ... | @@ -2450,9 +2450,7 @@ const StringTable = struct { | ... | @@ -2450,9 +2450,7 @@ const StringTable = struct { |
| 2450 | if (shndx == elf.shndx.dynstr) { | 2450 | if (shndx == elf.shndx.dynstr) { |
| 2451 | elf.updateDynamicEntry(std.elf.DT_STRSZ, new_size); | 2451 | elf.updateDynamicEntry(std.elf.DT_STRSZ, new_size); |
| 2452 | } | 2452 | } |
| 2453 | _, const node_size = ni.location(&elf.mf).resolve(&elf.mf); | 2453 | try elf.ensureNodeSize(ni, new_size); |
| 2454 | if (new_size > node_size) | ||
| 2455 | try ni.resize(&elf.mf, gpa, new_size +| new_size / MappedFile.growth_factor); | ||
| 2456 | const slice = ni.slice(&elf.mf)[old_size..]; | 2454 | const slice = ni.slice(&elf.mf)[old_size..]; |
| 2457 | @memcpy(slice[0..key.len], key); | 2455 | @memcpy(slice[0..key.len], key); |
| 2458 | slice[key.len] = 0; | 2456 | slice[key.len] = 0; |
| ... | @@ -3615,7 +3613,13 @@ fn mapInputSection(elf: *Elf, opts: struct { | ... | @@ -3615,7 +3613,13 @@ fn mapInputSection(elf: *Elf, opts: struct { |
| 3615 | flags: std.elf.SHF, | 3613 | flags: std.elf.SHF, |
| 3616 | addralign: std.elf.Xword, | 3614 | addralign: std.elf.Xword, |
| 3617 | entsize: std.elf.Xword, | 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 | const gpa = elf.base.comp.gpa; | 3623 | const gpa = elf.base.comp.gpa; |
| 3620 | if (opts.flags.INFO_LINK or | 3624 | if (opts.flags.INFO_LINK or |
| 3621 | opts.flags.LINK_ORDER or | 3625 | opts.flags.LINK_ORDER or |
| ... | @@ -3733,7 +3737,7 @@ fn mapInputSection(elf: *Elf, opts: struct { | ... | @@ -3733,7 +3737,7 @@ fn mapInputSection(elf: *Elf, opts: struct { |
| 3733 | } | 3737 | } |
| 3734 | return existing_shndx; | 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 | const gpa = zcu.gpa; | 3741 | const gpa = zcu.gpa; |
| 3738 | const ip = &zcu.intern_pool; | 3742 | const ip = &zcu.intern_pool; |
| 3739 | const nav = ip.getNav(nav_index); | 3743 | const nav = ip.getNav(nav_index); |
| ... | @@ -3826,7 +3830,7 @@ fn uavMapIndex( | ... | @@ -3826,7 +3830,7 @@ fn uavMapIndex( |
| 3826 | elf: *Elf, | 3830 | elf: *Elf, |
| 3827 | uav_val: InternPool.Index, | 3831 | uav_val: InternPool.Index, |
| 3828 | uav_align: InternPool.Alignment, | 3832 | uav_align: InternPool.Alignment, |
| 3829 | ) !Node.UavMapIndex { | 3833 | ) Error!Node.UavMapIndex { |
| 3830 | const gpa = elf.base.comp.gpa; | 3834 | const gpa = elf.base.comp.gpa; |
| 3831 | const zcu = elf.base.comp.zcu.?; | 3835 | const zcu = elf.base.comp.zcu.?; |
| 3832 | 3836 | ||
| ... | @@ -3878,26 +3882,78 @@ fn uavMapIndex( | ... | @@ -3878,26 +3882,78 @@ fn uavMapIndex( |
| 3878 | return umi; | 3882 | return umi; |
| 3879 | } | 3883 | } |
| 3880 | 3884 | ||
| 3881 | pub fn loadInput(elf: *Elf, input: link.Input) (Io.File.Reader.SizeError || | 3885 | /// Internal error set used by input parsing functions `loadObject`, `loadArchive`, `loadDso`. |
| 3882 | Io.File.Reader.Error || MappedFile.Error || error{ EndOfStream, BadMagic, LinkFailure })!void { | 3886 | const LoadParseInputError = Error || Io.File.SeekError || Io.Reader.Error; |
| 3883 | const io = elf.base.comp.io; | 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 | var buf: [4096]u8 = undefined; | 3904 | var buf: [4096]u8 = undefined; |
| 3885 | switch (input) { | 3905 | switch (input) { |
| 3886 | .object => |object| { | 3906 | .object => |object| { |
| 3887 | var fr = object.file.reader(io, &buf); | 3907 | var fr = object.file.reader(io, &buf); |
| 3888 | elf.loadObject(object.path, null, &fr, .{ | 3908 | elf.loadObject(object.path, null, &fr, .{ |
| 3889 | .offset = fr.logicalPos(), | 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 | }) catch |err| switch (err) { | 3917 | }) catch |err| switch (err) { |
| 3892 | error.ReadFailed => return fr.err.?, | ||
| 3893 | else => |e| return e, | 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 | .archive => |archive| { | 3937 | .archive => |archive| { |
| 3897 | var fr = archive.file.reader(io, &buf); | 3938 | var fr = archive.file.reader(io, &buf); |
| 3898 | elf.loadArchive(archive.path, &fr) catch |err| switch (err) { | 3939 | elf.loadArchive(archive.path, &fr) catch |err| switch (err) { |
| 3899 | error.ReadFailed => return fr.err.?, | ||
| 3900 | else => |e| return e, | 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 | .res => unreachable, | 3959 | .res => unreachable, |
| ... | @@ -3905,8 +3961,23 @@ pub fn loadInput(elf: *Elf, input: link.Input) (Io.File.Reader.SizeError || | ... | @@ -3905,8 +3961,23 @@ pub fn loadInput(elf: *Elf, input: link.Input) (Io.File.Reader.SizeError || |
| 3905 | try elf.needed.ensureUnusedCapacity(elf.base.comp.gpa, 1); | 3961 | try elf.needed.ensureUnusedCapacity(elf.base.comp.gpa, 1); |
| 3906 | var fr = dso.file.reader(io, &buf); | 3962 | var fr = dso.file.reader(io, &buf); |
| 3907 | elf.loadDso(dso.path, &fr) catch |err| switch (err) { | 3963 | elf.loadDso(dso.path, &fr) catch |err| switch (err) { |
| 3908 | error.ReadFailed => return fr.err.?, | ||
| 3909 | else => |e| return e, | 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 | .dso_exact => |dso_exact| { | 3983 | .dso_exact => |dso_exact| { |
| ... | @@ -3919,14 +3990,22 @@ pub fn loadInput(elf: *Elf, input: link.Input) (Io.File.Reader.SizeError || | ... | @@ -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 | const comp = elf.base.comp; | 3994 | const comp = elf.base.comp; |
| 3924 | const gpa = comp.gpa; | 3995 | const gpa = comp.gpa; |
| 3925 | const diags = &comp.link_diags; | 3996 | const diags = &comp.link_diags; |
| 3926 | const r = &fr.interface; | 3997 | const r = &fr.interface; |
| 3927 | 3998 | ||
| 3928 | log.debug("loadArchive({f})", .{path.fmtEscapeString()}); | 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 | var strtab: std.Io.Writer.Allocating = .init(gpa); | 4009 | var strtab: std.Io.Writer.Allocating = .init(gpa); |
| 3931 | defer strtab.deinit(); | 4010 | defer strtab.deinit(); |
| 3932 | while (r.takeStruct(std.elf.ar_hdr, native_endian)) |header| { | 4011 | while (r.takeStruct(std.elf.ar_hdr, native_endian)) |header| { |
| ... | @@ -3987,7 +4066,7 @@ fn loadObject( | ... | @@ -3987,7 +4066,7 @@ fn loadObject( |
| 3987 | member: ?[]const u8, | 4066 | member: ?[]const u8, |
| 3988 | fr: *Io.File.Reader, | 4067 | fr: *Io.File.Reader, |
| 3989 | fl: MappedFile.Node.FileLocation, | 4068 | fl: MappedFile.Node.FileLocation, |
| 3990 | ) !void { | 4069 | ) LoadParseInputError!void { |
| 3991 | const comp = elf.base.comp; | 4070 | const comp = elf.base.comp; |
| 3992 | const gpa = comp.gpa; | 4071 | const gpa = comp.gpa; |
| 3993 | const diags = &comp.link_diags; | 4072 | const diags = &comp.link_diags; |
| ... | @@ -3995,7 +4074,14 @@ fn loadObject( | ... | @@ -3995,7 +4074,14 @@ fn loadObject( |
| 3995 | 4074 | ||
| 3996 | const input_index: Node.InputIndex = @enumFromInt(elf.inputs.items.len); | 4075 | const input_index: Node.InputIndex = @enumFromInt(elf.inputs.items.len); |
| 3997 | log.debug("loadObject({f}{f})", .{ path.fmtEscapeString(), fmtMemberString(member) }); | 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 | try elf.ensureUnusedSymbolCapacity(1, .all_local); | 4085 | try elf.ensureUnusedSymbolCapacity(1, .all_local); |
| 4000 | try elf.inputs.ensureUnusedCapacity(gpa, 1); | 4086 | try elf.inputs.ensureUnusedCapacity(gpa, 1); |
| 4001 | const file_symbol = elf.addLocalSymbolAssumeCapacity(.{ | 4087 | const file_symbol = elf.addLocalSymbolAssumeCapacity(.{ |
| ... | @@ -4376,7 +4462,7 @@ fn loadObject( | ... | @@ -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 | const comp = elf.base.comp; | 4466 | const comp = elf.base.comp; |
| 4381 | const gpa = comp.gpa; | 4467 | const gpa = comp.gpa; |
| 4382 | const diags = &comp.link_diags; | 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,23 +4679,29 @@ fn loadDso(elf: *Elf, path: std.Build.Cache.Path, fr: *Io.File.Reader) !void { |
| 4593 | 4679 | ||
| 4594 | /// Validates that the `std.elf.Ident` present at the start of `r` is a compatible link input. | 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 | /// Does not advance the position of `r`. Requires `r` to have a 16-byte buffer. | 4686 | /// Does not advance the position of `r`. Requires `r` to have a 16-byte buffer. |
| 4599 | fn checkInputIdent( | 4687 | fn checkInputIdent( |
| 4600 | elf: *const Elf, | 4688 | elf: *const Elf, |
| 4601 | path: std.Build.Cache.Path, | 4689 | path: std.Build.Cache.Path, |
| 4602 | r: *Io.Reader, | 4690 | r: *Io.Reader, |
| 4603 | ) !void { | 4691 | ) error{ BadMagic, EndOfStream, AlreadyReported, ReadFailed }!void { |
| 4604 | const diags = &elf.base.comp.link_diags; | 4692 | const diags = &elf.base.comp.link_diags; |
| 4605 | 4693 | ||
| 4606 | const ident = try r.peekStructPointer(std.elf.Ident); | 4694 | const magic = r.peek(std.elf.MAGIC.len) catch |err| switch (err) { |
| 4607 | const target: *const std.elf.Ident = @ptrCast(elf.mf.memory_map.memory[0..@sizeOf(std.elf.Ident)]); | 4695 | error.ReadFailed => |e| return e, |
| 4608 | 4696 | error.EndOfStream => return error.BadMagic, | |
| 4609 | if (!std.mem.eql(u8, &ident.magic, std.elf.MAGIC)) { | 4697 | }; |
| 4698 | if (!std.mem.eql(u8, magic, std.elf.MAGIC)) { | ||
| 4610 | return error.BadMagic; | 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 | if (ident.class != target.class) return diags.failParse( | 4705 | if (ident.class != target.class) return diags.failParse( |
| 4614 | path, | 4706 | path, |
| 4615 | "bad ELF class ({?s})", | 4707 | "bad ELF class ({?s})", |
| ... | @@ -4649,7 +4741,7 @@ fn createInitFiniArraySection( | ... | @@ -4649,7 +4741,7 @@ fn createInitFiniArraySection( |
| 4649 | shndx: *Section.Index, | 4741 | shndx: *Section.Index, |
| 4650 | comptime name: []const u8, | 4742 | comptime name: []const u8, |
| 4651 | @"type": std.elf.SHT, | 4743 | @"type": std.elf.SHT, |
| 4652 | ) !void { | 4744 | ) Error!void { |
| 4653 | assert(shndx.* == .UNDEF); | 4745 | assert(shndx.* == .UNDEF); |
| 4654 | const gpa = elf.base.comp.gpa; | 4746 | const gpa = elf.base.comp.gpa; |
| 4655 | const addr_align: std.mem.Alignment = switch (elf.identClass()) { | 4747 | const addr_align: std.mem.Alignment = switch (elf.identClass()) { |
| ... | @@ -4722,14 +4814,15 @@ fn updateInitFiniArraySectionSize( | ... | @@ -4722,14 +4814,15 @@ fn updateInitFiniArraySectionSize( |
| 4722 | Symbol.Id.global(end_sym_name).flushMoved(elf, end_vaddr); | 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 | _ = prog_node; | 4818 | _ = prog_node; |
| 4819 | const diags = &elf.base.comp.link_diags; | ||
| 4727 | elf.prelinkInner() catch |err| switch (err) { | 4820 | elf.prelinkInner() catch |err| switch (err) { |
| 4728 | error.OutOfMemory => |e| return e, | 4821 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 4729 | else => |e| return elf.base.comp.link_diags.fail("prelink failed: {t}", .{e}), | 4822 | else => |e| return e, |
| 4730 | }; | 4823 | }; |
| 4731 | } | 4824 | } |
| 4732 | fn prelinkInner(elf: *Elf) !void { | 4825 | fn prelinkInner(elf: *Elf) Error!void { |
| 4733 | const comp = elf.base.comp; | 4826 | const comp = elf.base.comp; |
| 4734 | const gpa = comp.gpa; | 4827 | const gpa = comp.gpa; |
| 4735 | try elf.ensureUnusedSymbolCapacity(1, .all_local); | 4828 | try elf.ensureUnusedSymbolCapacity(1, .all_local); |
| ... | @@ -4954,7 +5047,7 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { | ... | @@ -4954,7 +5047,7 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { |
| 4954 | entsize: std.elf.Word = 0, | 5047 | entsize: std.elf.Word = 0, |
| 4955 | node_align: std.mem.Alignment = .@"1", | 5048 | node_align: std.mem.Alignment = .@"1", |
| 4956 | fixed: bool = false, | 5049 | fixed: bool = false, |
| 4957 | }) !Section.Index { | 5050 | }) Error!Section.Index { |
| 4958 | switch (opts.type) { | 5051 | switch (opts.type) { |
| 4959 | .NULL => assert(opts.size == 0), | 5052 | .NULL => assert(opts.size == 0), |
| 4960 | .PROGBITS => assert(opts.size > 0), | 5053 | .PROGBITS => assert(opts.size > 0), |
| ... | @@ -4996,9 +5089,7 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { | ... | @@ -4996,9 +5089,7 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { |
| 4996 | break :shndx .{ @enumFromInt(shndx), @as(u64, elf.targetLoad(&ehdr.shentsize)) * @as(u64, shnum) }; | 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); | 5092 | try elf.ensureNodeSize(elf.ni.shdr, new_shdr_size); |
| 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); | ||
| 5002 | const ni = try elf.mf.addLastChildNode(gpa, switch (elf.ehdrField(.type)) { | 5093 | const ni = try elf.mf.addLastChildNode(gpa, switch (elf.ehdrField(.type)) { |
| 5003 | .NONE, .CORE, _ => unreachable, | 5094 | .NONE, .CORE, _ => unreachable, |
| 5004 | .REL => elf.ni.file, | 5095 | .REL => elf.ni.file, |
| ... | @@ -5045,7 +5136,7 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { | ... | @@ -5045,7 +5136,7 @@ fn addSection(elf: *Elf, segment_ni: MappedFile.Node.Index, opts: struct { |
| 5045 | return shndx; | 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 | if (len == 0) return; | 5140 | if (len == 0) return; |
| 5050 | const gpa = elf.base.comp.gpa; | 5141 | const gpa = elf.base.comp.gpa; |
| 5051 | try elf.symbol_relocs.ensureUnusedCapacity(gpa, len); | 5142 | try elf.symbol_relocs.ensureUnusedCapacity(gpa, len); |
| ... | @@ -5090,14 +5181,11 @@ fn ensureUnusedRelocCapacity(elf: *Elf, node: MappedFile.Node.Index, len: usize) | ... | @@ -5090,14 +5181,11 @@ fn ensureUnusedRelocCapacity(elf: *Elf, node: MappedFile.Node.Index, len: usize) |
| 5090 | try elf.tls_size_symbol_relocs.ensureUnusedCapacity(gpa, len); | 5181 | try elf.tls_size_symbol_relocs.ensureUnusedCapacity(gpa, len); |
| 5091 | const new_got_entries = len * 2; // at worst, every reloc is a new TLSGD | 5182 | const new_got_entries = len * 2; // at worst, every reloc is a new TLSGD |
| 5092 | try elf.got.ensureUnusedCapacity(gpa, new_got_entries); | 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 | const need_got_size = switch (class) { | 5184 | const need_got_size = switch (class) { |
| 5096 | .NONE, _ => unreachable, | 5185 | .NONE, _ => unreachable, |
| 5097 | inline else => |ct_class| (elf.got.count() + new_got_entries) * @sizeOf(ct_class.ElfN().Addr), | 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) | 5188 | try elf.ensureNodeSize(elf.shndx.got.get(elf).ni, need_got_size); |
| 5100 | try got_ni.resize(&elf.mf, gpa, need_got_size +| need_got_size / MappedFile.growth_factor); | ||
| 5101 | 5189 | ||
| 5102 | if (elf.shndx.dynamic != .UNDEF) { | 5190 | if (elf.shndx.dynamic != .UNDEF) { |
| 5103 | try elf.shndx.rela_dyn.relaEnsureAdditionalCapacity(elf, new_got_entries); | 5191 | try elf.shndx.rela_dyn.relaEnsureAdditionalCapacity(elf, new_got_entries); |
| ... | @@ -5114,7 +5202,7 @@ fn addRelocAssumeCapacity( | ... | @@ -5114,7 +5202,7 @@ fn addRelocAssumeCapacity( |
| 5114 | target: Symbol.Id, | 5202 | target: Symbol.Id, |
| 5115 | addend: i64, | 5203 | addend: i64, |
| 5116 | @"type": MachineRelocType, | 5204 | @"type": MachineRelocType, |
| 5117 | ) !void { | 5205 | ) Error!void { |
| 5118 | assert(node != .none); | 5206 | assert(node != .none); |
| 5119 | switch (elf.ehdrField(.type)) { | 5207 | switch (elf.ehdrField(.type)) { |
| 5120 | .NONE, .CORE, _ => unreachable, | 5208 | .NONE, .CORE, _ => unreachable, |
| ... | @@ -5233,7 +5321,7 @@ fn addSymbolRelocAssumeCapacity( | ... | @@ -5233,7 +5321,7 @@ fn addSymbolRelocAssumeCapacity( |
| 5233 | target: Symbol.Id, | 5321 | target: Symbol.Id, |
| 5234 | addend: i64, | 5322 | addend: i64, |
| 5235 | @"type": SymbolReloc.Type, | 5323 | @"type": SymbolReloc.Type, |
| 5236 | ) !void { | 5324 | ) Error!void { |
| 5237 | assert(elf.ehdrField(.type) != .REL); | 5325 | assert(elf.ehdrField(.type) != .REL); |
| 5238 | 5326 | ||
| 5239 | const rela_index: Section.RelaIndex.Optional = r: { | 5327 | const rela_index: Section.RelaIndex.Optional = r: { |
| ... | @@ -5594,7 +5682,7 @@ fn nodeWantsDsoRelocation(elf: *Elf, node: MappedFile.Node.Index) enum { yes, ye | ... | @@ -5594,7 +5682,7 @@ fn nodeWantsDsoRelocation(elf: *Elf, node: MappedFile.Node.Index) enum { yes, ye |
| 5594 | /// global where needed---the caller does not need to do this. | 5682 | /// global where needed---the caller does not need to do this. |
| 5595 | /// | 5683 | /// |
| 5596 | /// Asserts that `elf.shndx.dynamic != .UNDEF` and that `global_name` refers to an *undefined* global. | 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 | assert(elf.shndx.dynamic != .UNDEF); | 5686 | assert(elf.shndx.dynamic != .UNDEF); |
| 5599 | 5687 | ||
| 5600 | const gpa = elf.base.comp.gpa; | 5688 | const gpa = elf.base.comp.gpa; |
| ... | @@ -5657,16 +5745,14 @@ fn maybeAddCopyRelocation(elf: *Elf, global_name: String(.strtab)) !bool { | ... | @@ -5657,16 +5745,14 @@ fn maybeAddCopyRelocation(elf: *Elf, global_name: String(.strtab)) !bool { |
| 5657 | return true; | 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 | elf.updateNavInner(pt, nav_index) catch |err| switch (err) { | 5750 | elf.updateNavInner(pt, nav_index) catch |err| switch (err) { |
| 5662 | error.OutOfMemory, | 5751 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 5663 | error.Overflow, | 5752 | else => |e| return e, |
| 5664 | error.RelocationNotByteAligned, | ||
| 5665 | => |e| return e, | ||
| 5666 | else => |e| return elf.base.cgFail(nav_index, "linker failed to update variable: {t}", .{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 | const zcu = pt.zcu; | 5756 | const zcu = pt.zcu; |
| 5671 | const gpa = zcu.gpa; | 5757 | const gpa = zcu.gpa; |
| 5672 | const ip = &zcu.intern_pool; | 5758 | const ip = &zcu.intern_pool; |
| ... | @@ -5689,12 +5775,11 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) | ... | @@ -5689,12 +5775,11 @@ fn updateNavInner(elf: *Elf, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) |
| 5689 | codegen.generateSymbol( | 5775 | codegen.generateSymbol( |
| 5690 | &elf.base, | 5776 | &elf.base, |
| 5691 | pt, | 5777 | pt, |
| 5692 | zcu.navSrcLoc(nav_index), | ||
| 5693 | .fromInterned(nav.resolved.?.value), | 5778 | .fromInterned(nav.resolved.?.value), |
| 5694 | &nw.interface, | 5779 | &nw.interface, |
| 5695 | .{ .atom_index = Node.toAtom(ni) }, | 5780 | .{ .atom_index = Node.toAtom(ni) }, |
| 5696 | ) catch |err| switch (err) { | 5781 | ) catch |err| switch (err) { |
| 5697 | error.WriteFailed => return error.OutOfMemory, | 5782 | error.WriteFailed => return nw.err.?, |
| 5698 | else => |e| return e, | 5783 | else => |e| return e, |
| 5699 | }; | 5784 | }; |
| 5700 | switch (elf.symPtr(nmi.symbol(elf).index())) { | 5785 | switch (elf.symPtr(nmi.symbol(elf).index())) { |
| ... | @@ -5707,18 +5792,11 @@ pub fn updateFunc( | ... | @@ -5707,18 +5792,11 @@ pub fn updateFunc( |
| 5707 | pt: Zcu.PerThread, | 5792 | pt: Zcu.PerThread, |
| 5708 | func_index: InternPool.Index, | 5793 | func_index: InternPool.Index, |
| 5709 | mir: *const codegen.AnyMir, | 5794 | mir: *const codegen.AnyMir, |
| 5710 | ) !void { | 5795 | ) link.Error!void { |
| 5796 | const diags = &elf.base.comp.link_diags; | ||
| 5711 | elf.updateFuncInner(pt, func_index, mir) catch |err| switch (err) { | 5797 | elf.updateFuncInner(pt, func_index, mir) catch |err| switch (err) { |
| 5712 | error.OutOfMemory, | 5798 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 5713 | error.Overflow, | 5799 | else => |e| return e, |
| 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 | ), | ||
| 5722 | }; | 5800 | }; |
| 5723 | } | 5801 | } |
| 5724 | fn updateFuncInner( | 5802 | fn updateFuncInner( |
| ... | @@ -5726,7 +5804,7 @@ fn updateFuncInner( | ... | @@ -5726,7 +5804,7 @@ fn updateFuncInner( |
| 5726 | pt: Zcu.PerThread, | 5804 | pt: Zcu.PerThread, |
| 5727 | func_index: InternPool.Index, | 5805 | func_index: InternPool.Index, |
| 5728 | mir: *const codegen.AnyMir, | 5806 | mir: *const codegen.AnyMir, |
| 5729 | ) !void { | 5807 | ) Error!void { |
| 5730 | const zcu = pt.zcu; | 5808 | const zcu = pt.zcu; |
| 5731 | const gpa = zcu.gpa; | 5809 | const gpa = zcu.gpa; |
| 5732 | const ip = &zcu.intern_pool; | 5810 | const ip = &zcu.intern_pool; |
| ... | @@ -5748,7 +5826,6 @@ fn updateFuncInner( | ... | @@ -5748,7 +5826,6 @@ fn updateFuncInner( |
| 5748 | codegen.emitFunction( | 5826 | codegen.emitFunction( |
| 5749 | &elf.base, | 5827 | &elf.base, |
| 5750 | pt, | 5828 | pt, |
| 5751 | zcu.navSrcLoc(func.owner_nav), | ||
| 5752 | func_index, | 5829 | func_index, |
| 5753 | Node.toAtom(ni), | 5830 | Node.toAtom(ni), |
| 5754 | mir, | 5831 | mir, |
| ... | @@ -5763,14 +5840,14 @@ fn updateFuncInner( | ... | @@ -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 | elf.flushLazy(pt, .{ | 5845 | elf.flushLazy(pt, .{ |
| 5768 | .kind = .const_data, | 5846 | .kind = .const_data, |
| 5769 | .index = @intCast(elf.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return), | 5847 | .index = @intCast(elf.lazy.getPtr(.const_data).map.getIndex(.anyerror_type) orelse return), |
| 5770 | }) catch |err| switch (err) { | 5848 | }) catch |err| switch (err) { |
| 5771 | error.OutOfMemory => |e| return e, | 5849 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 5772 | error.CodegenFail => return error.LinkFailure, | 5850 | else => |e| return e, |
| 5773 | else => |e| return elf.base.comp.link_diags.fail("updateErrorData failed: {t}", .{e}), | ||
| 5774 | }; | 5851 | }; |
| 5775 | } | 5852 | } |
| 5776 | 5853 | ||
| ... | @@ -5779,8 +5856,9 @@ pub fn flush( | ... | @@ -5779,8 +5856,9 @@ pub fn flush( |
| 5779 | arena: std.mem.Allocator, | 5856 | arena: std.mem.Allocator, |
| 5780 | tid: Zcu.PerThread.Id, | 5857 | tid: Zcu.PerThread.Id, |
| 5781 | prog_node: std.Progress.Node, | 5858 | prog_node: std.Progress.Node, |
| 5782 | ) !void { | 5859 | ) link.Error!void { |
| 5783 | const comp = elf.base.comp; | 5860 | const comp = elf.base.comp; |
| 5861 | const diags = &comp.link_diags; | ||
| 5784 | _ = arena; | 5862 | _ = arena; |
| 5785 | _ = prog_node; | 5863 | _ = prog_node; |
| 5786 | 5864 | ||
| ... | @@ -5791,12 +5869,12 @@ pub fn flush( | ... | @@ -5791,12 +5869,12 @@ pub fn flush( |
| 5791 | any_undef = true; | 5869 | any_undef = true; |
| 5792 | comp.link_diags.addError("undefined global symbol '{s}'", .{name.slice(elf)}); | 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 | elf.updateDynamicTextrel() catch |err| switch (err) { | 5875 | elf.updateDynamicTextrel() catch |err| switch (err) { |
| 5798 | error.OutOfMemory => |e| return e, | 5876 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 5799 | else => |e| return elf.base.comp.link_diags.fail("updateDynamicTextrel failed: {t}", .{e}), | 5877 | else => |e| return e, |
| 5800 | }; | 5878 | }; |
| 5801 | 5879 | ||
| 5802 | while (try elf.idle(tid)) {} | 5880 | while (try elf.idle(tid)) {} |
| ... | @@ -5812,8 +5890,8 @@ pub fn flush( | ... | @@ -5812,8 +5890,8 @@ pub fn flush( |
| 5812 | .named => |named| named, | 5890 | .named => |named| named, |
| 5813 | }; | 5891 | }; |
| 5814 | const sym_name_strtab = elf.string(.strtab, sym_name_slice) catch |err| switch (err) { | 5892 | const sym_name_strtab = elf.string(.strtab, sym_name_slice) catch |err| switch (err) { |
| 5815 | error.Canceled => |e| return e, | 5893 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 5816 | else => |e| return comp.link_diags.fail("flush write failed: {t}", .{e}), | 5894 | else => |e| return e, |
| 5817 | }; | 5895 | }; |
| 5818 | if (elf.globalByName(sym_name_strtab) == null) break :entry 0; | 5896 | if (elf.globalByName(sym_name_strtab) == null) break :entry 0; |
| 5819 | break :entry Symbol.Id.global(sym_name_strtab).value(elf); | 5897 | break :entry Symbol.Id.global(sym_name_strtab).value(elf); |
| ... | @@ -5823,11 +5901,11 @@ pub fn flush( | ... | @@ -5823,11 +5901,11 @@ pub fn flush( |
| 5823 | } | 5901 | } |
| 5824 | 5902 | ||
| 5825 | elf.mf.flush() catch |err| switch (err) { | 5903 | elf.mf.flush() catch |err| switch (err) { |
| 5826 | error.Canceled => |e| return e, | 5904 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 5827 | else => |e| return comp.link_diags.fail("flush write failed: {t}", .{e}), | 5905 | else => |e| return e, |
| 5828 | }; | 5906 | }; |
| 5829 | } | 5907 | } |
| 5830 | fn updateDynamicTextrel(elf: *Elf) !void { | 5908 | fn updateDynamicTextrel(elf: *Elf) Error!void { |
| 5831 | if (elf.shndx.dynamic == .UNDEF) return; | 5909 | if (elf.shndx.dynamic == .UNDEF) return; |
| 5832 | const dynamic_ni = elf.shndx.dynamic.get(elf).ni; | 5910 | const dynamic_ni = elf.shndx.dynamic.get(elf).ni; |
| 5833 | switch (elf.shdrPtr(elf.shndx.dynamic)) { | 5911 | switch (elf.shdrPtr(elf.shndx.dynamic)) { |
| ... | @@ -5844,10 +5922,7 @@ fn updateDynamicTextrel(elf: *Elf) !void { | ... | @@ -5844,10 +5922,7 @@ fn updateDynamicTextrel(elf: *Elf) !void { |
| 5844 | if (!has_textrel) { | 5922 | if (!has_textrel) { |
| 5845 | // Add a DT_TEXTREL entry before the final DT_NULL entry. | 5923 | // Add a DT_TEXTREL entry before the final DT_NULL entry. |
| 5846 | const new_size = cur_size + @sizeOf([2]class.ElfN().Addr); | 5924 | const new_size = cur_size + @sizeOf([2]class.ElfN().Addr); |
| 5847 | _, const node_size = dynamic_ni.location(&elf.mf).resolve(&elf.mf); | 5925 | try elf.ensureNodeSize(dynamic_ni, new_size); |
| 5848 | if (node_size < new_size) { | ||
| 5849 | try dynamic_ni.resize(&elf.mf, elf.base.comp.gpa, new_size); | ||
| 5850 | } | ||
| 5851 | elf.targetStore(&shdr.size, new_size); | 5926 | elf.targetStore(&shdr.size, new_size); |
| 5852 | const new_entries: [][2]class.ElfN().Addr = @ptrCast(@alignCast( | 5927 | const new_entries: [][2]class.ElfN().Addr = @ptrCast(@alignCast( |
| 5853 | dynamic_ni.slice(&elf.mf)[0..@intCast(new_size)], | 5928 | dynamic_ni.slice(&elf.mf)[0..@intCast(new_size)], |
| ... | @@ -5869,18 +5944,16 @@ fn updateDynamicTextrel(elf: *Elf) !void { | ... | @@ -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 | const comp = elf.base.comp; | 5948 | const comp = elf.base.comp; |
| 5949 | const diags = &comp.link_diags; | ||
| 5874 | task: { | 5950 | task: { |
| 5875 | while (elf.pending_uavs.pop()) |umi| { | 5951 | while (elf.pending_uavs.pop()) |umi| { |
| 5876 | const sub_prog_node = elf.idleProgNode(tid, elf.const_prog_node, .{ .uav = umi }); | 5952 | const sub_prog_node = elf.idleProgNode(tid, elf.const_prog_node, .{ .uav = umi }); |
| 5877 | defer sub_prog_node.end(); | 5953 | defer sub_prog_node.end(); |
| 5878 | elf.flushUav(.{ .zcu = comp.zcu.?, .tid = tid }, umi) catch |err| switch (err) { | 5954 | elf.flushUav(.{ .zcu = comp.zcu.?, .tid = tid }, umi) catch |err| switch (err) { |
| 5879 | error.OutOfMemory => |e| return e, | 5955 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 5880 | else => |e| return comp.link_diags.fail( | 5956 | else => |e| return e, |
| 5881 | "linker failed to lower constant: {t}", | ||
| 5882 | .{e}, | ||
| 5883 | ), | ||
| 5884 | }; | 5957 | }; |
| 5885 | break :task; | 5958 | break :task; |
| 5886 | } | 5959 | } |
| ... | @@ -5903,11 +5976,8 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) !bool { | ... | @@ -5903,11 +5976,8 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) !bool { |
| 5903 | ); | 5976 | ); |
| 5904 | defer sub_prog_node.end(); | 5977 | defer sub_prog_node.end(); |
| 5905 | elf.flushLazy(pt, lmr) catch |err| switch (err) { | 5978 | elf.flushLazy(pt, lmr) catch |err| switch (err) { |
| 5906 | error.OutOfMemory => |e| return e, | 5979 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 5907 | else => |e| return comp.link_diags.fail( | 5980 | else => |e| return e, |
| 5908 | "linker failed to lower lazy {s}: {t}", | ||
| 5909 | .{ kind, e }, | ||
| 5910 | ), | ||
| 5911 | }; | 5981 | }; |
| 5912 | break :task; | 5982 | break :task; |
| 5913 | }; | 5983 | }; |
| ... | @@ -5917,18 +5987,8 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) !bool { | ... | @@ -5917,18 +5987,8 @@ pub fn idle(elf: *Elf, tid: Zcu.PerThread.Id) !bool { |
| 5917 | const sub_prog_node = elf.idleProgNode(tid, elf.input_prog_node, elf.getNode(isi.node(elf))); | 5987 | const sub_prog_node = elf.idleProgNode(tid, elf.input_prog_node, elf.getNode(isi.node(elf))); |
| 5918 | defer sub_prog_node.end(); | 5988 | defer sub_prog_node.end(); |
| 5919 | elf.flushInputSection(isi) catch |err| switch (err) { | 5989 | elf.flushInputSection(isi) catch |err| switch (err) { |
| 5920 | else => |e| { | 5990 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 5921 | const ii = isi.input(elf); | 5991 | else => |e| return e, |
| 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 | }, | ||
| 5932 | }; | 5992 | }; |
| 5933 | break :task; | 5993 | break :task; |
| 5934 | } | 5994 | } |
| ... | @@ -6005,10 +6065,9 @@ fn flushUav( | ... | @@ -6005,10 +6065,9 @@ fn flushUav( |
| 6005 | elf: *Elf, | 6065 | elf: *Elf, |
| 6006 | pt: Zcu.PerThread, | 6066 | pt: Zcu.PerThread, |
| 6007 | umi: Node.UavMapIndex, | 6067 | umi: Node.UavMapIndex, |
| 6008 | ) !void { | 6068 | ) Error!void { |
| 6009 | const comp = elf.base.comp; | 6069 | const comp = elf.base.comp; |
| 6010 | const gpa = comp.gpa; | 6070 | const gpa = comp.gpa; |
| 6011 | const zcu = pt.zcu; | ||
| 6012 | 6071 | ||
| 6013 | const uav_val = umi.uavValue(elf); | 6072 | const uav_val = umi.uavValue(elf); |
| 6014 | const ni = umi.symbol(elf).index().ptr(elf).node; | 6073 | const ni = umi.symbol(elf).index().ptr(elf).node; |
| ... | @@ -6017,23 +6076,14 @@ fn flushUav( | ... | @@ -6017,23 +6076,14 @@ fn flushUav( |
| 6017 | var nw: MappedFile.Node.Writer = undefined; | 6076 | var nw: MappedFile.Node.Writer = undefined; |
| 6018 | ni.writer(&elf.mf, gpa, &nw); | 6077 | ni.writer(&elf.mf, gpa, &nw); |
| 6019 | defer nw.deinit(); | 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 | codegen.generateSymbol( | 6079 | codegen.generateSymbol( |
| 6029 | &elf.base, | 6080 | &elf.base, |
| 6030 | pt, | 6081 | pt, |
| 6031 | dummy_src_loc, | ||
| 6032 | .fromInterned(uav_val), | 6082 | .fromInterned(uav_val), |
| 6033 | &nw.interface, | 6083 | &nw.interface, |
| 6034 | .{ .atom_index = Node.toAtom(ni) }, | 6084 | .{ .atom_index = Node.toAtom(ni) }, |
| 6035 | ) catch |err| switch (err) { | 6085 | ) catch |err| switch (err) { |
| 6036 | error.WriteFailed => return error.OutOfMemory, | 6086 | error.WriteFailed => return nw.err.?, |
| 6037 | else => |e| return e, | 6087 | else => |e| return e, |
| 6038 | }; | 6088 | }; |
| 6039 | switch (elf.symPtr(umi.symbol(elf).index())) { | 6089 | switch (elf.symPtr(umi.symbol(elf).index())) { |
| ... | @@ -6044,7 +6094,7 @@ fn flushUav( | ... | @@ -6044,7 +6094,7 @@ fn flushUav( |
| 6044 | assert(ni.hasMoved(&elf.mf)); | 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 | const zcu = pt.zcu; | 6098 | const zcu = pt.zcu; |
| 6049 | const gpa = zcu.gpa; | 6099 | const gpa = zcu.gpa; |
| 6050 | 6100 | ||
| ... | @@ -6060,44 +6110,70 @@ fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void { | ... | @@ -6060,44 +6110,70 @@ fn flushLazy(elf: *Elf, pt: Zcu.PerThread, lmr: Node.LazyMapRef) !void { |
| 6060 | var nw: MappedFile.Node.Writer = undefined; | 6110 | var nw: MappedFile.Node.Writer = undefined; |
| 6061 | ni.writer(&elf.mf, gpa, &nw); | 6111 | ni.writer(&elf.mf, gpa, &nw); |
| 6062 | defer nw.deinit(); | 6112 | defer nw.deinit(); |
| 6063 | try codegen.generateLazySymbol( | 6113 | codegen.generateLazySymbol( |
| 6064 | &elf.base, | 6114 | &elf.base, |
| 6065 | pt, | 6115 | pt, |
| 6066 | Type.fromInterned(lazy.ty).srcLocOrNull(pt.zcu) orelse .unneeded, | ||
| 6067 | lazy, | 6116 | lazy, |
| 6068 | &required_alignment, | 6117 | &required_alignment, |
| 6069 | &nw.interface, | 6118 | &nw.interface, |
| 6070 | .none, | 6119 | .none, |
| 6071 | .{ .atom_index = Node.toAtom(ni) }, | 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 | switch (elf.symPtr(lmr.symbol(elf).index())) { | 6125 | switch (elf.symPtr(lmr.symbol(elf).index())) { |
| 6074 | inline else => |sym| elf.targetStore(&sym.size, @intCast(nw.interface.end)), | 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 | const file_loc = isi.fileLocation(elf); | 6131 | const file_loc = isi.fileLocation(elf); |
| 6080 | if (file_loc.size == 0) return; | 6132 | if (file_loc.size == 0) return; |
| 6081 | const comp = elf.base.comp; | 6133 | const comp = elf.base.comp; |
| 6082 | const io = comp.io; | 6134 | const io = comp.io; |
| 6083 | const gpa = comp.gpa; | 6135 | const gpa = comp.gpa; |
| 6136 | const diags = &comp.link_diags; | ||
| 6084 | const ii = isi.input(elf); | 6137 | const ii = isi.input(elf); |
| 6085 | const path = ii.path(elf); | 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 | defer file.close(io); | 6143 | defer file.close(io); |
| 6088 | var fr = file.reader(io, &.{}); | 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 | var nw: MappedFile.Node.Writer = undefined; | 6154 | var nw: MappedFile.Node.Writer = undefined; |
| 6091 | isi.node(elf).writer(&elf.mf, gpa, &nw); | 6155 | isi.node(elf).writer(&elf.mf, gpa, &nw); |
| 6092 | defer nw.deinit(); | 6156 | defer nw.deinit(); |
| 6093 | if (try nw.interface.sendFileAll(&fr, .limited(@intCast(file_loc.size))) != file_loc.size) | 6157 | const n_bytes = nw.interface.sendFileAll(&fr, .limited(@intCast(file_loc.size))) catch |err| switch (err) { |
| 6094 | return error.EndOfStream; | 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 | // The input section should already be considered to have moved, because it is created as moved | 6171 | // The input section should already be considered to have moved, because it is created as moved |
| 6096 | // and pending calls to `flushInputSection` always happen before pending calls to `flushMoved`. | 6172 | // and pending calls to `flushInputSection` always happen before pending calls to `flushMoved`. |
| 6097 | assert(isi.node(elf).hasMoved(&elf.mf)); | 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 | switch (elf.getNode(ni)) { | 6177 | switch (elf.getNode(ni)) { |
| 6102 | else => unreachable, | 6178 | else => unreachable, |
| 6103 | .ehdr => assert(ni.fileLocation(&elf.mf, false).offset == 0), | 6179 | .ehdr => assert(ni.fileLocation(&elf.mf, false).offset == 0), |
| ... | @@ -6118,7 +6194,7 @@ fn flushFileOffset(elf: *Elf, ni: MappedFile.Node.Index) !void { | ... | @@ -6118,7 +6194,7 @@ fn flushFileOffset(elf: *Elf, ni: MappedFile.Node.Index) !void { |
| 6118 | }, | 6194 | }, |
| 6119 | } | 6195 | } |
| 6120 | var child_it = ni.children(&elf.mf); | 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 | .section => |shndx| switch (elf.shdrPtr(shndx)) { | 6199 | .section => |shndx| switch (elf.shdrPtr(shndx)) { |
| 6124 | inline else => |shdr| elf.targetStore(&shdr.offset, @intCast( | 6200 | inline else => |shdr| elf.targetStore(&shdr.offset, @intCast( |
| ... | @@ -6128,14 +6204,14 @@ fn flushFileOffset(elf: *Elf, ni: MappedFile.Node.Index) !void { | ... | @@ -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 | const trace = tracy.trace(@src()); | 6208 | const trace = tracy.trace(@src()); |
| 6133 | defer trace.end(); | 6209 | defer trace.end(); |
| 6134 | switch (elf.getNode(ni)) { | 6210 | switch (elf.getNode(ni)) { |
| 6135 | .file => unreachable, | 6211 | .file => unreachable, |
| 6136 | .ehdr, .shdr => try elf.flushFileOffset(ni), | 6212 | .ehdr, .shdr => elf.flushFileOffset(ni), |
| 6137 | .segment => |phndx| { | 6213 | .segment => |phndx| { |
| 6138 | try elf.flushFileOffset(ni); | 6214 | elf.flushFileOffset(ni); |
| 6139 | switch (elf.phdrSlice()) { | 6215 | switch (elf.phdrSlice()) { |
| 6140 | inline else => |phdr| { | 6216 | inline else => |phdr| { |
| 6141 | const ph = &phdr[phndx]; | 6217 | const ph = &phdr[phndx]; |
| ... | @@ -6156,7 +6232,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) !void { | ... | @@ -6156,7 +6232,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) !void { |
| 6156 | } | 6232 | } |
| 6157 | }, | 6233 | }, |
| 6158 | .section => |shndx| { | 6234 | .section => |shndx| { |
| 6159 | try elf.flushFileOffset(ni); | 6235 | elf.flushFileOffset(ni); |
| 6160 | const addr = elf.computeNodeVAddr(ni); | 6236 | const addr = elf.computeNodeVAddr(ni); |
| 6161 | const old_addr: u64, const flags: std.elf.SHF = switch (elf.shdrPtr(shndx)) { | 6237 | const old_addr: u64, const flags: std.elf.SHF = switch (elf.shdrPtr(shndx)) { |
| 6162 | inline else => |shdr| .{ | 6238 | inline else => |shdr| .{ |
| ... | @@ -6293,7 +6369,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) !void { | ... | @@ -6293,7 +6369,7 @@ fn flushMoved(elf: *Elf, ni: MappedFile.Node.Index) !void { |
| 6293 | try ni.childrenMoved(elf.base.comp.gpa, &elf.mf); | 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 | const trace = tracy.trace(@src()); | 6373 | const trace = tracy.trace(@src()); |
| 6298 | defer trace.end(); | 6374 | defer trace.end(); |
| 6299 | _, const size = ni.location(&elf.mf).resolve(&elf.mf); | 6375 | _, const size = ni.location(&elf.mf).resolve(&elf.mf); |
| ... | @@ -6486,16 +6562,11 @@ pub fn updateExports( | ... | @@ -6486,16 +6562,11 @@ pub fn updateExports( |
| 6486 | pt: Zcu.PerThread, | 6562 | pt: Zcu.PerThread, |
| 6487 | exported: Zcu.Exported, | 6563 | exported: Zcu.Exported, |
| 6488 | export_indices: []const Zcu.Export.Index, | 6564 | export_indices: []const Zcu.Export.Index, |
| 6489 | ) !void { | 6565 | ) link.Error!void { |
| 6566 | const diags = &elf.base.comp.link_diags; | ||
| 6490 | return elf.updateExportsInner(pt, exported, export_indices) catch |err| switch (err) { | 6567 | return elf.updateExportsInner(pt, exported, export_indices) catch |err| switch (err) { |
| 6491 | error.OutOfMemory => error.OutOfMemory, | 6568 | else => |e| return e, |
| 6492 | error.LinkFailure => error.AnalysisFail, | 6569 | error.MappedFileIo => return diags.fail("failed to write output file: {t}", .{elf.mf.io_err.?}), |
| 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 | }, | ||
| 6499 | }; | 6570 | }; |
| 6500 | } | 6571 | } |
| 6501 | fn updateExportsInner( | 6572 | fn updateExportsInner( |
| ... | @@ -6503,7 +6574,7 @@ fn updateExportsInner( | ... | @@ -6503,7 +6574,7 @@ fn updateExportsInner( |
| 6503 | pt: Zcu.PerThread, | 6574 | pt: Zcu.PerThread, |
| 6504 | exported: Zcu.Exported, | 6575 | exported: Zcu.Exported, |
| 6505 | export_indices: []const Zcu.Export.Index, | 6576 | export_indices: []const Zcu.Export.Index, |
| 6506 | ) !void { | 6577 | ) Error!void { |
| 6507 | const zcu = pt.zcu; | 6578 | const zcu = pt.zcu; |
| 6508 | const ip = &zcu.intern_pool; | 6579 | const ip = &zcu.intern_pool; |
| 6509 | 6580 | ||
| ... | @@ -6543,7 +6614,7 @@ fn updateExportsInner( | ... | @@ -6543,7 +6614,7 @@ fn updateExportsInner( |
| 6543 | .internal => @panic("TODO internal linkage"), | 6614 | .internal => @panic("TODO internal linkage"), |
| 6544 | .strong => .strong, | 6615 | .strong => .strong, |
| 6545 | .weak => .weak, | 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 | .visibility = switch (@"export".opts.visibility) { | 6619 | .visibility = switch (@"export".opts.visibility) { |
| 6549 | .default => .DEFAULT, | 6620 | .default => .DEFAULT, |
| ... | @@ -6591,10 +6662,10 @@ pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) Io.Cancelable!void { | ... | @@ -6591,10 +6662,10 @@ pub fn dump(elf: *Elf, tid: Zcu.PerThread.Id) Io.Cancelable!void { |
| 6591 | pub fn printNode( | 6662 | pub fn printNode( |
| 6592 | elf: *Elf, | 6663 | elf: *Elf, |
| 6593 | tid: Zcu.PerThread.Id, | 6664 | tid: Zcu.PerThread.Id, |
| 6594 | w: *std.Io.Writer, | 6665 | w: *Io.Writer, |
| 6595 | ni: MappedFile.Node.Index, | 6666 | ni: MappedFile.Node.Index, |
| 6596 | indent: usize, | 6667 | indent: usize, |
| 6597 | ) !void { | 6668 | ) Io.Writer.Error!void { |
| 6598 | const node = elf.getNode(ni); | 6669 | const node = elf.getNode(ni); |
| 6599 | try w.splatByteAll(' ', indent); | 6670 | try w.splatByteAll(' ', indent); |
| 6600 | try w.writeAll(@tagName(node)); | 6671 | try w.writeAll(@tagName(node)); |
| ... | @@ -6698,3 +6769,15 @@ pub fn printNode( | ... | @@ -6698,3 +6769,15 @@ pub fn printNode( |
| 6698 | try w.writeByte('\n'); | 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,7 +13,7 @@ pub fn deinit(ls: *LdScript, gpa: Allocator) void { |
| 13 | } | 13 | } |
| 14 | 14 | ||
| 15 | pub const Error = error{ | 15 | pub const Error = error{ |
| 16 | LinkFailure, | 16 | AlreadyReported, |
| 17 | UnknownCpuArch, | 17 | UnknownCpuArch, |
| 18 | OutOfMemory, | 18 | OutOfMemory, |
| 19 | }; | 19 | }; |
src/link/Lld.zig+4-4| ... | @@ -255,7 +255,7 @@ pub fn flush( | ... | @@ -255,7 +255,7 @@ pub fn flush( |
| 255 | arena: Allocator, | 255 | arena: Allocator, |
| 256 | tid: Zcu.PerThread.Id, | 256 | tid: Zcu.PerThread.Id, |
| 257 | prog_node: std.Progress.Node, | 257 | prog_node: std.Progress.Node, |
| 258 | ) link.File.FlushError!void { | 258 | ) link.Error!void { |
| 259 | dev.check(.lld_linker); | 259 | dev.check(.lld_linker); |
| 260 | _ = tid; | 260 | _ = tid; |
| 261 | 261 | ||
| ... | @@ -277,7 +277,7 @@ pub fn flush( | ... | @@ -277,7 +277,7 @@ pub fn flush( |
| 277 | .wasm => wasmLink(lld, arena), | 277 | .wasm => wasmLink(lld, arena), |
| 278 | }; | 278 | }; |
| 279 | result catch |err| switch (err) { | 279 | result catch |err| switch (err) { |
| 280 | error.OutOfMemory, error.LinkFailure => |e| return e, | 280 | error.OutOfMemory, error.AlreadyReported => |e| return e, |
| 281 | else => |e| return lld.base.comp.link_diags.fail("failed to link with LLD: {t}", .{e}), | 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,7 +1620,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi |
| 1620 | const exit_code = try lldMain(arena, argv, false); | 1620 | const exit_code = try lldMain(arena, argv, false); |
| 1621 | if (exit_code == 0) return; | 1621 | if (exit_code == 0) return; |
| 1622 | if (comp.clang_passthrough_mode) std.process.exit(exit_code); | 1622 | if (comp.clang_passthrough_mode) std.process.exit(exit_code); |
| 1623 | return error.LinkFailure; | 1623 | return error.AlreadyReported; |
| 1624 | } | 1624 | } |
| 1625 | 1625 | ||
| 1626 | var stderr: []u8 = &.{}; | 1626 | var stderr: []u8 = &.{}; |
| ... | @@ -1720,7 +1720,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi | ... | @@ -1720,7 +1720,7 @@ fn spawnLld(comp: *Compilation, arena: Allocator, argv: []const []const u8) !voi |
| 1720 | .exited => |code| if (code != 0) { | 1720 | .exited => |code| if (code != 0) { |
| 1721 | if (comp.clang_passthrough_mode) std.process.exit(code); | 1721 | if (comp.clang_passthrough_mode) std.process.exit(code); |
| 1722 | diags.lockAndParseLldStderr(argv[1], stderr); | 1722 | diags.lockAndParseLldStderr(argv[1], stderr); |
| 1723 | return error.LinkFailure; | 1723 | return error.AlreadyReported; |
| 1724 | }, | 1724 | }, |
| 1725 | .signal => |sig| { | 1725 | .signal => |sig| { |
| 1726 | if (comp.clang_passthrough_mode) std.process.abort(); | 1726 | if (comp.clang_passthrough_mode) std.process.abort(); |
src/link/MachO.zig+32-29| ... | @@ -341,7 +341,7 @@ pub fn flush( | ... | @@ -341,7 +341,7 @@ pub fn flush( |
| 341 | arena: Allocator, | 341 | arena: Allocator, |
| 342 | tid: Zcu.PerThread.Id, | 342 | tid: Zcu.PerThread.Id, |
| 343 | prog_node: std.Progress.Node, | 343 | prog_node: std.Progress.Node, |
| 344 | ) link.File.FlushError!void { | 344 | ) link.Error!void { |
| 345 | const tracy = trace(@src()); | 345 | const tracy = trace(@src()); |
| 346 | defer tracy.end(); | 346 | defer tracy.end(); |
| 347 | 347 | ||
| ... | @@ -490,7 +490,7 @@ pub fn flush( | ... | @@ -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 | const index = @as(File.Index, @intCast(try self.files.addOne(gpa))); | 496 | const index = @as(File.Index, @intCast(try self.files.addOne(gpa))); |
| ... | @@ -504,7 +504,7 @@ pub fn flush( | ... | @@ -504,7 +504,7 @@ pub fn flush( |
| 504 | try self.resolveSymbols(); | 504 | try self.resolveSymbols(); |
| 505 | try self.convertTentativeDefsAndResolveSpecialSymbols(); | 505 | try self.convertTentativeDefsAndResolveSpecialSymbols(); |
| 506 | self.dedupLiterals() catch |err| switch (err) { | 506 | self.dedupLiterals() catch |err| switch (err) { |
| 507 | error.LinkFailure => |e| return e, | 507 | error.AlreadyReported => |e| return e, |
| 508 | else => |e| return diags.fail("failed to deduplicate literals: {s}", .{@errorName(e)}), | 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,7 +513,7 @@ pub fn flush( |
| 513 | } | 513 | } |
| 514 | 514 | ||
| 515 | self.checkDuplicates() catch |err| switch (err) { | 515 | self.checkDuplicates() catch |err| switch (err) { |
| 516 | error.HasDuplicates => return error.LinkFailure, | 516 | error.HasDuplicates => return error.AlreadyReported, |
| 517 | else => |e| return diags.fail("failed to check for duplicate symbol definitions: {s}", .{@errorName(e)}), | 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,7 +528,7 @@ pub fn flush( |
| 528 | self.claimUnresolved(); | 528 | self.claimUnresolved(); |
| 529 | 529 | ||
| 530 | self.scanRelocs() catch |err| switch (err) { | 530 | self.scanRelocs() catch |err| switch (err) { |
| 531 | error.HasUndefinedSymbols => return error.LinkFailure, | 531 | error.HasUndefinedSymbols => return error.AlreadyReported, |
| 532 | else => |e| return diags.fail("failed to scan relocations: {s}", .{@errorName(e)}), | 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,7 +542,7 @@ pub fn flush( |
| 542 | 542 | ||
| 543 | try self.initSegments(); | 543 | try self.initSegments(); |
| 544 | self.allocateSections() catch |err| switch (err) { | 544 | self.allocateSections() catch |err| switch (err) { |
| 545 | error.LinkFailure => |e| return e, | 545 | error.AlreadyReported => |e| return e, |
| 546 | else => |e| return diags.fail("failed to allocate sections: {s}", .{@errorName(e)}), | 546 | else => |e| return diags.fail("failed to allocate sections: {s}", .{@errorName(e)}), |
| 547 | }; | 547 | }; |
| 548 | self.allocateSegments(); | 548 | self.allocateSegments(); |
| ... | @@ -558,7 +558,7 @@ pub fn flush( | ... | @@ -558,7 +558,7 @@ pub fn flush( |
| 558 | 558 | ||
| 559 | if (self.getZigObject()) |zo| { | 559 | if (self.getZigObject()) |zo| { |
| 560 | zo.resolveRelocs(self) catch |err| switch (err) { | 560 | zo.resolveRelocs(self) catch |err| switch (err) { |
| 561 | error.ResolveFailed => return error.LinkFailure, | 561 | error.ResolveFailed => return error.AlreadyReported, |
| 562 | else => |e| return e, | 562 | else => |e| return e, |
| 563 | }; | 563 | }; |
| 564 | } | 564 | } |
| ... | @@ -567,7 +567,7 @@ pub fn flush( | ... | @@ -567,7 +567,7 @@ pub fn flush( |
| 567 | try self.writeSectionsToFile(); | 567 | try self.writeSectionsToFile(); |
| 568 | try self.allocateLinkeditSegment(); | 568 | try self.allocateLinkeditSegment(); |
| 569 | self.writeLinkeditSectionsToFile() catch |err| switch (err) { | 569 | self.writeLinkeditSectionsToFile() catch |err| switch (err) { |
| 570 | error.OutOfMemory, error.LinkFailure => |e| return e, | 570 | error.OutOfMemory, error.AlreadyReported => |e| return e, |
| 571 | else => |e| return diags.fail("failed to write linkedit sections to file: {t}", .{e}), | 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,11 +594,11 @@ pub fn flush( |
| 594 | 594 | ||
| 595 | const ncmds, const sizeofcmds, const uuid_cmd_offset = self.writeLoadCommands() catch |err| switch (err) { | 595 | const ncmds, const sizeofcmds, const uuid_cmd_offset = self.writeLoadCommands() catch |err| switch (err) { |
| 596 | error.WriteFailed => unreachable, | 596 | error.WriteFailed => unreachable, |
| 597 | error.OutOfMemory, error.LinkFailure => |e| return e, | 597 | error.OutOfMemory, error.AlreadyReported => |e| return e, |
| 598 | }; | 598 | }; |
| 599 | try self.writeHeader(ncmds, sizeofcmds); | 599 | try self.writeHeader(ncmds, sizeofcmds); |
| 600 | self.writeUuid(uuid_cmd_offset, self.requiresCodeSig()) catch |err| switch (err) { | 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 | else => |e| return diags.fail("failed to calculate and write uuid: {s}", .{@errorName(e)}), | 602 | else => |e| return diags.fail("failed to calculate and write uuid: {s}", .{@errorName(e)}), |
| 603 | }; | 603 | }; |
| 604 | if (self.getDebugSymbols()) |dsym| dsym.flush(self) catch |err| switch (err) { | 604 | if (self.getDebugSymbols()) |dsym| dsym.flush(self) catch |err| switch (err) { |
| ... | @@ -609,7 +609,7 @@ pub fn flush( | ... | @@ -609,7 +609,7 @@ pub fn flush( |
| 609 | // Code signing always comes last. | 609 | // Code signing always comes last. |
| 610 | if (codesig) |*csig| { | 610 | if (codesig) |*csig| { |
| 611 | self.writeCodeSignature(csig) catch |err| switch (err) { | 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 | else => |e| return diags.fail("failed to write code signature: {s}", .{@errorName(e)}), | 613 | else => |e| return diags.fail("failed to write code signature: {s}", .{@errorName(e)}), |
| 614 | }; | 614 | }; |
| 615 | const emit = self.base.emit; | 615 | const emit = self.base.emit; |
| ... | @@ -968,7 +968,7 @@ pub fn parseInputFiles(self: *MachO) !void { | ... | @@ -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 | fn parseInputFileWorker(self: *MachO, file: File) void { | 974 | fn parseInputFileWorker(self: *MachO, file: File) void { |
| ... | @@ -1365,7 +1365,7 @@ fn convertTentativeDefsAndResolveSpecialSymbols(self: *MachO) !void { | ... | @@ -1365,7 +1365,7 @@ fn convertTentativeDefsAndResolveSpecialSymbols(self: *MachO) !void { |
| 1365 | resolveSpecialSymbolsWorker(self, obj); | 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 | fn convertTentativeDefinitionsWorker(self: *MachO, object: *Object) void { | 1371 | fn convertTentativeDefinitionsWorker(self: *MachO, object: *Object) void { |
| ... | @@ -1450,7 +1450,7 @@ fn checkDuplicates(self: *MachO) !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 | try self.reportDuplicates(); | 1455 | try self.reportDuplicates(); |
| 1456 | } | 1456 | } |
| ... | @@ -1517,7 +1517,7 @@ fn scanRelocs(self: *MachO) !void { | ... | @@ -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 | if (self.getInternalObject()) |obj| { | 1522 | if (self.getInternalObject()) |obj| { |
| 1523 | try obj.checkUndefs(self); | 1523 | try obj.checkUndefs(self); |
| ... | @@ -1990,7 +1990,7 @@ fn calcSectionSizes(self: *MachO) !void { | ... | @@ -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 | try self.calcSymtabSize(); | 1995 | try self.calcSymtabSize(); |
| 1996 | 1996 | ||
| ... | @@ -2527,7 +2527,7 @@ fn writeSectionsAndUpdateLinkeditSizes(self: *MachO) !void { | ... | @@ -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 | fn writeAtomsWorker(self: *MachO, file: File) void { | 2533 | fn writeAtomsWorker(self: *MachO, file: File) void { |
| ... | @@ -3074,15 +3074,15 @@ pub fn updateFunc( | ... | @@ -3074,15 +3074,15 @@ pub fn updateFunc( |
| 3074 | pt: Zcu.PerThread, | 3074 | pt: Zcu.PerThread, |
| 3075 | func_index: InternPool.Index, | 3075 | func_index: InternPool.Index, |
| 3076 | mir: *const codegen.AnyMir, | 3076 | mir: *const codegen.AnyMir, |
| 3077 | ) link.File.UpdateNavError!void { | 3077 | ) link.Error!void { |
| 3078 | return self.getZigObject().?.updateFunc(self, pt, func_index, mir); | 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 | return self.getZigObject().?.updateNav(self, pt, nav); | 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 | return self.getZigObject().?.updateLineNumber(pt, ti_id); | 3086 | return self.getZigObject().?.updateLineNumber(pt, ti_id); |
| 3087 | } | 3087 | } |
| 3088 | 3088 | ||
| ... | @@ -3091,7 +3091,7 @@ pub fn updateExports( | ... | @@ -3091,7 +3091,7 @@ pub fn updateExports( |
| 3091 | pt: Zcu.PerThread, | 3091 | pt: Zcu.PerThread, |
| 3092 | exported: Zcu.Exported, | 3092 | exported: Zcu.Exported, |
| 3093 | export_indices: []const Zcu.Export.Index, | 3093 | export_indices: []const Zcu.Export.Index, |
| 3094 | ) link.File.UpdateExportsError!void { | 3094 | ) link.Error!void { |
| 3095 | return self.getZigObject().?.updateExports(self, pt, exported, export_indices); | 3095 | return self.getZigObject().?.updateExports(self, pt, exported, export_indices); |
| 3096 | } | 3096 | } |
| 3097 | 3097 | ||
| ... | @@ -3116,9 +3116,8 @@ pub fn lowerUav( | ... | @@ -3116,9 +3116,8 @@ pub fn lowerUav( |
| 3116 | pt: Zcu.PerThread, | 3116 | pt: Zcu.PerThread, |
| 3117 | uav: InternPool.Index, | 3117 | uav: InternPool.Index, |
| 3118 | explicit_alignment: InternPool.Alignment, | 3118 | explicit_alignment: InternPool.Alignment, |
| 3119 | src_loc: Zcu.LazySrcLoc, | 3119 | ) !link.File.SymbolId { |
| 3120 | ) !codegen.SymbolResult { | 3120 | return self.getZigObject().?.lowerUav(self, pt, uav, explicit_alignment); |
| 3121 | return self.getZigObject().?.lowerUav(self, pt, uav, explicit_alignment, src_loc); | ||
| 3122 | } | 3121 | } |
| 3123 | 3122 | ||
| 3124 | pub fn getUavVAddr(self: *MachO, uav: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 { | 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,7 +3264,11 @@ fn copyRangeAllZeroOut(self: *MachO, old_offset: u64, new_offset: u64, size: u64 |
| 3265 | file_writer.pos = new_offset; | 3264 | file_writer.pos = new_offset; |
| 3266 | const size_u = math.cast(usize, size) orelse return error.Overflow; | 3265 | const size_u = math.cast(usize, size) orelse return error.Overflow; |
| 3267 | const n = file_writer.interface.sendFileAll(&file_reader, .limited(size_u)) catch |err| switch (err) { | 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 | error.WriteFailed => return file_writer.err.?, | 3272 | error.WriteFailed => return file_writer.err.?, |
| 3270 | }; | 3273 | }; |
| 3271 | assert(n == size_u); | 3274 | assert(n == size_u); |
| ... | @@ -5373,7 +5376,7 @@ fn isReachable(atom: *const Atom, rel: Relocation, macho_file: *MachO) bool { | ... | @@ -5373,7 +5376,7 @@ fn isReachable(atom: *const Atom, rel: Relocation, macho_file: *MachO) bool { |
| 5373 | return true; | 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 | const comp = macho_file.base.comp; | 5380 | const comp = macho_file.base.comp; |
| 5378 | const io = comp.io; | 5381 | const io = comp.io; |
| 5379 | const diags = &comp.link_diags; | 5382 | const diags = &comp.link_diags; |
| ... | @@ -5381,7 +5384,7 @@ pub fn pwriteAll(macho_file: *MachO, bytes: []const u8, offset: u64) error{LinkF | ... | @@ -5381,7 +5384,7 @@ pub fn pwriteAll(macho_file: *MachO, bytes: []const u8, offset: u64) error{LinkF |
| 5381 | return diags.fail("failed to write: {t}", .{err}); | 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 | const comp = macho_file.base.comp; | 5388 | const comp = macho_file.base.comp; |
| 5386 | const io = comp.io; | 5389 | const io = comp.io; |
| 5387 | const diags = &comp.link_diags; | 5390 | const diags = &comp.link_diags; |
| ... | @@ -5389,7 +5392,7 @@ pub fn setLength(macho_file: *MachO, length: u64) error{LinkFailure}!void { | ... | @@ -5389,7 +5392,7 @@ pub fn setLength(macho_file: *MachO, length: u64) error{LinkFailure}!void { |
| 5389 | return diags.fail("failed to set file end pos: {t}", .{err}); | 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 | return std.math.cast(T, x) orelse { | 5396 | return std.math.cast(T, x) orelse { |
| 5394 | const comp = macho_file.base.comp; | 5397 | const comp = macho_file.base.comp; |
| 5395 | const diags = &comp.link_diags; | 5398 | const diags = &comp.link_diags; |
| ... | @@ -5397,7 +5400,7 @@ pub fn cast(macho_file: *MachO, comptime T: type, x: anytype) error{LinkFailure} | ... | @@ -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 | const result, const ov = @shlWithOverflow(@as(u32, 1), try cast(macho_file, u5, x)); | 5404 | const result, const ov = @shlWithOverflow(@as(u32, 1), try cast(macho_file, u5, x)); |
| 5402 | if (ov != 0) { | 5405 | if (ov != 0) { |
| 5403 | const comp = macho_file.base.comp; | 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,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 | const tracy = trace(@src()); | 934 | const tracy = trace(@src()); |
| 935 | defer tracy.end(); | 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,7 +648,7 @@ fn addSection(self: *InternalObject, allocator: Allocator, segname: []const u8, |
| 648 | return n_sect; | 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 | const slice = self.sections.slice(); | 652 | const slice = self.sections.slice(); |
| 653 | assert(index < slice.items(.header).len); | 653 | assert(index < slice.items(.header).len); |
| 654 | const sect = slice.items(.header)[index]; | 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,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 | const gpa = macho_file.base.comp.gpa; | 431 | const gpa = macho_file.base.comp.gpa; |
| 432 | const diags = &macho_file.base.comp.link_diags; | 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,7 +555,7 @@ pub fn getInputSection(self: ZigObject, atom: Atom, macho_file: *MachO) macho.se |
| 555 | return sect; | 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 | const diags = &macho_file.base.comp.link_diags; | 559 | const diags = &macho_file.base.comp.link_diags; |
| 560 | 560 | ||
| 561 | // Handle any lazy symbols that were emitted by incremental compilation. | 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,7 +571,7 @@ pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.F |
| 571 | .{ .kind = .code, .ty = .anyerror_type }, | 571 | .{ .kind = .code, .ty = .anyerror_type }, |
| 572 | metadata.text_symbol_index, | 572 | metadata.text_symbol_index, |
| 573 | ) catch |err| switch (err) { | 573 | ) catch |err| switch (err) { |
| 574 | error.OutOfMemory, error.LinkFailure => |e| return e, | 574 | error.OutOfMemory, error.AlreadyReported => |e| return e, |
| 575 | else => |e| return diags.fail("failed to update lazy symbol: {s}", .{@errorName(e)}), | 575 | else => |e| return diags.fail("failed to update lazy symbol: {s}", .{@errorName(e)}), |
| 576 | }; | 576 | }; |
| 577 | if (metadata.const_state != .unused) self.updateLazySymbol( | 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,7 +580,7 @@ pub fn flush(self: *ZigObject, macho_file: *MachO, tid: Zcu.PerThread.Id) link.F |
| 580 | .{ .kind = .const_data, .ty = .anyerror_type }, | 580 | .{ .kind = .const_data, .ty = .anyerror_type }, |
| 581 | metadata.const_symbol_index, | 581 | metadata.const_symbol_index, |
| 582 | ) catch |err| switch (err) { | 582 | ) catch |err| switch (err) { |
| 583 | error.OutOfMemory, error.LinkFailure => |e| return e, | 583 | error.OutOfMemory, error.AlreadyReported => |e| return e, |
| 584 | else => |e| return diags.fail("failed to update lazy symbol: {s}", .{@errorName(e)}), | 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,8 +704,7 @@ pub fn lowerUav( |
| 704 | pt: Zcu.PerThread, | 704 | pt: Zcu.PerThread, |
| 705 | uav: InternPool.Index, | 705 | uav: InternPool.Index, |
| 706 | explicit_alignment: Atom.Alignment, | 706 | explicit_alignment: Atom.Alignment, |
| 707 | src_loc: Zcu.LazySrcLoc, | 707 | ) !link.File.SymbolId { |
| 708 | ) !codegen.SymbolResult { | ||
| 709 | const zcu = pt.zcu; | 708 | const zcu = pt.zcu; |
| 710 | const gpa = zcu.gpa; | 709 | const gpa = zcu.gpa; |
| 711 | const val = Value.fromInterned(uav); | 710 | const val = Value.fromInterned(uav); |
| ... | @@ -717,35 +716,29 @@ pub fn lowerUav( | ... | @@ -717,35 +716,29 @@ pub fn lowerUav( |
| 717 | const sym = self.symbols.items[metadata.symbol_index]; | 716 | const sym = self.symbols.items[metadata.symbol_index]; |
| 718 | const existing_alignment = sym.getAtom(macho_file).?.alignment; | 717 | const existing_alignment = sym.getAtom(macho_file).?.alignment; |
| 719 | if (uav_alignment.order(existing_alignment).compare(.lte)) | 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 | var name_buf: [32]u8 = undefined; | 722 | var name_buf: [32]u8 = undefined; |
| 724 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ | 723 | const name = std.fmt.bufPrint(&name_buf, "__anon_{d}", .{ |
| 725 | @intFromEnum(uav), | 724 | @intFromEnum(uav), |
| 726 | }) catch unreachable; | 725 | }) catch unreachable; |
| 727 | const res = self.lowerConst( | 726 | const sym_index = self.lowerConst( |
| 728 | macho_file, | 727 | macho_file, |
| 729 | pt, | 728 | pt, |
| 730 | name, | 729 | name, |
| 731 | val, | 730 | val, |
| 732 | uav_alignment, | 731 | uav_alignment, |
| 733 | macho_file.zig_const_sect_index.?, | 732 | macho_file.zig_const_sect_index.?, |
| 734 | src_loc, | ||
| 735 | ) catch |err| switch (err) { | 733 | ) catch |err| switch (err) { |
| 736 | error.OutOfMemory => |e| return e, | 734 | error.OutOfMemory => |e| return e, |
| 737 | else => |e| return .{ .fail = try Zcu.ErrorMsg.create( | 735 | else => |e| return macho_file.base.comp.link_diags.fail( |
| 738 | gpa, | 736 | "failed to lower constant value: {t}", |
| 739 | src_loc, | 737 | .{e}, |
| 740 | "unable to lower constant value: {s}", | 738 | ), |
| 741 | .{@errorName(e)}, | ||
| 742 | ) }, | ||
| 743 | }; | 739 | }; |
| 744 | switch (res) { | 740 | try self.uavs.put(gpa, uav, .{ .symbol_index = @intFromEnum(sym_index) }); |
| 745 | .sym_index => |sym_index| try self.uavs.put(gpa, uav, .{ .symbol_index = @intFromEnum(sym_index) }), | 741 | return sym_index; |
| 746 | .fail => {}, | ||
| 747 | } | ||
| 748 | return res; | ||
| 749 | } | 742 | } |
| 750 | 743 | ||
| 751 | fn freeNavMetadata(self: *ZigObject, macho_file: *MachO, sym_index: Symbol.Index) void { | 744 | fn freeNavMetadata(self: *ZigObject, macho_file: *MachO, sym_index: Symbol.Index) void { |
| ... | @@ -776,7 +769,7 @@ pub fn updateFunc( | ... | @@ -776,7 +769,7 @@ pub fn updateFunc( |
| 776 | pt: Zcu.PerThread, | 769 | pt: Zcu.PerThread, |
| 777 | func_index: InternPool.Index, | 770 | func_index: InternPool.Index, |
| 778 | mir: *const codegen.AnyMir, | 771 | mir: *const codegen.AnyMir, |
| 779 | ) link.File.UpdateNavError!void { | 772 | ) link.Error!void { |
| 780 | const tracy = trace(@src()); | 773 | const tracy = trace(@src()); |
| 781 | defer tracy.end(); | 774 | defer tracy.end(); |
| 782 | 775 | ||
| ... | @@ -796,7 +789,6 @@ pub fn updateFunc( | ... | @@ -796,7 +789,6 @@ pub fn updateFunc( |
| 796 | codegen.emitFunction( | 789 | codegen.emitFunction( |
| 797 | &macho_file.base, | 790 | &macho_file.base, |
| 798 | pt, | 791 | pt, |
| 799 | zcu.navSrcLoc(func.owner_nav), | ||
| 800 | func_index, | 792 | func_index, |
| 801 | @enumFromInt(sym_index), | 793 | @enumFromInt(sym_index), |
| 802 | mir, | 794 | mir, |
| ... | @@ -867,7 +859,7 @@ pub fn updateNav( | ... | @@ -867,7 +859,7 @@ pub fn updateNav( |
| 867 | macho_file: *MachO, | 859 | macho_file: *MachO, |
| 868 | pt: Zcu.PerThread, | 860 | pt: Zcu.PerThread, |
| 869 | nav_index: InternPool.Nav.Index, | 861 | nav_index: InternPool.Nav.Index, |
| 870 | ) link.File.UpdateNavError!void { | 862 | ) link.Error!void { |
| 871 | const tracy = trace(@src()); | 863 | const tracy = trace(@src()); |
| 872 | defer tracy.end(); | 864 | defer tracy.end(); |
| 873 | 865 | ||
| ... | @@ -887,7 +879,7 @@ pub fn updateNav( | ... | @@ -887,7 +879,7 @@ pub fn updateNav( |
| 887 | var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, @enumFromInt(sym_index)); | 879 | var debug_wip_nav = try dwarf.initWipNav(pt, nav_index, @enumFromInt(sym_index)); |
| 888 | defer debug_wip_nav.deinit(); | 880 | defer debug_wip_nav.deinit(); |
| 889 | dwarf.finishWipNav(pt, nav_index, &debug_wip_nav) catch |err| switch (err) { | 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 | else => |e| return macho_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}), | 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,7 +900,6 @@ pub fn updateNav( |
| 908 | codegen.generateSymbol( | 900 | codegen.generateSymbol( |
| 909 | &macho_file.base, | 901 | &macho_file.base, |
| 910 | pt, | 902 | pt, |
| 911 | zcu.navSrcLoc(nav_index), | ||
| 912 | .fromInterned(nav.resolved.?.value), | 903 | .fromInterned(nav.resolved.?.value), |
| 913 | &aw.writer, | 904 | &aw.writer, |
| 914 | .{ .atom_index = @enumFromInt(sym_index) }, | 905 | .{ .atom_index = @enumFromInt(sym_index) }, |
| ... | @@ -925,7 +916,7 @@ pub fn updateNav( | ... | @@ -925,7 +916,7 @@ pub fn updateNav( |
| 925 | try self.updateNavCode(macho_file, pt, nav_index, sym_index, sect_index, code); | 916 | try self.updateNavCode(macho_file, pt, nav_index, sym_index, sect_index, code); |
| 926 | 917 | ||
| 927 | if (debug_wip_nav) |*wip_nav| self.dwarf.?.finishWipNav(pt, nav_index, wip_nav) catch |err| switch (err) { | 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 | else => |e| return macho_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}), | 920 | else => |e| return macho_file.base.cgFail(nav_index, "failed to finish dwarf nav: {s}", .{@errorName(e)}), |
| 930 | }; | 921 | }; |
| 931 | } else if (self.dwarf) |*dwarf| try dwarf.updateComptimeNav(pt, nav_index); | 922 | } else if (self.dwarf) |*dwarf| try dwarf.updateComptimeNav(pt, nav_index); |
| ... | @@ -941,7 +932,7 @@ fn updateNavCode( | ... | @@ -941,7 +932,7 @@ fn updateNavCode( |
| 941 | sym_index: Symbol.Index, | 932 | sym_index: Symbol.Index, |
| 942 | sect_index: u8, | 933 | sect_index: u8, |
| 943 | code: []const u8, | 934 | code: []const u8, |
| 944 | ) link.File.UpdateNavError!void { | 935 | ) link.Error!void { |
| 945 | const zcu = pt.zcu; | 936 | const zcu = pt.zcu; |
| 946 | const gpa = zcu.gpa; | 937 | const gpa = zcu.gpa; |
| 947 | const comp = zcu.comp; | 938 | const comp = zcu.comp; |
| ... | @@ -1198,8 +1189,7 @@ fn lowerConst( | ... | @@ -1198,8 +1189,7 @@ fn lowerConst( |
| 1198 | val: Value, | 1189 | val: Value, |
| 1199 | required_alignment: Atom.Alignment, | 1190 | required_alignment: Atom.Alignment, |
| 1200 | output_section_index: u8, | 1191 | output_section_index: u8, |
| 1201 | src_loc: Zcu.LazySrcLoc, | 1192 | ) !link.File.SymbolId { |
| 1202 | ) !codegen.SymbolResult { | ||
| 1203 | const gpa = macho_file.base.comp.gpa; | 1193 | const gpa = macho_file.base.comp.gpa; |
| 1204 | 1194 | ||
| 1205 | var aw: std.Io.Writer.Allocating = .init(gpa); | 1195 | var aw: std.Io.Writer.Allocating = .init(gpa); |
| ... | @@ -1211,7 +1201,6 @@ fn lowerConst( | ... | @@ -1211,7 +1201,6 @@ fn lowerConst( |
| 1211 | codegen.generateSymbol( | 1201 | codegen.generateSymbol( |
| 1212 | &macho_file.base, | 1202 | &macho_file.base, |
| 1213 | pt, | 1203 | pt, |
| 1214 | src_loc, | ||
| 1215 | val, | 1204 | val, |
| 1216 | &aw.writer, | 1205 | &aw.writer, |
| 1217 | .{ .atom_index = @enumFromInt(sym_index) }, | 1206 | .{ .atom_index = @enumFromInt(sym_index) }, |
| ... | @@ -1242,7 +1231,7 @@ fn lowerConst( | ... | @@ -1242,7 +1231,7 @@ fn lowerConst( |
| 1242 | const file_offset = sect.offset + atom.value; | 1231 | const file_offset = sect.offset + atom.value; |
| 1243 | try macho_file.pwriteAll(code, file_offset); | 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 | pub fn updateExports( | 1237 | pub fn updateExports( |
| ... | @@ -1251,7 +1240,7 @@ pub fn updateExports( | ... | @@ -1251,7 +1240,7 @@ pub fn updateExports( |
| 1251 | pt: Zcu.PerThread, | 1240 | pt: Zcu.PerThread, |
| 1252 | exported: Zcu.Exported, | 1241 | exported: Zcu.Exported, |
| 1253 | export_indices: []const Zcu.Export.Index, | 1242 | export_indices: []const Zcu.Export.Index, |
| 1254 | ) link.File.UpdateExportsError!void { | 1243 | ) link.Error!void { |
| 1255 | const tracy = trace(@src()); | 1244 | const tracy = trace(@src()); |
| 1256 | defer tracy.end(); | 1245 | defer tracy.end(); |
| 1257 | 1246 | ||
| ... | @@ -1263,18 +1252,7 @@ pub fn updateExports( | ... | @@ -1263,18 +1252,7 @@ pub fn updateExports( |
| 1263 | break :blk self.navs.getPtr(nav).?; | 1252 | break :blk self.navs.getPtr(nav).?; |
| 1264 | }, | 1253 | }, |
| 1265 | .uav => |uav| self.uavs.getPtr(uav) orelse blk: { | 1254 | .uav => |uav| self.uavs.getPtr(uav) orelse blk: { |
| 1266 | const first_exp = export_indices[0].ptr(zcu); | 1255 | _ = try self.lowerUav(macho_file, pt, uav, .none); |
| 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 | } | ||
| 1278 | break :blk self.uavs.getPtr(uav).?; | 1256 | break :blk self.uavs.getPtr(uav).?; |
| 1279 | }, | 1257 | }, |
| 1280 | }; | 1258 | }; |
| ... | @@ -1368,11 +1346,9 @@ fn updateLazySymbol( | ... | @@ -1368,11 +1346,9 @@ fn updateLazySymbol( |
| 1368 | break :blk try self.addString(gpa, name); | 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 | try codegen.generateLazySymbol( | 1349 | try codegen.generateLazySymbol( |
| 1373 | &macho_file.base, | 1350 | &macho_file.base, |
| 1374 | pt, | 1351 | pt, |
| 1375 | src, | ||
| 1376 | lazy_sym, | 1352 | lazy_sym, |
| 1377 | &required_alignment, | 1353 | &required_alignment, |
| 1378 | &aw.writer, | 1354 | &aw.writer, |
| ... | @@ -1413,12 +1389,12 @@ fn updateLazySymbol( | ... | @@ -1413,12 +1389,12 @@ fn updateLazySymbol( |
| 1413 | try macho_file.pwriteAll(code, file_offset); | 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 | if (self.dwarf) |*dwarf| { | 1393 | if (self.dwarf) |*dwarf| { |
| 1418 | const comp = dwarf.bin_file.comp; | 1394 | const comp = dwarf.bin_file.comp; |
| 1419 | const diags = &comp.link_diags; | 1395 | const diags = &comp.link_diags; |
| 1420 | dwarf.updateLineNumber(pt.zcu, ti_id) catch |err| switch (err) { | 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 | else => |e| return diags.fail("failed to update dwarf line numbers: {s}", .{@errorName(e)}), | 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,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 | const gpa = comp.gpa; | 2 | const gpa = comp.gpa; |
| 3 | const io = comp.io; | 3 | const io = comp.io; |
| 4 | const diags = &comp.link_diags; | 4 | const diags = &comp.link_diags; |
| ... | @@ -34,15 +34,15 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat | ... | @@ -34,15 +34,15 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat |
| 34 | diags.addParseError(link_input.path().?, "failed to read input file: {s}", .{@errorName(err)}); | 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 | try macho_file.parseInputFiles(); | 39 | try macho_file.parseInputFiles(); |
| 40 | 40 | ||
| 41 | if (diags.hasErrors()) return error.LinkFailure; | 41 | if (diags.hasErrors()) return error.AlreadyReported; |
| 42 | 42 | ||
| 43 | try macho_file.resolveSymbols(); | 43 | try macho_file.resolveSymbols(); |
| 44 | macho_file.dedupLiterals() catch |err| switch (err) { | 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 | else => |e| return diags.fail("failed to update ar size: {s}", .{@errorName(e)}), | 46 | else => |e| return diags.fail("failed to update ar size: {s}", .{@errorName(e)}), |
| 47 | }; | 47 | }; |
| 48 | markExports(macho_file); | 48 | markExports(macho_file); |
| ... | @@ -54,7 +54,7 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat | ... | @@ -54,7 +54,7 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat |
| 54 | 54 | ||
| 55 | try createSegment(macho_file); | 55 | try createSegment(macho_file); |
| 56 | allocateSections(macho_file) catch |err| switch (err) { | 56 | allocateSections(macho_file) catch |err| switch (err) { |
| 57 | error.LinkFailure => |e| return e, | 57 | error.AlreadyReported => |e| return e, |
| 58 | else => |e| return diags.fail("failed to allocate sections: {s}", .{@errorName(e)}), | 58 | else => |e| return diags.fail("failed to allocate sections: {s}", .{@errorName(e)}), |
| 59 | }; | 59 | }; |
| 60 | allocateSegment(macho_file); | 60 | allocateSegment(macho_file); |
| ... | @@ -75,7 +75,7 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat | ... | @@ -75,7 +75,7 @@ pub fn flushObject(macho_file: *MachO, comp: *Compilation, module_obj_path: ?Pat |
| 75 | try writeHeader(macho_file, ncmds, sizeofcmds); | 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 | const gpa = comp.gpa; | 79 | const gpa = comp.gpa; |
| 80 | const io = comp.io; | 80 | const io = comp.io; |
| 81 | const diags = &macho_file.base.comp.link_diags; | 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,11 +105,11 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ? |
| 105 | diags.addParseError(link_input.path().?, "failed to read input file: {s}", .{@errorName(err)}); | 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 | try parseInputFilesAr(macho_file); | 110 | try parseInputFilesAr(macho_file); |
| 111 | 111 | ||
| 112 | if (diags.hasErrors()) return error.LinkFailure; | 112 | if (diags.hasErrors()) return error.AlreadyReported; |
| 113 | 113 | ||
| 114 | // First, we flush relocatable object file generated with our backends. | 114 | // First, we flush relocatable object file generated with our backends. |
| 115 | if (macho_file.getZigObject()) |zo| { | 115 | if (macho_file.getZigObject()) |zo| { |
| ... | @@ -231,7 +231,7 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ? | ... | @@ -231,7 +231,7 @@ pub fn flushStaticLib(macho_file: *MachO, comp: *Compilation, module_obj_path: ? |
| 231 | try macho_file.setLength(total_size); | 231 | try macho_file.setLength(total_size); |
| 232 | try macho_file.pwriteAll(writer.buffered(), 0); | 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 | fn parseInputFilesAr(macho_file: *MachO) !void { | 237 | fn parseInputFilesAr(macho_file: *MachO) !void { |
| ... | @@ -339,7 +339,7 @@ fn calcSectionSizes(macho_file: *MachO) !void { | ... | @@ -339,7 +339,7 @@ fn calcSectionSizes(macho_file: *MachO) !void { |
| 339 | } | 339 | } |
| 340 | try calcSymtabSize(macho_file); | 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 | fn calcSectionSizeWorker(macho_file: *MachO, sect_id: u8) void { | 345 | fn calcSectionSizeWorker(macho_file: *MachO, sect_id: u8) void { |
| ... | @@ -586,7 +586,7 @@ fn sortRelocs(macho_file: *MachO) 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 | const tracy = trace(@src()); | 590 | const tracy = trace(@src()); |
| 591 | defer tracy.end(); | 591 | defer tracy.end(); |
| 592 | 592 | ||
| ... | @@ -632,7 +632,7 @@ fn writeSections(macho_file: *MachO) link.File.FlushError!void { | ... | @@ -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 | if (macho_file.getZigObject()) |zo| { | 637 | if (macho_file.getZigObject()) |zo| { |
| 638 | try zo.writeRelocs(macho_file); | 638 | try zo.writeRelocs(macho_file); |
| ... | @@ -685,7 +685,7 @@ fn writeSectionsToFile(macho_file: *MachO) !void { | ... | @@ -685,7 +685,7 @@ fn writeSectionsToFile(macho_file: *MachO) !void { |
| 685 | try macho_file.pwriteAll(macho_file.strtab.items, macho_file.symtab_cmd.stroff); | 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 | const gpa = macho_file.base.comp.gpa; | 689 | const gpa = macho_file.base.comp.gpa; |
| 690 | const needed_size = load_commands.calcLoadCommandsSizeObject(macho_file); | 690 | const needed_size = load_commands.calcLoadCommandsSizeObject(macho_file); |
| 691 | const buffer = try gpa.alloc(u8, needed_size); | 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,6 +5,7 @@ const is_linux = builtin.os.tag == .linux; |
| 5 | const is_windows = builtin.os.tag == .windows; | 5 | const is_windows = builtin.os.tag == .windows; |
| 6 | 6 | ||
| 7 | const std = @import("std"); | 7 | const std = @import("std"); |
| 8 | const Allocator = std.mem.Allocator; | ||
| 8 | const Io = std.Io; | 9 | const Io = std.Io; |
| 9 | const assert = std.debug.assert; | 10 | const assert = std.debug.assert; |
| 10 | const linux = std.os.linux; | 11 | const linux = std.os.linux; |
| ... | @@ -24,14 +25,40 @@ large: std.ArrayList(u64), | ... | @@ -24,14 +25,40 @@ large: std.ArrayList(u64), |
| 24 | updates: std.ArrayList(Node.Index), | 25 | updates: std.ArrayList(Node.Index), |
| 25 | update_prog_node: std.Progress.Node, | 26 | update_prog_node: std.Progress.Node, |
| 26 | writers: std.SinglyLinkedList, | 27 | writers: std.SinglyLinkedList, |
| 28 | io_err: ?IoError, | ||
| 27 | 29 | ||
| 28 | pub const growth_factor = 4; | 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 | NotFile, | 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 | var mf: MappedFile = .{ | 62 | var mf: MappedFile = .{ |
| 36 | .io = io, | 63 | .io = io, |
| 37 | .flags = undefined, | 64 | .flags = undefined, |
| ... | @@ -47,10 +74,14 @@ pub fn init(file: Io.File, gpa: std.mem.Allocator, io: Io) !MappedFile { | ... | @@ -47,10 +74,14 @@ pub fn init(file: Io.File, gpa: std.mem.Allocator, io: Io) !MappedFile { |
| 47 | .updates = .empty, | 74 | .updates = .empty, |
| 48 | .update_prog_node = .none, | 75 | .update_prog_node = .none, |
| 49 | .writers = .{}, | 76 | .writers = .{}, |
| 77 | .io_err = null, | ||
| 50 | }; | 78 | }; |
| 51 | errdefer mf.deinit(gpa); | 79 | errdefer mf.deinit(gpa); |
| 52 | const size: u64, const block_size = stat: { | 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 | if (stat.kind != .file) return error.PathAlreadyExists; | 85 | if (stat.kind != .file) return error.PathAlreadyExists; |
| 55 | break :stat .{ stat.size, @max(std.heap.pageSize(), stat.block_size) }; | 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,14 +92,16 @@ pub fn init(file: Io.File, gpa: std.mem.Allocator, io: Io) !MappedFile { |
| 61 | .fallocate_punch_hole_unsupported = false, | 92 | .fallocate_punch_hole_unsupported = false, |
| 62 | }; | 93 | }; |
| 63 | try mf.nodes.ensureUnusedCapacity(gpa, 1); | 94 | try mf.nodes.ensureUnusedCapacity(gpa, 1); |
| 64 | assert(try mf.addNode(gpa, .{ | 95 | const root_ni = mf.addNode(gpa, .{ .add_node = .{ |
| 65 | .add_node = .{ | 96 | .size = size, |
| 66 | .size = size, | 97 | .alignment = mf.flags.block_size, |
| 67 | .alignment = mf.flags.block_size, | 98 | .fixed = true, |
| 68 | .fixed = true, | 99 | } }) catch |err| switch (err) { |
| 69 | }, | 100 | error.MappedFileIo => return mf.io_err.?, |
| 70 | }) == Node.Index.root); | 101 | else => |e| return e, |
| 71 | try mf.ensureTotalCapacity(@intCast(size)); | 102 | }; |
| 103 | assert(root_ni == Node.Index.root); | ||
| 104 | try mf.ensureTotalCapacityInner(@intCast(size)); | ||
| 72 | return mf; | 105 | return mf; |
| 73 | } | 106 | } |
| 74 | 107 | ||
| ... | @@ -174,7 +207,7 @@ pub const Node = extern struct { | ... | @@ -174,7 +207,7 @@ pub const Node = extern struct { |
| 174 | return .{ .mf = mf, .ni = ni.get(mf).last }; | 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 | var child_ni = ni.get(mf).last; | 211 | var child_ni = ni.get(mf).last; |
| 179 | while (child_ni != .none) { | 212 | while (child_ni != .none) { |
| 180 | try child_ni.moved(gpa, mf); | 213 | try child_ni.moved(gpa, mf); |
| ... | @@ -192,7 +225,7 @@ pub const Node = extern struct { | ... | @@ -192,7 +225,7 @@ pub const Node = extern struct { |
| 192 | } | 225 | } |
| 193 | return false; | 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 | try mf.updates.ensureUnusedCapacity(gpa, 1); | 229 | try mf.updates.ensureUnusedCapacity(gpa, 1); |
| 197 | ni.movedAssumeCapacity(mf); | 230 | ni.movedAssumeCapacity(mf); |
| 198 | } | 231 | } |
| ... | @@ -213,7 +246,7 @@ pub const Node = extern struct { | ... | @@ -213,7 +246,7 @@ pub const Node = extern struct { |
| 213 | pub fn hasResized(ni: Node.Index, mf: *const MappedFile) bool { | 246 | pub fn hasResized(ni: Node.Index, mf: *const MappedFile) bool { |
| 214 | return ni.get(mf).flags.resized; | 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 | try mf.updates.ensureUnusedCapacity(gpa, 1); | 250 | try mf.updates.ensureUnusedCapacity(gpa, 1); |
| 218 | ni.resizedAssumeCapacity(mf); | 251 | ni.resizedAssumeCapacity(mf); |
| 219 | } | 252 | } |
| ... | @@ -296,8 +329,16 @@ pub const Node = extern struct { | ... | @@ -296,8 +329,16 @@ pub const Node = extern struct { |
| 296 | return mf.memory_map.memory[@intCast(file_loc.offset)..][0..@intCast(file_loc.size)]; | 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 { | 332 | pub fn resize(ni: Node.Index, mf: *MappedFile, gpa: std.mem.Allocator, size: u64) Error!void { |
| 300 | try mf.resizeNode(gpa, ni, size); | 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 | var writers_it = mf.writers.first; | 342 | var writers_it = mf.writers.first; |
| 302 | while (writers_it) |writer_node| : (writers_it = writer_node.next) { | 343 | while (writers_it) |writer_node| : (writers_it = writer_node.next) { |
| 303 | const w: *Node.Writer = @fieldParentPtr("writer_node", writer_node); | 344 | const w: *Node.Writer = @fieldParentPtr("writer_node", writer_node); |
| ... | @@ -313,8 +354,16 @@ pub const Node = extern struct { | ... | @@ -313,8 +354,16 @@ pub const Node = extern struct { |
| 313 | mf: *MappedFile, | 354 | mf: *MappedFile, |
| 314 | gpa: std.mem.Allocator, | 355 | gpa: std.mem.Allocator, |
| 315 | new_alignment: std.mem.Alignment, | 356 | new_alignment: std.mem.Alignment, |
| 316 | ) !void { | 357 | ) Error!void { |
| 317 | try mf.realignNode(gpa, ni, new_alignment); | 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 | var writers_it = mf.writers.first; | 367 | var writers_it = mf.writers.first; |
| 319 | while (writers_it) |writer_node| : (writers_it = writer_node.next) { | 368 | while (writers_it) |writer_node| : (writers_it = writer_node.next) { |
| 320 | const w: *Node.Writer = @fieldParentPtr("writer_node", writer_node); | 369 | const w: *Node.Writer = @fieldParentPtr("writer_node", writer_node); |
| ... | @@ -422,9 +471,16 @@ pub const Node = extern struct { | ... | @@ -422,9 +471,16 @@ pub const Node = extern struct { |
| 422 | file_reader.pos, | 471 | file_reader.pos, |
| 423 | w.ni.fileLocation(w.mf, true).offset + interface.end, | 472 | w.ni.fileLocation(w.mf, true).offset + interface.end, |
| 424 | limit.minInt(interface.unusedCapacityLen()), | 473 | limit.minInt(interface.unusedCapacityLen()), |
| 425 | ) catch |err| { | 474 | ) catch |err| switch (err) { |
| 426 | w.err = err; | 475 | error.Canceled => |e| { |
| 427 | return error.WriteFailed; | 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 | if (n == 0) return error.Unimplemented; | 485 | if (n == 0) return error.Unimplemented; |
| 430 | file_reader.pos += n; | 486 | file_reader.pos += n; |
| ... | @@ -472,7 +528,7 @@ fn addNode(mf: *MappedFile, gpa: std.mem.Allocator, opts: struct { | ... | @@ -472,7 +528,7 @@ fn addNode(mf: *MappedFile, gpa: std.mem.Allocator, opts: struct { |
| 472 | next: Node.Index = .none, | 528 | next: Node.Index = .none, |
| 473 | offset: u64 = 0, | 529 | offset: u64 = 0, |
| 474 | add_node: AddNodeOptions, | 530 | add_node: AddNodeOptions, |
| 475 | }) !Node.Index { | 531 | }) Error!Node.Index { |
| 476 | if (opts.add_node.moved or opts.add_node.resized) try mf.updates.ensureUnusedCapacity(gpa, 1); | 532 | if (opts.add_node.moved or opts.add_node.resized) try mf.updates.ensureUnusedCapacity(gpa, 1); |
| 477 | const offset = opts.add_node.alignment.forward(@intCast(opts.offset)); | 533 | const offset = opts.add_node.alignment.forward(@intCast(opts.offset)); |
| 478 | const location_tag: Node.Location.Tag, const location_payload: Node.Location.Payload = location: { | 534 | const location_tag: Node.Location.Tag, const location_payload: Node.Location.Payload = location: { |
| ... | @@ -544,7 +600,7 @@ pub fn addOnlyChildNode( | ... | @@ -544,7 +600,7 @@ pub fn addOnlyChildNode( |
| 544 | gpa: std.mem.Allocator, | 600 | gpa: std.mem.Allocator, |
| 545 | parent_ni: Node.Index, | 601 | parent_ni: Node.Index, |
| 546 | opts: AddNodeOptions, | 602 | opts: AddNodeOptions, |
| 547 | ) !Node.Index { | 603 | ) Error!Node.Index { |
| 548 | try mf.nodes.ensureUnusedCapacity(gpa, 1); | 604 | try mf.nodes.ensureUnusedCapacity(gpa, 1); |
| 549 | const parent = parent_ni.get(mf); | 605 | const parent = parent_ni.get(mf); |
| 550 | assert(parent.first == .none and parent.last == .none); | 606 | assert(parent.first == .none and parent.last == .none); |
| ... | @@ -559,7 +615,7 @@ pub fn addFirstChildNode( | ... | @@ -559,7 +615,7 @@ pub fn addFirstChildNode( |
| 559 | gpa: std.mem.Allocator, | 615 | gpa: std.mem.Allocator, |
| 560 | parent_ni: Node.Index, | 616 | parent_ni: Node.Index, |
| 561 | opts: AddNodeOptions, | 617 | opts: AddNodeOptions, |
| 562 | ) !Node.Index { | 618 | ) Error!Node.Index { |
| 563 | try mf.nodes.ensureUnusedCapacity(gpa, 1); | 619 | try mf.nodes.ensureUnusedCapacity(gpa, 1); |
| 564 | const parent = parent_ni.get(mf); | 620 | const parent = parent_ni.get(mf); |
| 565 | return mf.addNode(gpa, .{ | 621 | return mf.addNode(gpa, .{ |
| ... | @@ -574,7 +630,7 @@ pub fn addLastChildNode( | ... | @@ -574,7 +630,7 @@ pub fn addLastChildNode( |
| 574 | gpa: std.mem.Allocator, | 630 | gpa: std.mem.Allocator, |
| 575 | parent_ni: Node.Index, | 631 | parent_ni: Node.Index, |
| 576 | opts: AddNodeOptions, | 632 | opts: AddNodeOptions, |
| 577 | ) !Node.Index { | 633 | ) Error!Node.Index { |
| 578 | try mf.nodes.ensureUnusedCapacity(gpa, 1); | 634 | try mf.nodes.ensureUnusedCapacity(gpa, 1); |
| 579 | const parent = parent_ni.get(mf); | 635 | const parent = parent_ni.get(mf); |
| 580 | return mf.addNode(gpa, .{ | 636 | return mf.addNode(gpa, .{ |
| ... | @@ -596,7 +652,7 @@ pub fn addNodeAfter( | ... | @@ -596,7 +652,7 @@ pub fn addNodeAfter( |
| 596 | gpa: std.mem.Allocator, | 652 | gpa: std.mem.Allocator, |
| 597 | prev_ni: Node.Index, | 653 | prev_ni: Node.Index, |
| 598 | opts: AddNodeOptions, | 654 | opts: AddNodeOptions, |
| 599 | ) !Node.Index { | 655 | ) Error!Node.Index { |
| 600 | assert(prev_ni != .none); | 656 | assert(prev_ni != .none); |
| 601 | try mf.nodes.ensureUnusedCapacity(gpa, 1); | 657 | try mf.nodes.ensureUnusedCapacity(gpa, 1); |
| 602 | const prev = prev_ni.get(mf); | 658 | const prev = prev_ni.get(mf); |
| ... | @@ -610,7 +666,7 @@ pub fn addNodeAfter( | ... | @@ -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 | const io = mf.io; | 670 | const io = mf.io; |
| 615 | const node = ni.get(mf); | 671 | const node = ni.get(mf); |
| 616 | const old_offset, const old_size = node.location().resolve(mf); | 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,9 +674,13 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested |
| 618 | // Resize the entire file | 674 | // Resize the entire file |
| 619 | if (ni == Node.Index.root) { | 675 | if (ni == Node.Index.root) { |
| 620 | try mf.ensureCapacityForSetLocation(gpa); | 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 | try mf.memory_map.file.setLength(io, new_size); | 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 | ni.setLocationAssumeCapacity(mf, old_offset, new_size); | 684 | ni.setLocationAssumeCapacity(mf, old_offset, new_size); |
| 625 | return; | 685 | return; |
| 626 | } | 686 | } |
| ... | @@ -643,7 +703,11 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested | ... | @@ -643,7 +703,11 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested |
| 643 | if (is_linux and !mf.flags.fallocate_insert_range_unsupported and | 703 | if (is_linux and !mf.flags.fallocate_insert_range_unsupported and |
| 644 | node.flags.alignment.order(mf.flags.block_size).compare(.gte)) | 704 | node.flags.alignment.order(mf.flags.block_size).compare(.gte)) |
| 645 | insert_range: { | 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 | // Ask the filesystem driver to insert extents into the file without copying any data | 711 | // Ask the filesystem driver to insert extents into the file without copying any data |
| 648 | const last_offset, const last_size = parent.last.location(mf).resolve(mf); | 712 | const last_offset, const last_size = parent.last.location(mf).resolve(mf); |
| 649 | const last_end = last_offset + last_size; | 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,7 +738,7 @@ fn resizeNode(mf: *MappedFile, gpa: std.mem.Allocator, ni: Node.Index, requested |
| 674 | enclosing_ni.setLocationAssumeCapacity(mf, enclosing_offset, new_enclosing_size); | 738 | enclosing_ni.setLocationAssumeCapacity(mf, enclosing_offset, new_enclosing_size); |
| 675 | if (enclosing_ni == Node.Index.root) { | 739 | if (enclosing_ni == Node.Index.root) { |
| 676 | assert(enclosing_offset == 0); | 740 | assert(enclosing_offset == 0); |
| 677 | try mf.ensureTotalCapacity(@intCast(new_enclosing_size)); | 741 | try mf.ensureTotalCapacityInner(@intCast(new_enclosing_size)); |
| 678 | break; | 742 | break; |
| 679 | } | 743 | } |
| 680 | var after_ni = enclosing.next; | 744 | var after_ni = enclosing.next; |
| ... | @@ -865,7 +929,7 @@ fn realignNode( | ... | @@ -865,7 +929,7 @@ fn realignNode( |
| 865 | gpa: std.mem.Allocator, | 929 | gpa: std.mem.Allocator, |
| 866 | ni: Node.Index, | 930 | ni: Node.Index, |
| 867 | new_alignment: std.mem.Alignment, | 931 | new_alignment: std.mem.Alignment, |
| 868 | ) !void { | 932 | ) (Allocator.Error || Io.Cancelable || IoError)!void { |
| 869 | assert(ni != Node.Index.root); // currently unsupported | 933 | assert(ni != Node.Index.root); // currently unsupported |
| 870 | 934 | ||
| 871 | const node = ni.get(mf); | 935 | const node = ni.get(mf); |
| ... | @@ -936,7 +1000,7 @@ fn realignNode( | ... | @@ -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 | // make a copy of this node at the new location | 1004 | // make a copy of this node at the new location |
| 941 | try mf.copyRange(old_file_offset, new_file_offset, size); | 1005 | try mf.copyRange(old_file_offset, new_file_offset, size); |
| 942 | // delete the copy of this node at the old location | 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,7 +1030,7 @@ fn moveRange(mf: *MappedFile, old_file_offset: u64, new_file_offset: u64, size: |
| 966 | @memset(mf.memory_map.memory[@intCast(old_file_offset)..][0..@intCast(size)], 0); | 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 | const copy_size = try mf.copyFileRange(mf.memory_map.file, old_file_offset, new_file_offset, size); | 1034 | const copy_size = try mf.copyFileRange(mf.memory_map.file, old_file_offset, new_file_offset, size); |
| 971 | if (copy_size < size) @memcpy( | 1035 | if (copy_size < size) @memcpy( |
| 972 | mf.memory_map.memory[@intCast(new_file_offset + copy_size)..][0..@intCast(size - copy_size)], | 1036 | mf.memory_map.memory[@intCast(new_file_offset + copy_size)..][0..@intCast(size - copy_size)], |
| ... | @@ -980,9 +1044,13 @@ fn copyFileRange( | ... | @@ -980,9 +1044,13 @@ fn copyFileRange( |
| 980 | old_file_offset: u64, | 1044 | old_file_offset: u64, |
| 981 | new_file_offset: u64, | 1045 | new_file_offset: u64, |
| 982 | size: u64, | 1046 | size: u64, |
| 983 | ) !u64 { | 1047 | ) (Io.Cancelable || IoError)!u64 { |
| 984 | const io = mf.io; | 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 | var remaining_size = size; | 1054 | var remaining_size = size; |
| 987 | if (is_linux and !mf.flags.copy_file_range_unsupported) { | 1055 | if (is_linux and !mf.flags.copy_file_range_unsupported) { |
| 988 | var old_file_offset_mut: i64 = @intCast(old_file_offset); | 1056 | var old_file_offset_mut: i64 = @intCast(old_file_offset); |
| ... | @@ -1021,17 +1089,41 @@ fn copyFileRange( | ... | @@ -1021,17 +1089,41 @@ fn copyFileRange( |
| 1021 | return size - remaining_size; | 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 | try mf.large.ensureUnusedCapacity(gpa, 2); | 1093 | try mf.large.ensureUnusedCapacity(gpa, 2); |
| 1026 | try mf.updates.ensureUnusedCapacity(gpa, 1); | 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 | if (mf.memory_map.memory.len >= new_capacity) return; | 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 | if (mf.memory_map.memory.len >= new_capacity) return; | 1127 | if (mf.memory_map.memory.len >= new_capacity) return; |
| 1036 | const io = mf.io; | 1128 | const io = mf.io; |
| 1037 | const aligned_capacity = mf.flags.block_size.forward(new_capacity); | 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,7 +1139,11 @@ pub fn ensureTotalCapacityPrecise(mf: *MappedFile, new_capacity: usize) !void { |
| 1047 | } | 1139 | } |
| 1048 | 1140 | ||
| 1049 | const file = mf.memory_map.file; | 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 | pub fn unmap(mf: *MappedFile) void { | 1149 | pub fn unmap(mf: *MappedFile) void { |
| ... | @@ -1059,9 +1155,22 @@ pub fn unmap(mf: *MappedFile) void { | ... | @@ -1059,9 +1155,22 @@ pub fn unmap(mf: *MappedFile) void { |
| 1059 | mf.memory_map.file = file; | 1155 | mf.memory_map.file = file; |
| 1060 | } | 1156 | } |
| 1061 | 1157 | ||
| 1062 | pub fn flush(mf: *MappedFile) Io.File.WritePositionalError!void { | 1158 | pub fn flush(mf: *MappedFile) (Io.Cancelable || error{MappedFileIo})!void { |
| 1063 | const io = mf.io; | 1159 | mf.memory_map.write(mf.io) catch |err| switch (err) { |
| 1064 | try mf.memory_map.write(io); | 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 | fn verify(mf: *MappedFile) void { | 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,7 +135,7 @@ pub fn finishPrelinkQueue(q: *Queue, comp: *Compilation) Io.Cancelable!void { |
| 135 | lf.post_prelink = true; | 135 | lf.post_prelink = true; |
| 136 | } else |err| switch (err) { | 136 | } else |err| switch (err) { |
| 137 | error.OutOfMemory => comp.link_diags.setAllocFailure(), | 137 | error.OutOfMemory => comp.link_diags.setAllocFailure(), |
| 138 | error.LinkFailure => {}, | 138 | error.AlreadyReported => {}, |
| 139 | error.Canceled => |e| return e, | 139 | error.Canceled => |e| return e, |
| 140 | } | 140 | } |
| 141 | } | 141 | } |
| ... | @@ -178,7 +178,7 @@ fn runLinkTasks(q: *Queue, comp: *Compilation) void { | ... | @@ -178,7 +178,7 @@ fn runLinkTasks(q: *Queue, comp: *Compilation) void { |
| 178 | } else |err| switch (err) { | 178 | } else |err| switch (err) { |
| 179 | error.OutOfMemory => comp.link_diags.setAllocFailure(), | 179 | error.OutOfMemory => comp.link_diags.setAllocFailure(), |
| 180 | error.Canceled => @panic("TODO"), | 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,7 +205,11 @@ fn runIdleTask(comp: *Compilation, tid: Zcu.PerThread.Id) bool { |
| 205 | comp.link_diags.setAllocFailure(); | 205 | comp.link_diags.setAllocFailure(); |
| 206 | break :have_more false; | 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,19 +140,8 @@ fn generate( |
| 140 | }; | 140 | }; |
| 141 | 141 | ||
| 142 | linker.cg.genNav(do_codegen) catch |err| switch (err) { | 142 | linker.cg.genNav(do_codegen) catch |err| switch (err) { |
| 143 | error.CodegenFail => switch (zcu.codegenFailMsg(nav_index, linker.cg.error_msg.?)) { | 143 | error.AlreadyReported => return, |
| 144 | error.CodegenFail => {}, | 144 | else => |e| return e, |
| 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 | }, | ||
| 156 | }; | 145 | }; |
| 157 | } | 146 | } |
| 158 | 147 | ||
| ... | @@ -168,7 +157,7 @@ pub fn updateFunc( | ... | @@ -168,7 +157,7 @@ pub fn updateFunc( |
| 168 | try linker.generate(pt, nav, air.*, liveness.*.?, true); | 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 | const ip = &pt.zcu.intern_pool; | 161 | const ip = &pt.zcu.intern_pool; |
| 173 | log.debug("lowering nav {f}({d})", .{ ip.getNav(nav).fqn.fmt(ip), nav }); | 162 | log.debug("lowering nav {f}({d})", .{ ip.getNav(nav).fqn.fmt(ip), nav }); |
| 174 | try linker.generate(pt, nav, undefined, undefined, false); | 163 | try linker.generate(pt, nav, undefined, undefined, false); |
| ... | @@ -231,7 +220,7 @@ pub fn flush( | ... | @@ -231,7 +220,7 @@ pub fn flush( |
| 231 | arena: Allocator, | 220 | arena: Allocator, |
| 232 | tid: Zcu.PerThread.Id, | 221 | tid: Zcu.PerThread.Id, |
| 233 | prog_node: std.Progress.Node, | 222 | prog_node: std.Progress.Node, |
| 234 | ) link.File.FlushError!void { | 223 | ) link.Error!void { |
| 235 | // The goal is to never use this because it's only needed if we need to | 224 | // The goal is to never use this because it's only needed if we need to |
| 236 | // write to InternPool, but flush is too late to be writing to the | 225 | // write to InternPool, but flush is too late to be writing to the |
| 237 | // InternPool. | 226 | // InternPool. |
src/link/Wasm.zig+19-19| ... | @@ -568,7 +568,7 @@ pub const SourceLocation = enum(u32) { | ... | @@ -568,7 +568,7 @@ pub const SourceLocation = enum(u32) { |
| 568 | err_msg.notes[err.note_slot - 1].source_location = .{ .wasm = sl }; | 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 | return diags.failSourceLocation(.{ .wasm = sl }, format, args); | 572 | return diags.failSourceLocation(.{ .wasm = sl }, format, args); |
| 573 | } | 573 | } |
| 574 | 574 | ||
| ... | @@ -3027,12 +3027,12 @@ fn openParseObjectReportingFailure(wasm: *Wasm, path: Path) void { | ... | @@ -3027,12 +3027,12 @@ fn openParseObjectReportingFailure(wasm: *Wasm, path: Path) void { |
| 3027 | const diags = &comp.link_diags; | 3027 | const diags = &comp.link_diags; |
| 3028 | const obj = link.openObject(io, path, false, false) catch |err| { | 3028 | const obj = link.openObject(io, path, false, false) catch |err| { |
| 3029 | switch (diags.failParse(path, "failed to open object: {t}", .{err})) { | 3029 | switch (diags.failParse(path, "failed to open object: {t}", .{err})) { |
| 3030 | error.LinkFailure => return, | 3030 | error.AlreadyReported => return, |
| 3031 | } | 3031 | } |
| 3032 | }; | 3032 | }; |
| 3033 | wasm.parseObject(obj) catch |err| { | 3033 | wasm.parseObject(obj) catch |err| { |
| 3034 | switch (diags.failParse(path, "failed to parse object: {t}", .{err})) { | 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,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 | const comp = wasm.base.comp; | 3340 | const comp = wasm.base.comp; |
| 3341 | const diags = &comp.link_diags; | 3341 | const diags = &comp.link_diags; |
| 3342 | if (wasm.dwarf) |*dw| { | 3342 | if (wasm.dwarf) |*dw| { |
| 3343 | dw.updateLineNumber(pt.zcu, ti_id) catch |err| switch (err) { | 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 | else => |e| return diags.fail("failed to update dwarf line numbers: {s}", .{@errorName(e)}), | 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,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 | const tracy = trace(@src()); | 3421 | const tracy = trace(@src()); |
| 3422 | defer tracy.end(); | 3422 | defer tracy.end(); |
| 3423 | 3423 | ||
| ... | @@ -3526,7 +3526,7 @@ pub fn markFunctionImport( | ... | @@ -3526,7 +3526,7 @@ pub fn markFunctionImport( |
| 3526 | name: String, | 3526 | name: String, |
| 3527 | import: *FunctionImport, | 3527 | import: *FunctionImport, |
| 3528 | func_index: FunctionImport.Index, | 3528 | func_index: FunctionImport.Index, |
| 3529 | ) link.File.FlushError!void { | 3529 | ) link.Error!void { |
| 3530 | // import.flags.alive might be already true from a previous update. In such | 3530 | // import.flags.alive might be already true from a previous update. In such |
| 3531 | // case, we must still run the logic in this function, in case the item | 3531 | // case, we must still run the logic in this function, in case the item |
| 3532 | // being marked was reverted by the `flush` logic that resets the hash | 3532 | // being marked was reverted by the `flush` logic that resets the hash |
| ... | @@ -3557,7 +3557,7 @@ pub fn markFunctionImport( | ... | @@ -3557,7 +3557,7 @@ pub fn markFunctionImport( |
| 3557 | } | 3557 | } |
| 3558 | 3558 | ||
| 3559 | /// Recursively mark alive everything referenced by the function. | 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 | const comp = wasm.base.comp; | 3561 | const comp = wasm.base.comp; |
| 3562 | const gpa = comp.gpa; | 3562 | const gpa = comp.gpa; |
| 3563 | const gop = try wasm.functions.getOrPut(gpa, .fromObjectFunction(wasm, i)); | 3563 | const gop = try wasm.functions.getOrPut(gpa, .fromObjectFunction(wasm, i)); |
| ... | @@ -3590,7 +3590,7 @@ fn markGlobalImport( | ... | @@ -3590,7 +3590,7 @@ fn markGlobalImport( |
| 3590 | name: String, | 3590 | name: String, |
| 3591 | import: *GlobalImport, | 3591 | import: *GlobalImport, |
| 3592 | global_index: GlobalImport.Index, | 3592 | global_index: GlobalImport.Index, |
| 3593 | ) link.File.FlushError!void { | 3593 | ) link.Error!void { |
| 3594 | // import.flags.alive might be already true from a previous update. In such | 3594 | // import.flags.alive might be already true from a previous update. In such |
| 3595 | // case, we must still run the logic in this function, in case the item | 3595 | // case, we must still run the logic in this function, in case the item |
| 3596 | // being marked was reverted by the `flush` logic that resets the hash | 3596 | // being marked was reverted by the `flush` logic that resets the hash |
| ... | @@ -3630,7 +3630,7 @@ fn markGlobalImport( | ... | @@ -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 | const comp = wasm.base.comp; | 3634 | const comp = wasm.base.comp; |
| 3635 | const gpa = comp.gpa; | 3635 | const gpa = comp.gpa; |
| 3636 | const gop = try wasm.globals.getOrPut(gpa, .fromObjectGlobal(wasm, i)); | 3636 | const gop = try wasm.globals.getOrPut(gpa, .fromObjectGlobal(wasm, i)); |
| ... | @@ -3653,7 +3653,7 @@ fn markTableImport( | ... | @@ -3653,7 +3653,7 @@ fn markTableImport( |
| 3653 | name: String, | 3653 | name: String, |
| 3654 | import: *TableImport, | 3654 | import: *TableImport, |
| 3655 | table_index: TableImport.Index, | 3655 | table_index: TableImport.Index, |
| 3656 | ) link.File.FlushError!void { | 3656 | ) link.Error!void { |
| 3657 | if (import.flags.alive) return; | 3657 | if (import.flags.alive) return; |
| 3658 | import.flags.alive = true; | 3658 | import.flags.alive = true; |
| 3659 | 3659 | ||
| ... | @@ -3675,7 +3675,7 @@ fn markTableImport( | ... | @@ -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 | const comp = wasm.base.comp; | 3679 | const comp = wasm.base.comp; |
| 3680 | const segment = segment_index.ptr(wasm); | 3680 | const segment = segment_index.ptr(wasm); |
| 3681 | if (segment.flags.alive) return; | 3681 | if (segment.flags.alive) return; |
| ... | @@ -3693,7 +3693,7 @@ pub fn markDataImport( | ... | @@ -3693,7 +3693,7 @@ pub fn markDataImport( |
| 3693 | name: String, | 3693 | name: String, |
| 3694 | import: *ObjectDataImport, | 3694 | import: *ObjectDataImport, |
| 3695 | data_index: ObjectDataImport.Index, | 3695 | data_index: ObjectDataImport.Index, |
| 3696 | ) link.File.FlushError!void { | 3696 | ) link.Error!void { |
| 3697 | if (import.flags.alive) return; | 3697 | if (import.flags.alive) return; |
| 3698 | import.flags.alive = true; | 3698 | import.flags.alive = true; |
| 3699 | 3699 | ||
| ... | @@ -3715,7 +3715,7 @@ pub fn markDataImport( | ... | @@ -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 | const gpa = wasm.base.comp.gpa; | 3719 | const gpa = wasm.base.comp.gpa; |
| 3720 | for (relocs.slice.tags(wasm), relocs.slice.pointees(wasm), relocs.slice.offsets(wasm)) |tag, pointee, offset| { | 3720 | for (relocs.slice.tags(wasm), relocs.slice.pointees(wasm), relocs.slice.offsets(wasm)) |tag, pointee, offset| { |
| 3721 | if (offset >= relocs.end) break; | 3721 | if (offset >= relocs.end) break; |
| ... | @@ -3812,7 +3812,7 @@ fn markRelocations(wasm: *Wasm, relocs: ObjectRelocation.IterableSlice) link.Fil | ... | @@ -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 | try wasm.tables.put(wasm.base.comp.gpa, .fromObjectTable(i), {}); | 3816 | try wasm.tables.put(wasm.base.comp.gpa, .fromObjectTable(i), {}); |
| 3817 | } | 3817 | } |
| 3818 | 3818 | ||
| ... | @@ -3821,7 +3821,7 @@ pub fn flush( | ... | @@ -3821,7 +3821,7 @@ pub fn flush( |
| 3821 | arena: Allocator, | 3821 | arena: Allocator, |
| 3822 | tid: Zcu.PerThread.Id, | 3822 | tid: Zcu.PerThread.Id, |
| 3823 | prog_node: std.Progress.Node, | 3823 | prog_node: std.Progress.Node, |
| 3824 | ) link.File.FlushError!void { | 3824 | ) link.Error!void { |
| 3825 | // The goal is to never use this because it's only needed if we need to | 3825 | // The goal is to never use this because it's only needed if we need to |
| 3826 | // write to InternPool, but flush is too late to be writing to the | 3826 | // write to InternPool, but flush is too late to be writing to the |
| 3827 | // InternPool. | 3827 | // InternPool. |
| ... | @@ -3864,7 +3864,7 @@ pub fn flush( | ... | @@ -3864,7 +3864,7 @@ pub fn flush( |
| 3864 | try wasm.flush_buffer.data_imports.reinit(gpa, wasm.data_imports.keys(), wasm.data_imports.values()); | 3864 | try wasm.flush_buffer.data_imports.reinit(gpa, wasm.data_imports.keys(), wasm.data_imports.values()); |
| 3865 | 3865 | ||
| 3866 | return wasm.flush_buffer.finish(wasm) catch |err| switch (err) { | 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 | else => |e| return diags.fail("failed to flush wasm: {s}", .{@errorName(e)}), | 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,7 +4275,7 @@ fn lowerZcuData(wasm: *Wasm, pt: Zcu.PerThread, ip_index: InternPool.Index) !Zcu |
| 4275 | { | 4275 | { |
| 4276 | var aw: std.Io.Writer.Allocating = .fromArrayList(wasm.base.comp.gpa, &wasm.string_bytes); | 4276 | var aw: std.Io.Writer.Allocating = .fromArrayList(wasm.base.comp.gpa, &wasm.string_bytes); |
| 4277 | defer wasm.string_bytes = aw.toArrayList(); | 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 | error.WriteFailed => return error.OutOfMemory, | 4279 | error.WriteFailed => return error.OutOfMemory, |
| 4280 | else => |e| return e, | 4280 | else => |e| return e, |
| 4281 | }; | 4281 | }; |
| ... | @@ -4349,7 +4349,7 @@ fn resolveFunctionSynthetic( | ... | @@ -4349,7 +4349,7 @@ fn resolveFunctionSynthetic( |
| 4349 | res: FunctionImport.Resolution, | 4349 | res: FunctionImport.Resolution, |
| 4350 | params: []const std.wasm.Valtype, | 4350 | params: []const std.wasm.Valtype, |
| 4351 | returns: []const std.wasm.Valtype, | 4351 | returns: []const std.wasm.Valtype, |
| 4352 | ) link.File.FlushError!void { | 4352 | ) link.Error!void { |
| 4353 | import.resolution = res; | 4353 | import.resolution = res; |
| 4354 | wasm.functions.putAssumeCapacity(res, {}); | 4354 | wasm.functions.putAssumeCapacity(res, {}); |
| 4355 | // This is not only used for type-checking but also ensures the function | 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,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 | // Merge indirect function tables. | 279 | // Merge indirect function tables. |
| 280 | try f.indirect_function_table.ensureUnusedCapacity(gpa, wasm.zcu_indirect_function_set.entries.len + | 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,7 +513,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 513 | if (initial_memory > std.math.maxInt(u32)) { | 513 | if (initial_memory > std.math.maxInt(u32)) { |
| 514 | diags.addError("initial memory value {d} exceeds 32-bit address space", .{initial_memory}); | 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 | memory_ptr = initial_memory; | 517 | memory_ptr = initial_memory; |
| 518 | } else { | 518 | } else { |
| 519 | memory_ptr = mem.alignForward(u64, memory_ptr, std.wasm.page_size); | 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,7 +535,7 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void { |
| 535 | if (max_memory > std.math.maxInt(u32)) { | 535 | if (max_memory > std.math.maxInt(u32)) { |
| 536 | diags.addError("maximum memory value {d} exceeds 32-bit address space", .{max_memory}); | 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 | wasm.memories.limits.max = @intCast(max_memory / page_size); | 539 | wasm.memories.limits.max = @intCast(max_memory / page_size); |
| 540 | wasm.memories.limits.flags.has_max = true; | 540 | wasm.memories.limits.flags.has_max = true; |
| 541 | if (shared_memory) wasm.memories.limits.flags.is_shared = true; | 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,7 +1431,7 @@ fn parseFeatures( |
| 1431 | bytes: []const u8, | 1431 | bytes: []const u8, |
| 1432 | start_pos: usize, | 1432 | start_pos: usize, |
| 1433 | path: Path, | 1433 | path: Path, |
| 1434 | ) error{ OutOfMemory, LinkFailure }!struct { Wasm.Feature.Set, usize } { | 1434 | ) error{ OutOfMemory, AlreadyReported }!struct { Wasm.Feature.Set, usize } { |
| 1435 | const gpa = wasm.base.comp.gpa; | 1435 | const gpa = wasm.base.comp.gpa; |
| 1436 | const diags = &wasm.base.comp.link_diags; | 1436 | const diags = &wasm.base.comp.link_diags; |
| 1437 | const features_len, var pos = readLeb(u32, bytes, start_pos); | 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,7 +14,7 @@ const link = @import("link.zig"); |
| 14 | 14 | ||
| 15 | const log = std.log.scoped(.register_manager); | 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 | pub fn RegisterManager( | 19 | pub fn RegisterManager( |
| 20 | comptime Function: type, | 20 | comptime Function: type, |