Struct pdb::ItemInformation
source · [−]pub struct ItemInformation<'s, I> { /* private fields */ }
Expand description
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);
}
}
}
Implementations
sourceimpl<'s, I> ItemInformation<'s, I> where
I: ItemIndex,
impl<'s, I> ItemInformation<'s, I> where
I: ItemIndex,
sourcepub fn iter(&self) -> ItemIter<'_, I>
pub fn iter(&self) -> ItemIter<'_, I>
Returns an iterator that can traverse the type table in sequential order.
sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
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()
.
sourcepub fn finder(&self) -> ItemFinder<'_, I>
pub fn finder(&self) -> ItemFinder<'_, I>
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
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
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