summaryrefslogtreecommitdiff
path: root/rust/examples/dwarf/shared/src
diff options
context:
space:
mode:
authorKyleMiles <krm504@nyu.edu>2023-08-30 10:34:03 -0400
committerKyleMiles <krm504@nyu.edu>2023-08-30 10:37:57 -0400
commit6a6d93ba92252bbf1f66850f6384771ed0de4343 (patch)
treeefd94abcd48b59ddb3e25d41093ced64f7393a9d /rust/examples/dwarf/shared/src
parent9202af38c7d0d894038be4192e0a90294a7c07aa (diff)
DWARF Import : >450,000% Performance Improvement
Diffstat (limited to 'rust/examples/dwarf/shared/src')
-rw-r--r--rust/examples/dwarf/shared/src/lib.rs169
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() + &section_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))
}
}