aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAshok Thirumurthi <ashok.thirumurthi@intel.com>2013-07-29 16:05:11 +0000
committerAshok Thirumurthi <ashok.thirumurthi@intel.com>2013-07-29 16:05:11 +0000
commite6017d3908c724f6a11b0b77f19f42d793b9e56f (patch)
treef91d904c23afbe020295c6c2f00ebac13017183d
parent10384183ef67c625485cfd87b092eb1b3f11a02f (diff)
downloadlldb-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.cpp32
-rw-r--r--source/Symbol/DWARFCallFrameInfo.cpp3
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;
}