PDB


Introduction

Compared to DWARF debug info, the PDB debug info are always externalized from the original binary. Nevertheless, the original binary keeps the path of the PDB file in the attribute .
import lief

pe = lief.PE.parse("some.exe")
if debug_info := pe.debug_info:
    assert isinstance(debug_info, lief.pdb.DebugInfo)
    print(f"PDB Debug handler: {debug_info}")

# Or you can load the PDB directly:
pdb: lief.pdb.DebugInfo = lief.pdb.load("some.pdb")
At this point, the PDB instance () can be used to explore the PDB debug info:
print("arg={}, guid={}", pdb.age, pdb.guid)

for sym in pdb.public_symbols:
    print("name={}, section={}, RVA={}",
          sym.name, sym.section_name, sym.RVA)

for ty in pdb.types:
    if isinstance(ty, lief.pdb.types.Class):
        print("Class[name]={}", ty.name)

for cu in pdb.compilation_units:
    print("module={}", cu.module_name)
    for src in cu.sources:
        print("  - {}", src)

    for func in cu.functions:
        print("name={}, section={}, RVA={}, code_size={}",
              func.name, func.section_name, func.RVA, func.code_size)

API

You can find the documentation of the API for the different languages here:

Python API

C++ API

Rust API: lief::pdb