pub struct PDB<'s, S> { /* private fields */ }
Expand description
PDB
provides access to the data within a PDB file.
A PDB file is internally a Multi-Stream File (MSF), composed of multiple independent
(and usually discontiguous) data streams on-disk. PDB
provides lazy access to these data
structures, which means the PDB
accessor methods usually cause disk accesses.
Implementations
sourceimpl<'s, S: Source<'s> + 's> PDB<'s, S>
impl<'s, S: Source<'s> + 's> PDB<'s, S>
sourcepub fn open(source: S) -> Result<PDB<'s, S>>
pub fn open(source: S) -> Result<PDB<'s, S>>
Create a new PDB
for a Source
.
open()
accesses enough of the source file to find the MSF stream table. This usually
involves reading the header, a block near the end of the file, and finally the stream table
itself. It does not access or validate any of the contents of the rest of the PDB.
Errors
Error::UnimplementedFeature
if the PDB file predates ~2002Error::UnrecognizedFileFormat
if theSource
does not appear to be a PDB fileError::IoError
if returned by theSource
Error::PageReferenceOutOfRange
,Error::InvalidPageSize
if the PDB file seems corrupt
sourcepub fn pdb_information(&mut self) -> Result<PDBInformation<'s>>
pub fn pdb_information(&mut self) -> Result<PDBInformation<'s>>
Retrieve the PDBInformation
for this PDB.
The PDBInformation
object contains the GUID and age fields that can be used to verify
that a PDB file matches a binary, as well as the stream indicies of named PDB streams.
Errors
Error::StreamNotFound
if the PDB somehow does not contain the PDB information streamError::IoError
if returned by theSource
Error::PageReferenceOutOfRange
if the PDB file seems corrupt
sourcepub fn type_information(&mut self) -> Result<TypeInformation<'s>>
pub fn type_information(&mut self) -> Result<TypeInformation<'s>>
Retrieve the TypeInformation
for this PDB.
The TypeInformation
object owns a SourceView
for the type information (“TPI”) stream.
This is usually the single largest stream of the PDB file.
Errors
Error::StreamNotFound
if the PDB does not contain the type information streamError::IoError
if returned by theSource
Error::PageReferenceOutOfRange
if the PDB file seems corruptError::InvalidTypeInformationHeader
if the type information stream header was not understood
sourcepub fn id_information(&mut self) -> Result<IdInformation<'s>>
pub fn id_information(&mut self) -> Result<IdInformation<'s>>
Retrieve the IdInformation
for this PDB.
The IdInformation
object owns a SourceView
for the type information (“IPI”) stream.
Errors
Error::StreamNotFound
if the PDB does not contain the id information streamError::IoError
if returned by theSource
Error::PageReferenceOutOfRange
if the PDB file seems corruptError::InvalidTypeInformationHeader
if the id information stream header was not understood
sourcepub fn debug_information(&mut self) -> Result<DebugInformation<'s>>
pub fn debug_information(&mut self) -> Result<DebugInformation<'s>>
Retrieve the DebugInformation
for this PDB.
The DebugInformation
object owns a SourceView
for the debug information (“DBI”) stream.
Errors
Error::StreamNotFound
if the PDB somehow does not contain a symbol records streamError::IoError
if returned by theSource
Error::PageReferenceOutOfRange
if the PDB file seems corruptError::UnimplementedFeature
if the debug information header predates ~1995
sourcepub fn global_symbols(&mut self) -> Result<SymbolTable<'s>>
pub fn global_symbols(&mut self) -> Result<SymbolTable<'s>>
Retrieve the global symbol table for this PDB.
The SymbolTable
object owns a SourceView
for the symbol records stream. This is usually
the second-largest stream of the PDB file.
The debug information stream indicates which stream is the symbol records stream, so
global_symbols()
accesses the debug information stream to read the header unless
debug_information()
was called first.
Errors
Error::StreamNotFound
if the PDB somehow does not contain a symbol records streamError::IoError
if returned by theSource
Error::PageReferenceOutOfRange
if the PDB file seems corrupt
If debug_information()
was not already called, global_symbols()
will additionally read
the debug information header, in which case it can also return:
Error::StreamNotFound
if the PDB somehow does not contain a debug information streamError::UnimplementedFeature
if the debug information header predates ~1995
sourcepub fn module_info<'m>(
&mut self,
module: &Module<'m>
) -> Result<Option<ModuleInfo<'s>>>
pub fn module_info<'m>(
&mut self,
module: &Module<'m>
) -> Result<Option<ModuleInfo<'s>>>
Retrieve the module info stream for a specific Module
.
Some information for each module is stored in a separate stream per-module. Module
s can be
retrieved from the PDB
by first calling debug_information
to
get the debug information stream, and then calling modules
on
that.
Errors
Error::StreamNotFound
if the PDB does not contain this module info streamError::IoError
if returned by theSource
Error::PageReferenceOutOfRange
if the PDB file seems corruptError::UnimplementedFeature
if the module information stream is an unsupported version
Example
let file = std::fs::File::open("fixtures/self/foo.pdb")?;
let mut pdb = pdb::PDB::open(file)?;
let dbi = pdb.debug_information()?;
let mut modules = dbi.modules()?;
if let Some(module) = modules.next()? {
println!("module name: {}, object file name: {}",
module.module_name(), module.object_file_name());
match pdb.module_info(&module)? {
Some(info) => println!("contains {} symbols", info.symbols()?.count()?),
None => println!("module information not available"),
}
}
sourcepub fn sections(&mut self) -> Result<Option<Vec<ImageSectionHeader>>>
pub fn sections(&mut self) -> Result<Option<Vec<ImageSectionHeader>>>
Retrieve the executable’s section headers, as stored inside this PDB.
The debug information stream indicates which stream contains the section headers, so
sections()
accesses the debug information stream to read the header unless
debug_information()
was called first.
Errors
Error::StreamNotFound
if the PDB somehow does not contain section headersError::IoError
if returned by theSource
Error::PageReferenceOutOfRange
if the PDB file seems corruptError::UnexpectedEof
if the section headers are truncated mid-record
If debug_information()
was not already called, sections()
will additionally read
the debug information header, in which case it can also return:
Error::StreamNotFound
if the PDB somehow does not contain a debug information streamError::UnimplementedFeature
if the debug information header predates ~1995
sourcepub fn frame_table(&mut self) -> Result<FrameTable<'s>>
pub fn frame_table(&mut self) -> Result<FrameTable<'s>>
Retrieve the global frame data table.
This table describes the stack frame layout for functions from all modules in the PDB. Not every function in the image file must have FPO information defined for it. Those functions that do not have FPO information are assumed to have normal stack frames.
If this PDB does not contain frame data, the returned table is empty.
Errors
Error::StreamNotFound
if the PDB does not contain the referenced streamsError::IoError
if returned by theSource
Error::PageReferenceOutOfRange
if the PDB file seems corrupt
Example
let mut pdb = PDB::open(source)?;
// Read the tables once and reuse them
let address_map = pdb.address_map()?;
let frame_table = pdb.frame_table()?;
let mut frames = frame_table.iter();
// Iterate frame data in internal RVA order
while let Some(frame) = frames.next()? {
println!("{:#?}", frame);
}
sourcepub fn address_map(&mut self) -> Result<AddressMap<'s>>
pub fn address_map(&mut self) -> Result<AddressMap<'s>>
Build a map translating between different kinds of offsets and virtual addresses.
For more information on address translation, see AddressMap
.
This reads omap_from_src
and either original_sections
or sections
from this PDB and
chooses internally which strategy to use for resolving RVAs. Consider to reuse this instance
for multiple translations.
Errors
Error::OmapNotFound
if an OMAP is required for translation but missingError::StreamNotFound
if the PDB somehow does not contain section headersError::IoError
if returned by theSource
Error::PageReferenceOutOfRange
if the PDB file seems corruptError::UnexpectedEof
if the section headers are truncated mid-record
If debug_information()
was not already called, omap_table()
will additionally read the
debug information header, in which case it can also return:
Error::StreamNotFound
if the PDB somehow does not contain a debug information streamError::UnimplementedFeature
if the debug information header predates ~1995
Example
let mut pdb = pdb::PDB::open(source)?;
// Compute the address map once and reuse it
let address_map = pdb.address_map()?;
// Obtain some section offset, eg from a symbol, and convert it
match pubsym.offset.to_rva(&address_map) {
Some(rva) => {
println!("symbol is at {}", rva);
}
None => {
println!("symbol refers to eliminated code");
}
}
sourcepub fn string_table(&mut self) -> Result<StringTable<'s>>
pub fn string_table(&mut self) -> Result<StringTable<'s>>
Retrieve the global string table of this PDB.
Long strings, such as file names, are stored in a global deduplicated string table. They are
referred to by the StringRef
type, which contains an offset into that table. Strings in
the table are stored as null-terminated C strings. Modern PDBs only store valid UTF-8 data
in the string table, but for older types a decoding might be necessary.
The string table offers cheap zero-copy access to the underlying string data. It is therefore cheap to build.
Example
let mut pdb = PDB::open(file)?;
let strings = pdb.string_table()?;
// obtain a string ref somehow
let raw_string = strings.get(string_ref)?;
println!("{}", raw_string.to_string());
// alternatively, use convenience methods
println!("{}", string_ref.to_string_lossy(&strings)?);
Errors
Error::StreamNotFound
if the PDB somehow does not contain section headersError::IoError
if returned by theSource
Error::PageReferenceOutOfRange
if the PDB file seems corruptError::UnexpectedEof
if the string table ends prematurely
sourcepub fn raw_stream(&mut self, index: StreamIndex) -> Result<Option<Stream<'s>>>
pub fn raw_stream(&mut self, index: StreamIndex) -> Result<Option<Stream<'s>>>
Retrieve a stream by its index to read its contents as bytes.
Errors
Error::StreamNotFound
if the PDB does not contain this streamError::IoError
if returned by theSource
Error::PageReferenceOutOfRange
if the PDB file seems corrupt
Example
let file = std::fs::File::open("fixtures/self/foo.pdb")?;
let mut pdb = pdb::PDB::open(file)?;
// This is the index of the "mystream" stream that was added using pdbstr.exe.
let s = pdb.raw_stream(pdb::StreamIndex(208))?.expect("stream exists");
assert_eq!(s.as_slice(), b"hello world\n");
sourcepub fn named_stream(&mut self, name: &[u8]) -> Result<Stream<'s>>
pub fn named_stream(&mut self, name: &[u8]) -> Result<Stream<'s>>
Retrieve a stream by its name, as declared in the PDB info stream.
Errors
Error::StreamNameNotFound
if the PDB does not specify a stream with that nameError::StreamNotFound
if the PDB does not contain the stream referred toError::IoError
if returned by theSource
Error::PageReferenceOutOfRange
if the PDB file seems corrupt
Trait Implementations
Auto Trait Implementations
impl<'s, S> !RefUnwindSafe for PDB<'s, S>
impl<'s, S> !Send for PDB<'s, S>
impl<'s, S> !Sync for PDB<'s, S>
impl<'s, S> Unpin for PDB<'s, S>
impl<'s, S> !UnwindSafe for PDB<'s, S>
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more