Skip to content

Commit

Permalink
Merge pull request #169 from rust-secure-code/riscv-refactor
Browse files Browse the repository at this point in the history
More robust OS detection for riscv feature detection
  • Loading branch information
Shnatsel authored Nov 9, 2024
2 parents 4ccbc72 + c5fe62a commit dc78465
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 10 deletions.
29 changes: 20 additions & 9 deletions cargo-auditable/src/object_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ fn create_object_file(
Architecture::Riscv32 | Architecture::Riscv64 => {
// Source: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/079772828bd10933d34121117a222b4cc0ee2200/riscv-elf.adoc
let mut e_flags: u32 = 0x0;
let features = riscv_features(target_triple);
let features = riscv_features(target_triple, info);
// Check if compressed is enabled
if features.contains('c') {
e_flags |= elf::EF_RISCV_RVC;
Expand Down Expand Up @@ -187,7 +187,10 @@ fn create_object_file(
// This function was not present in the original rustc code, which simply used
// `sess.target.options.features`
// We do not have access to compiler internals, so we have to reimplement this function.
fn riscv_features(target_triple: &str) -> String {
// And `rustc --print=cfg` doesn't expose some of the features we care about,
// specifically the 'd' and 'f' features.
// Hence this function, which is not as robust as I would like.
fn riscv_features(target_triple: &str, info: &RustcTargetInfo) -> String {
let arch = target_triple.split('-').next().unwrap();
assert_eq!(&arch[..5], "riscv");
let mut extensions = arch[7..].to_owned();
Expand All @@ -197,8 +200,9 @@ fn riscv_features(target_triple: &str) -> String {
// Most but not all riscv targets declare target features.
// A notable exception is `riscv64-linux-android`.
// We assume that all Linux-capable targets are -gc.
if target_triple.contains("linux") {
extensions.push_str("imadfc");
match info["target_os"].as_str() {
"linux" | "android" => extensions.push_str("imadfc"),
_ => (),
}
extensions
}
Expand All @@ -215,33 +219,40 @@ fn loongarch_features(target_triple: &str) -> String {

#[cfg(test)]
mod tests {
use std::collections::HashMap;

use super::*;
use crate::target_info::parse_rustc_target_info;

#[test]
fn test_riscv_abi_detection() {
// real-world target with double floats
let features = riscv_features("riscv64gc-unknown-linux-gnu");
let info = HashMap::from([("target_os".to_owned(), "linux".to_owned())]);
let features = riscv_features("riscv64gc-unknown-linux-gnu", &info);
assert!(features.contains('c'));
assert!(features.contains('d'));
assert!(features.contains('f'));
// real-world target without floats
let features = riscv_features("riscv32imac-unknown-none-elf");
let info = HashMap::from([("target_os".to_owned(), "none".to_owned())]);
let features = riscv_features("riscv32imac-unknown-none-elf", &info);
assert!(features.contains('c'));
assert!(!features.contains('d'));
assert!(!features.contains('f'));
// real-world target without floats or compression
let features = riscv_features("riscv32i-unknown-none-elf");
let info = HashMap::from([("target_os".to_owned(), "none".to_owned())]);
let features = riscv_features("riscv32i-unknown-none-elf", &info);
assert!(!features.contains('c'));
assert!(!features.contains('d'));
assert!(!features.contains('f'));
// made-up target without compression and with single floats
let features = riscv_features("riscv32if-unknown-none-elf");
let info = HashMap::from([("target_os".to_owned(), "none".to_owned())]);
let features = riscv_features("riscv32if-unknown-none-elf", &info);
assert!(!features.contains('c'));
assert!(!features.contains('d'));
assert!(features.contains('f'));
// real-world Android riscv target
let features = riscv_features("riscv64-linux-android");
let info = HashMap::from([("target_os".to_owned(), "android".to_owned())]);
let features = riscv_features("riscv64-linux-android", &info);
assert!(features.contains('c'));
assert!(features.contains('d'));
assert!(features.contains('f'));
Expand Down
2 changes: 1 addition & 1 deletion rust-audit-info/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit dc78465

Please sign in to comment.