[−][src]Struct pdb::ItemInformation
Zero-copy access to a PDB type or id stream.
PDBs store two kinds of related streams with an identical internal structure:
TypeInformation
(TPI stream) contains information on primitive types, classes and procedures, including their return type and arguments. Its contents are identified byTypeIndex
.IdInformation
(IPI stream) is a stricter version of the above stream that contains inline functions, build infos and source references. Its contents are identified byIdIndex
.
Items in these streams are stored by their index in ascending order. Symbols declared in
[ModuleInfo
] can refer to items in both streams, as well as items to other items with one
exception: Type
s cannot refer to Id
s. Also, the PDB format requires that items refer only to
types with lower indexes. Thus, the stream of items forms a directed acyclic graph.
Both streams can iterate by their index using ItemInformation::iter
. Additionally,
ItemFinder
is a secondary data structure to provide efficient backtracking for random
access.
There are type definitions for both streams:
ItemInformation
:TypeInformation
andIdInformation
ItemFinder
:TypeFinder
andIdFinder
ItemIndex
:TypeIndex
andIdIndex
ItemIter
:TypeIter
andIdIter
Item
:Type
andId
Examples
Iterating over the types while building a TypeFinder
:
let type_information = pdb.type_information()?; let mut type_finder = type_information.finder(); let mut iter = type_information.iter(); while let Some(typ) = iter.next()? { // build the type finder as we go type_finder.update(&iter); // parse the type record match typ.parse() { Ok(pdb::TypeData::Class(pdb::ClassType {name, properties, fields: Some(fields), ..})) => { // this Type describes a class-like type with fields println!("type {} is a class named {}", typ.index(), name); // `fields` is a TypeIndex which refers to a FieldList // To find information about the fields, find and parse that Type match type_finder.find(fields)?.parse()? { pdb::TypeData::FieldList(list) => { // `fields` is a Vec<TypeData> for field in list.fields { if let pdb::TypeData::Member(member) = field { // follow `member.field_type` as desired println!(" - field {} at offset {:x}", member.name, member.offset); } else { // handle member functions, nested types, etc. } } if let Some(more_fields) = list.continuation { // A FieldList can be split across multiple records // TODO: follow `more_fields` and handle the next FieldList } } _ => { } } }, Ok(_) => { // ignore everything that's not a class-like type }, Err(pdb::Error::UnimplementedTypeKind(_)) => { // found an unhandled type record // this probably isn't fatal in most use cases }, Err(e) => { // other error, probably is worth failing return Err(e); } } }
Methods
impl<'s, I> ItemInformation<'s, I> where
I: ItemIndex,
[src]
I: ItemIndex,
pub fn iter(&self) -> ItemIter<I>
[src]
Returns an iterator that can traverse the type table in sequential order.
pub fn len(&self) -> usize
[src]
Returns the number of items contained in this ItemInformation
.
Note that in the case of the type stream (TypeInformation
) primitive types are not
stored in the PDB file. The number of distinct types reachable via this table will be higher
than len()
.
pub fn is_empty(&self) -> bool
[src]
Returns whether this ItemInformation
contains any data.
pub fn finder(&self) -> ItemFinder<I>
[src]
Returns an ItemFinder
with a default time-space tradeoff useful for access by
ItemIndex
.
The ItemFinder
is initially empty and must be populated by iterating. See the struct-level
docs for an example.
Trait Implementations
impl<'s, I: Debug> Debug for ItemInformation<'s, I>
[src]
Auto Trait Implementations
impl<'s, I> !RefUnwindSafe for ItemInformation<'s, I>
impl<'s, I> !Send for ItemInformation<'s, I>
impl<'s, I> !Sync for ItemInformation<'s, I>
impl<'s, I> Unpin for ItemInformation<'s, I>
impl<'s, I> !UnwindSafe for ItemInformation<'s, I>
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,