summaryrefslogtreecommitdiffstats
path: root/third_party/rust/goblin/src/pe/section_table.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/goblin/src/pe/section_table.rs')
-rw-r--r--third_party/rust/goblin/src/pe/section_table.rs41
1 files changed, 39 insertions, 2 deletions
diff --git a/third_party/rust/goblin/src/pe/section_table.rs b/third_party/rust/goblin/src/pe/section_table.rs
index 4491827f16..f49c2b689c 100644
--- a/third_party/rust/goblin/src/pe/section_table.rs
+++ b/third_party/rust/goblin/src/pe/section_table.rs
@@ -1,6 +1,8 @@
use crate::error::{self, Error};
use crate::pe::relocation;
+use alloc::borrow::Cow;
use alloc::string::{String, ToString};
+use alloc::vec::Vec;
use scroll::{ctx, Pread, Pwrite};
#[repr(C)]
@@ -79,6 +81,32 @@ impl SectionTable {
Ok(table)
}
+ pub fn data<'a, 'b: 'a>(&'a self, pe_bytes: &'b [u8]) -> error::Result<Option<Cow<[u8]>>> {
+ let section_start: usize = self.pointer_to_raw_data.try_into().map_err(|_| {
+ Error::Malformed(format!("Virtual address cannot fit in platform `usize`"))
+ })?;
+
+ // assert!(self.virtual_size <= self.size_of_raw_data);
+ // if vsize > size_of_raw_data, the section is zero padded.
+ let section_end: usize = section_start
+ + usize::try_from(self.size_of_raw_data).map_err(|_| {
+ Error::Malformed(format!("Virtual size cannot fit in platform `usize`"))
+ })?;
+
+ let original_bytes = pe_bytes.get(section_start..section_end).map(Cow::Borrowed);
+
+ if original_bytes.is_some() && self.virtual_size > self.size_of_raw_data {
+ let mut bytes: Vec<u8> = Vec::new();
+ bytes.resize(self.size_of_raw_data.try_into()?, 0);
+ bytes.copy_from_slice(&original_bytes.unwrap());
+ bytes.resize(self.virtual_size.try_into()?, 0);
+
+ Ok(Some(Cow::Owned(bytes)))
+ } else {
+ Ok(original_bytes)
+ }
+ }
+
pub fn name_offset(&self) -> error::Result<Option<usize>> {
// Based on https://github.com/llvm-mirror/llvm/blob/af7b1832a03ab6486c42a40d21695b2c03b2d8a3/lib/Object/COFFObjectFile.cpp#L1054
if self.name[0] == b'/' {
@@ -163,6 +191,15 @@ impl SectionTable {
let number = self.number_of_relocations as usize;
relocation::Relocations::parse(bytes, offset, number)
}
+
+ /// Tests if `another_section` on-disk ranges will collide.
+ pub fn overlaps_with(&self, another_section: &SectionTable) -> bool {
+ let self_end = self.pointer_to_raw_data + self.size_of_raw_data;
+ let another_end = another_section.pointer_to_raw_data + another_section.size_of_raw_data;
+
+ !((self_end <= another_section.pointer_to_raw_data)
+ || (another_end <= self.pointer_to_raw_data))
+ }
}
impl ctx::SizeWith<scroll::Endian> for SectionTable {
@@ -171,7 +208,7 @@ impl ctx::SizeWith<scroll::Endian> for SectionTable {
}
}
-impl ctx::TryIntoCtx<scroll::Endian> for SectionTable {
+impl ctx::TryIntoCtx<scroll::Endian> for &SectionTable {
type Error = error::Error;
fn try_into_ctx(self, bytes: &mut [u8], ctx: scroll::Endian) -> Result<usize, Self::Error> {
let offset = &mut 0;
@@ -189,7 +226,7 @@ impl ctx::TryIntoCtx<scroll::Endian> for SectionTable {
}
}
-impl ctx::IntoCtx<scroll::Endian> for SectionTable {
+impl ctx::IntoCtx<scroll::Endian> for &SectionTable {
fn into_ctx(self, bytes: &mut [u8], ctx: scroll::Endian) {
bytes.pwrite_with(self, 0, ctx).unwrap();
}