Skip to content

Commit 916bc1a

Browse files
committed
Add alloc feature
This allows building the `endian_fd` feature without `std`, although it does still require the `alloc` crate and a nightly rustc.
1 parent 79aecc8 commit 916bc1a

25 files changed

+253
-156
lines changed

Cargo.toml

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,29 @@ env_logger = "0.4.3"
1818

1919
[dependencies]
2020
plain = "0.2.3"
21-
log = { version = "0.3.8", optional = true }
21+
22+
[dependencies.log]
23+
version = "0.3.8"
24+
default-features = false
25+
optional = true
2226

2327
[dependencies.scroll]
24-
version = "0.8.0"
28+
version = "0.9.0"
2529
default_features = false
2630

2731
[features]
28-
default = ["std", "elf32", "elf64", "mach32", "mach64", "pe32", "pe64", "goblin", "endian_fd", "archive", "scroll/std"]
29-
std = ["scroll/derive", "log"]
30-
endian_fd = ["std"]
32+
default = ["std", "elf32", "elf64", "mach32", "mach64", "pe32", "pe64", "archive", "endian_fd"]
33+
std = ["alloc", "scroll/std"]
34+
alloc = ["scroll/derive", "log"]
35+
endian_fd = ["alloc", "elf32", "elf64", "mach32", "mach64", "pe32", "pe64", "archive"]
3136
elf32 = []
3237
elf64 = []
33-
# for now we will require mach and pe to be std + endian_fd
34-
mach32 = ["std", "endian_fd"]
35-
mach64 = ["std", "endian_fd"]
36-
pe32 = ["std", "endian_fd"]
37-
pe64 = ["std", "endian_fd"]
38-
archive = ["endian_fd"]
39-
goblin = []
38+
# for now we will require mach and pe to be alloc + endian_fd
39+
mach32 = ["alloc", "endian_fd"]
40+
mach64 = ["alloc", "endian_fd"]
41+
pe32 = ["alloc", "endian_fd"]
42+
pe64 = ["alloc", "endian_fd"]
43+
archive = ["alloc"]
4044

4145
# [profile.dev]
4246
# opt-level = 0

Makefile

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,21 @@ api:
2828
cargo build --no-default-features --features="elf32"
2929
cargo build --no-default-features --features="elf32 elf64"
3030
cargo build --no-default-features --features="elf32 elf64 std"
31-
cargo build --no-default-features --features="elf32 elf64 endian_fd"
31+
cargo build --no-default-features --features="archive std"
32+
cargo build --no-default-features --features="mach64 mach32 std"
33+
cargo build --no-default-features --features="pe32 pe64 std"
34+
cargo build --no-default-features --features="endian_fd std"
35+
cargo build
36+
37+
nightly_api:
38+
cargo build --no-default-features --features="alloc"
39+
cargo build --no-default-features --features="elf32 elf64 alloc"
3240
cargo build --no-default-features --features="archive"
3341
cargo build --no-default-features --features="mach64"
3442
cargo build --no-default-features --features="mach32"
3543
cargo build --no-default-features --features="mach64 mach32"
3644
cargo build --no-default-features --features="pe32"
3745
cargo build --no-default-features --features="pe32 pe64"
38-
cargo build
46+
cargo build --no-default-features --features="endian_fd"
3947

4048
.PHONY: clean test example doc

src/archive/mod.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ use scroll::{self, Pread};
1111
use strtab;
1212
use error::{Result, Error};
1313

14-
use std::usize;
15-
use std::collections::HashMap;
14+
use core::usize;
15+
use alloc::btree_map::BTreeMap;
16+
use alloc::vec::Vec;
1617

1718
pub const SIZEOF_MAGIC: usize = 8;
1819
/// The magic number of a Unix Archive
@@ -334,9 +335,9 @@ pub struct Archive<'a> {
334335
sysv_name_index: NameIndex<'a>,
335336
// the array of members, which are indexed by the members hash and symbol index
336337
member_array: Vec<Member<'a>>,
337-
members: HashMap<&'a str, usize>,
338+
members: BTreeMap<&'a str, usize>,
338339
// symbol -> member
339-
symbol_index: HashMap<&'a str, usize>
340+
symbol_index: BTreeMap<&'a str, usize>
340341
}
341342

