DwarfCfiBuildRow
Description
Run the CIE’s initial instructions plus the FDE’s instructions up to (but not past) target_pc, producing the unwind row that applies at that PC.
Parameters
| Name | Direction | Description |
|---|---|---|
cfi |
in | Parsed .eh_frame index. |
fde |
in | FDE covering target_pc (caller obtained via DwarfCfiFindFde). |
target_pc |
in | File-relative virtual address inside the FDE’s [pc_begin, pc_begin+pc_range) range. |
out |
out | Populated on success. |
Success
Returns true. out->cfa.kind is set to a usable rule (typically REG_OFFSET on x86-64). out->regs[ra] tells the caller where to find the previous frame’s return address.
Failure
Returns false on malformed CFI bytecode, unsupported DW_CFA_*_expression instructions, or target_pc outside the FDE. out is left zeroed.
Usage example (Cross-references)
Usage examples (Cross-references)
- In
Backtrace.c:628:
DwarfUnwindRow row;
if (!DwarfCfiBuildRow(cfi, fde, file_relative, &row))
break; }
bool DwarfCfiBuildRow(const DwarfCfi *cfi, const DwarfFde *fde, u64 target_pc, DwarfUnwindRow *out) {
if (!cfi || !fde || !out)
return false; if (ok) {
const DwarfFde *fde = DwarfCfiFindFde(&cfi, target_pc);
ok = fde != NULL && DwarfCfiBuildRow(&cfi, fde, target_pc, out_row);
DwarfCfiDeinit(&cfi);
} if (ok) {
const DwarfFde *fde = DwarfCfiFindFde(&cfi, target_pc);
ok = fde != NULL && DwarfCfiBuildRow(&cfi, fde, target_pc, out_row);
DwarfCfiDeinit(&cfi);
} if (ok) {
const DwarfFde *fde = DwarfCfiFindFde(&cfi, target_pc);
ok = fde != NULL && DwarfCfiBuildRow(&cfi, fde, target_pc, out_row);
DwarfCfiDeinit(&cfi);
} if (ok) {
const DwarfFde *fde = DwarfCfiFindFde(&cfi, target_pc);
ok = fde != NULL && DwarfCfiBuildRow(&cfi, fde, target_pc, out_row);
DwarfCfiDeinit(&cfi);
} // eh_frame_addr must record the .debug_frame section's address (the
// fallback branch), not a constant.
ok = fde != NULL && DwarfCfiBuildRow(&cfi, fde, 0x5000, &row) && row.cfa.reg == 7 &&
cfi.eh_frame_addr == EH_SECTION_VADDR;
DwarfCfiDeinit(&cfi); const DwarfFde *fde = DwarfCfiFindFde(&cfi, 0x1000);
DwarfUnwindRow row;
ok = fde != NULL && DwarfCfiBuildRow(&cfi, fde, 0x1080, &row) // in range -> ok
&& !DwarfCfiBuildRow(&cfi, fde, 0x1100, &row); // == end -> rejected
DwarfCfiDeinit(&cfi); DwarfUnwindRow row;
ok = fde != NULL && DwarfCfiBuildRow(&cfi, fde, 0x1080, &row) // in range -> ok
&& !DwarfCfiBuildRow(&cfi, fde, 0x1100, &row); // == end -> rejected
DwarfCfiDeinit(&cfi);
}- In
Dwarf.c:135:
// leaves it in x30 with no CFI rule yet (UNDEFINED).
DwarfUnwindRow row;
ok = ok && DwarfCfiBuildRow(&cfi, fde, file_relative, &row);
ok = ok && row.cfa.kind == DWARF_CFA_RULE_REG_OFFSET;
}
Last updated on