DwarfFde
Description
Decoded FDE record. pc_begin and pc_range are file-relative virtual addresses (the same address-space ElfSymbol.value uses). instructions is the per-FDE CFI bytecode that runs after the CIE’s initial instructions.
Usage example (Cross-references)
Usage examples (Cross-references)
void *runtime_addr,
const DwarfCfi **out_cfi,
const DwarfFde **out_fde,
u64 *out_module_base
);- In
Dwarf.h:167:
const u8 *instructions;
u64 instructions_size;
} DwarfFde;
typedef Vec(DwarfCie) DwarfCies;- In
Dwarf.h:170:
typedef Vec(DwarfCie) DwarfCies;
typedef Vec(DwarfFde) DwarfFdes;
///
- In
Dwarf.h:213:
/// TAGS: Parser, DWARF, CFI, Lookup
///
const DwarfFde *DwarfCfiFindFde(const DwarfCfi *self, u64 vaddr);
///
- In
Dwarf.h:306:
/// TAGS: Parser, DWARF, CFI, Unwind
///
bool DwarfCfiBuildRow(const DwarfCfi *cfi, const DwarfFde *fde, u64 target_pc, DwarfUnwindRow *out);
// ===========================================================================
void *runtime_addr,
const DwarfCfi **out_cfi,
const DwarfFde **out_fde,
u64 *out_module_base
) {
u64 file_relative = addr - load_base;
const DwarfFde *fde = DwarfCfiFindFde(&cache_entry->cfi, file_relative);
if (!fde)
return false;- In
Backtrace.c:621:
const DwarfCfi *cfi = NULL;
const DwarfFde *fde = NULL;
u64 module_base = 0;
if (!SymbolResolverFindFde(resolver, (void *)(u64)rip, &cfi, &fde, &module_base)) const u8 *section_data,
u64 section_addr,
DwarfFde *out
) {
MemSet(out, 0, sizeof(*out)); cie_offset = id_field_off - (u64)id;
}
DwarfFde fde;
BufIter body = BufIterFromMemory(IterDataAt(§ion_cur, IterIndex(§ion_cur)), length32 - 4);
if (parse_fde(&body, rec_start, cie_offset, out, section_data, section_addr, &fde)) { }
const DwarfFde *DwarfCfiFindFde(const DwarfCfi *self, u64 vaddr) {
if (!self)
return NULL; // Linear scan -- fine up to a few thousand FDEs.
for (u64 i = 0; i < VecLen(&self->fdes); ++i) {
const DwarfFde *f = VecPtrAt(&self->fdes, i);
if (vaddr >= f->pc_begin && vaddr < f->pc_begin + f->pc_range) {
return f; }
bool DwarfCfiBuildRow(const DwarfCfi *cfi, const DwarfFde *fde, u64 target_pc, DwarfUnwindRow *out) {
if (!cfi || !fde || !out)
return false; bool ok = DwarfCfiBuildFromElf(&cfi, &elf, base);
if (ok) {
const DwarfFde *fde = DwarfCfiFindFde(&cfi, target_pc);
ok = fde != NULL && DwarfCfiBuildRow(&cfi, fde, target_pc, out_row);
DwarfCfiDeinit(&cfi); bool ok = DwarfCfiBuildFromElf(&cfi, &elf, base);
if (ok) {
const DwarfFde *fde = DwarfCfiFindFde(&cfi, target_pc);
ok = fde != NULL && DwarfCfiBuildRow(&cfi, fde, target_pc, out_row);
DwarfCfiDeinit(&cfi); bool ok = DwarfCfiBuildFromElf(&cfi, &elf, base);
if (ok) {
const DwarfFde *fde = DwarfCfiFindFde(&cfi, target_pc);
ok = fde != NULL && DwarfCfiBuildRow(&cfi, fde, target_pc, out_row);
DwarfCfiDeinit(&cfi); bool ok = DwarfCfiBuildFromElf(&cfi, &elf, base);
if (ok) {
const DwarfFde *fde = DwarfCfiFindFde(&cfi, target_pc);
ok = fde != NULL && DwarfCfiBuildRow(&cfi, fde, target_pc, out_row);
DwarfCfiDeinit(&cfi); DwarfCfi cfi;
if (DwarfCfiBuildFromElf(&cfi, &elf, base)) {
const DwarfFde *fde = DwarfCfiFindFde(&cfi, 0x5000);
DwarfUnwindRow row;
// eh_frame_addr must record the .debug_frame section's address (the
DwarfCfi cfi;
if (DwarfCfiBuildFromElf(&cfi, &elf, base)) {
const DwarfFde *fde = DwarfCfiFindFde(&cfi, 0x1000);
DwarfUnwindRow row;
ok = fde != NULL && DwarfCfiBuildRow(&cfi, fde, 0x1080, &row) // in range -> ok
DwarfCfi cfi;
if (DwarfCfiBuildFromElf(&cfi, &elf, base)) {
const DwarfFde *fde = DwarfCfiFindFde(&cfi, 0x1000);
ok = fde != NULL && fde->offset == fde_off;
DwarfCfiDeinit(&cfi);- In
Dwarf.c:121:
// parsed now, so a "no FDE" outcome means the unwinder is broken on this
// toolchain (the historic clang .debug_frame gap), not correct behaviour.
const DwarfFde *fde = built ? DwarfCfiFindFde(&cfi, file_relative) : NULL;
bool ok = built && fde != NULL;
if (ok) {
Last updated on