Skip to content

Commit

Permalink
read: Documentation improvements (#610)
Browse files Browse the repository at this point in the history
Fix links, add some examples, and various other tweaks.
  • Loading branch information
philipc authored Dec 18, 2023
1 parent f242fe7 commit c87a9bd
Show file tree
Hide file tree
Showing 54 changed files with 834 additions and 354 deletions.
16 changes: 7 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,14 @@ use object::{Object, ObjectSection};
use std::error::Error;
use std::fs;

/// Reads a file and displays the content of the ".boot" section.
/// Reads a file and displays the name of each section.
fn main() -> Result<(), Box<dyn Error>> {
let bin_data = fs::read("./multiboot2-binary.elf")?;
let obj_file = object::File::parse(&*bin_data)?;
if let Some(section) = obj_file.section_by_name(".boot") {
println!("{:#x?}", section.data()?);
} else {
eprintln!("section not available");
}
Ok(())
let binary_data = fs::read("path/to/binary")?;
let file = object::File::parse(&*binary_data)?;
for section in file.sections() {
println!("{}", section.name()?);
}
Ok(())
}
```

Expand Down
48 changes: 15 additions & 33 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,52 +8,34 @@
//!
//! Raw structs are defined for: [ELF](elf), [Mach-O](macho), [PE/COFF](pe),
//! [XCOFF](xcoff), [archive].
//! Types and traits for zerocopy support are defined in [pod] and [endian].
//! Types and traits for zerocopy support are defined in the [`pod`] and [`endian`] modules.
//!
//! ## Unified read API
//!
//! The [read::Object] trait defines the unified interface. This trait is implemented
//! by [read::File], which allows reading any file format, as well as implementations
//! for each file format: [ELF](read::elf::ElfFile), [Mach-O](read::macho::MachOFile),
//! [COFF](read::coff::CoffFile), [PE](read::pe::PeFile), [Wasm](read::wasm::WasmFile),
//! [XCOFF](read::xcoff::XcoffFile).
//! The [`read`] module provides a unified read API using the [`read::Object`] trait.
//! There is an implementation of this trait for [`read::File`], which allows reading any
//! file format, as well as implementations for each file format.
//!
//! ## Low level read API
//!
//! In addition to the unified read API, the various `read` modules define helpers that
//! operate on the raw structs. These also provide traits that abstract over the differences
//! between 32-bit and 64-bit versions of the file format.
//! The [`read#modules`] submodules define helpers that operate on the raw structs.
//! These can be used instead of the unified API, or in conjunction with it to access
//! details that are not available via the unified API.
//!
//! ## Unified write API
//!
//! [write::Object] allows building a COFF/ELF/Mach-O/XCOFF relocatable object file and
//! then writing it out.
//! The [`mod@write`] module provides a unified write API for relocatable object files
//! using [`write::Object`]. This does not support writing executable files.
//!
//! ## Low level executable writers
//! ## Low level write API
//!
//! [write::elf::Writer] and [write::pe::Writer] allow writing executable files.
//! The [`mod@write#modules`] submodules define helpers for writing the raw structs.
//!
//! ## Example for unified read API
//! ```no_run
//! # #[cfg(feature = "read")]
//! use object::{Object, ObjectSection};
//! use std::error::Error;
//! use std::fs;
//! ## Shared definitions
//!
//! /// Reads a file and displays the content of the ".boot" section.
//! fn main() -> Result<(), Box<dyn Error>> {
//! # #[cfg(all(feature = "read", feature = "std"))] {
//! let bin_data = fs::read("./multiboot2-binary.elf")?;
//! let obj_file = object::File::parse(&*bin_data)?;
//! if let Some(section) = obj_file.section_by_name(".boot") {
//! println!("{:#x?}", section.data()?);
//! } else {
//! eprintln!("section not available");
//! }
//! # }
//! Ok(())
//! }
//! ```
//! The crate provides a number of definitions that are used by both the read and write
//! APIs. These are defined at the top level module, but none of these are the main entry
//! points of the crate.

#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
Expand Down
38 changes: 24 additions & 14 deletions src/read/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,9 @@ macro_rules! next_inner {
};
}

/// An object file.
/// An object file that can be any supported file format.
///
/// Most functionality is provided by the `Object` trait implementation.
/// Most functionality is provided by the [`Object`] trait implementation.
#[derive(Debug)]
#[non_exhaustive]
#[allow(missing_docs)]
Expand Down Expand Up @@ -485,7 +485,7 @@ where
}
}

/// An iterator over the segments of a `File`.
/// An iterator for the loadable segments in a [`File`].
#[derive(Debug)]
pub struct SegmentIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
inner: SegmentIteratorInternal<'data, 'file, R>,
Expand Down Expand Up @@ -526,7 +526,9 @@ impl<'data, 'file, R: ReadRef<'data>> Iterator for SegmentIterator<'data, 'file,
}
}

