Fixed a bug in the expression parser where the 'this'

or 'self' variable was not properly read if the compiler
optimized it into a register.

llvm-svn: 126973
This commit is contained in:
Sean Callanan 2011-03-04 00:23:47 +00:00
parent 1a69e23300
commit 54366f12cb
1 changed files with 66 additions and 32 deletions

View File

@ -551,41 +551,75 @@ ClangExpressionDeclMap::GetObjectPointer
return false;
}
if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
{
lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
uint32_t address_byte_size = exe_ctx.target->GetArchitecture().GetAddressByteSize();
lldb::ByteOrder address_byte_order = exe_ctx.process->GetByteOrder();
if (ClangASTType::GetClangTypeBitWidth(m_struct_vars->m_object_pointer_type.GetASTContext(),
m_struct_vars->m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
{
err.SetErrorStringWithFormat("'%s' is not of an expected pointer size", object_name.GetCString());
return false;
}
DataBufferHeap data;
data.SetByteSize(address_byte_size);
Error read_error;
if (exe_ctx.process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size)
{
err.SetErrorStringWithFormat("Coldn't read '%s' from the target: %s", object_name.GetCString(), read_error.AsCString());
return false;
}
DataExtractor extractor(data.GetBytes(), data.GetByteSize(), address_byte_order, address_byte_size);
uint32_t offset = 0;
object_ptr = extractor.GetPointer(&offset);
return true;
}
else
switch (location_value->GetValueType())
{
default:
err.SetErrorStringWithFormat("'%s' is not in memory; LLDB must be extended to handle registers", object_name.GetCString());
return false;
case Value::eValueTypeLoadAddress:
{
lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
uint32_t address_byte_size = exe_ctx.target->GetArchitecture().GetAddressByteSize();
lldb::ByteOrder address_byte_order = exe_ctx.process->GetByteOrder();
if (ClangASTType::GetClangTypeBitWidth(m_struct_vars->m_object_pointer_type.GetASTContext(),
m_struct_vars->m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
{
err.SetErrorStringWithFormat("'%s' is not of an expected pointer size", object_name.GetCString());
return false;
}
DataBufferHeap data;
data.SetByteSize(address_byte_size);
Error read_error;
if (exe_ctx.process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size)
{
err.SetErrorStringWithFormat("Coldn't read '%s' from the target: %s", object_name.GetCString(), read_error.AsCString());
return false;
}
DataExtractor extractor(data.GetBytes(), data.GetByteSize(), address_byte_order, address_byte_size);
uint32_t offset = 0;
object_ptr = extractor.GetPointer(&offset);
return true;
}
case Value::eValueTypeScalar:
{
if (location_value->GetContextType() != Value::eContextTypeRegisterInfo)
{
StreamString ss;
location_value->Dump(&ss);
err.SetErrorStringWithFormat("%s is a scalar of unhandled type: %s", object_name.GetCString(), ss.GetString().c_str());
return false;
}
lldb::RegisterInfo *register_info = location_value->GetRegisterInfo();
if (!register_info)
{
err.SetErrorStringWithFormat("Couldn't get the register information for %s", object_name.GetCString());
return false;
}
RegisterContext *register_context = exe_ctx.GetRegisterContext();
if (!register_context)
{
err.SetErrorStringWithFormat("Couldn't read register context to read %s from %s", object_name.GetCString(), register_info->name);
return false;
}
uint32_t register_number = register_info->kinds[lldb::eRegisterKindLLDB];
object_ptr = register_context->ReadRegisterAsUnsigned(register_number, 0x0);
return true;
}
}
}