diff options
author | Ashok Thirumurthi <ashok.thirumurthi@intel.com> | 2013-07-29 16:05:11 +0000 |
---|---|---|
committer | Ashok Thirumurthi <ashok.thirumurthi@intel.com> | 2013-07-29 16:05:11 +0000 |
commit | e6017d3908c724f6a11b0b77f19f42d793b9e56f (patch) | |
tree | f91d904c23afbe020295c6c2f00ebac13017183d | |
parent | 10384183ef67c625485cfd87b092eb1b3f11a02f (diff) | |
download | lldb-e6017d3908c724f6a11b0b77f19f42d793b9e56f.tar.gz |
Adds a DW_OP_call_frame_cfa handler when evaluating DWARF 3/4 expressions
in LLDB that load the canonical frame address rather than a location list.
- Handles the simple case where a CFA can be pulled from the current stack frame.
- Fixes more than one hundred failing tests with gcc 4.8!
TODO: Use UnwindPlan::GetRowForFunctionOffset if the DWARFExpression needs
to be evaluated in a context analogous to a virtual unwind (perhaps using RegisterContextLLDB).
- Also adds some comments to DWARFCallFrameInfo whenever I got confused.
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@187361 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | source/Expression/DWARFExpression.cpp | 32 | ||||
-rw-r--r-- | source/Symbol/DWARFCallFrameInfo.cpp | 3 |
2 files changed, 34 insertions, 1 deletions
diff --git a/source/Expression/DWARFExpression.cpp b/source/Expression/DWARFExpression.cpp index 7797205ff..fc955c5cc 100644 --- a/source/Expression/DWARFExpression.cpp +++ b/source/Expression/DWARFExpression.cpp @@ -37,6 +37,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StackFrame.h" +#include "lldb/Target/StackID.h" using namespace lldb; using namespace lldb_private; @@ -2627,6 +2628,37 @@ DWARFExpression::Evaluate case DW_OP_stack_value: stack.back().SetValueType(Value::eValueTypeScalar); break; + + //---------------------------------------------------------------------- + // OPCODE: DW_OP_call_frame_cfa + // OPERANDS: None + // DESCRIPTION: Specifies a DWARF expression that pushes the value of + // the canonical frame address consistent with the call frame information + // located in .debug_frame (or in the FDEs of the eh_frame section). + //---------------------------------------------------------------------- + case DW_OP_call_frame_cfa: + if (frame) + { + // Note that we don't have to parse FDEs because this DWARF expression + // is commonly evaluated with a valid stack frame. + StackID id = frame->GetStackID(); + addr_t cfa = id.GetCallFrameAddress(); + if (cfa != LLDB_INVALID_ADDRESS) + { + stack.push_back(Scalar(cfa)); + stack.back().SetValueType (Value::eValueTypeHostAddress); + } + else + if (error_ptr) + error_ptr->SetErrorString ("Stack frame does not include a canonical frame address for DW_OP_call_frame_cfa opcode."); + } + else + { + if (error_ptr) + error_ptr->SetErrorString ("Invalid stack frame in context for DW_OP_call_frame_cfa opcode."); + return false; + } + break; } } diff --git a/source/Symbol/DWARFCallFrameInfo.cpp b/source/Symbol/DWARFCallFrameInfo.cpp index 003b945a5..e8f99a980 100644 --- a/source/Symbol/DWARFCallFrameInfo.cpp +++ b/source/Symbol/DWARFCallFrameInfo.cpp @@ -155,7 +155,7 @@ DWARFCallFrameInfo::ParseCIE (const dw_offset_t cie_offset) // cie.offset = cie_offset; // cie.length = length; // cie.cieID = cieID; - cie_sp->ptr_encoding = DW_EH_PE_absptr; + cie_sp->ptr_encoding = DW_EH_PE_absptr; // default cie_sp->version = m_cfi_data.GetU8(&offset); for (i=0; i<CFI_AUG_MAX_SIZE; ++i) @@ -233,6 +233,7 @@ DWARFCallFrameInfo::ParseCIE (const dw_offset_t cie_offset) // Data shall include a 1 byte argument that // represents the pointer encoding for the address // pointers used in the FDE. + // Example: 0x1B == DW_EH_PE_pcrel | DW_EH_PE_sdata4 cie_sp->ptr_encoding = m_cfi_data.GetU8(&offset); break; } |