forked from OSchip/llvm-project
Miscellaneous fixes for big-endian systems
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. Differential Revision: http://reviews.llvm.org/D18983 llvm-svn: 266313
This commit is contained in:
parent
461bd680c3
commit
0501eebda6
|
@ -237,11 +237,12 @@ class StdVectorSynthProvider:
|
|||
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:
|
||||
|
|
|
@ -192,6 +192,14 @@ lldb_private::formatters::WCharSummaryProvider (ValueObject& valobj, Stream& str
|
|||
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);
|
||||
|
@ -200,5 +208,17 @@ lldb_private::formatters::WCharSummaryProvider (ValueObject& valobj, Stream& str
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -6075,8 +6075,9 @@ ClangASTContext::GetChildCompilerTypeAtIndex (lldb::opaque_compiler_type_t type,
|
|||
{
|
||||
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;
|
||||
|
|
|
@ -2437,7 +2437,7 @@ Process::ReadStringFromMemory (addr_t addr, char *dst, size_t max_bytes, Error &
|
|||
// 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;
|
||||
|
|
Loading…
Reference in New Issue