1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
use error::Error; use types; use header::Header; use std::io::BufWriter; use std::io::{Read, Write}; use num_traits::{FromPrimitive, ToPrimitive}; #[derive(Default, Debug, Clone)] pub struct SegmentHeader { pub phtype: types::SegmentType, pub flags: types::SegmentFlags, pub offset: u64, pub vaddr: u64, pub paddr: u64, pub filesz: u64, pub memsz: u64, pub align: u64, } impl SegmentHeader { pub fn entsize(eh: &Header) -> usize { match eh.ident_class { types::Class::Class64 => 4 + 4 + 6 * 8, types::Class::Class32 => 4 + 4 + 6 * 4, } } pub fn from_reader<R>(io: &mut R, eh: &Header) -> Result<SegmentHeader, Error> where R: Read, { let mut r = SegmentHeader::default(); let reb = elf_read_u32!(eh, io)?; r.phtype = match types::SegmentType::from_u32(reb) { Some(v) => v, None => return Err(Error::InvalidSegmentType(reb)), }; match eh.ident_class { types::Class::Class64 => { r.flags = types::SegmentFlags::from_bits_truncate(elf_read_u32!(eh, io)? as u64); r.offset = elf_read_u64!(eh, io)?; r.vaddr = elf_read_u64!(eh, io)?; r.paddr = elf_read_u64!(eh, io)?; r.filesz = elf_read_u64!(eh, io)?; r.memsz = elf_read_u64!(eh, io)?; r.align = elf_read_u64!(eh, io)?; } types::Class::Class32 => { r.offset = elf_read_u32!(eh, io)? as u64; r.vaddr = elf_read_u32!(eh, io)? as u64; r.paddr = elf_read_u32!(eh, io)? as u64; r.filesz = elf_read_u32!(eh, io)? as u64; r.memsz = elf_read_u32!(eh, io)? as u64; r.flags = types::SegmentFlags::from_bits_truncate(elf_read_u32!(eh, io)? as u64); r.align = elf_read_u32!(eh, io)? as u64; } }; Ok(r) } pub fn to_writer<R>(&self, eh: &Header, io: &mut R) -> Result<(), Error> where R: Write, { let mut w = BufWriter::new(io); elf_write_u32!(eh, w, self.phtype.to_u32().unwrap())?; match eh.ident_class { types::Class::Class64 => { elf_write_u32!(eh, w, self.flags.bits() as u32)?; elf_write_u64!(eh, w, self.offset)?; elf_write_u64!(eh, w, self.vaddr)?; elf_write_u64!(eh, w, self.paddr)?; elf_write_u64!(eh, w, self.filesz)?; elf_write_u64!(eh, w, self.memsz)?; elf_write_u64!(eh, w, self.align)?; } types::Class::Class32 => { elf_write_u32!(eh, w, self.offset as u32)?; elf_write_u32!(eh, w, self.vaddr as u32)?; elf_write_u32!(eh, w, self.paddr as u32)?; elf_write_u32!(eh, w, self.filesz as u32)?; elf_write_u32!(eh, w, self.memsz as u32)?; elf_write_u32!(eh, w, self.flags.bits() as u32)?; elf_write_u32!(eh, w, self.align as u32)?; } }; Ok(()) } }