diff options
author | Adrian Prantl <aprantl@apple.com> | 2018-05-03 23:32:47 +0000 |
---|---|---|
committer | Adrian Prantl <aprantl@apple.com> | 2018-05-03 23:32:47 +0000 |
commit | b51804e0d8c0ecbc5befda89b376e189c652f6b3 (patch) | |
tree | beb28a1c6b8d4aa4c9ed926ef668bd61acfdb495 | |
parent | 3835320617d7c37e8ac545b0b7828db2a57d46a4 (diff) | |
download | bcm5719-llvm-b51804e0d8c0ecbc5befda89b376e189c652f6b3.tar.gz bcm5719-llvm-b51804e0d8c0ecbc5befda89b376e189c652f6b3.zip |
DWARFExpression: Convert file addresses to load addresses early on.
This is a change that only affects Swift and is NFC for the language
plugins on llvm.org. In Swift, we can have global variables with a
location such as DW_OP_addr <addr> DW_OP_deref. The DWARF expression
evaluator doesn't know how to apply a DW_OP_deref to a file address,
but at the very end we convert the file address into a load address.
This patch moves the file->load address conversion to right after the
result of the DW_OP_addr is pushed onto the stack so that a subsequent
DW_OP_deref (and potentially other operations) can be interpreted.
rdar://problem/39767528
Differential revision: https://reviews.llvm.org/D46362
llvm-svn: 331492
-rw-r--r-- | lldb/include/lldb/Core/Value.h | 3 | ||||
-rw-r--r-- | lldb/source/Core/Value.cpp | 19 | ||||
-rw-r--r-- | lldb/source/Core/ValueObjectVariable.cpp | 21 | ||||
-rw-r--r-- | lldb/source/Expression/DWARFExpression.cpp | 6 |
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; //---------------------------------------------------------------------- |