Skip to content

Commit

Permalink
Merge pull request #77 from philipc/alloc
Browse files Browse the repository at this point in the history
Add alloc feature
  • Loading branch information
m4b authored Feb 7, 2018
2 parents e76101f + b864469 commit 28cadaa
Show file tree
Hide file tree
Showing 25 changed files with 255 additions and 149 deletions.
28 changes: 16 additions & 12 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,29 @@ env_logger = "0.4.3"

[dependencies]
plain = "0.2.3"
log = { version = "0.3.8", optional = true }

[dependencies.log]
version = "0.3.8"
default-features = false
optional = true

[dependencies.scroll]
version = "0.8.0"
version = "0.9.0"
default_features = false

[features]
default = ["std", "elf32", "elf64", "mach32", "mach64", "pe32", "pe64", "goblin", "endian_fd", "archive", "scroll/std"]
std = ["scroll/derive", "log"]
endian_fd = ["std"]
default = ["std", "elf32", "elf64", "mach32", "mach64", "pe32", "pe64", "archive", "endian_fd"]
std = ["alloc", "scroll/std"]
alloc = ["scroll/derive", "log"]
endian_fd = ["alloc"]
elf32 = []
elf64 = []
# for now we will require mach and pe to be std + endian_fd
mach32 = ["std", "endian_fd"]
mach64 = ["std", "endian_fd"]
pe32 = ["std", "endian_fd"]
pe64 = ["std", "endian_fd"]
archive = ["endian_fd"]
goblin = []
# for now we will require mach and pe to be alloc + endian_fd
mach32 = ["alloc", "endian_fd"]
mach64 = ["alloc", "endian_fd"]
pe32 = ["alloc", "endian_fd"]
pe64 = ["alloc", "endian_fd"]
archive = ["alloc"]

# [profile.dev]
# opt-level = 0
Expand Down
14 changes: 13 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,28 @@ example:
api:
cargo build --no-default-features
cargo build --no-default-features --features="std"
cargo build --no-default-features --features="endian_fd std"
cargo build --no-default-features --features="elf32"
cargo build --no-default-features --features="elf32 elf64"
cargo build --no-default-features --features="elf32 elf64 std"
cargo build --no-default-features --features="elf32 elf64 endian_fd std"
cargo build --no-default-features --features="archive std"
cargo build --no-default-features --features="mach64 std"
cargo build --no-default-features --features="mach32 std"
cargo build --no-default-features --features="mach64 mach32 std"
cargo build --no-default-features --features="pe32 std"
cargo build --no-default-features --features="pe32 pe64 std"
cargo build

nightly_api:
cargo build --no-default-features --features="alloc"
cargo build --no-default-features --features="endian_fd"
cargo build --no-default-features --features="elf32 elf64 endian_fd"
cargo build --no-default-features --features="archive"
cargo build --no-default-features --features="mach64"
cargo build --no-default-features --features="mach32"
cargo build --no-default-features --features="mach64 mach32"
cargo build --no-default-features --features="pe32"
cargo build --no-default-features --features="pe32 pe64"
cargo build

.PHONY: clean test example doc
15 changes: 8 additions & 7 deletions src/archive/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ use scroll::{self, Pread};
use strtab;
use error::{Result, Error};

use std::usize;
use std::collections::HashMap;
use core::usize;
use alloc::btree_map::BTreeMap;
use alloc::vec::Vec;

pub const SIZEOF_MAGIC: usize = 8;
/// The magic number of a Unix Archive
Expand Down Expand Up @@ -334,9 +335,9 @@ pub struct Archive<'a> {
sysv_name_index: NameIndex<'a>,
// the array of members, which are indexed by the members hash and symbol index
member_array: Vec<Member<'a>>,
members: HashMap<&'a str, usize>,
members: BTreeMap<&'a str, usize>,
// symbol -> member
symbol_index: HashMap<&'a str, usize>
symbol_index: BTreeMap<&'a str, usize>
}


Expand Down Expand Up @@ -383,8 +384,8 @@ impl<'a> Archive<'a> {
}

