diff options
author | Greg Clayton <gclayton@apple.com> | 2016-05-31 22:29:56 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2016-05-31 22:29:56 +0000 |
commit | 892fa7dbcb631c5af36949ec16af4530e2b44eaf (patch) | |
tree | ab1cef061f31e512f3f6a6a048f5e870de4342aa | |
parent | ed0b620a653091f225743ce790d260b1d6f6a97e (diff) | |
download | bcm5719-llvm-892fa7dbcb631c5af36949ec16af4530e2b44eaf.tar.gz bcm5719-llvm-892fa7dbcb631c5af36949ec16af4530e2b44eaf.zip |
Add more verification on consectutive bitfields otherwise clang will assert.
We need to verify that consecutive bitfields have higher offsets and don't overlap. The issues was found by running a broken version of recent clangs where the bitfield offsets were being emitted incorrectly. To guard against this we now verify and toss out any invalid bitfields and print a message that indicates to file a bug against the compiler.
<rdar://problem/25737621>
llvm-svn: 271343
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp | 52 |
1 files changed, 35 insertions, 17 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index ef434ee0393..41bdce53d44 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -99,9 +99,9 @@ struct BitfieldInfo uint64_t bit_size; uint64_t bit_offset; - BitfieldInfo () : - bit_size (LLDB_INVALID_ADDRESS), - bit_offset (LLDB_INVALID_ADDRESS) + BitfieldInfo() : + bit_size(LLDB_INVALID_ADDRESS), + bit_offset(LLDB_INVALID_ADDRESS) { } @@ -112,10 +112,28 @@ struct BitfieldInfo bit_offset = LLDB_INVALID_ADDRESS; } - bool IsValid () + bool + IsValid() const { return (bit_size != LLDB_INVALID_ADDRESS) && - (bit_offset != LLDB_INVALID_ADDRESS); + (bit_offset != LLDB_INVALID_ADDRESS); + } + + bool + NextBitfieldOffsetIsValid(const uint64_t next_bit_offset) const + { + if (IsValid()) + { + // This bitfield info is valid, so any subsequent bitfields + // must not overlap and must be at a higher bit offset than + // any previous bitfield + size. + return (bit_size + bit_offset) <= next_bit_offset; + } + else + { + // If the this BitfieldInfo is not valid, then any offset isOK + return true; + } } }; @@ -2965,24 +2983,24 @@ DWARFASTParserClang::ParseChildMembers(const SymbolContext &sc, const DWARFDIE & { this_field_info.bit_offset += byte_size * 8; this_field_info.bit_offset -= (bit_offset + bit_size); - - if (this_field_info.bit_offset >= parent_bit_size) - { - objfile->GetModule()->ReportWarning("0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid bit offset (0x%8.8" PRIx64 ") member will be ignored. Please file a bug against the compiler and include the preprocessed output for %s\n", - die.GetID(), - DW_TAG_value_to_name(tag), - name, - this_field_info.bit_offset, - sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file"); - this_field_info.Clear(); - continue; - } } else { this_field_info.bit_offset += bit_offset; } + if ((this_field_info.bit_offset >= parent_bit_size) || !last_field_info.NextBitfieldOffsetIsValid(this_field_info.bit_offset)) + { + objfile->GetModule()->ReportWarning("0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid bit offset (0x%8.8" PRIx64 ") member will be ignored. Please file a bug against the compiler and include the preprocessed output for %s\n", + die.GetID(), + DW_TAG_value_to_name(tag), + name, + this_field_info.bit_offset, + sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file"); + this_field_info.Clear(); + continue; + } + // Update the field bit offset we will report for layout field_bit_offset = this_field_info.bit_offset; |