342343

@@ -383,8 +384,8 @@ impl<'a> Archive<'a> {
383384
}
384385

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

402403
// build the symbol index, translating symbol names into member indexes
403-
let mut symbol_index: HashMap<&str, usize> = HashMap::new();
404+
let mut symbol_index: BTreeMap<&str, usize> = BTreeMap::new();
404405
for (member_offset, name) in index.symbol_indexes.iter().zip(index.strtab.iter()) {
405406
let name = name.clone();
406407
let member_index = member_index_by_offset[member_offset];

src/elf/dyn.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ macro_rules! elf_dyn {
33
($size:ty) => {
44
#[repr(C)]
55
#[derive(Copy, Clone, PartialEq, Default)]
6-
#[cfg_attr(feature = "std", derive(Pread, Pwrite, SizeWith))]
6+
#[cfg_attr(feature = "alloc", derive(Pread, Pwrite, SizeWith))]
77
/// An entry in the dynamic array
88
pub struct Dyn {
99
/// Dynamic entry type
@@ -271,13 +271,14 @@ pub const DF_1_GLOBAUDIT: u64 = 0x01000000;
271271
/// Singleton dyn are used.
272272
pub const DF_1_SINGLETON: u64 = 0x02000000;
273273

274-
if_std! {
274+
if_alloc! {
275275
use core::fmt;
276276
use scroll::ctx;
277277
use core::result;
278278
use container::{Ctx, Container};
279279
use strtab::Strtab;
280280
use self::dyn32::{DynamicInfo};
281+
use alloc::vec::Vec;
281282

282283
#[derive(Default, PartialEq, Clone)]
283284
pub struct Dyn {
@@ -419,19 +420,23 @@ macro_rules! elf_dyn_std_impl {
419420
}
420421
}
421422

422-
if_std! {
423+
if_alloc! {
423424
use core::fmt;
424425
use core::slice;
426+
use alloc::vec::Vec;
425427

426-
use std::fs::File;
427-
use std::io::{Read, Seek};
428-
use std::io::SeekFrom::Start;
429428
use elf::program_header::{PT_DYNAMIC};
430429
use strtab::Strtab;
431-
use error::Result;
432430

433431
use elf::dyn::Dyn as ElfDyn;
434432

433+
if_std! {
434+
use std::fs::File;
435+
use std::io::{Read, Seek};
436+
use std::io::SeekFrom::Start;
437+
use error::Result;
438+
}
439+
435440
impl From<ElfDyn> for Dyn {
436441
fn from(dyn: ElfDyn) -> Self {
437442
Dyn {
@@ -489,6 +494,7 @@ macro_rules! elf_dyn_std_impl {
489494
}
490495

491496
/// Returns a vector of dynamic entries from the given fd and program headers
497+
#[cfg(feature = "std")]
492498
pub fn from_fd(mut fd: &File, phdrs: &[$phdr]) -> Result<Option<Vec<Dyn>>> {
493499
for phdr in phdrs {
494500
if phdr.p_type == PT_DYNAMIC {

src/elf/header.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,12 @@ pub fn et_to_str(et: u16) -> &'static str {
139139
}
140140
}
141141

142-
if_std! {
142+
if_alloc! {
143143
use error::{self};
144144
use scroll::{self, ctx, Endian};
145145
use core::fmt;
146146
use container::{Ctx, Container};
147+
use alloc::string::ToString;
147148

148149
#[derive(Copy, Clone, PartialEq)]
149150
/// An ELF header
@@ -335,21 +336,26 @@ if_std! {
335336
};
336337
}
337338
}
338-
} // end if_std
339+
} // end if_alloc
339340

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

343-
if_std! {
344+
if_alloc! {
344345
use elf::header::Header as ElfHeader;
345-
use error::{Result, Error};
346+
use error::Error;
347+
#[cfg(any(feature = "std", feature = "endian_fd"))]
348+
use error::Result;
346349

347350
use scroll::{self, ctx, Pread};
348-
use std::fs::File;
349-
use std::io::{Read};
350351

351352
use core::result;
352353

354+
if_std! {
355+
use std::fs::File;
356+
use std::io::{Read};
357+
}
358+
353359
impl From<ElfHeader> for Header {
354360
fn from(eh: ElfHeader) -> Self {
355361
Header {
@@ -456,8 +462,8 @@ macro_rules! elf_header_std_impl {
456462
}
457463

458464
impl Header {
459-
460465
/// Load a header from a file. **You must** ensure the seek is at the correct position.
466+
#[cfg(feature = "std")]
461467
pub fn from_fd(bytes: &mut File) -> Result<Header> {
462468
let mut elf_header = [0; $size];
463469
bytes.read(&mut elf_header)?;
@@ -496,7 +502,7 @@ macro_rules! elf_header_std_impl {
496502
Ok(elf_header)
497503
}
498504
}
499-
} // end if_std
505+
} // end if_alloc
500506
};
501507
}
502508

@@ -510,6 +516,7 @@ macro_rules! elf_header_test {
510516
use elf::header::Header as ElfHeader;
511517
use super::*;
512518
use container::{Ctx, Container};
519+
use alloc::vec::Vec;
513520
#[test]
514521
fn size_of() {
515522
assert_eq!(::std::mem::size_of::<Header>(), SIZEOF_EHDR);

src/elf/mod.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,18 +53,12 @@ pub mod reloc;
5353
pub mod note;
5454

5555

56-
macro_rules! if_sylvan {
57-
($($i:item)*) => ($(
58-
#[cfg(all(feature = "std", feature = "elf32", feature = "elf64", feature = "endian_fd"))]
59-
$i
60-
)*)
61-
}
62-
63-
if_sylvan! {
56+
if_endian_fd! {
6457
use scroll::{self, ctx, Pread, Endian};
6558
use strtab::Strtab;
6659
use error;
6760
use container::{Container, Ctx};
61+
use alloc::vec::Vec;
6862

6963
pub type Header = header::Header;
7064
pub type ProgramHeader = program_header::ProgramHeader;

src/elf/note.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub const NT_GNU_BUILD_ID: u32 = 3;
3232
pub const NT_GNU_GOLD_VERSION: u32 = 4;
3333

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

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

60-
if_std! {
60+
if_alloc! {
6161
use error;
6262
use container;
6363
use scroll::{ctx, Pread};
64+
use alloc::vec::Vec;
6465

6566
/// An iterator over ELF binary notes in a note section or segment
6667
pub struct NoteDataIterator<'a> {

src/elf/program_header.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,13 @@ pub fn pt_to_str(pt: u32) -> &'static str {
7575
}
7676
}
7777

78-
if_std! {
78+
if_alloc! {
7979
use core::fmt;
8080
use scroll::ctx;
8181
use core::result;
8282
use core::ops::Range;
8383
use container::{Ctx, Container};
84+
use alloc::vec::Vec;
8485

8586
#[derive(Default, PartialEq, Clone)]
8687
/// A unified ProgramHeader - convertable to and from 32-bit and 64-bit variants
@@ -224,7 +225,7 @@ if_std! {
224225
}
225226
}
226227
}
227-
} // end if_std
228+
} // end if_alloc
228229

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

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

240-
if_std! {
241+
if_alloc! {
241242

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

245247
use core::slice;
246248
use core::fmt;
247249

248-
use std::fs::File;
249-
use std::io::{Seek, Read};
250-
use std::io::SeekFrom::Start;
251-
252250
use plain::Plain;
253251

252+
if_std! {
253+
use std::fs::File;
254+
use std::io::{Seek, Read};
255+
use std::io::SeekFrom::Start;
256+
}
257+
254258
impl From<ProgramHeader> for ElfProgramHeader {
255259
fn from(ph: ProgramHeader) -> Self {
256260
ElfProgramHeader {
@@ -319,6 +323,7 @@ macro_rules! elf_program_header_std_impl { ($size:ty) => {
319323
slice::from_raw_parts(phdrp, phnum)
320324
}
321325

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

334339

@@ -337,7 +342,7 @@ pub mod program_header32 {
337342

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

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

0 commit comments

Comments
 (0)