summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core/ValueObject.cpp
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2013-04-13 01:21:23 +0000
committerSean Callanan <scallanan@apple.com>2013-04-13 01:21:23 +0000
commit389823e99594aa3a06f5b6218d07252f7ce0d567 (patch)
treecd128f9228a9755b37b08401f9ec2d82df9ec80a /lldb/source/Core/ValueObject.cpp
parent53a65587714c6cb65f428cd283f2bb77aee6d784 (diff)
downloadbcm5719-llvm-389823e99594aa3a06f5b6218d07252f7ce0d567.tar.gz
bcm5719-llvm-389823e99594aa3a06f5b6218d07252f7ce0d567.zip
Added a SetData() method to ValueObject. This
lets a ValueObject's contents be set from raw data. This has certain limitations (notably, registers can only be set to data that is as large as the register) but will be useful for the new Materializer. I also exposed this interface through SBValue. I have added a testcase that exercises various special cases of SBValue::SetData(). llvm-svn: 179437
Diffstat (limited to 'lldb/source/Core/ValueObject.cpp')
-rw-r--r--lldb/source/Core/ValueObject.cpp78
1 files changed, 78 insertions, 0 deletions
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index dcc9e0e8265..19dfdee5b2a 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -1013,6 +1013,84 @@ ValueObject::GetData (DataExtractor& data)
return data.GetByteSize();
}
+bool
+ValueObject::SetData (DataExtractor &data, Error &error)
+{
+ error.Clear();
+ // Make sure our value is up to date first so that our location and location
+ // type is valid.
+ if (!UpdateValueIfNeeded(false))
+ {
+ error.SetErrorString("unable to read value");
+ return false;
+ }
+
+ uint64_t count = 0;
+ Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
+
+ const size_t byte_size = GetByteSize();
+
+ Value::ValueType value_type = m_value.GetValueType();
+
+ switch (value_type)
+ {
+ case Value::eValueTypeScalar:
+ {
+ Error set_error = m_value.GetScalar().SetValueFromData(data, encoding, byte_size);
+
+ if (!set_error.Success())
+ {
+ error.SetErrorStringWithFormat("unable to set scalar value: %s", set_error.AsCString());
+ return false;
+ }
+ }
+ break;
+ case Value::eValueTypeLoadAddress:
+ {
+ // If it is a load address, then the scalar value is the storage location
+ // of the data, and we have to shove this value down to that load location.
+ ExecutionContext exe_ctx (GetExecutionContextRef());
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process)
+ {
+ addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ size_t bytes_written = process->WriteMemory(target_addr,
+ data.GetDataStart(),
+ byte_size,
+ error);
+ if (!error.Success())
+ return false;
+ if (bytes_written != byte_size)
+ {
+ error.SetErrorString("unable to write value to memory");
+ return false;
+ }
+ }
+ }
+ break;
+ case Value::eValueTypeHostAddress:
+ {
+ // If it is a host address, then we stuff the scalar as a DataBuffer into the Value's data.
+ DataBufferSP buffer_sp (new DataBufferHeap(byte_size, 0));
+ m_data.SetData(buffer_sp, 0);
+ data.CopyByteOrderedData (0,
+ byte_size,
+ const_cast<uint8_t *>(m_data.GetDataStart()),
+ byte_size,
+ m_data.GetByteOrder());
+ m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
+ }
+ break;
+ case Value::eValueTypeFileAddress:
+ case Value::eValueTypeVector:
+ break;
+ }
+
+ // If we have reached this point, then we have successfully changed the value.
+ SetNeedsUpdate();
+ return true;
+}
+
// will compute strlen(str), but without consuming more than
// maxlen bytes out of str (this serves the purpose of reading
// chunks of a string without having to worry about
OpenPOWER on IntegriCloud