///|
pub fn PEImage::debug_entries(self : Self) -> Array[DebugEntry] raise PeError {
let directory = match self.directory(6) {
Some(directory) if directory.virtual_address != 0UL && directory.size > 0 =>
directory
_ => return []
}
let start = self.rva_to_offset(directory.virtual_address)
let count = if directory.size / 28 < 4096 {
directory.size / 28
} else {
4096
}
let entries = []
for index in 0..= 4 {
self.read_codeview(address_of_raw_data, size_of_data)
} else {
(None, None, None)
}
entries.push({
debug_type,
type_name: debug_type_name(debug_type),
timestamp: checked_int(
read_u32(self.data, offset + 4),
offset + 4,
"debug timestamp",
),
size_of_data,
address_of_raw_data,
pointer_to_raw_data,
pdb_path,
pdb_age,
pdb_guid,
})
}
entries
}
///|
fn PEImage::read_codeview(
self : Self,
data_rva : UInt64,
size : Int32,
) -> (String?, Int32?, String?) {
let result = try {
let offset = self.rva_to_offset(data_rva)
ensure_range(self.data, offset, 4)
if read_u8(self.data, offset) != 0x52 ||
read_u8(self.data, offset + 1) != 0x53 ||
read_u8(self.data, offset + 2) != 0x44 ||
read_u8(self.data, offset + 3) != 0x53 {
(None, None, None)
} else if size >= 24 && offset + 24 <= self.data.length() {
let age = checked_int(
read_u32(self.data, offset + 20),
offset + 20,
"PDB age",
)
let guid = bytes_hex(self.data, offset + 4, 16)
let path = read_ascii_z(self.data, offset + 24, size - 24)
(Some(path), Some(age), Some(guid))
} else {
(None, None, None)
}
} catch {
PeError(_, _) => (None, None, None)
}
result
}
///|
fn bytes_hex(data : Bytes, offset : Int32, length : Int32) -> String {
let builder = StringBuilder()
for index in 0..> 4))
builder.write_char(hex_digit(value & 0xf))
}
builder.to_string()
}
///|
fn hex_digit(value : Int32) -> Char {
if value < 10 {
('0'.to_int() + value).unsafe_to_char()
} else {
('a'.to_int() + value - 10).unsafe_to_char()
}
}
///|
fn debug_type_name(debug_type : Int32) -> String {
match debug_type {
1 => "coff"
2 => "codeview"
3 => "fpo"
4 => "misc"
5 => "exception"
6 => "fixup"
9 => "borland"
10 => "reserved"
11 => "clsid"
12 => "vc-feature"
13 => "pogo"
14 => "iltcg"
16 => "repro"
17 => "exdll-characteristics"
20 => "pdb-checksum"
_ => "unknown"
}
}