summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/DebugInfo
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@fb.com>2019-12-03 16:44:02 -0800
committerGreg Clayton <gclayton@fb.com>2019-12-05 16:49:53 -0800
commitaeda128a96c4ac9eecef7563f4cf07dfcd2af0db (patch)
tree2452f0050027c3a641fee592fdfa16b0bfc9e9fc /llvm/unittests/DebugInfo
parent6470497817eafe3fe2d15e11ade78fd99753d7ca (diff)
downloadbcm5719-llvm-aeda128a96c4ac9eecef7563f4cf07dfcd2af0db.tar.gz
bcm5719-llvm-aeda128a96c4ac9eecef7563f4cf07dfcd2af0db.zip
Add lookup functions for efficient lookups of addresses when using GsymReader classes.
Summary: Lookup functions are designed to not fully decode a FunctionInfo, LineTable or InlineInfo, they decode only what is needed into a LookupResult object. This allows lookups to avoid costly memory allocations and avoid parsing large amounts of information one a suitable match is found. LookupResult objects contain the address that was looked up, the concrete function address range, the name of the concrete function, and a list of source locations. One for each inline function, and one for the concrete function. This allows one address to turn into multiple frames and improves the signal you get when symbolicating addresses in GSYM files. Reviewers: labath, aprantl Subscribers: mgorny, hiraditya, llvm-commits, lldb-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D70993
Diffstat (limited to 'llvm/unittests/DebugInfo')
-rw-r--r--llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp b/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp
index 9fd8edf6a10..bee1d4091cd 100644
--- a/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp
+++ b/llvm/unittests/DebugInfo/GSYM/GSYMTest.cpp
@@ -20,8 +20,10 @@
#include "llvm/DebugInfo/GSYM/StringTable.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Testing/Support/Error.h"
#include "gtest/gtest.h"
+#include "gmock/gmock.h"
#include <string>
using namespace llvm;
@@ -1302,3 +1304,100 @@ TEST(GSYMTest, TestGsymReader) {
"address 0x1030 not in GSYM");
}
}
+
+TEST(GSYMTest, TestGsymLookups) {
+ // Test creating a GSYM file with a function that has a inline information.
+ // Verify that lookups work correctly. Lookups do not decode the entire
+ // FunctionInfo or InlineInfo, they only extract information needed for the
+ // lookup to happen which avoids allocations which can slow down
+ // symbolication.
+ GsymCreator GC;
+ FunctionInfo FI(0x1000, 0x100, GC.insertString("main"));
+ const auto ByteOrder = support::endian::system_endianness();
+ FI.OptLineTable = LineTable();
+ const uint32_t MainFileIndex = GC.insertFile("/tmp/main.c");
+ const uint32_t FooFileIndex = GC.insertFile("/tmp/foo.h");
+ FI.OptLineTable->push(LineEntry(0x1000, MainFileIndex, 5));
+ FI.OptLineTable->push(LineEntry(0x1010, FooFileIndex, 10));
+ FI.OptLineTable->push(LineEntry(0x1012, FooFileIndex, 20));
+ FI.OptLineTable->push(LineEntry(0x1014, FooFileIndex, 11));
+ FI.OptLineTable->push(LineEntry(0x1016, FooFileIndex, 30));
+ FI.OptLineTable->push(LineEntry(0x1018, FooFileIndex, 12));
+ FI.OptLineTable->push(LineEntry(0x1020, MainFileIndex, 8));
+ FI.Inline = InlineInfo();
+
+ FI.Inline->Name = GC.insertString("inline1");
+ FI.Inline->CallFile = MainFileIndex;
+ FI.Inline->CallLine = 6;
+ FI.Inline->Ranges.insert(AddressRange(0x1010, 0x1020));
+ InlineInfo Inline2;
+ Inline2.Name = GC.insertString("inline2");
+ Inline2.CallFile = FooFileIndex;
+ Inline2.CallLine = 33;
+ Inline2.Ranges.insert(AddressRange(0x1012, 0x1014));
+ FI.Inline->Children.emplace_back(Inline2);
+ InlineInfo Inline3;
+ Inline3.Name = GC.insertString("inline3");
+ Inline3.CallFile = FooFileIndex;
+ Inline3.CallLine = 35;
+ Inline3.Ranges.insert(AddressRange(0x1016, 0x1018));
+ FI.Inline->Children.emplace_back(Inline3);
+ GC.addFunctionInfo(std::move(FI));
+ Error FinalizeErr = GC.finalize(llvm::nulls());
+ ASSERT_FALSE(FinalizeErr);
+ SmallString<512> Str;
+ raw_svector_ostream OutStrm(Str);
+ FileWriter FW(OutStrm, ByteOrder);
+ llvm::Error Err = GC.encode(FW);
+ ASSERT_FALSE((bool)Err);
+ Expected<GsymReader> GR = GsymReader::copyBuffer(OutStrm.str());
+ ASSERT_TRUE(bool(GR));
+
+ // Verify inline info is correct when doing lookups.
+ auto LR = GR->lookup(0x1000);
+ ASSERT_THAT_EXPECTED(LR, Succeeded());
+ EXPECT_THAT(LR->Locations,
+ testing::ElementsAre(SourceLocation{"main", "/tmp", "main.c", 5}));
+ LR = GR->lookup(0x100F);
+ ASSERT_THAT_EXPECTED(LR, Succeeded());
+ EXPECT_THAT(LR->Locations,
+ testing::ElementsAre(SourceLocation{"main", "/tmp", "main.c", 5}));
+
+ LR = GR->lookup(0x1010);
+ ASSERT_THAT_EXPECTED(LR, Succeeded());
+
+ EXPECT_THAT(LR->Locations,
+ testing::ElementsAre(SourceLocation{"inline1", "/tmp", "foo.h", 10},
+ SourceLocation{"main", "/tmp", "main.c", 6}));
+
+ LR = GR->lookup(0x1012);
+ ASSERT_THAT_EXPECTED(LR, Succeeded());
+ EXPECT_THAT(LR->Locations,
+ testing::ElementsAre(SourceLocation{"inline2", "/tmp", "foo.h", 20},
+ SourceLocation{"inline1", "/tmp", "foo.h", 33},
+ SourceLocation{"main", "/tmp", "main.c", 6}));
+
+ LR = GR->lookup(0x1014);
+ ASSERT_THAT_EXPECTED(LR, Succeeded());
+ EXPECT_THAT(LR->Locations,
+ testing::ElementsAre(SourceLocation{"inline1", "/tmp", "foo.h", 11},
+ SourceLocation{"main", "/tmp", "main.c", 6}));
+
+ LR = GR->lookup(0x1016);
+ ASSERT_THAT_EXPECTED(LR, Succeeded());
+ EXPECT_THAT(LR->Locations,
+ testing::ElementsAre(SourceLocation{"inline3", "/tmp", "foo.h", 30},
+ SourceLocation{"inline1", "/tmp", "foo.h", 35},
+ SourceLocation{"main", "/tmp", "main.c", 6}));
+
+ LR = GR->lookup(0x1018);
+ ASSERT_THAT_EXPECTED(LR, Succeeded());
+ EXPECT_THAT(LR->Locations,
+ testing::ElementsAre(SourceLocation{"inline1", "/tmp", "foo.h", 12},
+ SourceLocation{"main", "/tmp", "main.c", 6}));
+
+ LR = GR->lookup(0x1020);
+ ASSERT_THAT_EXPECTED(LR, Succeeded());
+ EXPECT_THAT(LR->Locations,
+ testing::ElementsAre(SourceLocation{"main", "/tmp", "main.c", 8}));
+}
OpenPOWER on IntegriCloud