summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core/Value.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Core/Value.cpp')
-rw-r--r--lldb/source/Core/Value.cpp425
1 files changed, 128 insertions, 297 deletions
diff --git a/lldb/source/Core/Value.cpp b/lldb/source/Core/Value.cpp
index 2ba490ebb0a..897ab8cb59d 100644
--- a/lldb/source/Core/Value.cpp
+++ b/lldb/source/Core/Value.cpp
@@ -31,98 +31,30 @@ using namespace lldb;
using namespace lldb_private;
Value::Value() :
- m_value(),
- m_value_type(eValueTypeScalar),
- m_context(NULL),
- m_context_type(eContextTypeInvalid)
+ m_value (),
+ m_value_type (eValueTypeScalar),
+ m_context (NULL),
+ m_context_type (eContextTypeInvalid),
+ m_data_buffer ()
{
}
Value::Value(const Scalar& scalar) :
- m_value(scalar),
- m_value_type(eValueTypeScalar),
- m_context(NULL),
- m_context_type(eContextTypeInvalid)
+ m_value (scalar),
+ m_value_type (eValueTypeScalar),
+ m_context (NULL),
+ m_context_type (eContextTypeInvalid),
+ m_data_buffer ()
{
}
-Value::Value(int v) :
- m_value(v),
- m_value_type(eValueTypeScalar),
- m_context(NULL),
- m_context_type(eContextTypeInvalid)
-{
-}
-
-Value::Value(unsigned int v) :
- m_value(v),
- m_value_type(eValueTypeScalar),
- m_context(NULL),
- m_context_type(eContextTypeInvalid)
-{
-}
-
-Value::Value(long v) :
- m_value(v),
- m_value_type(eValueTypeScalar),
- m_context(NULL),
- m_context_type(eContextTypeInvalid)
-{
-}
-
-Value::Value(unsigned long v) :
- m_value(v),
- m_value_type(eValueTypeScalar),
- m_context(NULL),
- m_context_type(eContextTypeInvalid)
-{
-}
-
-Value::Value(long long v) :
- m_value(v),
- m_value_type(eValueTypeScalar),
- m_context(NULL),
- m_context_type(eContextTypeInvalid)
-{
-}
-
-Value::Value(unsigned long long v) :
- m_value(v),
- m_value_type(eValueTypeScalar),
- m_context(NULL),
- m_context_type(eContextTypeInvalid)
-{
-}
-
-Value::Value(float v) :
- m_value(v),
- m_value_type(eValueTypeScalar),
- m_context(NULL),
- m_context_type(eContextTypeInvalid)
-{
-}
-
-Value::Value(double v) :
- m_value(v),
- m_value_type(eValueTypeScalar),
- m_context(NULL),
- m_context_type(eContextTypeInvalid)
-{
-}
-
-Value::Value(long double v) :
- m_value(v),
- m_value_type(eValueTypeScalar),
- m_context(NULL),
- m_context_type(eContextTypeInvalid)
-{
-}
Value::Value(const uint8_t *bytes, int len) :
- m_value(),
- m_value_type(eValueTypeHostAddress),
- m_context(NULL),
- m_context_type(eContextTypeInvalid)
+ m_value (),
+ m_value_type (eValueTypeHostAddress),
+ m_context (NULL),
+ m_context_type (eContextTypeInvalid),
+ m_data_buffer ()
{
m_data_buffer.CopyData(bytes, len);
m_value = (uintptr_t)m_data_buffer.GetBytes();
@@ -163,35 +95,9 @@ Value::operator=(const Value &rhs)
return *this;
}
-Value *
-Value::CreateProxy()
-{
- if (m_context_type == eContextTypeValue)
- return ((Value*)m_context)->CreateProxy ();
-
- Value *ret = new Value;
- ret->SetContext(eContextTypeValue, this);
- return ret;
-}
-
-Value *
-Value::GetProxyTarget()
-{
- if (m_context_type == eContextTypeValue)
- return (Value*)m_context;
- else
- return NULL;
-}
-
void
Value::Dump (Stream* strm)
{
- if (m_context_type == eContextTypeValue)
- {
- ((Value*)m_context)->Dump (strm);
- return;
- }
-
m_value.GetValue (strm, true);
strm->Printf(", value_type = %s, context = %p, context_type = %s",
Value::GetValueTypeAsCString(m_value_type),
@@ -202,18 +108,12 @@ Value::Dump (Stream* strm)
Value::ValueType
Value::GetValueType() const
{
- if (m_context_type == eContextTypeValue)
- return ((Value*)m_context)->GetValueType ();
-
return m_value_type;
}
AddressType
Value::GetValueAddressType () const
{
- if (m_context_type == eContextTypeValue)
- return ((Value*)m_context)->GetValueAddressType ();
-
switch (m_value_type)
{
default:
@@ -226,60 +126,9 @@ Value::GetValueAddressType () const
return eAddressTypeInvalid;
}
-
-Value::ContextType
-Value::GetContextType() const
-{
- if (m_context_type == eContextTypeValue)
- return ((Value*)m_context)->GetContextType ();
-
- return m_context_type;
-}
-
-void
-Value::SetValueType (Value::ValueType value_type)
-{
- if (m_context_type == eContextTypeValue)
- {
- ((Value*)m_context)->SetValueType(value_type);
- return;
- }
-
- m_value_type = value_type;
-}
-
-void
-Value::ClearContext ()
-{
- if (m_context_type == eContextTypeValue)
- {
- ((Value*)m_context)->ClearContext();
- return;
- }
-
- m_context = NULL;
- m_context_type = eContextTypeInvalid;
-}
-
-void
-Value::SetContext (Value::ContextType context_type, void *p)
-{
- if (m_context_type == eContextTypeValue)
- {
- ((Value*)m_context)->SetContext(context_type, p);
- return;
- }
-
- m_context_type = context_type;
- m_context = p;
-}
-
RegisterInfo *
Value::GetRegisterInfo()
{
- if (m_context_type == eContextTypeValue)
- return ((Value*)m_context)->GetRegisterInfo();
-
if (m_context_type == eContextTypeRegisterInfo)
return static_cast<RegisterInfo *> (m_context);
return NULL;
@@ -288,32 +137,14 @@ Value::GetRegisterInfo()
Type *
Value::GetType()
{
- if (m_context_type == eContextTypeValue)
- return ((Value*)m_context)->GetType();
-
if (m_context_type == eContextTypeLLDBType)
return static_cast<Type *> (m_context);
return NULL;
}
-Scalar &
-Value::GetScalar()
-{
- if (m_context_type == eContextTypeValue)
- return ((Value*)m_context)->GetScalar();
-
- return m_value;
-}
-
void
Value::ResizeData(int len)
{
- if (m_context_type == eContextTypeValue)
- {
- ((Value*)m_context)->ResizeData(len);
- return;
- }
-
m_value_type = eValueTypeHostAddress;
m_data_buffer.SetByteSize(len);
m_value = (uintptr_t)m_data_buffer.GetBytes();
@@ -322,19 +153,16 @@ Value::ResizeData(int len)
bool
Value::ValueOf(ExecutionContext *exe_ctx, clang::ASTContext *ast_context)
{
- if (m_context_type == eContextTypeValue)
- return ((Value*)m_context)->ValueOf(exe_ctx, ast_context);
-
switch (m_context_type)
{
default:
case eContextTypeInvalid:
- case eContextTypeClangType: // clang::Type *
- case eContextTypeRegisterInfo: // RegisterInfo *
- case eContextTypeLLDBType: // Type *
+ case eContextTypeClangType: // clang::Type *
+ case eContextTypeRegisterInfo: // RegisterInfo *
+ case eContextTypeLLDBType: // Type *
break;
- case eContextTypeVariable: // Variable *
+ case eContextTypeVariable: // Variable *
ResolveValue(exe_ctx, ast_context);
return true;
}
@@ -344,9 +172,6 @@ Value::ValueOf(ExecutionContext *exe_ctx, clang::ASTContext *ast_context)
size_t
Value::GetValueByteSize (clang::ASTContext *ast_context, Error *error_ptr)
{
- if (m_context_type == eContextTypeValue)
- return ((Value*)m_context)->GetValueByteSize(ast_context, error_ptr);
-
size_t byte_size = 0;
switch (m_context_type)
@@ -412,9 +237,6 @@ Value::GetValueByteSize (clang::ASTContext *ast_context, Error *error_ptr)
clang_type_t
Value::GetClangType ()
{
- if (m_context_type == eContextTypeValue)
- return ((Value*)m_context)->GetClangType();
-
switch (m_context_type)
{
default:
@@ -444,9 +266,6 @@ Value::GetClangType ()
lldb::Format
Value::GetValueDefaultFormat ()
{
- if (m_context_type == eContextTypeValue)
- return ((Value*)m_context)->GetValueDefaultFormat();
-
switch (m_context_type)
{
default:
@@ -506,11 +325,12 @@ Value::GetData (DataExtractor &data)
}
Error
-Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context, DataExtractor &data, uint32_t data_offset)
+Value::GetValueAsData (ExecutionContext *exe_ctx,
+ clang::ASTContext *ast_context,
+ DataExtractor &data,
+ uint32_t data_offset,
+ Module *module)
{
- if (m_context_type == eContextTypeValue)
- return ((Value*)m_context)->GetValueAsData(exe_ctx, ast_context, data, data_offset);
-
data.Clear();
Error error;
@@ -544,16 +364,20 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
{
error.SetErrorString ("can't read load address (no execution context)");
}
- else if (exe_ctx->process == NULL)
+ else
{
- error.SetErrorString ("can't read load address (invalid process)");
- }
- else
- {
- address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
- address_type = eAddressTypeLoad;
- data.SetByteOrder(exe_ctx->process->GetTarget().GetArchitecture().GetByteOrder());
- data.SetAddressByteSize(exe_ctx->process->GetTarget().GetArchitecture().GetAddressByteSize());
+ Process *process = exe_ctx->GetProcess();
+ if (process == NULL)
+ {
+ error.SetErrorString ("can't read load address (invalid process)");
+ }
+ else
+ {
+ address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
+ address_type = eAddressTypeLoad;
+ data.SetByteOrder(process->GetTarget().GetArchitecture().GetByteOrder());
+ data.SetAddressByteSize(process->GetTarget().GetArchitecture().GetAddressByteSize());
+ }
}
break;
@@ -568,71 +392,91 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
}
else
{
- // The only thing we can currently lock down to a module so that
- // we can resolve a file address, is a variable.
- Variable *variable = GetVariable();
-
- if (GetVariable())
+ address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
+ if (address == LLDB_INVALID_ADDRESS)
{
- address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
- if (address != LLDB_INVALID_ADDRESS)
+ error.SetErrorString ("invalid file address");
+ }
+ else
+ {
+ if (module == NULL)
+ {
+ // The only thing we can currently lock down to a module so that
+ // we can resolve a file address, is a variable.
+ Variable *variable = GetVariable();
+ if (variable)
+ {
+ SymbolContext var_sc;
+ variable->CalculateSymbolContext(&var_sc);
+ module = var_sc.module_sp.get();
+ }
+ }
+
+ if (module)
{
bool resolved = false;
- SymbolContext var_sc;
- variable->CalculateSymbolContext(&var_sc);
- if (var_sc.module_sp)
+ ObjectFile *objfile = module->GetObjectFile();
+ if (objfile)
{
- ObjectFile *objfile = var_sc.module_sp->GetObjectFile();
- if (objfile)
+ Address so_addr(address, objfile->GetSectionList());
+ addr_t load_address = so_addr.GetLoadAddress (exe_ctx->target);
+ if (load_address != LLDB_INVALID_ADDRESS)
{
- Address so_addr(address, objfile->GetSectionList());
- addr_t load_address = so_addr.GetLoadAddress (exe_ctx->target);
- if (load_address != LLDB_INVALID_ADDRESS)
+ resolved = true;
+ address = load_address;
+ address_type = eAddressTypeLoad;
+ data.SetByteOrder(exe_ctx->target->GetArchitecture().GetByteOrder());
+ data.SetAddressByteSize(exe_ctx->target->GetArchitecture().GetAddressByteSize());
+ }
+ else
+ {
+ if (so_addr.IsSectionOffset())
{
resolved = true;
- address = load_address;
- address_type = eAddressTypeLoad;
- data.SetByteOrder(exe_ctx->target->GetArchitecture().GetByteOrder());
- data.SetAddressByteSize(exe_ctx->target->GetArchitecture().GetAddressByteSize());
- }
- else
- {
- if (so_addr.IsSectionOffset())
- {
- resolved = true;
- file_so_addr = so_addr;
- data.SetByteOrder(objfile->GetByteOrder());
- data.SetAddressByteSize(objfile->GetAddressByteSize());
- }
+ file_so_addr = so_addr;
+ data.SetByteOrder(objfile->GetByteOrder());
+ data.SetAddressByteSize(objfile->GetAddressByteSize());
}
}
}
if (!resolved)
{
- if (var_sc.module_sp)
- error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s' in %s%s%s",
- address,
- variable->GetName().AsCString(""),
- var_sc.module_sp->GetFileSpec().GetDirectory().GetCString(),
- var_sc.module_sp->GetFileSpec().GetDirectory() ? "/" : "",
- var_sc.module_sp->GetFileSpec().GetFilename().GetCString());
+ Variable *variable = GetVariable();
+
+ if (module)
+ {
+ if (variable)
+ error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s' in %s%s%s",
+ address,
+ variable->GetName().AsCString(""),
+ module->GetFileSpec().GetDirectory().GetCString(),
+ module->GetFileSpec().GetDirectory() ? "/" : "",
+ module->GetFileSpec().GetFilename().GetCString());
+ else
+ error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx in %s%s%s",
+ address,
+ module->GetFileSpec().GetDirectory().GetCString(),
+ module->GetFileSpec().GetDirectory() ? "/" : "",
+ module->GetFileSpec().GetFilename().GetCString());
+ }
else
- error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s'",
- address,
- variable->GetName().AsCString(""));
+ {
+ if (variable)
+ error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx for variable '%s'",
+ address,
+ variable->GetName().AsCString(""));
+ else
+ error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%llx", address);
+ }
}
}
else
{
- error.SetErrorString ("invalid file address");
+ // Can't convert a file address to anything valid without more
+ // context (which Module it came from)
+ error.SetErrorString ("can't read memory from file address without more context");
}
}
- else
- {
- // Can't convert a file address to anything valid without more
- // context (which Module it came from)
- error.SetErrorString ("can't read memory from file address without more context");
- }
}
break;
@@ -695,9 +539,24 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
}
else
{
- if (exe_ctx->process->ReadMemory(address, dst, byte_size, error) != byte_size)
+ // The execution context might have a NULL process, but it
+ // might have a valid process in the exe_ctx->target, so use
+ // the ExecutionContext::GetProcess accessor to ensure we
+ // get the process if there is one.
+ Process *process = exe_ctx->GetProcess();
+
+ if (process)
{
- error.SetErrorStringWithFormat("read memory from 0x%llx failed", (uint64_t)address);
+ const size_t bytes_read = process->ReadMemory(address, dst, byte_size, error);
+ if (bytes_read != byte_size)
+ error.SetErrorStringWithFormat("read memory from 0x%llx failed (%u of %u bytes read)",
+ (uint64_t)address,
+ (uint32_t)bytes_read,
+ (uint32_t)byte_size);
+ }
+ else
+ {
+ error.SetErrorStringWithFormat("read memory from 0x%llx failed (invalid process)", (uint64_t)address);
}
}
}
@@ -717,30 +576,9 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, clang::ASTContext *ast_context
Scalar &
Value::ResolveValue(ExecutionContext *exe_ctx, clang::ASTContext *ast_context)
{
- Scalar scalar;
- if (m_context_type == eContextTypeValue)
+ void *opaque_clang_qual_type = GetClangType();
+ if (opaque_clang_qual_type)
{
- // Resolve the proxy
-
- Value * rhs = (Value*)m_context;
-
- m_value = rhs->m_value;
- m_value_type = rhs->m_value_type;
- m_context = rhs->m_context;
- m_context_type = rhs->m_context_type;
-
- if ((uintptr_t)rhs->m_value.ULongLong(LLDB_INVALID_ADDRESS) == (uintptr_t)rhs->m_data_buffer.GetBytes())
- {
- m_data_buffer.CopyData(rhs->m_data_buffer.GetBytes(),
- rhs->m_data_buffer.GetByteSize());
-
- m_value = (uintptr_t)m_data_buffer.GetBytes();
- }
- }
-
- if (m_context_type == eContextTypeClangType)
- {
- void *opaque_clang_qual_type = GetClangType();
switch (m_value_type)
{
case eValueTypeScalar: // raw scalar value
@@ -759,6 +597,7 @@ Value::ResolveValue(ExecutionContext *exe_ctx, clang::ASTContext *ast_context)
DataExtractor data;
if (ClangASTType::ReadFromMemory (ast_context, opaque_clang_qual_type, exe_ctx, addr, address_type, data))
{
+ Scalar scalar;
if (ClangASTType::GetValueAsScalar (ast_context, opaque_clang_qual_type, data, 0, data.GetByteSize(), scalar))
{
m_value = scalar;
@@ -784,8 +623,6 @@ Value::ResolveValue(ExecutionContext *exe_ctx, clang::ASTContext *ast_context)
}
break;
}
-
-
}
return m_value;
}
@@ -793,16 +630,11 @@ Value::ResolveValue(ExecutionContext *exe_ctx, clang::ASTContext *ast_context)
Variable *
Value::GetVariable()
{
- if (m_context_type == eContextTypeValue)
- return ((Value*)m_context)->GetVariable();
-
if (m_context_type == eContextTypeVariable)
return static_cast<Variable *> (m_context);
return NULL;
}
-
-
const char *
Value::GetValueTypeAsCString (ValueType value_type)
{
@@ -821,12 +653,11 @@ Value::GetContextTypeAsCString (ContextType context_type)
{
switch (context_type)
{
- case eContextTypeInvalid: return "invalid";
- case eContextTypeClangType: return "clang::Type *";
- case eContextTypeRegisterInfo: return "RegisterInfo *";
- case eContextTypeLLDBType: return "Type *";
- case eContextTypeVariable: return "Variable *";
- case eContextTypeValue: return "Value"; // TODO: Sean, more description here?
+ case eContextTypeInvalid: return "invalid";
+ case eContextTypeClangType: return "clang::Type *";
+ case eContextTypeRegisterInfo: return "RegisterInfo *";
+ case eContextTypeLLDBType: return "Type *";
+ case eContextTypeVariable: return "Variable *";
};
return "???";
}
OpenPOWER on IntegriCloud