diff options
Diffstat (limited to 'unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp')
| -rw-r--r-- | unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp | 992 |
1 files changed, 913 insertions, 79 deletions
diff --git a/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp b/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp index 6ffb710d2549..cb7bf82d86f6 100644 --- a/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp +++ b/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp @@ -14,27 +14,24 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/BinaryFormat/Dwarf.h" -#include "llvm/Config/llvm-config.h" #include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/Config/llvm-config.h" #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/DebugInfo/DWARF/DWARFDie.h" #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" +#include "llvm/DebugInfo/DWARF/DWARFVerifier.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/Object/ObjectFile.h" #include "llvm/ObjectYAML/DWARFEmitter.h" -#include "llvm/ObjectYAML/DWARFYAML.h" #include "llvm/Support/Error.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/TargetSelect.h" #include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/TargetSelect.h" #include "llvm/Testing/Support/Error.h" #include "gtest/gtest.h" -#include <climits> -#include <cstdint> -#include <cstring> #include <string> using namespace llvm; @@ -85,6 +82,8 @@ void TestAllForms() { const uint32_t Data4 = 0x6789abcdU; const uint64_t Data8 = 0x0011223344556677ULL; const uint64_t Data8_2 = 0xAABBCCDDEEFF0011ULL; + const uint8_t Data16[16] = {1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16}; const int64_t SData = INT64_MIN; const int64_t ICSData = INT64_MAX; // DW_FORM_implicit_const SData const uint64_t UData[] = {UINT64_MAX - 1, UINT64_MAX - 2, UINT64_MAX - 3, @@ -123,6 +122,11 @@ void TestAllForms() { const auto Attr_DW_FORM_block4 = static_cast<dwarf::Attribute>(Attr++); CUDie.addAttribute(Attr_DW_FORM_block4, DW_FORM_block4, BlockData, BlockSize); + // We handle data16 as a block form. + const auto Attr_DW_FORM_data16 = static_cast<dwarf::Attribute>(Attr++); + if (Version >= 5) + CUDie.addAttribute(Attr_DW_FORM_data16, DW_FORM_data16, Data16, 16); + //---------------------------------------------------------------------- // Test data forms //---------------------------------------------------------------------- @@ -228,10 +232,10 @@ void TestAllForms() { MemoryBufferRef FileBuffer(FileBytes, "dwarf"); auto Obj = object::ObjectFile::createObjectFile(FileBuffer); EXPECT_TRUE((bool)Obj); - DWARFContextInMemory DwarfContext(*Obj.get()); - uint32_t NumCUs = DwarfContext.getNumCompileUnits(); + std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj); + uint32_t NumCUs = DwarfContext->getNumCompileUnits(); EXPECT_EQ(NumCUs, 1u); - DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0); + DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0); auto DieDG = U->getUnitDIE(false); EXPECT_TRUE(DieDG.isValid()); @@ -279,6 +283,17 @@ void TestAllForms() { EXPECT_EQ(ExtractedBlockData.size(), BlockSize); EXPECT_TRUE(memcmp(ExtractedBlockData.data(), BlockData, BlockSize) == 0); + // Data16 is handled like a block. + if (Version >= 5) { + FormValue = DieDG.find(Attr_DW_FORM_data16); + EXPECT_TRUE((bool)FormValue); + BlockDataOpt = FormValue->getAsBlock(); + EXPECT_TRUE(BlockDataOpt.hasValue()); + ExtractedBlockData = BlockDataOpt.getValue(); + EXPECT_EQ(ExtractedBlockData.size(), 16u); + EXPECT_TRUE(memcmp(ExtractedBlockData.data(), Data16, 16) == 0); + } + //---------------------------------------------------------------------- // Test data forms //---------------------------------------------------------------------- @@ -458,12 +473,12 @@ template <uint16_t Version, class AddrType> void TestChildren() { MemoryBufferRef FileBuffer(FileBytes, "dwarf"); auto Obj = object::ObjectFile::createObjectFile(FileBuffer); EXPECT_TRUE((bool)Obj); - DWARFContextInMemory DwarfContext(*Obj.get()); + std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj); // Verify the number of compile units is correct. - uint32_t NumCUs = DwarfContext.getNumCompileUnits(); + uint32_t NumCUs = DwarfContext->getNumCompileUnits(); EXPECT_EQ(NumCUs, 1u); - DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0); + DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0); // Get the compile unit DIE is valid. auto DieDG = U->getUnitDIE(false); @@ -629,13 +644,13 @@ template <uint16_t Version, class AddrType> void TestReferences() { MemoryBufferRef FileBuffer(FileBytes, "dwarf"); auto Obj = object::ObjectFile::createObjectFile(FileBuffer); EXPECT_TRUE((bool)Obj); - DWARFContextInMemory DwarfContext(*Obj.get()); + std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj); // Verify the number of compile units is correct. - uint32_t NumCUs = DwarfContext.getNumCompileUnits(); + uint32_t NumCUs = DwarfContext->getNumCompileUnits(); EXPECT_EQ(NumCUs, 2u); - DWARFCompileUnit *U1 = DwarfContext.getCompileUnitAtIndex(0); - DWARFCompileUnit *U2 = DwarfContext.getCompileUnitAtIndex(1); + DWARFCompileUnit *U1 = DwarfContext->getCompileUnitAtIndex(0); + DWARFCompileUnit *U2 = DwarfContext->getCompileUnitAtIndex(1); // Get the compile unit DIE is valid. auto Unit1DieDG = U1->getUnitDIE(false); @@ -837,12 +852,12 @@ template <uint16_t Version, class AddrType> void TestAddresses() { MemoryBufferRef FileBuffer(FileBytes, "dwarf"); auto Obj = object::ObjectFile::createObjectFile(FileBuffer); EXPECT_TRUE((bool)Obj); - DWARFContextInMemory DwarfContext(*Obj.get()); + std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj); // Verify the number of compile units is correct. - uint32_t NumCUs = DwarfContext.getNumCompileUnits(); + uint32_t NumCUs = DwarfContext->getNumCompileUnits(); EXPECT_EQ(NumCUs, 1u); - DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0); + DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0); // Get the compile unit DIE is valid. auto DieDG = U->getUnitDIE(false); @@ -1012,12 +1027,12 @@ TEST(DWARFDebugInfo, TestRelations) { MemoryBufferRef FileBuffer(DG->generate(), "dwarf"); auto Obj = object::ObjectFile::createObjectFile(FileBuffer); EXPECT_TRUE((bool)Obj); - DWARFContextInMemory DwarfContext(*Obj.get()); + std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj); // Verify the number of compile units is correct. - uint32_t NumCUs = DwarfContext.getNumCompileUnits(); + uint32_t NumCUs = DwarfContext->getNumCompileUnits(); EXPECT_EQ(NumCUs, 1u); - DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0); + DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0); // Get the compile unit DIE is valid. auto CUDie = U->getUnitDIE(false); @@ -1127,12 +1142,12 @@ TEST(DWARFDebugInfo, TestChildIterators) { MemoryBufferRef FileBuffer(DG->generate(), "dwarf"); auto Obj = object::ObjectFile::createObjectFile(FileBuffer); EXPECT_TRUE((bool)Obj); - DWARFContextInMemory DwarfContext(*Obj.get()); + std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj); // Verify the number of compile units is correct. - uint32_t NumCUs = DwarfContext.getNumCompileUnits(); + uint32_t NumCUs = DwarfContext->getNumCompileUnits(); EXPECT_EQ(NumCUs, 1u); - DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0); + DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0); // Get the compile unit DIE is valid. auto CUDie = U->getUnitDIE(false); @@ -1188,12 +1203,13 @@ TEST(DWARFDebugInfo, TestEmptyChildren) { auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata)); ASSERT_TRUE((bool)ErrOrSections); - DWARFContextInMemory DwarfContext(*ErrOrSections, 8); + std::unique_ptr<DWARFContext> DwarfContext = + DWARFContext::create(*ErrOrSections, 8); // Verify the number of compile units is correct. - uint32_t NumCUs = DwarfContext.getNumCompileUnits(); + uint32_t NumCUs = DwarfContext->getNumCompileUnits(); EXPECT_EQ(NumCUs, 1u); - DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0); + DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0); // Get the compile unit DIE is valid. auto CUDie = U->getUnitDIE(false); @@ -1235,12 +1251,12 @@ TEST(DWARFDebugInfo, TestAttributeIterators) { MemoryBufferRef FileBuffer(DG->generate(), "dwarf"); auto Obj = object::ObjectFile::createObjectFile(FileBuffer); EXPECT_TRUE((bool)Obj); - DWARFContextInMemory DwarfContext(*Obj.get()); + std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj); // Verify the number of compile units is correct. - uint32_t NumCUs = DwarfContext.getNumCompileUnits(); + uint32_t NumCUs = DwarfContext->getNumCompileUnits(); EXPECT_EQ(NumCUs, 1u); - DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0); + DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0); // Get the compile unit DIE is valid. auto CUDie = U->getUnitDIE(false); @@ -1285,12 +1301,16 @@ TEST(DWARFDebugInfo, TestFindRecurse) { auto CUDie = CU.getUnitDIE(); auto FuncSpecDie = CUDie.addChild(DW_TAG_subprogram); auto FuncAbsDie = CUDie.addChild(DW_TAG_subprogram); + // Put the linkage name in a second abstract origin DIE to ensure we + // recurse through more than just one DIE when looking for attributes. + auto FuncAbsDie2 = CUDie.addChild(DW_TAG_subprogram); auto FuncDie = CUDie.addChild(DW_TAG_subprogram); auto VarAbsDie = CUDie.addChild(DW_TAG_variable); auto VarDie = CUDie.addChild(DW_TAG_variable); FuncSpecDie.addAttribute(DW_AT_name, DW_FORM_strp, SpecDieName); - FuncAbsDie.addAttribute(DW_AT_linkage_name, DW_FORM_strp, SpecLinkageName); + FuncAbsDie2.addAttribute(DW_AT_linkage_name, DW_FORM_strp, SpecLinkageName); FuncAbsDie.addAttribute(DW_AT_specification, DW_FORM_ref4, FuncSpecDie); + FuncAbsDie.addAttribute(DW_AT_abstract_origin, DW_FORM_ref4, FuncAbsDie2); FuncDie.addAttribute(DW_AT_abstract_origin, DW_FORM_ref4, FuncAbsDie); VarAbsDie.addAttribute(DW_AT_name, DW_FORM_strp, AbsDieName); VarDie.addAttribute(DW_AT_abstract_origin, DW_FORM_ref4, VarAbsDie); @@ -1299,12 +1319,12 @@ TEST(DWARFDebugInfo, TestFindRecurse) { MemoryBufferRef FileBuffer(DG->generate(), "dwarf"); auto Obj = object::ObjectFile::createObjectFile(FileBuffer); EXPECT_TRUE((bool)Obj); - DWARFContextInMemory DwarfContext(*Obj.get()); + std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj); // Verify the number of compile units is correct. - uint32_t NumCUs = DwarfContext.getNumCompileUnits(); + uint32_t NumCUs = DwarfContext->getNumCompileUnits(); EXPECT_EQ(NumCUs, 1u); - DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0); + DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0); // Get the compile unit DIE is valid. auto CUDie = U->getUnitDIE(false); @@ -1312,7 +1332,8 @@ TEST(DWARFDebugInfo, TestFindRecurse) { auto FuncSpecDie = CUDie.getFirstChild(); auto FuncAbsDie = FuncSpecDie.getSibling(); - auto FuncDie = FuncAbsDie.getSibling(); + auto FuncAbsDie2 = FuncAbsDie.getSibling(); + auto FuncDie = FuncAbsDie2.getSibling(); auto VarAbsDie = FuncDie.getSibling(); auto VarDie = VarAbsDie.getSibling(); @@ -1505,12 +1526,12 @@ TEST(DWARFDebugInfo, TestFindAttrs) { MemoryBufferRef FileBuffer(DG->generate(), "dwarf"); auto Obj = object::ObjectFile::createObjectFile(FileBuffer); EXPECT_TRUE((bool)Obj); - DWARFContextInMemory DwarfContext(*Obj.get()); + std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj); // Verify the number of compile units is correct. - uint32_t NumCUs = DwarfContext.getNumCompileUnits(); + uint32_t NumCUs = DwarfContext->getNumCompileUnits(); EXPECT_EQ(NumCUs, 1u); - DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0); + DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0); // Get the compile unit DIE is valid. auto CUDie = U->getUnitDIE(false); @@ -1568,8 +1589,8 @@ TEST(DWARFDebugInfo, TestImplicitConstAbbrevs) { MemoryBufferRef FileBuffer(DG->generate(), "dwarf"); auto Obj = object::ObjectFile::createObjectFile(FileBuffer); EXPECT_TRUE((bool)Obj); - DWARFContextInMemory DwarfContext(*Obj.get()); - DWARFCompileUnit *U = DwarfContext.getCompileUnitAtIndex(0); + std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj); + DWARFCompileUnit *U = DwarfContext->getCompileUnitAtIndex(0); EXPECT_TRUE((bool)U); const auto *Abbrevs = U->getAbbreviations(); @@ -1657,16 +1678,29 @@ TEST(DWARFDebugInfo, TestImplicitConstAbbrevs) { EXPECT_EQ(DIEs.find(Val2)->second, AbbrevPtrVal2); } +void VerifyWarning(DWARFContext &DwarfContext, StringRef Error) { + SmallString<1024> Str; + raw_svector_ostream Strm(Str); + EXPECT_TRUE(DwarfContext.verify(Strm)); + EXPECT_TRUE(Str.str().contains(Error)); +} + void VerifyError(DWARFContext &DwarfContext, StringRef Error) { SmallString<1024> Str; raw_svector_ostream Strm(Str); - EXPECT_FALSE(DwarfContext.verify(Strm, DIDT_All)); + EXPECT_FALSE(DwarfContext.verify(Strm)); EXPECT_TRUE(Str.str().contains(Error)); } +void VerifySuccess(DWARFContext &DwarfContext) { + SmallString<1024> Str; + raw_svector_ostream Strm(Str); + EXPECT_TRUE(DwarfContext.verify(Strm)); +} + TEST(DWARFDebugInfo, TestDwarfVerifyInvalidCURef) { // Create a single compile unit with a single function that has a DW_AT_type - // that is CU relative. The CU offset is not valid becuase it is larger than + // that is CU relative. The CU offset is not valid because it is larger than // the compile unit itself. const char *yamldata = R"( @@ -1708,10 +1742,11 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidCURef) { )"; auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata)); ASSERT_TRUE((bool)ErrOrSections); - DWARFContextInMemory DwarfContext(*ErrOrSections, 8); - VerifyError(DwarfContext, "error: DW_FORM_ref4 CU offset 0x00001234 is " - "invalid (must be less than CU size of " - "0x0000001a):"); + std::unique_ptr<DWARFContext> DwarfContext = + DWARFContext::create(*ErrOrSections, 8); + VerifyError(*DwarfContext, "error: DW_FORM_ref4 CU offset 0x00001234 is " + "invalid (must be less than CU size of " + "0x0000001a):"); } TEST(DWARFDebugInfo, TestDwarfVerifyInvalidRefAddr) { @@ -1756,8 +1791,9 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidRefAddr) { )"; auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata)); ASSERT_TRUE((bool)ErrOrSections); - DWARFContextInMemory DwarfContext(*ErrOrSections, 8); - VerifyError(DwarfContext, + std::unique_ptr<DWARFContext> DwarfContext = + DWARFContext::create(*ErrOrSections, 8); + VerifyError(*DwarfContext, "error: DW_FORM_ref_addr offset beyond .debug_info bounds:"); } @@ -1792,8 +1828,9 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidRanges) { )"; auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata)); ASSERT_TRUE((bool)ErrOrSections); - DWARFContextInMemory DwarfContext(*ErrOrSections, 8); - VerifyError(DwarfContext, + std::unique_ptr<DWARFContext> DwarfContext = + DWARFContext::create(*ErrOrSections, 8); + VerifyError(*DwarfContext, "error: DW_AT_ranges offset is beyond .debug_ranges bounds:"); } @@ -1828,9 +1865,10 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidStmtList) { )"; auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata)); ASSERT_TRUE((bool)ErrOrSections); - DWARFContextInMemory DwarfContext(*ErrOrSections, 8); + std::unique_ptr<DWARFContext> DwarfContext = + DWARFContext::create(*ErrOrSections, 8); VerifyError( - DwarfContext, + *DwarfContext, "error: DW_AT_stmt_list offset is beyond .debug_line bounds: 0x00001000"); } @@ -1860,8 +1898,9 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidStrp) { )"; auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata)); ASSERT_TRUE((bool)ErrOrSections); - DWARFContextInMemory DwarfContext(*ErrOrSections, 8); - VerifyError(DwarfContext, + std::unique_ptr<DWARFContext> DwarfContext = + DWARFContext::create(*ErrOrSections, 8); + VerifyError(*DwarfContext, "error: DW_FORM_strp offset beyond .debug_str bounds:"); } @@ -1907,9 +1946,10 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidRefAddrBetween) { )"; auto ErrOrSections = DWARFYAML::EmitDebugSections(StringRef(yamldata)); ASSERT_TRUE((bool)ErrOrSections); - DWARFContextInMemory DwarfContext(*ErrOrSections, 8); + std::unique_ptr<DWARFContext> DwarfContext = + DWARFContext::create(*ErrOrSections, 8); VerifyError( - DwarfContext, + *DwarfContext, "error: invalid DIE reference 0x00000011. Offset is in between DIEs:"); } @@ -1977,9 +2017,10 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidLineSequence) { )"; auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata); ASSERT_TRUE((bool)ErrOrSections); - DWARFContextInMemory DwarfContext(*ErrOrSections, 8); - VerifyError(DwarfContext, "error: .debug_line[0x00000000] row[1] decreases " - "in address from previous row:"); + std::unique_ptr<DWARFContext> DwarfContext = + DWARFContext::create(*ErrOrSections, 8); + VerifyError(*DwarfContext, "error: .debug_line[0x00000000] row[1] decreases " + "in address from previous row:"); } TEST(DWARFDebugInfo, TestDwarfVerifyInvalidLineFileIndex) { @@ -2048,9 +2089,160 @@ TEST(DWARFDebugInfo, TestDwarfVerifyInvalidLineFileIndex) { )"; auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata); ASSERT_TRUE((bool)ErrOrSections); - DWARFContextInMemory DwarfContext(*ErrOrSections, 8); - VerifyError(DwarfContext, "error: .debug_line[0x00000000][1] has invalid " - "file index 5 (valid values are [1,1]):"); + std::unique_ptr<DWARFContext> DwarfContext = + DWARFContext::create(*ErrOrSections, 8); + VerifyError(*DwarfContext, "error: .debug_line[0x00000000][1] has invalid " + "file index 5 (valid values are [1,1]):"); +} + +TEST(DWARFDebugInfo, TestDwarfVerifyInvalidLineTablePorlogueDirIndex) { + // Create a single compile unit whose line table has a prologue with an + // invalid dir index. + StringRef yamldata = R"( + debug_str: + - '' + - /tmp/main.c + debug_abbrev: + - Code: 0x00000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_stmt_list + Form: DW_FORM_sec_offset + debug_info: + - Length: + TotalLength: 16 + Version: 4 + AbbrOffset: 0 + AddrSize: 8 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x0000000000000001 + - Value: 0x0000000000000000 + debug_line: + - Length: + TotalLength: 61 + Version: 2 + PrologueLength: 34 + MinInstLength: 1 + DefaultIsStmt: 1 + LineBase: 251 + LineRange: 14 + OpcodeBase: 13 + StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ] + IncludeDirs: + - /tmp + Files: + - Name: main.c + DirIdx: 2 + ModTime: 0 + Length: 0 + Opcodes: + - Opcode: DW_LNS_extended_op + ExtLen: 9 + SubOpcode: DW_LNE_set_address + Data: 4096 + - Opcode: DW_LNS_advance_line + SData: 9 + Data: 4096 + - Opcode: DW_LNS_copy + Data: 4096 + - Opcode: DW_LNS_advance_pc + Data: 16 + - Opcode: DW_LNS_set_file + Data: 1 + - Opcode: DW_LNS_extended_op + ExtLen: 1 + SubOpcode: DW_LNE_end_sequence + Data: 1 + )"; + auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata); + ASSERT_TRUE((bool)ErrOrSections); + std::unique_ptr<DWARFContext> DwarfContext = + DWARFContext::create(*ErrOrSections, 8); + VerifyError(*DwarfContext, + "error: .debug_line[0x00000000].prologue." + "file_names[1].dir_idx contains an invalid index: 2"); +} + +TEST(DWARFDebugInfo, TestDwarfVerifyDuplicateFileWarning) { + // Create a single compile unit whose line table has a prologue with an + // invalid dir index. + StringRef yamldata = R"( + debug_str: + - '' + - /tmp/main.c + debug_abbrev: + - Code: 0x00000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_stmt_list + Form: DW_FORM_sec_offset + debug_info: + - Length: + TotalLength: 16 + Version: 4 + AbbrOffset: 0 + AddrSize: 8 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x0000000000000001 + - Value: 0x0000000000000000 + debug_line: + - Length: + TotalLength: 71 + Version: 2 + PrologueLength: 44 + MinInstLength: 1 + DefaultIsStmt: 1 + LineBase: 251 + LineRange: 14 + OpcodeBase: 13 + StandardOpcodeLengths: [ 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1 ] + IncludeDirs: + - /tmp + Files: + - Name: main.c + DirIdx: 1 + ModTime: 0 + Length: 0 + - Name: main.c + DirIdx: 1 + ModTime: 0 + Length: 0 + Opcodes: + - Opcode: DW_LNS_extended_op + ExtLen: 9 + SubOpcode: DW_LNE_set_address + Data: 4096 + - Opcode: DW_LNS_advance_line + SData: 9 + Data: 4096 + - Opcode: DW_LNS_copy + Data: 4096 + - Opcode: DW_LNS_advance_pc + Data: 16 + - Opcode: DW_LNS_set_file + Data: 1 + - Opcode: DW_LNS_extended_op + ExtLen: 1 + SubOpcode: DW_LNE_end_sequence + Data: 2 + )"; + auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata); + ASSERT_TRUE((bool)ErrOrSections); + std::unique_ptr<DWARFContext> DwarfContext = + DWARFContext::create(*ErrOrSections, 8); + VerifyWarning(*DwarfContext, + "warning: .debug_line[0x00000000].prologue.file_names[2] is " + "a duplicate of file_names[1]"); } TEST(DWARFDebugInfo, TestDwarfVerifyCUDontShareLineTable) { @@ -2128,10 +2320,12 @@ TEST(DWARFDebugInfo, TestDwarfVerifyCUDontShareLineTable) { )"; auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata); ASSERT_TRUE((bool)ErrOrSections); - DWARFContextInMemory DwarfContext(*ErrOrSections, 8); - VerifyError(DwarfContext, "error: two compile unit DIEs, 0x0000000b and " - "0x0000001f, have the same DW_AT_stmt_list section " - "offset:"); + std::unique_ptr<DWARFContext> DwarfContext = + DWARFContext::create(*ErrOrSections, 8); + VerifyError(*DwarfContext, + "error: two compile unit DIEs, 0x0000000b and " + "0x0000001f, have the same DW_AT_stmt_list section " + "offset:"); } TEST(DWARFDebugInfo, TestErrorReportingPolicy) { @@ -2158,24 +2352,664 @@ TEST(DWARFDebugInfo, TestErrorReportingPolicy) { EXPECT_TRUE((bool)Obj); // Case 1: error handler handles all errors. That allows - // DWARFContextInMemory - // to parse whole file and find both two errors we know about. + // DWARFContext to parse whole file and find both two errors we know about. int Errors = 0; - DWARFContextInMemory Ctx1(*Obj.get(), nullptr, [&](Error E) { - ++Errors; - consumeError(std::move(E)); - return ErrorPolicy::Continue; - }); + std::unique_ptr<DWARFContext> Ctx1 = + DWARFContext::create(**Obj, nullptr, [&](Error E) { + ++Errors; + consumeError(std::move(E)); + return ErrorPolicy::Continue; + }); EXPECT_TRUE(Errors == 2); // Case 2: error handler stops parsing of object after first error. Errors = 0; - DWARFContextInMemory Ctx2(*Obj.get(), nullptr, [&](Error E) { - ++Errors; - consumeError(std::move(E)); - return ErrorPolicy::Halt; - }); + std::unique_ptr<DWARFContext> Ctx2 = + DWARFContext::create(**Obj, nullptr, [&](Error E) { + ++Errors; + consumeError(std::move(E)); + return ErrorPolicy::Halt; + }); EXPECT_TRUE(Errors == 1); } +TEST(DWARFDebugInfo, TestDwarfVerifyCURangesIncomplete) { + // Create a single compile unit with a single function. The compile + // unit has a DW_AT_ranges attribute that doesn't fully contain the + // address range of the function. The verification should fail due to + // the CU ranges not containing all of the address ranges of all of the + // functions. + StringRef yamldata = R"( + debug_str: + - '' + - /tmp/main.c + debug_abbrev: + - Code: 0x00000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_addr + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Code: 0x00000002 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_addr + debug_info: + - Length: + TotalLength: 46 + Version: 4 + AbbrOffset: 0 + AddrSize: 8 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x0000000000001000 + - Value: 0x0000000000001500 + - Value: 0x0000000000000001 + - AbbrCode: 0x00000002 + Values: + - Value: 0x0000000000001000 + - Value: 0x0000000000002000 + - AbbrCode: 0x00000000 + Values: + )"; + auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata); + ASSERT_TRUE((bool)ErrOrSections); + std::unique_ptr<DWARFContext> DwarfContext = + DWARFContext::create(*ErrOrSections, 8); + VerifyError(*DwarfContext, "error: DIE address ranges are not " + "contained in its parent's ranges:"); +} + +TEST(DWARFDebugInfo, TestDwarfVerifyLexicalBlockRanges) { + // Create a single compile unit with a single function that has a lexical + // block whose address range is not contained in the function address range. + StringRef yamldata = R"( + debug_str: + - '' + - /tmp/main.c + - main + debug_abbrev: + - Code: 0x00000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Code: 0x00000002 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_addr + - Code: 0x00000003 + Tag: DW_TAG_lexical_block + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_addr + debug_info: + - Length: + TotalLength: 52 + Version: 4 + AbbrOffset: 0 + AddrSize: 8 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x0000000000000001 + - AbbrCode: 0x00000002 + Values: + - Value: 0x000000000000000D + - Value: 0x0000000000001000 + - Value: 0x0000000000002000 + - AbbrCode: 0x00000003 + Values: + - Value: 0x0000000000001000 + - Value: 0x0000000000002001 + - AbbrCode: 0x00000000 + Values: + - AbbrCode: 0x00000000 + Values: + )"; + auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata); + ASSERT_TRUE((bool)ErrOrSections); + std::unique_ptr<DWARFContext> DwarfContext = + DWARFContext::create(*ErrOrSections, 8); + VerifyError(*DwarfContext, "error: DIE address ranges are not " + "contained in its parent's ranges:"); +} + +TEST(DWARFDebugInfo, TestDwarfVerifyOverlappingFunctionRanges) { + // Create a single compile unit with a two functions that have overlapping + // address ranges. + StringRef yamldata = R"( + debug_str: + - '' + - /tmp/main.c + - main + - foo + debug_abbrev: + - Code: 0x00000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Code: 0x00000002 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_addr + debug_info: + - Length: + TotalLength: 55 + Version: 4 + AbbrOffset: 0 + AddrSize: 8 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x0000000000000001 + - AbbrCode: 0x00000002 + Values: + - Value: 0x000000000000000D + - Value: 0x0000000000001000 + - Value: 0x0000000000002000 + - AbbrCode: 0x00000002 + Values: + - Value: 0x0000000000000012 + - Value: 0x0000000000001FFF + - Value: 0x0000000000002000 + - AbbrCode: 0x00000000 + Values: + )"; + auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata); + ASSERT_TRUE((bool)ErrOrSections); + std::unique_ptr<DWARFContext> DwarfContext = + DWARFContext::create(*ErrOrSections, 8); + VerifyError(*DwarfContext, "error: DIEs have overlapping address ranges:"); +} + +TEST(DWARFDebugInfo, TestDwarfVerifyOverlappingLexicalBlockRanges) { + // Create a single compile unit with a one function that has two lexical + // blocks with overlapping address ranges. + StringRef yamldata = R"( + debug_str: + - '' + - /tmp/main.c + - main + debug_abbrev: + - Code: 0x00000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_addr + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Code: 0x00000002 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_addr + - Code: 0x00000003 + Tag: DW_TAG_lexical_block + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_addr + debug_info: + - Length: + TotalLength: 85 + Version: 4 + AbbrOffset: 0 + AddrSize: 8 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x0000000000001000 + - Value: 0x0000000000002000 + - Value: 0x0000000000000001 + - AbbrCode: 0x00000002 + Values: + - Value: 0x000000000000000D + - Value: 0x0000000000001000 + - Value: 0x0000000000002000 + - AbbrCode: 0x00000003 + Values: + - Value: 0x0000000000001100 + - Value: 0x0000000000001300 + - AbbrCode: 0x00000003 + Values: + - Value: 0x00000000000012FF + - Value: 0x0000000000001300 + - AbbrCode: 0x00000000 + Values: + - AbbrCode: 0x00000000 + Values: + )"; + auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata); + ASSERT_TRUE((bool)ErrOrSections); + std::unique_ptr<DWARFContext> DwarfContext = + DWARFContext::create(*ErrOrSections, 8); + VerifyError(*DwarfContext, "error: DIEs have overlapping address ranges:"); +} + +TEST(DWARFDebugInfo, TestDwarfVerifyInvalidDIERange) { + // Create a single compile unit with a single function that has an invalid + // address range where the high PC is smaller than the low PC. + StringRef yamldata = R"( + debug_str: + - '' + - /tmp/main.c + - main + debug_abbrev: + - Code: 0x00000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Code: 0x00000002 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_addr + debug_info: + - Length: + TotalLength: 34 + Version: 4 + AbbrOffset: 0 + AddrSize: 8 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x0000000000000001 + - AbbrCode: 0x00000002 + Values: + - Value: 0x000000000000000D + - Value: 0x0000000000001000 + - Value: 0x0000000000000900 + - AbbrCode: 0x00000000 + Values: + )"; + auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata); + ASSERT_TRUE((bool)ErrOrSections); + std::unique_ptr<DWARFContext> DwarfContext = + DWARFContext::create(*ErrOrSections, 8); + VerifyError(*DwarfContext, "error: Invalid address range"); +} + +TEST(DWARFDebugInfo, TestDwarfVerifyElidedDoesntFail) { + // Create a single compile unit with two functions: one that has a valid range + // and one whose low and high PC are the same. When the low and high PC are + // the same, this indicates the function was dead code stripped. We want to + // ensure that verification succeeds. + StringRef yamldata = R"( + debug_str: + - '' + - /tmp/main.c + - main + - elided + debug_abbrev: + - Code: 0x00000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_addr + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Code: 0x00000002 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_addr + debug_info: + - Length: + TotalLength: 71 + Version: 4 + AbbrOffset: 0 + AddrSize: 8 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x0000000000001000 + - Value: 0x0000000000002000 + - Value: 0x0000000000000001 + - AbbrCode: 0x00000002 + Values: + - Value: 0x000000000000000D + - Value: 0x0000000000001000 + - Value: 0x0000000000002000 + - AbbrCode: 0x00000002 + Values: + - Value: 0x0000000000000012 + - Value: 0x0000000000002000 + - Value: 0x0000000000002000 + - AbbrCode: 0x00000000 + Values: + )"; + auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata); + ASSERT_TRUE((bool)ErrOrSections); + std::unique_ptr<DWARFContext> DwarfContext = + DWARFContext::create(*ErrOrSections, 8); + VerifySuccess(*DwarfContext); +} + +TEST(DWARFDebugInfo, TestDwarfVerifyNestedFunctions) { + // Create a single compile unit with a nested function which is not contained + // in its parent. Although LLVM doesn't generate this, it is valid accoridng + // to the DWARF standard. + StringRef yamldata = R"( + debug_str: + - '' + - /tmp/main.c + - main + - nested + debug_abbrev: + - Code: 0x00000001 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_addr + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Code: 0x00000002 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_addr + debug_info: + - Length: + TotalLength: 73 + Version: 4 + AbbrOffset: 0 + AddrSize: 8 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x0000000000001000 + - Value: 0x0000000000002000 + - Value: 0x0000000000000001 + - AbbrCode: 0x00000002 + Values: + - Value: 0x000000000000000D + - Value: 0x0000000000001000 + - Value: 0x0000000000001500 + - AbbrCode: 0x00000002 + Values: + - Value: 0x0000000000000012 + - Value: 0x0000000000001500 + - Value: 0x0000000000002000 + - AbbrCode: 0x00000000 + Values: + - AbbrCode: 0x00000000 + Values: + - AbbrCode: 0x00000000 + Values: + )"; + auto ErrOrSections = DWARFYAML::EmitDebugSections(yamldata); + ASSERT_TRUE((bool)ErrOrSections); + std::unique_ptr<DWARFContext> DwarfContext = + DWARFContext::create(*ErrOrSections, 8); + VerifySuccess(*DwarfContext); +} + +TEST(DWARFDebugInfo, TestDwarfRangesContains) { + DWARFAddressRange R(0x10, 0x20); + + //---------------------------------------------------------------------- + // Test ranges that start before R... + //---------------------------------------------------------------------- + // Other range ends before start of R + ASSERT_FALSE(R.contains({0x0f, 0x10})); + // Other range end address is start of a R + ASSERT_FALSE(R.contains({0x0f, 0x11})); + // Other range end address is at and of R + ASSERT_FALSE(R.contains({0x0f, 0x20})); + // Other range end address is past end of R + ASSERT_FALSE(R.contains({0x0f, 0x40})); + + //---------------------------------------------------------------------- + // Test ranges that start at R's start address + //---------------------------------------------------------------------- + // Ensure empty ranges matches + ASSERT_TRUE(R.contains({0x10, 0x10})); + // 1 byte of Range + ASSERT_TRUE(R.contains({0x10, 0x11})); + // same as Range + ASSERT_TRUE(R.contains({0x10, 0x20})); + // 1 byte past Range + ASSERT_FALSE(R.contains({0x10, 0x21})); + + //---------------------------------------------------------------------- + // Test ranges that start inside Range + //---------------------------------------------------------------------- + // empty in range + ASSERT_TRUE(R.contains({0x11, 0x11})); + // all in Range + ASSERT_TRUE(R.contains({0x11, 0x1f})); + // ends at end of Range + ASSERT_TRUE(R.contains({0x11, 0x20})); + // ends past Range + ASSERT_FALSE(R.contains({0x11, 0x21})); + + //---------------------------------------------------------------------- + // Test ranges that start at last bytes of Range + //---------------------------------------------------------------------- + // ends at end of Range + ASSERT_TRUE(R.contains({0x1f, 0x20})); + // ends past Range + ASSERT_FALSE(R.contains({0x1f, 0x21})); + + //---------------------------------------------------------------------- + // Test ranges that start after Range + //---------------------------------------------------------------------- + // empty considered in Range + ASSERT_TRUE(R.contains({0x20, 0x20})); + // valid past Range + ASSERT_FALSE(R.contains({0x20, 0x21})); +} + +TEST(DWARFDebugInfo, TestDWARFDieRangeInfoContains) { + DWARFVerifier::DieRangeInfo Ranges({{0x10, 0x20}, {0x30, 0x40}}); + + ASSERT_FALSE(Ranges.contains({{{0x0f, 0x10}}})); + ASSERT_FALSE(Ranges.contains({{{0x20, 0x30}}})); + ASSERT_FALSE(Ranges.contains({{{0x40, 0x41}}})); + ASSERT_TRUE(Ranges.contains({{{0x10, 0x20}}})); + ASSERT_TRUE(Ranges.contains({{{0x11, 0x12}}})); + ASSERT_TRUE(Ranges.contains({{{0x1f, 0x20}}})); + ASSERT_TRUE(Ranges.contains({{{0x30, 0x40}}})); + ASSERT_TRUE(Ranges.contains({{{0x31, 0x32}}})); + ASSERT_TRUE(Ranges.contains({{{0x3f, 0x40}}})); + ASSERT_TRUE(Ranges.contains({{{0x10, 0x20}, {0x30, 0x40}}})); + ASSERT_TRUE(Ranges.contains({{{0x11, 0x12}, {0x31, 0x32}}})); + ASSERT_TRUE(Ranges.contains( + {{{0x11, 0x12}, {0x12, 0x13}, {0x31, 0x32}, {0x32, 0x33}}})); + ASSERT_FALSE(Ranges.contains({{{0x11, 0x12}, + {0x12, 0x13}, + {0x20, 0x21}, + {0x31, 0x32}, + {0x32, 0x33}}})); + ASSERT_FALSE(Ranges.contains( + {{{0x11, 0x12}, {0x12, 0x13}, {0x31, 0x32}, {0x32, 0x41}}})); +} + +namespace { + +void AssertRangesIntersect(const DWARFAddressRange &LHS, + const DWARFAddressRange &RHS) { + ASSERT_TRUE(LHS.intersects(RHS)); + ASSERT_TRUE(RHS.intersects(LHS)); +} +void AssertRangesDontIntersect(const DWARFAddressRange &LHS, + const DWARFAddressRange &RHS) { + ASSERT_FALSE(LHS.intersects(RHS)); + ASSERT_FALSE(RHS.intersects(LHS)); +} + +void AssertRangesIntersect(const DWARFVerifier::DieRangeInfo &LHS, + const DWARFAddressRangesVector &Ranges) { + DWARFVerifier::DieRangeInfo RHS(Ranges); + ASSERT_TRUE(LHS.intersects(RHS)); + ASSERT_TRUE(RHS.intersects(LHS)); +} + +void AssertRangesDontIntersect(const DWARFVerifier::DieRangeInfo &LHS, + const DWARFAddressRangesVector &Ranges) { + DWARFVerifier::DieRangeInfo RHS(Ranges); + ASSERT_FALSE(LHS.intersects(RHS)); + ASSERT_FALSE(RHS.intersects(LHS)); +} + +} // namespace +TEST(DWARFDebugInfo, TestDwarfRangesIntersect) { + DWARFAddressRange R(0x10, 0x20); + + //---------------------------------------------------------------------- + // Test ranges that start before R... + //---------------------------------------------------------------------- + // Other range ends before start of R + AssertRangesDontIntersect(R, {0x00, 0x10}); + // Other range end address is start of a R + AssertRangesIntersect(R, {0x00, 0x11}); + // Other range end address is in R + AssertRangesIntersect(R, {0x00, 0x15}); + // Other range end address is at and of R + AssertRangesIntersect(R, {0x00, 0x20}); + // Other range end address is past end of R + AssertRangesIntersect(R, {0x00, 0x40}); + + //---------------------------------------------------------------------- + // Test ranges that start at R's start address + //---------------------------------------------------------------------- + // Ensure empty ranges doesn't match + AssertRangesDontIntersect(R, {0x10, 0x10}); + // 1 byte of Range + AssertRangesIntersect(R, {0x10, 0x11}); + // same as Range + AssertRangesIntersect(R, {0x10, 0x20}); + // 1 byte past Range + AssertRangesIntersect(R, {0x10, 0x21}); + + //---------------------------------------------------------------------- + // Test ranges that start inside Range + //---------------------------------------------------------------------- + // empty in range + AssertRangesDontIntersect(R, {0x11, 0x11}); + // all in Range + AssertRangesIntersect(R, {0x11, 0x1f}); + // ends at end of Range + AssertRangesIntersect(R, {0x11, 0x20}); + // ends past Range + AssertRangesIntersect(R, {0x11, 0x21}); + + //---------------------------------------------------------------------- + // Test ranges that start at last bytes of Range + //---------------------------------------------------------------------- + // ends at end of Range + AssertRangesIntersect(R, {0x1f, 0x20}); + // ends past Range + AssertRangesIntersect(R, {0x1f, 0x21}); + + //---------------------------------------------------------------------- + // Test ranges that start after Range + //---------------------------------------------------------------------- + // empty just past in Range + AssertRangesDontIntersect(R, {0x20, 0x20}); + // valid past Range + AssertRangesDontIntersect(R, {0x20, 0x21}); +} + +TEST(DWARFDebugInfo, TestDWARFDieRangeInfoIntersects) { + + DWARFVerifier::DieRangeInfo Ranges({{0x10, 0x20}, {0x30, 0x40}}); + + // Test empty range + AssertRangesDontIntersect(Ranges, {}); + // Test range that appears before all ranges in Ranges + AssertRangesDontIntersect(Ranges, {{0x00, 0x10}}); + // Test range that appears between ranges in Ranges + AssertRangesDontIntersect(Ranges, {{0x20, 0x30}}); + // Test range that appears after ranges in Ranges + AssertRangesDontIntersect(Ranges, {{0x40, 0x50}}); + + // Test range that start before first range + AssertRangesIntersect(Ranges, {{0x00, 0x11}}); + // Test range that start at first range + AssertRangesIntersect(Ranges, {{0x10, 0x11}}); + // Test range that start in first range + AssertRangesIntersect(Ranges, {{0x11, 0x12}}); + // Test range that start at end of first range + AssertRangesIntersect(Ranges, {{0x1f, 0x20}}); + // Test range that starts at end of first range + AssertRangesDontIntersect(Ranges, {{0x20, 0x21}}); + // Test range that starts at end of first range + AssertRangesIntersect(Ranges, {{0x20, 0x31}}); + + // Test range that start before second range and ends before second + AssertRangesDontIntersect(Ranges, {{0x2f, 0x30}}); + // Test range that start before second range and ends in second + AssertRangesIntersect(Ranges, {{0x2f, 0x31}}); + // Test range that start at second range + AssertRangesIntersect(Ranges, {{0x30, 0x31}}); + // Test range that start in second range + AssertRangesIntersect(Ranges, {{0x31, 0x32}}); + // Test range that start at end of second range + AssertRangesIntersect(Ranges, {{0x3f, 0x40}}); + // Test range that starts at end of second range + AssertRangesDontIntersect(Ranges, {{0x40, 0x41}}); +} + } // end anonymous namespace |
