[Lldb-commits] [PATCH] D18983: Miscellaneous fixes for big-endian systems
Ulrich Weigand via lldb-commits
lldb-commits at lists.llvm.org
Mon Apr 11 11:45:07 PDT 2016
uweigand created this revision.
uweigand added reviewers: clayborg, granata.enrico, spyffe.
uweigand added a subscriber: lldb-commits.
This patch fixes a bunch of issues that show up on big-endian systems:
- The gnu_libstdcpp.py script doesn't follow the way libstdc++ encodes
bit vectors: it should identify the enclosing *word* and then access
the appropriate bit within that word. Instead, the script simply
operates on bytes. This gives the same result on little-endian
systems, but not on big-endian.
- lldb_private::formatters::WCharSummaryProvider always assumes wchar_t
is UTF16, even though it could also be UTF8 or UTF32. This is mostly
not an issue on little-endian systems, but immediately fails on BE.
Fixed by checking the size of wchar_t like WCharStringSummaryProvider
already does.
- ClangASTContext::GetChildCompilerTypeAtIndex uses uint32_t to access
the virtual base offset stored in the vtable, even though the size
of this field matches the target pointer size according to the C++
ABI. Again, this is mostly not visible on LE, but fails on BE.
- Process::ReadStringFromMemory uses strncmp to search for a terminator
consisting of multiple zero bytes. This doesn't work since strncmp
will stop already at the first zero byte. Use memcmp instead.
http://reviews.llvm.org/D18983
Files:
examples/synthetic/gnu_libstdcpp.py
source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
source/Symbol/ClangASTContext.cpp
source/Target/Process.cpp
Index: source/Target/Process.cpp
===================================================================
--- source/Target/Process.cpp
+++ source/Target/Process.cpp
@@ -2437,7 +2437,7 @@
// Search for a null terminator of correct size and alignment in bytes_read
size_t aligned_start = total_bytes_read - total_bytes_read % type_width;
for (size_t i = aligned_start; i + type_width <= total_bytes_read + bytes_read; i += type_width)
- if (::strncmp(&dst[i], terminator, type_width) == 0)
+ if (::memcmp(&dst[i], terminator, type_width) == 0)
{
error.Clear();
return i;
Index: source/Symbol/ClangASTContext.cpp
===================================================================
--- source/Symbol/ClangASTContext.cpp
+++ source/Symbol/ClangASTContext.cpp
@@ -6038,8 +6038,9 @@
{
clang::CharUnits base_offset_offset = itanium_vtable_ctx->getVirtualBaseOffsetOffset(cxx_record_decl, base_class_decl);
const lldb::addr_t base_offset_addr = vtable_ptr + base_offset_offset.getQuantity();
- const uint32_t base_offset = process->ReadUnsignedIntegerFromMemory(base_offset_addr, 4, UINT32_MAX, err);
- if (base_offset != UINT32_MAX)
+ const uint32_t base_offset_size = process->GetAddressByteSize();
+ const uint64_t base_offset = process->ReadUnsignedIntegerFromMemory(base_offset_addr, base_offset_size, UINT32_MAX, err);
+ if (base_offset < UINT32_MAX)
{
handled = true;
bit_offset = base_offset * 8;
Index: source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
===================================================================
--- source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
+++ source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
@@ -192,13 +192,33 @@
if (error.Fail())
return false;
+ // Get a wchar_t basic type from the current type system
+ CompilerType wchar_compiler_type = valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);
+
+ if (!wchar_compiler_type)
+ return false;
+
+ const uint32_t wchar_size = wchar_compiler_type.GetBitSize(nullptr); // Safe to pass NULL for exe_scope here
+
StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
options.SetData(data);
options.SetStream(&stream);
options.SetPrefixToken("L");
options.SetQuote('\'');
options.SetSourceSize(1);
options.SetBinaryZeroIsTerminator(false);
- return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF16>(options);
+ switch (wchar_size)
+ {
+ case 8:
+ return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF8>(options);
+ case 16:
+ return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF16>(options);
+ case 32:
+ return StringPrinter::ReadBufferAndDumpToStream<StringPrinter::StringElementType::UTF32>(options);
+ default:
+ stream.Printf("size for wchar_t is not valid");
+ return true;
+ }
+ return true;
}
Index: examples/synthetic/gnu_libstdcpp.py
===================================================================
--- examples/synthetic/gnu_libstdcpp.py
+++ examples/synthetic/gnu_libstdcpp.py
@@ -237,11 +237,12 @@
def get_child_at_index(self, index):
if index >= self.num_children():
return None
- byte_offset = index / 8
- bit_offset = index % 8
- element_size = self.start_p.GetType().GetPointeeType().GetByteSize()
- data = self.start_p.GetPointeeData(byte_offset / element_size)
- bit = data.GetUnsignedInt8(lldb.SBError(), byte_offset % element_size) & (1 << bit_offset)
+ element_type = self.start_p.GetType().GetPointeeType()
+ element_bits = 8 * element_type.GetByteSize()
+ element_offset = index / element_bits
+ bit_offset = index % element_bits
+ element = self.start_p.CreateChildAtOffset('['+str(index)+']',element_offset,element_type)
+ bit = element.GetValueAsUnsigned(0) & (1 << bit_offset)
if bit != 0:
value_expr = "(bool)true"
else:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D18983.53299.patch
Type: text/x-patch
Size: 4780 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20160411/58a475e2/attachment-0001.bin>
More information about the lldb-commits
mailing list