/// A segment of a `File`.
/// A loadable segment in a [`File`].
///
/// Most functionality is provided by the [`ObjectSegment`] trait implementation.
pub struct Segment<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
inner: SegmentInternal<'data, 'file, R>,
}
Expand Down Expand Up @@ -616,7 +618,7 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSegment<'data> for Segment<'data, 'f
}
}

/// An iterator of the sections of a `File`.
/// An iterator for the sections in a [`File`].
#[derive(Debug)]
pub struct SectionIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
inner: SectionIteratorInternal<'data, 'file, R>,
Expand Down Expand Up @@ -658,7 +660,9 @@ impl<'data, 'file, R: ReadRef<'data>> Iterator for SectionIterator<'data, 'file,
}
}

/// A Section of a File
/// A section in a [`File`].
///
/// Most functionality is provided by the [`ObjectSection`] trait implementation.
pub struct Section<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
inner: SectionInternal<'data, 'file, R>,
}
Expand Down Expand Up @@ -788,7 +792,7 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSection<'data> for Section<'data, 'f
}
}

/// An iterator of the COMDAT section groups of a `File`.
/// An iterator for the COMDAT section groups in a [`File`].
#[derive(Debug)]
pub struct ComdatIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
inner: ComdatIteratorInternal<'data, 'file, R>,
Expand Down Expand Up @@ -829,7 +833,9 @@ impl<'data, 'file, R: ReadRef<'data>> Iterator for ComdatIterator<'data, 'file,
}
}

/// A COMDAT section group of a `File`.
/// A COMDAT section group in a [`File`].
///
/// Most functionality is provided by the [`ObjectComdat`] trait implementation.
pub struct Comdat<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
inner: ComdatInternal<'data, 'file, R>,
}
Expand Down Expand Up @@ -902,7 +908,7 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectComdat<'data> for Comdat<'data, 'fil
}
}

/// An iterator over COMDAT section entries.
/// An iterator for the sections in a [`Comdat`].
#[derive(Debug)]
pub struct ComdatSectionIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
inner: ComdatSectionIteratorInternal<'data, 'file, R>,
Expand Down Expand Up @@ -942,7 +948,9 @@ impl<'data, 'file, R: ReadRef<'data>> Iterator for ComdatSectionIterator<'data,
}
}

/// A symbol table.
/// A symbol table in a [`File`].
///
/// Most functionality is provided by the [`ObjectSymbolTable`] trait implementation.
#[derive(Debug)]
pub struct SymbolTable<'data, 'file, R = &'data [u8]>
where
Expand Down Expand Up @@ -1026,7 +1034,7 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSymbolTable<'data> for SymbolTable<'
}
}

/// An iterator over symbol table entries.
/// An iterator for the symbols in a [`SymbolTable`].
#[derive(Debug)]
pub struct SymbolIterator<'data, 'file, R = &'data [u8]>
where
Expand Down Expand Up @@ -1105,7 +1113,9 @@ impl<'data, 'file, R: ReadRef<'data>> Iterator for SymbolIterator<'data, 'file,
}
}

/// A symbol table entry.
/// An symbol in a [`SymbolTable`].
///
/// Most functionality is provided by the [`ObjectSymbol`] trait implementation.
pub struct Symbol<'data, 'file, R = &'data [u8]>
where
R: ReadRef<'data>,
Expand Down Expand Up @@ -1240,7 +1250,7 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSymbol<'data> for Symbol<'data, 'fil
}
}

/// An iterator over dynamic relocation entries.
/// An iterator for the dynamic relocation entries in a [`File`].
#[derive(Debug)]
pub struct DynamicRelocationIterator<'data, 'file, R = &'data [u8]>
where
Expand Down Expand Up @@ -1277,7 +1287,7 @@ impl<'data, 'file, R: ReadRef<'data>> Iterator for DynamicRelocationIterator<'da
}
}

/// An iterator over section relocation entries.
/// An iterator for the relocation entries in a [`Section`].
#[derive(Debug)]
pub struct SectionRelocationIterator<'data, 'file, R: ReadRef<'data> = &'data [u8]> {
inner: SectionRelocationIteratorInternal<'data, 'file, R>,
Expand Down
20 changes: 20 additions & 0 deletions src/read/archive.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,24 @@
//! Support for archive files.
//!
//! ## Example
//! ```no_run
//! use object::{Object, ObjectSection};
//! use std::error::Error;
//! use std::fs;
//!
//! /// Reads an archive and displays the name of each member.
//! fn main() -> Result<(), Box<dyn Error>> {
//! # #[cfg(feature = "std")] {
//! let data = fs::read("path/to/binary")?;
//! let file = object::read::archive::ArchiveFile::parse(&*data)?;
//! for member in file.members() {
//! let member = member?;
//! println!("{}", String::from_utf8_lossy(member.name()));
//! }
//! # }
//! Ok(())
//! }
//! ```

use core::convert::TryInto;

Expand Down
16 changes: 10 additions & 6 deletions src/read/coff/comdat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ use crate::read::{

use super::{CoffFile, CoffHeader, ImageSymbol};

/// An iterator over the COMDAT section groups of a `CoffBigFile`.
/// An iterator for the COMDAT section groups in a [`CoffBigFile`](super::CoffBigFile).
pub type CoffBigComdatIterator<'data, 'file, R = &'data [u8]> =
CoffComdatIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>;

/// An iterator over the COMDAT section groups of a `CoffFile`.
/// An iterator for the COMDAT section groups in a [`CoffFile`].
#[derive(Debug)]
pub struct CoffComdatIterator<
'data,
Expand Down Expand Up @@ -41,11 +41,15 @@ impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator
}
}

