#[cfg(feature = "std")]
pub trait ElfSectionHeader {
fn sh_name(&self) -> u32;
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, PartialEq, Default)]
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 {
_ => "UNKNOWN_SHT",
}
}
macro_rules! elf_section_header_from_bytes { () => {
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
}};}
macro_rules! elf_section_header_from_raw_parts { () => {
pub unsafe fn from_raw_parts<'a>(shdrp: *const SectionHeader,
shnum: usize)
-> &'a [SectionHeader] {
slice::from_raw_parts(shdrp, shnum)
}};}
macro_rules! elf_section_header_from_fd { () => {
pub fn from_fd(fd: &mut File, offset: u64, count: usize) -> io::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))
}
};}
macro_rules! elf_section_header_from_endian { ($from_endian:item) => {
#[cfg(feature = "endian_fd")]
$from_endian
};}
macro_rules! elf_section_header_impure_impl { ($header:item) => {
#[cfg(feature = "std")]
pub use self::impure::*;
#[cfg(feature = "std")]
mod impure {
use super::*;
use core::slice;
use core::fmt;
use std::fs::File;
use std::io::{self, Read, Seek};
use std::io::SeekFrom::Start;
impl ElfSectionHeader for SectionHeader {
fn sh_name(&self) -> u32 {
self.sh_name
}
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)
}
}
$header
}
};}