Index: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp =================================================================== --- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -1743,7 +1743,28 @@ } break; } - // TODO: handle isDWARFExpression + case UnwindPlan::Row::CFAValue::isDWARFExpression: + { + ExecutionContext exe_ctx(m_thread.shared_from_this()); + Process *process = exe_ctx.GetProcessPtr(); + DataExtractor dwarfdata (row->GetCFAValue().GetDWARFExpressionBytes(), + row->GetCFAValue().GetDWARFExpressionLength(), + process->GetByteOrder(), process->GetAddressByteSize()); + ModuleSP opcode_ctx; + DWARFExpression dwarfexpr (opcode_ctx, dwarfdata, 0, row->GetCFAValue().GetDWARFExpressionLength()); + dwarfexpr.SetRegisterKind (row_register_kind); + Value result; + Error error; + if (dwarfexpr.Evaluate (&exe_ctx, NULL, NULL, this, 0, NULL, result, &error)) + { + cfa_value = result.GetScalar().ULongLong(); + + UnwindLogMsg ("CFA value set by DWARF expression is 0x%" PRIx64, cfa_value); + return true; + } + UnwindLogMsg ("Failed to set CFA value via DWARF expression: %s", error.AsCString()); + break; + } default: return false; } Index: lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp =================================================================== --- lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp +++ lldb/trunk/source/Symbol/DWARFCallFrameInfo.cpp @@ -748,7 +748,9 @@ case DW_CFA_def_cfa_expression : // 0xF (CFA Definition Instruction) { size_t block_len = (size_t)m_cfi_data.GetULEB128(&offset); - offset += (uint32_t)block_len; + const uint8_t *block_data = + static_cast(m_cfi_data.GetData(&offset, block_len)); + row->GetCFAValue().SetIsDWARFExpression(block_data, block_len); } break; Index: lldb/trunk/source/Symbol/UnwindPlan.cpp =================================================================== --- lldb/trunk/source/Symbol/UnwindPlan.cpp +++ lldb/trunk/source/Symbol/UnwindPlan.cpp @@ -434,10 +434,8 @@ // If the 0th Row of unwind instructions is missing, or if it doesn't provide // a register to use to find the Canonical Frame Address, this is not a valid UnwindPlan. - // CFA set by a DWARF expression is not currently supported, so ignore that as well. if (GetRowAtIndex(0).get() == nullptr || - GetRowAtIndex(0)->GetCFAValue().GetValueType() == Row::CFAValue::unspecified || - GetRowAtIndex(0)->GetCFAValue().GetValueType() == Row::CFAValue::isDWARFExpression) + GetRowAtIndex(0)->GetCFAValue().GetValueType() == Row::CFAValue::unspecified) { Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); if (log)