use common::*;
use std::fmt::{self, Debug};
#[derive(Copy,Clone,PartialEq,Eq)]
pub struct ImageSectionHeader {
pub name: [u8; 8],
pub physical_address: u32,
pub virtual_address: u32,
pub size_of_raw_data: u32,
pub pointer_to_raw_data: u32,
pub pointer_to_relocations: u32,
pub pointer_to_line_numbers: u32,
pub number_of_relocations: u16,
pub number_of_line_numbers: u16,
pub characteristics: u32,
}
impl ImageSectionHeader {
pub(crate) fn parse(parse_buffer: &mut ParseBuffer) -> Result<Self> {
let name_bytes = parse_buffer.take(8)?;
Ok(ImageSectionHeader{
name: [
name_bytes[0], name_bytes[1], name_bytes[2], name_bytes[3],
name_bytes[4], name_bytes[5], name_bytes[6], name_bytes[7]
],
physical_address: parse_buffer.parse_u32()?,
virtual_address: parse_buffer.parse_u32()?,
size_of_raw_data: parse_buffer.parse_u32()?,
pointer_to_raw_data: parse_buffer.parse_u32()?,
pointer_to_relocations: parse_buffer.parse_u32()?,
pointer_to_line_numbers: parse_buffer.parse_u32()?,
number_of_relocations: parse_buffer.parse_u16()?,
number_of_line_numbers: parse_buffer.parse_u16()?,
characteristics: parse_buffer.parse_u32()?,
})
}
pub fn name(&self) -> RawString {
let first_nul = self.name.iter().position(|ch| *ch == 0);
let name_bytes = &self.name[0..first_nul.unwrap_or(self.name.len())];
RawString::from(name_bytes)
}
}
impl Debug for ImageSectionHeader {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("ImageSectionHeader")
.field("name()", &self.name().to_string())
.field("physical_address", &format_args!("{:#x}", self.physical_address))
.field("virtual_address", &format_args!("{:#x}", self.virtual_address))
.field("size_of_raw_data", &self.size_of_raw_data)
.field("pointer_to_raw_data", &format_args!("{:#x}", self.pointer_to_raw_data))
.field("pointer_to_relocations", &format_args!("{:#x}", self.pointer_to_relocations))
.field("pointer_to_line_numbers", &format_args!("{:#x}", self.pointer_to_line_numbers))
.field("number_of_relocations", &self.number_of_relocations)
.field("number_of_line_numbers", &self.number_of_line_numbers)
.field("characteristics", &format_args!("{:#x}", self.characteristics))
.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn image_section_header() {
let bytes: Vec<u8> = vec![
0x2E, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00,
0x48, 0x35, 0x09, 0x00, 0x00, 0xD0, 0x1E, 0x00,
0x00, 0xFE, 0x00, 0x00, 0x00, 0xA2, 0x1E, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0xC8
];
let mut parse_buffer = ParseBuffer::from(bytes.as_slice());
let ish = ImageSectionHeader::parse(&mut parse_buffer).expect("parse");
assert_eq!(&ish.name, b".data\0\0\0");
assert_eq!(ish.name(), RawString::from(".data"));
assert_eq!(ish.physical_address, 0x93548);
assert_eq!(ish.virtual_address, 0x1ed000);
assert_eq!(ish.size_of_raw_data, 0xfe00);
assert_eq!(ish.pointer_to_raw_data, 0x1ea200);
assert_eq!(ish.pointer_to_relocations, 0);
assert_eq!(ish.pointer_to_line_numbers, 0);
assert_eq!(ish.number_of_relocations, 0);
assert_eq!(ish.number_of_line_numbers, 0);
assert_eq!(ish.characteristics, 0xc8000040);
}
}