Fix libnyx, library upgrades (#2254)

* try this thing

* this?

* use new mmap signature in nix.

* fix import

* fix to work with addr2line v0.23.

* remove unused flag

* update strum also for dependency...

* clippy

* clippy

* update lain git hash

* bump many outdated crates

* fix hash
This commit is contained in:
Romain Malmain 2024-05-28 17:15:08 +02:00 committed by GitHub
parent c3f67daefb
commit 65af5a7f78
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 237 additions and 73 deletions

View File

@ -9,6 +9,7 @@ on:
merge_group: merge_group:
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
CARGO_NET_GIT_FETCH_WITH_CLI: true
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true cancel-in-progress: true

View File

@ -22,10 +22,10 @@ strip = true
[build-dependencies] [build-dependencies]
cc = { version = "1.0", features = ["parallel"] } cc = { version = "1.0", features = ["parallel"] }
which = "4.4" which = "6.0"
[dependencies] [dependencies]
env_logger = "0.10" env_logger = "0.11"
once_cell = "1.19" once_cell = "1.19"
libafl = { path = "../../libafl/" } libafl = { path = "../../libafl/" }
libafl_bolts = { path = "../../libafl_bolts/" } libafl_bolts = { path = "../../libafl_bolts/" }
@ -33,7 +33,7 @@ libafl_targets = { path = "../../libafl_targets/", features = ["sancov_pcguard_h
# TODO Include it only when building cc # TODO Include it only when building cc
libafl_cc = { path = "../../libafl_cc/" } libafl_cc = { path = "../../libafl_cc/" }
clap = { version = "4.0", features = ["default"] } clap = { version = "4.0", features = ["default"] }
nix = { version = "0.27", features = ["fs"] } nix = { version = "0.29", features = ["fs"] }
mimalloc = { version = "*", default-features = false } mimalloc = { version = "*", default-features = false }
[lib] [lib]

View File

@ -18,16 +18,16 @@ debug = true
[build-dependencies] [build-dependencies]
cc = { version = "1.0", features = ["parallel"] } cc = { version = "1.0", features = ["parallel"] }
which = { version = "4.4" } which = { version = "6.0" }
[dependencies] [dependencies]
clap = { version = "4.0", features = ["derive"] } clap = { version = "4.0", features = ["derive"] }
nix = "0.27" nix = { version = "0.29", features = ["signal"] }
libafl = { path = "../../libafl/" } libafl = { path = "../../libafl/" }
libafl_bolts = { path = "../../libafl_bolts/" } libafl_bolts = { path = "../../libafl_bolts/" }
libafl_cc = { path = "../../libafl_cc/" } libafl_cc = { path = "../../libafl_cc/" }
libafl_targets = { path = "../../libafl_targets/", features = ["sancov_pcguard_hitcounts", "libfuzzer", "pointer_maps"] } libafl_targets = { path = "../../libafl_targets/", features = ["sancov_pcguard_hitcounts", "libfuzzer", "pointer_maps"] }
env_logger = "0.10" env_logger = "0.11"
[lib] [lib]
name = "libforkserver_libafl_cc" name = "libforkserver_libafl_cc"

View File

@ -16,8 +16,8 @@ codegen-units = 1
opt-level = 3 opt-level = 3
[dependencies] [dependencies]
env_logger = "0.10" env_logger = "0.11"
libafl = { path = "../../libafl/", features = ["std", "derive"] } libafl = { path = "../../libafl/", features = ["std", "derive"] }
libafl_bolts = { path = "../../libafl_bolts/" } libafl_bolts = { path = "../../libafl_bolts/" }
clap = { version = "4.0", features = ["derive"] } clap = { version = "4.0", features = ["derive"] }
nix = "0.27" nix = { version = "0.29", features = ["signal"] }

View File

@ -22,7 +22,7 @@ strip = true
[build-dependencies] [build-dependencies]
cc = { version = "1.0", features = ["parallel"] } cc = { version = "1.0", features = ["parallel"] }
which = "4.4" which = "6.0"
[dependencies] [dependencies]
libafl = { path = "../../libafl/" } libafl = { path = "../../libafl/" }
@ -31,7 +31,7 @@ libafl_targets = { path = "../../libafl_targets/", features = ["sancov_pcguard_h
# TODO Include it only when building cc # TODO Include it only when building cc
libafl_cc = { path = "../../libafl_cc/" } libafl_cc = { path = "../../libafl_cc/" }
clap = { version = "4.0", features = ["default"] } clap = { version = "4.0", features = ["default"] }
nix = { version = "0.27", features = ["fs"] } nix = { version = "0.29", features = ["fs"] }
mimalloc = { version = "*", default-features = false } mimalloc = { version = "*", default-features = false }
[lib] [lib]

View File

@ -22,7 +22,7 @@ strip = true
[build-dependencies] [build-dependencies]
cc = { version = "1.0", features = ["parallel"] } cc = { version = "1.0", features = ["parallel"] }
which = "4.4" which = "6.0"
[dependencies] [dependencies]
libafl = { path = "../../libafl/" } libafl = { path = "../../libafl/" }
@ -31,7 +31,7 @@ libafl_targets = { path = "../../libafl_targets/", features = ["sancov_pcguard_h
# TODO Include it only when building cc # TODO Include it only when building cc
libafl_cc = { path = "../../libafl_cc/" } libafl_cc = { path = "../../libafl_cc/" }
clap = { version = "4.0", features = ["default"] } clap = { version = "4.0", features = ["default"] }
nix = { version = "0.27", features = ["fs"] } nix = { version = "0.29", features = ["fs"] }
mimalloc = { version = "*", default-features = false } mimalloc = { version = "*", default-features = false }
[lib] [lib]

View File

@ -25,4 +25,4 @@ libafl_bolts = { path = "../../libafl_bolts/" }
libafl_qemu = { path = "../../libafl_qemu/", features = ["x86_64", "usermode"] } libafl_qemu = { path = "../../libafl_qemu/", features = ["x86_64", "usermode"] }
clap = { version = "4.0", features = ["default"] } clap = { version = "4.0", features = ["default"] }
nix = { version = "0.27", features = ["fs"] } nix = { version = "0.29", features = ["fs"] }

View File

@ -17,11 +17,11 @@ strip = true
[build-dependencies] [build-dependencies]
cc = { version = "1.0", features = ["parallel"] } cc = { version = "1.0", features = ["parallel"] }
which = "4.4" which = "6.0"
[dependencies] [dependencies]
libafl = { path = "../../libafl/" } libafl = { path = "../../libafl/" }
libafl_bolts = { path = "../../libafl_bolts/" } libafl_bolts = { path = "../../libafl_bolts/" }
libafl_targets = { path = "../../libafl_targets/" } libafl_targets = { path = "../../libafl_targets/" }
clap = { version = "4.0", features = ["default"] } clap = { version = "4.0", features = ["default"] }
nix = "0.27" nix = { version = "0.29", features = ["signal"] }

View File

@ -17,11 +17,11 @@ strip = true
[build-dependencies] [build-dependencies]
cc = { version = "1.0", features = ["parallel"] } cc = { version = "1.0", features = ["parallel"] }
which = "4.4" which = "6.0"
[dependencies] [dependencies]
libafl = { path = "../../libafl/" } libafl = { path = "../../libafl/" }
libafl_bolts = { path = "../../libafl_bolts/" } libafl_bolts = { path = "../../libafl_bolts/" }
libafl_targets = { path = "../../libafl_targets/" } libafl_targets = { path = "../../libafl_targets/" }
clap = { version = "4.0", features = ["default"] } clap = { version = "4.0", features = ["default"] }
nix = "0.27" nix = { version = "0.29", features = ["signal"] }

View File

@ -25,5 +25,5 @@ libafl_bolts = { path = "../../libafl_bolts/" }
libafl_qemu = { path = "../../libafl_qemu/", features = ["x86_64", "usermode"] } libafl_qemu = { path = "../../libafl_qemu/", features = ["x86_64", "usermode"] }
clap = { version = "4.0", features = ["default"] } clap = { version = "4.0", features = ["default"] }
nix = { version = "0.27", features = ["fs"] } nix = { version = "0.29", features = ["fs"] }

View File

@ -17,7 +17,7 @@ debug = true
[build-dependencies] [build-dependencies]
cc = { version = "1.0", features = ["parallel"] } cc = { version = "1.0", features = ["parallel"] }
which = "4.4" which = "6.0"
[dependencies] [dependencies]
libafl = { path = "../../libafl/" } libafl = { path = "../../libafl/" }
@ -26,7 +26,7 @@ libafl_targets = { path = "../../libafl_targets/", features = ["sancov_pcguard_h
# TODO Include it only when building cc # TODO Include it only when building cc
libafl_cc = { path = "../../libafl_cc/" } libafl_cc = { path = "../../libafl_cc/" }
clap = { version = "4.0", features = ["default"] } clap = { version = "4.0", features = ["default"] }
nix = { version = "0.27", features = ["fs"] } nix = { version = "0.29", features = ["fs"] }
mimalloc = { version = "*", default-features = false } mimalloc = { version = "*", default-features = false }
content_inspector = "0.2.4" content_inspector = "0.2.4"
#log = "0.4" #log = "0.4"

View File

@ -33,15 +33,15 @@ opt-level = 3
debug = true debug = true
[build-dependencies] [build-dependencies]
vergen = { version = "8.2.1", features = ["build", "cargo", "git", "gitcl", "rustc", "si"] } vergen = { version = "8.2", features = ["build", "cargo", "git", "gitcl", "rustc", "si"] }
[dependencies] [dependencies]
clap = { version = "4.3.0", features = ["derive", "string"]} clap = { version = "4.3", features = ["derive", "string"]}
libafl = { path = "../../libafl/" } libafl = { path = "../../libafl/" }
libafl_bolts = { path = "../../libafl_bolts/", features = ["errors_backtrace"] } libafl_bolts = { path = "../../libafl_bolts/", features = ["errors_backtrace"] }
libafl_qemu = { path = "../../libafl_qemu/", features = ["usermode"] } libafl_qemu = { path = "../../libafl_qemu/", features = ["usermode"] }
log = {version = "0.4.20" } log = {version = "0.4.20" }
nix = { version = "0.27", features = ["fs"] } nix = { version = "0.29", features = ["fs"] }
rangemap = { version = "1.3" } rangemap = { version = "1.3" }
readonly = { version = "0.2.10" } readonly = { version = "0.2.10" }
typed-builder = { version = "0.15.1" } typed-builder = { version = "0.18" }

View File

@ -23,7 +23,7 @@ libafl = { path = "../../libafl/", features = ["default", "rand_trait"] }
libafl_bolts = { path = "../../libafl_bolts/" } libafl_bolts = { path = "../../libafl_bolts/" }
libafl_targets = { path = "../../libafl_targets/", features = ["sancov_pcguard_hitcounts", "libfuzzer", "sancov_cmplog"] } libafl_targets = { path = "../../libafl_targets/", features = ["sancov_pcguard_hitcounts", "libfuzzer", "sancov_cmplog"] }
serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib serde = { version = "1.0", default-features = false, features = ["alloc"] } # serialization lib
lain = { version = "0.5", features = ["serde_support"], git = "https://github.com/Mrmaxmeier/lain.git", rev = "6c8a786" } # We're using a lain fork with updated rand crate lain = { version = "0.5", features = ["serde_support"], git = "https://github.com/Mrmaxmeier/lain.git", rev = "6c8a786c7e27ed80c913c07177f95d475421bf69" } # We're using a lain fork with updated rand crate
# TODO Include it only when building cc # TODO Include it only when building cc
libafl_cc = { path = "../../libafl_cc/" } libafl_cc = { path = "../../libafl_cc/" }

View File

@ -1,11 +1,13 @@
//! Unix `pipe` wrapper for `LibAFL` //! Unix `pipe` wrapper for `LibAFL`
use alloc::rc::Rc; use alloc::rc::Rc;
use core::{borrow::Borrow, cell::RefCell}; use core::{borrow::Borrow, cell::RefCell};
use std::os::fd::{AsFd, AsRawFd, OwnedFd};
#[cfg(feature = "std")] #[cfg(feature = "std")]
use std::{ use std::{
io::{self, ErrorKind, Read, Write}, io::{self, ErrorKind, Read, Write},
os::unix::io::RawFd, os::{
fd::{AsFd, AsRawFd, OwnedFd},
unix::io::RawFd,
},
}; };
#[cfg(feature = "std")] #[cfg(feature = "std")]

View File

@ -18,7 +18,7 @@ use libafl::{
use libafl_bolts::{cli::FuzzerOptions, tuples::MatchFirstType}; use libafl_bolts::{cli::FuzzerOptions, tuples::MatchFirstType};
use libafl_targets::drcov::DrCovBasicBlock; use libafl_targets::drcov::DrCovBasicBlock;
#[cfg(unix)] #[cfg(unix)]
use nix::sys::mman::{mmap, MapFlags, ProtFlags}; use nix::sys::mman::{mmap_anonymous, MapFlags, ProtFlags};
use rangemap::RangeMap; use rangemap::RangeMap;
#[cfg(target_arch = "aarch64")] #[cfg(target_arch = "aarch64")]
use yaxpeax_arch::Arch; use yaxpeax_arch::Arch;
@ -31,11 +31,6 @@ use yaxpeax_x86::amd64::InstDecoder;
use crate::cmplog_rt::CmpLogRuntime; use crate::cmplog_rt::CmpLogRuntime;
use crate::{asan::asan_rt::AsanRuntime, coverage_rt::CoverageRuntime, drcov_rt::DrCovRuntime}; use crate::{asan::asan_rt::AsanRuntime, coverage_rt::CoverageRuntime, drcov_rt::DrCovRuntime};
#[cfg(target_vendor = "apple")]
const ANONYMOUS_FLAG: MapFlags = MapFlags::MAP_ANON;
#[cfg(not(any(target_vendor = "apple", target_os = "windows")))]
const ANONYMOUS_FLAG: MapFlags = MapFlags::MAP_ANONYMOUS;
/// The Runtime trait /// The Runtime trait
pub trait FridaRuntime: 'static + Debug { pub trait FridaRuntime: 'static + Debug {
/// Initialization /// Initialization
@ -613,26 +608,20 @@ where
// workaround frida's frida-gum-allocate-near bug: // workaround frida's frida-gum-allocate-near bug:
#[cfg(unix)] #[cfg(unix)]
fn workaround_gum_allocate_near() { fn workaround_gum_allocate_near() {
use std::fs::File;
unsafe { unsafe {
for _ in 0..512 { for _ in 0..512 {
mmap::<File>( mmap_anonymous(
None, None,
std::num::NonZeroUsize::new_unchecked(128 * 1024), std::num::NonZeroUsize::new_unchecked(128 * 1024),
ProtFlags::PROT_NONE, ProtFlags::PROT_NONE,
ANONYMOUS_FLAG | MapFlags::MAP_PRIVATE | MapFlags::MAP_NORESERVE, MapFlags::MAP_PRIVATE | MapFlags::MAP_NORESERVE,
None,
0,
) )
.expect("Failed to map dummy regions for frida workaround"); .expect("Failed to map dummy regions for frida workaround");
mmap::<File>( mmap_anonymous(
None, None,
std::num::NonZeroUsize::new_unchecked(4 * 1024 * 1024), std::num::NonZeroUsize::new_unchecked(4 * 1024 * 1024),
ProtFlags::PROT_NONE, ProtFlags::PROT_NONE,
ANONYMOUS_FLAG | MapFlags::MAP_PRIVATE | MapFlags::MAP_NORESERVE, MapFlags::MAP_PRIVATE | MapFlags::MAP_NORESERVE,
None,
0,
) )
.expect("Failed to map dummy regions for frida workaround"); .expect("Failed to map dummy regions for frida workaround");
} }

View File

@ -14,10 +14,10 @@ categories = ["development-tools::testing", "emulators", "embedded", "os", "no-s
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[target.'cfg(target_os = "linux")'.dependencies] [target.'cfg(target_os = "linux")'.dependencies]
libnyx = { git = "https://github.com/nyx-fuzz/libnyx.git", rev = "6833d23" } libnyx = { git = "https://github.com/nyx-fuzz/libnyx.git", rev = "6833d236dfe785a8a23d8c8d79e74c99fa635004" }
libafl = { path = "../libafl", version = "0.12.0", features = ["std", "libafl_derive", "frida_cli" ]} libafl = { path = "../libafl", version = "0.12.0", features = ["std", "libafl_derive", "frida_cli" ]}
libafl_bolts = { path = "../libafl_bolts", version = "0.12.0", features = ["std", "libafl_derive", "frida_cli" ]} libafl_bolts = { path = "../libafl_bolts", version = "0.12.0", features = ["std", "libafl_derive", "frida_cli" ]}
libafl_targets = { path = "../libafl_targets", version = "0.12.0", features = ["std", "sancov_cmplog"] } libafl_targets = { path = "../libafl_targets", version = "0.12.0", features = ["std", "sancov_cmplog"] }
nix = { version = "0.29.0", features = ["fs"] } nix = { version = "0.29", features = ["fs"] }
typed-builder = "0.18.1" typed-builder = "0.18"

View File

@ -75,14 +75,15 @@ num-derive = "0.4"
num_enum = "0.7" num_enum = "0.7"
goblin = "0.8" goblin = "0.8"
libc = "0.2" libc = "0.2"
strum = "0.25" strum = "0.26"
strum_macros = "0.25" strum_macros = "0.26"
syscall-numbers = "3.0" syscall-numbers = "3.0"
meminterval = "0.4" meminterval = "0.4"
thread_local = "1.1.4" thread_local = "1.1.4"
capstone = "0.12.0" capstone = "0.12.0"
rangemap = "1.3" rangemap = "1.3"
log = "0.4.20" log = "0.4"
object = "0.36"
addr2line = "0.23" addr2line = "0.23"
typed-arena = "2.0" typed-arena = "2.0"
paste = "1" paste = "1"
@ -92,6 +93,7 @@ toml = { version = "0.8.13", optional = true } # For parsing the injections toml
pyo3 = { version = "0.18", optional = true , features = ["multiple-pymethods"]} pyo3 = { version = "0.18", optional = true , features = ["multiple-pymethods"]}
bytes-utils = "0.1" bytes-utils = "0.1"
typed-builder = "0.18" typed-builder = "0.18"
memmap2 = "0.9"
# Document all features of this crate (for `cargo doc`) # Document all features of this crate (for `cargo doc`)
document-features = { version = "0.2", optional = true } document-features = { version = "0.2", optional = true }

View File

@ -30,7 +30,7 @@ paranoid_debug = [] # Will perform as many checks as possible. The target will b
[dependencies] [dependencies]
bindgen = "0.69.4" bindgen = "0.69.4"
which = "4.4" which = "6.0"
json = "0.12" json = "0.12"
shell-words = "1.1" shell-words = "1.1"
pkg-config = "0.3.26" pkg-config = "0.3.26"

View File

@ -44,11 +44,11 @@ paranoid_debug = ["libafl_qemu_build/paranoid_debug"] # Will perform as many che
paste = "1" paste = "1"
num_enum = "0.7" num_enum = "0.7"
libc = "0.2" libc = "0.2"
strum = "0.25" strum = "0.26"
strum_macros = "0.25" strum_macros = "0.26"
pyo3 = { version = "0.18", optional = true } pyo3 = { version = "0.18", optional = true }
[build-dependencies] [build-dependencies]
libafl_qemu_build = { path = "../libafl_qemu_build", version = "0.12.0" } libafl_qemu_build = { path = "../libafl_qemu_build", version = "0.12.0" }
pyo3-build-config = { version = "0.18", optional = true } pyo3-build-config = { version = "0.21", optional = true }
rustversion = "1.0" rustversion = "1.0"

View File

@ -4,10 +4,10 @@ use std::{
borrow::Cow, borrow::Cow,
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
env, fs, env, fs,
path::PathBuf,
sync::Mutex, sync::Mutex,
}; };
use addr2line::object::{Object, ObjectSection};
use libafl::{executors::ExitKind, inputs::UsesInput, observers::ObserversTuple, HasMetadata}; use libafl::{executors::ExitKind, inputs::UsesInput, observers::ObserversTuple, HasMetadata};
use libc::{ use libc::{
c_void, MAP_ANON, MAP_FAILED, MAP_FIXED, MAP_NORESERVE, MAP_PRIVATE, PROT_READ, PROT_WRITE, c_void, MAP_ANON, MAP_FAILED, MAP_FIXED, MAP_NORESERVE, MAP_PRIVATE, PROT_READ, PROT_WRITE,
@ -154,6 +154,9 @@ impl AllocTreeItem {
} }
} }
use std::pin::Pin; use std::pin::Pin;
use object::{Object, ObjectSection};
pub struct AsanGiovese { pub struct AsanGiovese {
pub alloc_tree: Mutex<IntervalTree<GuestAddr, AllocTreeItem>>, pub alloc_tree: Mutex<IntervalTree<GuestAddr, AllocTreeItem>>,
pub saved_tree: IntervalTree<GuestAddr, AllocTreeItem>, pub saved_tree: IntervalTree<GuestAddr, AllocTreeItem>,
@ -1324,10 +1327,10 @@ where
fn load_file_section<'input, 'arena, Endian: addr2line::gimli::Endianity>( fn load_file_section<'input, 'arena, Endian: addr2line::gimli::Endianity>(
id: addr2line::gimli::SectionId, id: addr2line::gimli::SectionId,
file: &addr2line::object::File<'input>, file: &object::File<'input>,
endian: Endian, endian: Endian,
arena_data: &'arena typed_arena::Arena<Cow<'input, [u8]>>, arena_data: &'arena typed_arena::Arena<Cow<'input, [u8]>>,
) -> Result<addr2line::gimli::EndianSlice<'arena, Endian>, addr2line::object::Error> { ) -> Result<addr2line::gimli::EndianSlice<'arena, Endian>, object::Error> {
// TODO: Unify with dwarfdump.rs in gimli. // TODO: Unify with dwarfdump.rs in gimli.
let name = id.name(); let name = id.name();
match file.section_by_name(name) { match file.section_by_name(name) {
@ -1342,10 +1345,178 @@ fn load_file_section<'input, 'arena, Endian: addr2line::gimli::Endianity>(
} }
} }
/// Taken from `addr2line` [v0.22](https://github.com/gimli-rs/addr2line/blob/5c3c83f74f992220b2d9a17b3ac498a89214bf92/src/builtin_split_dwarf_loader.rs)
/// has been removed in version v0.23 for some reason.
/// TODO: find another cleaner solution.
mod addr2line_legacy {
use std::{borrow::Cow, ffi::OsString, fs::File, path::PathBuf, sync::Arc};
use addr2line::{gimli, LookupContinuation, LookupResult};
use object::Object;
#[cfg(unix)]
fn convert_path<R: gimli::Reader<Endian = gimli::RunTimeEndian>>(
r: &R,
) -> Result<PathBuf, gimli::Error> {
use std::{ffi::OsStr, os::unix::ffi::OsStrExt};
let bytes = r.to_slice()?;
let s = OsStr::from_bytes(&bytes);
Ok(PathBuf::from(s))
}
#[cfg(not(unix))]
fn convert_path<R: gimli::Reader<Endian = gimli::RunTimeEndian>>(
r: &R,
) -> Result<PathBuf, gimli::Error> {
let bytes = r.to_slice()?;
let s = std::str::from_utf8(&bytes).map_err(|_| gimli::Error::BadUtf8)?;
Ok(PathBuf::from(s))
}
fn load_section<'data, O, R, F>(
id: gimli::SectionId,
file: &O,
endian: R::Endian,
loader: &mut F,
) -> R
where
O: Object<'data>,
R: gimli::Reader<Endian = gimli::RunTimeEndian>,
F: FnMut(Cow<'data, [u8]>, R::Endian) -> R,
{
use object::ObjectSection;
let data = id
.dwo_name()
.and_then(|dwo_name| {
file.section_by_name(dwo_name)
.and_then(|section| section.uncompressed_data().ok())
})
.unwrap_or(Cow::Borrowed(&[]));
loader(data, endian)
}
/// A simple builtin split DWARF loader.
pub struct SplitDwarfLoader<R, F>
where
R: gimli::Reader<Endian = gimli::RunTimeEndian>,
F: FnMut(Cow<'_, [u8]>, R::Endian) -> R,
{
loader: F,
dwarf_package: Option<gimli::DwarfPackage<R>>,
}
impl<R, F> SplitDwarfLoader<R, F>
where
R: gimli::Reader<Endian = gimli::RunTimeEndian>,
F: FnMut(Cow<'_, [u8]>, R::Endian) -> R,
{
fn load_dwarf_package(
loader: &mut F,
path: Option<PathBuf>,
) -> Option<gimli::DwarfPackage<R>> {
let mut path = path.map_or_else(std::env::current_exe, Ok).ok()?;
let dwp_extension = path.extension().map_or_else(
|| OsString::from("dwp"),
|previous_extension| {
let mut previous_extension = previous_extension.to_os_string();
previous_extension.push(".dwp");
previous_extension
},
);
path.set_extension(dwp_extension);
let file = File::open(&path).ok()?;
let map = unsafe { memmap2::Mmap::map(&file).ok()? };
let dwp = object::File::parse(&*map).ok()?;
let endian = if dwp.is_little_endian() {
gimli::RunTimeEndian::Little
} else {
gimli::RunTimeEndian::Big
};
let empty = loader(Cow::Borrowed(&[]), endian);
gimli::DwarfPackage::load::<_, gimli::Error>(
|section_id| Ok(load_section(section_id, &dwp, endian, loader)),
empty,
)
.ok()
}
/// Create a new split DWARF loader.
pub fn new(mut loader: F, path: Option<PathBuf>) -> SplitDwarfLoader<R, F> {
let dwarf_package = SplitDwarfLoader::load_dwarf_package(&mut loader, path);
SplitDwarfLoader {
loader,
dwarf_package,
}
}
/// Run the provided `LookupResult` to completion, loading any necessary
/// split DWARF along the way.
pub fn run<L>(&mut self, mut l: LookupResult<L>) -> L::Output
where
L: LookupContinuation<Buf = R>,
{
loop {
let (load, continuation) = match l {
LookupResult::Output(output) => break output,
LookupResult::Load { load, continuation } => (load, continuation),
};
let mut r: Option<Arc<gimli::Dwarf<_>>> = None;
if let Some(dwp) = self.dwarf_package.as_ref() {
if let Ok(Some(cu)) = dwp.find_cu(load.dwo_id, &load.parent) {
r = Some(Arc::new(cu));
}
}
if r.is_none() {
let mut path = PathBuf::new();
if let Some(p) = load.comp_dir.as_ref() {
if let Ok(p) = convert_path(p) {
path.push(p);
}
}
if let Some(p) = load.path.as_ref() {
if let Ok(p) = convert_path(p) {
path.push(p);
}
}
if let Ok(file) = File::open(&path) {
if let Ok(map) = unsafe { memmap2::Mmap::map(&file) } {
if let Ok(file) = object::File::parse(&*map) {
let endian = if file.is_little_endian() {
gimli::RunTimeEndian::Little
} else {
gimli::RunTimeEndian::Big
};
r = gimli::Dwarf::load::<_, gimli::Error>(|id| {
Ok(load_section(id, &file, endian, &mut self.loader))
})
.ok()
.map(|mut dwo_dwarf| {
dwo_dwarf.make_dwo(&load.parent);
Arc::new(dwo_dwarf)
});
}
}
}
}
l = continuation.resume(r);
}
}
}
}
#[allow(clippy::unnecessary_cast)] #[allow(clippy::unnecessary_cast)]
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
pub fn asan_report(rt: &AsanGiovese, qemu: Qemu, pc: GuestAddr, err: AsanError) { pub fn asan_report(rt: &AsanGiovese, qemu: Qemu, pc: GuestAddr, err: AsanError) {
let mut regions = std::collections::HashMap::new(); let mut regions = HashMap::new();
for region in qemu.mappings() { for region in qemu.mappings() {
if let Some(path) = region.path() { if let Some(path) = region.path() {
let start = region.start(); let start = region.start();
@ -1365,7 +1536,7 @@ pub fn asan_report(rt: &AsanGiovese, qemu: Qemu, pc: GuestAddr, err: AsanError)
let mut ranges = RangeMap::new(); let mut ranges = RangeMap::new();
for (path, rng) in regions { for (path, rng) in regions {
let data = std::fs::read(&path); let data = fs::read(&path);
if data.is_err() { if data.is_err() {
continue; continue;
} }
@ -1378,7 +1549,7 @@ pub fn asan_report(rt: &AsanGiovese, qemu: Qemu, pc: GuestAddr, err: AsanError)
let arena_data = typed_arena::Arena::new(); let arena_data = typed_arena::Arena::new();
for img in &images { for img in &images {
if let Ok(obj) = addr2line::object::read::File::parse(&*img.1) { if let Ok(obj) = object::read::File::parse(&*img.1) {
let endian = if obj.is_little_endian() { let endian = if obj.is_little_endian() {
addr2line::gimli::RunTimeEndian::Little addr2line::gimli::RunTimeEndian::Little
} else { } else {
@ -1409,17 +1580,16 @@ pub fn asan_report(rt: &AsanGiovese, qemu: Qemu, pc: GuestAddr, err: AsanError)
let mut func = symbols.get(raddr).map(|x| x.name().to_string()); let mut func = symbols.get(raddr).map(|x| x.name().to_string());
if func.is_none() { if func.is_none() {
let pathname = std::path::PathBuf::from(images[*idx].0.clone()); let pathname = PathBuf::from(images[*idx].0.clone());
let mut split_dwarf_loader = let mut split_dwarf_loader = addr2line_legacy::SplitDwarfLoader::new(
addr2line::builtin_split_dwarf_loader::SplitDwarfLoader::new( |data, endian| {
|data, endian| { addr2line::gimli::EndianSlice::new(
addr2line::gimli::EndianSlice::new( arena_data.alloc(Cow::Owned(data.into_owned())),
arena_data.alloc(Cow::Owned(data.into_owned())), endian,
endian, )
) },
}, Some(pathname),
Some(pathname), );
);
let frames = ctx.find_frames(raddr); let frames = ctx.find_frames(raddr);
if let Ok(mut frames) = split_dwarf_loader.run(frames) { if let Ok(mut frames) = split_dwarf_loader.run(frames) {

View File

@ -11,6 +11,6 @@ anyhow = { version = "1.0", default-features = false }
clap = { version = "4.5", default-features = false, features = ["derive", "string", "std", "help", "derive", "error-context", "usage"] } clap = { version = "4.5", default-features = false, features = ["derive", "string", "std", "help", "derive", "error-context", "usage"] }
libc = {version = "0.2", default-features = false } libc = {version = "0.2", default-features = false }
log = { version = "0.4.20", default-features = false } log = { version = "0.4.20", default-features = false }
nix = { version = "0.27", default-features = false, features = ["signal", "fs"] } nix = { version = "0.29", default-features = false, features = ["signal", "fs"] }
readonly = { version = "0.2.8", default-features = false } readonly = { version = "0.2.8", default-features = false }
simplelog = { version = "0.12.1", default-features = false } simplelog = { version = "0.12.1", default-features = false }

View File

@ -13,7 +13,7 @@ crate-type = ["dylib"]
[dependencies] [dependencies]
anyhow = { version = "1.0", default-features = false } anyhow = { version = "1.0", default-features = false }
ctor = { version = "0.2", default-features = false } ctor = { version = "0.2", default-features = false }
nix = { version = "0.27", default-features = false, features = ["process", "personality"] } nix = { version = "0.29", default-features = false, features = ["process", "personality"] }
[target.'cfg(any(target_os = "freebsd", target_os = "netbsd"))'.dependencies] [target.'cfg(any(target_os = "freebsd", target_os = "netbsd"))'.dependencies]
libc = "0.2" libc = "0.2"

View File

@ -10,7 +10,7 @@ vergen = { version = "8.1.1", features = ["build", "cargo", "git", "gitcl", "rus
anyhow = { version = "1.0", default-features = false } anyhow = { version = "1.0", default-features = false }
clap = { version = "4.5", default-features = false, features = ["derive", "string", "std", "help", "derive", "error-context", "usage"] } clap = { version = "4.5", default-features = false, features = ["derive", "string", "std", "help", "derive", "error-context", "usage"] }
log = { version = "0.4.20", default-features = false } log = { version = "0.4.20", default-features = false }
nix = { version = "0.27", default-features = false, features = ["process", "personality"] } nix = { version = "0.29", default-features = false, features = ["process", "personality"] }
readonly = { version = "0.2.8", default-features = false } readonly = { version = "0.2.8", default-features = false }
simplelog = { version = "0.12.1", default-features = false } simplelog = { version = "0.12.1", default-features = false }