mirror of
https://github.com/encounter/object.git
synced 2026-03-30 11:32:22 -07:00
Use target-lexicon
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user