Pdb
Description
Parsed PDB file. Holds the raw bytes (always parser-owned) plus decoded indices into them. All three PdbOpen* constructors leave the parser as sole owner of data – see the L / R semantics on the FromMemory / FromMemoryCopy constructors (mirrors VecInsertL / VecInsertR).
Fields
| Name | Description |
|---|---|
allocator |
Allocator backing data + the functions vec. |
data |
Raw PDB bytes (owned). |
data_size |
Length of data in bytes. |
block_size |
MSF page size (read from the superblock; usually 4096 but can be 512/1024/2048). |
num_streams |
Stream count from the directory. |
info |
Decoded PDB Info stream (#1). |
functions |
Sorted-by-rva list of public function names from the Publics stream. Populated by PdbOpen[FromMemory]. |
Usage example (Cross-references)
Usage examples (Cross-references)
- In
Pdb.c:12:
#include <Misra.h>
#include <Misra/Parsers/Pdb.h>
#include <Misra/Std/Zstr.h>
#include <Misra/Std/Allocator/Default.h>- In
Pdb.c:98:
build_msf_blob();
Pdb pdb;
bool ok = PdbOpenFromMemoryCopy(&pdb, blob, sizeof(blob), base);
if (!ok) {- In
Pdb.c:124:
MemSet(garbage, 0xCC, sizeof(garbage));
Pdb pdb;
bool ok = !PdbOpenFromMemoryCopy(&pdb, garbage, sizeof(garbage), base);- In
Pdb.c:286:
build_full_pdb_blob();
Pdb pdb;
bool ok = PdbOpenFromMemoryCopy(&pdb, fblob, sizeof(fblob), base);
if (!ok) {- In
Pdb.c:311:
int main(void) {
WriteFmt("[INFO] Starting Pdb tests\n\n");
TestFunction tests[] = {- In
Pdb.c:319:
};
return run_test_suite(tests, sizeof(tests) / sizeof(tests[0]), NULL, 0, "Pdb");
}- In
Pdb.c:9:
#include <Misra/Std/Container/Buf.h>
#include <Misra/Parsers/Pdb.h>
#include <Misra/Std.h>
#include <Misra/Std/File.h>- In
Pdb.c:91:
// Return a pointer to the first byte of block `block_id` inside the
// PDB file. NULL on out-of-range.
static const u8 *block_ptr(const Pdb *self, u32 block_id) {
u64 off = (u64)block_id * self->block_size;
if (off + self->block_size > BufLength(&self->data))- In
Pdb.c:100:
// Read `n` bytes from stream `idx` starting at byte offset `offset`
// into `dest`. Walks the stream's block chain.
static bool stream_read(const Pdb *self, u32 idx, u64 offset, u8 *dest, u64 n) {
if (idx >= self->num_streams)
return false;- In
Pdb.c:140:
// ---------------------------------------------------------------------------
static bool parse_superblock(Pdb *self, u32 *out_num_dir_bytes, u32 *out_block_map_addr) {
if (BufLength(&self->data) < SUPERBLOCK_SIZE) {
LOG_ERROR("PDB: file too small for MSF superblock");- In
Pdb.c:180:
// Reconstruct the stream directory into a contiguous buffer.
static bool reconstruct_directory(Pdb *self, u32 num_dir_bytes, u32 block_map_addr) {
// The block_map_addr page holds an array of u32 block indices,
// one per `block_size` chunk of the directory. The number of
- In
Pdb.c:225:
// Parse the reconstructed directory bytes into per-stream metadata.
static bool parse_directory(Pdb *self) {
if (self->stream_dir_size < 4) {
LOG_ERROR("PDB: directory truncated (no stream count)");- In
Pdb.c:311:
// ---------------------------------------------------------------------------
static bool parse_pdb_info(Pdb *self) {
if (self->num_streams <= 1)
return true; // no info stream
- In
Pdb.c:350:
} DbiSubstreamInfo;
static DbiSubstreamInfo parse_dbi_header(const Pdb *self) {
DbiSubstreamInfo r = {0};
if (DBI_STREAM_INDEX >= self->num_streams)- In
Pdb.c:437:
// return a small allocator-backed array of (RVA, VSize) pairs. Caller
// frees via AllocatorFree.
static SectionRva *load_section_table(const Pdb *self, u16 section_hdr_stream, u32 *out_count) {
*out_count = 0;
if (section_hdr_stream >= self->num_streams)- In
Pdb.c:511:
static bool walk_publics(
const Pdb *self,
u16 symrec_stream,
const SectionRva *sections,- In
Pdb.c:601:
// Top-level: pull DBI -> SectionHdr table + SymRecord stream -> publics.
static bool parse_pdb_functions(Pdb *self) {
DbiSubstreamInfo dbi = parse_dbi_header(self);
if (!dbi.ok)- In
Pdb.c:688:
// L-value form. `data` is `u8 **` -- ownership of the pointer moves
// from caller to parser. On exit `*data == NULL` (success or failure).
bool pdb_open_from_memory(Pdb *out, Buf *in) {
if (!out || !in || !in->data || !in->allocator) {
LOG_FATAL("PdbOpenFromMemory: NULL argument (contract violation)");- In
Pdb.c:720:
// R-value form: allocate Buf, copy, hand `©` to the L-form.
bool pdb_open_from_memory_copy(Pdb *out, const u8 *data, size data_size, Allocator *alloc) {
if (!out || !data || !alloc) {
LOG_FATAL("PdbOpenFromMemoryCopy: NULL argument (contract violation)");- In
Pdb.c:734:
}
bool pdb_open(Pdb *out, const char *path, Allocator *alloc) {
if (!out || !path || !alloc) {
LOG_FATAL("PdbOpen: NULL argument (contract violation)");- In
Pdb.c:747:
}
void PdbDeinit(Pdb *self) {
if (!self)
return;- In
Pdb.c:768:
}
const PdbFunction *PdbResolveRva(const Pdb *self, u32 rva) {
if (!self || self->functions.length == 0)
return NULL;- In
PdbCache.h:26:
#define MISRA_SYS_PDB_CACHE_H
#include <Misra/Parsers/Pdb.h>
#include <Misra/Parsers/Pe.h>
#include <Misra/Std/Allocator.h>- In
PdbCache.h:36:
u64 module_base; // last-seen runtime load base
Pe pe;
Pdb pdb;
bool pe_open;
bool pdb_open;- In
Pdb.h:108:
size name_pool_size;
size name_pool_used;
} Pdb;
///
- In
Pdb.h:118:
/// TAGS: Parser, PDB, File
///
bool pdb_open(Pdb *out, const char *path, Allocator *alloc);
#define PdbOpen(...) MISRA_OVERLOAD(PdbOpen, __VA_ARGS__)
#define PdbOpen_2(out, path) \- In
Pdb.h:153:
/// TAGS: Parser, PDB, Memory, Ownership
///
bool pdb_open_from_memory(Pdb *out, Buf *in);
#define PdbOpenFromMemory(out, in) pdb_open_from_memory((out), (in))- In
Pdb.h:168:
/// TAGS: Parser, PDB, Memory, Copy
///
bool pdb_open_from_memory_copy(Pdb *out, const u8 *data, size data_size, Allocator *alloc);
#define PdbOpenFromMemoryCopy(...) MISRA_OVERLOAD(PdbOpenFromMemoryCopy, __VA_ARGS__)
#define PdbOpenFromMemoryCopy_3(out, data, data_size) pdb_open_from_memory_copy((out), (data), (data_size), MisraScope)- In
Pdb.h:177:
/// Release storage owned by a `Pdb`. Safe on a zeroed struct.
///
void PdbDeinit(Pdb *self);
///
- In
Pdb.h:188:
/// FAILURE : Returns NULL.
///
const PdbFunction *PdbResolveRva(const Pdb *self, u32 rva);
#endif // MISRA_PARSERS_PDB_H
Last updated on