///|
/// A PDB address combined with PE mapping, public symbol, and source location.
pub struct SymbolizedAddress {
segment : UInt16
section_offset : UInt32
section_name : String
rva : UInt32
image_address : UInt64
public_symbol : ResolvedPublicSymbol?
source : SourceLocation?
}
///|
pub fn SymbolizedAddress::segment(self : SymbolizedAddress) -> UInt16 {
self.segment
}
///|
pub fn SymbolizedAddress::section_offset(self : SymbolizedAddress) -> UInt32 {
self.section_offset
}
///|
pub fn SymbolizedAddress::section_name(self : SymbolizedAddress) -> String {
self.section_name
}
///|
pub fn SymbolizedAddress::rva(self : SymbolizedAddress) -> UInt32 {
self.rva
}
///|
pub fn SymbolizedAddress::image_address(self : SymbolizedAddress) -> UInt64 {
self.image_address
}
///|
pub fn SymbolizedAddress::public_symbol(
self : SymbolizedAddress,
) -> ResolvedPublicSymbol? {
self.public_symbol
}
///|
pub fn SymbolizedAddress::source(self : SymbolizedAddress) -> SourceLocation? {
self.source
}
///|
/// Combine PE mapping, nearest public symbol, and C13 source line information.
pub fn symbolicate_address(
pe : PeImage,
publics : PublicsStream,
c13_modules : Array[C13DebugInfo],
segment : UInt16,
offset : UInt32,
) -> SymbolizedAddress? {
let mapped = match pe.map_segment_offset(segment, offset) {
Some(value) => value
None => return None
}
let public_symbol = publics.find_public_nearest(segment, offset)
let mut source : SourceLocation? = None
for item in c13_modules {
match item.find_line(segment, offset) {
Some(value) => {
source = Some(value)
break
}
None => ()
}
}
Some(SymbolizedAddress::{
segment,
section_offset: offset,
section_name: mapped.section_name,
rva: mapped.rva,
image_address: mapped.image_address,
public_symbol,
source,
})
}
///|
/// Symbolicate a batch of PDB segment-relative addresses.
pub fn symbolicate_addresses(
pe : PeImage,
publics : PublicsStream,
c13_modules : Array[C13DebugInfo],
addresses : Array[(UInt16, UInt32)],
) -> Array[SymbolizedAddress] {
let results = []
for address in addresses {
match symbolicate_address(pe, publics, c13_modules, address.0, address.1) {
Some(value) => results.push(value)
None => ()
}
}
results
}