Skip to content

Commit

Permalink
Merge pull request #44 from mjhouse/development
Browse files Browse the repository at this point in the history
Modified RelocationInfo to handle 32 and 64 bit relocations
  • Loading branch information
mjhouse authored Sep 5, 2023
2 parents 680d44e + a461304 commit c1d3fa8
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 45 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ cargo add deaf
Or by manually updating your cargo toml:

```bash
deaf = "0.1.0"
deaf = "0.1.2"
```

Then use it in your project like so:
Expand Down
4 changes: 4 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ pub enum Error {
#[error("Given section is of the wrong type")]
WrongSectionError,

/// Could not parse complex type from primitive
#[error("Could not convert from complex value")]
FromComplexError,

/// Could not parse complex type from primitive
#[error("Could not convert from primitive value")]
FromPrimitiveError(String),
Expand Down
116 changes: 73 additions & 43 deletions src/tables/info/relocation.rs
Original file line number Diff line number Diff line change
@@ -1,70 +1,69 @@
use crate::errors::Result;
use crate::errors::{Result, Error};
use crate::common::Convert;

/// Representation of the info field in a Relocation record
#[derive(Default,Clone,Copy,PartialEq)]
#[derive(Default,Debug,Clone,Copy,PartialEq)]
pub struct RelocationInfo {
symbol: u64,
kind: u8,
}

impl RelocationInfo {

/// Initialize an empty relocation info instance
pub fn empty() -> Self {
Self {
symbol: 0,
kind: 0
}
}

/// Parse a combined value as an info struct
pub fn new(v: u64) -> Result<Self> {
Ok(Self {
symbol: v >> 8,
kind: v as u8,
})
}

/// Get the combined value of the info struct
pub fn value(&self) -> u64 {
(self.symbol << 8) + (self.kind as u64)
fn new(symbol: u64, kind: u8) -> Self {
Self { symbol, kind }
}

/// Get the 'symbol' component of the info struct
pub fn symbol(&self) -> u64 {
self.symbol
}

/// Set the 'symbol' component of the info struct
pub fn set_symbol(&mut self, value: u64) {
self.symbol = value;
}

/// Get the 'kind' component of the info struct
pub fn kind(&self) -> u8 {
self.kind
}

/// Set the 'kind' component of the info struct
pub fn set_kind(&mut self, value: u8) {
self.kind = value;
}

}

impl Convert<u64> for RelocationInfo {
fn convert(self) -> Result<u64> { Ok(self.value()) }
fn convert(self) -> Result<u64> {
Ok((self.symbol as u64) << 32 | self.kind as u64)
}
}

impl Convert<u32> for RelocationInfo {
fn convert(self) -> Result<u32> { Ok(self.value().try_into()?) }
fn convert(self) -> Result<u32> {
Ok((self.symbol as u32) << 8 | self.kind as u32)
}
}

impl Convert<RelocationInfo> for u64 {
fn convert(self) -> Result<RelocationInfo> { RelocationInfo::new(self) }
fn convert(self) -> Result<RelocationInfo> {
Ok(RelocationInfo::new(
self >> 32,
self as u8)
)
}
}

impl Convert<RelocationInfo> for u32 {
fn convert(self) -> Result<RelocationInfo> { RelocationInfo::new(self.into()) }
}

impl std::fmt::Debug for RelocationInfo {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("RelocationInfo")
.field("symbol", &self.symbol())
.field("kind", &self.kind())
.finish()
fn convert(self) -> Result<RelocationInfo> {
Ok(RelocationInfo::new(
(self as u64) >> 8,
self as u8)
)
}
}

Expand All @@ -73,29 +72,46 @@ mod tests {
use super::*;

#[test]
fn test_relocation_info_parse_pair() {
fn test_relocation_info_parse_pair_32() {
// original value (0xfe000000 + 0x06)
let value: u32 = 0xfe000006;

// parse the relocation info from value
let result: Result<RelocationInfo> = value.convert();

// unwrap the relocation result
assert!(result.is_ok());
let info = result.unwrap();

// verify that fields have expected value
assert_eq!(info.symbol,0xfe0000);
assert_eq!(info.kind,0x06);
}

#[test]
fn test_relocation_info_parse_pair_64() {
// original value (0xfe000000 + 0x06)
let value = 0xfe00000006;
let value: u64 = 0xfe00000006;

// parse the relocation info from value
let result = RelocationInfo::new(value);
let result: Result<RelocationInfo> = value.convert();

// unwrap the relocation result
assert!(result.is_ok());
let info = result.unwrap();

// verify that fields have expected value
assert_eq!(info.symbol,0xfe000000);
assert_eq!(info.symbol,0xfe);
assert_eq!(info.kind,0x06);
}

#[test]
fn test_relocation_info_parse_zeroes() {
// original value
let value = 0x0000000000;
let value: u64 = 0x0000000000;

// parse the relocation info from value
let result = RelocationInfo::new(value);
let result: Result<RelocationInfo> = value.convert();

// unwrap the relocation result
assert!(result.is_ok());
Expand All @@ -109,10 +125,10 @@ mod tests {
#[test]
fn test_relocation_info_back_to_zeroes() {
// original value
let value = 0x0000000000;
let value: u64 = 0x0000000000;

// parse the relocation info and then convert back
let info = RelocationInfo::new(value).unwrap();
let info: RelocationInfo = value.convert().unwrap();
let result: Result<u64> = info.convert();

// verify that the result matches the original
Expand All @@ -121,12 +137,26 @@ mod tests {
}

#[test]
fn test_relocation_info_back_to_value() {
fn test_relocation_info_back_to_value_32() {
// original value
let value: u32 = 0xfe000006;

// parse the relocation info and then convert back
let info: RelocationInfo = value.convert().unwrap();
let result: Result<u32> = info.convert();

// verify that the result matches the original
assert!(result.is_ok());
assert_eq!(result.unwrap(),value);
}

#[test]
fn test_relocation_info_back_to_value_64() {
// original value
let value = 0xfe00000006;
let value: u64 = 0xfe00000006;

// parse the relocation info and then convert back
let info = RelocationInfo::new(value).unwrap();
let info: RelocationInfo = value.convert().unwrap();
let result: Result<u64> = info.convert();

// verify that the result matches the original
Expand Down
2 changes: 1 addition & 1 deletion src/tables/items/relocation.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::common::{Width,Layout,Item,ranges::*};
use crate::tables::info::RelocationInfo;
use crate::tables::info::{RelocationInfo};
use crate::tables::TableItem;
use crate::errors::Result;

Expand Down

0 comments on commit c1d3fa8

Please sign in to comment.