/// A COMDAT section group of a `CoffBigFile`.
/// A COMDAT section group in a [`CoffBigFile`](super::CoffBigFile).
///
/// Most functionality is provided by the [`ObjectComdat`] trait implementation.
pub type CoffBigComdat<'data, 'file, R = &'data [u8]> =
CoffComdat<'data, 'file, R, pe::AnonObjectHeaderBigobj>;

/// A COMDAT section group of a `CoffFile`.
/// A COMDAT section group in a [`CoffFile`].
///
/// Most functionality is provided by the [`ObjectComdat`] trait implementation.
#[derive(Debug)]
pub struct CoffComdat<
'data,
Expand Down Expand Up @@ -150,11 +154,11 @@ impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> ObjectComdat<'data>
}
}

/// An iterator over the sections in a COMDAT section group of a `CoffBigFile`.
/// An iterator for the sections in a COMDAT section group in a [`CoffBigFile`](super::CoffBigFile).
pub type CoffBigComdatSectionIterator<'data, 'file, R = &'data [u8]> =
CoffComdatSectionIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>;

/// An iterator over the sections in a COMDAT section group of a `CoffFile`.
/// An iterator for the sections in a COMDAT section group in a [`CoffFile`].
#[derive(Debug)]
pub struct CoffComdatSectionIterator<
'data,
Expand Down
16 changes: 13 additions & 3 deletions src/read/coff/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,19 @@ pub(crate) struct CoffCommon<'data, R: ReadRef<'data>, Coff: CoffHeader = pe::Im
}

/// A COFF bigobj object file with 32-bit section numbers.
///
/// This is a file that starts with [`pe::AnonObjectHeaderBigobj`], and corresponds
/// to [`crate::FileKind::CoffBig`].
///
/// Most functionality is provided by the [`Object`] trait implementation.
pub type CoffBigFile<'data, R = &'data [u8]> = CoffFile<'data, R, pe::AnonObjectHeaderBigobj>;

/// A COFF object file.
///
/// This is a file that starts with [`pe::ImageFileHeader`], and corresponds
/// to [`crate::FileKind::Coff`].
///
/// Most functionality is provided by the [`Object`] trait implementation.
#[derive(Debug)]
pub struct CoffFile<'data, R: ReadRef<'data> = &'data [u8], Coff: CoffHeader = pe::ImageFileHeader>
{
Expand Down Expand Up @@ -222,7 +232,7 @@ where
}
}

/// Read the `class_id` field from an anon object header.
/// Read the `class_id` field from a [`pe::AnonObjectHeader`].
///
/// This can be used to determine the format of the header.
pub fn anon_object_class_id<'data, R: ReadRef<'data>>(data: R) -> Result<pe::ClsId> {
Expand All @@ -232,13 +242,13 @@ pub fn anon_object_class_id<'data, R: ReadRef<'data>>(data: R) -> Result<pe::Cls
Ok(header.class_id)
}

/// A trait for generic access to `ImageFileHeader` and `AnonObjectHeaderBigobj`.
/// A trait for generic access to [`pe::ImageFileHeader`] and [`pe::AnonObjectHeaderBigobj`].
#[allow(missing_docs)]
pub trait CoffHeader: Debug + Pod {
type ImageSymbol: ImageSymbol;
type ImageSymbolBytes: Debug + Pod;

/// Return true if this type is `AnonObjectHeaderBigobj`.
/// Return true if this type is [`pe::AnonObjectHeaderBigobj`].
///
/// This is a property of the type, not a value in the header data.
fn is_type_bigobj() -> bool;
Expand Down
5 changes: 4 additions & 1 deletion src/read/coff/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ use crate::{pe, ByteString, Bytes, LittleEndian as LE, SubArchitecture};
///
/// Used in Windows import libraries to provide a mapping from
/// a symbol name to a DLL export. This is not an object file.
///
/// This is a file that starts with [`pe::ImportObjectHeader`], and corresponds
/// to [`crate::FileKind::CoffImport`].
#[derive(Debug, Clone)]
pub struct ImportFile<'data> {
header: &'data pe::ImportObjectHeader,
Expand Down Expand Up @@ -189,7 +192,7 @@ impl pe::ImportObjectHeader {
}
}

/// The data following `ImportObjectHeader`.
/// The data following [`pe::ImportObjectHeader`].
#[derive(Debug, Clone)]
pub struct ImportObjectData<'data> {
symbol: ByteString<'data>,
Expand Down
Loading

0 comments on commit c87a9bd

Please sign in to comment.