1 use crate::common::Config;
2 use std::env;
3 use std::ffi::OsStr;
4 use std::path::PathBuf;
5 use std::process::Command;
6
7 use tracing::*;
8
9 #[cfg(test)]
10 mod tests;
11
12 pub const ASAN_SUPPORTED_TARGETS: &[&str] = &[
13 "aarch64-apple-darwin",
14 "aarch64-apple-ios",
15 "aarch64-apple-ios-sim",
16 "aarch64-unknown-fuchsia",
17 "aarch64-linux-android",
18 "aarch64-unknown-linux-gnu",
19 "arm-linux-androideabi",
20 "armv7-linux-androideabi",
21 "i686-linux-android",
22 "i686-unknown-linux-gnu",
23 "x86_64-apple-darwin",
24 "x86_64-apple-ios",
25 "x86_64-unknown-fuchsia",
26 "x86_64-linux-android",
27 "x86_64-unknown-freebsd",
28 "x86_64-unknown-linux-gnu",
29 "s390x-unknown-linux-gnu",
30 ];
31
32 // FIXME(rcvalle): More targets are likely supported.
33 pub const CFI_SUPPORTED_TARGETS: &[&str] = &[
34 "aarch64-apple-darwin",
35 "aarch64-unknown-fuchsia",
36 "aarch64-linux-android",
37 "aarch64-unknown-freebsd",
38 "aarch64-unknown-linux-gnu",
39 "x86_64-apple-darwin",
40 "x86_64-unknown-fuchsia",
41 "x86_64-pc-solaris",
42 "x86_64-unknown-freebsd",
43 "x86_64-unknown-illumos",
44 "x86_64-unknown-linux-gnu",
45 "x86_64-unknown-linux-musl",
46 "x86_64-unknown-netbsd",
47 ];
48
49 pub const KCFI_SUPPORTED_TARGETS: &[&str] = &["aarch64-linux-none", "x86_64-linux-none"];
50
51 pub const KASAN_SUPPORTED_TARGETS: &[&str] = &[
52 "aarch64-unknown-none",
53 "riscv64gc-unknown-none-elf",
54 "riscv64imac-unknown-none-elf",
55 "x86_64-unknown-none",
56 ];
57
58 pub const LSAN_SUPPORTED_TARGETS: &[&str] = &[
59 // FIXME: currently broken, see #88132
60 // "aarch64-apple-darwin",
61 "aarch64-unknown-linux-gnu",
62 "x86_64-apple-darwin",
63 "x86_64-unknown-linux-gnu",
64 "s390x-unknown-linux-gnu",
65 ];
66
67 pub const MSAN_SUPPORTED_TARGETS: &[&str] = &[
68 "aarch64-unknown-linux-gnu",
69 "x86_64-unknown-freebsd",
70 "x86_64-unknown-linux-gnu",
71 "s390x-unknown-linux-gnu",
72 ];
73
74 pub const TSAN_SUPPORTED_TARGETS: &[&str] = &[
75 "aarch64-apple-darwin",
76 "aarch64-apple-ios",
77 "aarch64-apple-ios-sim",
78 "aarch64-unknown-linux-gnu",
79 "x86_64-apple-darwin",
80 "x86_64-apple-ios",
81 "x86_64-unknown-freebsd",
82 "x86_64-unknown-linux-gnu",
83 "s390x-unknown-linux-gnu",
84 ];
85
86 pub const HWASAN_SUPPORTED_TARGETS: &[&str] =
87 &["aarch64-linux-android", "aarch64-unknown-linux-gnu"];
88
89 pub const MEMTAG_SUPPORTED_TARGETS: &[&str] =
90 &["aarch64-linux-android", "aarch64-unknown-linux-gnu"];
91
92 pub const SHADOWCALLSTACK_SUPPORTED_TARGETS: &[&str] = &["aarch64-linux-android"];
93
94 pub const XRAY_SUPPORTED_TARGETS: &[&str] = &[
95 "aarch64-linux-android",
96 "aarch64-unknown-linux-gnu",
97 "aarch64-unknown-linux-musl",
98 "x86_64-linux-android",
99 "x86_64-unknown-freebsd",
100 "x86_64-unknown-linux-gnu",
101 "x86_64-unknown-linux-musl",
102 "x86_64-unknown-netbsd",
103 "x86_64-unknown-none-linuxkernel",
104 "x86_64-unknown-openbsd",
105 ];
106
107 pub const SAFESTACK_SUPPORTED_TARGETS: &[&str] = &["x86_64-unknown-linux-gnu"];
108
make_new_path(path: &str) -> String109 pub fn make_new_path(path: &str) -> String {
110 assert!(cfg!(windows));
111 // Windows just uses PATH as the library search path, so we have to
112 // maintain the current value while adding our own
113 match env::var(lib_path_env_var()) {
114 Ok(curr) => format!("{}{}{}", path, path_div(), curr),
115 Err(..) => path.to_owned(),
116 }
117 }
118
lib_path_env_var() -> &'static str119 pub fn lib_path_env_var() -> &'static str {
120 "PATH"
121 }
path_div() -> &'static str122 fn path_div() -> &'static str {
123 ";"
124 }
125
logv(config: &Config, s: String)126 pub fn logv(config: &Config, s: String) {
127 debug!("{}", s);
128 if config.verbose {
129 println!("{}", s);
130 }
131 }
132
133 pub trait PathBufExt {
134 /// Append an extension to the path, even if it already has one.
with_extra_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf135 fn with_extra_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf;
136 }
137
138 impl PathBufExt for PathBuf {
with_extra_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf139 fn with_extra_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf {
140 if extension.as_ref().is_empty() {
141 self.clone()
142 } else {
143 let mut fname = self.file_name().unwrap().to_os_string();
144 if !extension.as_ref().to_str().unwrap().starts_with('.') {
145 fname.push(".");
146 }
147 fname.push(extension);
148 self.with_file_name(fname)
149 }
150 }
151 }
152
153 /// The name of the environment variable that holds dynamic library locations.
dylib_env_var() -> &'static str154 pub fn dylib_env_var() -> &'static str {
155 if cfg!(windows) {
156 "PATH"
157 } else if cfg!(target_os = "macos") {
158 "DYLD_LIBRARY_PATH"
159 } else if cfg!(target_os = "haiku") {
160 "LIBRARY_PATH"
161 } else if cfg!(target_os = "aix") {
162 "LIBPATH"
163 } else {
164 "LD_LIBRARY_PATH"
165 }
166 }
167
168 /// Adds a list of lookup paths to `cmd`'s dynamic library lookup path.
169 /// If the dylib_path_var is already set for this cmd, the old value will be overwritten!
add_dylib_path(cmd: &mut Command, paths: impl Iterator<Item = impl Into<PathBuf>>)170 pub fn add_dylib_path(cmd: &mut Command, paths: impl Iterator<Item = impl Into<PathBuf>>) {
171 let path_env = env::var_os(dylib_env_var());
172 let old_paths = path_env.as_ref().map(env::split_paths);
173 let new_paths = paths.map(Into::into).chain(old_paths.into_iter().flatten());
174 cmd.env(dylib_env_var(), env::join_paths(new_paths).unwrap());
175 }
176