diff options
Diffstat (limited to 'llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp')
-rw-r--r-- | llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp b/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp index 38e57a8363c..f0e488e731b 100644 --- a/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp +++ b/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp @@ -134,6 +134,67 @@ TEST(GSYMTest, TestFunctionInfo) { EXPECT_LT(FIWithLines, FIWithLinesWithHigherAddress); } +void checkError(ArrayRef<std::string> ExpectedMsgs, Error Err) { + ASSERT_TRUE(Err.operator bool()); + size_t WhichMsg = 0; + Error Remaining = + handleErrors(std::move(Err), [&](const ErrorInfoBase &Actual) { + ASSERT_LT(WhichMsg, ExpectedMsgs.size()); + // Use .str(), because googletest doesn't visualise a StringRef + // properly. + EXPECT_EQ(Actual.message(), ExpectedMsgs[WhichMsg++]); + }); + EXPECT_EQ(WhichMsg, ExpectedMsgs.size()); + EXPECT_FALSE(Remaining); +} + +void checkError(std::string ExpectedMsg, Error Err) { + checkError(ArrayRef<std::string>{ExpectedMsg}, std::move(Err)); +} + +static void TestInlineInfoEncodeDecode(llvm::support::endianness ByteOrder, + const InlineInfo &Inline) { + // Test encoding and decoding InlineInfo objects + SmallString<512> Str; + raw_svector_ostream OutStrm(Str); + FileWriter FW(OutStrm, ByteOrder); + const uint64_t BaseAddr = Inline.Ranges[0].Start; + llvm::Error Err = Inline.encode(FW, BaseAddr); + ASSERT_FALSE(Err); + std::string Bytes(OutStrm.str()); + uint8_t AddressSize = 4; + DataExtractor Data(Bytes, ByteOrder == llvm::support::little, AddressSize); + llvm::Expected<InlineInfo> Decoded = InlineInfo::decode(Data, BaseAddr); + // Make sure decoding succeeded. + ASSERT_TRUE((bool)Decoded); + // Make sure decoded object is the same as the one we encoded. + EXPECT_EQ(Inline, Decoded.get()); +} + +static void TestInlineInfoDecodeError(llvm::support::endianness ByteOrder, + std::string Bytes, + const uint64_t BaseAddr, + std::string ExpectedErrorMsg) { + uint8_t AddressSize = 4; + DataExtractor Data(Bytes, ByteOrder == llvm::support::little, AddressSize); + llvm::Expected<InlineInfo> Decoded = InlineInfo::decode(Data, BaseAddr); + // Make sure decoding fails. + ASSERT_FALSE((bool)Decoded); + // Make sure decoded object is the same as the one we encoded. + checkError(ExpectedErrorMsg, Decoded.takeError()); +} + +static void TestInlineInfoEncodeError(llvm::support::endianness ByteOrder, + const InlineInfo &Inline, + std::string ExpectedErrorMsg) { + SmallString<512> Str; + raw_svector_ostream OutStrm(Str); + FileWriter FW(OutStrm, ByteOrder); + const uint64_t BaseAddr = Inline.Ranges.empty() ? 0 : Inline.Ranges[0].Start; + llvm::Error Err = Inline.encode(FW, BaseAddr); + checkError(ExpectedErrorMsg, std::move(Err)); +} + TEST(GSYMTest, TestInlineInfo) { // Test InlineInfo structs. InlineInfo II; @@ -226,6 +287,69 @@ TEST(GSYMTest, TestInlineInfo) { ASSERT_EQ(InlineInfos->size(), 2u); ASSERT_EQ(*InlineInfos->at(0), Inline1Sub2); ASSERT_EQ(*InlineInfos->at(1), Inline1); + + // Test encoding and decoding InlineInfo objects + TestInlineInfoEncodeDecode(llvm::support::little, Root); + TestInlineInfoEncodeDecode(llvm::support::big, Root); +} + +TEST(GSYMTest, TestInlineInfoEncodeErrors) { + // Test InlineInfo encoding errors. + + // Test that we get an error when trying to encode an InlineInfo object + // that has no ranges. + InlineInfo Empty; + std::string EmptyErr("attempted to encode invalid InlineInfo object"); + TestInlineInfoEncodeError(llvm::support::little, Empty, EmptyErr); + TestInlineInfoEncodeError(llvm::support::big, Empty, EmptyErr); + + // Verify that we get an error trying to encode an InlineInfo object that has + // a child InlineInfo that has no ranges. + InlineInfo ContainsEmpty; + ContainsEmpty.Ranges.insert({0x100,200}); + ContainsEmpty.Children.push_back(Empty); + TestInlineInfoEncodeError(llvm::support::little, ContainsEmpty, EmptyErr); + TestInlineInfoEncodeError(llvm::support::big, ContainsEmpty, EmptyErr); + + // Verify that we get an error trying to encode an InlineInfo object that has + // a child whose address range is not contained in the parent address range. + InlineInfo ChildNotContained; + std::string ChildNotContainedErr("child range not contained in parent"); + ChildNotContained.Ranges.insert({0x100,200}); + InlineInfo ChildNotContainedChild; + ChildNotContainedChild.Ranges.insert({0x200,300}); + ChildNotContained.Children.push_back(ChildNotContainedChild); + TestInlineInfoEncodeError(llvm::support::little, ChildNotContained, + ChildNotContainedErr); + TestInlineInfoEncodeError(llvm::support::big, ChildNotContained, + ChildNotContainedErr); + +} + +TEST(GSYMTest, TestInlineInfoDecodeErrors) { + // Test decoding InlineInfo objects that ensure we report an appropriate + // error message. + const llvm::support::endianness ByteOrder = llvm::support::little; + SmallString<512> Str; + raw_svector_ostream OutStrm(Str); + FileWriter FW(OutStrm, ByteOrder); + const uint64_t BaseAddr = 0x100; + TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr, + "0x00000000: missing InlineInfo address ranges data"); + AddressRanges Ranges; + Ranges.insert({BaseAddr, BaseAddr+0x100}); + Ranges.encode(FW, BaseAddr); + TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr, + "0x00000004: missing InlineInfo uint8_t indicating children"); + FW.writeU8(0); + TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr, + "0x00000005: missing InlineInfo uint32_t for name"); + FW.writeU32(0); + TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr, + "0x00000009: missing ULEB128 for InlineInfo call file"); + FW.writeU8(0); + TestInlineInfoDecodeError(ByteOrder, OutStrm.str(), BaseAddr, + "0x0000000a: missing ULEB128 for InlineInfo call line"); } TEST(GSYMTest, TestLineEntry) { @@ -334,6 +458,18 @@ TEST(GSYMTest, TestRanges) { EXPECT_FALSE(Ranges.contains(0x5000 + 1)); EXPECT_FALSE(Ranges.contains(UINT64_MAX)); + EXPECT_FALSE(Ranges.contains(AddressRange())); + EXPECT_FALSE(Ranges.contains(AddressRange(0x1000-1, 0x1000))); + EXPECT_FALSE(Ranges.contains(AddressRange(0x1000, 0x1000))); + EXPECT_TRUE(Ranges.contains(AddressRange(0x1000, 0x1000+1))); + EXPECT_TRUE(Ranges.contains(AddressRange(0x1000, 0x2000))); + EXPECT_FALSE(Ranges.contains(AddressRange(0x1000, 0x2001))); + EXPECT_TRUE(Ranges.contains(AddressRange(0x2000, 0x3000))); + EXPECT_FALSE(Ranges.contains(AddressRange(0x2000, 0x3001))); + EXPECT_FALSE(Ranges.contains(AddressRange(0x3000, 0x3001))); + EXPECT_FALSE(Ranges.contains(AddressRange(0x1500, 0x4500))); + EXPECT_FALSE(Ranges.contains(AddressRange(0x5000, 0x5001))); + // Verify that intersecting ranges get combined Ranges.clear(); Ranges.insert(AddressRange(0x1100, 0x1F00)); |