diff options
| author | David Rubin <daviru007@icloud.com> | 2024-10-20 01:44:25 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2024-11-22 19:34:47 -0500 |
| commit | 66a7c09defec1fe4f4f1751e36acc412e3ca8ea9 (patch) | |
| tree | 6ceb71191d103f008418111f749aedb55faf8e59 /src/link/Elf/Object.zig | |
| parent | b2c62bcbf64a3ffa2af6a8e441f1c12e10c598ec (diff) | |
| download | zig-66a7c09defec1fe4f4f1751e36acc412e3ca8ea9.tar.gz zig-66a7c09defec1fe4f4f1751e36acc412e3ca8ea9.zip | |
link: use target to determine risc-v eflag validity
Diffstat (limited to 'src/link/Elf/Object.zig')
| -rw-r--r-- | src/link/Elf/Object.zig | 103 |
1 files changed, 72 insertions, 31 deletions
diff --git a/src/link/Elf/Object.zig b/src/link/Elf/Object.zig index 688e51f3f1..65a62ff1a6 100644 --- a/src/link/Elf/Object.zig +++ b/src/link/Elf/Object.zig @@ -99,7 +99,6 @@ pub fn parseCommon( path: Path, handle: fs.File, target: std.Target, - first_eflags: *?elf.Word, ) !void { const offset = if (self.archive) |ar| ar.offset else 0; const file_size = (try handle.stat()).size; @@ -114,7 +113,7 @@ pub fn parseCommon( @tagName(self.header.?.e_machine), }); } - try validateEFlags(diags, path, target, self.header.?.e_flags, first_eflags); + try validateEFlags(diags, path, target, self.header.?.e_flags); if (self.header.?.e_shnum == 0) return; @@ -180,39 +179,81 @@ pub fn parseCommon( } } -fn validateEFlags( +pub fn validateEFlags( diags: *Diags, path: Path, target: std.Target, e_flags: elf.Word, - first_eflags: *?elf.Word, -) error{LinkFailure}!void { - if (first_eflags.*) |*self_eflags| { - switch (target.cpu.arch) { - .riscv64 => { - if (e_flags != self_eflags.*) { - const riscv_eflags: riscv.RiscvEflags = @bitCast(e_flags); - const self_riscv_eflags: *riscv.RiscvEflags = @ptrCast(self_eflags); - - self_riscv_eflags.rvc = self_riscv_eflags.rvc or riscv_eflags.rvc; - self_riscv_eflags.tso = self_riscv_eflags.tso or riscv_eflags.tso; - - var any_errors: bool = false; - if (self_riscv_eflags.fabi != riscv_eflags.fabi) { - any_errors = true; - diags.addParseError(path, "cannot link object files with different float-point ABIs", .{}); - } - if (self_riscv_eflags.rve != riscv_eflags.rve) { - any_errors = true; - diags.addParseError(path, "cannot link object files with different RVEs", .{}); - } - if (any_errors) return error.LinkFailure; - } - }, - else => {}, - } - } else { - first_eflags.* = e_flags; +) !void { + switch (target.cpu.arch) { + .riscv64 => { + const features = target.cpu.features; + const flags: riscv.Eflags = @bitCast(e_flags); + var any_errors: bool = false; + + // For an input object to target an ABI that the target CPU doesn't have enabled + // is invalid, and will throw an error. + + // Invalid when + // 1. The input uses C and we do not. + if (flags.rvc and !std.Target.riscv.featureSetHas(features, .c)) { + any_errors = true; + diags.addParseError( + path, + "cannot link object file targeting the C feature without having the C feature enabled", + .{}, + ); + } + + // Invalid when + // 1. We use E and the input does not. + // 2. The input uses E and we do not. + if (std.Target.riscv.featureSetHas(features, .e) != flags.rve) { + any_errors = true; + diags.addParseError( + path, + "{s}", + .{ + if (flags.rve) + "cannot link object file targeting the E feature without having the E feature enabled" + else + "cannot link object file not targeting the E feature while having the E feature enabled", + }, + ); + } + + // Invalid when + // 1. We use total store order and the input does not. + // 2. The input uses total store order and we do not. + if (flags.tso != std.Target.riscv.featureSetHas(features, .ztso)) { + any_errors = true; + diags.addParseError( + path, + "cannot link object file targeting the TSO memory model without having the ztso feature enabled", + .{}, + ); + } + + const fabi: riscv.Eflags.FloatAbi = + if (std.Target.riscv.featureSetHas(features, .d)) + .double + else if (std.Target.riscv.featureSetHas(features, .f)) + .single + else + .soft; + + if (flags.fabi != fabi) { + any_errors = true; + diags.addParseError( + path, + "cannot link object file targeting a different floating-point ABI. targeting {s}, found {s}", + .{ @tagName(fabi), @tagName(flags.fabi) }, + ); + } + + if (any_errors) return error.LinkFailure; + }, + else => {}, } } |
