Skip to content

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)
        bool     ok    = false;
        if (built) {
            const DwarfFde *fde = DwarfCfiFindFde(&cfi, file_relative);
            ok                  = fde != NULL && fde->pc_range > 0 && file_relative >= fde->pc_begin &&
                 file_relative < fde->pc_begin + fde->pc_range;
    
            const DwarfCfi *cfi         = NULL;
            const DwarfFde *fde         = NULL;
            u64             module_base = 0;
            if (!SymbolResolverFindFde(resolver, (void *)(uintptr_t)rip, &cfi, &fde, &module_base))
        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;
        const u8       *section_data,
        u64             section_addr,
        DwarfFde       *out
    ) {
        MemSet(out, 0, sizeof(*out));
                u64       id_field_off = (u64)(section_cur.p - 4 - section_data);
                u64       cie_offset   = id_field_off - id;
                DwarfFde  fde;
                DwUCursor body = {.p = section_cur.p, .end = body_end};
                if (parse_fde(&body, rec_start, cie_offset, out, section_data, eh->addr, &fde)) {
    }
    
    const DwarfFde *DwarfCfiFindFde(const DwarfCfi *self, u64 vaddr) {
        if (!self)
            return NULL;
        // still sub-microsecond.
        for (u64 i = 0; i < self->fdes.length; ++i) {
            const DwarfFde *f = &self->fdes.data[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;
        void            *runtime_addr,
        const DwarfCfi **out_cfi,
        const DwarfFde **out_fde,
        u64             *out_module_base
    );
        const u8 *instructions;
        u64       instructions_size;
    } DwarfFde;
    
    typedef Vec(DwarfCie) DwarfCies;
    
    typedef Vec(DwarfCie) DwarfCies;
    typedef Vec(DwarfFde) DwarfFdes;
    
    ///
    /// `vaddr` (file-relative). Returns NULL if no FDE covers the address.
    ///
    const DwarfFde *DwarfCfiFindFde(const DwarfCfi *self, u64 vaddr);
    
    ///
    /// TAGS: Parser, DWARF, CFI, Unwind
    ///
    bool DwarfCfiBuildRow(const DwarfCfi *cfi, const DwarfFde *fde, u64 target_pc, DwarfUnwindRow *out);
    
    // ===========================================================================
Last updated on