Struct symbolic::debuginfo::pdb::pdb::PDB

source ·
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§

source§

impl<'s, S> PDB<'s, S>
where S: Source<'s> + 's,

source

pub fn open(source: S) -> Result<PDB<'s, S>, Error>

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 ~2002
  • Error::UnrecognizedFileFormat if the Source does not appear to be a PDB file
  • Error::IoError if returned by the Source
  • Error::PageReferenceOutOfRange, Error::InvalidPageSize if the PDB file seems corrupt
source

pub fn pdb_information(&mut self) -> Result<PDBInformation<'s>, Error>

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 stream
  • Error::IoError if returned by the Source
  • Error::PageReferenceOutOfRange if the PDB file seems corrupt
source

pub fn type_information( &mut self, ) -> Result<ItemInformation<'s, TypeIndex>, Error>

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 stream
  • Error::IoError if returned by the Source
  • Error::PageReferenceOutOfRange if the PDB file seems corrupt
  • Error::InvalidTypeInformationHeader if the type information stream header was not understood
source

pub fn id_information(&mut self) -> Result<ItemInformation<'s, IdIndex>, Error>

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 stream
  • Error::IoError if returned by the Source
  • Error::PageReferenceOutOfRange if the PDB file seems corrupt
  • Error::InvalidTypeInformationHeader if the id information stream header was not understood
source

pub fn debug_information(&mut self) -> Result<DebugInformation<'s>, Error>

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 stream
  • Error::IoError if returned by the Source
  • Error::PageReferenceOutOfRange if the PDB file seems corrupt
  • Error::UnimplementedFeature if the debug information header predates ~1995
source

pub fn global_symbols(&mut self) -> Result<SymbolTable<'s>, Error>

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 stream
  • Error::IoError if returned by the Source
  • 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 stream
  • Error::UnimplementedFeature if the debug information header predates ~1995
source

pub fn module_info<'m>( &mut self, module: &Module<'m>, ) -> Result<Option<ModuleInfo<'s>>, Error>

Retrieve the module info stream for a specific Module.

Some information for each module is stored in a separate stream per-module. Modules 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 stream
  • Error::IoError if returned by the Source
  • Error::PageReferenceOutOfRange if the PDB file seems corrupt
  • Error::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"),
    }
}
source

pub fn sections(&mut self) -> Result<Option<Vec<ImageSectionHeader>>, Error>

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 headers
  • Error::IoError if returned by the Source
  • Error::PageReferenceOutOfRange if the PDB file seems corrupt
  • Error::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 stream
  • Error::UnimplementedFeature if the debug information header predates ~1995
source

pub fn frame_table(&mut self) -> Result<FrameTable<'s>, Error>

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 streams
  • Error::IoError if returned by the Source
  • 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);
}
source

pub fn address_map(&mut self) -> Result<AddressMap<'s>, Error>

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 missing
  • Error::StreamNotFound if the PDB somehow does not contain section headers
  • Error::IoError if returned by the Source
  • Error::PageReferenceOutOfRange if the PDB file seems corrupt
  • Error::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 stream
  • Error::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");
    }
}
source

pub fn string_table(&mut self) -> Result<StringTable<'s>, Error>

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 headers
  • Error::IoError if returned by the Source
  • Error::PageReferenceOutOfRange if the PDB file seems corrupt
  • Error::UnexpectedEof if the string table ends prematurely
source

pub fn raw_stream( &mut self, index: StreamIndex, ) -> Result<Option<Stream<'s>>, Error>

Retrieve a stream by its index to read its contents as bytes.

§Errors
  • Error::StreamNotFound if the PDB does not contain this stream
  • Error::IoError if returned by the Source
  • 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");
source

pub fn named_stream(&mut self, name: &[u8]) -> Result<Stream<'s>, Error>

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 name
  • Error::StreamNotFound if the PDB does not contain the stream referred to
  • Error::IoError if returned by the Source
  • Error::PageReferenceOutOfRange if the PDB file seems corrupt

Trait Implementations§

source§

impl<'s, S> Debug for PDB<'s, S>
where S: Debug,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'s, S> Freeze for PDB<'s, S>

§

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§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> Conv for T

source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
source§

impl<I, T> ExtractContext<I, ()> for T

source§

fn extract_context(self, _original_input: I)

Given the context attached to a nom error, and given the original input to the nom parser, extract more the useful context information. Read more
source§

impl<T> FmtForward for T

source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> IntoEither for T

source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

impl<T> Pipe for T
where T: ?Sized,

source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R, ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
source§

impl<I> RecreateContext<I> for I

source§

fn recreate_context(_original_input: I, tail: I) -> I

Given the original input, as well as the context reported by nom, recreate a context in the original string where the error occurred. Read more
source§

impl<T> Tap for T

source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
source§

impl<T> TryConv for T

source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

impl<T> Send for T
where T: ?Sized,

source§

impl<T> Sync for T
where T: ?Sized,