Use target-lexicon

This commit is contained in:
Philip Craig
2019-06-05 12:35:44 +10:00
parent 2aa2471473
commit e1602da694
9 changed files with 118 additions and 149 deletions
+1
View File
@@ -11,6 +11,7 @@ exclude = ["/.coveralls.yml", "/.travis.yml"]
[dependencies]
scroll = { version = "0.9", default-features = false }
target-lexicon = { version = "0.4" }
uuid = { version = "0.7", default-features = false }
flate2 = { version = "1", optional = true }
+3 -2
View File
@@ -29,8 +29,9 @@ mod alloc {
pub use std::vec;
}
// Re-export since this is used in public signatures.
pub use uuid::Uuid;
// Re-export since these are used in public signatures.
pub use target_lexicon;
pub use uuid;
pub mod read;
pub use read::*;
+18 -51
View File
@@ -1,34 +1,15 @@
use crate::alloc::borrow::Cow;
use crate::alloc::fmt;
use target_lexicon::{Architecture, BinaryFormat};
use uuid::Uuid;
#[cfg(feature = "wasm")]
use crate::read::wasm;
use crate::read::{elf, macho, pe};
use crate::read::{
Machine, Object, ObjectSection, ObjectSegment, Relocation, SectionIndex, SectionKind, Symbol,
Object, ObjectSection, ObjectSegment, Relocation, SectionIndex, SectionKind, Symbol,
SymbolIndex, SymbolMap,
};
use crate::Uuid;
/// The object file format.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Format {
/// 32-bit ELF
Elf32,
/// 64-bit ELF
Elf64,
/// 32-bit Mach-O
MachO32,
/// 64-bit Mach-O
MachO64,
/// 32-bit PE
Pe32,
/// 64-bit PE
Pe64,
/// WebAssembly
#[cfg(feature = "wasm")]
Wasm,
}
/// Evaluate an expression on the contents of a file format enum.
///
@@ -154,31 +135,13 @@ impl<'data> File<'data> {
}
/// Return the file format.
pub fn format(&self) -> Format {
pub fn format(&self) -> BinaryFormat {
match self.inner {
FileInternal::Elf(ref inner) => {
if inner.is_64() {
Format::Elf64
} else {
Format::Elf32
}
}
FileInternal::MachO(ref inner) => {
if inner.is_64() {
Format::MachO64
} else {
Format::MachO32
}
}
FileInternal::Pe(ref inner) => {
if inner.is_64() {
Format::Pe64
} else {
Format::Pe32
}
}
FileInternal::Elf(_) => BinaryFormat::Elf,
FileInternal::MachO(_) => BinaryFormat::Macho,
FileInternal::Pe(_) => BinaryFormat::Coff,
#[cfg(feature = "wasm")]
FileInternal::Wasm(_) => Format::Wasm,
FileInternal::Wasm(_) => BinaryFormat::Wasm,
}
}
}
@@ -193,8 +156,16 @@ where
type SectionIterator = SectionIterator<'data, 'file>;
type SymbolIterator = SymbolIterator<'data, 'file>;
fn machine(&self) -> Machine {
with_inner!(self.inner, FileInternal, |x| x.machine())
fn architecture(&self) -> Architecture {
with_inner!(self.inner, FileInternal, |x| x.architecture())
}
fn is_little_endian(&self) -> bool {
with_inner!(self.inner, FileInternal, |x| x.is_little_endian())
}
fn is_64(&self) -> bool {
with_inner!(self.inner, FileInternal, |x| x.is_64())
}
fn segments(&'file self) -> SegmentIterator<'data, 'file> {
@@ -250,10 +221,6 @@ where
with_inner!(self.inner, FileInternal, |x| x.symbol_map())
}
fn is_little_endian(&self) -> bool {
with_inner!(self.inner, FileInternal, |x| x.is_little_endian())
}
fn has_debug_symbols(&self) -> bool {
with_inner!(self.inner, FileInternal, |x| x.has_debug_symbols())
}
+20 -23
View File
@@ -1,21 +1,19 @@
use crate::alloc::borrow::Cow;
use crate::alloc::fmt;
use crate::alloc::vec::Vec;
use std::iter;
use std::slice;
#[cfg(feature = "compression")]
use flate2::{Decompress, FlushDecompress};
#[cfg(feature = "compression")]
use goblin::container;
use goblin::{elf, strtab};
#[cfg(feature = "compression")]
use scroll::ctx::TryFromCtx;
use scroll::{self, Pread};
use std::{iter, slice};
use target_lexicon::Architecture;
use crate::read::{
self, Machine, Object, ObjectSection, ObjectSegment, Relocation, RelocationKind, SectionIndex,
self, Object, ObjectSection, ObjectSegment, Relocation, RelocationKind, SectionIndex,
SectionKind, Symbol, SymbolIndex, SymbolKind, SymbolMap,
};
@@ -40,12 +38,6 @@ impl<'data> ElfFile<'data> {
Ok(ElfFile { elf, data })
}
/// True for 64-bit files.
#[inline]
pub fn is_64(&self) -> bool {
self.elf.is_64
}
fn raw_section_by_name<'file>(
&'file self,
section_name: &str,
@@ -94,17 +86,27 @@ where
type SectionIterator = ElfSectionIterator<'data, 'file>;
type SymbolIterator = ElfSymbolIterator<'data, 'file>;
fn machine(&self) -> Machine {
fn architecture(&self) -> Architecture {
match self.elf.header.e_machine {
elf::header::EM_ARM => Machine::Arm,
elf::header::EM_AARCH64 => Machine::Arm64,
elf::header::EM_386 => Machine::X86,
elf::header::EM_X86_64 => Machine::X86_64,
elf::header::EM_MIPS => Machine::Mips,
_ => Machine::Other,
elf::header::EM_ARM => Architecture::Arm,
elf::header::EM_AARCH64 => Architecture::Aarch64,
elf::header::EM_386 => Architecture::I386,
elf::header::EM_X86_64 => Architecture::X86_64,
elf::header::EM_MIPS => Architecture::Mips,
_ => Architecture::Unknown,
}
}
#[inline]
fn is_little_endian(&self) -> bool {
self.elf.little_endian
}
#[inline]
fn is_64(&self) -> bool {
self.elf.is_64
}
fn segments(&'file self) -> ElfSegmentIterator<'data, 'file> {
ElfSegmentIterator {
file: self,
@@ -166,11 +168,6 @@ where
SymbolMap { symbols }
}
#[inline]
fn is_little_endian(&self) -> bool {
self.elf.little_endian
}
fn has_debug_symbols(&self) -> bool {
for header in &self.elf.section_headers {
if let Some(Ok(name)) = self.elf.shdr_strtab.get(header.sh_name) {
+20 -21
View File
@@ -1,14 +1,14 @@
use crate::alloc::borrow::Cow;
use crate::alloc::vec::Vec;
use std::{fmt, iter, slice};
use goblin::container;
use goblin::mach;
use goblin::mach::load_command::CommandVariant;
use std::{fmt, iter, slice};
use target_lexicon::Architecture;
use uuid::Uuid;
use crate::read::{
self, Machine, Object, ObjectSection, ObjectSegment, Relocation, RelocationKind, SectionIndex,
self, Object, ObjectSection, ObjectSegment, Relocation, RelocationKind, SectionIndex,
SectionKind, Symbol, SymbolIndex, SymbolKind, SymbolMap,
};
@@ -36,12 +36,6 @@ impl<'data> MachOFile<'data> {
let macho = mach::MachO::parse(data, 0).map_err(|_| "Could not parse Mach-O header")?;
Ok(MachOFile { macho, data, ctx })
}
/// True for 64-bit files.
#[inline]
pub fn is_64(&self) -> bool {
self.macho.is_64
}
}
impl<'data, 'file> Object<'data, 'file> for MachOFile<'data>
@@ -54,17 +48,27 @@ where
type SectionIterator = MachOSectionIterator<'data, 'file>;
type SymbolIterator = MachOSymbolIterator<'data>;
fn machine(&self) -> Machine {
fn architecture(&self) -> Architecture {
match self.macho.header.cputype {
mach::cputype::CPU_TYPE_ARM => Machine::Arm,
mach::cputype::CPU_TYPE_ARM64 => Machine::Arm64,
mach::cputype::CPU_TYPE_X86 => Machine::X86,
mach::cputype::CPU_TYPE_X86_64 => Machine::X86_64,
mach::cputype::CPU_TYPE_MIPS => Machine::Mips,
_ => Machine::Other,
mach::cputype::CPU_TYPE_ARM => Architecture::Arm,
mach::cputype::CPU_TYPE_ARM64 => Architecture::Aarch64,
mach::cputype::CPU_TYPE_X86 => Architecture::I386,
mach::cputype::CPU_TYPE_X86_64 => Architecture::X86_64,
mach::cputype::CPU_TYPE_MIPS => Architecture::Mips,
_ => Architecture::Unknown,
}
}
#[inline]
fn is_little_endian(&self) -> bool {
self.macho.little_endian
}
#[inline]
fn is_64(&self) -> bool {
self.macho.is_64
}
fn segments(&'file self) -> MachOSegmentIterator<'data, 'file> {
MachOSegmentIterator {
segments: self.macho.segments.iter(),
@@ -169,11 +173,6 @@ where
SymbolMap { symbols }
}
#[inline]
fn is_little_endian(&self) -> bool {
self.macho.little_endian
}
fn has_debug_symbols(&self) -> bool {
self.section_data_by_name(".debug_info").is_some()
}
-18
View File
@@ -38,24 +38,6 @@ pub type NativeFile<'data> = PeFile<'data>;
#[cfg(all(feature = "wasm", target_arch = "wasm32"))]
pub type NativeFile<'data> = WasmFile<'data>;
/// The machine type of an object file.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Machine {
/// An unrecognized machine type.
Other,
/// ARM
Arm,
/// ARM64
Arm64,
/// x86
X86,
/// x86-64
#[allow(non_camel_case_types)]
X86_64,
/// MIPS
Mips,
}
/// The kind of a section.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SectionKind {
+20 -21
View File
@@ -1,12 +1,12 @@
use crate::alloc::borrow::Cow;
use crate::alloc::vec::Vec;
use std::{cmp, iter, slice};
use goblin::pe;
use std::{cmp, iter, slice};
use target_lexicon::Architecture;
use crate::read::{
self, Machine, Object, ObjectSection, ObjectSegment, Relocation, SectionIndex, SectionKind,
Symbol, SymbolIndex, SymbolKind, SymbolMap,
self, Object, ObjectSection, ObjectSegment, Relocation, SectionIndex, SectionKind, Symbol,
SymbolIndex, SymbolKind, SymbolMap,
};
/// A PE object file.
@@ -30,12 +30,6 @@ impl<'data> PeFile<'data> {
Ok(PeFile { pe, data })
}
/// True for 64-bit files.
#[inline]
pub fn is_64(&self) -> bool {
self.pe.is_64
}
fn section_alignment(&self) -> u64 {
u64::from(
self.pe
@@ -57,15 +51,27 @@ where
type SectionIterator = PeSectionIterator<'data, 'file>;
type SymbolIterator = PeSymbolIterator<'data, 'file>;
fn machine(&self) -> Machine {
fn architecture(&self) -> Architecture {
match self.pe.header.coff_header.machine {
// TODO: Arm/Arm64
pe::header::COFF_MACHINE_X86 => Machine::X86,
pe::header::COFF_MACHINE_X86_64 => Machine::X86_64,
_ => Machine::Other,
pe::header::COFF_MACHINE_X86 => Architecture::I386,
pe::header::COFF_MACHINE_X86_64 => Architecture::X86_64,
_ => Architecture::Unknown,
}
}
#[inline]
fn is_little_endian(&self) -> bool {
// TODO: always little endian? The COFF header has some bits in the
// characteristics flags, but these are obsolete.
true
}
#[inline]
fn is_64(&self) -> bool {
self.pe.is_64
}
fn segments(&'file self) -> PeSegmentIterator<'data, 'file> {
PeSegmentIterator {
file: self,
@@ -122,13 +128,6 @@ where
SymbolMap { symbols }
}
#[inline]
fn is_little_endian(&self) -> bool {
// TODO: always little endian? The COFF header has some bits in the
// characteristics flags, but these are obsolete.
true
}
fn has_debug_symbols(&self) -> bool {
// TODO: check if CodeView-in-PE still works
for section in &self.pe.sections {
+21 -6
View File
@@ -1,5 +1,7 @@
use crate::alloc::borrow::Cow;
use crate::{Machine, Relocation, SectionIndex, SectionKind, Symbol, SymbolIndex, SymbolMap, Uuid};
use crate::{Relocation, SectionIndex, SectionKind, Symbol, SymbolIndex, SymbolMap};
use target_lexicon::{Architecture, Endianness};
use uuid::Uuid;
/// An object file.
pub trait Object<'data, 'file> {
@@ -18,8 +20,24 @@ pub trait Object<'data, 'file> {
/// An iterator over the symbols in the object file.
type SymbolIterator: Iterator<Item = (SymbolIndex, Symbol<'data>)>;
/// Get the machine type of the file.
fn machine(&self) -> Machine;
/// Get the architecture type of the file.
fn architecture(&self) -> Architecture;
/// Get the endianness of the file.
#[inline]
fn endianness(&self) -> Endianness {
if self.is_little_endian() {
Endianness::Little
} else {
Endianness::Big
}
}
/// Return true if the file is little endian, false if it is big endian.
fn is_little_endian(&self) -> bool;
/// Return true if the file can contain 64-bit addresses.
fn is_64(&self) -> bool;
/// Get an iterator over the segments in the file.
fn segments(&'file self) -> Self::SegmentIterator;
@@ -97,9 +115,6 @@ pub trait Object<'data, 'file> {
/// Construct a map from addresses to symbols.
fn symbol_map(&self) -> SymbolMap<'data>;
/// Return true if the file is little endian, false if it is big endian.
fn is_little_endian(&self) -> bool;
/// Return true if the file contains debug information sections, false if not.
fn has_debug_symbols(&self) -> bool;
+15 -7
View File
@@ -2,9 +2,10 @@ use crate::alloc::vec::Vec;
use parity_wasm::elements::{self, Deserialize};
use std::borrow::Cow;
use std::{iter, slice};
use target_lexicon::Architecture;
use crate::read::{
Machine, Object, ObjectSection, ObjectSegment, Relocation, SectionIndex, SectionKind, Symbol,
Object, ObjectSection, ObjectSegment, Relocation, SectionIndex, SectionKind, Symbol,
SymbolIndex, SymbolMap,
};
@@ -39,8 +40,19 @@ impl<'file> Object<'static, 'file> for WasmFile {
type SectionIterator = WasmSectionIterator<'file>;
type SymbolIterator = WasmSymbolIterator<'file>;
fn machine(&self) -> Machine {
Machine::Other
#[inline]
fn architecture(&self) -> Architecture {
Architecture::Wasm32
}
#[inline]
fn is_little_endian(&self) -> bool {
true
}
#[inline]
fn is_64(&self) -> bool {
false
}
fn segments(&'file self) -> Self::SegmentIterator {
@@ -86,10 +98,6 @@ impl<'file> Object<'static, 'file> for WasmFile {
}
}
fn is_little_endian(&self) -> bool {
true
}
fn has_debug_symbols(&self) -> bool {
// We ignore the "name" section, and use this to mean whether the wasm
// has DWARF.