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
This commit is contained in:
Adrian Prantl 2018-05-03 23:32:47 +00:00
parent 3835320617
commit b51804e0d8
4 changed files with 30 additions and 19 deletions

View File

@ -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();

View File

@ -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) {

View File

@ -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

View File

@ -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;
//----------------------------------------------------------------------