[Lldb-commits] [lldb] r115658 - /lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
Sean Callanan
scallanan at apple.com
Tue Oct 5 13:18:49 PDT 2010
Author: spyffe
Date: Tue Oct 5 15:18:48 2010
New Revision: 115658
URL: http://llvm.org/viewvc/llvm-project?rev=115658&view=rev
Log:
Added support for (de)materializing values in registers,
so that expressions can use them.
Modified:
lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=115658&r1=115657&r2=115658&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Tue Oct 5 15:18:48 2010
@@ -32,6 +32,7 @@
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
@@ -612,7 +613,7 @@
{
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
- if (!exe_ctx.frame)
+ if (!exe_ctx.frame || !exe_ctx.process)
return false;
Variable *var = FindVariableInScope(*exe_ctx.frame, name, &type);
@@ -635,54 +636,216 @@
err.SetErrorStringWithFormat("Couldn't get value for %s", name);
return false;
}
+
+ // The size of the type contained in addr
- if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
+ size_t addr_bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
+ size_t addr_byte_size = addr_bit_size % 8 ? ((addr_bit_size + 8) / 8) : (addr_bit_size / 8);
+
+ Value::ValueType value_type = location_value->GetValueType();
+
+ switch (value_type)
{
- lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
-
- size_t bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
- size_t byte_size = bit_size % 8 ? ((bit_size + 8) / 8) : (bit_size / 8);
-
- DataBufferHeap data;
- data.SetByteSize(byte_size);
-
- lldb::addr_t src_addr;
- lldb::addr_t dest_addr;
-
- if (dematerialize)
+ default:
{
- src_addr = addr;
- dest_addr = value_addr;
- }
- else
- {
- src_addr = value_addr;
- dest_addr = addr;
+ StreamString ss;
+
+ location_value->Dump(&ss);
+
+ err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name, ss.GetString().c_str());
+ return false;
}
-
- Error error;
- if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), byte_size, error) != byte_size)
+ break;
+ case Value::eValueTypeLoadAddress:
{
- err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
- return false;
+ lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
+
+ DataBufferHeap data;
+ data.SetByteSize(addr_byte_size);
+
+ lldb::addr_t src_addr;
+ lldb::addr_t dest_addr;
+
+ if (dematerialize)
+ {
+ src_addr = addr;
+ dest_addr = value_addr;
+ }
+ else
+ {
+ src_addr = value_addr;
+ dest_addr = addr;
+ }
+
+ Error error;
+ if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
+ {
+ err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name, error.AsCString());
+ return false;
+ }
+
+ if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
+ {
+ err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", name, error.AsCString());
+ return false;
+ }
+
+ if (log)
+ log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
}
-
- if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), byte_size, error) != byte_size)
+ break;
+ case Value::eValueTypeScalar:
{
- err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
- return false;
+ if (location_value->GetContextType() != Value::eContextTypeDCRegisterInfo)
+ {
+ StreamString ss;
+
+ location_value->Dump(&ss);
+
+ err.SetErrorStringWithFormat("%s is a scalar of unhandled type: %s", name, 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", name);
+ return false;
+ }
+
+ RegisterContext *register_context = exe_ctx.GetRegisterContext();
+
+ if (!register_context)
+ {
+ err.SetErrorStringWithFormat("Couldn't read register context to read %s from %s", name, register_info->name);
+ return false;
+ }
+
+ uint32_t register_number = register_info->kinds[lldb::eRegisterKindLLDB];
+ uint32_t register_byte_size = register_info->byte_size;
+
+ if (dematerialize)
+ {
+ // Moving from addr into a register
+ //
+ // Case 1: addr_byte_size and register_byte_size are the same
+ //
+ // |AABBCCDD| Address contents
+ // |AABBCCDD| Register contents
+ //
+ // Case 2: addr_byte_size is bigger than register_byte_size
+ //
+ // Error! (The register should always be big enough to hold the data)
+ //
+ // Case 3: register_byte_size is bigger than addr_byte_size
+ //
+ // |AABB| Address contents
+ // |AABB0000| Register contents [on little-endian hardware]
+ // |0000AABB| Register contents [on big-endian hardware]
+
+ if (addr_byte_size > register_byte_size)
+ {
+ err.SetErrorStringWithFormat("%s is too big to store in %s", name, register_info->name);
+ return false;
+ }
+
+ uint32_t register_offset;
+
+ switch (exe_ctx.process->GetByteOrder())
+ {
+ default:
+ err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name);
+ return false;
+ case lldb::eByteOrderLittle:
+ register_offset = 0;
+ break;
+ case lldb::eByteOrderBig:
+ register_offset = register_byte_size - addr_byte_size;
+ break;
+ }
+
+ DataBufferHeap register_data (register_byte_size, 0);
+
+ Error error;
+ if (exe_ctx.process->ReadMemory (addr, register_data.GetBytes() + register_offset, addr_byte_size, error) != addr_byte_size)
+ {
+ err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name, error.AsCString());
+ return false;
+ }
+
+ DataExtractor register_extractor (register_data.GetBytes(), register_byte_size, exe_ctx.process->GetByteOrder(), exe_ctx.process->GetAddressByteSize());
+
+ if (!register_context->WriteRegisterBytes(register_number, register_extractor, 0))
+ {
+ err.SetErrorStringWithFormat("Couldn't read %s from %s", name, register_info->name);
+ return false;
+ }
+ }
+ else
+ {
+ // Moving from a register into addr
+ //
+ // Case 1: addr_byte_size and register_byte_size are the same
+ //
+ // |AABBCCDD| Register contents
+ // |AABBCCDD| Address contents
+ //
+ // Case 2: addr_byte_size is bigger than register_byte_size
+ //
+ // Error! (The register should always be big enough to hold the data)
+ //
+ // Case 3: register_byte_size is bigger than addr_byte_size
+ //
+ // |AABBCCDD| Register contents
+ // |AABB| Address contents on little-endian hardware
+ // |CCDD| Address contents on big-endian hardware
+
+ if (addr_byte_size > register_byte_size)
+ {
+ err.SetErrorStringWithFormat("%s is too big to store in %s", name, register_info->name);
+ return false;
+ }
+
+ uint32_t register_offset;
+
+ switch (exe_ctx.process->GetByteOrder())
+ {
+ default:
+ err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name);
+ return false;
+ case lldb::eByteOrderLittle:
+ register_offset = 0;
+ break;
+ case lldb::eByteOrderBig:
+ register_offset = register_byte_size - addr_byte_size;
+ break;
+ }
+
+ DataExtractor register_extractor;
+
+ if (!register_context->ReadRegisterBytes(register_number, register_extractor))
+ {
+ err.SetErrorStringWithFormat("Couldn't read %s from %s", name, register_info->name);
+ return false;
+ }
+
+ const void *register_data = register_extractor.GetData(®ister_offset, addr_byte_size);
+
+ if (!register_data)
+ {
+ err.SetErrorStringWithFormat("Read but couldn't extract data for %s from %s", name, register_info->name);
+ return false;
+ }
+
+ Error error;
+ if (exe_ctx.process->WriteMemory (addr, register_data, addr_byte_size, error) != addr_byte_size)
+ {
+ err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", error.AsCString());
+ return false;
+ }
+ }
}
-
- if (log)
- log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
- }
- else
- {
- StreamString ss;
-
- location_value->Dump(&ss);
-
- err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name, ss.GetString().c_str());
}
return true;
More information about the lldb-commits
mailing list