#![cfg_attr(not(feature = "std"), no_std)]
extern crate scroll;
#[cfg(feature = "std")]
extern crate core;
#[cfg(feature = "std")]
#[macro_use]
extern crate scroll_derive;
#[cfg(feature = "std")]
pub mod error;
#[cfg(feature = "std")]
pub mod strtab;
pub mod container {
use scroll;
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum Container {
Little,
Big,
}
#[cfg(not(target_pointer_width = "64"))]
pub const CONTAINER: Container = Container::Little;
#[cfg(target_pointer_width = "64")]
pub const CONTAINER: Container = Container::Big;
impl Default for Container {
#[inline]
fn default() -> Self {
CONTAINER
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Ctx {
pub container: Container,
pub le: scroll::Endian,
}
impl Ctx {
pub fn new (container: Container, le: scroll::Endian) -> Self {
Ctx { container: container, le: le }
}
}
impl From<Container> for Ctx {
fn from(container: Container) -> Self {
Ctx { container: container, le: scroll::Endian::default() }
}
}
impl From<scroll::Endian> for Ctx {
fn from(le: scroll::Endian) -> Self {
Ctx { container: CONTAINER, le: le }
}
}
impl Default for Ctx {
#[inline]
fn default() -> Self {
Ctx { container: Container::default(), le: scroll::Endian::default() }
}
}
}
#[cfg(feature = "std")]
pub use peek::*;
#[cfg(all(feature = "std"))]
mod peek {
#[derive(Debug, Default)]
pub struct HintData {
pub is_lsb: bool,
pub is_64: Option<bool>,
}
#[derive(Debug)]
pub enum Hint {
Elf(HintData),
Mach,
PE,
Archive,
Unknown(u64),
}
#[cfg(all(feature = "endian_fd", feature = "elf64", feature = "elf32", feature = "pe64", feature = "pe32", feature = "mach64", feature = "mach32", feature = "archive"))]
pub fn peek<R: ::std::io::Read + ::std::io::Seek>(fd: &mut R) -> super::error::Result<Hint> {
use scroll::Pread;
use std::io::SeekFrom;
use super::*;
let mut bytes = [0u8; 16];
fd.seek(SeekFrom::Start(0))?;
fd.read_exact(&mut bytes)?;
fd.seek(SeekFrom::Start(0))?;
if &bytes[0..elf::header::SELFMAG] == elf::header::ELFMAG {
let class = bytes[elf::header::EI_CLASS];
let is_lsb = bytes[elf::header::EI_DATA] == elf::header::ELFDATA2LSB;
let is_64 =
if class == elf::header::ELFCLASS64 {
Some (true)
} else if class == elf::header::ELFCLASS32 {
Some (false)
} else { None };
Ok(Hint::Elf(HintData { is_lsb: is_lsb, is_64: is_64 }))
} else if &bytes[0..archive::SIZEOF_MAGIC] == archive::MAGIC {
Ok(Hint::Archive)
} else if (&bytes[0..2]).pread::<u16>(0)? == pe::header::DOS_MAGIC {
Ok(Hint::PE)
} else {
Ok(Hint::Unknown(bytes.pread::<u64>(0)?))
}
}
}
#[cfg(any(feature = "elf64", feature = "elf32"))]
#[macro_use]
pub mod elf;
#[cfg(feature = "elf32")]
pub mod elf32 {
pub use elf::header::header32 as header;
pub use elf::program_header::program_header32 as program_header;
pub use elf::section_header::section_header32 as section_header;
pub use elf::dyn::dyn32 as dyn;
pub use elf::sym::sym32 as sym;
pub use elf::reloc::reloc32 as reloc;
#[cfg(feature = "std")]
pub use strtab;
#[cfg(feature = "std")]
pub mod gnu_hash {
elf_gnu_hash_impl!(u32);
}
}
#[cfg(feature = "elf64")]
pub mod elf64 {
pub use elf::header::header64 as header;
pub use elf::program_header::program_header64 as program_header;
pub use elf::section_header::section_header64 as section_header;
pub use elf::dyn::dyn64 as dyn;
pub use elf::sym::sym64 as sym;
pub use elf::reloc::reloc64 as reloc;
#[cfg(feature = "std")]
pub use strtab;
#[cfg(feature = "std")]
pub mod gnu_hash {
elf_gnu_hash_impl!(u64);
}
}
#[cfg(feature = "mach64")]
pub mod mach;
#[cfg(all(feature = "archive", feature = "std"))]
pub mod archive;
#[cfg(all(feature = "pe32", feature = "std"))]
pub mod pe;