cameron314 created this revision.
cameron314 added reviewers: spyffe, zturner, clayborg.
cameron314 added a subscriber: lldb-commits.
The `EntityVariable` materializer was, under certain conditions, taking the
bytes of a `DataExtractor` that were potentially in host order (e.g. little
endian) and putting them in the `IRMemoryMap` (which assumes all values are in
target order, e.g. big endian). This caused certain values to have the wrong
endianness during expression evaluation.
On our platform, this manifested as certain expressions yielding incorrect
results when the variables were in registers (e.g. `argc + 1` would give
`0x0101`).
http://reviews.llvm.org/D21328
Files:
include/lldb/Expression/IRMemoryMap.h
source/Expression/IRMemoryMap.cpp
source/Expression/Materializer.cpp
Index: source/Expression/Materializer.cpp
===
--- source/Expression/Materializer.cpp
+++ source/Expression/Materializer.cpp
@@ -575,7 +575,7 @@
Error write_error;
-map.WriteMemory(m_temporary_allocation, data.GetDataStart(),
data.GetByteSize(), write_error);
+map.WriteMemory(m_temporary_allocation, data.GetDataStart(),
data.GetByteSize(), data.GetByteOrder(), write_error);
if (!write_error.Success())
{
Index: source/Expression/IRMemoryMap.cpp
===
--- source/Expression/IRMemoryMap.cpp
+++ source/Expression/IRMemoryMap.cpp
@@ -564,6 +564,22 @@
}
void
+IRMemoryMap::WriteMemory(lldb::addr_t process_address, const uint8_t *bytes,
size_t size, lldb::ByteOrder byteOrder, Error &error)
+{
+std::vector temp;
+if (byteOrder != GetByteOrder())
+{
+// Need to byte-swap the bytes before putting them in the map,
otherwise they'll
+// be interpreted with the wrong endianness when they're read back out.
+temp.reserve(size);
+typedef std::reverse_iterator revit;
+temp.assign(revit(bytes + size), revit(bytes));
+bytes = temp.data();
+}
+WriteMemory(process_address, bytes, size, error);
+}
+
+void
IRMemoryMap::WriteMemory (lldb::addr_t process_address, const uint8_t *bytes,
size_t size, Error &error)
{
error.Clear();
Index: include/lldb/Expression/IRMemoryMap.h
===
--- include/lldb/Expression/IRMemoryMap.h
+++ include/lldb/Expression/IRMemoryMap.h
@@ -60,6 +60,7 @@
void Free (lldb::addr_t process_address, Error &error);
void WriteMemory (lldb::addr_t process_address, const uint8_t *bytes,
size_t size, Error &error);
+void WriteMemory (lldb::addr_t process_address, const uint8_t *bytes,
size_t size, lldb::ByteOrder order, Error &error);
void WriteScalarToMemory (lldb::addr_t process_address, Scalar &scalar,
size_t size, Error &error);
void WritePointerToMemory (lldb::addr_t process_address, lldb::addr_t
address, Error &error);
void ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t
size, Error &error);
Index: source/Expression/Materializer.cpp
===
--- source/Expression/Materializer.cpp
+++ source/Expression/Materializer.cpp
@@ -575,7 +575,7 @@
Error write_error;
-map.WriteMemory(m_temporary_allocation, data.GetDataStart(), data.GetByteSize(), write_error);
+map.WriteMemory(m_temporary_allocation, data.GetDataStart(), data.GetByteSize(), data.GetByteOrder(), write_error);
if (!write_error.Success())
{
Index: source/Expression/IRMemoryMap.cpp
===
--- source/Expression/IRMemoryMap.cpp
+++ source/Expression/IRMemoryMap.cpp
@@ -564,6 +564,22 @@
}
void
+IRMemoryMap::WriteMemory(lldb::addr_t process_address, const uint8_t *bytes, size_t size, lldb::ByteOrder byteOrder, Error &error)
+{
+std::vector temp;
+if (byteOrder != GetByteOrder())
+{
+// Need to byte-swap the bytes before putting them in the map, otherwise they'll
+// be interpreted with the wrong endianness when they're read back out.
+temp.reserve(size);
+typedef std::reverse_iterator revit;
+temp.assign(revit(bytes + size), revit(bytes));
+bytes = temp.data();
+}
+WriteMemory(process_address, bytes, size, error);
+}
+
+void
IRMemoryMap::WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, size_t size, Error &error)
{
error.Clear();
Index: include/lldb/Expression/IRMemoryMap.h
===
--- include/lldb/Expression/IRMemoryMap.h
+++ include/lldb/Expression/IRMemoryMap.h
@@ -60,6 +60,7 @@
void Free (lldb::addr_t process_address, Error &error);
void WriteMemory (lldb::addr_t process_address, const