Skip to content

Commit 16b45a0

Browse files
committed
Add bare linker detection function
1 parent bfcaa58 commit 16b45a0

1 file changed

Lines changed: 37 additions & 11 deletions

File tree

cargo-auditable/src/rustc_arguments.rs

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,29 @@ impl RustcArgs {
3636
}
3737
result
3838
}
39+
40+
/// Normally `rustc` uses a C compiler such as `cc` or `clang` as linker,
41+
/// and arguments to the actual linker need to be passed prefixed with `-Wl,`.
42+
/// But it is possible to configure Cargo and rustc to call a linker directly,
43+
/// and the breakage it causes is subtle enough that people just roll with it
44+
/// and complain when cargo-auditable doesn't support this configuration:
45+
/// <https://github.com/rust-secure-code/cargo-auditable/issues/202>
46+
///
47+
/// This function can tell you if a bare linker is in use
48+
/// and whether you need to prepend `-Wl,` or not.
49+
///
50+
/// Such setups are exceptionally rare and frankly it's a misconfiguration
51+
/// that will break more than just `cargo auditable`, but I am feeling generous.
52+
pub fn bare_linker(&self) -> bool {
53+
let linker_flag = self.codegen.iter().find(|s| s.starts_with("linker="));
54+
if let Some(linker_flag) = linker_flag {
55+
let linker = linker_flag.strip_prefix("linker=").unwrap();
56+
if linker.ends_with("ld") {
57+
return true;
58+
}
59+
}
60+
false
61+
}
3962
}
4063

4164
impl RustcArgs {
@@ -149,11 +172,7 @@ mod tests {
149172

150173
#[test]
151174
fn multiple_emit_values() {
152-
let raw_rustc_args = vec![
153-
"--emit=dep-info,link",
154-
"--emit",
155-
"llvm-bc",
156-
];
175+
let raw_rustc_args = vec!["--emit=dep-info,link", "--emit", "llvm-bc"];
157176
let raw_rustc_args: Vec<OsString> = raw_rustc_args.into_iter().map(|s| s.into()).collect();
158177
let mut args = RustcArgs::from_vec(raw_rustc_args).unwrap();
159178

@@ -166,13 +185,18 @@ mod tests {
166185
assert_eq!(args.emit, expected)
167186
}
168187

188+
#[test]
189+
fn detect_bare_linker() {
190+
let raw_rustc_args = vec!["-C", "linker=rust-lld"];
191+
let raw_rustc_args: Vec<OsString> = raw_rustc_args.into_iter().map(|s| s.into()).collect();
192+
let mut args = RustcArgs::from_vec(raw_rustc_args).unwrap();
193+
194+
assert!(args.bare_linker());
195+
}
196+
169197
#[test]
170198
fn multiple_codegen_options() {
171-
let raw_rustc_args = vec![
172-
"-Clinker=clang",
173-
"-C",
174-
"link-arg=-fuse-ld=/usr/bin/mold",
175-
];
199+
let raw_rustc_args = vec!["-Clinker=clang", "-C", "link-arg=-fuse-ld=/usr/bin/mold"];
176200
let raw_rustc_args: Vec<OsString> = raw_rustc_args.into_iter().map(|s| s.into()).collect();
177201
let mut args = RustcArgs::from_vec(raw_rustc_args).unwrap();
178202

@@ -182,6 +206,8 @@ mod tests {
182206
args.codegen.sort();
183207
expected.sort();
184208

185-
assert_eq!(args.codegen, expected)
209+
assert_eq!(args.codegen, expected);
210+
211+
assert!(!args.bare_linker());
186212
}
187213
}

0 commit comments

Comments
 (0)