Skip to content

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
        DwarfFdes  fdes;
        u64        eh_frame_addr;
    } DwarfCfi;
    
    ///
    /// TAGS: Parser, DWARF, CFI, Lookup
    ///
    const DwarfFde *DwarfCfiFindFde(const DwarfCfi *self, u64 vaddr);
    
    ///
    /// TAGS: Parser, DWARF, CFI, Lookup
    ///
    const DwarfCie *DwarfCfiFindCie(const DwarfCfi *self, u64 cie_offset);
    
    ///
    /// TAGS: Parser, DWARF, CFI, Deinit, Lifecycle
    ///
    void DwarfCfiDeinit(DwarfCfi *self);
    
    // ---------------------------------------------------------------------------
    /// 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
            ++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);
        }
    
        DwarfCfi cfi;
        bool     built = DwarfCfiBuildFromElf(&cfi, &elf, base);
        // Contract (strict): the parse must succeed AND an FDE must cover this
Last updated on