#[cfg(feature = "std")]
pub trait ElfSectionHeader {
fn sh_name(&self) -> usize;
fn sh_type(&self) -> u32;
fn sh_flags(&self) -> u64;
fn sh_addr(&self) -> u64;
fn sh_offset(&self) -> u64;
fn sh_size(&self) -> u64;
fn sh_link(&self) -> u32;
fn sh_info(&self) -> u32;
fn sh_addralign(&self) -> u64;
fn sh_entsize(&self) -> u64;
}
macro_rules! elf_section_header {
($size:ident) => {
#[repr(C)]
#[derive(Copy, Clone, Eq, PartialEq, Default)]
#[cfg_attr(feature = "endian_fd", derive(Pread, Pwrite))]
pub struct SectionHeader {
pub sh_name: u32,
pub sh_type: u32,
pub sh_flags: $size,
pub sh_addr: $size,
pub sh_offset: $size,
pub sh_size: $size,
pub sh_link: u32,
pub sh_info: u32,
pub sh_addralign: $size,
pub sh_entsize: $size,
}
}
}
pub const SHN_UNDEF: u32 = 0;
pub const SHN_LORESERVE: u32 = 0xff00;
pub const SHN_LOPROC: u32 = 0xff00;
pub const SHN_BEFORE: u32 = 0xff00;
pub const SHN_AFTER: u32 = 0xff01;
pub const SHN_HIPROC: u32 = 0xff1f;
pub const SHN_LOOS: u32 = 0xff20;
pub const SHN_HIOS: u32 = 0xff3f;
pub const SHN_ABS: u32 = 0xfff1;
pub const SHN_COMMON: u32 = 0xfff2;
pub const SHN_XINDEX: u32 = 0xffff;
pub const SHN_HIRESERVE: u32 = 0xffff;
pub const SHT_NULL: u32 = 0;
pub const SHT_PROGBITS: u32 = 1;
pub const SHT_SYMTAB: u32 = 2;
pub const SHT_STRTAB: u32 = 3;
pub const SHT_RELA: u32 = 4;
pub const SHT_HASH: u32 = 5;
pub const SHT_DYNAMIC: u32 = 6;
pub const SHT_NOTE: u32 = 7;
pub const SHT_NOBITS: u32 = 8;
pub const SHT_REL: u32 = 9;
pub const SHT_SHLIB: u32 = 10;
pub const SHT_DYNSYM: u32 = 11;
pub const SHT_INIT_ARRAY: u32 = 14;
pub const SHT_FINI_ARRAY: u32 = 15;
pub const SHT_PREINIT_ARRAY: u32 = 16;
pub const SHT_GROUP: u32 = 17;
pub const SHT_SYMTAB_SHNDX: u32 = 18;
pub const SHT_NUM: u32 = 19;
pub const SHT_LOOS: u32 = 0x60000000;
pub const SHT_GNU_ATTRIBUTES: u32 = 0x6ffffff5;
pub const SHT_GNU_HASH: u32 = 0x6ffffff6;
pub const SHT_GNU_LIBLIST: u32 = 0x6ffffff7;
pub const SHT_CHECKSUM: u32 = 0x6ffffff8;
pub const SHT_LOSUNW: u32 = 0x6ffffffa;
pub const SHT_SUNW_MOVE: u32 = 0x6ffffffa;
pub const SHT_SUNW_COMDAT: u32 = 0x6ffffffb;
pub const SHT_SUNW_SYMINFO: u32 = 0x6ffffffc;
pub const SHT_GNU_VERDEF: u32 = 0x6ffffffd;
pub const SHT_GNU_VERNEED: u32 = 0x6ffffffe;
pub const SHT_GNU_VERSYM: u32 = 0x6fffffff;
pub const SHT_HISUNW: u32 = 0x6fffffff;
pub const SHT_HIOS: u32 = 0x6fffffff;
pub const SHT_LOPROC: u32 = 0x70000000;
pub const SHT_HIPROC: u32 = 0x7fffffff;
pub const SHT_LOUSER: u32 = 0x80000000;
pub const SHT_HIUSER: u32 = 0x8fffffff;
pub const SHF_WRITE: u32 = 1 << 0;
pub const SHF_ALLOC: u32 = 1 << 1;
pub const SHF_EXECINSTR: u32 = 1 << 2;
pub const SHF_MERGE: u32 = 1 << 4;
pub const SHF_STRINGS: u32 = 1 << 5;
pub const SHF_INFO_LINK: u32 = 1 << 6;
pub const SHF_LINK_ORDER: u32 = 1 << 7;
pub const SHF_OS_NONCONFORMING: u32 = 1 << 8;
pub const SHF_GROUP: u32 = 1 << 9;
pub const SHF_TLS: u32 = 1 << 10;
pub const SHF_COMPRESSED: u32 = 1 << 11;
pub const SHF_MASKOS: u32 = 0x0ff00000;
pub const SHF_MASKPROC: u32 = 0xf0000000;
pub const SHF_ORDERED: u32 = 1 << 30;
pub fn sht_to_str(sht: u32) -> &'static str {
match sht {
SHT_NULL => "SHT_NULL",
SHT_PROGBITS => "SHT_PROGBITS",
SHT_SYMTAB => "SHT_SYMTAB",
SHT_STRTAB => "SHT_STRTAB",
SHT_RELA => "SHT_RELA",
SHT_HASH => "SHT_HASH",
SHT_DYNAMIC => "SHT_DYNAMIC",
SHT_NOTE => "SHT_NOTE",
SHT_NOBITS => "SHT_NOBITS",
SHT_REL => "SHT_REL",
SHT_SHLIB => "SHT_SHLIB",
SHT_DYNSYM => "SHT_DYNSYM",
SHT_INIT_ARRAY => "SHT_INIT_ARRAY",
SHT_FINI_ARRAY => "SHT_FINI_ARRAY",
SHT_PREINIT_ARRAY => "SHT_PREINIT_ARRAY",
SHT_GROUP => "SHT_GROUP",
SHT_SYMTAB_SHNDX => "SHT_SYMTAB_SHNDX",
SHT_NUM => "SHT_NUM",
SHT_LOOS => "SHT_LOOS",
SHT_GNU_ATTRIBUTES => "SHT_GNU_ATTRIBUTES",
SHT_GNU_HASH => "SHT_GNU_HASH",
SHT_GNU_LIBLIST => "SHT_GNU_LIBLIST",
SHT_CHECKSUM => "SHT_CHECKSUM",
SHT_SUNW_MOVE => "SHT_SUNW_MOVE",
SHT_SUNW_COMDAT => "SHT_SUNW_COMDAT",
SHT_SUNW_SYMINFO => "SHT_SUNW_SYMINFO",
SHT_GNU_VERDEF => "SHT_GNU_VERDEF",
SHT_GNU_VERNEED => "SHT_GNU_VERNEED",
SHT_GNU_VERSYM => "SHT_GNU_VERSYM",
SHT_LOPROC => "SHT_LOPROC",
SHT_HIPROC => "SHT_HIPROC",
SHT_LOUSER => "SHT_LOUSER",
SHT_HIUSER => "SHT_HIUSER",
_ => "UNKNOWN_SHT",
}
}
macro_rules! elf_section_header_impure_impl { () => {
#[cfg(feature = "std")]
pub use self::impure::*;
#[cfg(feature = "std")]
mod impure {
use super::*;
use elf::error::*;
use core::slice;
use core::fmt;
use scroll;
use std::fs::File;
use std::io::{Read, Seek};
use std::io::SeekFrom::Start;
impl ElfSectionHeader for SectionHeader {
fn sh_name(&self) -> usize {
self.sh_name as usize
}
fn sh_type(&self) -> u32 {
self.sh_type
}
fn sh_flags(&self) -> u64 {
self.sh_flags as u64
}
fn sh_addr(&self) -> u64 {
self.sh_addr as u64
}
fn sh_offset(&self) -> u64 {
self.sh_offset as u64
}
fn sh_size(&self) -> u64 {
self.sh_size as u64
}
fn sh_link(&self) -> u32 {
self.sh_link
}
fn sh_info(&self) -> u32 {
self.sh_info
}
fn sh_addralign(&self) -> u64 {
self.sh_addralign as u64
}
fn sh_entsize(&self) -> u64 {
self.sh_entsize as u64
}
}
impl fmt::Debug for SectionHeader {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f,
"sh_name: {} sh_type {} sh_flags: 0x{:x} sh_addr: 0x{:x} sh_offset: 0x{:x} \
sh_size: 0x{:x} sh_link: 0x{:x} sh_info: 0x{:x} sh_addralign 0x{:x} sh_entsize 0x{:x}",
self.sh_name,
sht_to_str(self.sh_type as u32),
self.sh_flags,
self.sh_addr,
self.sh_offset,
self.sh_size,
self.sh_link,
self.sh_info,
self.sh_addralign,
self.sh_entsize)
}
}
impl SectionHeader {
pub fn from_bytes(bytes: &[u8], shnum: usize) -> Vec<SectionHeader> {
let bytes = unsafe { slice::from_raw_parts(bytes.as_ptr() as *mut SectionHeader, shnum) };
let mut shdrs = Vec::with_capacity(shnum);
shdrs.extend_from_slice(bytes);
shdrs
}
pub unsafe fn from_raw_parts<'a>(shdrp: *const SectionHeader,
shnum: usize)
-> &'a [SectionHeader] {
slice::from_raw_parts(shdrp, shnum)
}
pub fn from_fd(fd: &mut File, offset: u64, count: usize) -> Result<Vec<SectionHeader>> {
let mut shdrs = vec![0u8; count * SIZEOF_SHDR];
try!(fd.seek(Start(offset)));
try!(fd.read(&mut shdrs));
Ok(SectionHeader::from_bytes(&shdrs, count))
}
#[cfg(feature = "endian_fd")]
pub fn parse<S: scroll::Gread>(bytes: &S, mut offset: usize, count: usize, endianness: scroll::Endian) -> Result<Vec<SectionHeader>> {
let mut section_headers = vec![SectionHeader::default(); count];
let mut offset = &mut offset;
bytes.gread_inout_with(offset, &mut section_headers, endianness)?;
Ok(section_headers)
}
}
}
};}