[Lldb-commits] [lldb] r119885 - in /lldb/trunk: include/lldb/Expression/DWARFExpression.h include/lldb/Symbol/UnwindPlan.h source/Core/ValueObjectVariable.cpp source/Expression/ClangExpressionDeclMap.cpp source/Expression/DWARFExpression.cpp source/Plugins/Process/Utility/RegisterContextLLDB.cpp source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp source/Target/StackFrame.cpp
Jason Molenda
jmolenda at apple.com
Fri Nov 19 17:28:30 PST 2010
Author: jmolenda
Date: Fri Nov 19 19:28:30 2010
New Revision: 119885
URL: http://llvm.org/viewvc/llvm-project?rev=119885&view=rev
Log:
Change the DWARFExpression::Evaluate methods to take an optional
RegisterContext* - normally this is retrieved from the ExecutionContext's
StackFrame but when we need to evaluate an expression while creating
the stack frame list this can be a little tricky.
Add DW_OP_deref_size, needed for the _sigtramp FDE expression.
Add support for processing DWARF expressions in RegisterContextLLDB.
Update callers to DWARFExpression::Evaluate.
Modified:
lldb/trunk/include/lldb/Expression/DWARFExpression.h
lldb/trunk/include/lldb/Symbol/UnwindPlan.h
lldb/trunk/source/Core/ValueObjectVariable.cpp
lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
lldb/trunk/source/Expression/DWARFExpression.cpp
lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
lldb/trunk/source/Target/StackFrame.cpp
Modified: lldb/trunk/include/lldb/Expression/DWARFExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/DWARFExpression.h?rev=119885&r1=119884&r2=119885&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/DWARFExpression.h (original)
+++ lldb/trunk/include/lldb/Expression/DWARFExpression.h Fri Nov 19 19:28:30 2010
@@ -201,6 +201,7 @@
bool
Evaluate (ExecutionContext *exe_ctx,
clang::ASTContext *ast_context,
+ RegisterContext *reg_ctx,
lldb::addr_t loclist_base_load_addr,
const Value* initial_value_ptr,
Value& result,
@@ -234,6 +235,13 @@
/// expression. Can be NULL if the location expression uses no
/// external variables.
///
+ /// @param[in] reg_ctx
+ /// An optional parameter which provides a RegisterContext for use
+ /// when evaluating the expression (i.e. for fetching register values).
+ /// Normally this will come from the ExecutionContext's StackFrame but
+ /// in the case where an expression needs to be evaluated while building
+ /// the stack frame list, this short-cut is available.
+ ///
/// @param[in] offset
/// The offset of the location expression in the data extractor.
///
@@ -264,6 +272,7 @@
const DataExtractor& opcodes,
ClangExpressionVariableList *expr_locals,
ClangExpressionDeclMap *decl_map,
+ RegisterContext *reg_ctx,
const uint32_t offset,
const uint32_t length,
const uint32_t reg_set,
Modified: lldb/trunk/include/lldb/Symbol/UnwindPlan.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/UnwindPlan.h?rev=119885&r1=119884&r2=119885&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/UnwindPlan.h (original)
+++ lldb/trunk/include/lldb/Symbol/UnwindPlan.h Fri Nov 19 19:28:30 2010
@@ -104,6 +104,12 @@
void
SetIsDWARFExpression (const uint8_t *opcodes, uint32_t len);
+ const uint8_t *
+ GetDWARFExpressionBytes () { return m_location.expr.opcodes; }
+
+ int
+ GetDWARFExpressionLength () { return m_location.expr.length; }
+
void
Dump (Stream &s) const;
Modified: lldb/trunk/source/Core/ValueObjectVariable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectVariable.cpp?rev=119885&r1=119884&r2=119885&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectVariable.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectVariable.cpp Fri Nov 19 19:28:30 2010
@@ -118,7 +118,7 @@
loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.target);
}
Value old_value(m_value);
- if (expr.Evaluate (&exe_ctx, GetClangAST(), loclist_base_load_addr, NULL, m_value, &m_error))
+ if (expr.Evaluate (&exe_ctx, GetClangAST(), NULL, loclist_base_load_addr, NULL, m_value, &m_error))
{
m_value.SetContext(Value::eContextTypeVariable, variable);
Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=119885&r1=119884&r2=119885&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Fri Nov 19 19:28:30 2010
@@ -1205,7 +1205,7 @@
}
Error err;
- if (!var_location_expr.Evaluate(&exe_ctx, exe_ast_ctx, loclist_base_load_addr, NULL, *var_location.get(), &err))
+ if (!var_location_expr.Evaluate(&exe_ctx, exe_ast_ctx, NULL, loclist_base_load_addr, NULL, *var_location.get(), &err))
{
if (log)
log->Printf("Error evaluating location: %s", err.AsCString());
Modified: lldb/trunk/source/Expression/DWARFExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/DWARFExpression.cpp?rev=119885&r1=119884&r2=119885&view=diff
==============================================================================
--- lldb/trunk/source/Expression/DWARFExpression.cpp (original)
+++ lldb/trunk/source/Expression/DWARFExpression.cpp Fri Nov 19 19:28:30 2010
@@ -631,48 +631,38 @@
static bool
ReadRegisterValueAsScalar
(
- ExecutionContext *exe_ctx,
+ RegisterContext *reg_context,
uint32_t reg_kind,
uint32_t reg_num,
Error *error_ptr,
Value &value
)
{
- if (exe_ctx && exe_ctx->frame)
+ if (reg_context == NULL)
{
- RegisterContext *reg_context = exe_ctx->frame->GetRegisterContext();
-
- if (reg_context == NULL)
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat("No register context in frame.\n");
+ }
+ else
+ {
+ uint32_t native_reg = reg_context->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
+ if (native_reg == LLDB_INVALID_REGNUM)
{
if (error_ptr)
- error_ptr->SetErrorStringWithFormat("No register context in frame.\n");
+ error_ptr->SetErrorStringWithFormat("Unable to convert register kind=%u reg_num=%u to a native register number.\n", reg_kind, reg_num);
}
else
{
- uint32_t native_reg = reg_context->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
- if (native_reg == LLDB_INVALID_REGNUM)
- {
- if (error_ptr)
- error_ptr->SetErrorStringWithFormat("Unable to convert register kind=%u reg_num=%u to a native register number.\n", reg_kind, reg_num);
- }
- else
- {
- value.SetValueType (Value::eValueTypeScalar);
- value.SetContext (Value::eContextTypeRegisterInfo, const_cast<RegisterInfo *>(reg_context->GetRegisterInfoAtIndex(native_reg)));
+ value.SetValueType (Value::eValueTypeScalar);
+ value.SetContext (Value::eContextTypeRegisterInfo, const_cast<RegisterInfo *>(reg_context->GetRegisterInfoAtIndex(native_reg)));
- if (reg_context->ReadRegisterValue (native_reg, value.GetScalar()))
- return true;
+ if (reg_context->ReadRegisterValue (native_reg, value.GetScalar()))
+ return true;
- if (error_ptr)
- error_ptr->SetErrorStringWithFormat("Failed to read register %u.\n", native_reg);
- }
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat("Failed to read register %u.\n", native_reg);
}
}
- else
- {
- if (error_ptr)
- error_ptr->SetErrorStringWithFormat("Invalid frame in execution context.\n");
- }
return false;
}
@@ -766,7 +756,7 @@
) const
{
ExecutionContext exe_ctx (exe_scope);
- return Evaluate(&exe_ctx, ast_context, loclist_base_load_addr, initial_value_ptr, result, error_ptr);
+ return Evaluate(&exe_ctx, ast_context, NULL, loclist_base_load_addr, initial_value_ptr, result, error_ptr);
}
bool
@@ -774,6 +764,7 @@
(
ExecutionContext *exe_ctx,
clang::ASTContext *ast_context,
+ RegisterContext *reg_ctx,
lldb::addr_t loclist_base_load_addr,
const Value* initial_value_ptr,
Value& result,
@@ -783,7 +774,11 @@
if (IsLocationList())
{
uint32_t offset = 0;
- addr_t pc = exe_ctx->frame->GetRegisterContext()->GetPC();
+ addr_t pc;
+ if (reg_ctx)
+ pc = reg_ctx->GetPC();
+ else
+ pc = exe_ctx->frame->GetRegisterContext()->GetPC();
if (loclist_base_load_addr != LLDB_INVALID_ADDRESS)
{
@@ -814,7 +809,7 @@
if (length > 0 && lo_pc <= pc && pc < hi_pc)
{
- return DWARFExpression::Evaluate (exe_ctx, ast_context, m_data, m_expr_locals, m_decl_map, offset, length, m_reg_kind, initial_value_ptr, result, error_ptr);
+ return DWARFExpression::Evaluate (exe_ctx, ast_context, m_data, m_expr_locals, m_decl_map, reg_ctx, offset, length, m_reg_kind, initial_value_ptr, result, error_ptr);
}
offset += length;
}
@@ -826,7 +821,7 @@
}
// Not a location list, just a single expression.
- return DWARFExpression::Evaluate (exe_ctx, ast_context, m_data, m_expr_locals, m_decl_map, 0, m_data.GetByteSize(), m_reg_kind, initial_value_ptr, result, error_ptr);
+ return DWARFExpression::Evaluate (exe_ctx, ast_context, m_data, m_expr_locals, m_decl_map, reg_ctx, 0, m_data.GetByteSize(), m_reg_kind, initial_value_ptr, result, error_ptr);
}
@@ -839,6 +834,7 @@
const DataExtractor& opcodes,
ClangExpressionVariableList *expr_locals,
ClangExpressionDeclMap *decl_map,
+ RegisterContext *reg_ctx,
const uint32_t opcodes_offset,
const uint32_t opcodes_length,
const uint32_t reg_kind,
@@ -849,6 +845,9 @@
{
std::vector<Value> stack;
+ if (reg_ctx == NULL && exe_ctx && exe_ctx->frame)
+ reg_ctx = exe_ctx->frame->GetRegisterContext();
+
if (initial_value_ptr)
stack.push_back(*initial_value_ptr);
@@ -1015,9 +1014,86 @@
// on the expression stack.
//----------------------------------------------------------------------
case DW_OP_deref_size:
- if (error_ptr)
- error_ptr->SetErrorString("Unimplemented opcode: DW_OP_deref_size.");
- return false;
+ {
+ uint8_t size = opcodes.GetU8(&offset);
+ Value::ValueType value_type = stack.back().GetValueType();
+ switch (value_type)
+ {
+ case Value::eValueTypeHostAddress:
+ {
+ void *src = (void *)stack.back().GetScalar().ULongLong();
+ intptr_t ptr;
+ ::memcpy (&ptr, src, sizeof(void *));
+ // I can't decide whether the size operand should apply to the bytes in their
+ // lldb-host endianness or the target endianness.. I doubt this'll ever come up
+ // but I'll opt for assuming big endian regardless.
+ switch (size)
+ {
+ case 1: ptr = ptr & 0xff; break;
+ case 2: ptr = ptr & 0xffff; break;
+ case 3: ptr = ptr & 0xffffff; break;
+ case 4: ptr = ptr & 0xffffffff; break;
+ case 5: ptr = ptr & 0xffffffffff; break;
+ case 6: ptr = ptr & 0xffffffffffff; break;
+ case 7: ptr = ptr & 0xffffffffffffff; break;
+ default: break;
+ }
+ stack.back().GetScalar() = ptr;
+ stack.back().ClearContext();
+ }
+ break;
+ case Value::eValueTypeLoadAddress:
+ if (exe_ctx)
+ {
+ if (exe_ctx->process)
+ {
+ lldb::addr_t pointer_addr = stack.back().GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ uint8_t addr_bytes[sizeof(lldb::addr_t)];
+ Error error;
+ if (exe_ctx->process->ReadMemory(pointer_addr, &addr_bytes, size, error) == size)
+ {
+ DataExtractor addr_data(addr_bytes, sizeof(addr_bytes), exe_ctx->process->GetByteOrder(), size);
+ uint32_t addr_data_offset = 0;
+ switch (size)
+ {
+ case 1: stack.back().GetScalar() = addr_data.GetU8(&addr_data_offset); break;
+ case 2: stack.back().GetScalar() = addr_data.GetU16(&addr_data_offset); break;
+ case 4: stack.back().GetScalar() = addr_data.GetU32(&addr_data_offset); break;
+ case 8: stack.back().GetScalar() = addr_data.GetU64(&addr_data_offset); break;
+ default: stack.back().GetScalar() = addr_data.GetPointer(&addr_data_offset);
+ }
+ stack.back().ClearContext();
+ }
+ else
+ {
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat ("Failed to dereference pointer from 0x%llx for DW_OP_deref: %s\n",
+ pointer_addr,
+ error.AsCString());
+ return false;
+ }
+ }
+ else
+ {
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat ("NULL process for DW_OP_deref.\n");
+ return false;
+ }
+ }
+ else
+ {
+ if (error_ptr)
+ error_ptr->SetErrorStringWithFormat ("NULL execution context for DW_OP_deref.\n");
+ return false;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ }
+ break;
//----------------------------------------------------------------------
// OPCODE: DW_OP_xderef_size
@@ -1837,7 +1913,7 @@
{
reg_num = op - DW_OP_reg0;
- if (ReadRegisterValueAsScalar (exe_ctx, reg_kind, reg_num, error_ptr, tmp))
+ if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp))
stack.push_back(tmp);
else
return false;
@@ -1852,7 +1928,7 @@
case DW_OP_regx:
{
reg_num = opcodes.GetULEB128(&offset);
- if (ReadRegisterValueAsScalar (exe_ctx, reg_kind, reg_num, error_ptr, tmp))
+ if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp))
stack.push_back(tmp);
else
return false;
@@ -1901,7 +1977,7 @@
{
reg_num = op - DW_OP_breg0;
- if (ReadRegisterValueAsScalar (exe_ctx, reg_kind, reg_num, error_ptr, tmp))
+ if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp))
{
int64_t breg_offset = opcodes.GetSLEB128(&offset);
tmp.ResolveValue(exe_ctx, ast_context) += (uint64_t)breg_offset;
@@ -1924,7 +2000,7 @@
{
reg_num = opcodes.GetULEB128(&offset);
- if (ReadRegisterValueAsScalar (exe_ctx, reg_kind, reg_num, error_ptr, tmp))
+ if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp))
{
int64_t breg_offset = opcodes.GetSLEB128(&offset);
tmp.ResolveValue(exe_ctx, ast_context) += (uint64_t)breg_offset;
Modified: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp?rev=119885&r1=119884&r2=119885&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Fri Nov 19 19:28:30 2010
@@ -22,6 +22,10 @@
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Utility/ArchVolatileRegs.h"
#include "lldb/Core/Log.h"
+#include "lldb/Expression/DWARFExpression.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/StackFrame.h"
using namespace lldb;
using namespace lldb_private;
@@ -814,7 +818,7 @@
UnwindPlan::Row::RegisterLocation unwindplan_regloc;
bool have_unwindplan_regloc = false;
- int unwindplan_registerkind;
+ int unwindplan_registerkind = -1;
if (m_fast_unwind_plan)
{
@@ -995,6 +999,44 @@
return true;
}
+ if (unwindplan_regloc.IsDWARFExpression() || unwindplan_regloc.IsAtDWARFExpression())
+ {
+ DataExtractor dwarfdata (unwindplan_regloc.GetDWARFExpressionBytes(),
+ unwindplan_regloc.GetDWARFExpressionLength(),
+ m_thread.GetProcess().GetByteOrder(), m_thread.GetProcess().GetAddressByteSize());
+ DWARFExpression dwarfexpr (dwarfdata, 0, unwindplan_regloc.GetDWARFExpressionLength());
+ dwarfexpr.SetRegisterKind (unwindplan_registerkind);
+ ExecutionContext exe_ctx (&m_thread.GetProcess(), &m_thread, NULL);
+ Value result;
+ Error error;
+ if (dwarfexpr.Evaluate (&exe_ctx, NULL, this, 0, NULL, result, &error))
+ {
+ addr_t val;
+ val = result.GetScalar().ULongLong();
+ if (unwindplan_regloc.IsDWARFExpression())
+ {
+ regloc.type = eRegisterValueInferred;
+ regloc.location.register_value = val;
+ m_registers[lldb_regnum] = regloc;
+ return true;
+ }
+ else
+ {
+ regloc.type = eRegisterSavedAtMemoryLocation;
+ regloc.location.target_memory_location = val;
+ m_registers[lldb_regnum] = regloc;
+ return true;
+ }
+ }
+ if (log)
+ {
+ log->Printf("%*sFrame %d tried to use IsDWARFExpression or IsAtDWARFExpression for reg %d but failed",
+ m_frame_number < 100 ? m_frame_number : 100, "", m_frame_number,
+ lldb_regnum);
+ }
+ return false;
+ }
+
if (log)
{
log->Printf("%*sFrame %d could not supply caller's reg %d location",
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=119885&r1=119884&r2=119885&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Fri Nov 19 19:28:30 2010
@@ -1225,6 +1225,7 @@
debug_info_data,
NULL,
NULL,
+ NULL,
block_offset,
block_length,
eRegisterKindDWARF,
Modified: lldb/trunk/source/Target/StackFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StackFrame.cpp?rev=119885&r1=119884&r2=119885&view=diff
==============================================================================
--- lldb/trunk/source/Target/StackFrame.cpp (original)
+++ lldb/trunk/source/Target/StackFrame.cpp Fri Nov 19 19:28:30 2010
@@ -496,7 +496,7 @@
if (m_sc.function->GetFrameBaseExpression().IsLocationList())
loclist_base_addr = m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (&m_thread.GetProcess().GetTarget());
- if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false)
+ if (m_sc.function->GetFrameBaseExpression().Evaluate(&exe_ctx, NULL, NULL, loclist_base_addr, NULL, expr_value, &m_frame_base_error) == false)
{
// We should really have an error if evaluate returns, but in case
// we don't, lets set the error to something at least.
More information about the lldb-commits
mailing list