summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core/ValueObject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Core/ValueObject.cpp')
-rw-r--r--lldb/source/Core/ValueObject.cpp159
1 files changed, 74 insertions, 85 deletions
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 46feb995573..e02dda7f7e3 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -252,6 +252,15 @@ ValueObject::UpdateFormatsIfNeeded(lldb::DynamicValueType use_dynamic)
}
}
+void
+ValueObject::SetNeedsUpdate ()
+{
+ m_update_point.SetNeedsUpdate();
+ // We have to clear the value string here so ConstResult children will notice if their values are
+ // changed by hand (i.e. with SetValueAsCString).
+ m_value_str.clear();
+}
+
DataExtractor &
ValueObject::GetDataExtractor ()
{
@@ -338,7 +347,8 @@ ValueObject::ResolveValue (Scalar &scalar)
ExecutionContextScope *exe_scope = GetExecutionContextScope();
if (exe_scope)
exe_scope->CalculateExecutionContext(exe_ctx);
- scalar = m_value.ResolveValue(&exe_ctx, GetClangAST ());
+ Value tmp_value(m_value);
+ scalar = tmp_value.ResolveValue(&exe_ctx, GetClangAST ());
return scalar.IsValid();
}
else
@@ -1220,104 +1230,83 @@ ValueObject::SetValueFromCString (const char *value_str)
uint32_t count = 0;
lldb::Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
- char *end = NULL;
const size_t byte_size = GetByteSize();
- switch (encoding)
- {
- case eEncodingInvalid:
- return false;
- case eEncodingUint:
- if (byte_size > sizeof(unsigned long long))
- {
- return false;
- }
- else
+ Value::ValueType value_type = m_value.GetValueType();
+
+ if (value_type == Value::eValueTypeScalar)
+ {
+ // If the value is already a scalar, then let the scalar change itself:
+ m_value.GetScalar().SetValueFromCString (value_str, encoding, byte_size);
+ }
+ else if (byte_size <= Scalar::GetMaxByteSize())
+ {
+ // If the value fits in a scalar, then make a new scalar and again let the
+ // scalar code do the conversion, then figure out where to put the new value.
+ Scalar new_scalar;
+ Error error;
+ error = new_scalar.SetValueFromCString (value_str, encoding, byte_size);
+ if (error.Success())
{
- unsigned long long ull_val = strtoull(value_str, &end, 0);
- if (end && *end != '\0')
- return false;
- Value::ValueType value_type = m_value.GetValueType();
switch (value_type)
{
- case Value::eValueTypeLoadAddress:
- case Value::eValueTypeHostAddress:
- // The value in these cases lives in the data. So update the data:
-
- break;
- case Value::eValueTypeScalar:
- m_value.GetScalar() = ull_val;
+ 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.
+ ProcessSP process_sp = GetUpdatePoint().GetProcessSP();
+ if (process_sp)
+ {
+ lldb::addr_t target_addr = m_value.GetScalar().GetRawBits64(LLDB_INVALID_ADDRESS);
+ size_t bytes_written = process_sp->WriteScalarToMemory (target_addr,
+ new_scalar,
+ byte_size,
+ error);
+ if (!error.Success() || bytes_written != byte_size)
+ return false;
+ }
+ }
break;
- case Value::eValueTypeFileAddress:
- // Try to convert the file address to a load address and then write the new value there.
+ case Value::eValueTypeHostAddress:
+ {
+ // If it is a host address, then we stuff the scalar as a DataBuffer into the Value's data.
+ DataExtractor new_data;
+ new_data.SetByteOrder (m_data.GetByteOrder());
+
+ DataBufferSP buffer_sp (new DataBufferHeap(byte_size, 0));
+ m_data.SetData(buffer_sp, 0);
+ bool success = new_scalar.GetData(new_data);
+ if (success)
+ {
+ new_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::eValueTypeScalar:
+ break;
}
- // Limit the bytes in our m_data appropriately.
- m_value.GetScalar().GetData (m_data, byte_size);
- }
- break;
-
- case eEncodingSint:
- if (byte_size > sizeof(long long))
- {
- return false;
}
else
{
- long long sll_val = strtoll(value_str, &end, 0);
- if (end && *end != '\0')
- return false;
- m_value.GetScalar() = sll_val;
- // Limit the bytes in our m_data appropriately.
- m_value.GetScalar().GetData (m_data, byte_size);
- }
- break;
-
- case eEncodingIEEE754:
- {
- const off_t byte_offset = GetByteOffset();
- uint8_t *dst = const_cast<uint8_t *>(m_data.PeekData(byte_offset, byte_size));
- if (dst != NULL)
- {
- // We are decoding a float into host byte order below, so make
- // sure m_data knows what it contains.
- m_data.SetByteOrder(lldb::endian::InlHostByteOrder());
- const size_t converted_byte_size = ClangASTContext::ConvertStringToFloatValue (
- GetClangAST(),
- GetClangType(),
- value_str,
- dst,
- byte_size);
-
- if (converted_byte_size == byte_size)
- {
- }
- }
+ return false;
}
- break;
-
- case eEncodingVector:
- return false;
-
- default:
+ }
+ else
+ {
+ // We don't support setting things bigger than a scalar at present.
return false;
}
-
- // If we have made it here the value is in m_data and we should write it
- // out to the target
- return Write ();
-}
-
-bool
-ValueObject::Write ()
-{
- // Clear the update ID so the next time we try and read the value
- // we try and read it again.
- m_update_point.SetNeedsUpdate();
-
- // TODO: when Value has a method to write a value back, call it from here.
- return false;
-
+
+ // If we have reached this point, then we have successfully changed the value.
+ SetNeedsUpdate();
+ return true;
}
lldb::LanguageType
OpenPOWER on IntegriCloud