DwarfCfi
Description
Parsed .eh_frame index. CIEs are de-duplicated; FDEs each point at their CIE by offset. eh_frame_base is the runtime address that pc-relative encodings in .eh_frame are relative to (= the section’s load address); we record the file-relative form, so DwarfCfi-consuming callers should pass already-file-relative PCs.
Usage example (Cross-references)
Usage examples (Cross-references)
bool sidecar_dwarf_ok;
// Lazily-parsed .eh_frame for the CFI-based unwinder.
DwarfCfi cfi;
bool cfi_built;
bool cfi_ok; SymbolResolver *self,
void *runtime_addr,
const DwarfCfi **out_cfi,
const DwarfFde **out_fde,
u64 *out_module_base- In
Dwarf.h:184:
DwarfFdes fdes;
u64 eh_frame_addr;
} DwarfCfi;
///
- In
Dwarf.h:213:
/// TAGS: Parser, DWARF, CFI, Lookup
///
const DwarfFde *DwarfCfiFindFde(const DwarfCfi *self, u64 vaddr);
///
- In
Dwarf.h:224:
/// TAGS: Parser, DWARF, CFI, Lookup
///
const DwarfCie *DwarfCfiFindCie(const DwarfCfi *self, u64 cie_offset);
///
- In
Dwarf.h:235:
/// TAGS: Parser, DWARF, CFI, Deinit, Lifecycle
///
void DwarfCfiDeinit(DwarfCfi *self);
// ---------------------------------------------------------------------------
- In
Dwarf.h:306:
/// TAGS: Parser, DWARF, CFI, Unwind
///
bool DwarfCfiBuildRow(const DwarfCfi *cfi, const DwarfFde *fde, u64 target_pc, DwarfUnwindRow *out);
// ===========================================================================
SymbolResolver *self,
void *runtime_addr,
const DwarfCfi **out_cfi,
const DwarfFde **out_fde,
u64 *out_module_base- In
Backtrace.c:620:
++emitted;
const DwarfCfi *cfi = NULL;
const DwarfFde *fde = NULL;
u64 module_base = 0; const u8 *body_start,
u64 cie_offset,
const DwarfCfi *cfi,
const u8 *section_data,
u64 section_addr, // augmentation). Returns false only on allocation failure.
static bool
cfi_parse_section(DwarfCfi *out, const u8 *section_data, u64 section_addr, u64 section_size, bool is_debug_frame) {
const u32 cie_id = is_debug_frame ? 0xffffffffu : 0u;
BufIter section_cur = BufIterFromMemory(section_data, section_size); }
bool dwarf_cfi_build_from_elf(DwarfCfi *out, const Elf *elf, Allocator *alloc) {
if (!out || !elf || !alloc) {
LOG_FATAL("DwarfCfiBuildFromElf: NULL argument"); }
const DwarfCie *DwarfCfiFindCie(const DwarfCfi *self, u64 cie_offset) {
if (!self)
return NULL; }
const DwarfFde *DwarfCfiFindFde(const DwarfCfi *self, u64 vaddr) {
if (!self)
return NULL; }
void DwarfCfiDeinit(DwarfCfi *self) {
if (!self)
return; }
bool DwarfCfiBuildRow(const DwarfCfi *cfi, const DwarfFde *fde, u64 target_pc, DwarfUnwindRow *out) {
if (!cfi || !fde || !out)
return false; }
DwarfCfi cfi;
bool ok = DwarfCfiBuildFromElf(&cfi, &elf, base);
if (ok) { return false;
}
DwarfCfi cfi;
bool ok = DwarfCfiBuildFromElf(&cfi, &elf, base);
if (ok) { return false;
}
DwarfCfi cfi;
bool ok = DwarfCfiBuildFromElf(&cfi, &elf, base);
if (ok) { return false;
}
DwarfCfi cfi;
bool ok = DwarfCfiBuildFromElf(&cfi, &elf, base);
if (ok) { Elf elf;
if (ElfOpenFromMemoryCopy(&elf, elfbuf, (size)elf_len, base)) {
DwarfCfi cfi;
if (DwarfCfiBuildFromElf(&cfi, &elf, base)) {
const DwarfFde *fde = DwarfCfiFindFde(&cfi, 0x5000); Elf elf;
if (ElfOpenFromMemoryCopy(&elf, elfbuf, (size)elf_len, base)) {
DwarfCfi cfi;
if (DwarfCfiBuildFromElf(&cfi, &elf, base)) {
ok = DwarfCfiFindFde(&cfi, 0x10ff) != NULL // last in-range address
Elf elf;
if (ElfOpenFromMemoryCopy(&elf, elfbuf, (size)elf_len, base)) {
DwarfCfi cfi;
if (DwarfCfiBuildFromElf(&cfi, &elf, base)) {
const DwarfFde *fde = DwarfCfiFindFde(&cfi, 0x1000); Elf elf;
if (ElfOpenFromMemoryCopy(&elf, elfbuf, (size)elf_len, base)) {
DwarfCfi cfi;
if (DwarfCfiBuildFromElf(&cfi, &elf, base)) {
const DwarfCie *cie = DwarfCfiFindCie(&cfi, 0); Elf elf;
if (ElfOpenFromMemoryCopy(&elf, elfbuf, (size)elf_len, base)) {
DwarfCfi cfi;
if (DwarfCfiBuildFromElf(&cfi, &elf, base)) {
const DwarfFde *fde = DwarfCfiFindFde(&cfi, 0x1000);- In
Dwarf.c:114:
}
DwarfCfi cfi;
bool built = DwarfCfiBuildFromElf(&cfi, &elf, base);
// Contract (strict): the parse must succeed AND an FDE must cover this
Last updated on