summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Core/Value.h3
-rw-r--r--lldb/source/Core/Value.cpp19
-rw-r--r--lldb/source/Core/ValueObjectVariable.cpp21
-rw-r--r--lldb/source/Expression/DWARFExpression.cpp6
4 files changed, 30 insertions, 19 deletions
diff --git a/lldb/include/lldb/Core/Value.h b/lldb/include/lldb/Core/Value.h
index 6ef2b7d9667..801e818c6f5 100644
--- a/lldb/include/lldb/Core/Value.h
+++ b/lldb/include/lldb/Core/Value.h
@@ -228,6 +228,9 @@ public:
static const char *GetContextTypeAsCString(ContextType context_type);
+ /// Convert this value's file address to a load address, if possible.
+ void ConvertToLoadAddress(Module *module, Target *target);
+
bool GetData(DataExtractor &data);
void Clear();
diff --git a/lldb/source/Core/Value.cpp b/lldb/source/Core/Value.cpp
index 292ba0725ff..254c9008bab 100644
--- a/lldb/source/Core/Value.cpp
+++ b/lldb/source/Core/Value.cpp
@@ -669,6 +669,25 @@ const char *Value::GetContextTypeAsCString(ContextType context_type) {
return "???";
}
+void Value::ConvertToLoadAddress(Module *module, Target *target) {
+ if (!module || !target || (GetValueType() != eValueTypeFileAddress))
+ return;
+
+ lldb::addr_t file_addr = GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ if (file_addr == LLDB_INVALID_ADDRESS)
+ return;
+
+ Address so_addr;
+ if (!module->ResolveFileAddress(file_addr, so_addr))
+ return;
+ lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
+ if (load_addr == LLDB_INVALID_ADDRESS)
+ return;
+
+ SetValueType(Value::eValueTypeLoadAddress);
+ GetScalar() = load_addr;
+}
+
ValueList::ValueList(const ValueList &rhs) { m_values = rhs.m_values; }
const ValueList &ValueList::operator=(const ValueList &rhs) {
diff --git a/lldb/source/Core/ValueObjectVariable.cpp b/lldb/source/Core/ValueObjectVariable.cpp
index e08963210ec..95b58b3336c 100644
--- a/lldb/source/Core/ValueObjectVariable.cpp
+++ b/lldb/source/Core/ValueObjectVariable.cpp
@@ -235,25 +235,8 @@ bool ValueObjectVariable::UpdateValue() {
// m_data. Make sure this type has a value before we try and read it
// If we have a file address, convert it to a load address if we can.
- if (value_type == Value::eValueTypeFileAddress && process_is_alive) {
- lldb::addr_t file_addr =
- m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
- if (file_addr != LLDB_INVALID_ADDRESS) {
- SymbolContext var_sc;
- variable->CalculateSymbolContext(&var_sc);
- if (var_sc.module_sp) {
- ObjectFile *objfile = var_sc.module_sp->GetObjectFile();
- if (objfile) {
- Address so_addr(file_addr, objfile->GetSectionList());
- lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
- if (load_addr != LLDB_INVALID_ADDRESS) {
- m_value.SetValueType(Value::eValueTypeLoadAddress);
- m_value.GetScalar() = load_addr;
- }
- }
- }
- }
- }
+ if (value_type == Value::eValueTypeFileAddress && process_is_alive)
+ m_value.ConvertToLoadAddress(GetModule().get(), target);
if (!CanProvideValue()) {
// this value object represents an aggregate type whose children have
diff --git a/lldb/source/Expression/DWARFExpression.cpp b/lldb/source/Expression/DWARFExpression.cpp
index 71495715e75..8f54bf37ea0 100644
--- a/lldb/source/Expression/DWARFExpression.cpp
+++ b/lldb/source/Expression/DWARFExpression.cpp
@@ -1374,6 +1374,7 @@ bool DWARFExpression::Evaluate(
}
log->Printf("0x%8.8" PRIx64 ": %s", op_offset, DW_OP_value_to_name(op));
}
+
switch (op) {
//----------------------------------------------------------------------
// The DW_OP_addr operation has a single operand that encodes a machine
@@ -1382,6 +1383,11 @@ bool DWARFExpression::Evaluate(
case DW_OP_addr:
stack.push_back(Scalar(opcodes.GetAddress(&offset)));
stack.back().SetValueType(Value::eValueTypeFileAddress);
+ // Convert the file address to a load address, so subsequent
+ // DWARF operators can operate on it.
+ if (frame)
+ stack.back().ConvertToLoadAddress(module_sp.get(),
+ frame->CalculateTarget().get());
break;
//----------------------------------------------------------------------
OpenPOWER on IntegriCloud