diff --git a/README.md b/README.md index 5b90fca3..08d9c803 100644 --- a/README.md +++ b/README.md @@ -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> { - 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(()) } ``` diff --git a/src/lib.rs b/src/lib.rs index e17802c4..a1f31cc4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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> { -//! # #[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)] diff --git a/src/read/any.rs b/src/read/any.rs index 254d7bd9..a14e56d3 100644 --- a/src/read/any.rs +++ b/src/read/any.rs @@ -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)] @@ -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>, @@ -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>, } @@ -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>, @@ -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>, } @@ -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>, @@ -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>, } @@ -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>, @@ -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 @@ -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 @@ -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>, @@ -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 @@ -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>, diff --git a/src/read/archive.rs b/src/read/archive.rs index f5aaa9b1..5d4ec4a4 100644 --- a/src/read/archive.rs +++ b/src/read/archive.rs @@ -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> { +//! # #[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; diff --git a/src/read/coff/comdat.rs b/src/read/coff/comdat.rs index 22e061a2..90c29be6 100644 --- a/src/read/coff/comdat.rs +++ b/src/read/coff/comdat.rs @@ -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, @@ -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, @@ -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, diff --git a/src/read/coff/file.rs b/src/read/coff/file.rs index a82e3105..40b9e708 100644 --- a/src/read/coff/file.rs +++ b/src/read/coff/file.rs @@ -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> { @@ -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 { @@ -232,13 +242,13 @@ pub fn anon_object_class_id<'data, R: ReadRef<'data>>(data: R) -> Result bool; diff --git a/src/read/coff/import.rs b/src/read/coff/import.rs index e4c64004..a296ac31 100644 --- a/src/read/coff/import.rs +++ b/src/read/coff/import.rs @@ -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, @@ -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>, diff --git a/src/read/coff/mod.rs b/src/read/coff/mod.rs index 26020d79..de397da0 100644 --- a/src/read/coff/mod.rs +++ b/src/read/coff/mod.rs @@ -1,6 +1,51 @@ //! Support for reading Windows COFF files. //! -//! Provides `CoffFile` and related types which implement the `Object` trait. +//! Traits are used to abstract over the difference between COFF object files +//! and COFF bigobj files. The primary trait for this is [`CoffHeader`]. +//! +//! ## High level API +//! +//! [`CoffFile`] implements the [`Object`](crate::read::Object) trait for +//! COFF files. [`CoffFile`] is parameterised by [`CoffHeader`]. +//! The default parameter allows reading regular COFF object files, +//! while the type alias [`CoffBigFile`] allows reading COFF bigobj files. +//! +//! [`ImportFile`] allows reading COFF short imports that are used in import +//! libraries. Currently these are not integrated with the unified read API. +//! +//! ## Low level API +//! +//! The [`CoffHeader`] trait can be directly used to parse both COFF +//! object files (which start with [`pe::ImageFileHeader`]) and COFF bigobj +//! files (which start with [`pe::AnonObjectHeaderBigobj`]). +//! +//! ### Example for low level API +//! ```no_run +//! use object::pe; +//! use object::read::coff::{CoffHeader, ImageSymbol as _}; +//! use std::error::Error; +//! use std::fs; +//! +//! /// Reads a file and displays the name of each section and symbol. +//! fn main() -> Result<(), Box> { +//! # #[cfg(feature = "std")] { +//! let data = fs::read("path/to/binary")?; +//! let mut offset = 0; +//! let header = pe::ImageFileHeader::parse(&*data, &mut offset)?; +//! let sections = header.sections(&*data, offset)?; +//! let symbols = header.symbols(&*data)?; +//! for section in sections.iter() { +//! println!("{}", String::from_utf8_lossy(section.name(symbols.strings())?)); +//! } +//! for (_index, symbol) in symbols.iter() { +//! println!("{}", String::from_utf8_lossy(symbol.name(symbols.strings())?)); +//! } +//! # } +//! Ok(()) +//! } +//! ``` +#[cfg(doc)] +use crate::pe; mod file; pub use file::*; diff --git a/src/read/coff/relocation.rs b/src/read/coff/relocation.rs index 85f769d0..e9909448 100644 --- a/src/read/coff/relocation.rs +++ b/src/read/coff/relocation.rs @@ -9,11 +9,11 @@ use crate::read::{ use super::{CoffFile, CoffHeader}; -/// An iterator over the relocations in a `CoffBigSection`. +/// An iterator for the relocations in a [`CoffBigSection`](super::CoffBigSection). pub type CoffBigRelocationIterator<'data, 'file, R = &'data [u8]> = CoffRelocationIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>; -/// An iterator over the relocations in a `CoffSection`. +/// An iterator for the relocations in a [`CoffSection`](super::CoffSection). pub struct CoffRelocationIterator< 'data, 'file, diff --git a/src/read/coff/section.rs b/src/read/coff/section.rs index 75804034..84a3fa98 100644 --- a/src/read/coff/section.rs +++ b/src/read/coff/section.rs @@ -12,6 +12,9 @@ use crate::read::{ use super::{CoffFile, CoffHeader, CoffRelocationIterator}; /// The table of section headers in a COFF or PE file. +/// +/// Returned by [`CoffHeader::sections`] and +/// [`ImageNtHeaders::sections`](crate::read::pe::ImageNtHeaders::sections). #[derive(Debug, Default, Clone, Copy)] pub struct SectionTable<'data> { sections: &'data [pe::ImageSectionHeader], @@ -104,11 +107,11 @@ impl<'data> SectionTable<'data> { } } -/// An iterator over the loadable sections of a `CoffBigFile`. +/// An iterator for the loadable sections in a [`CoffBigFile`](super::CoffBigFile). pub type CoffBigSegmentIterator<'data, 'file, R = &'data [u8]> = CoffSegmentIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>; -/// An iterator over the loadable sections of a `CoffFile`. +/// An iterator for the loadable sections in a [`CoffFile`]. #[derive(Debug)] pub struct CoffSegmentIterator< 'data, @@ -133,11 +136,15 @@ impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator } } -/// A loadable section of a `CoffBigFile`. +/// A loadable section in a [`CoffBigFile`](super::CoffBigFile). +/// +/// Most functionality is provided by the [`ObjectSegment`] trait implementation. pub type CoffBigSegment<'data, 'file, R = &'data [u8]> = CoffSegment<'data, 'file, R, pe::AnonObjectHeaderBigobj>; -/// A loadable section of a `CoffFile`. +/// A loadable section in a [`CoffFile`]. +/// +/// Most functionality is provided by the [`ObjectSegment`] trait implementation. #[derive(Debug)] pub struct CoffSegment< 'data, @@ -222,11 +229,11 @@ impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> ObjectSegment<'data> } } -/// An iterator over the sections of a `CoffBigFile`. +/// An iterator for the sections in a [`CoffBigFile`](super::CoffBigFile). pub type CoffBigSectionIterator<'data, 'file, R = &'data [u8]> = CoffSectionIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>; -/// An iterator over the sections of a `CoffFile`. +/// An iterator for the sections in a [`CoffFile`]. #[derive(Debug)] pub struct CoffSectionIterator< 'data, @@ -252,11 +259,15 @@ impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator } } -/// A section of a `CoffBigFile`. +/// A section in a [`CoffBigFile`](super::CoffBigFile). +/// +/// Most functionality is provided by the [`ObjectSection`] trait implementation. pub type CoffBigSection<'data, 'file, R = &'data [u8]> = CoffSection<'data, 'file, R, pe::AnonObjectHeaderBigobj>; -/// A section of a `CoffFile`. +/// A section in a [`CoffFile`]. +/// +/// Most functionality is provided by the [`ObjectSection`] trait implementation. #[derive(Debug)] pub struct CoffSection< 'data, diff --git a/src/read/coff/symbol.rs b/src/read/coff/symbol.rs index 8adc4845..4f8a0c6e 100644 --- a/src/read/coff/symbol.rs +++ b/src/read/coff/symbol.rs @@ -17,6 +17,9 @@ use crate::read::{ /// A table of symbol entries in a COFF or PE file. /// /// Also includes the string table used for the symbol names. +/// +/// Returned by [`CoffHeader::symbols`] and +/// [`ImageNtHeaders::symbols`](crate::read::pe::ImageNtHeaders::symbols). #[derive(Debug)] pub struct SymbolTable<'data, R = &'data [u8], Coff = pe::ImageFileHeader> where @@ -187,11 +190,12 @@ impl<'data, 'table, R: ReadRef<'data>, Coff: CoffHeader> Iterator } } -/// A symbol table of a `CoffBigFile`. +/// A symbol table in a [`CoffBigFile`](super::CoffBigFile). pub type CoffBigSymbolTable<'data, 'file, R = &'data [u8]> = CoffSymbolTable<'data, 'file, R, pe::AnonObjectHeaderBigobj>; -/// A symbol table of a `CoffFile`. +/// A symbol table in a [`CoffFile`](super::CoffFile) +/// or [`PeFile`](crate::read::pe::PeFile). #[derive(Debug, Clone, Copy)] pub struct CoffSymbolTable<'data, 'file, R = &'data [u8], Coff = pe::ImageFileHeader> where @@ -229,11 +233,12 @@ impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> ObjectSymbolTable<'data> } } -/// An iterator over the symbols of a `CoffBigFile`. +/// An iterator for the symbols in a [`CoffBigFile`](super::CoffBigFile). pub type CoffBigSymbolIterator<'data, 'file, R = &'data [u8]> = CoffSymbolIterator<'data, 'file, R, pe::AnonObjectHeaderBigobj>; -/// An iterator over the symbols of a `CoffFile`. +/// An iterator for the symbols in a [`CoffFile`](super::CoffFile) +/// or [`PeFile`](crate::read::pe::PeFile). pub struct CoffSymbolIterator<'data, 'file, R = &'data [u8], Coff = pe::ImageFileHeader> where R: ReadRef<'data>, @@ -268,11 +273,15 @@ impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> Iterator } } -/// A symbol of a `CoffBigFile`. +/// A symbol in a [`CoffBigFile`](super::CoffBigFile). +/// +/// Most functionality is provided by the [`ObjectSymbol`] trait implementation. pub type CoffBigSymbol<'data, 'file, R = &'data [u8]> = CoffSymbol<'data, 'file, R, pe::AnonObjectHeaderBigobj>; -/// A symbol of a `CoffFile`. +/// A symbol in a [`CoffFile`](super::CoffFile) or [`PeFile`](crate::read::pe::PeFile). +/// +/// Most functionality is provided by the [`ObjectSymbol`] trait implementation. #[derive(Debug, Clone, Copy)] pub struct CoffSymbol<'data, 'file, R = &'data [u8], Coff = pe::ImageFileHeader> where @@ -496,7 +505,7 @@ impl<'data, 'file, R: ReadRef<'data>, Coff: CoffHeader> ObjectSymbol<'data> } } -/// A trait for generic access to `ImageSymbol` and `ImageSymbolEx`. +/// A trait for generic access to [`pe::ImageSymbol`] and [`pe::ImageSymbolEx`]. #[allow(missing_docs)] pub trait ImageSymbol: Debug + Pod { fn raw_name(&self) -> &[u8; 8]; diff --git a/src/read/elf/attributes.rs b/src/read/elf/attributes.rs index 6ec535d7..bf6f35cc 100644 --- a/src/read/elf/attributes.rs +++ b/src/read/elf/attributes.rs @@ -10,7 +10,10 @@ use super::FileHeader; /// /// This may be a GNU attributes section, or an architecture specific attributes section. /// -/// An attributes section contains a series of subsections. +/// An attributes section contains a series of [`AttributesSubsection`]. +/// +/// Returned by [`SectionHeader::attributes`](super::SectionHeader::attributes) +/// and [`SectionHeader::gnu_attributes`](super::SectionHeader::gnu_attributes). #[derive(Debug, Clone)] pub struct AttributesSection<'data, Elf: FileHeader> { endian: Elf::Endian, @@ -54,7 +57,7 @@ impl<'data, Elf: FileHeader> AttributesSection<'data, Elf> { } } -/// An iterator over the subsections in an ELF attributes section. +/// An iterator for the subsections in an [`AttributesSection`]. #[derive(Debug, Clone)] pub struct AttributesSubsectionIterator<'data, Elf: FileHeader> { endian: Elf::Endian, @@ -105,9 +108,10 @@ impl<'data, Elf: FileHeader> AttributesSubsectionIterator<'data, Elf> { } } -/// A subsection in an ELF attributes section. +/// A subsection in an [`AttributesSection`]. /// -/// A subsection is identified by a vendor name. It contains a series of sub-subsections. +/// A subsection is identified by a vendor name. It contains a series of +/// [`AttributesSubsubsection`]. #[derive(Debug, Clone)] pub struct AttributesSubsection<'data, Elf: FileHeader> { endian: Elf::Endian, @@ -136,7 +140,7 @@ impl<'data, Elf: FileHeader> AttributesSubsection<'data, Elf> { } } -/// An iterator over the sub-subsections in an ELF attributes section. +/// An iterator for the sub-subsections in an [`AttributesSubsection`]. #[derive(Debug, Clone)] pub struct AttributesSubsubsectionIterator<'data, Elf: FileHeader> { endian: Elf::Endian, @@ -200,7 +204,7 @@ impl<'data, Elf: FileHeader> AttributesSubsubsectionIterator<'data, Elf> { } } -/// A sub-subsection in an ELF attributes section. +/// A sub-subsection in an [`AttributesSubsection`]. /// /// A sub-subsection is identified by a tag. It contains an optional series of indices, /// followed by a series of attributes. @@ -248,7 +252,7 @@ impl<'data> AttributesSubsubsection<'data> { } } -/// An iterator over the indices in a sub-subsection in an ELF attributes section. +/// An iterator over the indices in an [`AttributesSubsubsection`]. #[derive(Debug, Clone)] pub struct AttributeIndexIterator<'data> { data: Bytes<'data>, @@ -271,7 +275,7 @@ impl<'data> AttributeIndexIterator<'data> { } } -/// A parser for the attributes in a sub-subsection in an ELF attributes section. +/// A parser for the attributes in an [`AttributesSubsubsection`]. /// /// The parser relies on the caller to know the format of the data for each attribute tag. #[derive(Debug, Clone)] diff --git a/src/read/elf/comdat.rs b/src/read/elf/comdat.rs index 1a2f2f44..882d2536 100644 --- a/src/read/elf/comdat.rs +++ b/src/read/elf/comdat.rs @@ -7,14 +7,14 @@ use crate::read::{self, ComdatKind, ObjectComdat, ReadError, ReadRef, SectionInd use super::{ElfFile, FileHeader, SectionHeader, Sym}; -/// An iterator over the COMDAT section groups of an `ElfFile32`. +/// An iterator for the COMDAT section groups in an [`ElfFile32`](super::ElfFile32). pub type ElfComdatIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfComdatIterator<'data, 'file, elf::FileHeader32, R>; -/// An iterator over the COMDAT section groups of an `ElfFile64`. +/// An iterator for the COMDAT section groups in an [`ElfFile64`](super::ElfFile64). pub type ElfComdatIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfComdatIterator<'data, 'file, elf::FileHeader64, R>; -/// An iterator over the COMDAT section groups of an `ElfFile`. +/// An iterator for the COMDAT section groups in an [`ElfFile`]. #[derive(Debug)] pub struct ElfComdatIterator<'data, 'file, Elf, R = &'data [u8]> where @@ -42,14 +42,16 @@ where } } -/// A COMDAT section group of an `ElfFile32`. +/// A COMDAT section group in an [`ElfFile32`](super::ElfFile32). pub type ElfComdat32<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfComdat<'data, 'file, elf::FileHeader32, R>; -/// A COMDAT section group of an `ElfFile64`. +/// A COMDAT section group in an [`ElfFile64`](super::ElfFile64). pub type ElfComdat64<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfComdat<'data, 'file, elf::FileHeader64, R>; -/// A COMDAT section group of an `ElfFile`. +/// A COMDAT section group in an [`ElfFile`]. +/// +/// Most functionality is provided by the [`ObjectComdat`] trait implementation. #[derive(Debug)] pub struct ElfComdat<'data, 'file, Elf, R = &'data [u8]> where @@ -128,14 +130,14 @@ where } } -/// An iterator over the sections in a COMDAT section group of an `ElfFile32`. +/// An iterator for the sections in a COMDAT section group in an [`ElfFile32`](super::ElfFile32). pub type ElfComdatSectionIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfComdatSectionIterator<'data, 'file, elf::FileHeader32, R>; -/// An iterator over the sections in a COMDAT section group of an `ElfFile64`. +/// An iterator for the sections in a COMDAT section group in an [`ElfFile64`](super::ElfFile64). pub type ElfComdatSectionIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfComdatSectionIterator<'data, 'file, elf::FileHeader64, R>; -/// An iterator over the sections in a COMDAT section group of an `ElfFile`. +/// An iterator for the sections in a COMDAT section group in an [`ElfFile`]. #[derive(Debug)] pub struct ElfComdatSectionIterator<'data, 'file, Elf, R = &'data [u8]> where diff --git a/src/read/elf/compression.rs b/src/read/elf/compression.rs index 7242dd39..de2533f2 100644 --- a/src/read/elf/compression.rs +++ b/src/read/elf/compression.rs @@ -4,7 +4,7 @@ use crate::elf; use crate::endian; use crate::pod::Pod; -/// A trait for generic access to `CompressionHeader32` and `CompressionHeader64`. +/// A trait for generic access to [`elf::CompressionHeader32`] and [`elf::CompressionHeader64`]. #[allow(missing_docs)] pub trait CompressionHeader: Debug + Pod { type Word: Into; diff --git a/src/read/elf/dynamic.rs b/src/read/elf/dynamic.rs index 5fe15b56..1661434a 100644 --- a/src/read/elf/dynamic.rs +++ b/src/read/elf/dynamic.rs @@ -6,7 +6,7 @@ use crate::endian; use crate::pod::Pod; use crate::read::{ReadError, Result, StringTable}; -/// A trait for generic access to `Dyn32` and `Dyn64`. +/// A trait for generic access to [`elf::Dyn32`] and [`elf::Dyn64`]. #[allow(missing_docs)] pub trait Dyn: Debug + Pod { type Word: Into; diff --git a/src/read/elf/file.rs b/src/read/elf/file.rs index 39c8ef38..14ba5685 100644 --- a/src/read/elf/file.rs +++ b/src/read/elf/file.rs @@ -17,15 +17,21 @@ use super::{ }; /// A 32-bit ELF object file. +/// +/// This is a file that starts with [`elf::FileHeader32`], and corresponds +/// to [`crate::FileKind::Elf32`]. pub type ElfFile32<'data, Endian = Endianness, R = &'data [u8]> = ElfFile<'data, elf::FileHeader32, R>; /// A 64-bit ELF object file. +/// +/// This is a file that starts with [`elf::FileHeader64`], and corresponds +/// to [`crate::FileKind::Elf64`]. pub type ElfFile64<'data, Endian = Endianness, R = &'data [u8]> = ElfFile<'data, elf::FileHeader64, R>; /// A partially parsed ELF file. /// -/// Most of the functionality of this type is provided by the `Object` trait implementation. +/// Most functionality is provided by the [`Object`] trait implementation. #[derive(Debug)] pub struct ElfFile<'data, Elf, R = &'data [u8]> where @@ -306,7 +312,6 @@ where }) } - /// Get the imported symbols. fn imports(&self) -> read::Result>> { let mut imports = Vec::new(); for symbol in self.dynamic_symbols.iter() { @@ -324,7 +329,6 @@ where Ok(imports) } - /// Get the exported symbols. fn exports(&self) -> read::Result>> { let mut exports = Vec::new(); for symbol in self.dynamic_symbols.iter() { @@ -437,7 +441,7 @@ where } } -/// A trait for generic access to `FileHeader32` and `FileHeader64`. +/// A trait for generic access to [`elf::FileHeader32`] and [`elf::FileHeader64`]. #[allow(missing_docs)] pub trait FileHeader: Debug + Pod { // Ideally this would be a `u64: From`, but can't express that. @@ -462,7 +466,7 @@ pub trait FileHeader: Debug + Pod { /// /// This is a property of the type, not a value in the header data. /// - /// This is the same as `is_type_64`, but is non-dispatchable. + /// This is the same as [`Self::is_type_64`], but is non-dispatchable. fn is_type_64_sized() -> bool where Self: Sized; diff --git a/src/read/elf/hash.rs b/src/read/elf/hash.rs index aadbb920..b0130cc9 100644 --- a/src/read/elf/hash.rs +++ b/src/read/elf/hash.rs @@ -7,6 +7,8 @@ use crate::{U32, U64}; use super::{FileHeader, Sym, SymbolTable, Version, VersionTable}; /// A SysV symbol hash table in an ELF file. +/// +/// Returned by [`SectionHeader::hash`](super::SectionHeader::hash). #[derive(Debug)] pub struct HashTable<'data, Elf: FileHeader> { buckets: &'data [U32], @@ -16,8 +18,8 @@ pub struct HashTable<'data, Elf: FileHeader> { impl<'data, Elf: FileHeader> HashTable<'data, Elf> { /// Parse a SysV hash table. /// - /// `data` should be from a `SHT_HASH` section, or from a - /// segment pointed to via the `DT_HASH` entry. + /// `data` should be from an [`elf::SHT_HASH`] section, or from a + /// segment pointed to via the [`elf::DT_HASH`] entry. /// /// The header is read at offset 0 in the given `data`. pub fn parse(endian: Elf::Endian, data: &'data [u8]) -> Result { @@ -70,6 +72,8 @@ impl<'data, Elf: FileHeader> HashTable<'data, Elf> { } /// A GNU symbol hash table in an ELF file. +/// +/// Returned by [`SectionHeader::gnu_hash`](super::SectionHeader::gnu_hash). #[derive(Debug)] pub struct GnuHashTable<'data, Elf: FileHeader> { symbol_base: u32, @@ -82,15 +86,15 @@ pub struct GnuHashTable<'data, Elf: FileHeader> { impl<'data, Elf: FileHeader> GnuHashTable<'data, Elf> { /// Parse a GNU hash table. /// - /// `data` should be from a `SHT_GNU_HASH` section, or from a - /// segment pointed to via the `DT_GNU_HASH` entry. + /// `data` should be from an [`elf::SHT_GNU_HASH`] section, or from a + /// segment pointed to via the [`elf::DT_GNU_HASH`] entry. /// /// The header is read at offset 0 in the given `data`. /// /// The header does not contain a length field, and so all of `data` /// will be used as the hash table values. It does not matter if this /// is longer than needed, and this will often the case when accessing - /// the hash table via the `DT_GNU_HASH` entry. + /// the hash table via the [`elf::DT_GNU_HASH`] entry. pub fn parse(endian: Elf::Endian, data: &'data [u8]) -> Result { let mut offset = 0; let header = data diff --git a/src/read/elf/mod.rs b/src/read/elf/mod.rs index 07db6cd6..66931bdd 100644 --- a/src/read/elf/mod.rs +++ b/src/read/elf/mod.rs @@ -1,9 +1,45 @@ //! Support for reading ELF files. //! -//! Defines traits to abstract over the difference between ELF32/ELF64, -//! and implements read functionality in terms of these traits. +//! Traits are used to abstract over the difference between 32-bit and 64-bit ELF. +//! The primary trait for this is [`FileHeader`]. //! -//! Also provides `ElfFile` and related types which implement the `Object` trait. +//! ## High level API +//! +//! [`ElfFile`] implements the [`Object`](crate::read::Object) trait for ELF files. +//! [`ElfFile`] is parameterised by [`FileHeader`] to allow reading both 32-bit and +//! 64-bit ELF. There are type aliases for these parameters ([`ElfFile32`] and +//! [`ElfFile64`]). +//! +//! ## Low level API +//! +//! The [`FileHeader`] trait can be directly used to parse both [`elf::FileHeader32`] +//! and [`elf::FileHeader64`]. +//! +//! ### Example for low level API +//! ```no_run +//! use object::elf; +//! use object::read::elf::{FileHeader, Sym}; +//! use std::error::Error; +//! use std::fs; +//! +//! /// Reads a file and displays the name of each symbol. +//! fn main() -> Result<(), Box> { +//! # #[cfg(feature = "std")] { +//! let data = fs::read("path/to/binary")?; +//! let elf = elf::FileHeader64::::parse(&*data)?; +//! let endian = elf.endian()?; +//! let sections = elf.sections(endian, &*data)?; +//! let symbols = sections.symbols(endian, &*data, elf::SHT_SYMTAB)?; +//! for symbol in symbols.iter() { +//! let name = symbol.name(endian, symbols.strings())?; +//! println!("{}", String::from_utf8_lossy(name)); +//! } +//! # } +//! Ok(()) +//! } +//! ``` +#[cfg(doc)] +use crate::elf; mod file; pub use file::*; diff --git a/src/read/elf/note.rs b/src/read/elf/note.rs index 84d4179d..e2beef92 100644 --- a/src/read/elf/note.rs +++ b/src/read/elf/note.rs @@ -10,6 +10,9 @@ use crate::read::{self, Bytes, Error, ReadError}; use super::FileHeader; /// An iterator over the notes in an ELF section or segment. +/// +/// Returned [`ProgramHeader::notes`](super::ProgramHeader::notes) +/// and [`SectionHeader::notes`](super::SectionHeader::notes). #[derive(Debug)] pub struct NoteIterator<'data, Elf> where @@ -84,7 +87,7 @@ where } } -/// A parsed `NoteHeader`. +/// A parsed [`NoteHeader`]. #[derive(Debug)] pub struct Note<'data, Elf> where @@ -141,7 +144,7 @@ impl<'data, Elf: FileHeader> Note<'data, Elf> { self.desc } - /// Return an iterator for properties if this note's type is `NT_GNU_PROPERTY_TYPE_0`. + /// Return an iterator for properties if this note's type is [`elf::NT_GNU_PROPERTY_TYPE_0`]. pub fn gnu_properties( &self, endian: Elf::Endian, @@ -160,7 +163,7 @@ impl<'data, Elf: FileHeader> Note<'data, Elf> { } } -/// A trait for generic access to `NoteHeader32` and `NoteHeader64`. +/// A trait for generic access to [`elf::NoteHeader32`] and [`elf::NoteHeader64`]. #[allow(missing_docs)] pub trait NoteHeader: Debug + Pod { type Endian: endian::Endian; @@ -208,7 +211,9 @@ impl NoteHeader for elf::NoteHeader64 { } } -/// An iterator over the properties in a `NT_GNU_PROPERTY_TYPE_0` note. +/// An iterator for the properties in a [`elf::NT_GNU_PROPERTY_TYPE_0`] note. +/// +/// Returned by [`Note::gnu_properties`]. #[derive(Debug)] pub struct GnuPropertyIterator<'data, Endian: endian::Endian> { endian: Endian, @@ -236,7 +241,7 @@ impl<'data, Endian: endian::Endian> GnuPropertyIterator<'data, Endian> { } } -/// A property in a `NT_GNU_PROPERTY_TYPE_0` note. +/// A property in a [`elf::NT_GNU_PROPERTY_TYPE_0`] note. #[derive(Debug)] pub struct GnuProperty<'data> { pr_type: u32, diff --git a/src/read/elf/relocation.rs b/src/read/elf/relocation.rs index 86ea1d7d..aac1574e 100644 --- a/src/read/elf/relocation.rs +++ b/src/read/elf/relocation.rs @@ -91,14 +91,14 @@ impl<'data, Elf: FileHeader> Iterator for ElfRelaIterator<'data, Elf> { } } -/// An iterator over the dynamic relocations for an `ElfFile32`. +/// An iterator for the dynamic relocations in an [`ElfFile32`](super::ElfFile32). pub type ElfDynamicRelocationIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfDynamicRelocationIterator<'data, 'file, elf::FileHeader32, R>; -/// An iterator over the dynamic relocations for an `ElfFile64`. +/// An iterator for the dynamic relocations in an [`ElfFile64`](super::ElfFile64). pub type ElfDynamicRelocationIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfDynamicRelocationIterator<'data, 'file, elf::FileHeader64, R>; -/// An iterator over the dynamic relocations for an `ElfFile`. +/// An iterator for the dynamic relocations in an [`ElfFile`]. pub struct ElfDynamicRelocationIterator<'data, 'file, Elf, R = &'data [u8]> where Elf: FileHeader, @@ -164,14 +164,14 @@ where } } -/// An iterator over the relocations for an `ElfSection32`. +/// An iterator for the relocations for an [`ElfSection32`](super::ElfSection32). pub type ElfSectionRelocationIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfSectionRelocationIterator<'data, 'file, elf::FileHeader32, R>; -/// An iterator over the relocations for an `ElfSection64`. +/// An iterator for the relocations for an [`ElfSection64`](super::ElfSection64). pub type ElfSectionRelocationIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfSectionRelocationIterator<'data, 'file, elf::FileHeader64, R>; -/// An iterator over the relocations for an `ElfSection`. +/// An iterator for the relocations for an [`ElfSection`](super::ElfSection). pub struct ElfSectionRelocationIterator<'data, 'file, Elf, R = &'data [u8]> where Elf: FileHeader, @@ -486,7 +486,7 @@ fn parse_relocation( } } -/// A trait for generic access to `Rel32` and `Rel64`. +/// A trait for generic access to [`elf::Rel32`] and [`elf::Rel64`]. #[allow(missing_docs)] pub trait Rel: Debug + Pod + Clone { type Word: Into; @@ -551,7 +551,7 @@ impl Rel for elf::Rel64 { } } -/// A trait for generic access to `Rela32` and `Rela64`. +/// A trait for generic access to [`elf::Rela32`] and [`elf::Rela64`]. #[allow(missing_docs)] pub trait Rela: Debug + Pod + Clone { type Word: Into; diff --git a/src/read/elf/section.rs b/src/read/elf/section.rs index df08f9e3..2b5ae01d 100644 --- a/src/read/elf/section.rs +++ b/src/read/elf/section.rs @@ -18,6 +18,8 @@ use super::{ /// The table of section headers in an ELF file. /// /// Also includes the string table used for the section names. +/// +/// Returned by [`FileHeader::sections`]. #[derive(Debug, Default, Clone, Copy)] pub struct SectionTable<'data, Elf: FileHeader, R = &'data [u8]> where @@ -318,14 +320,14 @@ impl<'data, Elf: FileHeader, R: ReadRef<'data>> SectionTable<'data, Elf, R> { } } -/// An iterator over the sections of an `ElfFile32`. +/// An iterator for the sections in an [`ElfFile32`](super::ElfFile32). pub type ElfSectionIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfSectionIterator<'data, 'file, elf::FileHeader32, R>; -/// An iterator over the sections of an `ElfFile64`. +/// An iterator for the sections in an [`ElfFile64`](super::ElfFile64). pub type ElfSectionIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfSectionIterator<'data, 'file, elf::FileHeader64, R>; -/// An iterator over the sections of an `ElfFile`. +/// An iterator for the sections in an [`ElfFile`]. #[derive(Debug)] pub struct ElfSectionIterator<'data, 'file, Elf, R = &'data [u8]> where @@ -352,14 +354,16 @@ where } } -/// A section of an `ElfFile32`. +/// A section in an [`ElfFile32`](super::ElfFile32). pub type ElfSection32<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfSection<'data, 'file, elf::FileHeader32, R>; -/// A section of an `ElfFile64`. +/// A section in an [`ElfFile64`](super::ElfFile64). pub type ElfSection64<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfSection<'data, 'file, elf::FileHeader64, R>; -/// A section of an `ElfFile`. +/// A section in an [`ElfFile`]. +/// +/// Most functionality is provided by the [`ObjectSection`] trait implementation. #[derive(Debug)] pub struct ElfSection<'data, 'file, Elf, R = &'data [u8]> where @@ -592,7 +596,7 @@ where } } -/// A trait for generic access to `SectionHeader32` and `SectionHeader64`. +/// A trait for generic access to [`elf::SectionHeader32`] and [`elf::SectionHeader64`]. #[allow(missing_docs)] pub trait SectionHeader: Debug + Pod { type Elf: FileHeader; diff --git a/src/read/elf/segment.rs b/src/read/elf/segment.rs index 3972731e..957117a4 100644 --- a/src/read/elf/segment.rs +++ b/src/read/elf/segment.rs @@ -8,14 +8,14 @@ use crate::read::{self, Bytes, ObjectSegment, ReadError, ReadRef, SegmentFlags}; use super::{ElfFile, FileHeader, NoteIterator}; -/// An iterator over the segments of an `ElfFile32`. +/// An iterator for the segments in an [`ElfFile32`](super::ElfFile32). pub type ElfSegmentIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfSegmentIterator<'data, 'file, elf::FileHeader32, R>; -/// An iterator over the segments of an `ElfFile64`. +/// An iterator for the segments in an [`ElfFile64`](super::ElfFile64). pub type ElfSegmentIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfSegmentIterator<'data, 'file, elf::FileHeader64, R>; -/// An iterator over the segments of an `ElfFile`. +/// An iterator for the segments in an [`ElfFile`]. #[derive(Debug)] pub struct ElfSegmentIterator<'data, 'file, Elf, R = &'data [u8]> where @@ -46,14 +46,16 @@ where } } -/// A segment of an `ElfFile32`. +/// A segment in an [`ElfFile32`](super::ElfFile32). pub type ElfSegment32<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfSegment<'data, 'file, elf::FileHeader32, R>; -/// A segment of an `ElfFile64`. +/// A segment in an [`ElfFile64`](super::ElfFile64). pub type ElfSegment64<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfSegment<'data, 'file, elf::FileHeader64, R>; -/// A segment of an `ElfFile`. +/// A segment in an [`ElfFile`]. +/// +/// Most functionality is provided by the [`ObjectSegment`] trait implementation. #[derive(Debug)] pub struct ElfSegment<'data, 'file, Elf, R = &'data [u8]> where @@ -135,7 +137,7 @@ where } } -/// A trait for generic access to `ProgramHeader32` and `ProgramHeader64`. +/// A trait for generic access to [`elf::ProgramHeader32`] and [`elf::ProgramHeader64`]. #[allow(missing_docs)] pub trait ProgramHeader: Debug + Pod { type Elf: FileHeader; diff --git a/src/read/elf/symbol.rs b/src/read/elf/symbol.rs index efc1a9f8..8ba707f7 100644 --- a/src/read/elf/symbol.rs +++ b/src/read/elf/symbol.rs @@ -18,6 +18,8 @@ use super::{FileHeader, SectionHeader, SectionTable}; /// A table of symbol entries in an ELF file. /// /// Also includes the string table used for the symbol names. +/// +/// Returned by [`SectionTable::symbols`]. #[derive(Debug, Clone, Copy)] pub struct SymbolTable<'data, Elf: FileHeader, R = &'data [u8]> where @@ -197,14 +199,14 @@ impl<'data, Elf: FileHeader, R: ReadRef<'data>> SymbolTable<'data, Elf, R> { } } -/// A symbol table of an `ElfFile32`. +/// A symbol table in an [`ElfFile32`](super::ElfFile32). pub type ElfSymbolTable32<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfSymbolTable<'data, 'file, elf::FileHeader32, R>; -/// A symbol table of an `ElfFile32`. +/// A symbol table in an [`ElfFile32`](super::ElfFile32). pub type ElfSymbolTable64<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfSymbolTable<'data, 'file, elf::FileHeader64, R>; -/// A symbol table of an `ElfFile`. +/// A symbol table in an [`ElfFile`](super::ElfFile). #[derive(Debug, Clone, Copy)] pub struct ElfSymbolTable<'data, 'file, Elf, R = &'data [u8]> where @@ -245,14 +247,14 @@ impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ObjectSymbolTable<'data> } } -/// An iterator over the symbols of an `ElfFile32`. +/// An iterator for the symbols in an [`ElfFile32`](super::ElfFile32). pub type ElfSymbolIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfSymbolIterator<'data, 'file, elf::FileHeader32, R>; -/// An iterator over the symbols of an `ElfFile64`. +/// An iterator for the symbols in an [`ElfFile64`](super::ElfFile64). pub type ElfSymbolIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfSymbolIterator<'data, 'file, elf::FileHeader64, R>; -/// An iterator over the symbols of an `ElfFile`. +/// An iterator for the symbols in an [`ElfFile`](super::ElfFile). pub struct ElfSymbolIterator<'data, 'file, Elf, R = &'data [u8]> where Elf: FileHeader, @@ -289,14 +291,16 @@ impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> Iterator } } -/// A symbol of an `ElfFile32`. +/// A symbol in an [`ElfFile32`](super::ElfFile32). pub type ElfSymbol32<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfSymbol<'data, 'file, elf::FileHeader32, R>; -/// A symbol of an `ElfFile64`. +/// A symbol in an [`ElfFile64`](super::ElfFile64). pub type ElfSymbol64<'data, 'file, Endian = Endianness, R = &'data [u8]> = ElfSymbol<'data, 'file, elf::FileHeader64, R>; -/// A symbol of an `ElfFile`. +/// A symbol in an [`ElfFile`](super::ElfFile). +/// +/// Most functionality is provided by the [`ObjectSymbol`] trait implementation. #[derive(Debug, Clone, Copy)] pub struct ElfSymbol<'data, 'file, Elf, R = &'data [u8]> where @@ -443,7 +447,7 @@ impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> } } -/// A trait for generic access to `Sym32` and `Sym64`. +/// A trait for generic access to [`elf::Sym32`] and [`elf::Sym64`]. #[allow(missing_docs)] pub trait Sym: Debug + Pod { type Word: Into; diff --git a/src/read/elf/version.rs b/src/read/elf/version.rs index cc87bbef..28eeed0a 100644 --- a/src/read/elf/version.rs +++ b/src/read/elf/version.rs @@ -33,7 +33,7 @@ impl VersionIndex { /// A version definition or requirement. /// -/// This is derived from entries in the `SHT_GNU_verdef` and `SHT_GNU_verneed` sections. +/// This is derived from entries in the [`elf::SHT_GNU_VERDEF`] and [`elf::SHT_GNU_VERNEED`] sections. #[derive(Debug, Default, Clone, Copy)] pub struct Version<'data> { name: &'data [u8], @@ -58,7 +58,10 @@ impl<'data> Version<'data> { /// /// It allows looking up the version information for a given symbol index. /// -/// This is derived from entries in the `SHT_GNU_versym`, `SHT_GNU_verdef` and `SHT_GNU_verneed` sections. +/// This is derived from entries in the [`elf::SHT_GNU_VERSYM`], [`elf::SHT_GNU_VERDEF`] +/// and [`elf::SHT_GNU_VERNEED`] sections. +/// +/// Returned by [`SectionTable::versions`](super::SectionTable::versions). #[derive(Debug, Clone)] pub struct VersionTable<'data, Elf: FileHeader> { symbols: &'data [elf::Versym], @@ -210,7 +213,7 @@ impl<'data, Elf: FileHeader> VersionTable<'data, Elf> { } } -/// An iterator over the entries in an ELF `SHT_GNU_verdef` section. +/// An iterator for the entries in an ELF [`elf::SHT_GNU_VERDEF`] section. #[derive(Debug, Clone)] pub struct VerdefIterator<'data, Elf: FileHeader> { endian: Elf::Endian, @@ -257,7 +260,7 @@ impl<'data, Elf: FileHeader> VerdefIterator<'data, Elf> { } } -/// An iterator over the auxiliary records for an entry in an ELF `SHT_GNU_verdef` section. +/// An iterator for the auxiliary records for an entry in an ELF [`elf::SHT_GNU_VERDEF`] section. #[derive(Debug, Clone)] pub struct VerdauxIterator<'data, Elf: FileHeader> { endian: Elf::Endian, @@ -293,7 +296,7 @@ impl<'data, Elf: FileHeader> VerdauxIterator<'data, Elf> { } } -/// An iterator over the entries in an ELF `SHT_GNU_verneed` section. +/// An iterator for the entries in an ELF [`elf::SHT_GNU_VERNEED`] section. #[derive(Debug, Clone)] pub struct VerneedIterator<'data, Elf: FileHeader> { endian: Elf::Endian, @@ -345,7 +348,7 @@ impl<'data, Elf: FileHeader> VerneedIterator<'data, Elf> { } } -/// An iterator over the auxiliary records for an entry in an ELF `SHT_GNU_verneed` section. +/// An iterator for the auxiliary records for an entry in an ELF [`elf::SHT_GNU_VERNEED`] section. #[derive(Debug, Clone)] pub struct VernauxIterator<'data, Elf: FileHeader> { endian: Elf::Endian, diff --git a/src/read/macho/dyld_cache.rs b/src/read/macho/dyld_cache.rs index 68f27f54..0f5dfc57 100644 --- a/src/read/macho/dyld_cache.rs +++ b/src/read/macho/dyld_cache.rs @@ -39,10 +39,11 @@ where R: ReadRef<'data>, { /// Parse the raw dyld shared cache data. + /// /// For shared caches from macOS 12 / iOS 15 and above, the subcache files need to be - /// supplied as well, in the correct order, with the .symbols subcache last (if present). - /// For example, data would be the data for dyld_shared_cache_x86_64, - /// and subcache_data would be the data for [dyld_shared_cache_x86_64.1, dyld_shared_cache_x86_64.2, ...] + /// supplied as well, in the correct order, with the `.symbols` subcache last (if present). + /// For example, `data` would be the data for `dyld_shared_cache_x86_64`, + /// and `subcache_data` would be the data for `[dyld_shared_cache_x86_64.1, dyld_shared_cache_x86_64.2, ...]`. pub fn parse(data: R, subcache_data: &[R]) -> Result { let header = macho::DyldCacheHeader::parse(data)?; let (arch, endian) = header.parse_magic()?; diff --git a/src/read/macho/fat.rs b/src/read/macho/fat.rs index d4301b7e..a4813512 100644 --- a/src/read/macho/fat.rs +++ b/src/read/macho/fat.rs @@ -39,7 +39,7 @@ impl FatHeader { } } -/// A trait for generic access to `FatArch32` and `FatArch64`. +/// A trait for generic access to [`macho::FatArch32`] and [`macho::FatArch64`]. #[allow(missing_docs)] pub trait FatArch: Pod { type Word: Into; diff --git a/src/read/macho/file.rs b/src/read/macho/file.rs index 26512cd2..99e39927 100644 --- a/src/read/macho/file.rs +++ b/src/read/macho/file.rs @@ -16,15 +16,21 @@ use super::{ }; /// A 32-bit Mach-O object file. +/// +/// This is a file that starts with [`macho::MachHeader32`], and corresponds +/// to [`crate::FileKind::MachO32`]. pub type MachOFile32<'data, Endian = Endianness, R = &'data [u8]> = MachOFile<'data, macho::MachHeader32, R>; /// A 64-bit Mach-O object file. +/// +/// This is a file that starts with [`macho::MachHeader64`], and corresponds +/// to [`crate::FileKind::MachO64`]. pub type MachOFile64<'data, Endian = Endianness, R = &'data [u8]> = MachOFile<'data, macho::MachHeader64, R>; /// A partially parsed Mach-O file. /// -/// Most of the functionality of this type is provided by the `Object` trait implementation. +/// Most of the functionality of this type is provided by the [`Object`] trait implementation. #[derive(Debug)] pub struct MachOFile<'data, Mach, R = &'data [u8]> where @@ -459,14 +465,16 @@ where } } -/// An iterator over the COMDAT section groups of a `MachOFile64`. +/// An iterator for the COMDAT section groups in a [`MachOFile64`]. pub type MachOComdatIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOComdatIterator<'data, 'file, macho::MachHeader32, R>; -/// An iterator over the COMDAT section groups of a `MachOFile64`. +/// An iterator for the COMDAT section groups in a [`MachOFile64`]. pub type MachOComdatIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOComdatIterator<'data, 'file, macho::MachHeader64, R>; -/// An iterator over the COMDAT section groups of a `MachOFile`. +/// An iterator for the COMDAT section groups in a [`MachOFile`]. +/// +/// This is a stub that doesn't implement any functionality. #[derive(Debug)] pub struct MachOComdatIterator<'data, 'file, Mach, R = &'data [u8]> where @@ -490,15 +498,17 @@ where } } -/// A COMDAT section group of a `MachOFile32`. +/// A COMDAT section group in a [`MachOFile32`]. pub type MachOComdat32<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOComdat<'data, 'file, macho::MachHeader32, R>; -/// A COMDAT section group of a `MachOFile64`. +/// A COMDAT section group in a [`MachOFile64`]. pub type MachOComdat64<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOComdat<'data, 'file, macho::MachHeader64, R>; -/// A COMDAT section group of a `MachOFile`. +/// A COMDAT section group in a [`MachOFile`]. +/// +/// This is a stub that doesn't implement any functionality. #[derive(Debug)] pub struct MachOComdat<'data, 'file, Mach, R = &'data [u8]> where @@ -549,14 +559,16 @@ where } } -/// An iterator over the sections in a COMDAT section group of a `MachOFile32`. +/// An iterator for the sections in a COMDAT section group in a [`MachOFile32`]. pub type MachOComdatSectionIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOComdatSectionIterator<'data, 'file, macho::MachHeader32, R>; -/// An iterator over the sections in a COMDAT section group of a `MachOFile64`. +/// An iterator for the sections in a COMDAT section group in a [`MachOFile64`]. pub type MachOComdatSectionIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOComdatSectionIterator<'data, 'file, macho::MachHeader64, R>; -/// An iterator over the sections in a COMDAT section group of a `MachOFile`. +/// An iterator for the sections in a COMDAT section group in a [`MachOFile`]. +/// +/// This is a stub that doesn't implement any functionality. #[derive(Debug)] pub struct MachOComdatSectionIterator<'data, 'file, Mach, R = &'data [u8]> where @@ -579,7 +591,7 @@ where } } -/// A trait for generic access to `MachHeader32` and `MachHeader64`. +/// A trait for generic access to [`macho::MachHeader32`] and [`macho::MachHeader64`]. #[allow(missing_docs)] pub trait MachHeader: Debug + Pod { type Word: Into; diff --git a/src/read/macho/load_command.rs b/src/read/macho/load_command.rs index 7ba407a0..7225fbdb 100644 --- a/src/read/macho/load_command.rs +++ b/src/read/macho/load_command.rs @@ -7,7 +7,7 @@ use crate::pod::Pod; use crate::read::macho::{MachHeader, SymbolTable}; use crate::read::{Bytes, Error, ReadError, ReadRef, Result, StringTable}; -/// An iterator over the load commands of a `MachHeader`. +/// An iterator for the load commands from a [`MachHeader`]. #[derive(Debug, Default, Clone, Copy)] pub struct LoadCommandIterator<'data, E: Endian> { endian: E, @@ -51,7 +51,7 @@ impl<'data, E: Endian> LoadCommandIterator<'data, E> { } } -/// The data for a `LoadCommand`. +/// The data for a [`macho::LoadCommand`]. #[derive(Debug, Clone, Copy)] pub struct LoadCommandData<'data, E: Endian> { cmd: u32, @@ -61,14 +61,14 @@ pub struct LoadCommandData<'data, E: Endian> { } impl<'data, E: Endian> LoadCommandData<'data, E> { - /// Return the `cmd` field of the `LoadCommand`. + /// Return the `cmd` field of the [`macho::LoadCommand`]. /// /// This is one of the `LC_` constants. pub fn cmd(&self) -> u32 { self.cmd } - /// Return the `cmdsize` field of the `LoadCommand`. + /// Return the `cmdsize` field of the [`macho::LoadCommand`]. pub fn cmdsize(&self) -> u32 { self.data.len() as u32 } @@ -81,7 +81,7 @@ impl<'data, E: Endian> LoadCommandData<'data, E> { .read_error("Invalid Mach-O command size") } - /// Raw bytes of this LoadCommand structure. + /// Raw bytes of this [`macho::LoadCommand`] structure. pub fn raw_data(&self) -> &'data [u8] { self.data.0 } @@ -163,7 +163,7 @@ impl<'data, E: Endian> LoadCommandData<'data, E> { }) } - /// Try to parse this command as a `SegmentCommand32`. + /// Try to parse this command as a [`macho::SegmentCommand32`]. /// /// Returns the segment command and the data containing the sections. pub fn segment_32(self) -> Result, &'data [u8])>> { @@ -176,7 +176,7 @@ impl<'data, E: Endian> LoadCommandData<'data, E> { } } - /// Try to parse this command as a `SymtabCommand`. + /// Try to parse this command as a [`macho::SymtabCommand`]. /// /// Returns the segment command and the data containing the sections. pub fn symtab(self) -> Result>> { @@ -187,7 +187,7 @@ impl<'data, E: Endian> LoadCommandData<'data, E> { } } - /// Try to parse this command as a `DysymtabCommand`. + /// Try to parse this command as a [`macho::DysymtabCommand`]. pub fn dysymtab(self) -> Result>> { if self.cmd == macho::LC_DYSYMTAB { Some(self.data()).transpose() @@ -196,7 +196,7 @@ impl<'data, E: Endian> LoadCommandData<'data, E> { } } - /// Try to parse this command as a `DylibCommand`. + /// Try to parse this command as a [`macho::DylibCommand`]. pub fn dylib(self) -> Result>> { if self.cmd == macho::LC_LOAD_DYLIB || self.cmd == macho::LC_LOAD_WEAK_DYLIB @@ -210,7 +210,7 @@ impl<'data, E: Endian> LoadCommandData<'data, E> { } } - /// Try to parse this command as a `UuidCommand`. + /// Try to parse this command as a [`macho::UuidCommand`]. pub fn uuid(self) -> Result>> { if self.cmd == macho::LC_UUID { Some(self.data()).transpose() @@ -219,7 +219,7 @@ impl<'data, E: Endian> LoadCommandData<'data, E> { } } - /// Try to parse this command as a `SegmentCommand64`. + /// Try to parse this command as a [`macho::SegmentCommand64`]. pub fn segment_64(self) -> Result, &'data [u8])>> { if self.cmd == macho::LC_SEGMENT_64 { let mut data = self.data; @@ -230,7 +230,7 @@ impl<'data, E: Endian> LoadCommandData<'data, E> { } } - /// Try to parse this command as a `DyldInfoCommand`. + /// Try to parse this command as a [`macho::DyldInfoCommand`]. pub fn dyld_info(self) -> Result>> { if self.cmd == macho::LC_DYLD_INFO || self.cmd == macho::LC_DYLD_INFO_ONLY { Some(self.data()).transpose() @@ -239,7 +239,7 @@ impl<'data, E: Endian> LoadCommandData<'data, E> { } } - /// Try to parse this command as an `EntryPointCommand`. + /// Try to parse this command as an [`macho::EntryPointCommand`]. pub fn entry_point(self) -> Result>> { if self.cmd == macho::LC_MAIN { Some(self.data()).transpose() @@ -248,7 +248,7 @@ impl<'data, E: Endian> LoadCommandData<'data, E> { } } - /// Try to parse this command as a `BuildVersionCommand`. + /// Try to parse this command as a [`macho::BuildVersionCommand`]. pub fn build_version(self) -> Result>> { if self.cmd == macho::LC_BUILD_VERSION { Some(self.data()).transpose() @@ -258,7 +258,7 @@ impl<'data, E: Endian> LoadCommandData<'data, E> { } } -/// A `LoadCommand` that has been interpreted according to its `cmd` field. +/// A [`macho::LoadCommand`] that has been interpreted according to its `cmd` field. #[derive(Debug, Clone, Copy)] #[non_exhaustive] pub enum LoadCommandVariant<'data, E: Endian> { diff --git a/src/read/macho/mod.rs b/src/read/macho/mod.rs index f07ed581..ab51ff32 100644 --- a/src/read/macho/mod.rs +++ b/src/read/macho/mod.rs @@ -1,9 +1,51 @@ //! Support for reading Mach-O files. //! -//! Defines traits to abstract over the difference between 32-bit and 64-bit -//! Mach-O files, and implements read functionality in terms of these traits. +//! Traits are used to abstract over the difference between 32-bit and 64-bit Mach-O +//! files. The primary trait for this is [`MachHeader`]. //! -//! Also provides `MachOFile` and related types which implement the `Object` trait. +//! ## High level API +//! +//! [`MachOFile`] implements the [`Object`](crate::read::Object) trait for Mach-O files. +//! [`MachOFile`] is parameterised by [`MachHeader`] to allow reading both 32-bit and +//! 64-bit Mach-O files. There are type aliases for these parameters ([`MachOFile32`] and +//! [`MachOFile64`]). +//! +//! ## Low level API +//! +//! The [`MachHeader`] trait can be directly used to parse both [`macho::MachHeader32`] +//! and [`macho::MachHeader64`]. Additionally, [`FatHeader`] and the [`FatArch`] trait +//! can be used to iterate images in multi-architecture binaries, and [`DyldCache`] can +//! be used to locate images in a dyld shared cache. +//! +//! ### Example for low level API +//! ```no_run +//! use object::macho; +//! use object::read::macho::{MachHeader, Nlist}; +//! use std::error::Error; +//! use std::fs; +//! +//! /// Reads a file and displays the name of each symbol. +//! fn main() -> Result<(), Box> { +//! # #[cfg(feature = "std")] { +//! let data = fs::read("path/to/binary")?; +//! let header = macho::MachHeader64::::parse(&*data, 0)?; +//! let endian = header.endian()?; +//! let mut commands = header.load_commands(endian, &*data, 0)?; +//! while let Some(command) = commands.next()? { +//! if let Some(symtab_command) = command.symtab()? { +//! let symbols = symtab_command.symbols::, _>(endian, &*data)?; +//! for symbol in symbols.iter() { +//! let name = symbol.name(endian, symbols.strings())?; +//! println!("{}", String::from_utf8_lossy(name)); +//! } +//! } +//! } +//! # } +//! Ok(()) +//! } +//! ``` +#[cfg(doc)] +use crate::macho; mod dyld_cache; pub use dyld_cache::*; diff --git a/src/read/macho/relocation.rs b/src/read/macho/relocation.rs index 05c48061..709f1a44 100644 --- a/src/read/macho/relocation.rs +++ b/src/read/macho/relocation.rs @@ -9,14 +9,14 @@ use crate::read::{ use super::{MachHeader, MachOFile}; -/// An iterator over the relocations in a `MachOSection32`. +/// An iterator for the relocations in a [`MachOSection32`](super::MachOSection32). pub type MachORelocationIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachORelocationIterator<'data, 'file, macho::MachHeader32, R>; -/// An iterator over the relocations in a `MachOSection64`. +/// An iterator for the relocations in a [`MachOSection64`](super::MachOSection64). pub type MachORelocationIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachORelocationIterator<'data, 'file, macho::MachHeader64, R>; -/// An iterator over the relocations in a `MachOSection`. +/// An iterator for the relocations in a [`MachOSection`](super::MachOSection). pub struct MachORelocationIterator<'data, 'file, Mach, R = &'data [u8]> where Mach: MachHeader, diff --git a/src/read/macho/section.rs b/src/read/macho/section.rs index f43a5b83..7c79123b 100644 --- a/src/read/macho/section.rs +++ b/src/read/macho/section.rs @@ -11,14 +11,14 @@ use crate::read::{ use super::{MachHeader, MachOFile, MachORelocationIterator}; -/// An iterator over the sections of a `MachOFile32`. +/// An iterator for the sections in a [`MachOFile32`](super::MachOFile32). pub type MachOSectionIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOSectionIterator<'data, 'file, macho::MachHeader32, R>; -/// An iterator over the sections of a `MachOFile64`. +/// An iterator for the sections in a [`MachOFile64`](super::MachOFile64). pub type MachOSectionIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOSectionIterator<'data, 'file, macho::MachHeader64, R>; -/// An iterator over the sections of a `MachOFile`. +/// An iterator for the sections in a [`MachOFile`]. pub struct MachOSectionIterator<'data, 'file, Mach, R = &'data [u8]> where Mach: MachHeader, @@ -54,14 +54,16 @@ where } } -/// A section of a `MachOFile32`. +/// A section in a [`MachOFile32`](super::MachOFile32). pub type MachOSection32<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOSection<'data, 'file, macho::MachHeader32, R>; -/// A section of a `MachOFile64`. +/// A section in a [`MachOFile64`](super::MachOFile64). pub type MachOSection64<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOSection<'data, 'file, macho::MachHeader64, R>; -/// A section of a `MachOFile`. +/// A section in a [`MachOFile`]. +/// +/// Most functionality is provided by the [`ObjectSection`] trait implementation. #[derive(Debug)] pub struct MachOSection<'data, 'file, Mach, R = &'data [u8]> where @@ -247,7 +249,7 @@ impl<'data, Mach: MachHeader> MachOSectionInternal<'data, Mach> { } } -/// A trait for generic access to `Section32` and `Section64`. +/// A trait for generic access to [`macho::Section32`] and [`macho::Section64`]. #[allow(missing_docs)] pub trait Section: Debug + Pod { type Word: Into; diff --git a/src/read/macho/segment.rs b/src/read/macho/segment.rs index 01037e1d..c889ad24 100644 --- a/src/read/macho/segment.rs +++ b/src/read/macho/segment.rs @@ -8,14 +8,14 @@ use crate::read::{self, ObjectSegment, ReadError, ReadRef, Result, SegmentFlags} use super::{LoadCommandData, MachHeader, MachOFile, Section}; -/// An iterator over the segments of a `MachOFile32`. +/// An iterator for the segments in a [`MachOFile32`](super::MachOFile32). pub type MachOSegmentIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOSegmentIterator<'data, 'file, macho::MachHeader32, R>; -/// An iterator over the segments of a `MachOFile64`. +/// An iterator for the segments in a [`MachOFile64`](super::MachOFile64). pub type MachOSegmentIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOSegmentIterator<'data, 'file, macho::MachHeader64, R>; -/// An iterator over the segments of a `MachOFile`. +/// An iterator for the segments in a [`MachOFile`]. #[derive(Debug)] pub struct MachOSegmentIterator<'data, 'file, Mach, R = &'data [u8]> where @@ -41,14 +41,16 @@ where } } -/// A segment of a `MachOFile32`. +/// A segment in a [`MachOFile32`](super::MachOFile32). pub type MachOSegment32<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOSegment<'data, 'file, macho::MachHeader32, R>; -/// A segment of a `MachOFile64`. +/// A segment in a [`MachOFile64`](super::MachOFile64). pub type MachOSegment64<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOSegment<'data, 'file, macho::MachHeader64, R>; -/// A segment of a `MachOFile`. +/// A segment in a [`MachOFile`]. +/// +/// Most functionality is provided by the [`ObjectSegment`] trait implementation. #[derive(Debug)] pub struct MachOSegment<'data, 'file, Mach, R = &'data [u8]> where @@ -151,7 +153,7 @@ pub(super) struct MachOSegmentInternal<'data, Mach: MachHeader, R: ReadRef<'data pub segment: &'data Mach::Segment, } -/// A trait for generic access to `SegmentCommand32` and `SegmentCommand64`. +/// A trait for generic access to [`macho::SegmentCommand32`] and [`macho::SegmentCommand64`]. #[allow(missing_docs)] pub trait Segment: Debug + Pod { type Word: Into; diff --git a/src/read/macho/symbol.rs b/src/read/macho/symbol.rs index 290b4817..434361f4 100644 --- a/src/read/macho/symbol.rs +++ b/src/read/macho/symbol.rs @@ -17,6 +17,8 @@ use super::{MachHeader, MachOFile}; /// A table of symbol entries in a Mach-O file. /// /// Also includes the string table used for the symbol names. +/// +/// Returned by [`macho::SymtabCommand::symbols`]. #[derive(Debug, Clone, Copy)] pub struct SymbolTable<'data, Mach: MachHeader, R = &'data [u8]> where @@ -143,14 +145,14 @@ impl<'data, Mach: MachHeader, R: ReadRef<'data>> SymbolTable<'data, Mach, R> { } } -/// An iterator over the symbols of a `MachOFile32`. +/// A symbol table in a [`MachOFile32`](super::MachOFile32). pub type MachOSymbolTable32<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOSymbolTable<'data, 'file, macho::MachHeader32, R>; -/// An iterator over the symbols of a `MachOFile64`. +/// A symbol table in a [`MachOFile64`](super::MachOFile64). pub type MachOSymbolTable64<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOSymbolTable<'data, 'file, macho::MachHeader64, R>; -/// A symbol table of a `MachOFile`. +/// A symbol table in a [`MachOFile`]. #[derive(Debug, Clone, Copy)] pub struct MachOSymbolTable<'data, 'file, Mach, R = &'data [u8]> where @@ -188,14 +190,14 @@ where } } -/// An iterator over the symbols of a `MachOFile32`. +/// An iterator for the symbols in a [`MachOFile32`](super::MachOFile32). pub type MachOSymbolIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOSymbolIterator<'data, 'file, macho::MachHeader32, R>; -/// An iterator over the symbols of a `MachOFile64`. +/// An iterator for the symbols in a [`MachOFile64`](super::MachOFile64). pub type MachOSymbolIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOSymbolIterator<'data, 'file, macho::MachHeader64, R>; -/// An iterator over the symbols of a `MachOFile`. +/// An iterator for the symbols in a [`MachOFile`]. pub struct MachOSymbolIterator<'data, 'file, Mach, R = &'data [u8]> where Mach: MachHeader, @@ -234,14 +236,16 @@ where } } -/// A symbol of a `MachOFile32`. +/// A symbol in a [`MachOFile32`](super::MachOFile32). pub type MachOSymbol32<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOSymbol<'data, 'file, macho::MachHeader32, R>; -/// A symbol of a `MachOFile64`. +/// A symbol in a [`MachOFile64`](super::MachOFile64). pub type MachOSymbol64<'data, 'file, Endian = Endianness, R = &'data [u8]> = MachOSymbol<'data, 'file, macho::MachHeader64, R>; -/// A symbol of a `MachOFile`. +/// A symbol in a [`MachOFile`]. +/// +/// Most functionality is provided by the [`ObjectSymbol`] trait implementation. #[derive(Debug, Clone, Copy)] pub struct MachOSymbol<'data, 'file, Mach, R = &'data [u8]> where @@ -394,7 +398,7 @@ where } } -/// A trait for generic access to `Nlist32` and `Nlist64`. +/// A trait for generic access to [`macho::Nlist32`] and [`macho::Nlist64`]. #[allow(missing_docs)] pub trait Nlist: Debug + Pod { type Word: Into; diff --git a/src/read/mod.rs b/src/read/mod.rs index 809d5f73..c13e3091 100644 --- a/src/read/mod.rs +++ b/src/read/mod.rs @@ -1,4 +1,45 @@ //! Interface for reading object files. +//! +//! ## Unified read API +//! +//! The [`Object`] trait provides a unified read API for accessing common features of +//! object files, such as sections and symbols. There is an implementation of this +//! trait for [`File`], which allows reading any file format, as well as implementations +//! for each file format: +//! [`ElfFile`](elf::ElfFile), [`MachOFile`](macho::MachOFile), [`CoffFile`](coff::CoffFile), +//! [`PeFile`](pe::PeFile), [`WasmFile`](wasm::WasmFile), [`XcoffFile`](xcoff::XcoffFile). +//! +//! ## Low level read API +//! +//! The submodules for each file format 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. +//! +//! See the [submodules](#modules) for examples of the low level read API. +//! +//! ## Naming Convention +//! +//! Types that form part of the unified API for a file format are prefixed with the +//! name of the file format. +//! +//! ## Example for unified read API +//! ```no_run +//! use object::{Object, ObjectSection}; +//! use std::error::Error; +//! use std::fs; +//! +//! /// Reads a file and displays the name of each section. +//! fn main() -> Result<(), Box> { +//! # #[cfg(feature = "std")] { +//! let data = fs::read("path/to/binary")?; +//! let file = object::File::parse(&*data)?; +//! for section in file.sections() { +//! println!("{}", section.name()?); +//! } +//! # } +//! Ok(()) +//! } +//! ``` use alloc::borrow::Cow; use alloc::vec::Vec; @@ -146,53 +187,85 @@ pub type NativeFile<'data, R = &'data [u8]> = wasm::WasmFile<'data, R>; #[non_exhaustive] pub enum FileKind { /// A Unix archive. + /// + /// See [`archive::ArchiveFile`]. #[cfg(feature = "archive")] Archive, /// A COFF object file. + /// + /// See [`coff::CoffFile`]. #[cfg(feature = "coff")] Coff, /// A COFF bigobj object file. /// /// This supports a larger number of sections. + /// + /// See [`coff::CoffBigFile`]. #[cfg(feature = "coff")] CoffBig, /// A Windows short import file. + /// + /// See [`coff::ImportFile`]. #[cfg(feature = "coff")] CoffImport, /// A dyld cache file containing Mach-O images. + /// + /// See [`macho::DyldCache`] #[cfg(feature = "macho")] DyldCache, /// A 32-bit ELF file. + /// + /// See [`elf::ElfFile32`]. #[cfg(feature = "elf")] Elf32, /// A 64-bit ELF file. + /// + /// See [`elf::ElfFile64`]. #[cfg(feature = "elf")] Elf64, /// A 32-bit Mach-O file. + /// + /// See [`macho::MachOFile32`]. #[cfg(feature = "macho")] MachO32, /// A 64-bit Mach-O file. + /// + /// See [`macho::MachOFile64`]. #[cfg(feature = "macho")] MachO64, /// A 32-bit Mach-O fat binary. + /// + /// See [`macho::FatHeader::parse_arch32`]. #[cfg(feature = "macho")] MachOFat32, /// A 64-bit Mach-O fat binary. + /// + /// See [`macho::FatHeader::parse_arch64`]. #[cfg(feature = "macho")] MachOFat64, /// A 32-bit PE file. + /// + /// See [`pe::PeFile32`]. #[cfg(feature = "pe")] Pe32, /// A 64-bit PE file. + /// + /// See [`pe::PeFile64`]. #[cfg(feature = "pe")] Pe64, /// A Wasm file. + /// + /// See [`wasm::WasmFile`]. #[cfg(feature = "wasm")] Wasm, /// A 32-bit XCOFF file. + /// + /// See [`xcoff::XcoffFile32`]. #[cfg(feature = "xcoff")] Xcoff32, /// A 64-bit XCOFF file. + /// + /// See [`xcoff::XcoffFile64`]. #[cfg(feature = "xcoff")] Xcoff64, } @@ -279,6 +352,8 @@ impl FileKind { } /// An object kind. +/// +/// Returned by [`Object::kind`]. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[non_exhaustive] pub enum ObjectKind { @@ -294,15 +369,15 @@ pub enum ObjectKind { Core, } -/// The index used to identify a section of a file. +/// The index used to identify a section in a file. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct SectionIndex(pub usize); -/// The index used to identify a symbol of a file. +/// The index used to identify a symbol in a symbol table. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct SymbolIndex(pub usize); -/// The section where a symbol is defined. +/// The section where an [`ObjectSymbol`] is defined. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[non_exhaustive] pub enum SymbolSection { @@ -334,13 +409,17 @@ impl SymbolSection { } } -/// An entry in a `SymbolMap`. +/// An entry in a [`SymbolMap`]. pub trait SymbolMapEntry { /// The symbol address. fn address(&self) -> u64; } -/// A map from addresses to symbols. +/// A map from addresses to symbol information. +/// +/// The symbol information depends on the chosen entry type, such as [`SymbolMapName`]. +/// +/// Returned by [`Object::symbol_map`]. #[derive(Debug, Default, Clone)] pub struct SymbolMap { symbols: Vec, @@ -374,7 +453,7 @@ impl SymbolMap { } } -/// A `SymbolMap` entry for symbol names. +/// The type used for entries in a [`SymbolMap`] that maps from addresses to names. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct SymbolMapName<'data> { address: u64, @@ -410,6 +489,8 @@ impl<'data> SymbolMapEntry for SymbolMapName<'data> { /// A map from addresses to symbol names and object files. /// /// This is derived from STAB entries in Mach-O files. +/// +/// Returned by [`Object::object_map`]. #[derive(Debug, Default, Clone)] pub struct ObjectMap<'data> { symbols: SymbolMap>, @@ -437,7 +518,7 @@ impl<'data> ObjectMap<'data> { } } -/// A `ObjectMap` entry. +/// An [`ObjectMap`] entry. #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] pub struct ObjectMapEntry<'data> { address: u64, @@ -488,6 +569,8 @@ impl<'data> SymbolMapEntry for ObjectMapEntry<'data> { } /// An imported symbol. +/// +/// Returned by [`Object::imports`]. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Import<'data> { library: ByteString<'data>, @@ -510,6 +593,8 @@ impl<'data> Import<'data> { } /// An exported symbol. +/// +/// Returned by [`Object::exports`]. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Export<'data> { // TODO: and ordinal? @@ -531,7 +616,7 @@ impl<'data> Export<'data> { } } -/// PDB Information +/// PDB information from the debug directory in a PE file. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct CodeView<'data> { guid: [u8; 16], @@ -540,13 +625,13 @@ pub struct CodeView<'data> { } impl<'data> CodeView<'data> { - /// The path to the PDB as stored in CodeView + /// The path to the PDB as stored in CodeView. #[inline] pub fn path(&self) -> &'data [u8] { self.path.0 } - /// The age of the PDB + /// The age of the PDB. #[inline] pub fn age(&self) -> u32 { self.age @@ -559,7 +644,7 @@ impl<'data> CodeView<'data> { } } -/// The target referenced by a relocation. +/// The target referenced by a [`Relocation`]. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[non_exhaustive] pub enum RelocationTarget { @@ -572,6 +657,8 @@ pub enum RelocationTarget { } /// A relocation entry. +/// +/// Returned by [`Object::dynamic_relocations`] or [`ObjectSection::relocations`]. #[derive(Debug)] pub struct Relocation { kind: RelocationKind, @@ -648,6 +735,8 @@ pub enum CompressionFormat { } /// A range in a file that may be compressed. +/// +/// Returned by [`ObjectSection::compressed_file_range`]. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct CompressedFileRange { /// The data compression format. @@ -681,7 +770,7 @@ impl CompressedFileRange { } } - /// Convert to `CompressedData` by reading from the file. + /// Convert to [`CompressedData`] by reading from the file. pub fn data<'data, R: ReadRef<'data>>(self, file: R) -> Result> { let data = file .read_bytes_at(self.offset, self.compressed_size) @@ -695,6 +784,8 @@ impl CompressedFileRange { } /// Data that may be compressed. +/// +/// Returned by [`ObjectSection::compressed_data`]. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct CompressedData<'data> { /// The data compression format. diff --git a/src/read/pe/data_directory.rs b/src/read/pe/data_directory.rs index 0e10244b..a17179f1 100644 --- a/src/read/pe/data_directory.rs +++ b/src/read/pe/data_directory.rs @@ -9,6 +9,8 @@ use super::{ }; /// The table of data directories in a PE file. +/// +/// Returned by [`ImageNtHeaders::parse`](super::ImageNtHeaders::parse). #[derive(Debug, Clone, Copy)] pub struct DataDirectories<'data> { entries: &'data [pe::ImageDataDirectory], diff --git a/src/read/pe/export.rs b/src/read/pe/export.rs index 88dc78d5..1aba844f 100644 --- a/src/read/pe/export.rs +++ b/src/read/pe/export.rs @@ -80,6 +80,8 @@ impl<'a> Debug for ExportTarget<'a> { } /// A partially parsed PE export table. +/// +/// Returned by [`DataDirectories::export_table`](super::DataDirectories::export_table). #[derive(Debug, Clone)] pub struct ExportTable<'data> { data: Bytes<'data>, diff --git a/src/read/pe/file.rs b/src/read/pe/file.rs index fe234aa1..5372bdda 100644 --- a/src/read/pe/file.rs +++ b/src/read/pe/file.rs @@ -17,11 +17,19 @@ use super::{ }; /// A PE32 (32-bit) image file. +/// +/// This is a file that starts with [`pe::ImageNtHeaders32`], and corresponds +/// to [`crate::FileKind::Pe32`]. pub type PeFile32<'data, R = &'data [u8]> = PeFile<'data, pe::ImageNtHeaders32, R>; /// A PE32+ (64-bit) image file. +/// +/// This is a file that starts with [`pe::ImageNtHeaders64`], and corresponds +/// to [`crate::FileKind::Pe64`]. pub type PeFile64<'data, R = &'data [u8]> = PeFile<'data, pe::ImageNtHeaders64, R>; -/// A PE object file. +/// A PE image file. +/// +/// Most functionality is provided by the [`Object`] trait implementation. #[derive(Debug)] pub struct PeFile<'data, Pe, R = &'data [u8]> where @@ -387,14 +395,16 @@ where } } -/// An iterator over the COMDAT section groups of a `PeFile32`. +/// An iterator for the COMDAT section groups in a [`PeFile32`]. pub type PeComdatIterator32<'data, 'file, R = &'data [u8]> = PeComdatIterator<'data, 'file, pe::ImageNtHeaders32, R>; -/// An iterator over the COMDAT section groups of a `PeFile64`. +/// An iterator for the COMDAT section groups in a [`PeFile64`]. pub type PeComdatIterator64<'data, 'file, R = &'data [u8]> = PeComdatIterator<'data, 'file, pe::ImageNtHeaders64, R>; -/// An iterator over the COMDAT section groups of a `PeFile`. +/// An iterator for the COMDAT section groups in a [`PeFile`]. +/// +/// This is a stub that doesn't implement any functionality. #[derive(Debug)] pub struct PeComdatIterator<'data, 'file, Pe, R = &'data [u8]> where @@ -418,14 +428,16 @@ where } } -/// A COMDAT section group of a `PeFile32`. +/// A COMDAT section group in a [`PeFile32`]. pub type PeComdat32<'data, 'file, R = &'data [u8]> = PeComdat<'data, 'file, pe::ImageNtHeaders32, R>; -/// A COMDAT section group of a `PeFile64`. +/// A COMDAT section group in a [`PeFile64`]. pub type PeComdat64<'data, 'file, R = &'data [u8]> = PeComdat<'data, 'file, pe::ImageNtHeaders64, R>; -/// A COMDAT section group of a `PeFile`. +/// A COMDAT section group in a [`PeFile`]. +/// +/// This is a stub that doesn't implement any functionality. #[derive(Debug)] pub struct PeComdat<'data, 'file, Pe, R = &'data [u8]> where @@ -476,14 +488,16 @@ where } } -/// An iterator over the sections in a COMDAT section group of a `PeFile32`. +/// An iterator for the sections in a COMDAT section group in a [`PeFile32`]. pub type PeComdatSectionIterator32<'data, 'file, R = &'data [u8]> = PeComdatSectionIterator<'data, 'file, pe::ImageNtHeaders32, R>; -/// An iterator over the sections in a COMDAT section group of a `PeFile64`. +/// An iterator for the sections in a COMDAT section group in a [`PeFile64`]. pub type PeComdatSectionIterator64<'data, 'file, R = &'data [u8]> = PeComdatSectionIterator<'data, 'file, pe::ImageNtHeaders64, R>; -/// An iterator over the sections in a COMDAT section group of a `PeFile`. +/// An iterator for the sections in a COMDAT section group in a [`PeFile`]. +/// +/// This is a stub that doesn't implement any functionality. #[derive(Debug)] pub struct PeComdatSectionIterator<'data, 'file, Pe, R = &'data [u8]> where @@ -528,7 +542,7 @@ impl pe::ImageDosHeader { } } -/// Find the optional header and read the `optional_header.magic`. +/// Find the optional header and read its `magic` field. /// /// It can be useful to know this magic value before trying to /// fully parse the NT headers. @@ -547,7 +561,7 @@ pub fn optional_header_magic<'data, R: ReadRef<'data>>(data: R) -> Result { Ok(nt_headers.optional_header().magic()) } -/// A trait for generic access to `ImageNtHeaders32` and `ImageNtHeaders64`. +/// A trait for generic access to [`pe::ImageNtHeaders32`] and [`pe::ImageNtHeaders64`]. #[allow(missing_docs)] pub trait ImageNtHeaders: Debug + Pod { type ImageOptionalHeader: ImageOptionalHeader; @@ -576,7 +590,7 @@ pub trait ImageNtHeaders: Debug + Pod { /// /// `data` must be for the entire file. /// - /// `offset` must be headers offset, which can be obtained from `ImageDosHeader::nt_headers_offset`. + /// `offset` must be headers offset, which can be obtained from [`pe::ImageDosHeader::nt_headers_offset`]. /// It is updated to point after the optional header, which is where the section headers are located. /// /// Also checks that the `signature` and `magic` fields in the headers are valid. @@ -633,7 +647,7 @@ pub trait ImageNtHeaders: Debug + Pod { } } -/// A trait for generic access to `ImageOptionalHeader32` and `ImageOptionalHeader64`. +/// A trait for generic access to [`pe::ImageOptionalHeader32`] and [`pe::ImageOptionalHeader64`]. #[allow(missing_docs)] pub trait ImageOptionalHeader: Debug + Pod { // Standard fields. diff --git a/src/read/pe/import.rs b/src/read/pe/import.rs index a5535dc3..8e9a9a9f 100644 --- a/src/read/pe/import.rs +++ b/src/read/pe/import.rs @@ -7,6 +7,8 @@ use crate::{pe, LittleEndian as LE, Pod, U16Bytes}; use super::ImageNtHeaders; /// Information for parsing a PE import table. +/// +/// Returned by [`DataDirectories::import_table`](super::DataDirectories::import_table). #[derive(Debug, Clone)] pub struct ImportTable<'data> { section_data: Bytes<'data>, @@ -218,6 +220,9 @@ impl ImageThunkData for pe::ImageThunkData32 { } /// Information for parsing a PE delay-load import table. +/// +/// Returned by +/// [`DataDirectories::delay_load_import_table`](super::DataDirectories::delay_load_import_table). #[derive(Debug, Clone)] pub struct DelayLoadImportTable<'data> { section_data: Bytes<'data>, diff --git a/src/read/pe/mod.rs b/src/read/pe/mod.rs index 2b7cc5d7..ab6011c8 100644 --- a/src/read/pe/mod.rs +++ b/src/read/pe/mod.rs @@ -1,11 +1,45 @@ //! Support for reading PE files. //! -//! Defines traits to abstract over the difference between PE32/PE32+, -//! and implements read functionality in terms of these traits. +//! Traits are used to abstract over the difference between PE32 and PE32+. +//! The primary trait for this is [`ImageNtHeaders`]. //! -//! This module reuses some of the COFF functionality. +//! ## High level API //! -//! Also provides `PeFile` and related types which implement the `Object` trait. +//! [`PeFile`] implements the [`Object`](crate::read::Object) trait for +//! PE files. [`PeFile`] is parameterised by [`ImageNtHeaders`] to allow +//! reading both PE32 and PE32+. There are type aliases for these parameters +//! ([`PeFile32`] and [`PeFile64`]). +//! +//! ## Low level API +//! +//! The [`ImageNtHeaders`] trait can be directly used to parse both +//! [`pe::ImageNtHeaders32`] and [`pe::ImageNtHeaders64`]. +//! +//! ### Example for low level API +//! ```no_run +//! use object::pe; +//! use object::read::pe::ImageNtHeaders; +//! use std::error::Error; +//! use std::fs; +//! +//! /// Reads a file and displays the name of each section. +//! fn main() -> Result<(), Box> { +//! # #[cfg(feature = "std")] { +//! let data = fs::read("path/to/binary")?; +//! let dos_header = pe::ImageDosHeader::parse(&*data)?; +//! let mut offset = dos_header.nt_headers_offset().into(); +//! let (nt_headers, data_directories) = pe::ImageNtHeaders64::parse(&*data, &mut offset)?; +//! let sections = nt_headers.sections(&*data, offset)?; +//! let symbols = nt_headers.symbols(&*data)?; +//! for section in sections.iter() { +//! println!("{}", String::from_utf8_lossy(section.name(symbols.strings())?)); +//! } +//! # } +//! Ok(()) +//! } +//! ``` +#[cfg(doc)] +use crate::pe; mod file; pub use file::*; diff --git a/src/read/pe/relocation.rs b/src/read/pe/relocation.rs index 06215bd1..77421b7b 100644 --- a/src/read/pe/relocation.rs +++ b/src/read/pe/relocation.rs @@ -5,6 +5,8 @@ use crate::pe; use crate::read::{Bytes, Error, ReadError, Result}; /// An iterator over the relocation blocks in the `.reloc` section of a PE file. +/// +/// Returned by [`DataDirectories::relocation_blocks`](super::DataDirectories::relocation_blocks). #[derive(Debug, Default, Clone, Copy)] pub struct RelocationBlockIterator<'data> { data: Bytes<'data>, diff --git a/src/read/pe/resource.rs b/src/read/pe/resource.rs index 646eaefa..331da3f6 100644 --- a/src/read/pe/resource.rs +++ b/src/read/pe/resource.rs @@ -5,6 +5,8 @@ use crate::read::{ReadError, ReadRef, Result}; use crate::{pe, LittleEndian as LE, U16Bytes}; /// The `.rsrc` section of a PE file. +/// +/// Returned by [`DataDirectories::resource_directory`](super::DataDirectories::resource_directory). #[derive(Debug, Clone, Copy)] pub struct ResourceDirectory<'data> { data: &'data [u8], diff --git a/src/read/pe/section.rs b/src/read/pe/section.rs index 2880e401..74c9d7f5 100644 --- a/src/read/pe/section.rs +++ b/src/read/pe/section.rs @@ -11,14 +11,14 @@ use crate::read::{ use super::{ImageNtHeaders, PeFile, SectionTable}; -/// An iterator over the loadable sections of a `PeFile32`. +/// An iterator for the loadable sections in a [`PeFile32`](super::PeFile32). pub type PeSegmentIterator32<'data, 'file, R = &'data [u8]> = PeSegmentIterator<'data, 'file, pe::ImageNtHeaders32, R>; -/// An iterator over the loadable sections of a `PeFile64`. +/// An iterator for the loadable sections in a [`PeFile64`](super::PeFile64). pub type PeSegmentIterator64<'data, 'file, R = &'data [u8]> = PeSegmentIterator<'data, 'file, pe::ImageNtHeaders64, R>; -/// An iterator over the loadable sections of a `PeFile`. +/// An iterator for the loadable sections in a [`PeFile`]. #[derive(Debug)] pub struct PeSegmentIterator<'data, 'file, Pe, R = &'data [u8]> where @@ -44,14 +44,16 @@ where } } -/// A loadable section of a `PeFile32`. +/// A loadable section in a [`PeFile32`](super::PeFile32). pub type PeSegment32<'data, 'file, R = &'data [u8]> = PeSegment<'data, 'file, pe::ImageNtHeaders32, R>; -/// A loadable section of a `PeFile64`. +/// A loadable section in a [`PeFile64`](super::PeFile64). pub type PeSegment64<'data, 'file, R = &'data [u8]> = PeSegment<'data, 'file, pe::ImageNtHeaders64, R>; -/// A loadable section of a `PeFile`. +/// A loadable section in a [`PeFile`]. +/// +/// Most functionality is provided by the [`ObjectSegment`] trait implementation. #[derive(Debug)] pub struct PeSegment<'data, 'file, Pe, R = &'data [u8]> where @@ -132,14 +134,14 @@ where } } -/// An iterator over the sections of a `PeFile32`. +/// An iterator for the sections in a [`PeFile32`](super::PeFile32). pub type PeSectionIterator32<'data, 'file, R = &'data [u8]> = PeSectionIterator<'data, 'file, pe::ImageNtHeaders32, R>; -/// An iterator over the sections of a `PeFile64`. +/// An iterator for the sections in a [`PeFile64`](super::PeFile64). pub type PeSectionIterator64<'data, 'file, R = &'data [u8]> = PeSectionIterator<'data, 'file, pe::ImageNtHeaders64, R>; -/// An iterator over the sections of a `PeFile`. +/// An iterator for the sections in a [`PeFile`]. #[derive(Debug)] pub struct PeSectionIterator<'data, 'file, Pe, R = &'data [u8]> where @@ -166,14 +168,16 @@ where } } -/// A section of a `PeFile32`. +/// A section in a [`PeFile32`](super::PeFile32). pub type PeSection32<'data, 'file, R = &'data [u8]> = PeSection<'data, 'file, pe::ImageNtHeaders32, R>; -/// A section of a `PeFile64`. +/// A section in a [`PeFile64`](super::PeFile64). pub type PeSection64<'data, 'file, R = &'data [u8]> = PeSection<'data, 'file, pe::ImageNtHeaders64, R>; -/// A section of a `PeFile`. +/// A section in a [`PeFile`]. +/// +/// Most functionality is provided by the [`ObjectSection`] trait implementation. #[derive(Debug)] pub struct PeSection<'data, 'file, Pe, R = &'data [u8]> where @@ -419,7 +423,9 @@ impl pe::ImageSectionHeader { } } -/// An iterator over the relocations in an `PeSection`. +/// An iterator for the relocations in an [`PeSection`]. +/// +/// This is a stub that doesn't implement any functionality. #[derive(Debug)] pub struct PeRelocationIterator<'data, 'file, R = &'data [u8]>( PhantomData<(&'data (), &'file (), R)>, diff --git a/src/read/read_cache.rs b/src/read/read_cache.rs index dfce1e1b..bdd09615 100644 --- a/src/read/read_cache.rs +++ b/src/read/read_cache.rs @@ -10,7 +10,7 @@ use std::vec::Vec; use crate::read::ReadRef; -/// An implementation of `ReadRef` for data in a stream that implements +/// An implementation of [`ReadRef`] for data in a stream that implements /// `Read + Seek`. /// /// Contains a cache of read-only blocks of data, allowing references to @@ -128,7 +128,7 @@ impl<'a, R: Read + Seek> ReadRef<'a> for &'a ReadCache { } } -/// An implementation of `ReadRef` for a range of data in a stream that +/// An implementation of [`ReadRef`] for a range of data in a stream that /// implements `Read + Seek`. /// /// Shares an underlying `ReadCache` with a lifetime of `'a`. diff --git a/src/read/read_ref.rs b/src/read/read_ref.rs index a9b42522..8b87cbab 100644 --- a/src/read/read_ref.rs +++ b/src/read/read_ref.rs @@ -8,7 +8,7 @@ use crate::pod::{from_bytes, slice_from_bytes, Pod}; type Result = result::Result; -/// A trait for reading references to `Pod` types from a block of data. +/// A trait for reading references to [`Pod`] types from a block of data. /// /// This allows parsers to handle both of these cases: /// - the block of data exists in memory, and it is desirable diff --git a/src/read/traits.rs b/src/read/traits.rs index d2d0a2b2..9d65c60c 100644 --- a/src/read/traits.rs +++ b/src/read/traits.rs @@ -10,29 +10,31 @@ use crate::read::{ use crate::Endianness; /// An object file. +/// +/// This is the primary trait for the unified read API. pub trait Object<'data: 'file, 'file>: read::private::Sealed { - /// A segment in the object file. + /// A loadable segment in the object file. type Segment: ObjectSegment<'data>; - /// An iterator over the segments in the object file. + /// An iterator for the loadable segments in the object file. type SegmentIterator: Iterator; /// A section in the object file. type Section: ObjectSection<'data>; - /// An iterator over the sections in the object file. + /// An iterator for the sections in the object file. type SectionIterator: Iterator; /// A COMDAT section group in the object file. type Comdat: ObjectComdat<'data>; - /// An iterator over the COMDAT section groups in the object file. + /// An iterator for the COMDAT section groups in the object file. type ComdatIterator: Iterator; /// A symbol in the object file. type Symbol: ObjectSymbol<'data>; - /// An iterator over symbols in the object file. + /// An iterator for symbols in the object file. type SymbolIterator: Iterator; /// A symbol table in the object file. @@ -42,7 +44,7 @@ pub trait Object<'data: 'file, 'file>: read::private::Sealed { SymbolIterator = Self::SymbolIterator, >; - /// An iterator over dynamic relocations in the file. + /// An iterator for the dynamic relocations in the file. /// /// The first field in the item tuple is the address /// that the relocation applies to. @@ -75,7 +77,12 @@ pub trait Object<'data: 'file, 'file>: read::private::Sealed { /// Return the kind of this object. fn kind(&self) -> ObjectKind; - /// Get an iterator over the segments in the file. + /// Get an iterator for the loadable segments in the file. + /// + /// For ELF, this is program headers with type [`PT_LOAD`](crate::elf::PT_LOAD). + /// For Mach-O, this is load commands with type [`LC_SEGMENT`](crate::macho::LC_SEGMENT) + /// or [`LC_SEGMENT_64`](crate::macho::LC_SEGMENT_64). + /// For PE, this is all sections. fn segments(&'file self) -> Self::SegmentIterator; /// Get the section named `section_name`, if such a section exists. @@ -108,13 +115,13 @@ pub trait Object<'data: 'file, 'file>: read::private::Sealed { /// Returns an error if the index is invalid. fn section_by_index(&'file self, index: SectionIndex) -> Result; - /// Get an iterator over the sections in the file. + /// Get an iterator for the sections in the file. fn sections(&'file self) -> Self::SectionIterator; - /// Get an iterator over the COMDAT section groups in the file. + /// Get an iterator for the COMDAT section groups in the file. fn comdats(&'file self) -> Self::ComdatIterator; - /// Get the symbol table, if any. + /// Get the debugging symbol table, if any. fn symbol_table(&'file self) -> Option; /// Get the debugging symbol at the given index. @@ -124,7 +131,7 @@ pub trait Object<'data: 'file, 'file>: read::private::Sealed { /// Returns an error if the index is invalid. fn symbol_by_index(&'file self, index: SymbolIndex) -> Result; - /// Get an iterator over the debugging symbols in the file. + /// Get an iterator for the debugging symbols in the file. /// /// This may skip over symbols that are malformed or unsupported. /// @@ -145,14 +152,16 @@ pub trait Object<'data: 'file, 'file>: read::private::Sealed { /// Get the dynamic linking symbol table, if any. /// /// Only ELF has a separate dynamic linking symbol table. + /// Consider using [`Self::exports`] or [`Self::imports`] instead. fn dynamic_symbol_table(&'file self) -> Option; - /// Get an iterator over the dynamic linking symbols in the file. + /// Get an iterator for the dynamic linking symbols in the file. /// /// This may skip over symbols that are malformed or unsupported. /// - /// Only ELF has separate dynamic linking symbols. + /// Only ELF has dynamic linking symbols. /// Other file formats will return an empty iterator. + /// Consider using [`Self::exports`] or [`Self::imports`] instead. fn dynamic_symbols(&'file self) -> Self::SymbolIterator; /// Get the dynamic relocations for this file. @@ -237,20 +246,20 @@ pub trait Object<'data: 'file, 'file>: read::private::Sealed { /// Get the exported symbols that expose both a name and an address. /// - /// Some file formats may provide other kinds of symbols, that can be retrieved using - /// the lower-level API. + /// Some file formats may provide other kinds of symbols that can be retrieved using + /// the low level API. fn exports(&self) -> Result>>; - /// Return true if the file contains debug information sections, false if not. + /// Return true if the file contains DWARF debug information sections, false if not. fn has_debug_symbols(&self) -> bool; - /// The UUID from a Mach-O `LC_UUID` load command. + /// The UUID from a Mach-O [`LC_UUID`](crate::macho::LC_UUID) load command. #[inline] fn mach_uuid(&self) -> Result> { Ok(None) } - /// The build ID from an ELF `NT_GNU_BUILD_ID` note. + /// The build ID from an ELF [`NT_GNU_BUILD_ID`](crate::elf::NT_GNU_BUILD_ID) note. #[inline] fn build_id(&self) -> Result> { Ok(None) @@ -268,7 +277,7 @@ pub trait Object<'data: 'file, 'file>: read::private::Sealed { Ok(None) } - /// The filename and GUID from the PE CodeView section + /// The filename and GUID from the PE CodeView section. #[inline] fn pdb_info(&self) -> Result>> { Ok(None) @@ -279,17 +288,16 @@ pub trait Object<'data: 'file, 'file>: read::private::Sealed { /// Currently this is only non-zero for PE. fn relative_address_base(&'file self) -> u64; - /// Get the virtual address of the entry point of the binary + /// Get the virtual address of the entry point of the binary. fn entry(&'file self) -> u64; /// File flags that are specific to each file format. fn flags(&self) -> FileFlags; } -/// A loadable segment defined in an object file. +/// A loadable segment in an [`Object`]. /// -/// For ELF, this is a program header with type `PT_LOAD`. -/// For Mach-O, this is a load command with type `LC_SEGMENT` or `LC_SEGMENT_64`. +/// This trait is part of the unified read API. pub trait ObjectSegment<'data>: read::private::Sealed { /// Returns the virtual address of the segment. fn address(&self) -> u64; @@ -326,9 +334,11 @@ pub trait ObjectSegment<'data>: read::private::Sealed { fn flags(&self) -> SegmentFlags; } -/// A section defined in an object file. +/// A section in an [`Object`]. +/// +/// This trait is part of the unified read API. pub trait ObjectSection<'data>: read::private::Sealed { - /// An iterator over the relocations for a section. + /// An iterator for the relocations for a section. /// /// The first field in the item tuple is the section offset /// that the relocation applies to. @@ -409,9 +419,11 @@ pub trait ObjectSection<'data>: read::private::Sealed { fn flags(&self) -> SectionFlags; } -/// A COMDAT section group defined in an object file. +/// A COMDAT section group in an [`Object`]. +/// +/// This trait is part of the unified read API. pub trait ObjectComdat<'data>: read::private::Sealed { - /// An iterator over the sections in the object file. + /// An iterator for the sections in the section group. type SectionIterator: Iterator; /// Returns the COMDAT selection kind. @@ -432,15 +444,17 @@ pub trait ObjectComdat<'data>: read::private::Sealed { fn sections(&self) -> Self::SectionIterator; } -/// A symbol table. +/// A symbol table in an [`Object`]. +/// +/// This trait is part of the unified read API. pub trait ObjectSymbolTable<'data>: read::private::Sealed { /// A symbol table entry. type Symbol: ObjectSymbol<'data>; - /// An iterator over the symbols in a symbol table. + /// An iterator for the symbols in a symbol table. type SymbolIterator: Iterator; - /// Get an iterator over the symbols in the table. + /// Get an iterator for the symbols in the table. /// /// This may skip over symbols that are malformed or unsupported. fn symbols(&self) -> Self::SymbolIterator; @@ -453,7 +467,9 @@ pub trait ObjectSymbolTable<'data>: read::private::Sealed { fn symbol_by_index(&self, index: SymbolIndex) -> Result; } -/// A symbol table entry. +/// A symbol table entry in an [`Object`]. +/// +/// This trait is part of the unified read API. pub trait ObjectSymbol<'data>: read::private::Sealed { /// The index of the symbol. fn index(&self) -> SymbolIndex; @@ -490,11 +506,13 @@ pub trait ObjectSymbol<'data>: read::private::Sealed { /// Return true if the symbol is a definition of a function or data object /// that has a known address. + /// + /// This is primarily used to implement [`Object::symbol_map`]. fn is_definition(&self) -> bool; /// Return true if the symbol is common data. /// - /// Note: does not check for `SymbolSection::Section` with `SectionKind::Common`. + /// Note: does not check for [`SymbolSection::Section`] with [`SectionKind::Common`]. fn is_common(&self) -> bool; /// Return true if the symbol is weak. @@ -505,7 +523,7 @@ pub trait ObjectSymbol<'data>: read::private::Sealed { /// Return true if the symbol visible outside of the compilation unit. /// - /// This treats `SymbolScope::Unknown` as global. + /// This treats [`SymbolScope::Unknown`] as global. fn is_global(&self) -> bool; /// Return true if the symbol is only visible within the compilation unit. diff --git a/src/read/util.rs b/src/read/util.rs index 7c3c65ec..7d85b272 100644 --- a/src/read/util.rs +++ b/src/read/util.rs @@ -269,7 +269,7 @@ pub(crate) fn data_range( /// A table of zero-terminated strings. /// -/// This is used for most file formats. +/// This is used by most file formats for strings such as section names and symbol names. #[derive(Debug, Clone, Copy)] pub struct StringTable<'data, R = &'data [u8]> where diff --git a/src/read/wasm.rs b/src/read/wasm.rs index 05b5cbc7..4d034bcc 100644 --- a/src/read/wasm.rs +++ b/src/read/wasm.rs @@ -1,8 +1,6 @@ //! Support for reading Wasm files. //! -//! Provides `WasmFile` and related types which implement the `Object` trait. -//! -//! Currently implements the minimum required to access DWARF debugging information. +//! [`WasmFile`] implements the [`Object`] trait for Wasm files. use alloc::boxed::Box; use alloc::vec::Vec; use core::marker::PhantomData; @@ -505,7 +503,9 @@ where } } -/// An iterator over the segments of a `WasmFile`. +/// An iterator for the segments in a [`WasmFile`]. +/// +/// This is a stub that doesn't implement any functionality. #[derive(Debug)] pub struct WasmSegmentIterator<'data, 'file, R = &'data [u8]> { #[allow(unused)] @@ -521,7 +521,9 @@ impl<'data, 'file, R> Iterator for WasmSegmentIterator<'data, 'file, R> { } } -/// A segment of a `WasmFile`. +/// A segment in a [`WasmFile`]. +/// +/// This is a stub that doesn't implement any functionality. #[derive(Debug)] pub struct WasmSegment<'data, 'file, R = &'data [u8]> { #[allow(unused)] @@ -575,7 +577,7 @@ impl<'data, 'file, R> ObjectSegment<'data> for WasmSegment<'data, 'file, R> { } } -/// An iterator over the sections of a `WasmFile`. +/// An iterator for the sections in a [`WasmFile`]. #[derive(Debug)] pub struct WasmSectionIterator<'data, 'file, R = &'data [u8]> { file: &'file WasmFile<'data, R>, @@ -594,7 +596,9 @@ impl<'data, 'file, R> Iterator for WasmSectionIterator<'data, 'file, R> { } } -/// A section of a `WasmFile`. +/// A section in a [`WasmFile`]. +/// +/// Most functionality is provided by the [`ObjectSection`] trait implementation. #[derive(Debug)] pub struct WasmSection<'data, 'file, R = &'data [u8]> { file: &'file WasmFile<'data, R>, @@ -725,7 +729,9 @@ impl<'data, 'file, R: ReadRef<'data>> ObjectSection<'data> for WasmSection<'data } } -/// An iterator over the COMDAT section groups of a `WasmFile`. +/// An iterator for the COMDAT section groups in a [`WasmFile`]. +/// +/// This is a stub that doesn't implement any functionality. #[derive(Debug)] pub struct WasmComdatIterator<'data, 'file, R = &'data [u8]> { #[allow(unused)] @@ -741,7 +747,9 @@ impl<'data, 'file, R> Iterator for WasmComdatIterator<'data, 'file, R> { } } -/// A COMDAT section group of a `WasmFile`. +/// A COMDAT section group in a [`WasmFile`]. +/// +/// This is a stub that doesn't implement any functionality. #[derive(Debug)] pub struct WasmComdat<'data, 'file, R = &'data [u8]> { #[allow(unused)] @@ -779,7 +787,9 @@ impl<'data, 'file, R> ObjectComdat<'data> for WasmComdat<'data, 'file, R> { } } -/// An iterator over the sections in a COMDAT section group of a `WasmFile`. +/// An iterator for the sections in a COMDAT section group in a [`WasmFile`]. +/// +/// This is a stub that doesn't implement any functionality. #[derive(Debug)] pub struct WasmComdatSectionIterator<'data, 'file, R = &'data [u8]> { #[allow(unused)] @@ -794,7 +804,7 @@ impl<'data, 'file, R> Iterator for WasmComdatSectionIterator<'data, 'file, R> { } } -/// A symbol table of a `WasmFile`. +/// A symbol table in a [`WasmFile`]. #[derive(Debug)] pub struct WasmSymbolTable<'data, 'file> { symbols: &'file [WasmSymbolInternal<'data>], @@ -821,7 +831,7 @@ impl<'data, 'file> ObjectSymbolTable<'data> for WasmSymbolTable<'data, 'file> { } } -/// An iterator over the symbols of a `WasmFile`. +/// An iterator for the symbols in a [`WasmFile`]. #[derive(Debug)] pub struct WasmSymbolIterator<'data, 'file> { symbols: core::iter::Enumerate>>, @@ -839,7 +849,9 @@ impl<'data, 'file> Iterator for WasmSymbolIterator<'data, 'file> { } } -/// A symbol of a `WasmFile`. +/// A symbol in a [`WasmFile`]. +/// +/// Most functionality is provided by the [`ObjectSymbol`] trait implementation. #[derive(Clone, Copy, Debug)] pub struct WasmSymbol<'data, 'file> { index: SymbolIndex, @@ -936,7 +948,9 @@ impl<'data, 'file> ObjectSymbol<'data> for WasmSymbol<'data, 'file> { } } -/// An iterator over the relocations in a `WasmSection`. +/// An iterator for the relocations for a [`WasmSection`]. +/// +/// This is a stub that doesn't implement any functionality. #[derive(Debug)] pub struct WasmRelocationIterator<'data, 'file, R = &'data [u8]>( PhantomData<(&'data (), &'file (), R)>, diff --git a/src/read/xcoff/comdat.rs b/src/read/xcoff/comdat.rs index 2b23d1db..03e52bfa 100644 --- a/src/read/xcoff/comdat.rs +++ b/src/read/xcoff/comdat.rs @@ -8,14 +8,16 @@ use crate::read::{self, ComdatKind, ObjectComdat, ReadRef, Result, SectionIndex, use super::{FileHeader, XcoffFile}; -/// An iterator over the COMDAT section groups of a `XcoffFile32`. +/// An iterator for the COMDAT section groups in a [`XcoffFile32`](super::XcoffFile32). pub type XcoffComdatIterator32<'data, 'file, R = &'data [u8]> = XcoffComdatIterator<'data, 'file, xcoff::FileHeader32, R>; -/// An iterator over the COMDAT section groups of a `XcoffFile64`. +/// An iterator for the COMDAT section groups in a [`XcoffFile64`](super::XcoffFile64). pub type XcoffComdatIterator64<'data, 'file, R = &'data [u8]> = XcoffComdatIterator<'data, 'file, xcoff::FileHeader64, R>; -/// An iterator over the COMDAT section groups of a `XcoffFile`. +/// An iterator for the COMDAT section groups in a [`XcoffFile`]. +/// +/// This is a stub that doesn't implement any functionality. #[derive(Debug)] pub struct XcoffComdatIterator<'data, 'file, Xcoff, R = &'data [u8]> where @@ -39,15 +41,17 @@ where } } -/// A COMDAT section group of a `XcoffFile32`. +/// A COMDAT section group in a [`XcoffFile32`](super::XcoffFile32). pub type XcoffComdat32<'data, 'file, R = &'data [u8]> = XcoffComdat<'data, 'file, xcoff::FileHeader32, R>; -/// A COMDAT section group of a `XcoffFile64`. +/// A COMDAT section group in a [`XcoffFile64`](super::XcoffFile64). pub type XcoffComdat64<'data, 'file, R = &'data [u8]> = XcoffComdat<'data, 'file, xcoff::FileHeader64, R>; -/// A COMDAT section group of a `XcoffFile`. +/// A COMDAT section group in a [`XcoffFile`]. +/// +/// This is a stub that doesn't implement any functionality. #[derive(Debug)] pub struct XcoffComdat<'data, 'file, Xcoff, R = &'data [u8]> where @@ -98,14 +102,16 @@ where } } -/// An iterator over the sections in a COMDAT section group of a `XcoffFile32`. +/// An iterator for the sections in a COMDAT section group in a [`XcoffFile32`](super::XcoffFile32). pub type XcoffComdatSectionIterator32<'data, 'file, R = &'data [u8]> = XcoffComdatSectionIterator<'data, 'file, xcoff::FileHeader32, R>; -/// An iterator over the sections in a COMDAT section group of a `XcoffFile64`. +/// An iterator for the sections in a COMDAT section group in a [`XcoffFile64`](super::XcoffFile64). pub type XcoffComdatSectionIterator64<'data, 'file, R = &'data [u8]> = XcoffComdatSectionIterator<'data, 'file, xcoff::FileHeader64, R>; -/// An iterator over the sections in a COMDAT section group of a `XcoffFile`. +/// An iterator for the sections in a COMDAT section group in a [`XcoffFile`]. +/// +/// This is a stub that doesn't implement any functionality. #[derive(Debug)] pub struct XcoffComdatSectionIterator<'data, 'file, Xcoff, R = &'data [u8]> where diff --git a/src/read/xcoff/file.rs b/src/read/xcoff/file.rs index 0e5c95b2..70d980a9 100644 --- a/src/read/xcoff/file.rs +++ b/src/read/xcoff/file.rs @@ -17,13 +17,19 @@ use super::{ }; /// A 32-bit XCOFF object file. +/// +/// This is a file that starts with [`xcoff::FileHeader32`], and corresponds +/// to [`crate::FileKind::Xcoff32`]. pub type XcoffFile32<'data, R = &'data [u8]> = XcoffFile<'data, xcoff::FileHeader32, R>; /// A 64-bit XCOFF object file. +/// +/// This is a file that starts with [`xcoff::FileHeader64`], and corresponds +/// to [`crate::FileKind::Xcoff64`]. pub type XcoffFile64<'data, R = &'data [u8]> = XcoffFile<'data, xcoff::FileHeader64, R>; /// A partially parsed XCOFF file. /// -/// Most of the functionality of this type is provided by the `Object` trait implementation. +/// Most functionality is provided by the [`Object`] trait implementation. #[derive(Debug)] pub struct XcoffFile<'data, Xcoff, R = &'data [u8]> where @@ -238,7 +244,7 @@ where } } -/// A trait for generic access to `FileHeader32` and `FileHeader64`. +/// A trait for generic access to [`xcoff::FileHeader32`] and [`xcoff::FileHeader64`]. #[allow(missing_docs)] pub trait FileHeader: Debug + Pod { type Word: Into; @@ -404,6 +410,7 @@ impl FileHeader for xcoff::FileHeader64 { } } +/// A trait for generic access to [`xcoff::AuxHeader32`] and [`xcoff::AuxHeader64`]. #[allow(missing_docs)] pub trait AuxHeader: Debug + Pod { type Word: Into; diff --git a/src/read/xcoff/mod.rs b/src/read/xcoff/mod.rs index 136e3107..b75c4da2 100644 --- a/src/read/xcoff/mod.rs +++ b/src/read/xcoff/mod.rs @@ -1,6 +1,48 @@ //! Support for reading AIX XCOFF files. //! -//! Provides `XcoffFile` and related types which implement the `Object` trait. +//! Traits are used to abstract over the difference between 32-bit and 64-bit XCOFF. +//! The primary trait for this is [`FileHeader`]. +//! +//! ## High level API +//! +//! [`XcoffFile`] implements the [`Object`](crate::read::Object) trait for XCOFF files. +//! [`XcoffFile`] is parameterised by [`FileHeader`] to allow reading both 32-bit and +//! 64-bit XCOFF. There are type aliases for these parameters ([`XcoffFile32`] and +//! [`XcoffFile64`]). +//! +//! ## Low level API +//! +//! The [`FileHeader`] trait can be directly used to parse both [`xcoff::FileHeader32`] +//! and [`xcoff::FileHeader64`]. +//! +//! ### Example for low level API +//! ```no_run +//! use object::xcoff; +//! use object::read::xcoff::{FileHeader, SectionHeader, Symbol}; +//! use std::error::Error; +//! use std::fs; +//! +//! /// Reads a file and displays the name of each section and symbol. +//! fn main() -> Result<(), Box> { +//! # #[cfg(feature = "std")] { +//! let data = fs::read("path/to/binary")?; +//! let mut offset = 0; +//! let header = xcoff::FileHeader64::parse(&*data, &mut offset)?; +//! let aux_header = header.aux_header(&*data, &mut offset)?; +//! let sections = header.sections(&*data, &mut offset)?; +//! let symbols = header.symbols(&*data)?; +//! for section in sections.iter() { +//! println!("{}", String::from_utf8_lossy(section.name())); +//! } +//! for (_index, symbol) in symbols.iter() { +//! println!("{}", String::from_utf8_lossy(symbol.name(symbols.strings())?)); +//! } +//! # } +//! Ok(()) +//! } +//! ``` +#[cfg(doc)] +use crate::xcoff; mod file; pub use file::*; diff --git a/src/read/xcoff/relocation.rs b/src/read/xcoff/relocation.rs index 78c6acfc..a655cccf 100644 --- a/src/read/xcoff/relocation.rs +++ b/src/read/xcoff/relocation.rs @@ -9,14 +9,14 @@ use crate::read::{ReadRef, RelocationEncoding, RelocationKind, RelocationTarget, use super::{FileHeader, SectionHeader, XcoffFile}; -/// An iterator over the relocations in a `XcoffSection32`. +/// An iterator for the relocations in an [`XcoffSection32`](super::XcoffSection32). pub type XcoffRelocationIterator32<'data, 'file, R = &'data [u8]> = XcoffRelocationIterator<'data, 'file, xcoff::FileHeader32, R>; -/// An iterator over the relocations in a `XcoffSection64`. +/// An iterator for the relocations in an [`XcoffSection64`](super::XcoffSection64). pub type XcoffRelocationIterator64<'data, 'file, R = &'data [u8]> = XcoffRelocationIterator<'data, 'file, xcoff::FileHeader64, R>; -/// An iterator over the relocations in a `XcoffSection`. +/// An iterator for the relocations in an [`XcoffSection`](super::XcoffSection). pub struct XcoffRelocationIterator<'data, 'file, Xcoff, R = &'data [u8]> where Xcoff: FileHeader, @@ -76,7 +76,7 @@ where } } -/// A trait for generic access to `Rel32` and `Rel64`. +/// A trait for generic access to [`xcoff::Rel32`] and [`xcoff::Rel64`]. #[allow(missing_docs)] pub trait Rel: Debug + Pod { type Word: Into; diff --git a/src/read/xcoff/section.rs b/src/read/xcoff/section.rs index 77453fcd..8a36bcf2 100644 --- a/src/read/xcoff/section.rs +++ b/src/read/xcoff/section.rs @@ -9,14 +9,14 @@ use crate::read::{self, Error, ObjectSection, ReadError, ReadRef, Result, Sectio use super::{AuxHeader, FileHeader, Rel, XcoffFile, XcoffRelocationIterator}; -/// An iterator over the sections of an `XcoffFile32`. +/// An iterator for the sections in an [`XcoffFile32`](super::XcoffFile32). pub type XcoffSectionIterator32<'data, 'file, R = &'data [u8]> = XcoffSectionIterator<'data, 'file, xcoff::FileHeader32, R>; -/// An iterator over the sections of an `XcoffFile64`. +/// An iterator for the sections in an [`XcoffFile64`](super::XcoffFile64). pub type XcoffSectionIterator64<'data, 'file, R = &'data [u8]> = XcoffSectionIterator<'data, 'file, xcoff::FileHeader64, R>; -/// An iterator over the sections of an `XcoffFile`. +/// An iterator for the sections in an [`XcoffFile`]. #[derive(Debug)] pub struct XcoffSectionIterator<'data, 'file, Xcoff, R = &'data [u8]> where @@ -43,14 +43,16 @@ where } } -/// A section of an `XcoffFile32`. +/// A section in an [`XcoffFile32`](super::XcoffFile32). pub type XcoffSection32<'data, 'file, R = &'data [u8]> = XcoffSection<'data, 'file, xcoff::FileHeader32, R>; -/// A section of an `XcoffFile64`. +/// A section in an [`XcoffFile64`](super::XcoffFile64). pub type XcoffSection64<'data, 'file, R = &'data [u8]> = XcoffSection<'data, 'file, xcoff::FileHeader64, R>; -/// A section of an `XcoffFile`. +/// A section in an [`XcoffFile`]. +/// +/// Most functionality is provided by the [`ObjectSection`] trait implementation. #[derive(Debug)] pub struct XcoffSection<'data, 'file, Xcoff, R = &'data [u8]> where @@ -199,6 +201,8 @@ where } /// The table of section headers in an XCOFF file. +/// +/// Returned by [`FileHeader::sections`]. #[derive(Debug, Clone, Copy)] pub struct SectionTable<'data, Xcoff: FileHeader> { sections: &'data [Xcoff::SectionHeader], @@ -260,7 +264,7 @@ where } } -/// A trait for generic access to `SectionHeader32` and `SectionHeader64`. +/// A trait for generic access to [`xcoff::SectionHeader32`] and [`xcoff::SectionHeader64`]. #[allow(missing_docs)] pub trait SectionHeader: Debug + Pod { type Word: Into; diff --git a/src/read/xcoff/segment.rs b/src/read/xcoff/segment.rs index 7eca7236..d30d7d8e 100644 --- a/src/read/xcoff/segment.rs +++ b/src/read/xcoff/segment.rs @@ -8,14 +8,16 @@ use crate::xcoff; use super::{FileHeader, XcoffFile}; -/// An iterator over the segments of an `XcoffFile32`. +/// An iterator for the segments in an [`XcoffFile32`](super::XcoffFile32). pub type XcoffSegmentIterator32<'data, 'file, R = &'data [u8]> = XcoffSegmentIterator<'data, 'file, xcoff::FileHeader32, R>; -/// An iterator over the segments of an `XcoffFile64`. +/// An iterator for the segments in an [`XcoffFile64`](super::XcoffFile64). pub type XcoffSegmentIterator64<'data, 'file, R = &'data [u8]> = XcoffSegmentIterator<'data, 'file, xcoff::FileHeader64, R>; -/// An iterator over the segments of an `XcoffFile`. +/// An iterator for the segments in an [`XcoffFile`]. +/// +/// This is a stub that doesn't implement any functionality. #[derive(Debug)] pub struct XcoffSegmentIterator<'data, 'file, Xcoff, R = &'data [u8]> where @@ -38,14 +40,16 @@ where } } -/// A segment of an `XcoffFile32`. +/// A segment in an [`XcoffFile32`](super::XcoffFile32). pub type XcoffSegment32<'data, 'file, R = &'data [u8]> = XcoffSegment<'data, 'file, xcoff::FileHeader32, R>; -/// A segment of an `XcoffFile64`. +/// A segment in an [`XcoffFile64`](super::XcoffFile64). pub type XcoffSegment64<'data, 'file, R = &'data [u8]> = XcoffSegment<'data, 'file, xcoff::FileHeader64, R>; -/// A loadable section of an `XcoffFile`. +/// A loadable section in an [`XcoffFile`]. +/// +/// This is a stub that doesn't implement any functionality. #[derive(Debug)] pub struct XcoffSegment<'data, 'file, Xcoff, R = &'data [u8]> where diff --git a/src/read/xcoff/symbol.rs b/src/read/xcoff/symbol.rs index 05ff15d3..72651c3f 100644 --- a/src/read/xcoff/symbol.rs +++ b/src/read/xcoff/symbol.rs @@ -19,6 +19,8 @@ use super::{FileHeader, XcoffFile}; /// A table of symbol entries in an XCOFF file. /// /// Also includes the string table used for the symbol names. +/// +/// Returned by [`FileHeader::symbols`]. #[derive(Debug)] pub struct SymbolTable<'data, Xcoff, R = &'data [u8]> where @@ -184,14 +186,14 @@ impl<'data, 'table, Xcoff: FileHeader, R: ReadRef<'data>> Iterator } } -/// A symbol table of an `XcoffFile32`. +/// A symbol table in an [`XcoffFile32`](super::XcoffFile32). pub type XcoffSymbolTable32<'data, 'file, R = &'data [u8]> = XcoffSymbolTable<'data, 'file, xcoff::FileHeader32, R>; -/// A symbol table of an `XcoffFile64`. +/// A symbol table in an [`XcoffFile64`](super::XcoffFile64). pub type XcoffSymbolTable64<'data, 'file, R = &'data [u8]> = XcoffSymbolTable<'data, 'file, xcoff::FileHeader64, R>; -/// A symbol table of an `XcoffFile`. +/// A symbol table in an [`XcoffFile`]. #[derive(Debug, Clone, Copy)] pub struct XcoffSymbolTable<'data, 'file, Xcoff, R = &'data [u8]> where @@ -231,14 +233,14 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbolTable<'data } } -/// An iterator over the symbols of an `XcoffFile32`. +/// An iterator for the symbols in an [`XcoffFile32`](super::XcoffFile32). pub type XcoffSymbolIterator32<'data, 'file, R = &'data [u8]> = XcoffSymbolIterator<'data, 'file, xcoff::FileHeader32, R>; -/// An iterator over the symbols of an `XcoffFile64`. +/// An iterator for the symbols in an [`XcoffFile64`](super::XcoffFile64). pub type XcoffSymbolIterator64<'data, 'file, R = &'data [u8]> = XcoffSymbolIterator<'data, 'file, xcoff::FileHeader64, R>; -/// An iterator over the symbols of an `XcoffFile`. +/// An iterator for the symbols in an [`XcoffFile`]. pub struct XcoffSymbolIterator<'data, 'file, Xcoff, R = &'data [u8]> where Xcoff: FileHeader, @@ -272,14 +274,16 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> Iterator } } -/// A symbol of an `XcoffFile32`. +/// A symbol in an [`XcoffFile32`](super::XcoffFile32). pub type XcoffSymbol32<'data, 'file, R = &'data [u8]> = XcoffSymbol<'data, 'file, xcoff::FileHeader32, R>; -/// A symbol of an `XcoffFile64`. +/// A symbol in an [`XcoffFile64`](super::XcoffFile64). pub type XcoffSymbol64<'data, 'file, R = &'data [u8]> = XcoffSymbol<'data, 'file, xcoff::FileHeader64, R>; -/// A symbol of an `XcoffFile`. +/// A symbol in an [`XcoffFile`]. +/// +/// Most functionality is provided by the [`ObjectSymbol`] trait implementation. #[derive(Debug, Clone, Copy)] pub struct XcoffSymbol<'data, 'file, Xcoff, R = &'data [u8]> where @@ -497,7 +501,7 @@ impl<'data, 'file, Xcoff: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> } } -/// A trait for generic access to `Symbol32` and `Symbol64`. +/// A trait for generic access to [`xcoff::Symbol32`] and [`xcoff::Symbol64`]. #[allow(missing_docs)] pub trait Symbol: Debug + Pod { type Word: Into; @@ -628,7 +632,7 @@ impl Symbol for xcoff::Symbol32 { } } -/// A trait for generic access to `FileAux32` and `FileAux64`. +/// A trait for generic access to [`xcoff::FileAux32`] and [`xcoff::FileAux64`]. #[allow(missing_docs)] pub trait FileAux: Debug + Pod { fn x_fname(&self) -> &[u8; 8]; @@ -693,7 +697,7 @@ impl FileAux for xcoff::FileAux32 { } } -/// A trait for generic access to `CsectAux32` and `CsectAux64`. +/// A trait for generic access to [`xcoff::CsectAux32`] and [`xcoff::CsectAux64`]. #[allow(missing_docs)] pub trait CsectAux: Debug + Pod { fn x_scnlen(&self) -> u64;