Skip to content

Commit

Permalink
read: add Object::kind (#352)
Browse files Browse the repository at this point in the history
Use this to check for supported object kind in `objcopy` example.
  • Loading branch information
philipc authored Aug 16, 2021
1 parent 543d560 commit 0b76070
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 17 deletions.
8 changes: 6 additions & 2 deletions examples/objcopy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use std::collections::HashMap;
use std::{env, fs, process};

use object::{
write, Object, ObjectComdat, ObjectSection, ObjectSymbol, RelocationTarget, SectionKind,
SymbolFlags, SymbolKind, SymbolSection,
write, Object, ObjectComdat, ObjectKind, ObjectSection, ObjectSymbol, RelocationTarget,
SectionKind, SymbolFlags, SymbolKind, SymbolSection,
};

fn main() {
Expand Down Expand Up @@ -38,6 +38,10 @@ fn main() {
process::exit(1);
}
};
if in_object.kind() != ObjectKind::Relocatable {
eprintln!("Unsupported object kind: {:?}", in_object.kind());
process::exit(1);
}

let mut out_object = write::Object::new(
in_object.format(),
Expand Down
1 change: 1 addition & 0 deletions examples/objdump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ fn dump_parsed_object(file: &object::File) {
file.endianness(),
if file.is_64() { "64" } else { "32" }
);
println!("Kind: {:?}", file.kind());
println!("Architecture: {:?}", file.architecture());
println!("Flags: {:x?}", file.flags());
println!("Relative Address Base: {:x?}", file.relative_address_base());
Expand Down
12 changes: 8 additions & 4 deletions src/read/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ use crate::read::pe;
use crate::read::wasm;
use crate::read::{
self, Architecture, BinaryFormat, CodeView, ComdatKind, CompressedData, CompressedFileRange,
Error, Export, FileFlags, FileKind, Import, Object, ObjectComdat, ObjectMap, ObjectSection,
ObjectSegment, ObjectSymbol, ObjectSymbolTable, ReadRef, Relocation, Result, SectionFlags,
SectionIndex, SectionKind, SymbolFlags, SymbolIndex, SymbolKind, SymbolMap, SymbolMapName,
SymbolScope, SymbolSection,
Error, Export, FileFlags, FileKind, Import, Object, ObjectComdat, ObjectKind, ObjectMap,
ObjectSection, ObjectSegment, ObjectSymbol, ObjectSymbolTable, ReadRef, Relocation, Result,
SectionFlags, SectionIndex, SectionKind, SymbolFlags, SymbolIndex, SymbolKind, SymbolMap,
SymbolMapName, SymbolScope, SymbolSection,
};
#[allow(unused_imports)]
use crate::Endianness;
Expand Down Expand Up @@ -286,6 +286,10 @@ where
with_inner!(self.inner, FileInternal, |x| x.is_64())
}

fn kind(&self) -> ObjectKind {
with_inner!(self.inner, FileInternal, |x| x.kind())
}

fn segments(&'file self) -> SegmentIterator<'data, 'file, R> {
SegmentIterator {
inner: map_inner!(self.inner, FileInternal, SegmentIteratorInternal, |x| x
Expand Down
6 changes: 5 additions & 1 deletion src/read/coff/file.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use alloc::vec::Vec;

use crate::read::{
self, Architecture, Export, FileFlags, Import, NoDynamicRelocationIterator, Object,
self, Architecture, Export, FileFlags, Import, NoDynamicRelocationIterator, Object, ObjectKind,
ObjectSection, ReadError, ReadRef, Result, SectionIndex, SymbolIndex,
};
use crate::{pe, LittleEndian as LE};
Expand Down Expand Up @@ -88,6 +88,10 @@ where
false
}

fn kind(&self) -> ObjectKind {
ObjectKind::Relocatable
}

fn segments(&'file self) -> CoffSegmentIterator<'data, 'file, R> {
CoffSegmentIterator {
file: self,
Expand Down
13 changes: 12 additions & 1 deletion src/read/elf/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use core::mem;

use crate::read::{
self, util, Architecture, ByteString, Bytes, Error, Export, FileFlags, Import, Object,
ReadError, ReadRef, SectionIndex, StringTable, SymbolIndex,
ObjectKind, ReadError, ReadRef, SectionIndex, StringTable, SymbolIndex,
};
use crate::{elf, endian, Endian, Endianness, Pod, U32};

Expand Down Expand Up @@ -189,6 +189,17 @@ where
self.header.is_class_64()
}

fn kind(&self) -> ObjectKind {
match self.header.e_type(self.endian) {
elf::ET_REL => ObjectKind::Relocatable,
elf::ET_EXEC => ObjectKind::Executable,
// TODO: check for `DF_1_PIE`?
elf::ET_DYN => ObjectKind::Dynamic,
elf::ET_CORE => ObjectKind::Core,
_ => ObjectKind::Unknown,
}
}

fn segments(&'file self) -> ElfSegmentIterator<'data, 'file, Elf, R> {
ElfSegmentIterator {
file: self,
Expand Down
14 changes: 12 additions & 2 deletions src/read/macho/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use core::{mem, str};

use crate::read::{
self, Architecture, ComdatKind, Error, Export, FileFlags, Import, NoDynamicRelocationIterator,
Object, ObjectComdat, ObjectMap, ObjectSection, ReadError, ReadRef, Result, SectionIndex,
SymbolIndex,
Object, ObjectComdat, ObjectKind, ObjectMap, ObjectSection, ReadError, ReadRef, Result,
SectionIndex, SymbolIndex,
};
use crate::{endian, macho, BigEndian, ByteString, Endian, Endianness, Pod};

Expand Down Expand Up @@ -142,6 +142,16 @@ where
self.header.is_type_64()
}

fn kind(&self) -> ObjectKind {
match self.header.filetype(self.endian) {
macho::MH_OBJECT => ObjectKind::Relocatable,
macho::MH_EXECUTE => ObjectKind::Executable,
macho::MH_CORE => ObjectKind::Core,
macho::MH_DYLIB => ObjectKind::Dynamic,
_ => ObjectKind::Unknown,
}
}

fn segments(&'file self) -> MachOSegmentIterator<'data, 'file, Mach, R> {
MachOSegmentIterator {
file: self,
Expand Down
18 changes: 17 additions & 1 deletion src/read/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ pub type NativeFile<'data, R = &'data [u8]> = pe::PeFile64<'data, R>;
#[cfg(all(feature = "wasm", target_arch = "wasm32", feature = "wasm"))]
pub type NativeFile<'data, R = &'data [u8]> = wasm::WasmFile<'data, R>;

/// An object file kind.
/// A file format kind.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum FileKind {
Expand Down Expand Up @@ -242,6 +242,22 @@ impl FileKind {
}
}

/// An object kind.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum ObjectKind {
/// The object kind is unknown.
Unknown,
/// Relocatable object.
Relocatable,
/// Executable.
Executable,
/// Dynamic shared object.
Dynamic,
/// Core.
Core,
}

/// The index used to identify a section of a file.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SectionIndex(pub usize);
Expand Down
13 changes: 12 additions & 1 deletion src/read/pe/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use core::convert::TryInto;
use crate::read::coff::{CoffCommon, CoffSymbol, CoffSymbolIterator, CoffSymbolTable, SymbolTable};
use crate::read::{
self, Architecture, ComdatKind, Error, Export, FileFlags, Import, NoDynamicRelocationIterator,
Object, ObjectComdat, ReadError, ReadRef, Result, SectionIndex, SymbolIndex,
Object, ObjectComdat, ObjectKind, ReadError, ReadRef, Result, SectionIndex, SymbolIndex,
};
use crate::{pe, ByteString, Bytes, CodeView, LittleEndian as LE, Pod, U32, U64};

Expand Down Expand Up @@ -140,6 +140,17 @@ where
self.nt_headers.is_type_64()
}

fn kind(&self) -> ObjectKind {
let characteristics = self.nt_headers.file_header().characteristics.get(LE);
if characteristics & pe::IMAGE_FILE_DLL != 0 {
ObjectKind::Dynamic
} else if characteristics & pe::IMAGE_FILE_SYSTEM != 0 {
ObjectKind::Unknown
} else {
ObjectKind::Executable
}
}

fn segments(&'file self) -> PeSegmentIterator<'data, 'file, Pe, R> {
PeSegmentIterator {
file: self,
Expand Down
8 changes: 6 additions & 2 deletions src/read/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ use alloc::vec::Vec;

use crate::read::{
self, Architecture, CodeView, ComdatKind, CompressedData, CompressedFileRange, Export,
FileFlags, Import, ObjectMap, Relocation, Result, SectionFlags, SectionIndex, SectionKind,
SymbolFlags, SymbolIndex, SymbolKind, SymbolMap, SymbolMapName, SymbolScope, SymbolSection,
FileFlags, Import, ObjectKind, ObjectMap, Relocation, Result, SectionFlags, SectionIndex,
SectionKind, SymbolFlags, SymbolIndex, SymbolKind, SymbolMap, SymbolMapName, SymbolScope,
SymbolSection,
};
use crate::Endianness;

Expand Down Expand Up @@ -66,6 +67,9 @@ pub trait Object<'data: 'file, 'file>: read::private::Sealed {
/// Return true if the file can contain 64-bit addresses.
fn is_64(&self) -> bool;

/// Return the kind of this object.
fn kind(&self) -> ObjectKind;

/// Get an iterator over the segments in the file.
fn segments(&'file self) -> Self::SegmentIterator;

Expand Down
12 changes: 9 additions & 3 deletions src/read/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ use wasmparser as wp;

use crate::read::{
self, Architecture, ComdatKind, CompressedData, CompressedFileRange, Error, Export, FileFlags,
Import, NoDynamicRelocationIterator, Object, ObjectComdat, ObjectSection, ObjectSegment,
ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, Relocation, Result, SectionFlags,
SectionIndex, SectionKind, SymbolFlags, SymbolIndex, SymbolKind, SymbolScope, SymbolSection,
Import, NoDynamicRelocationIterator, Object, ObjectComdat, ObjectKind, ObjectSection,
ObjectSegment, ObjectSymbol, ObjectSymbolTable, ReadError, ReadRef, Relocation, Result,
SectionFlags, SectionIndex, SectionKind, SymbolFlags, SymbolIndex, SymbolKind, SymbolScope,
SymbolSection,
};

const SECTION_CUSTOM: usize = 0;
Expand Down Expand Up @@ -326,6 +327,11 @@ where
false
}

fn kind(&self) -> ObjectKind {
// TODO: check for `linking` custom section
ObjectKind::Unknown
}

fn segments(&'file self) -> Self::SegmentIterator {
WasmSegmentIterator { file: self }
}
Expand Down

0 comments on commit 0b76070

Please sign in to comment.