LLVM passes for Windows (#710)
* libafl_cc fixes for windows * libafl_cc checks for llvm-config (again) * libafl_cc clang-format * libafl_cc fixes for macos * maintain libafl_cc pass manager selection logic * libafl_cc rustfmt
This commit is contained in:
parent
2504b6dae3
commit
c1aafe3e98
@ -4,7 +4,6 @@ use std::{env, fs::File, io::Write, path::Path, process::Command, str};
|
|||||||
|
|
||||||
#[cfg(target_vendor = "apple")]
|
#[cfg(target_vendor = "apple")]
|
||||||
use glob::glob;
|
use glob::glob;
|
||||||
#[cfg(not(target_vendor = "apple"))]
|
|
||||||
use which::which;
|
use which::which;
|
||||||
|
|
||||||
/// The max version of `LLVM` we're looking for
|
/// The max version of `LLVM` we're looking for
|
||||||
@ -18,7 +17,7 @@ const LLVM_VERSION_MIN: u32 = 6;
|
|||||||
/// Get the extension for a shared object
|
/// Get the extension for a shared object
|
||||||
fn dll_extension<'a>() -> &'a str {
|
fn dll_extension<'a>() -> &'a str {
|
||||||
match env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() {
|
match env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() {
|
||||||
"windwos" => "dll",
|
"windows" => "dll",
|
||||||
"macos" | "ios" => "dylib",
|
"macos" | "ios" => "dylib",
|
||||||
_ => "so",
|
_ => "so",
|
||||||
}
|
}
|
||||||
@ -50,28 +49,44 @@ fn find_llvm_config_brew() -> Result<PathBuf, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_llvm_config() -> String {
|
fn find_llvm_config() -> Result<String, String> {
|
||||||
env::var("LLVM_CONFIG").unwrap_or_else(|_| {
|
if let Ok(var) = env::var("LLVM_CONFIG") {
|
||||||
// for Ghithub Actions, we check if we find llvm-config in brew.
|
return Ok(var);
|
||||||
#[cfg(target_vendor = "apple")]
|
}
|
||||||
match find_llvm_config_brew() {
|
|
||||||
Ok(llvm_dir) => llvm_dir.to_str().unwrap().to_string(),
|
// for Github Actions, we check if we find llvm-config in brew.
|
||||||
Err(err) => {
|
#[cfg(target_vendor = "apple")]
|
||||||
println!("cargo:warning={}", err);
|
match find_llvm_config_brew() {
|
||||||
// falling back to system llvm-config
|
Ok(llvm_dir) => return Ok(llvm_dir.to_str().unwrap().to_string()),
|
||||||
"llvm-config".to_string()
|
Err(err) => {
|
||||||
}
|
println!("cargo:warning={}", err);
|
||||||
}
|
}
|
||||||
#[cfg(not(target_vendor = "apple"))]
|
};
|
||||||
for version in (LLVM_VERSION_MIN..=LLVM_VERSION_MAX).rev() {
|
|
||||||
let llvm_config_name = format!("llvm-config-{}", version);
|
#[cfg(not(target_vendor = "apple"))]
|
||||||
if which(&llvm_config_name).is_ok() {
|
for version in (LLVM_VERSION_MIN..=LLVM_VERSION_MAX).rev() {
|
||||||
return llvm_config_name;
|
let llvm_config_name: String = format!("llvm-config-{}", version);
|
||||||
}
|
if which(&llvm_config_name).is_ok() {
|
||||||
|
return Ok(llvm_config_name);
|
||||||
}
|
}
|
||||||
#[cfg(not(target_vendor = "apple"))]
|
}
|
||||||
"llvm-config".to_string()
|
|
||||||
})
|
if which("llvm-config").is_ok() {
|
||||||
|
return Ok("llvm-config".to_owned());
|
||||||
|
}
|
||||||
|
|
||||||
|
Err("could not find llvm-config".to_owned())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exec_llvm_config(args: &[&str]) -> String {
|
||||||
|
let llvm_config = find_llvm_config().expect("Unexpected error");
|
||||||
|
match Command::new(&llvm_config).args(args).output() {
|
||||||
|
Ok(output) => String::from_utf8(output.stdout)
|
||||||
|
.expect("Unexpected llvm-config output")
|
||||||
|
.trim()
|
||||||
|
.to_string(),
|
||||||
|
Err(e) => panic!("Could not execute llvm-config: {}", e),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use `xcrun` to get the path to the Xcode SDK tools library path, for linking
|
/// Use `xcrun` to get the path to the Xcode SDK tools library path, for linking
|
||||||
@ -86,165 +101,83 @@ fn find_macos_sdk_libs() -> String {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn find_llvm_version() -> Option<i32> {
|
||||||
|
let output = exec_llvm_config(&["--version"]);
|
||||||
|
if let Some(major) = output.split('.').collect::<Vec<&str>>().first() {
|
||||||
|
if let Ok(res) = major.parse::<i32>() {
|
||||||
|
return Some(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_pass(
|
||||||
|
bindir_path: &Path,
|
||||||
|
out_dir: &Path,
|
||||||
|
cxxflags: &Vec<String>,
|
||||||
|
ldflags: &Vec<&str>,
|
||||||
|
src_dir: &Path,
|
||||||
|
src_file: &str,
|
||||||
|
) {
|
||||||
|
let dot_offset = src_file.rfind('.').unwrap();
|
||||||
|
let src_stub = &src_file[..dot_offset];
|
||||||
|
|
||||||
|
println!("cargo:rerun-if-changed=src/{}", src_file);
|
||||||
|
if cfg!(unix) {
|
||||||
|
assert!(Command::new(bindir_path.join("clang++"))
|
||||||
|
.arg("-v")
|
||||||
|
.args(cxxflags)
|
||||||
|
.arg(src_dir.join(src_file))
|
||||||
|
.args(ldflags)
|
||||||
|
.args(&["-o"])
|
||||||
|
.arg(out_dir.join(format!("{}.{}", src_stub, dll_extension())))
|
||||||
|
.status()
|
||||||
|
.unwrap_or_else(|_| panic!("Failed to compile {}", src_file))
|
||||||
|
.success());
|
||||||
|
} else if cfg!(windows) {
|
||||||
|
println!("{:?}", cxxflags);
|
||||||
|
assert!(Command::new(bindir_path.join("clang-cl"))
|
||||||
|
.arg("-v")
|
||||||
|
.args(cxxflags)
|
||||||
|
.arg(src_dir.join(src_file))
|
||||||
|
.arg("/link")
|
||||||
|
.args(ldflags)
|
||||||
|
.arg(format!(
|
||||||
|
"/OUT:{}",
|
||||||
|
out_dir
|
||||||
|
.join(format!("{}.{}", src_stub, dll_extension()))
|
||||||
|
.display()
|
||||||
|
))
|
||||||
|
.status()
|
||||||
|
.unwrap_or_else(|_| panic!("Failed to compile {}", src_file))
|
||||||
|
.success());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
fn main() {
|
fn main() {
|
||||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||||
let out_dir = Path::new(&out_dir);
|
let out_dir = Path::new(&out_dir);
|
||||||
let src_dir = Path::new("src");
|
let src_dir = Path::new("src");
|
||||||
|
|
||||||
println!("cargo:rerun-if-env-changed=LLVM_CONFIG");
|
|
||||||
println!("cargo:rerun-if-env-changed=LIBAFL_EDGES_MAP_SIZE");
|
|
||||||
println!("cargo:rerun-if-env-changed=LIBAFL_ACCOUNTING_MAP_SIZE");
|
|
||||||
|
|
||||||
let mut custom_flags = vec![];
|
|
||||||
|
|
||||||
let dest_path = Path::new(&out_dir).join("clang_constants.rs");
|
let dest_path = Path::new(&out_dir).join("clang_constants.rs");
|
||||||
let mut clang_constants_file = File::create(&dest_path).expect("Could not create file");
|
let mut clang_constants_file = File::create(&dest_path).expect("Could not create file");
|
||||||
|
|
||||||
let edges_map_size: usize = option_env!("LIBAFL_EDGES_MAP_SIZE")
|
println!("cargo:rerun-if-env-changed=LLVM_CONFIG");
|
||||||
.map_or(Ok(65536), str::parse)
|
println!("cargo:rerun-if-env-changed=LIBAFL_EDGES_MAP_SIZE");
|
||||||
.expect("Could not parse LIBAFL_EDGES_MAP_SIZE");
|
println!("cargo:rerun-if-env-changed=LIBAFL_ACCOUNTING_MAP_SIZE");
|
||||||
custom_flags.push(format!("-DLIBAFL_EDGES_MAP_SIZE={}", edges_map_size));
|
println!("cargo:rerun-if-changed=src/common-llvm.h");
|
||||||
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
|
|
||||||
let acc_map_size: usize = option_env!("LIBAFL_ACCOUNTING_MAP_SIZE")
|
// test if llvm-config is available and we can compile the passes
|
||||||
.map_or(Ok(65536), str::parse)
|
if find_llvm_config().is_err() {
|
||||||
.expect("Could not parse LIBAFL_ACCOUNTING_MAP_SIZE");
|
println!(
|
||||||
custom_flags.push(format!("-DLIBAFL_ACCOUNTING_MAP_SIZE={}", acc_map_size));
|
"cargo:warning=Failed to find llvm-config, we will not build LLVM passes. If you need them, set the LLVM_CONFIG environment variable to a recent llvm-config."
|
||||||
|
|
||||||
let llvm_config = find_llvm_config();
|
|
||||||
|
|
||||||
// Get LLVM version.
|
|
||||||
let llvm_version = match llvm_config.split('-').collect::<Vec<&str>>().get(2) {
|
|
||||||
Some(ver) => ver.parse::<usize>().ok(),
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(ver) = llvm_version {
|
|
||||||
if ver >= 14 {
|
|
||||||
custom_flags.push("-DUSE_NEW_PM".to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Ok(output) = Command::new(&llvm_config).args(&["--bindir"]).output() {
|
|
||||||
let llvm_bindir = Path::new(
|
|
||||||
str::from_utf8(&output.stdout)
|
|
||||||
.expect("Invalid llvm-config output")
|
|
||||||
.trim(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
write!(
|
write!(
|
||||||
clang_constants_file,
|
clang_constants_file,
|
||||||
"// These constants are autogenerated by build.rs
|
"// These constants are autogenerated by build.rs
|
||||||
|
|
||||||
/// The path to the `clang` executable
|
|
||||||
pub const CLANG_PATH: &str = {:?};
|
|
||||||
/// The path to the `clang++` executable
|
|
||||||
pub const CLANGXX_PATH: &str = {:?};
|
|
||||||
|
|
||||||
/// The size of the edges map
|
|
||||||
pub const EDGES_MAP_SIZE: usize = {};
|
|
||||||
|
|
||||||
/// The size of the accounting maps
|
|
||||||
pub const ACCOUNTING_MAP_SIZE: usize = {};
|
|
||||||
|
|
||||||
/// The llvm version used to build llvm passes
|
|
||||||
pub const LIBAFL_CC_LLVM_VERSION: Option<usize> = {:?};
|
|
||||||
",
|
|
||||||
llvm_bindir.join("clang"),
|
|
||||||
llvm_bindir.join("clang++"),
|
|
||||||
edges_map_size,
|
|
||||||
acc_map_size,
|
|
||||||
llvm_version,
|
|
||||||
)
|
|
||||||
.expect("Could not write file");
|
|
||||||
|
|
||||||
let output = Command::new(&llvm_config)
|
|
||||||
.args(&["--cxxflags"])
|
|
||||||
.output()
|
|
||||||
.expect("Failed to execute llvm-config");
|
|
||||||
let cxxflags = str::from_utf8(&output.stdout).expect("Invalid llvm-config output");
|
|
||||||
|
|
||||||
let mut cmd = Command::new(&llvm_config);
|
|
||||||
|
|
||||||
#[cfg(target_vendor = "apple")]
|
|
||||||
{
|
|
||||||
cmd.args(&["--libs"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
let output = cmd
|
|
||||||
.args(&["--ldflags"])
|
|
||||||
.output()
|
|
||||||
.expect("Failed to execute llvm-config");
|
|
||||||
let ldflags = str::from_utf8(&output.stdout).expect("Invalid llvm-config output");
|
|
||||||
|
|
||||||
let cxxflags: Vec<&str> = cxxflags.split_whitespace().collect();
|
|
||||||
let mut ldflags: Vec<&str> = ldflags.split_whitespace().collect();
|
|
||||||
|
|
||||||
let sdk_path;
|
|
||||||
if env::var("CARGO_CFG_TARGET_VENDOR").unwrap().as_str() == "apple" {
|
|
||||||
// Needed on macos.
|
|
||||||
// Explanation at https://github.com/banach-space/llvm-tutor/blob/787b09ed31ff7f0e7bdd42ae20547d27e2991512/lib/CMakeLists.txt#L59
|
|
||||||
ldflags.push("-undefined");
|
|
||||||
ldflags.push("dynamic_lookup");
|
|
||||||
|
|
||||||
// In case the system is configured oddly, we may have trouble finding the SDK. Manually add the linker flag, just in case.
|
|
||||||
sdk_path = find_macos_sdk_libs();
|
|
||||||
ldflags.push(&sdk_path);
|
|
||||||
};
|
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed=src/common-llvm.h");
|
|
||||||
println!("cargo:rerun-if-changed=src/cmplog-routines-pass.cc");
|
|
||||||
println!("cargo:rerun-if-changed=src/afl-coverage-pass.cc");
|
|
||||||
println!("cargo:rerun-if-changed=src/autotokens-pass.cc");
|
|
||||||
println!("cargo:rerun-if-changed=src/coverage-accounting-pass.cc");
|
|
||||||
|
|
||||||
assert!(Command::new(llvm_bindir.join("clang++"))
|
|
||||||
.args(&cxxflags)
|
|
||||||
.args(&custom_flags)
|
|
||||||
.arg(src_dir.join("cmplog-routines-pass.cc"))
|
|
||||||
.args(&ldflags)
|
|
||||||
.args(&["-fPIC", "-shared", "-o"])
|
|
||||||
.arg(out_dir.join(format!("cmplog-routines-pass.{}", dll_extension())))
|
|
||||||
.status()
|
|
||||||
.expect("Failed to compile cmplog-routines-pass.cc")
|
|
||||||
.success());
|
|
||||||
|
|
||||||
assert!(Command::new(llvm_bindir.join("clang++"))
|
|
||||||
.args(&cxxflags)
|
|
||||||
.args(&custom_flags)
|
|
||||||
.arg(src_dir.join("afl-coverage-pass.cc"))
|
|
||||||
.args(&ldflags)
|
|
||||||
.args(&["-fPIC", "-shared", "-o"])
|
|
||||||
.arg(out_dir.join(format!("afl-coverage-pass.{}", dll_extension())))
|
|
||||||
.status()
|
|
||||||
.expect("Failed to compile afl-coverage-pass.cc")
|
|
||||||
.success());
|
|
||||||
|
|
||||||
assert!(Command::new(llvm_bindir.join("clang++"))
|
|
||||||
.args(&cxxflags)
|
|
||||||
.args(&custom_flags)
|
|
||||||
.arg(src_dir.join("autotokens-pass.cc"))
|
|
||||||
.args(&ldflags)
|
|
||||||
.args(&["-fPIC", "-shared", "-o"])
|
|
||||||
.arg(out_dir.join(format!("autotokens-pass.{}", dll_extension())))
|
|
||||||
.status()
|
|
||||||
.expect("Failed to compile autotokens-pass.cc")
|
|
||||||
.success());
|
|
||||||
|
|
||||||
assert!(Command::new(llvm_bindir.join("clang++"))
|
|
||||||
.args(&cxxflags)
|
|
||||||
.args(&custom_flags)
|
|
||||||
.arg(src_dir.join("coverage-accounting-pass.cc"))
|
|
||||||
.args(&ldflags)
|
|
||||||
.args(&["-fPIC", "-shared", "-o"])
|
|
||||||
.arg(out_dir.join(format!("coverage-accounting-pass.{}", dll_extension())))
|
|
||||||
.status()
|
|
||||||
.expect("Failed to compile coverage-accounting-pass.cc")
|
|
||||||
.success());
|
|
||||||
} else {
|
|
||||||
write!(
|
|
||||||
clang_constants_file,
|
|
||||||
"// These constants are autogenerated by build.rs
|
|
||||||
|
|
||||||
/// The path to the `clang` executable
|
/// The path to the `clang` executable
|
||||||
pub const CLANG_PATH: &str = \"clang\";
|
pub const CLANG_PATH: &str = \"clang\";
|
||||||
/// The path to the `clang++` executable
|
/// The path to the `clang++` executable
|
||||||
@ -255,16 +188,130 @@ pub const LIBAFL_CC_LLVM_VERSION: Option<usize> = None;
|
|||||||
)
|
)
|
||||||
.expect("Could not write file");
|
.expect("Could not write file");
|
||||||
|
|
||||||
println!(
|
return;
|
||||||
"cargo:warning=Failed to locate the LLVM path using {}, we will not build LLVM passes
|
}
|
||||||
(if you need them, set point the LLVM_CONFIG env to a recent llvm-config, or make sure {} is available)",
|
|
||||||
llvm_config, llvm_config
|
let cxxflags = exec_llvm_config(&["--cxxflags"]);
|
||||||
);
|
let mut cxxflags: Vec<String> = cxxflags.split_whitespace().map(String::from).collect();
|
||||||
|
|
||||||
|
let edges_map_size: usize = option_env!("LIBAFL_EDGES_MAP_SIZE")
|
||||||
|
.map_or(Ok(65536), str::parse)
|
||||||
|
.expect("Could not parse LIBAFL_EDGES_MAP_SIZE");
|
||||||
|
cxxflags.push(format!("-DLIBAFL_EDGES_MAP_SIZE={}", edges_map_size));
|
||||||
|
|
||||||
|
let acc_map_size: usize = option_env!("LIBAFL_ACCOUNTING_MAP_SIZE")
|
||||||
|
.map_or(Ok(65536), str::parse)
|
||||||
|
.expect("Could not parse LIBAFL_ACCOUNTING_MAP_SIZE");
|
||||||
|
cxxflags.push(format!("-DLIBAFL_ACCOUNTING_MAP_SIZE={}", acc_map_size));
|
||||||
|
|
||||||
|
let llvm_version = match find_llvm_config()
|
||||||
|
.unwrap()
|
||||||
|
.split('-')
|
||||||
|
.collect::<Vec<&str>>()
|
||||||
|
.get(2)
|
||||||
|
{
|
||||||
|
Some(ver) => ver.parse::<usize>().ok(),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
// The approach below causes issues with arguments to optimization passes.
|
||||||
|
// An example is fuzzers/libfuzzer_libpng_accounting which passes -granularity=FUNC.
|
||||||
|
// In CI/CD, the new pass manager is not used. For now, maintain the same behavior.
|
||||||
|
//let llvm_version = find_llvm_version();
|
||||||
|
|
||||||
|
if let Some(ver) = llvm_version {
|
||||||
|
if ver >= 14 {
|
||||||
|
cxxflags.push(String::from("-DUSE_NEW_PM"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let llvm_bindir = exec_llvm_config(&["--bindir"]);
|
||||||
|
let bindir_path = Path::new(&llvm_bindir);
|
||||||
|
|
||||||
|
write!(
|
||||||
|
clang_constants_file,
|
||||||
|
"// These constants are autogenerated by build.rs
|
||||||
|
|
||||||
|
/// The path to the `clang` executable
|
||||||
|
pub const CLANG_PATH: &str = {:?};
|
||||||
|
/// The path to the `clang++` executable
|
||||||
|
pub const CLANGXX_PATH: &str = {:?};
|
||||||
|
|
||||||
|
/// The size of the edges map
|
||||||
|
pub const EDGES_MAP_SIZE: usize = {};
|
||||||
|
|
||||||
|
/// The size of the accounting maps
|
||||||
|
pub const ACCOUNTING_MAP_SIZE: usize = {};
|
||||||
|
|
||||||
|
/// The llvm version used to build llvm passes
|
||||||
|
pub const LIBAFL_CC_LLVM_VERSION: Option<usize> = {:?};
|
||||||
|
",
|
||||||
|
bindir_path.join("clang"),
|
||||||
|
bindir_path.join("clang++"),
|
||||||
|
edges_map_size,
|
||||||
|
acc_map_size,
|
||||||
|
llvm_version,
|
||||||
|
)
|
||||||
|
.expect("Could not write file");
|
||||||
|
|
||||||
|
let mut llvm_config_ld = vec![];
|
||||||
|
if cfg!(target_vendor = "apple") {
|
||||||
|
llvm_config_ld.push("--libs");
|
||||||
|
}
|
||||||
|
if cfg!(windows) {
|
||||||
|
llvm_config_ld.push("--libs");
|
||||||
|
llvm_config_ld.push("--system-libs");
|
||||||
|
}
|
||||||
|
llvm_config_ld.push("--ldflags");
|
||||||
|
|
||||||
|
let ldflags = exec_llvm_config(&llvm_config_ld);
|
||||||
|
let mut ldflags: Vec<&str> = ldflags.split_whitespace().collect();
|
||||||
|
|
||||||
|
if cfg!(unix) {
|
||||||
|
cxxflags.push(String::from("-shared"));
|
||||||
|
cxxflags.push(String::from("-fPIC"));
|
||||||
|
}
|
||||||
|
if cfg!(windows) {
|
||||||
|
cxxflags.push(String::from("-fuse-ld=lld"));
|
||||||
|
cxxflags.push(String::from("/LD"));
|
||||||
|
/* clang on windows links against the libcmt.lib runtime
|
||||||
|
* however, the distributed binaries are compiled against msvcrt.lib
|
||||||
|
* we need to also use msvcrt.lib instead of libcmt.lib when building the optimization passes
|
||||||
|
* first, we tell clang-cl (and indirectly link) to ignore libcmt.lib via -nodefaultlib:libcmt
|
||||||
|
* second, we pass the /MD flag to clang-cl to use the msvcrt.lib runtime instead when generating the object file
|
||||||
|
*/
|
||||||
|
ldflags.push("-nodefaultlib:libcmt");
|
||||||
|
cxxflags.push(String::from("/MD"));
|
||||||
|
/* the include directories are not always added correctly when running --cxxflags or --includedir on windows
|
||||||
|
* this is somehow related to where/how llvm was compiled (vm, docker container, host)
|
||||||
|
* add the option of setting additional flags via the LLVM_CXXFLAGS variable
|
||||||
|
*/
|
||||||
|
if let Some(env_cxxflags) = option_env!("LLVM_CXXFLAGS") {
|
||||||
|
cxxflags.append(&mut env_cxxflags.split_whitespace().map(String::from).collect());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let sdk_path;
|
||||||
|
if env::var("CARGO_CFG_TARGET_VENDOR").unwrap().as_str() == "apple" {
|
||||||
|
// Needed on macos.
|
||||||
|
// Explanation at https://github.com/banach-space/llvm-tutor/blob/787b09ed31ff7f0e7bdd42ae20547d27e2991512/lib/CMakeLists.txt#L59
|
||||||
|
ldflags.push("-undefined");
|
||||||
|
ldflags.push("dynamic_lookup");
|
||||||
|
|
||||||
|
// In case the system is configured oddly, we may have trouble finding the SDK. Manually add the linker flag, just in case.
|
||||||
|
sdk_path = find_macos_sdk_libs();
|
||||||
|
ldflags.push(&sdk_path);
|
||||||
|
};
|
||||||
|
|
||||||
|
for pass in &[
|
||||||
|
"cmplog-routines-pass.cc",
|
||||||
|
"afl-coverage-pass.cc",
|
||||||
|
"autotokens-pass.cc",
|
||||||
|
"coverage-accounting-pass.cc",
|
||||||
|
] {
|
||||||
|
build_pass(bindir_path, out_dir, &cxxflags, &ldflags, src_dir, pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
cc::Build::new()
|
cc::Build::new()
|
||||||
.file(src_dir.join("no-link-rt.c"))
|
.file(src_dir.join("no-link-rt.c"))
|
||||||
.compile("no-link-rt");
|
.compile("no-link-rt");
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
|
||||||
}
|
}
|
||||||
|
@ -31,8 +31,12 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#ifndef _WIN32
|
||||||
#include <sys/time.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#else
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -781,8 +785,13 @@ bool AFLCoverage::runOnModule(Module &M) {
|
|||||||
}
|
}
|
||||||
if (DumpCFG) {
|
if (DumpCFG) {
|
||||||
int fd;
|
int fd;
|
||||||
|
#ifndef _WIN32
|
||||||
if ((fd = open(DumpCFGPath.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0644)) <
|
if ((fd = open(DumpCFGPath.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0644)) <
|
||||||
0)
|
0)
|
||||||
|
#else
|
||||||
|
if ((fd = _open(DumpCFGPath.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0644)) <
|
||||||
|
0)
|
||||||
|
#endif
|
||||||
FATAL("Could not open/create CFG dump file.");
|
FATAL("Could not open/create CFG dump file.");
|
||||||
std::string cfg = "";
|
std::string cfg = "";
|
||||||
for (auto record = entry_bb.begin(); record != entry_bb.end(); record++) {
|
for (auto record = entry_bb.begin(); record != entry_bb.end(); record++) {
|
||||||
|
@ -18,9 +18,13 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#ifndef _WIN32
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#else
|
||||||
|
#include <io.h>
|
||||||
|
#endif
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -213,7 +217,9 @@ void dict2file(int fd, uint8_t *mem, uint32_t len) {
|
|||||||
if (write(fd, line, strlen(line)) <= 0) {
|
if (write(fd, line, strlen(line)) <= 0) {
|
||||||
FATAL("Could not write to the dictionary file");
|
FATAL("Could not write to the dictionary file");
|
||||||
}
|
}
|
||||||
|
#ifndef _WIN32
|
||||||
fsync(fd);
|
fsync(fd);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_NEW_PM
|
#if USE_NEW_PM
|
||||||
@ -242,7 +248,11 @@ bool AutoTokensPass::runOnModule(Module &M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (use_file) {
|
if (use_file) {
|
||||||
|
#ifndef _WIN32
|
||||||
if ((fd = open(ptr, O_WRONLY | O_APPEND | O_CREAT | O_DSYNC, 0644)) < 0)
|
if ((fd = open(ptr, O_WRONLY | O_APPEND | O_CREAT | O_DSYNC, 0644)) < 0)
|
||||||
|
#else
|
||||||
|
if ((fd = open(ptr, O_WRONLY | O_APPEND | O_CREAT, 0644)) < 0)
|
||||||
|
#endif
|
||||||
FATAL("Could not open/create %s.", ptr);
|
FATAL("Could not open/create %s.", ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -684,4 +694,4 @@ static RegisterStandardPasses RegisterAutoTokensPass(
|
|||||||
|
|
||||||
static RegisterStandardPasses RegisterAutoTokensPass0(
|
static RegisterStandardPasses RegisterAutoTokensPass0(
|
||||||
PassManagerBuilder::EP_EnabledOnOptLevel0, registerAutoTokensPass);
|
PassManagerBuilder::EP_EnabledOnOptLevel0, registerAutoTokensPass);
|
||||||
#endif
|
#endif
|
||||||
|
@ -112,7 +112,11 @@ impl CompilerWrapper for ClangWrapper {
|
|||||||
|
|
||||||
self.name = args[0].as_ref().to_string();
|
self.name = args[0].as_ref().to_string();
|
||||||
// Detect C++ compiler looking at the wrapper name
|
// Detect C++ compiler looking at the wrapper name
|
||||||
self.is_cpp = self.is_cpp || self.name.ends_with("++");
|
self.is_cpp = if cfg!(windows) {
|
||||||
|
self.is_cpp || self.name.ends_with("++.exe")
|
||||||
|
} else {
|
||||||
|
self.is_cpp || self.name.ends_with("++")
|
||||||
|
};
|
||||||
|
|
||||||
// Sancov flag
|
// Sancov flag
|
||||||
// new_args.push("-fsanitize-coverage=trace-pc-guard".into());
|
// new_args.push("-fsanitize-coverage=trace-pc-guard".into());
|
||||||
@ -252,21 +256,22 @@ impl CompilerWrapper for ClangWrapper {
|
|||||||
where
|
where
|
||||||
S: AsRef<str>,
|
S: AsRef<str>,
|
||||||
{
|
{
|
||||||
if cfg!(target_vendor = "apple") {
|
let lib_file = dir
|
||||||
//self.add_link_arg("-force_load".into())?;
|
.join(format!("{}{}.{}", LIB_PREFIX, name.as_ref(), LIB_EXT))
|
||||||
|
.into_os_string()
|
||||||
|
.into_string()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
if cfg!(unix) {
|
||||||
|
if cfg!(target_vendor = "apple") {
|
||||||
|
self.add_link_arg(lib_file)
|
||||||
|
} else {
|
||||||
|
self.add_link_arg("-Wl,--whole-archive")
|
||||||
|
.add_link_arg(lib_file)
|
||||||
|
.add_link_arg("-Wl,--no-whole-archive")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
self.add_link_arg("-Wl,--whole-archive");
|
self.add_link_arg(format!("-Wl,-wholearchive:{}", lib_file))
|
||||||
}
|
|
||||||
self.add_link_arg(
|
|
||||||
dir.join(format!("{}{}.{}", LIB_PREFIX, name.as_ref(), LIB_EXT))
|
|
||||||
.into_os_string()
|
|
||||||
.into_string()
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
if cfg!(target_vendor = "apple") {
|
|
||||||
self
|
|
||||||
} else {
|
|
||||||
self.add_link_arg("-Wl,-no-whole-archive")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,12 +17,14 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#ifndef _WIN32
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sys/time.h>
|
|
||||||
#include "llvm/Config/llvm-config.h"
|
#include "llvm/Config/llvm-config.h"
|
||||||
|
|
||||||
#if USE_NEW_PM
|
#if USE_NEW_PM
|
||||||
|
Loading…
x
Reference in New Issue
Block a user