// preprocess member names
let mut members = HashMap::new();
let mut member_index_by_offset: HashMap<u32, usize> = HashMap::with_capacity(member_array.len());
let mut members = BTreeMap::new();
let mut member_index_by_offset: BTreeMap<u32, usize> = BTreeMap::new();
for (i, member) in member_array.iter_mut().enumerate() {
// copy in any SysV extended names
if let Ok(sysv_name) = sysv_name_index.get(member.raw_name()) {
Expand All @@ -400,7 +401,7 @@ impl<'a> Archive<'a> {
}

// build the symbol index, translating symbol names into member indexes
let mut symbol_index: HashMap<&str, usize> = HashMap::new();
let mut symbol_index: BTreeMap<&str, usize> = BTreeMap::new();
for (member_offset, name) in index.symbol_indexes.iter().zip(index.strtab.iter()) {
let name = name.clone();
let member_index = member_index_by_offset[member_offset];
Expand Down
20 changes: 13 additions & 7 deletions src/elf/dyn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ macro_rules! elf_dyn {
($size:ty) => {
#[repr(C)]
#[derive(Copy, Clone, PartialEq, Default)]
#[cfg_attr(feature = "std", derive(Pread, Pwrite, SizeWith))]
#[cfg_attr(feature = "alloc", derive(Pread, Pwrite, SizeWith))]
/// An entry in the dynamic array
pub struct Dyn {
/// Dynamic entry type
Expand Down Expand Up @@ -271,13 +271,14 @@ pub const DF_1_GLOBAUDIT: u64 = 0x01000000;
/// Singleton dyn are used.
pub const DF_1_SINGLETON: u64 = 0x02000000;

if_std! {
if_alloc! {
use core::fmt;
use scroll::ctx;
use core::result;
use container::{Ctx, Container};
use strtab::Strtab;
use self::dyn32::{DynamicInfo};
use alloc::vec::Vec;

#[derive(Default, PartialEq, Clone)]
pub struct Dyn {
Expand Down Expand Up @@ -419,19 +420,23 @@ macro_rules! elf_dyn_std_impl {
}
}

if_std! {
if_alloc! {
use core::fmt;
use core::slice;
use alloc::vec::Vec;

use std::fs::File;
use std::io::{Read, Seek};
use std::io::SeekFrom::Start;
use elf::program_header::{PT_DYNAMIC};
use strtab::Strtab;
use error::Result;

use elf::dyn::Dyn as ElfDyn;

if_std! {
use std::fs::File;
use std::io::{Read, Seek};
use std::io::SeekFrom::Start;
use error::Result;
}

impl From<ElfDyn> for Dyn {
fn from(dyn: ElfDyn) -> Self {
Dyn {
Expand Down Expand Up @@ -489,6 +494,7 @@ macro_rules! elf_dyn_std_impl {
}

/// Returns a vector of dynamic entries from the given fd and program headers
#[cfg(feature = "std")]
pub fn from_fd(mut fd: &File, phdrs: &[$phdr]) -> Result<Option<Vec<Dyn>>> {
for phdr in phdrs {
if phdr.p_type == PT_DYNAMIC {
Expand Down
23 changes: 15 additions & 8 deletions src/elf/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,12 @@ pub fn et_to_str(et: u16) -> &'static str {
}
}

if_std! {
if_alloc! {
use error::{self};
use scroll::{self, ctx, Endian};
use core::fmt;
use container::{Ctx, Container};
use alloc::string::ToString;

#[derive(Copy, Clone, PartialEq)]
/// An ELF header
Expand Down Expand Up @@ -335,21 +336,26 @@ if_std! {
};
}
}
} // end if_std
} // end if_alloc

macro_rules! elf_header_std_impl {
($size:expr, $width:ty) => {

if_std! {
if_alloc! {
use elf::header::Header as ElfHeader;
use error::{Result, Error};
use error::Error;
#[cfg(any(feature = "std", feature = "endian_fd"))]
use error::Result;

use scroll::{self, ctx, Pread};
use std::fs::File;
use std::io::{Read};

use core::result;

if_std! {
use std::fs::File;
use std::io::{Read};
}

impl From<ElfHeader> for Header {
fn from(eh: ElfHeader) -> Self {
Header {
Expand Down Expand Up @@ -456,8 +462,8 @@ macro_rules! elf_header_std_impl {
}

impl Header {

/// Load a header from a file. **You must** ensure the seek is at the correct position.
#[cfg(feature = "std")]
pub fn from_fd(bytes: &mut File) -> Result<Header> {
let mut elf_header = [0; $size];
bytes.read(&mut elf_header)?;
Expand Down Expand Up @@ -496,7 +502,7 @@ macro_rules! elf_header_std_impl {
Ok(elf_header)
}
}
} // end if_std
} // end if_alloc
};
}

Expand All @@ -510,6 +516,7 @@ macro_rules! elf_header_test {
use elf::header::Header as ElfHeader;
use super::*;
use container::{Ctx, Container};
use alloc::vec::Vec;
#[test]
fn size_of() {
assert_eq!(::std::mem::size_of::<Header>(), SIZEOF_EHDR);
Expand Down
4 changes: 2 additions & 2 deletions src/elf/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,9 @@ pub mod dyn;
pub mod reloc;
pub mod note;


macro_rules! if_sylvan {
($($i:item)*) => ($(
#[cfg(all(feature = "std", feature = "elf32", feature = "elf64", feature = "endian_fd"))]
#[cfg(all(feature = "elf32", feature = "elf64", feature = "endian_fd"))]
$i
)*)
}
Expand All @@ -65,6 +64,7 @@ if_sylvan! {
use strtab::Strtab;
use error;
use container::{Container, Ctx};
use alloc::vec::Vec;

pub type Header = header::Header;
pub type ProgramHeader = program_header::ProgramHeader;
Expand Down
7 changes: 4 additions & 3 deletions src/elf/note.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub const NT_GNU_BUILD_ID: u32 = 3;
pub const NT_GNU_GOLD_VERSION: u32 = 4;

#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "std", derive(Pread, Pwrite, IOread, IOwrite, SizeWith))]
#[cfg_attr(feature = "alloc", derive(Pread, Pwrite, IOread, IOwrite, SizeWith))]
#[repr(C)]
/// Note section contents. Each entry in the note section begins with a header of a fixed form.
pub struct Nhdr32 {
Expand All @@ -45,7 +45,7 @@ pub struct Nhdr32 {
}

#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "std", derive(Pread, Pwrite, IOread, IOwrite, SizeWith))]
#[cfg_attr(feature = "alloc", derive(Pread, Pwrite, IOread, IOwrite, SizeWith))]
#[repr(C)]
/// Note section contents. Each entry in the note section begins with a header of a fixed form.
pub struct Nhdr64 {
Expand All @@ -57,10 +57,11 @@ pub struct Nhdr64 {
pub n_type: u64,
}

if_std! {
if_alloc! {
use error;
use container;
use scroll::{ctx, Pread};
use alloc::vec::Vec;

/// An iterator over ELF binary notes in a note section or segment
pub struct NoteDataIterator<'a> {
Expand Down
25 changes: 15 additions & 10 deletions src/elf/program_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,13 @@ pub fn pt_to_str(pt: u32) -> &'static str {
}
}

if_std! {
if_alloc! {
use core::fmt;
use scroll::ctx;
use core::result;
use core::ops::Range;
use container::{Ctx, Container};
use alloc::vec::Vec;

#[derive(Default, PartialEq, Clone)]
/// A unified ProgramHeader - convertable to and from 32-bit and 64-bit variants
Expand Down Expand Up @@ -224,7 +225,7 @@ if_std! {
}
}
}
} // end if_std
} // end if_alloc

macro_rules! elf_program_header_std_impl { ($size:ty) => {

Expand All @@ -237,20 +238,23 @@ macro_rules! elf_program_header_std_impl { ($size:ty) => {
}
}

if_std! {
if_alloc! {

use elf::program_header::ProgramHeader as ElfProgramHeader;
#[cfg(any(feature = "std", feature = "endian_fd"))]
use error::Result;

use core::slice;
use core::fmt;

use std::fs::File;
use std::io::{Seek, Read};
use std::io::SeekFrom::Start;

use plain::Plain;

if_std! {
use std::fs::File;
use std::io::{Seek, Read};
use std::io::SeekFrom::Start;
}

impl From<ProgramHeader> for ElfProgramHeader {
fn from(ph: ProgramHeader) -> Self {
ElfProgramHeader {
Expand Down Expand Up @@ -319,6 +323,7 @@ macro_rules! elf_program_header_std_impl { ($size:ty) => {
slice::from_raw_parts(phdrp, phnum)
}

#[cfg(feature = "std")]
pub fn from_fd(fd: &mut File, offset: u64, count: usize) -> Result<Vec<ProgramHeader>> {
let mut phdrs = vec![ProgramHeader::default(); count];
try!(fd.seek(Start(offset)));
Expand All @@ -328,7 +333,7 @@ macro_rules! elf_program_header_std_impl { ($size:ty) => {
Ok(phdrs)
}
}
} // end if_std
} // end if_alloc
};}


Expand All @@ -337,7 +342,7 @@ pub mod program_header32 {

#[repr(C)]
#[derive(Copy, Clone, PartialEq, Default)]
#[cfg_attr(feature = "std", derive(Pread, Pwrite, SizeWith))]
#[cfg_attr(feature = "alloc", derive(Pread, Pwrite, SizeWith))]
/// A 64-bit ProgramHeader typically specifies how to map executable and data segments into memory
pub struct ProgramHeader {
/// Segment type
Expand Down Expand Up @@ -373,7 +378,7 @@ pub mod program_header64 {

#[repr(C)]
#[derive(Copy, Clone, PartialEq, Default)]
#[cfg_attr(feature = "std", derive(Pread, Pwrite, SizeWith))]
#[cfg_attr(feature = "alloc", derive(Pread, Pwrite, SizeWith))]
/// A 32-bit ProgramHeader typically specifies how to map executable and data segments into memory
pub struct ProgramHeader {
/// Segment type
Expand Down
Loading

0 comments on commit 28cadaa

Please sign in to comment.