diff options
Diffstat (limited to 'lldb/source')
| -rw-r--r-- | lldb/source/Core/ValueObjectVariable.cpp | 2 | ||||
| -rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 2 | ||||
| -rw-r--r-- | lldb/source/Expression/DWARFExpression.cpp | 150 | ||||
| -rw-r--r-- | lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp | 44 | ||||
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 1 | ||||
| -rw-r--r-- | lldb/source/Target/StackFrame.cpp | 2 |
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. |

