forked from OSchip/llvm-project
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:
parent
a40a805f30
commit
c0e8a85ea8
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue