Merge branch 'dev' of github.com:AFLplusplus/LibAFLrs into dev

This commit is contained in:
Andrea Fioraldi 2021-04-07 16:40:00 +02:00
commit 38f933fa04
25 changed files with 184 additions and 80 deletions

21
clippy.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/sh
# Clippy checks
cargo clean
RUST_BACKTRACE=full cargo clippy --all -- \
-D clippy::pedantic \
-W clippy::cast_sign_loss \
-W clippy::similar-names \
-W clippy::cast_ptr_alignment \
-A missing-docs \
-A clippy::doc_markdown \
-A clippy::must-use-candidate \
-A clippy::missing-errors-doc \
-A clippy::cast-possible-truncation \
-A clippy::used-underscore-binding \
-A clippy::ptr-as-ptr \
-A clippy::missing-panics-doc \
-A clippy::missing-docs-in-private-items \
-A clippy::unseparated-literal-suffix \
-A clippy::module-name-repetitions \
-A clippy::unreadable-literal \
-A clippy::if-not-else \

View File

@ -35,6 +35,7 @@ std = [] # print, sharedmap, ... support
anymapdbg = ["serde_json"] # uses serde_json to Debug the anymap trait. Disable for smaller footprint.
derive = ["libafl_derive"] # provide derive(SerdeAny) macro.
llmp_small_maps = [] # reduces initial map size for llmp
llmp_debug = [] # Enables debug output for LLMP
[[example]]
name = "llmp_test"
@ -56,6 +57,8 @@ serde_json = { version = "1.0", optional = true, default-features = false, featu
#TODO: for llmp brotli = { version = "3.3.0", default-features = false } # brotli compression
num_enum = "0.5.1"
backtrace = "0.3" # for llmp_debug
[target.'cfg(unix)'.dependencies]
libc = "0.2" # For (*nix) libc
nix = "0.20.0"

View File

@ -1,3 +1,5 @@
//! special handling to build and link libafl
fn main() {
#[cfg(target_os = "windows")]
windows::build!(

View File

@ -86,6 +86,9 @@ use std::os::unix::{
{io::AsRawFd, prelude::RawFd},
};
#[cfg(all(feature = "llmp_debug", feature = "std"))]
use backtrace::Backtrace;
#[cfg(all(unix, feature = "std"))]
use uds::{UnixListenerExt, UnixSocketAddr, UnixStreamExt};
@ -785,6 +788,21 @@ where
/// listener about it using a EOP message.
unsafe fn handle_out_eop(&mut self) -> Result<(), Error> {
#[cfg(all(feature = "llmp_debug", feature = "std"))]
{
#[cfg(debug_assertions)]
let bt = Backtrace::new();
#[cfg(not(debug_assertions))]
let bt = "<n/a (release)>";
let shm = self.out_maps.last().unwrap();
println!(
"LLMP_DEBUG: End of page reached for map {} with len {}, sending EOP, bt: {:?}",
shm.shmem.shm_str(),
shm.shmem.map().len(),
bt
);
}
let old_map = self.out_maps.last_mut().unwrap().page_mut();
// Create a new shard page.
@ -1024,8 +1042,12 @@ where
// Mark the new page save to unmap also (it's mapped by us, the broker now)
ptr::write_volatile(&mut (*page).save_to_unmap, 1);
#[cfg(feature = "std")]
dbg!("Got a new recv map", self.current_recv_map.shmem.shm_str());
#[cfg(all(feature = "llmp_debug", feature = "std"))]
println!(
"LLMP_DEBUG: Got a new recv map {} with len {:?}",
self.current_recv_map.shmem.shm_str(),
self.current_recv_map.shmem.map().len()
);
// After we mapped the new page, return the next message, if available
return self.recv();
}
@ -1064,6 +1086,7 @@ where
}
/// Returns the next message, tag, buf, if avaliable, else None
#[allow(clippy::type_complexity)]
#[inline]
pub fn recv_buf(&mut self) -> Result<Option<(u32, u32, &[u8])>, Error> {
unsafe {
@ -1134,6 +1157,13 @@ where
{
/// Creates a new page, initializing the passed shared mem struct
pub fn new(sender: u32, mut new_map: SH) -> Self {
#[cfg(all(feature = "llmp_debug", feature = "std"))]
println!(
"LLMP_DEBUG: Initializing map on {} with size {}",
new_map.shm_str(),
new_map.map().len()
);
unsafe {
_llmp_page_init(&mut new_map, sender, false);
}
@ -1142,6 +1172,20 @@ where
/// Maps and wraps an existing
pub fn existing(existing_map: SH) -> Self {
#[cfg(all(feature = "llmp_debug", feature = "std"))]
{
#[cfg(debug_assertions)]
let bt = Backtrace::new();
#[cfg(not(debug_assertions))]
let bt = "<n/a (release)>";
println!(
"LLMP_DEBUG: Using existing map {} with size {}, bt: {:?}",
existing_map.shm_str(),
existing_map.map().len(),
bt
);
}
let ret = Self {
shmem: existing_map,
};
@ -1824,6 +1868,7 @@ where
}
/// Returns the next message, tag, buf, if avaliable, else None
#[allow(clippy::type_complexity)]
#[inline]
pub fn recv_buf(&mut self) -> Result<Option<(u32, u32, &[u8])>, Error> {
self.receiver.recv_buf()

View File

@ -24,6 +24,7 @@ pub use libc::{c_void, siginfo_t};
#[derive(IntoPrimitive, TryFromPrimitive, Clone, Copy)]
#[repr(i32)]
#[allow(clippy::clippy::pub_enum_variant_names)]
pub enum Signal {
SigAbort = SIGABRT,
SigBus = SIGBUS,

View File

@ -356,6 +356,7 @@ pub mod unix_shmem {
}
/// Deinitialize this shmem instance
#[allow(clippy::clippy::clippy::unnecessary_cast)] // for c_ types
unsafe fn unix_shmem_deinit(shm: *mut UnixShMem) {
if shm.is_null() || (*shm).map.is_null() {
/* Serialized map id */
@ -369,6 +370,7 @@ pub mod unix_shmem {
/// Functions to create Shared memory region, for observation channels and
/// opening inputs and stuff.
#[allow(clippy::clippy::clippy::unnecessary_cast)] // for c_ types
unsafe fn unix_shmem_init(shm: *mut UnixShMem, map_size: usize) -> *mut c_uchar {
(*shm).map_size = map_size;
(*shm).map = ptr::null_mut();
@ -394,13 +396,14 @@ pub mod unix_shmem {
if (*shm).map == -(1 as c_int) as *mut c_void as *mut c_uchar || (*shm).map.is_null() {
shmctl((*shm).shm_id, 0 as c_int, ptr::null_mut());
(*shm).shm_id = -(1 as c_int);
(*shm).shm_str[0 as c_int as usize] = 0u8;
(*shm).shm_str[0] = 0u8;
return ptr::null_mut();
}
(*shm).map
}
/// Uses a shmap id string to open a shared map
#[allow(clippy::clippy::unnecessary_cast)] // for c_int and c_long
unsafe fn unix_shmem_by_str(
shm: *mut UnixShMem,
shm_str: &CStr,
@ -414,7 +417,7 @@ pub mod unix_shmem {
strncpy(
(*shm).shm_str.as_mut_ptr() as *mut c_char,
shm_str.as_ptr() as *const c_char,
(size_of::<[c_char; 20]>() as c_ulong).wrapping_sub(1 as c_int as c_ulong),
(size_of::<[c_char; 20]>() as c_ulong).wrapping_sub(1 as c_ulong),
);
(*shm).shm_id = shm_str
.to_str()

View File

@ -206,6 +206,7 @@ where
}
/// Handle arriving events in the broker
#[allow(clippy::clippy::unnecessary_wraps)]
fn handle_in_broker(
stats: &mut ST,
sender_id: u32,
@ -398,6 +399,7 @@ where
}
/// Deserialize the state and corpus tuple, previously serialized with `serialize_state_corpus(...)`
#[allow(clippy::type_complexity)]
pub fn deserialize_state_mgr<I, S, SH, ST>(
state_corpus_serialized: &[u8],
) -> Result<(S, LlmpEventManager<I, S, SH, ST>), Error>
@ -505,6 +507,7 @@ where
/// A restarting state is a combination of restarter and runner, that can be used on systems without `fork`.
/// The restarter will start a new process each time the child crashes or timeouts.
#[cfg(feature = "std")]
#[allow(clippy::clippy::unnecessary_operation, clippy::clippy::type_complexity)] // for { mgr = LlmpEventManager... }
pub fn setup_restarting_mgr<I, S, SH, ST>(
//mgr: &mut LlmpEventManager<I, S, SH, ST>,
stats: ST,
@ -534,43 +537,43 @@ where
println!("Doing broker things. Run this tool again to start fuzzing in a client.");
mgr.broker_loop()?;
return Err(Error::ShuttingDown);
} else {
// We are the fuzzer respawner in a llmp client
mgr.to_env(_ENV_FUZZER_BROKER_CLIENT_INITIAL);
}
// First, create a channel from the fuzzer (sender) to us (receiver) to report its state for restarts.
let sender = LlmpSender::new(0, false)?;
let receiver = LlmpReceiver::on_existing_map(
SH::clone_ref(&sender.out_maps.last().unwrap().shmem)?,
None,
)?;
// Store the information to a map.
sender.to_env(_ENV_FUZZER_SENDER)?;
receiver.to_env(_ENV_FUZZER_RECEIVER)?;
// We are the fuzzer respawner in a llmp client
mgr.to_env(_ENV_FUZZER_BROKER_CLIENT_INITIAL);
let mut ctr: u64 = 0;
// Client->parent loop
loop {
dbg!("Spawning next client (id {})", ctr);
// First, create a channel from the fuzzer (sender) to us (receiver) to report its state for restarts.
let sender = LlmpSender::new(0, false)?;
let receiver = LlmpReceiver::on_existing_map(
SH::clone_ref(&sender.out_maps.last().unwrap().shmem)?,
None,
)?;
// Store the information to a map.
sender.to_env(_ENV_FUZZER_SENDER)?;
receiver.to_env(_ENV_FUZZER_RECEIVER)?;
// On Unix, we fork (todo: measure if that is actually faster.)
#[cfg(unix)]
let _ = match unsafe { fork() }? {
ForkResult::Parent(handle) => handle.status(),
ForkResult::Child => break (sender, receiver),
};
let mut ctr: u64 = 0;
// Client->parent loop
loop {
dbg!("Spawning next client (id {})", ctr);
// On windows, we spawn ourself again
#[cfg(windows)]
startable_self()?.status()?;
// On Unix, we fork (todo: measure if that is actually faster.)
#[cfg(unix)]
let _ = match unsafe { fork() }? {
ForkResult::Parent(handle) => handle.status(),
ForkResult::Child => break (sender, receiver),
};
if unsafe { read_volatile(&(*receiver.current_recv_map.page()).size_used) } == 0 {
// Storing state in the last round did not work
panic!("Fuzzer-respawner: Storing state in crashed fuzzer instance did not work, no point to spawn the next client!");
}
// On windows, we spawn ourself again
#[cfg(windows)]
startable_self()?.status()?;
ctr = ctr.wrapping_add(1);
if unsafe { read_volatile(&(*receiver.current_recv_map.page()).size_used) } == 0 {
// Storing state in the last round did not work
panic!("Fuzzer-respawner: Storing state in crashed fuzzer instance did not work, no point to spawn the next client!");
}
ctr = ctr.wrapping_add(1);
}
} else {
// We are the newly started fuzzing instance, first, connect to our own restore map.

View File

@ -73,6 +73,7 @@ where
}
// Handle arriving events in the broker
#[allow(clippy::unnecessary_wraps)]
fn handle_in_broker(stats: &mut ST, event: &Event<I>) -> Result<BrokerEventResult, Error> {
match event {
Event::NewTestcase {

View File

@ -21,7 +21,7 @@ use crate::{
pub enum ExitKind {
Ok,
Crash,
OOM,
Oom,
Timeout,
}
@ -49,7 +49,7 @@ where
}
/// A simple executor that does nothing.
/// If intput len is 0, run_target will return Err
/// If intput len is 0, `run_target` will return Err
struct NopExecutor<I> {
phantom: PhantomData<I>,
}

View File

@ -1,4 +1,4 @@
//! A TimeoutExecutor set a timeout before each target run
//! A `TimeoutExecutor` sets a timeout before each target run
use core::{marker::PhantomData, time::Duration};

View File

@ -259,7 +259,7 @@ where
R: Reducer<T>,
O: MapObserver<T> + Observer,
{
/// Create new MapFeedback
/// Create new `MapFeedback`
pub fn new(name: &'static str, map_size: usize) -> Self {
Self {
history_map: vec![T::default(); map_size],
@ -270,7 +270,7 @@ where
}
}
/// Create new MapFeedback for the observer type.
/// Create new `MapFeedback` for the observer type.
pub fn new_with_observer(map_observer: &O) -> Self {
Self {
history_map: vec![T::default(); map_observer.map().len()],
@ -281,7 +281,7 @@ where
}
}
/// Create new MapFeedback specifying if it must track indexes of novelties
/// Create new `MapFeedback` specifying if it must track indexes of novelties
pub fn new_track(
name: &'static str,
map_size: usize,
@ -297,7 +297,7 @@ where
}
}
/// Create new MapFeedback for the observer type if it must track indexes of novelties
/// Create new `MapFeedback` for the observer type if it must track indexes of novelties
pub fn new_with_observer_track(
map_observer: &O,
track_indexes: bool,
@ -319,7 +319,7 @@ where
R: Reducer<T>,
O: MapObserver<T>,
{
/// Create new MapFeedback using a map observer, and a map.
/// Create new `MapFeedback` using a map observer, and a map.
/// The map can be shared.
pub fn with_history_map(name: &'static str, history_map: Vec<T>) -> Self {
Self {

View File

@ -24,7 +24,7 @@ pub trait Feedback<I>: Named + serde::Serialize + serde::de::DeserializeOwned +
where
I: Input,
{
/// is_interesting should return the "Interestingness" from 0 to 255 (percent times 2.55)
/// `is_interesting ` should return the "Interestingness" from 0 to 255 (percent times 2.55)
fn is_interesting<OT: ObserversTuple>(
&mut self,
input: &I,

View File

@ -96,7 +96,7 @@ pub trait Fuzzer<E, EM, S, CS> {
Ok(ret)
}
/// Given the last time, if stats_timeout seconds passed, send off an info/stats/heartbeat message to the broker.
/// Given the last time, if `stats_timeout` seconds passed, send off an info/stats/heartbeat message to the broker.
/// Returns the new `last` time (so the old one, unless `stats_timeout` time has passed and stats have been sent)
/// Will return an Error, if the stats could not be sent.
fn maybe_report_stats(

View File

@ -48,7 +48,7 @@ where
Ok(BytesInput::new(random_bytes))
}
/// Generates up to DUMMY_BYTES_MAX non-random dummy bytes (0)
/// Generates up to `DUMMY_BYTES_MAX` non-random dummy bytes (0)
fn generate_dummy(&self) -> BytesInput {
let size = min(self.max_size, DUMMY_BYTES_MAX);
BytesInput::new(vec![0; size])
@ -90,10 +90,10 @@ where
Ok(BytesInput::new(random_bytes))
}
/// Generates up to DUMMY_BYTES_MAX non-random dummy bytes (0)
/// Generates up to `DUMMY_BYTES_MAX` non-random dummy bytes (0)
fn generate_dummy(&self) -> BytesInput {
let size = min(self.max_size, DUMMY_BYTES_MAX);
BytesInput::new(vec![0u8; size])
BytesInput::new(vec![0_u8; size])
}
}

View File

@ -17,9 +17,9 @@ pub struct BytesInput {
impl Input for BytesInput {}
/// Rc Ref-cell from Input
impl Into<Rc<RefCell<Self>>> for BytesInput {
fn into(self) -> Rc<RefCell<Self>> {
Rc::new(RefCell::new(self))
impl From<BytesInput> for Rc<RefCell<BytesInput>> {
fn from(input: BytesInput) -> Self {
Rc::new(RefCell::new(input))
}
}

View File

@ -44,7 +44,7 @@ pub fn buffer_copy(dst: &mut [u8], src: &[u8], from: usize, to: usize, len: usiz
/// A simple buffer_set.
/// The compiler does the heavy lifting.
/// see https://stackoverflow.com/a/51732799/1345238
/// see <https://stackoverflow.com/a/51732799/1345238/>
#[inline]
fn buffer_set(data: &mut [u8], from: usize, len: usize, val: u8) {
debug_assert!(from + len <= data.len());

View File

@ -179,7 +179,7 @@ where
/// Create a new StdScheduledMutator instance specifying mutations
pub fn new(mutations: MT) -> Self {
StdScheduledMutator {
mutations: mutations,
mutations,
phantom: PhantomData,
}
}
@ -377,7 +377,7 @@ where
/// Create a new StdScheduledMutator instance without mutations and corpus
pub fn new(scheduled: SM) -> Self {
Self {
scheduled: scheduled,
scheduled,
mutation_log: vec![],
phantom: PhantomData,
}

View File

@ -49,6 +49,7 @@ impl Tokens {
/// Adds a token to a dictionary, checking it is not a duplicate
/// Returns `false` if the token was already present and did not get added.
#[allow(clippy::clippy::ptr_arg)]
pub fn add_token(&mut self, token: &Vec<u8>) -> bool {
if self.token_vec.contains(token) {
return false;

View File

@ -81,6 +81,7 @@ where
R: Rand,
{
mutator: M,
#[allow(clippy::type_complexity)]
phantom: PhantomData<(C, CS, E, EM, I, OT, R, S)>,
}

View File

@ -25,7 +25,7 @@ use crate::{
use crate::inputs::bytes::BytesInput;
/// The maximum size of a testcase
pub const DEFAULT_MAX_SIZE: usize = 1048576;
pub const DEFAULT_MAX_SIZE: usize = 1_048_576;
/// Trait for elements offering a corpus
pub trait HasCorpus<C, I>
@ -453,9 +453,8 @@ where
where
OT: ObserversTuple,
{
Ok(self
.feedbacks_mut()
.is_interesting_all(input, observers, exit_kind)?)
self.feedbacks_mut()
.is_interesting_all(input, observers, exit_kind)
}
/// Adds this input to the corpus, if it's intersting, and return the index

View File

@ -97,14 +97,14 @@ pub trait Stats {
fn corpus_size(&self) -> u64 {
self.client_stats()
.iter()
.fold(0u64, |acc, x| acc + x.corpus_size)
.fold(0_u64, |acc, x| acc + x.corpus_size)
}
/// Amount of elements in the objectives (combined for all children)
fn objective_size(&self) -> u64 {
self.client_stats()
.iter()
.fold(0u64, |acc, x| acc + x.objective_size)
.fold(0_u64, |acc, x| acc + x.objective_size)
}
/// Total executions
@ -112,7 +112,7 @@ pub trait Stats {
fn total_execs(&mut self) -> u64 {
self.client_stats()
.iter()
.fold(0u64, |acc, x| acc + x.executions)
.fold(0_u64, |acc, x| acc + x.executions)
}
/// Executions per second
@ -121,7 +121,7 @@ pub trait Stats {
let cur_time = current_time();
self.client_stats_mut()
.iter_mut()
.fold(0u64, |acc, x| acc + x.execs_per_sec(cur_time))
.fold(0_u64, |acc, x| acc + x.execs_per_sec(cur_time))
}
/// The client stats for a specific id, creating new if it doesn't exist

View File

@ -179,6 +179,7 @@ pub struct Xoshiro256StarRand {
}
impl Rand for Xoshiro256StarRand {
#[allow(clippy::clippy::unreadable_literal)]
fn set_seed(&mut self, seed: u64) {
self.rand_seed[0] = xxh3_64_with_seed(&HASH_CONST.to_le_bytes(), seed);
self.rand_seed[1] = self.rand_seed[0] ^ 0x1234567890abcdef;
@ -223,6 +224,7 @@ pub struct XorShift64Rand {
}
impl Rand for XorShift64Rand {
#[allow(clippy::clippy::unreadable_literal)]
fn set_seed(&mut self, seed: u64) {
self.rand_seed = seed ^ 0x1234567890abcdef;
}
@ -254,11 +256,13 @@ pub struct Lehmer64Rand {
}
impl Rand for Lehmer64Rand {
#[allow(clippy::clippy::unreadable_literal)]
fn set_seed(&mut self, seed: u64) {
self.rand_seed = (seed as u128) ^ 0x1234567890abcdef;
}
#[inline]
#[allow(clippy::clippy::unreadable_literal)]
fn next(&mut self) -> u64 {
self.rand_seed *= 0xda942042e4dd58b5;
(self.rand_seed >> 64) as u64
@ -303,6 +307,7 @@ impl Rand for RomuTrioRand {
}
#[inline]
#[allow(clippy::clippy::unreadable_literal)]
fn next(&mut self) -> u64 {
let xp = self.x_state;
let yp = self.y_state;
@ -339,6 +344,7 @@ impl Rand for RomuDuoJrRand {
}
#[inline]
#[allow(clippy::clippy::unreadable_literal)]
fn next(&mut self) -> u64 {
let xp = self.x_state;
self.x_state = 15241094284759029579u64.wrapping_mul(self.y_state);
@ -396,7 +402,7 @@ impl ChildHandle {
}
#[cfg(unix)]
/// The ForkResult
/// The `ForkResult` (result of a fork)
pub enum ForkResult {
Parent(ChildHandle),
Child,

View File

@ -1,36 +1,46 @@
//! Compiler Wrapper from `LibAFL`
use std::{process::Command, string::String, vec::Vec};
/// `LibAFL` CC Error Type
#[derive(Debug)]
pub enum Error {
/// CC Wrapper called with invalid arguments
InvalidArguments(String),
IOError(std::io::Error),
/// Io error occurred
Io(std::io::Error),
/// Something else happened
Unknown(String),
}
// TODO macOS
/// extension for static libraries
#[cfg(windows)]
pub const LIB_EXT: &'static str = "lib";
pub const LIB_EXT: &str = "lib";
/// extension for static libraries
#[cfg(not(windows))]
pub const LIB_EXT: &'static str = "a";
pub const LIB_EXT: &str = "a";
/// prefix for static libraries
#[cfg(windows)]
pub const LIB_PREFIX: &'static str = "";
pub const LIB_PREFIX: &str = "";
/// prefix for static libraries
#[cfg(not(windows))]
pub const LIB_PREFIX: &'static str = "lib";
pub const LIB_PREFIX: &str = "lib";
/// Wrap a compiler hijacking its arguments
pub trait CompilerWrapper {
/// Set the wrapper arguments parsing a command line set of arguments
fn from_args<'a>(&'a mut self, args: &[String]) -> Result<&'a mut Self, Error>;
fn from_args(&mut self, args: &[String]) -> Result<&'_ mut Self, Error>;
/// Add a compiler argument
fn add_arg<'a>(&'a mut self, arg: String) -> Result<&'a mut Self, Error>;
fn add_arg(&mut self, arg: String) -> Result<&'_ mut Self, Error>;
/// Add a compiler argument only when compiling
fn add_cc_arg<'a>(&'a mut self, arg: String) -> Result<&'a mut Self, Error>;
fn add_cc_arg(&mut self, arg: String) -> Result<&'_ mut Self, Error>;
/// Add a compiler argument only when linking
fn add_link_arg<'a>(&'a mut self, arg: String) -> Result<&'a mut Self, Error>;
fn add_link_arg(&mut self, arg: String) -> Result<&'_ mut Self, Error>;
/// Command to run the compiler
fn command(&mut self) -> Result<Vec<String>, Error>;
@ -42,14 +52,14 @@ pub trait CompilerWrapper {
fn run(&mut self) -> Result<(), Error> {
let args = self.command()?;
dbg!(&args);
if args.len() < 1 {
if args.is_empty() {
return Err(Error::InvalidArguments(
"The number of arguments cannot be 0".into(),
));
}
let status = match Command::new(&args[0]).args(&args[1..]).status() {
Ok(s) => s,
Err(e) => return Err(Error::IOError(e)),
Err(e) => return Err(Error::Io(e)),
};
dbg!(status);
Ok(())
@ -57,6 +67,7 @@ pub trait CompilerWrapper {
}
/// Wrap Clang
#[allow(clippy::clippy::struct_excessive_bools)]
pub struct ClangWrapper {
optimize: bool,
wrapped_cc: String,
@ -73,10 +84,11 @@ pub struct ClangWrapper {
link_args: Vec<String>,
}
#[allow(clippy::match_same_arms)] // for the linking = false wip for "shared"
impl CompilerWrapper for ClangWrapper {
fn from_args<'a>(&'a mut self, args: &[String]) -> Result<&'a mut Self, Error> {
let mut new_args = vec![];
if args.len() < 1 {
if args.is_empty() {
return Err(Error::InvalidArguments(
"The number of arguments cannot be 0".into(),
));
@ -122,17 +134,17 @@ impl CompilerWrapper for ClangWrapper {
Ok(self)
}
fn add_arg<'a>(&'a mut self, arg: String) -> Result<&'a mut Self, Error> {
fn add_arg(&mut self, arg: String) -> Result<&'_ mut Self, Error> {
self.base_args.push(arg);
Ok(self)
}
fn add_cc_arg<'a>(&'a mut self, arg: String) -> Result<&'a mut Self, Error> {
fn add_cc_arg(&mut self, arg: String) -> Result<&'_ mut Self, Error> {
self.cc_args.push(arg);
Ok(self)
}
fn add_link_arg<'a>(&'a mut self, arg: String) -> Result<&'a mut Self, Error> {
fn add_link_arg(&mut self, arg: String) -> Result<&'_ mut Self, Error> {
self.link_args.push(arg);
Ok(self)
}
@ -165,6 +177,8 @@ impl CompilerWrapper for ClangWrapper {
}
impl ClangWrapper {
/// Create a new Clang Wrapper
#[must_use]
pub fn new(wrapped_cc: &str, wrapped_cxx: &str) -> Self {
Self {
optimize: true,
@ -181,12 +195,14 @@ impl ClangWrapper {
}
}
pub fn dont_optimize<'a>(&'a mut self) -> &'a mut Self {
/// Disable optimizations
pub fn dont_optimize(&mut self) -> &'_ mut Self {
self.optimize = false;
self
}
pub fn is_cpp<'a>(&'a mut self) -> &'a mut Self {
/// set cpp mode
pub fn is_cpp(&mut self) -> &'_ mut Self {
self.is_cpp = true;
self
}

View File

@ -1,4 +1,4 @@
// build.rs
//! build.rs for `libafl_targets`
use std::env;
use std::path::Path;

View File

@ -1,3 +1,5 @@
//! `libafl_targets` contains runtime code, injected in the target itself during compilation.
#[cfg(any(feature = "pcguard_edges", feature = "pcguard_hitcounts"))]
pub mod pcguard;
#[cfg(any(feature = "pcguard_edges", feature = "pcguard_hitcounts"))]