1- //! Make sure that cross-language LTO works on riscv targets,
2- //! which requires extra `target-abi` metadata to be emitted.
1+ //! Make sure that cross-language LTO works on riscv targets, which requires extra `target-abi`
2+ //! metadata to be emitted.
33//@ needs-force-clang-based-tests
4- //@ needs-llvm-components riscv
4+ //@ needs-llvm-components: riscv
55
6- //@ needs-force-clang-based-tests
7- // FIXME(#126180): This test can only run on `x86_64-gnu-debug`, because that CI job sets
8- // RUSTBUILD_FORCE_CLANG_BASED_TESTS and only runs tests which contain "clang" in their
9- // name.
10- // However, this test does not run at all as its name does not contain "clang".
11-
12- use std:: path:: PathBuf ;
13- use std:: process:: { Command , Output } ;
14- use std:: { env, str} ;
6+ // ignore-tidy-linelength
157
16- use run_make_support:: { bin_name, clang, llvm_readobj, rustc} ;
8+ use object:: elf;
9+ use object:: read:: elf as readelf;
10+ use run_make_support:: { bin_name, clang, object, rfs, rustc} ;
1711
18- fn check_target ( target : & str , clang_target : & str , carch : & str , is_double_float : bool ) {
12+ fn check_target < H : readelf:: FileHeader < Endian = object:: Endianness > > (
13+ target : & str ,
14+ clang_target : & str ,
15+ carch : & str ,
16+ is_double_float : bool ,
17+ ) {
1918 eprintln ! ( "Checking target {target}" ) ;
2019 // Rust part
2120 rustc ( )
@@ -39,16 +38,55 @@ fn check_target(target: &str, clang_target: &str, carch: &str, is_double_float:
3938
4039 // Check that the built binary has correct float abi
4140 let executable = bin_name ( "riscv-xlto" ) ;
42- let output = llvm_readobj ( ) . input ( & executable) . file_header ( ) . run ( ) ;
43- let stdout = String :: from_utf8_lossy ( & output. stdout ) ;
44- eprintln ! ( "obj:\n {}" , stdout) ;
45-
46- assert ! ( !( is_double_float ^ stdout. contains( "EF_RISCV_FLOAT_ABI_DOUBLE" ) ) ) ;
41+ let data = rfs:: read ( & executable) ;
42+ let header = <H >:: parse ( & * data) . unwrap ( ) ;
43+ let endian = match header. e_ident ( ) . data {
44+ elf:: ELFDATA2LSB => object:: Endianness :: Little ,
45+ elf:: ELFDATA2MSB => object:: Endianness :: Big ,
46+ x => unreachable ! ( "invalid e_ident data: {:#010b}" , x) ,
47+ } ;
48+ // Check `(e_flags & EF_RISCV_FLOAT_ABI) == EF_RISCV_FLOAT_ABI_DOUBLE`.
49+ //
50+ // See
51+ // <https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-elf.adoc#elf-object-files>.
52+ if is_double_float {
53+ assert_eq ! (
54+ header. e_flags( endian) & elf:: EF_RISCV_FLOAT_ABI ,
55+ elf:: EF_RISCV_FLOAT_ABI_DOUBLE ,
56+ "expected {target} to use double ABI, but it did not"
57+ ) ;
58+ } else {
59+ assert_ne ! (
60+ header. e_flags( endian) & elf:: EF_RISCV_FLOAT_ABI ,
61+ elf:: EF_RISCV_FLOAT_ABI_DOUBLE ,
62+ "did not expected {target} to use double ABI"
63+ ) ;
64+ }
4765}
4866
4967fn main ( ) {
50- check_target ( "riscv64gc-unknown-linux-gnu" , "riscv64-linux-gnu" , "rv64gc" , true ) ;
51- check_target ( "riscv64imac-unknown-none-elf" , "riscv64-unknown-elf" , "rv64imac" , false ) ;
52- check_target ( "riscv32imac-unknown-none-elf" , "riscv32-unknown-elf" , "rv32imac" , false ) ;
53- check_target ( "riscv32gc-unknown-linux-gnu" , "riscv32-linux-gnu" , "rv32gc" , true ) ;
68+ check_target :: < elf:: FileHeader64 < object:: Endianness > > (
69+ "riscv64gc-unknown-linux-gnu" ,
70+ "riscv64-linux-gnu" ,
71+ "rv64gc" ,
72+ true ,
73+ ) ;
74+ check_target :: < elf:: FileHeader64 < object:: Endianness > > (
75+ "riscv64imac-unknown-none-elf" ,
76+ "riscv64-unknown-elf" ,
77+ "rv64imac" ,
78+ false ,
79+ ) ;
80+ check_target :: < elf:: FileHeader32 < object:: Endianness > > (
81+ "riscv32imac-unknown-none-elf" ,
82+ "riscv32-unknown-elf" ,
83+ "rv32imac" ,
84+ false ,
85+ ) ;
86+ check_target :: < elf:: FileHeader32 < object:: Endianness > > (
87+ "riscv32gc-unknown-linux-gnu" ,
88+ "riscv32-linux-gnu" ,
89+ "rv32gc" ,
90+ true ,
91+ ) ;
5492}
0 commit comments