Modified Value.cpp to share the code that gets the values as bytes (Value::GetValueAsData()) so now Value::ResolveValue() doesn't do its own thing by reading memory directly.

Also modified the Value class so that you can evaluate expressions without a process, yet with some sections loaded in the target. This allows casting pointers that are in data sections to types and being able to evaluate expressions in the data. For example:

(lldb) target create a.out
(lldb) target modules load --file a.out --slide 0
... find address of something in data ...
(lldb) script
expr_opts = lldb.SBExpressionOptions()
v = lldb.target.EvaluateExpression('(foo *)0x1230000', expr_opts)
print v
vv = lldb.value(v)
print v.pt.x

Above we were able to cast a pointer to an address which was in a.out's data
section and print out entire structures and navigate to the child ivars of the expression.

llvm-svn: 172227
This commit is contained in:
Greg Clayton 2013-01-11 18:01:02 +00:00
parent a40a805f30
commit c0e8a85ea8
1 changed files with 51 additions and 9 deletions

View File

@ -326,7 +326,7 @@ Value::GetData (DataExtractor &data)
}
Error
Value::GetValueAsData (ExecutionContext *exe_ctx,
Value::GetValueAsData (ExecutionContext *exe_ctx,
clang::ASTContext *ast_context,
DataExtractor &data,
uint32_t data_offset,
@ -368,9 +368,54 @@ Value::GetValueAsData (ExecutionContext *exe_ctx,
else
{
Process *process = exe_ctx->GetProcessPtr();
if (process == NULL)
if (process == NULL || !process->IsAlive())
{
error.SetErrorString ("can't read load address (invalid process)");
Target *target = exe_ctx->GetTargetPtr();
if (target)
{
// Allow expressions to run and evaluate things when the target
// has memory sections loaded. This allows you to use "target modules load"
// to load your executable and any shared libraries, then execute
// commands where you can look at types in data sections.
const SectionLoadList &target_sections = target->GetSectionLoadList();
if (!target_sections.IsEmpty())
{
address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
if (target_sections.ResolveLoadAddress(address, file_so_addr))
{
address_type = eAddressTypeLoad;
data.SetByteOrder(target->GetArchitecture().GetByteOrder());
data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
}
else
address = LLDB_INVALID_ADDRESS;
}
// else
// {
// ModuleSP exe_module_sp (target->GetExecutableModule());
// if (exe_module_sp)
// {
// address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
// if (address != LLDB_INVALID_ADDRESS)
// {
// if (exe_module_sp->ResolveFileAddress(address, file_so_addr))
// {
// data.SetByteOrder(target->GetArchitecture().GetByteOrder());
// data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
// address_type = eAddressTypeFile;
// }
// else
// {
// address = LLDB_INVALID_ADDRESS;
// }
// }
// }
// }
}
else
{
error.SetErrorString ("can't read load address (invalid process)");
}
}
else
{
@ -602,16 +647,13 @@ Value::ResolveValue(ExecutionContext *exe_ctx, clang::ASTContext *ast_context)
default:
case eValueTypeFileAddress:
m_value.Clear();
break;
case eValueTypeLoadAddress: // load address value
case eValueTypeHostAddress: // host address value (for memory in the process that is using liblldb)
{
AddressType address_type = m_value_type == eValueTypeLoadAddress ? eAddressTypeLoad : eAddressTypeHost;
lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);
DataExtractor data;
if (ClangASTType::ReadFromMemory (ast_context, opaque_clang_qual_type, exe_ctx, addr, address_type, data))
lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);
Error error (GetValueAsData (exe_ctx, ast_context, data, 0, NULL));
if (error.Success())
{
Scalar scalar;
if (ClangASTType::GetValueAsScalar (ast_context, opaque_clang_qual_type, data, 0, data.GetByteSize(), scalar))