void DwarfBuf::dwarf_cfa_sfp(uint8_t reg, int offset, int scale) { DwarfBuf b; byte(DW_CFA_val_expression); byte(reg); b.dwarf_sfp_expr(offset, scale); /* this assumes expression fits in 127 bytes, else we have to LEB128 encode size */ byte(b.size()); dwarf_sfp_expr(offset, scale); }
bool ElfWriter::addFrameInfo(DwarfChunk* d) { Dwarf_Error error = 0; DwarfBuf& b = d->m_buf; b.clear(); /* Define common set of rules for unwinding frames in the VM stack*/ /* Frame pointer (CFA) for previous frame is in RBP + 16 */ b.dwarf_cfa_def_cfa(RBP, CFA_OFFSET); /* Previous RIP is at CFA - 1 . DWARF_DATA_ALIGN (8) */ b.dwarf_cfa_offset_extended_sf(RIP, -1); /* Previous RBP is at CFA - 2 . DWARF_DATA_ALIGN (8) */ b.dwarf_cfa_offset_extended_sf(RBP, -2); /* * RSP is unchanged in VM frames, except for some rare cases with * calls to functions that we assume don't throw. (Technically * debug information will be wrong if we stop under one of those * cases.) * * Note: if rVmSp is ever changed to refer to rsp, this code needs * to change. */ b.dwarf_cfa_same_value(RSP); /* register above rules in a CIE (common information entry) */ Dwarf_Signed cie_index = dwarf_add_frame_cie( m_dwarfProducer, "", DWARF_CODE_ALIGN, DWARF_DATA_ALIGN, RIP, (void *)b.getBuf(), b.size(), &error ); if (cie_index == DW_DLV_NOCOUNT) { logError("Unable to add CIE frame"); return false; } /* for each tracelet, register tracelet address ranges in * an FDE (Frame Description entry) */ FuncPtrDB::iterator it; for (it = d->m_functions.begin(); it != d->m_functions.end(); it++) { Dwarf_P_Fde fde = dwarf_new_fde(m_dwarfProducer, &error); if (reinterpret_cast<Dwarf_Addr>(fde) == DW_DLV_BADADDR) { logError("Unable to create FDE"); return false; } DwarfBuf buf; int err = dwarf_insert_fde_inst_bytes( m_dwarfProducer, fde, buf.size(), buf.getBuf(), &error); if (err == DW_DLV_ERROR) { logError("Unable to add instructions to fde"); return false; } Dwarf_Unsigned fde_index = dwarf_add_frame_fde( m_dwarfProducer, fde, 0, cie_index, (Dwarf_Unsigned)((*it)->range.begin()), (*it)->range.size(), 0, &error); if (fde_index == DW_DLV_BADADDR) { logError("Unable to add FDE"); return false; } } return true; }