diff options
| author | KyleMiles <krm504@nyu.edu> | 2023-08-30 10:34:03 -0400 |
|---|---|---|
| committer | KyleMiles <krm504@nyu.edu> | 2023-08-30 10:37:57 -0400 |
| commit | 6a6d93ba92252bbf1f66850f6384771ed0de4343 (patch) | |
| tree | efd94abcd48b59ddb3e25d41093ced64f7393a9d /rust/examples/dwarf/shared/src | |
| parent | 9202af38c7d0d894038be4192e0a90294a7c07aa (diff) | |
DWARF Import : >450,000% Performance Improvement
Diffstat (limited to 'rust/examples/dwarf/shared/src')
| -rw-r--r-- | rust/examples/dwarf/shared/src/lib.rs | 169 |
1 files changed, 13 insertions, 156 deletions
diff --git a/rust/examples/dwarf/shared/src/lib.rs b/rust/examples/dwarf/shared/src/lib.rs index fd141f1f..0bf11771 100644 --- a/rust/examples/dwarf/shared/src/lib.rs +++ b/rust/examples/dwarf/shared/src/lib.rs @@ -1,4 +1,4 @@ -// Copyright 2021-2022 Vector 35 Inc. +// Copyright 2021-2023 Vector 35 Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use gimli::{Endianity, Error, Reader, ReaderOffsetId, RunTimeEndian, SectionId}; +use gimli::{EndianRcSlice, Endianity, Error, RunTimeEndian, SectionId}; use binaryninja::binaryninjacore_sys::*; @@ -22,10 +22,7 @@ use binaryninja::{ Endianness, }; -use std::borrow::Cow; -use std::convert::TryInto; -use std::ffi::CString; -use std::{fmt, str}; +use std::{ffi::CString, rc::Rc}; ////////////////////// // Dwarf Validation @@ -69,155 +66,12 @@ pub fn get_endian(view: &BinaryView) -> RunTimeEndian { } } -#[derive(Clone)] -pub struct DWARFReader<Endian: Endianity> { - data: Vec<u8>, - endian: Endian, - data_offset: usize, - section_offset: usize, -} - -impl<Endian: Endianity> DWARFReader<Endian> { - pub fn new(data: Vec<u8>, endian: Endian) -> Self { - Self { - data, - endian, - data_offset: 0, - section_offset: 0, - } - } -} - -impl<Endian: Endianity> fmt::Debug for DWARFReader<Endian> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let data = if self.data.len() < 6 { - self.data.clone() - } else { - let mut vec = vec![0; 6]; - vec.clone_from_slice(&self.data[0..6]); - vec - }; - f.debug_struct("DWARFReader") - .field("data", &data) - .field("endian", &self.endian) - .field("data_offset", &self.data_offset) - .field("section_offset", &self.section_offset) - .finish() - } -} - -impl<Endian: Endianity> Reader for DWARFReader<Endian> { - type Endian = Endian; - type Offset = usize; - - fn endian(&self) -> Endian { - self.endian - } - - fn len(&self) -> usize { - self.data.len() - self.data_offset - } - - fn empty(&mut self) { - self.data.clear(); - self.data_offset = 0; - } - - fn truncate(&mut self, len: usize) -> Result<(), Error> { - self.data.truncate(self.data_offset + len); - Ok(()) - } - - fn offset_from(&self, base: &Self) -> usize { - (self.section_offset + self.data_offset) - (base.section_offset + base.data_offset) - } - - fn offset_id(&self) -> ReaderOffsetId { - ReaderOffsetId(self.data_offset.try_into().unwrap()) - } - - fn lookup_offset_id(&self, id: ReaderOffsetId) -> Option<usize> { - Some(id.0.try_into().unwrap()) - } - - fn find(&self, byte: u8) -> Result<usize, Error> { - match self - .data - .iter() - .skip(self.data_offset) - .position(|&b| b == byte) - { - Some(value) => Ok(value), - _ => Err(Error::UnexpectedEof(self.offset_id())), - } - } - - fn skip(&mut self, len: usize) -> Result<(), Error> { - if self.data.len() < self.data_offset + len { - Err(Error::UnexpectedEof(self.offset_id())) - } else { - self.data_offset += len; - Ok(()) - } - } - - fn split(&mut self, len: usize) -> Result<Self, Error> { - if self.data.len() < self.data_offset + len { - unreachable!(); - // Err(Error::UnexpectedEof(self.offset_id())) - } else { - self.data_offset += len; - - Ok(Self { - data: self.data[(self.data_offset - len)..self.data_offset].to_vec(), - endian: self.endian, - data_offset: 0, - section_offset: self.section_offset + self.data_offset - len, - }) - } - } - - fn to_slice(&self) -> Result<Cow<'_, [u8]>, Error> { - Ok(self.data[self.data_offset..].into()) - } - - fn to_string(&self) -> Result<Cow<'_, str>, Error> { - Ok(str::from_utf8(&self.data[self.data_offset..]) - .unwrap() - .into()) - } - - fn to_string_lossy(&self) -> Result<Cow<'_, str>, Error> { - Ok(str::from_utf8(&self.data[self.data_offset..]) - .unwrap() - .into()) - } - - fn read_slice(&mut self, buf: &mut [u8]) -> Result<(), Error> { - if self.len() >= 4 { - let mut vec = vec![0; 4]; - vec.clone_from_slice(&self.data[self.data_offset..self.data_offset + 4]); - } - - if self.data.len() < self.data_offset + buf.len() { - Err(Error::UnexpectedEof(self.offset_id())) - } else { - for b in buf { - *b = self.data[self.data_offset]; - self.data_offset += 1; - } - - Ok(()) - } - } -} - pub fn create_section_reader<'a, Endian: 'a + Endianity>( section_id: SectionId, view: &'a BinaryView, endian: Endian, dwo_file: bool, -) -> Result<DWARFReader<Endian>, Error> { +) -> Result<EndianRcSlice<Endian>, Error> { let section_name = if dwo_file && section_id.dwo_name().is_some() { section_id.dwo_name().unwrap() } else { @@ -276,7 +130,7 @@ pub fn create_section_reader<'a, Endian: 'a + Endianity>( let output_buffer: DataBuffer = unsafe { std::mem::transmute(raw_buf) }; - return Ok(DWARFReader::new( + return Ok(EndianRcSlice::new( output_buffer.get_data().into(), endian, )); @@ -289,16 +143,19 @@ pub fn create_section_reader<'a, Endian: 'a + Endianity>( let offset = section.start(); let len = section.len(); if len == 0 { - Ok(DWARFReader::new(vec![], endian)) + Ok(EndianRcSlice::new(Rc::from([]), endian)) } else { - Ok(DWARFReader::new(view.read_vec(offset, len), endian)) + Ok(EndianRcSlice::new( + Rc::from(view.read_vec(offset, len).as_slice()), + endian, + )) } } else if let Ok(section) = view.section_by_name("__".to_string() + §ion_name[1..]) { - Ok(DWARFReader::new( - view.read_vec(section.start(), section.len()), + Ok(EndianRcSlice::new( + Rc::from(view.read_vec(section.start(), section.len()).as_slice()), endian, )) } else { - Ok(DWARFReader::new(vec![], endian)) + Ok(EndianRcSlice::new(Rc::from([]), endian)) } } |
