| ... | @@ -94,6 +94,13 @@ pub const imp_prefix = "__imp_"; | ... | @@ -94,6 +94,13 @@ pub const imp_prefix = "__imp_"; |
| 94 | | 94 | |
| 95 | const header_name_max_len = @typeInfo(@FieldType(std.coff.SectionHeader, "name")).array.len; | 95 | const header_name_max_len = @typeInfo(@FieldType(std.coff.SectionHeader, "name")).array.len; |
| 96 | | 96 | |
| | 97 | const Error = link.Error || error{MappedFileIo}; |
| | 98 | const LoadInputError = Error || |
| | 99 | Io.File.SeekError || |
| | 100 | Io.File.Reader.SizeError || |
| | 101 | Io.Reader.Error || |
| | 102 | MappedFile.Error; |
| | 103 | |
| 97 | /// This is the start of a Portable Executable (PE) file. | 104 | /// This is the start of a Portable Executable (PE) file. |
| 98 | /// It starts with a MS-DOS header followed by a MS-DOS stub program. | 105 | /// It starts with a MS-DOS header followed by a MS-DOS stub program. |
| 99 | /// This data does not change so we include it as follows in all binaries. | 106 | /// This data does not change so we include it as follows in all binaries. |
| ... | @@ -484,7 +491,7 @@ pub const Member = struct { | ... | @@ -484,7 +491,7 @@ pub const Member = struct { |
| 484 | longnames, | 491 | longnames, |
| 485 | _, | 492 | _, |
| 486 | | 493 | |
| 487 | const known_count = @typeInfo(Index).@"enum".fields.len; | 494 | const known_count = @typeInfo(Index).@"enum".field_names.len; |
| 488 | | 495 | |
| 489 | pub fn get(member_index: Member.Index, coff: *Coff) *Member { | 496 | pub fn get(member_index: Member.Index, coff: *Coff) *Member { |
| 490 | return &coff.members.items[@intFromEnum(member_index)]; | 497 | return &coff.members.items[@intFromEnum(member_index)]; |
| ... | @@ -2855,7 +2862,7 @@ pub fn getNavVAddr( | ... | @@ -2855,7 +2862,7 @@ pub fn getNavVAddr( |
| 2855 | pt: Zcu.PerThread, | 2862 | pt: Zcu.PerThread, |
| 2856 | nav: InternPool.Nav.Index, | 2863 | nav: InternPool.Nav.Index, |
| 2857 | reloc_info: link.File.RelocInfo, | 2864 | reloc_info: link.File.RelocInfo, |
| 2858 | ) !u64 { | 2865 | ) link.Error!u64 { |
| 2859 | return coff.getVAddr(reloc_info, try coff.navSymbol(pt.zcu, nav)); | 2866 | return coff.getVAddr(reloc_info, try coff.navSymbol(pt.zcu, nav)); |
| 2860 | } | 2867 | } |
| 2861 | | 2868 | |
| ... | @@ -2863,11 +2870,11 @@ pub fn getUavVAddr( | ... | @@ -2863,11 +2870,11 @@ pub fn getUavVAddr( |
| 2863 | coff: *Coff, | 2870 | coff: *Coff, |
| 2864 | uav: InternPool.Index, | 2871 | uav: InternPool.Index, |
| 2865 | reloc_info: link.File.RelocInfo, | 2872 | reloc_info: link.File.RelocInfo, |
| 2866 | ) !u64 { | 2873 | ) link.Error!u64 { |
| 2867 | return coff.getVAddr(reloc_info, try coff.uavSymbol(uav)); | 2874 | return coff.getVAddr(reloc_info, try coff.uavSymbol(uav)); |
| 2868 | } | 2875 | } |
| 2869 | | 2876 | |
| 2870 | pub fn getVAddr(coff: *Coff, reloc_info: link.File.RelocInfo, target_si: Symbol.Index) !u64 { | 2877 | pub fn getVAddr(coff: *Coff, reloc_info: link.File.RelocInfo, target_si: Symbol.Index) link.Error!u64 { |
| 2871 | try coff.addReloc( | 2878 | try coff.addReloc( |
| 2872 | @enumFromInt(@intFromEnum(reloc_info.parent.atom_index)), | 2879 | @enumFromInt(@intFromEnum(reloc_info.parent.atom_index)), |
| 2873 | reloc_info.offset, | 2880 | reloc_info.offset, |
| ... | @@ -3524,19 +3531,13 @@ fn objectSectionMapIndex( | ... | @@ -3524,19 +3531,13 @@ fn objectSectionMapIndex( |
| 3524 | const parent_alignment = parent_ni.alignment(&coff.mf); | 3531 | const parent_alignment = parent_ni.alignment(&coff.mf); |
| 3525 | if (alignment.compare(.gt, parent_alignment)) { | 3532 | if (alignment.compare(.gt, parent_alignment)) { |
| 3526 | log.debug("realignParent({s}, {d}) {d}->{d}", .{ name.toSlice(coff), parent_ni, parent_alignment, alignment }); | 3533 | log.debug("realignParent({s}, {d}) {d}->{d}", .{ name.toSlice(coff), parent_ni, parent_alignment, alignment }); |
| 3527 | parent_ni.realign(&coff.mf, gpa, alignment, true) catch |err| switch (err) { | 3534 | try parent_ni.realign(&coff.mf, gpa, alignment, true); |
| 3528 | error.Unimplemented => unreachable, | | |
| 3529 | else => |e| return e, | | |
| 3530 | }; | | |
| 3531 | } | 3535 | } |
| 3532 | | 3536 | |
| 3533 | const old_alignment = sym.ni.alignment(&coff.mf); | 3537 | const old_alignment = sym.ni.alignment(&coff.mf); |
| 3534 | if (alignment.compare(.gt, old_alignment)) { | 3538 | if (alignment.compare(.gt, old_alignment)) { |
| 3535 | log.debug("realignObject({s}) {d}->{d}", .{ name.toSlice(coff), old_alignment, alignment }); | 3539 | log.debug("realignObject({s}) {d}->{d}", .{ name.toSlice(coff), old_alignment, alignment }); |
| 3536 | sym.ni.realign(&coff.mf, gpa, alignment, true) catch |err| switch (err) { | 3540 | try sym.ni.realign(&coff.mf, gpa, alignment, true); |
| 3537 | error.Unimplemented => unreachable, | | |
| 3538 | else => |e| return e, | | |
| 3539 | }; | | |
| 3540 | } | 3541 | } |
| 3541 | | 3542 | |
| 3542 | try coff.verifyParentSectionAttributes( | 3543 | try coff.verifyParentSectionAttributes( |
| ... | @@ -3561,7 +3562,6 @@ fn verifyParentSectionAttributes( | ... | @@ -3561,7 +3562,6 @@ fn verifyParentSectionAttributes( |
| 3561 | ) !void { | 3562 | ) !void { |
| 3562 | if (parent_attrs == child_attrs) return; | 3563 | if (parent_attrs == child_attrs) return; |
| 3563 | | 3564 | |
| 3564 | const fields = std.meta.fields(ObjectSectionAttributes); | | |
| 3565 | const BackingT = @typeInfo(ObjectSectionAttributes).@"struct".backing_integer.?; | 3565 | const BackingT = @typeInfo(ObjectSectionAttributes).@"struct".backing_integer.?; |
| 3566 | const num_notes = @popCount(@as(BackingT, @bitCast(parent_attrs)) ^ @as(BackingT, @bitCast(child_attrs))); | 3566 | const num_notes = @popCount(@as(BackingT, @bitCast(parent_attrs)) ^ @as(BackingT, @bitCast(child_attrs))); |
| 3567 | var err = try coff.base.comp.link_diags.addErrorWithNotes(num_notes); | 3567 | var err = try coff.base.comp.link_diags.addErrorWithNotes(num_notes); |
| ... | @@ -3571,30 +3571,67 @@ fn verifyParentSectionAttributes( | ... | @@ -3571,30 +3571,67 @@ fn verifyParentSectionAttributes( |
| 3571 | parent_name.toSlice(coff), | 3571 | parent_name.toSlice(coff), |
| 3572 | }); | 3572 | }); |
| 3573 | | 3573 | |
| 3574 | inline for (fields) |field| { | 3574 | inline for (comptime std.meta.fieldNames(ObjectSectionAttributes)) |field| { |
| 3575 | if (@field(child_attrs, field.name) != @field(parent_attrs, field.name)) { | 3575 | if (@field(child_attrs, field) != @field(parent_attrs, field)) { |
| 3576 | err.addNote("flags.{s} was {d} in {s}, but {d} in {s}", .{ | 3576 | err.addNote("flags.{s} was {d} in {s}, but {d} in {s}", .{ |
| 3577 | field.name, | 3577 | field, |
| 3578 | @intFromBool(@field(child_attrs, field.name)), | 3578 | @intFromBool(@field(child_attrs, field)), |
| 3579 | child_name.toSlice(coff), | 3579 | child_name.toSlice(coff), |
| 3580 | @intFromBool(@field(parent_attrs, field.name)), | 3580 | @intFromBool(@field(parent_attrs, field)), |
| 3581 | parent_name.toSlice(coff), | 3581 | parent_name.toSlice(coff), |
| 3582 | }); | 3582 | }); |
| 3583 | } | 3583 | } |
| 3584 | } | 3584 | } |
| 3585 | | 3585 | |
| 3586 | return error.LinkFailure; | 3586 | return error.AlreadyReported; |
| 3587 | } | 3587 | } |
| 3588 | | 3588 | |
| | 3589 | const RelocAddend = union(enum) { |
| | 3590 | known: i64, |
| | 3591 | /// Relocs tables in input objects don't include the addend. |
| | 3592 | /// The value needs to be recovered from the reloc location. |
| | 3593 | pending: void, |
| | 3594 | }; |
| | 3595 | |
| 3589 | pub fn addReloc( | 3596 | pub fn addReloc( |
| 3590 | coff: *Coff, | 3597 | coff: *Coff, |
| 3591 | loc_si: Symbol.Index, | 3598 | loc_si: Symbol.Index, |
| 3592 | offset: u64, | 3599 | offset: u64, |
| 3593 | target_si: Symbol.Index, | 3600 | target_si: Symbol.Index, |
| 3594 | addend: union(enum) { | 3601 | addend: RelocAddend, |
| 3595 | known: i64, | 3602 | @"type": Reloc.Type, |
| 3596 | pending: void, | 3603 | ) link.Error!void { |
| 3597 | }, | 3604 | const diags = &coff.base.comp.link_diags; |
| | 3605 | try coff.ensureUnusedRelocCapacity(loc_si, 1); |
| | 3606 | coff.addRelocAssumeCapacity(loc_si, offset, target_si, addend, @"type") catch |err| switch (err) { |
| | 3607 | error.MappedFileIo => return diags.fail( |
| | 3608 | "failed to write output file: {t}", |
| | 3609 | .{coff.mf.io_err.?}, |
| | 3610 | ), |
| | 3611 | else => |e| return e, |
| | 3612 | }; |
| | 3613 | } |
| | 3614 | |
| | 3615 | fn ensureUnusedRelocCapacity(coff: *Coff, loc_si: Symbol.Index, len: usize) !void { |
| | 3616 | const gpa = coff.base.comp.gpa; |
| | 3617 | try coff.relocs.ensureUnusedCapacity(gpa, len); |
| | 3618 | if (isImage(coff)) return; |
| | 3619 | switch (loc_si.get(coff).section_number) { |
| | 3620 | .UNDEFINED, .ABSOLUTE, .DEBUG => {}, |
| | 3621 | else => |loc_sn| { |
| | 3622 | const section = loc_sn.section(coff); |
| | 3623 | if (section.relocation_table_ni == .none) |
| | 3624 | try coff.nodes.ensureUnusedCapacity(gpa, 1); |
| | 3625 | }, |
| | 3626 | } |
| | 3627 | } |
| | 3628 | |
| | 3629 | fn addRelocAssumeCapacity( |
| | 3630 | coff: *Coff, |
| | 3631 | loc_si: Symbol.Index, |
| | 3632 | offset: u64, |
| | 3633 | target_si: Symbol.Index, |
| | 3634 | addend: RelocAddend, |
| 3598 | @"type": Reloc.Type, | 3635 | @"type": Reloc.Type, |
| 3599 | ) !void { | 3636 | ) !void { |
| 3600 | const gpa = coff.base.comp.gpa; | 3637 | const gpa = coff.base.comp.gpa; |
| ... | @@ -3612,8 +3649,6 @@ pub fn addReloc( | ... | @@ -3612,8 +3649,6 @@ pub fn addReloc( |
| 3612 | ri, | 3649 | ri, |
| 3613 | }); | 3650 | }); |
| 3614 | | 3651 | |
| 3615 | try coff.relocs.ensureUnusedCapacity(gpa, 1); | | |
| 3616 | | | |
| 3617 | const sri: Section.RelocationIndex = if (isImage(coff)) | 3652 | const sri: Section.RelocationIndex = if (isImage(coff)) |
| 3618 | .none | 3653 | .none |
| 3619 | else switch (loc_si.get(coff).section_number) { | 3654 | else switch (loc_si.get(coff).section_number) { |
| ... | @@ -3638,13 +3673,16 @@ pub fn addReloc( | ... | @@ -3638,13 +3673,16 @@ pub fn addReloc( |
| 3638 | const new_num_relocations = old_num_relocations + 1; | 3673 | const new_num_relocations = old_num_relocations + 1; |
| 3639 | const new_size = new_num_relocations * std.coff.Relocation.sizeOf(); | 3674 | const new_size = new_num_relocations * std.coff.Relocation.sizeOf(); |
| 3640 | if (section.relocation_table_ni == .none) { | 3675 | if (section.relocation_table_ni == .none) { |
| 3641 | try coff.nodes.ensureUnusedCapacity(gpa, 1); | 3676 | section.relocation_table_ni = try coff.mf.addLastChildNode( |
| 3642 | section.relocation_table_ni = try coff.mf.addLastChildNode(gpa, coff.sectionParent(), .{ | 3677 | gpa, |
| 3643 | .size = new_size, | 3678 | coff.sectionParent(), |
| 3644 | .alignment = .@"2", | 3679 | .{ |
| 3645 | .moved = true, | 3680 | .size = new_size, |
| 3646 | .resized = true, | 3681 | .alignment = .@"2", |
| 3647 | }); | 3682 | .moved = true, |
| | 3683 | .resized = true, |
| | 3684 | }, |
| | 3685 | ); |
| 3648 | coff.nodes.appendAssumeCapacity(.{ .relocation_table = loc_sn }); | 3686 | coff.nodes.appendAssumeCapacity(.{ .relocation_table = loc_sn }); |
| 3649 | } else { | 3687 | } else { |
| 3650 | try section.relocation_table_ni.resize(&coff.mf, gpa, new_size); | 3688 | try section.relocation_table_ni.resize(&coff.mf, gpa, new_size); |
| ... | @@ -3687,8 +3725,60 @@ pub fn addReloc( | ... | @@ -3687,8 +3725,60 @@ pub fn addReloc( |
| 3687 | target.target_relocs = ri; | 3725 | target.target_relocs = ri; |
| 3688 | } | 3726 | } |
| 3689 | | 3727 | |
| 3690 | pub fn loadInput(coff: *Coff, input: link.Input) (Io.File.Reader.SizeError || | 3728 | // pub fn loadInput(coff: *Coff, input: link.Input) link.Error!void { |
| 3691 | Io.File.Reader.Error || MappedFile.Error || error{ WriteFailed, EndOfStream, BadMagic, LinkFailure })!void { | 3729 | // const diags = &coff.base.comp.link_diags; |
| | 3730 | // return coff.loadInputInner(input) catch |err| switch (err) { |
| | 3731 | // else => |e| return e, |
| | 3732 | // error.MappedFileIo => return diags.fail( |
| | 3733 | // "failed to write output file: {t}", |
| | 3734 | // .{coff.mf.io_err.?}, |
| | 3735 | // ), |
| | 3736 | // }; |
| | 3737 | // } |
| | 3738 | |
| | 3739 | fn failLoadInput( |
| | 3740 | coff: *Coff, |
| | 3741 | err: LoadInputError, |
| | 3742 | fr: *Io.File.Reader, |
| | 3743 | path: std.Build.Cache.Path, |
| | 3744 | ) link.Error { |
| | 3745 | const diags = &coff.base.comp.link_diags; |
| | 3746 | switch (err) { |
| | 3747 | else => |e| return e, |
| | 3748 | error.MappedFileIo => return diags.fail( |
| | 3749 | "failed to write output file: {t}", |
| | 3750 | .{coff.mf.io_err.?}, |
| | 3751 | ), |
| | 3752 | error.EndOfStream => return diags.failParse( |
| | 3753 | path, |
| | 3754 | "unexpected eof", |
| | 3755 | .{}, |
| | 3756 | ), |
| | 3757 | error.AccessDenied, |
| | 3758 | error.Unexpected, |
| | 3759 | error.Unseekable, |
| | 3760 | => |e| return diags.fail( |
| | 3761 | "failed to read \"{f}\": {t}", |
| | 3762 | .{ path.fmtEscapeString(), e }, |
| | 3763 | ), |
| | 3764 | error.PermissionDenied, |
| | 3765 | error.SystemResources, |
| | 3766 | error.Streaming, |
| | 3767 | => |e| return diags.fail( |
| | 3768 | "failed to stat \"{f}\": {t}", |
| | 3769 | .{ path.fmtEscapeString(), e }, |
| | 3770 | ), |
| | 3771 | error.ReadFailed => switch (fr.err.?) { |
| | 3772 | error.Canceled => |e| return e, |
| | 3773 | else => |e| return diags.fail( |
| | 3774 | "failed to read \"{f}\": {t}", |
| | 3775 | .{ path.fmtEscapeString(), e }, |
| | 3776 | ), |
| | 3777 | }, |
| | 3778 | } |
| | 3779 | } |
| | 3780 | |
| | 3781 | pub fn loadInput(coff: *Coff, input: link.Input) link.Error!void { |
| 3692 | const comp = coff.base.comp; | 3782 | const comp = coff.base.comp; |
| 3693 | const io = comp.io; | 3783 | const io = comp.io; |
| 3694 | | 3784 | |
| ... | @@ -3703,32 +3793,24 @@ pub fn loadInput(coff: *Coff, input: link.Input) (Io.File.Reader.SizeError || | ... | @@ -3703,32 +3793,24 @@ pub fn loadInput(coff: *Coff, input: link.Input) (Io.File.Reader.SizeError || |
| 3703 | var fr = object.file.reader(io, &buf); | 3793 | var fr = object.file.reader(io, &buf); |
| 3704 | coff.loadObject(object.path, null, &fr, .{ | 3794 | coff.loadObject(object.path, null, &fr, .{ |
| 3705 | .offset = fr.logicalPos(), | 3795 | .offset = fr.logicalPos(), |
| 3706 | .size = try fr.getSize(), | 3796 | .size = fr.getSize() catch |err| |
| 3707 | }) catch |err| switch (err) { | 3797 | return coff.failLoadInput(err, &fr, object.path), |
| 3708 | error.ReadFailed => return fr.err.?, | 3798 | }) catch |err| return coff.failLoadInput(err, &fr, object.path); |
| 3709 | else => |e| return e, | | |
| 3710 | }; | | |
| 3711 | }, | 3799 | }, |
| 3712 | .archive => |archive| { | 3800 | .archive => |archive| { |
| 3713 | var fr = archive.file.reader(io, &buf); | 3801 | var fr = archive.file.reader(io, &buf); |
| 3714 | coff.loadArchive(archive.path, &fr) catch |err| switch (err) { | 3802 | coff.loadArchive(archive.path, &fr) catch |err| |
| 3715 | error.ReadFailed => return fr.err.?, | 3803 | return coff.failLoadInput(err, &fr, archive.path); |
| 3716 | else => |e| return e, | | |
| 3717 | }; | | |
| 3718 | }, | 3804 | }, |
| 3719 | .res => |res| { | 3805 | .res => |res| { |
| 3720 | var fr = res.file.reader(io, &buf); | 3806 | var fr = res.file.reader(io, &buf); |
| 3721 | coff.loadRes(res.path, &fr) catch |err| switch (err) { | 3807 | coff.loadRes(res.path, &fr) catch |err| |
| 3722 | error.ReadFailed => return fr.err.?, | 3808 | return coff.failLoadInput(err, &fr, res.path); |
| 3723 | else => |e| return e, | | |
| 3724 | }; | | |
| 3725 | }, | 3809 | }, |
| 3726 | .dso => |dso| { | 3810 | .dso => |dso| { |
| 3727 | var fr = dso.file.reader(io, &buf); | 3811 | var fr = dso.file.reader(io, &buf); |
| 3728 | coff.loadDll(dso.path, &fr) catch |err| switch (err) { | 3812 | coff.loadDll(dso.path, &fr) catch |err| |
| 3729 | error.ReadFailed => return fr.err.?, | 3813 | return coff.failLoadInput(err, &fr, dso.path); |
| 3730 | else => |e| return e, | | |
| 3731 | }; | | |
| 3732 | }, | 3814 | }, |
| 3733 | .dso_exact => unreachable, | 3815 | .dso_exact => unreachable, |
| 3734 | } | 3816 | } |
| ... | @@ -3771,7 +3853,7 @@ fn loadObject( | ... | @@ -3771,7 +3853,7 @@ fn loadObject( |
| 3771 | member_name: ?[]const u8, | 3853 | member_name: ?[]const u8, |
| 3772 | fr: *Io.File.Reader, | 3854 | fr: *Io.File.Reader, |
| 3773 | fl: MappedFile.Node.FileLocation, | 3855 | fl: MappedFile.Node.FileLocation, |
| 3774 | ) !void { | 3856 | ) LoadInputError!void { |
| 3775 | const comp = coff.base.comp; | 3857 | const comp = coff.base.comp; |
| 3776 | const gpa = comp.gpa; | 3858 | const gpa = comp.gpa; |
| 3777 | const diags = &comp.link_diags; | 3859 | const diags = &comp.link_diags; |
| ... | @@ -3955,14 +4037,18 @@ fn loadObject( | ... | @@ -3955,14 +4037,18 @@ fn loadObject( |
| 3955 | try member.initHeader(coff, path_str, header.time_date_stamp); | 4037 | try member.initHeader(coff, path_str, header.time_date_stamp); |
| 3956 | | 4038 | |
| 3957 | { | 4039 | { |
| 3958 | // TODO: This should be deferred to an idle task | 4040 | // TODO: This should be deferred to an idle task (but resize it here!) |
| 3959 | var nw: MappedFile.Node.Writer = undefined; | 4041 | var nw: MappedFile.Node.Writer = undefined; |
| 3960 | member.content_ni.writer(&coff.mf, gpa, &nw); | 4042 | member.content_ni.writer(&coff.mf, gpa, &nw); |
| 3961 | defer nw.deinit(); | 4043 | defer nw.deinit(); |
| 3962 | | 4044 | |
| 3963 | try fr.seekTo(fl.offset); | 4045 | try fr.seekTo(fl.offset); |
| 3964 | if (try nw.interface.sendFileAll(fr, .limited64(fl.size)) != fl.size) | 4046 | const written = nw.interface.sendFileAll(fr, .limited64(fl.size)) catch |err| switch (err) { |
| 3965 | return error.EndOfStream; | 4047 | error.WriteFailed => return nw.err.?, |
| | 4048 | else => |e| return e, |
| | 4049 | }; |
| | 4050 | |
| | 4051 | if (written != fl.size) return error.EndOfStream; |
| 3966 | } | 4052 | } |
| 3967 | | 4053 | |
| 3968 | break :mi mi; | 4054 | break :mi mi; |
| ... | @@ -4816,7 +4902,7 @@ fn failMultipleDefinitions( | ... | @@ -4816,7 +4902,7 @@ fn failMultipleDefinitions( |
| 4816 | size: struct { a: u64, b: u64 }, | 4902 | size: struct { a: u64, b: u64 }, |
| 4817 | crc: struct { a: u32, b: u32 }, | 4903 | crc: struct { a: u32, b: u32 }, |
| 4818 | }, | 4904 | }, |
| 4819 | ) error{ LinkFailure, OutOfMemory } { | 4905 | ) error{ AlreadyReported, OutOfMemory } { |
| 4820 | const num_notes: usize = 2 + @as(usize, @intFromBool(comdat_reason != .none)); | 4906 | const num_notes: usize = 2 + @as(usize, @intFromBool(comdat_reason != .none)); |
| 4821 | var err = try coff.base.comp.link_diags.addErrorWithNotes(num_notes); | 4907 | var err = try coff.base.comp.link_diags.addErrorWithNotes(num_notes); |
| 4822 | try err.addMsg("multiple definitions of '{s}'", .{name.toSlice(coff)}); | 4908 | try err.addMsg("multiple definitions of '{s}'", .{name.toSlice(coff)}); |
| ... | @@ -4849,7 +4935,7 @@ fn failMultipleDefinitions( | ... | @@ -4849,7 +4935,7 @@ fn failMultipleDefinitions( |
| 4849 | ), | 4935 | ), |
| 4850 | } | 4936 | } |
| 4851 | | 4937 | |
| 4852 | return error.LinkFailure; | 4938 | return error.AlreadyReported; |
| 4853 | } | 4939 | } |
| 4854 | | 4940 | |
| 4855 | const ArchiveMemberHeader = struct { | 4941 | const ArchiveMemberHeader = struct { |
| ... | @@ -4889,7 +4975,7 @@ fn parseArchiveMemberHeaderInner( | ... | @@ -4889,7 +4975,7 @@ fn parseArchiveMemberHeaderInner( |
| 4889 | }; | 4975 | }; |
| 4890 | } | 4976 | } |
| 4891 | | 4977 | |
| 4892 | fn loadArchive(coff: *Coff, path: std.Build.Cache.Path, fr: *Io.File.Reader) !void { | 4978 | fn loadArchive(coff: *Coff, path: std.Build.Cache.Path, fr: *Io.File.Reader) LoadInputError!void { |
| 4893 | const comp = coff.base.comp; | 4979 | const comp = coff.base.comp; |
| 4894 | const gpa = comp.gpa; | 4980 | const gpa = comp.gpa; |
| 4895 | const diags = &comp.link_diags; | 4981 | const diags = &comp.link_diags; |
| ... | @@ -5164,7 +5250,7 @@ fn loadArchive(coff: *Coff, path: std.Build.Cache.Path, fr: *Io.File.Reader) !vo | ... | @@ -5164,7 +5250,7 @@ fn loadArchive(coff: *Coff, path: std.Build.Cache.Path, fr: *Io.File.Reader) !vo |
| 5164 | } | 5250 | } |
| 5165 | } | 5251 | } |
| 5166 | | 5252 | |
| 5167 | fn loadRes(coff: *Coff, path: std.Build.Cache.Path, fr: *Io.File.Reader) !void { | 5253 | fn loadRes(coff: *Coff, path: std.Build.Cache.Path, fr: *Io.File.Reader) LoadInputError!void { |
| 5168 | const comp = coff.base.comp; | 5254 | const comp = coff.base.comp; |
| 5169 | const gpa = comp.gpa; | 5255 | const gpa = comp.gpa; |
| 5170 | const diags = &comp.link_diags; | 5256 | const diags = &comp.link_diags; |
| ... | @@ -5177,7 +5263,7 @@ fn loadRes(coff: *Coff, path: std.Build.Cache.Path, fr: *Io.File.Reader) !void { | ... | @@ -5177,7 +5263,7 @@ fn loadRes(coff: *Coff, path: std.Build.Cache.Path, fr: *Io.File.Reader) !void { |
| 5177 | _ = r; | 5263 | _ = r; |
| 5178 | } | 5264 | } |
| 5179 | | 5265 | |
| 5180 | fn loadDll(coff: *Coff, path: std.Build.Cache.Path, fr: *Io.File.Reader) !void { | 5266 | fn loadDll(coff: *Coff, path: std.Build.Cache.Path, fr: *Io.File.Reader) LoadInputError!void { |
| 5181 | const comp = coff.base.comp; | 5267 | const comp = coff.base.comp; |
| 5182 | const gpa = comp.gpa; | 5268 | const gpa = comp.gpa; |
| 5183 | const diags = &comp.link_diags; | 5269 | const diags = &comp.link_diags; |
| ... | @@ -5241,7 +5327,6 @@ pub fn prelink(coff: *Coff, prog_node: std.Progress.Node) link.Error!void { | ... | @@ -5241,7 +5327,6 @@ pub fn prelink(coff: *Coff, prog_node: std.Progress.Node) link.Error!void { |
| 5241 | errdefer archive.file.close(comp.io); | 5327 | errdefer archive.file.close(comp.io); |
| 5242 | | 5328 | |
| 5243 | coff.loadInput(.{ .archive = archive }) catch |err| switch (err) { | 5329 | coff.loadInput(.{ .archive = archive }) catch |err| switch (err) { |
| 5244 | error.LinkFailure => return, | | |
| 5245 | else => |e| return comp.link_diags.failParse( | 5330 | else => |e| return comp.link_diags.failParse( |
| 5246 | lib.ioi.path(coff), | 5331 | lib.ioi.path(coff), |
| 5247 | "error loading /DEFAULTLIB library '{s}': {t}", | 5332 | "error loading /DEFAULTLIB library '{s}': {t}", |
| ... | @@ -5265,10 +5350,14 @@ pub fn prelink(coff: *Coff, prog_node: std.Progress.Node) link.Error!void { | ... | @@ -5265,10 +5350,14 @@ pub fn prelink(coff: *Coff, prog_node: std.Progress.Node) link.Error!void { |
| 5265 | coff.exports_complete = true; | 5350 | coff.exports_complete = true; |
| 5266 | } | 5351 | } |
| 5267 | | 5352 | |
| 5268 | pub fn updateNav(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void { | 5353 | pub fn updateNav(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) link.Error!void { |
| 5269 | coff.updateNavInner(pt, nav_index) catch |err| switch (err) { | 5354 | coff.updateNavInner(pt, nav_index) catch |err| switch (err) { |
| | 5355 | error.MappedFileIo => return coff.base.cgFail( |
| | 5356 | nav_index, |
| | 5357 | "linker failed to update variable: {t}", |
| | 5358 | .{coff.mf.io_err.?}, |
| | 5359 | ), |
| 5270 | else => |e| return e, | 5360 | else => |e| return e, |
| 5271 | error.MappedFileIo => return coff.base.cgFail(nav_index, "linker failed to update variable: {t}", .{coff.mf.io_err.?}), | | |
| 5272 | }; | 5361 | }; |
| 5273 | } | 5362 | } |
| 5274 | fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void { | 5363 | fn updateNavInner(coff: *Coff, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index) !void { |
| ... | @@ -5351,7 +5440,7 @@ pub fn lowerUav( | ... | @@ -5351,7 +5440,7 @@ pub fn lowerUav( |
| 5351 | pt: Zcu.PerThread, | 5440 | pt: Zcu.PerThread, |
| 5352 | uav_val: InternPool.Index, | 5441 | uav_val: InternPool.Index, |
| 5353 | uav_align: InternPool.Alignment, | 5442 | uav_align: InternPool.Alignment, |
| 5354 | ) !link.File.SymbolId { | 5443 | ) link.Error!link.File.SymbolId { |
| 5355 | const zcu = pt.zcu; | 5444 | const zcu = pt.zcu; |
| 5356 | const gpa = zcu.gpa; | 5445 | const gpa = zcu.gpa; |
| 5357 | | 5446 | |
| ... | @@ -5380,7 +5469,7 @@ pub fn updateFunc( | ... | @@ -5380,7 +5469,7 @@ pub fn updateFunc( |
| 5380 | pt: Zcu.PerThread, | 5469 | pt: Zcu.PerThread, |
| 5381 | func_index: InternPool.Index, | 5470 | func_index: InternPool.Index, |
| 5382 | mir: *const codegen.AnyMir, | 5471 | mir: *const codegen.AnyMir, |
| 5383 | ) !void { | 5472 | ) link.Error!void { |
| 5384 | coff.updateFuncInner(pt, func_index, mir) catch |err| switch (err) { | 5473 | coff.updateFuncInner(pt, func_index, mir) catch |err| switch (err) { |
| 5385 | else => |e| return e, | 5474 | else => |e| return e, |
| 5386 | error.MappedFileIo => return coff.base.cgFail( | 5475 | error.MappedFileIo => return coff.base.cgFail( |
| ... | @@ -5692,7 +5781,7 @@ fn reportUndefs(coff: *Coff, tid: Zcu.PerThread.Id) !void { | ... | @@ -5692,7 +5781,7 @@ fn reportUndefs(coff: *Coff, tid: Zcu.PerThread.Id) !void { |
| 5692 | } | 5781 | } |
| 5693 | } | 5782 | } |
| 5694 | | 5783 | |
| 5695 | return error.LinkFailure; | 5784 | return error.AlreadyReported; |
| 5696 | } | 5785 | } |
| 5697 | | 5786 | |
| 5698 | pub fn flush( | 5787 | pub fn flush( |
| ... | @@ -5700,7 +5789,7 @@ pub fn flush( | ... | @@ -5700,7 +5789,7 @@ pub fn flush( |
| 5700 | arena: std.mem.Allocator, | 5789 | arena: std.mem.Allocator, |
| 5701 | tid: Zcu.PerThread.Id, | 5790 | tid: Zcu.PerThread.Id, |
| 5702 | prog_node: std.Progress.Node, | 5791 | prog_node: std.Progress.Node, |
| 5703 | ) !void { | 5792 | ) link.Error!void { |
| 5704 | _ = arena; | 5793 | _ = arena; |
| 5705 | _ = prog_node; | 5794 | _ = prog_node; |
| 5706 | const comp = coff.base.comp; | 5795 | const comp = coff.base.comp; |
| ... | @@ -5723,13 +5812,10 @@ pub fn flush( | ... | @@ -5723,13 +5812,10 @@ pub fn flush( |
| 5723 | comp.gpa, | 5812 | comp.gpa, |
| 5724 | number_of_symbols * std.coff.Symbol.sizeOf(), | 5813 | number_of_symbols * std.coff.Symbol.sizeOf(), |
| 5725 | true, | 5814 | true, |
| 5726 | ) catch |err| switch (err) { | 5815 | ) catch |err| return comp.link_diags.fail( |
| 5727 | error.OutOfMemory => return error.OutOfMemory, | 5816 | "linker failed to compact symbol table: {t}", |
| 5728 | else => |e| return comp.link_diags.fail( | 5817 | .{err}, |
| 5729 | "linker failed to compact symbol table: {t}", | 5818 | ); |
| 5730 | .{e}, | | |
| 5731 | ), | | |
| 5732 | }; | | |
| 5733 | } | 5819 | } |
| 5734 | while (try coff.idle(tid)) {} | 5820 | while (try coff.idle(tid)) {} |
| 5735 | | 5821 | |
| ... | @@ -7220,10 +7306,14 @@ pub fn updateExports( | ... | @@ -7220,10 +7306,14 @@ pub fn updateExports( |
| 7220 | pt: Zcu.PerThread, | 7306 | pt: Zcu.PerThread, |
| 7221 | exported: Zcu.Exported, | 7307 | exported: Zcu.Exported, |
| 7222 | export_indices: []const Zcu.Export.Index, | 7308 | export_indices: []const Zcu.Export.Index, |
| 7223 | ) !void { | 7309 | ) link.Error!void { |
| | 7310 | const diags = &coff.base.comp.link_diags; |
| 7224 | return coff.updateExportsInner(pt, exported, export_indices) catch |err| switch (err) { | 7311 | return coff.updateExportsInner(pt, exported, export_indices) catch |err| switch (err) { |
| 7225 | error.OutOfMemory => error.OutOfMemory, | 7312 | error.MappedFileIo => return diags.fail( |
| 7226 | else => |e| coff.base.comp.link_diags.fail("updateExports failed {t}", .{e}) catch error.AnalysisFail, | 7313 | "failed to write output file: {t}", |
| | 7314 | .{coff.mf.io_err.?}, |
| | 7315 | ), |
| | 7316 | else => |e| return e, |
| 7227 | }; | 7317 | }; |
| 7228 | } | 7318 | } |
| 7229 | fn updateExportsInner( | 7319 | fn updateExportsInner( |