Extract linker args when building QEMU (#1377)

* Update qemu commit

* Hook the linker and automatically extract linker args

* Comment code
This commit is contained in:
Andrea Fioraldi 2023-07-26 10:42:15 +02:00 committed by GitHub
parent 993eb62bb8
commit cb24b5dc2d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 67 additions and 7 deletions

View File

@ -28,3 +28,4 @@ which = "4.2"
json = "0.12"
shell-words = "1.1"
pkg-config = "0.3.26"
cc = "1.0"

View File

@ -8,7 +8,7 @@ use which::which;
const QEMU_URL: &str = "https://github.com/AFLplusplus/qemu-libafl-bridge";
const QEMU_DIRNAME: &str = "qemu-libafl-bridge";
const QEMU_REVISION: &str = "98efc72c4ca20b60c80dd16e2c88af114b8b2ae7";
const QEMU_REVISION: &str = "3a774d591acb9770eeeb286ec88c657271c398d8";
fn build_dep_check(tools: &[&str]) {
for tool in tools {
@ -60,6 +60,8 @@ pub fn build(
build_dep_check(&["git", "make"]);
let cpp_compiler = cc::Build::new().cpp(true).get_compiler();
let qemu_path = if let Some(qemu_dir) = custum_qemu_dir.as_ref() {
Path::new(&qemu_dir).to_path_buf()
} else {
@ -136,6 +138,12 @@ pub fn build(
let mut cmd = Command::new("./configure");
cmd.current_dir(&qemu_path)
//.arg("--as-static-lib")
.env("__LIBAFL_QEMU_BUILD_OUT", build_dir.join("linkinfo.json"))
.env("__LIBAFL_QEMU_BUILD_CXX", cpp_compiler.path())
.arg(&format!(
"--cxx={}",
qemu_path.join("linker_interceptor.py").display()
))
.arg("--as-shared-lib")
.arg(&format!("--target-list={cpu_target}-{target_suffix}"))
.args([
@ -152,6 +160,12 @@ pub fn build(
let mut cmd = Command::new("./configure");
cmd.current_dir(&qemu_path)
//.arg("--as-static-lib")
.env("__LIBAFL_QEMU_BUILD_OUT", build_dir.join("linkinfo.json"))
.env("__LIBAFL_QEMU_BUILD_CXX", cpp_compiler.path())
.arg(&format!(
"--cxx={}",
qemu_path.join("linker_interceptor.py").display()
)) // TODO set __LIBAFL_QEMU_BUILD_CXX
.arg("--as-shared-lib")
.arg(&format!("--target-list={cpu_target}-{target_suffix}"))
.arg(if cfg!(feature = "slirp") {
@ -277,6 +291,7 @@ pub fn build(
.current_dir(&build_dir)
.arg("-j")
.arg(&format!("{j}"))
.env("V", "1")
.status()
.expect("Make failed");
} else {
@ -288,6 +303,7 @@ pub fn build(
}
}
/*
let mut objects = vec![];
for dir in &[
build_dir.join("libcommon.fa.p"),
@ -308,7 +324,33 @@ pub fn build(
}
}
}
*/
let compile_commands_string =
&fs::read_to_string(build_dir.join("linkinfo.json")).expect("Failed to read linkinfo.json");
let linkinfo = json::parse(compile_commands_string).expect("Failed to parse linkinfo.json");
let mut cmd = vec![];
for arg in linkinfo["cmd"].members() {
cmd.push(
arg.as_str()
.expect("linkinfo.json `cmd` values must be strings"),
);
}
assert!(cpp_compiler
.to_command()
.current_dir(&build_dir)
.arg("-o")
.arg("libqemu-partially-linked.o")
.arg("-r")
.args(cmd)
.status()
.expect("Partial linked failure")
.success());
/* // Old manual linking, kept here for reference and debugging
if is_usermode {
Command::new("ld")
.current_dir(out_dir_path)
@ -390,18 +432,34 @@ pub fn build(
.arg("--end-group")
.status()
.expect("Partial linked failure");
}
}*/
Command::new("ar")
.current_dir(out_dir_path)
.arg("crs")
.arg("libqemu-partially-linked.a")
.arg("libqemu-partially-linked.o")
.arg(build_dir.join("libqemu-partially-linked.o"))
.status()
.expect("Ar creation");
println!("cargo:rustc-link-search=native={out_dir}");
println!("cargo:rustc-link-lib=static=qemu-partially-linked");
for arg in linkinfo["search"].members() {
let val = arg
.as_str()
.expect("linkinfo.json `search` values must be strings");
println!("cargo:rustc-link-search={val}");
}
for arg in linkinfo["libs"].members() {
let val = arg
.as_str()
.expect("linkinfo.json `libs` values must be strings");
println!("cargo:rustc-link-lib={val}");
}
/*
println!("cargo:rustc-link-lib=rt");
println!("cargo:rustc-link-lib=gmodule-2.0");
println!("cargo:rustc-link-lib=glib-2.0");
@ -411,12 +469,13 @@ pub fn build(
// therefore, we need to link with keyutils if our system have libkeyutils.
let _: Result<pkg_config::Library, pkg_config::Error> =
pkg_config::Config::new().probe("libkeyutils");
*/
if !is_usermode {
println!("cargo:rustc-link-lib=pixman-1");
if env::var("LINK_SLIRP").is_ok() || cfg!(feature = "slirp") {
println!("cargo:rustc-link-lib=slirp");
}
//println!("cargo:rustc-link-lib=pixman-1");
//if env::var("LINK_SLIRP").is_ok() || cfg!(feature = "slirp") {
// println!("cargo:rustc-link-lib=slirp");
//}
fs::create_dir_all(target_dir.join("pc-bios")).unwrap();
for path in fs::read_dir(build_dir.join("pc-bios")).unwrap() {