summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Core/ValueObjectVariable.cpp2
-rw-r--r--lldb/source/Expression/ClangExpressionDeclMap.cpp2
-rw-r--r--lldb/source/Expression/DWARFExpression.cpp150
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp44
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp1
-rw-r--r--lldb/source/Target/StackFrame.cpp2
6 files changed, 160 insertions, 41 deletions
diff --git a/lldb/source/Core/ValueObjectVariable.cpp b/lldb/source/Core/ValueObjectVariable.cpp
index 4f8bfe248fd..0d91cd47aae 100644
--- a/lldb/source/Core/ValueObjectVariable.cpp
+++ b/lldb/source/Core/ValueObjectVariable.cpp
@@ -118,7 +118,7 @@ ValueObjectVariable::UpdateValue (ExecutionContextScope *exe_scope)
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);
diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp
index 0775b4fea1d..f2d2bc96248 100644
--- a/lldb/source/Expression/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp
@@ -1205,7 +1205,7 @@ ClangExpressionDeclMap::GetVariableValue
}
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());
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 30381b0439e..df4170fee9e 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -631,48 +631,38 @@ DWARFExpression::GetDescription (Stream *s, lldb::DescriptionLevel level, addr_t
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 @@ DWARFExpression::Evaluate
) 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 @@ DWARFExpression::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,
@@ -783,7 +774,11 @@ DWARFExpression::Evaluate
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 @@ DWARFExpression::Evaluate
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 @@ DWARFExpression::Evaluate
}
// 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 @@ DWARFExpression::Evaluate
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 @@ DWARFExpression::Evaluate
{
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 @@ DWARFExpression::Evaluate
// 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 @@ DWARFExpression::Evaluate
{
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 @@ DWARFExpression::Evaluate
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 @@ DWARFExpression::Evaluate
{
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 @@ DWARFExpression::Evaluate
{
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;
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index 16bf87e527a..cbb79a2178c 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -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 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc
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 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, RegisterLoc
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",
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index ce300727f7b..8d466559ba5 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1225,6 +1225,7 @@ SymbolFileDWARF::ParseChildMembers
debug_info_data,
NULL,
NULL,
+ NULL,
block_offset,
block_length,
eRegisterKindDWARF,
diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index 7671eab0ef0..7281ba427e4 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -496,7 +496,7 @@ StackFrame::GetFrameBaseValue (Scalar &frame_base, Error *error_ptr)
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.
OpenPOWER on IntegriCloud