diff --git a/afl/src/corpus/mod.rs b/afl/src/corpus/mod.rs index f0ff8f247d..8a000cfadd 100644 --- a/afl/src/corpus/mod.rs +++ b/afl/src/corpus/mod.rs @@ -33,11 +33,13 @@ where R: Rand, { /// Returns the number of elements + #[inline] fn count(&self) -> usize { self.entries().len() } /// Add an entry to the corpus and return its index + #[inline] fn add(&mut self, testcase: Testcase) -> usize { self.entries_mut().push(RefCell::new(testcase)); self.entries().len() - 1 @@ -56,11 +58,13 @@ where } /// Get by id + #[inline] fn get(&self, idx: usize) -> &RefCell> { &self.entries()[idx] } /// Removes an entry from the corpus, returning it if it was present. + #[inline] fn remove(&mut self, entry: &Testcase) -> Option> { match self .entries() @@ -73,6 +77,7 @@ where } /// Gets a random entry + #[inline] fn random_entry(&self, rand: &mut R) -> Result<(&RefCell>, usize), AflError> { if self.count() == 0 { Err(AflError::Empty("No entries in corpus".to_owned())) @@ -142,6 +147,7 @@ where R: Rand, { /// Gets the next entry + #[inline] fn next(&mut self, rand: &mut R) -> Result<(&RefCell>, usize), AflError> { if self.count() == 0 { Err(AflError::Empty("No entries in corpus".to_owned())) @@ -154,6 +160,7 @@ where } /// Returns the testacase we currently use + #[inline] fn current_testcase(&self) -> (&RefCell>, usize) { (self.get(self.pos), self.pos) } @@ -192,9 +199,11 @@ where I: Input, R: Rand, { + #[inline] fn entries(&self) -> &[RefCell>] { &self.entries } + #[inline] fn entries_mut(&mut self) -> &mut Vec>> { &mut self.entries } @@ -221,11 +230,13 @@ where self.entries.len() - 1 } + #[inline] fn current_testcase(&self) -> (&RefCell>, usize) { (self.get(self.pos), self.pos) } /// Gets the next entry + #[inline] fn next(&mut self, rand: &mut R) -> Result<(&RefCell>, usize), AflError> { if self.count() == 0 { Err(AflError::Empty("No entries in corpus".to_owned())) @@ -275,9 +286,11 @@ where I: Input, R: Rand, { + #[inline] fn entries(&self) -> &[RefCell>] { self.corpus.entries() } + #[inline] fn entries_mut(&mut self) -> &mut Vec>> { self.corpus.entries_mut() } @@ -290,30 +303,36 @@ where R: Rand, { /// Returns the number of elements + #[inline] fn count(&self) -> usize { self.corpus.count() } + #[inline] fn add(&mut self, entry: Testcase) -> usize { self.corpus.add(entry) } /// Removes an entry from the corpus, returning it if it was present. + #[inline] fn remove(&mut self, entry: &Testcase) -> Option> { self.corpus.remove(entry) } /// Gets a random entry + #[inline] fn random_entry(&self, rand: &mut R) -> Result<(&RefCell>, usize), AflError> { self.corpus.random_entry(rand) } /// Returns the testacase we currently use + #[inline] fn current_testcase(&self) -> (&RefCell>, usize) { (self.get(self.pos - 1), self.pos - 1) } /// Gets the next entry + #[inline] fn next(&mut self, _rand: &mut R) -> Result<(&RefCell>, usize), AflError> { self.pos += 1; if self.corpus.count() == 0 { @@ -343,10 +362,12 @@ where } } + #[inline] pub fn cycles(&self) -> u64 { self.cycles } + #[inline] pub fn pos(&self) -> usize { self.pos } diff --git a/afl/src/corpus/testcase.rs b/afl/src/corpus/testcase.rs index bf1925e26e..3d0730ac74 100644 --- a/afl/src/corpus/testcase.rs +++ b/afl/src/corpus/testcase.rs @@ -84,49 +84,67 @@ where } /// Get the input, if any + #[inline] pub fn input(&self) -> &Option { &self.input } + /// Get the input, if any (mutable) + #[inline] pub fn input_mut(&mut self) -> &mut Option { &mut self.input } + /// Set the input + #[inline] pub fn set_input(&mut self, input: I) { self.input = Some(input); } /// Get the filename, if any + #[inline] pub fn filename(&self) -> &Option { &self.filename } + /// Get the filename, if any (mutable) + #[inline] pub fn filename_mut(&mut self) -> &mut Option { &mut self.filename } + /// Set the filename + #[inline] pub fn set_filename(&mut self, filename: String) { self.filename = Some(filename); } /// Get the fitness + #[inline] pub fn fitness(&self) -> u32 { self.fitness } + /// Get the fitness (mutable) + #[inline] pub fn fitness_mut(&mut self) -> &mut u32 { &mut self.fitness } + /// Set the fitness + #[inline] pub fn set_fitness(&mut self, fitness: u32) { self.fitness = fitness; } /// Get all the metadatas into an HashMap (mutable) + #[inline] pub fn metadatas(&mut self) -> &mut SerdeAnyMap { &mut self.metadatas } + /// Add a metadata + #[inline] pub fn add_metadata(&mut self, meta: TM) where TM: TestcaseMetadata + 'static, @@ -135,6 +153,7 @@ where } /// Create a new Testcase instace given an input + #[inline] pub fn new(input: T) -> Self where T: Into, @@ -148,6 +167,7 @@ where } /// Create a new Testcase instace given an input and a filename + #[inline] pub fn with_filename(input: I, filename: String) -> Self { Testcase { input: Some(input), @@ -157,6 +177,7 @@ where } } + #[inline] pub fn default() -> Self { Testcase { input: None, diff --git a/afl/src/engines/mod.rs b/afl/src/engines/mod.rs index 632156c397..1432ddcdb4 100644 --- a/afl/src/engines/mod.rs +++ b/afl/src/engines/mod.rs @@ -44,22 +44,27 @@ where R: Rand, { /// Get executions + #[inline] pub fn executions(&self) -> usize { self.executions } /// Set executions + #[inline] pub fn set_executions(&mut self, executions: usize) { self.executions = executions } + #[inline] pub fn start_time(&self) -> u64 { self.start_time } + #[inline] pub fn set_start_time(&mut self, ms: u64) { self.start_time = ms } + #[inline] pub fn executions_over_seconds(&self) -> u64 { let elapsed = current_milliseconds() - self.start_time(); if elapsed == 0 { @@ -74,31 +79,37 @@ where } /// Get all the metadatas into an HashMap + #[inline] pub fn metadatas(&self) -> &HashMap<&'static str, Box> { &self.metadatas } /// Get all the metadatas into an HashMap (mutable) + #[inline] pub fn metadatas_mut(&mut self) -> &mut HashMap<&'static str, Box> { &mut self.metadatas } /// Add a metadata + #[inline] pub fn add_metadata(&mut self, meta: Box) { self.metadatas_mut().insert(meta.name(), meta); } /// Returns vector of feebacks + #[inline] pub fn feedbacks(&self) -> &[Box>] { &self.feedbacks } /// Returns vector of feebacks (mutable) + #[inline] pub fn feedbacks_mut(&mut self) -> &mut Vec>> { &mut self.feedbacks } /// Adds a feedback + #[inline] pub fn add_feedback(&mut self, feedback: Box>) { self.feedbacks_mut().push(feedback); } @@ -124,6 +135,7 @@ where } /// Resets all current feedbacks + #[inline] pub fn discard_input(&mut self, input: &I) -> Result<(), AflError> { // TODO: This could probably be automatic in the feedback somehow? for feedback in self.feedbacks_mut() { @@ -133,6 +145,7 @@ where } /// Creates a new testcase, appending the metadata from each feedback + #[inline] pub fn input_to_testcase(&mut self, input: I, fitness: u32) -> Result, AflError> { let mut testcase = Testcase::new(input); testcase.set_fitness(fitness); @@ -144,6 +157,7 @@ where } /// Create a testcase from this input, if it's intersting + #[inline] pub fn testcase_if_interesting( &mut self, input: I, @@ -158,6 +172,7 @@ where } /// Adds this input to the corpus, if it's intersting + #[inline] pub fn add_if_interesting( &mut self, corpus: &mut C, diff --git a/afl/src/events/llmp.rs b/afl/src/events/llmp.rs index 25530467d0..9e32558e32 100644 --- a/afl/src/events/llmp.rs +++ b/afl/src/events/llmp.rs @@ -164,6 +164,7 @@ impl LlmpMsg { } /// Gets the buffer from this message as slice, with the corrent length. + #[inline] pub fn as_slice(&self, map: &LlmpSharedMap) -> Result<&[u8], AflError> { unsafe { if self.in_map(map) { @@ -175,6 +176,7 @@ impl LlmpMsg { } /// Returns true, if the pointer is, indeed, in the page of this shared map. + #[inline] pub fn in_map(&self, map: &LlmpSharedMap) -> bool { unsafe { let buf_ptr = self.buf.as_ptr(); @@ -286,6 +288,7 @@ unsafe fn shmem2page(afl_shmem: &AflShmem) -> *mut LlmpPage { } /// Return, if a msg is contained in the current page +#[inline] unsafe fn llmp_msg_in_page(page: *mut LlmpPage, msg: *mut LlmpMsg) -> bool { /* DBG("llmp_msg_in_page %p within %p-%p\n", msg, page, page + page->size_total); */ return (page as *mut u8) < msg as *mut u8 @@ -506,6 +509,7 @@ impl LlmpSender { /// Commit the message last allocated by alloc_next to the queue. /// After commiting, the msg shall no longer be altered! /// It will be read by the consuming threads (broker->clients or client->broker) + #[inline(never)] // Not inlined to make cpu-level reodering (hopefully?) improbable unsafe fn send(&mut self, msg: *mut LlmpMsg) -> Result<(), AflError> { if self.last_msg_sent == msg { panic!("Message sent twice!"); @@ -720,6 +724,7 @@ impl LlmpReceiver { } /// Returns the next message, tag, buf, if avaliable, else None + #[inline] pub fn recv_buf(&mut self) -> Result, AflError> { unsafe { Ok(match self.recv()? { @@ -730,6 +735,7 @@ impl LlmpReceiver { } /// Returns the next message, tag, buf, looping until it becomes available + #[inline] pub fn recv_buf_blocking(&mut self) -> Result<(u32, &[u8]), AflError> { unsafe { let msg = self.recv_blocking()?; @@ -827,6 +833,7 @@ impl LlmpBroker { } /// broker broadcast to its own page for all others to read */ + #[inline] unsafe fn handle_new_msgs(&mut self, client_id: u32) -> Result<(), AflError> { let mut next_id = self.llmp_clients.len() as u32; @@ -885,6 +892,7 @@ impl LlmpBroker { /// The broker walks all pages and looks for changes, then broadcasts them on /// its own shared page, once. + #[inline] pub fn once(&mut self) -> Result<(), AflError> { compiler_fence(Ordering::SeqCst); for i in 0..self.llmp_clients.len() { @@ -1070,28 +1078,33 @@ impl LlmpClient { /// A client receives a broadcast message. /// Returns null if no message is availiable + #[inline] pub unsafe fn recv(&mut self) -> Result, AflError> { self.llmp_in.recv() } /// A client blocks/spins until the next message gets posted to the page, /// then returns that message. + #[inline] pub unsafe fn recv_blocking(&mut self) -> Result<*mut LlmpMsg, AflError> { self.llmp_in.recv_blocking() } /// The current page could have changed in recv (EOP) /// Alloc the next message, internally handling end of page by allocating a new one. + #[inline] pub unsafe fn alloc_next(&mut self, buf_len: usize) -> Result<*mut LlmpMsg, AflError> { self.llmp_out.alloc_next(buf_len) } /// Returns the next message, tag, buf, if avaliable, else None + #[inline] pub fn recv_buf(&mut self) -> Result, AflError> { self.llmp_in.recv_buf() } /// Receives a buf from the broker, looping until a messages becomes avaliable + #[inline] pub fn recv_buf_blocking(&mut self) -> Result<(u32, &[u8]), AflError> { self.llmp_in.recv_buf_blocking() } diff --git a/afl/src/feedbacks/mod.rs b/afl/src/feedbacks/mod.rs index b7d49ed8f5..988e54f5be 100644 --- a/afl/src/feedbacks/mod.rs +++ b/afl/src/feedbacks/mod.rs @@ -27,11 +27,13 @@ where fn is_interesting(&mut self, input: &I, observers: &NamedSerdeAnyMap) -> Result; /// Append to the testcase the generated metadata in case of a new corpus item + #[inline] fn append_metadata(&mut self, _testcase: &mut Testcase) -> Result<(), AflError> { Ok(()) } /// Discard the stored metadata in case that the testcase is not added to the corpus + #[inline] fn discard_metadata(&mut self, _input: &I) -> Result<(), AflError> { Ok(()) } diff --git a/afl/src/mutators/scheduled.rs b/afl/src/mutators/scheduled.rs index 62ee7df245..2ad35f4551 100644 --- a/afl/src/mutators/scheduled.rs +++ b/afl/src/mutators/scheduled.rs @@ -14,6 +14,7 @@ where R: Rand, { /// Compute the number of iterations used to apply stacked mutations + #[inline] fn iterations(&mut self, rand: &mut R, _input: &I) -> u64 { 1 << (1 + rand.below(6)) } @@ -113,9 +114,12 @@ where I: Input, R: Rand, { + #[inline] fn max_size(&self) -> usize { self.max_size } + + #[inline] fn set_max_size(&mut self, max_size: usize) { self.max_size = max_size; } diff --git a/afl/src/observers/mod.rs b/afl/src/observers/mod.rs index e4ab5b8f1b..fdcd1c0020 100644 --- a/afl/src/observers/mod.rs +++ b/afl/src/observers/mod.rs @@ -13,12 +13,16 @@ use crate::AflError; /// Observers observe different information about the target. /// They can then be used by various sorts of feedback. pub trait Observer: SerdeAny + 'static { + + /// The testcase finished execution, calculate any changes. + #[inline] fn flush(&mut self) -> Result<(), AflError> { Ok(()) } fn reset(&mut self) -> Result<(), AflError>; + #[inline] fn post_exec(&mut self) -> Result<(), AflError> { Ok(()) } @@ -49,6 +53,7 @@ where fn set_initial(&mut self, initial: T); /// Reset the map + #[inline] fn reset_map(&mut self) -> Result<(), AflError> { // Normal memset, see https://rust.godbolt.org/z/Trs5hv let initial = self.initial();