summaryrefslogtreecommitdiff
path: root/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp')
-rw-r--r--unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp992
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