summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo
diff options
context:
space:
mode:
authorGreg Clayton <clayborg@gmail.com>2019-06-26 14:09:09 +0000
committerGreg Clayton <clayborg@gmail.com>2019-06-26 14:09:09 +0000
commit044776bf5d92ce37ad32aab7d59a87d4bcb2e8e8 (patch)
tree7769fefd461b77566588f3ec47fb676440085ff5 /llvm/lib/DebugInfo
parent5f798f134659e7917cbca89702111b13d50e5b46 (diff)
downloadbcm5719-llvm-044776bf5d92ce37ad32aab7d59a87d4bcb2e8e8.tar.gz
bcm5719-llvm-044776bf5d92ce37ad32aab7d59a87d4bcb2e8e8.zip
Add GSYM utility files along with unit tests.
The full GSYM patch started with: https://reviews.llvm.org/D53379 In that patch we wanted to split up getting GSYM into the LLVM code base so we are not committing too much code at once. This is a first in a series of patches where I only add the foundation classes along with complete unit tests. They provide the foundation for encoding and decoding a GSYM file. File entries are defined in llvm::gsym::FileEntry. This class splits the file up into a directory and filename represented by uniqued string table offsets. This allows all files that are referred to in a GSYM file to be encoded as 1 based indexes into a global file table in the GSYM file. Function information in stored in llvm::gsym::FunctionInfo. This object represents a contiguous address range that has a name and range with an optional line table and inline call stack information. Line table entries are defined in llvm::gsym::LineEntry. They store only address, file and line information to keep the line tables simple and allows the information to be efficiently encoded in a subsequent patch. Inline information is defined in llvm::gsym::InlineInfo. These structs store the name of the inline function, along with one or more address ranges, and the file and line that called this function. They also contain any child inline information. There are also utility classes for address ranges in llvm::gsym::AddressRange, and string table support in llvm::gsym::StringTable which are simple classes. The unit tests test all the APIs on these simple classes so they will be ready for the next patches where we will create GSYM files and parse GSYM files. Differential Revision: https://reviews.llvm.org/D63104 llvm-svn: 364427
Diffstat (limited to 'llvm/lib/DebugInfo')
-rw-r--r--llvm/lib/DebugInfo/CMakeLists.txt1
-rw-r--r--llvm/lib/DebugInfo/GSYM/CMakeLists.txt9
-rw-r--r--llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp23
-rw-r--r--llvm/lib/DebugInfo/GSYM/InlineInfo.cpp59
-rw-r--r--llvm/lib/DebugInfo/GSYM/Range.cpp71
5 files changed, 163 insertions, 0 deletions
diff --git a/llvm/lib/DebugInfo/CMakeLists.txt b/llvm/lib/DebugInfo/CMakeLists.txt
index e7be0a0617d..6355ba08d03 100644
--- a/llvm/lib/DebugInfo/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/CMakeLists.txt
@@ -1,4 +1,5 @@
add_subdirectory(DWARF)
+add_subdirectory(GSYM)
add_subdirectory(MSF)
add_subdirectory(CodeView)
add_subdirectory(PDB)
diff --git a/llvm/lib/DebugInfo/GSYM/CMakeLists.txt b/llvm/lib/DebugInfo/GSYM/CMakeLists.txt
new file mode 100644
index 00000000000..fc37d560e61
--- /dev/null
+++ b/llvm/lib/DebugInfo/GSYM/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_llvm_library(LLVMDebugInfoGSYM
+ FunctionInfo.cpp
+ InlineInfo.cpp
+ Range.cpp
+
+ ADDITIONAL_HEADER_DIRS
+ ${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/GSYM
+ ${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo
+ )
diff --git a/llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp b/llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp
new file mode 100644
index 00000000000..bd0c8bc51f5
--- /dev/null
+++ b/llvm/lib/DebugInfo/GSYM/FunctionInfo.cpp
@@ -0,0 +1,23 @@
+//===- FunctionInfo.cpp -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/GSYM/FunctionInfo.h"
+
+using namespace llvm;
+using namespace gsym;
+
+raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const FunctionInfo &FI) {
+ OS << '[' << HEX64(FI.Range.startAddress()) << '-'
+ << HEX64(FI.Range.endAddress()) << "): "
+ << "Name=" << HEX32(FI.Name) << '\n';
+ for (const auto &Line : FI.Lines)
+ OS << Line << '\n';
+ OS << FI.Inline;
+ return OS;
+}
diff --git a/llvm/lib/DebugInfo/GSYM/InlineInfo.cpp b/llvm/lib/DebugInfo/GSYM/InlineInfo.cpp
new file mode 100644
index 00000000000..78e6ed46274
--- /dev/null
+++ b/llvm/lib/DebugInfo/GSYM/InlineInfo.cpp
@@ -0,0 +1,59 @@
+//===- InlineInfo.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/GSYM/FileEntry.h"
+#include "llvm/DebugInfo/GSYM/InlineInfo.h"
+#include <algorithm>
+#include <inttypes.h>
+
+using namespace llvm;
+using namespace gsym;
+
+
+raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const InlineInfo &II) {
+ if (!II.isValid())
+ return OS;
+ bool First = true;
+ for (auto Range : II.Ranges) {
+ if (First)
+ First = false;
+ else
+ OS << ' ';
+ OS << Range;
+ }
+ OS << " Name = " << HEX32(II.Name) << ", CallFile = " << II.CallFile
+ << ", CallLine = " << II.CallFile << '\n';
+ for (const auto &Child : II.Children)
+ OS << Child;
+ return OS;
+}
+
+static bool getInlineStackHelper(const InlineInfo &II, uint64_t Addr,
+ std::vector<const InlineInfo *> &InlineStack) {
+ if (II.Ranges.contains(Addr)) {
+ // If this is the top level that represents the concrete function,
+ // there will be no name and we shoud clear the inline stack. Otherwise
+ // we have found an inline call stack that we need to insert.
+ if (II.Name != 0)
+ InlineStack.insert(InlineStack.begin(), &II);
+ for (const auto &Child : II.Children) {
+ if (::getInlineStackHelper(Child, Addr, InlineStack))
+ break;
+ }
+ return !InlineStack.empty();
+ }
+ return false;
+}
+
+llvm::Optional<InlineInfo::InlineArray> InlineInfo::getInlineStack(uint64_t Addr) const {
+ InlineArray Result;
+ if (getInlineStackHelper(*this, Addr, Result))
+ return Result;
+ return llvm::None;
+}
diff --git a/llvm/lib/DebugInfo/GSYM/Range.cpp b/llvm/lib/DebugInfo/GSYM/Range.cpp
new file mode 100644
index 00000000000..fdf4c2e6542
--- /dev/null
+++ b/llvm/lib/DebugInfo/GSYM/Range.cpp
@@ -0,0 +1,71 @@
+//===- Range.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/GSYM/Range.h"
+#include <algorithm>
+#include <inttypes.h>
+
+using namespace llvm;
+using namespace gsym;
+
+
+void AddressRanges::insert(const AddressRange &Range) {
+ if (Range.size() == 0)
+ return;
+ // Ranges.insert(std::upper_bound(Ranges.begin(), Ranges.end(), Range), Range);
+
+ // // Check if an existing range intersects with this range, and if so,
+ // // grow the intersecting ranges instead of adding a new one.
+ auto Begin = Ranges.begin();
+ auto End = Ranges.end();
+ const auto Iter = std::upper_bound(Begin, End, Range);
+ if (Iter != Begin) {
+ auto PrevIter = Iter - 1;
+ // If the previous range itersects with "Range" they will be combined.
+ if (PrevIter->intersect(Range)) {
+ // Now check if the previous range intersects with the next range since
+ // the previous range was combined. If so, combine them and remove the
+ // next range.
+ if (PrevIter->intersect(*Iter))
+ Ranges.erase(Iter);
+ return;
+ }
+ }
+ // If the next range intersects with "Range", combined and return.
+ if (Iter != End && Iter->intersect(Range))
+ return;
+ Ranges.insert(Iter, Range);
+}
+
+bool AddressRanges::contains(uint64_t Addr) const {
+ if (Ranges.empty())
+ return false;
+ auto Begin = Ranges.begin();
+ auto Pos = std::upper_bound(Begin, Ranges.end(), Addr);
+ if (Pos == Begin)
+ return false;
+ --Pos;
+ return Pos->contains(Addr);
+}
+
+raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const AddressRange &R) {
+ return OS << '[' << HEX64(R.startAddress()) << " - " << HEX64(R.endAddress())
+ << ")";
+}
+
+raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const AddressRanges &AR) {
+ size_t Size = AR.size();
+ for (size_t I=0; I<Size; ++I) {
+ if (I)
+ OS << ' ';
+ OS << AR[I];
+ }
+ return OS;
+}
+
OpenPOWER on IntegriCloud