summaryrefslogtreecommitdiff
path: root/third_party/llvm-project/include/llvm/DebugInfo/DIContext.h
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/llvm-project/include/llvm/DebugInfo/DIContext.h')
-rw-r--r--third_party/llvm-project/include/llvm/DebugInfo/DIContext.h302
1 files changed, 302 insertions, 0 deletions
diff --git a/third_party/llvm-project/include/llvm/DebugInfo/DIContext.h b/third_party/llvm-project/include/llvm/DebugInfo/DIContext.h
new file mode 100644
index 000000000..fbebfe634
--- /dev/null
+++ b/third_party/llvm-project/include/llvm/DebugInfo/DIContext.h
@@ -0,0 +1,302 @@
+//===- DIContext.h ----------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines DIContext, an abstract data structure that holds
+// debug information data.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_DICONTEXT_H
+#define LLVM_DEBUGINFO_DICONTEXT_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <tuple>
+#include <utility>
+
+namespace llvm {
+
+/// A format-neutral container for source line information.
+struct DILineInfo {
+ // DILineInfo contains "<invalid>" for function/filename it cannot fetch.
+ static constexpr const char *const BadString = "<invalid>";
+ // Use "??" instead of "<invalid>" to make our output closer to addr2line.
+ static constexpr const char *const Addr2LineBadString = "??";
+ std::string FileName;
+ std::string FunctionName;
+ Optional<StringRef> Source;
+ uint32_t Line = 0;
+ uint32_t Column = 0;
+ uint32_t StartLine = 0;
+
+ // DWARF-specific.
+ uint32_t Discriminator = 0;
+
+ DILineInfo() : FileName(BadString), FunctionName(BadString) {}
+
+ bool operator==(const DILineInfo &RHS) const {
+ return Line == RHS.Line && Column == RHS.Column &&
+ FileName == RHS.FileName && FunctionName == RHS.FunctionName &&
+ StartLine == RHS.StartLine && Discriminator == RHS.Discriminator;
+ }
+
+ bool operator!=(const DILineInfo &RHS) const {
+ return !(*this == RHS);
+ }
+
+ bool operator<(const DILineInfo &RHS) const {
+ return std::tie(FileName, FunctionName, Line, Column, StartLine,
+ Discriminator) <
+ std::tie(RHS.FileName, RHS.FunctionName, RHS.Line, RHS.Column,
+ RHS.StartLine, RHS.Discriminator);
+ }
+
+ explicit operator bool() const { return *this != DILineInfo(); }
+
+ void dump(raw_ostream &OS) {
+ OS << "Line info: ";
+ if (FileName != BadString)
+ OS << "file '" << FileName << "', ";
+ if (FunctionName != BadString)
+ OS << "function '" << FunctionName << "', ";
+ OS << "line " << Line << ", ";
+ OS << "column " << Column << ", ";
+ OS << "start line " << StartLine << '\n';
+ }
+};
+
+using DILineInfoTable = SmallVector<std::pair<uint64_t, DILineInfo>, 16>;
+
+/// A format-neutral container for inlined code description.
+class DIInliningInfo {
+ SmallVector<DILineInfo, 4> Frames;
+
+public:
+ DIInliningInfo() = default;
+
+ const DILineInfo & getFrame(unsigned Index) const {
+ assert(Index < Frames.size());
+ return Frames[Index];
+ }
+
+ DILineInfo *getMutableFrame(unsigned Index) {
+ assert(Index < Frames.size());
+ return &Frames[Index];
+ }
+
+ uint32_t getNumberOfFrames() const {
+ return Frames.size();
+ }
+
+ void addFrame(const DILineInfo &Frame) {
+ Frames.push_back(Frame);
+ }
+
+ void resize(unsigned i) {
+ Frames.resize(i);
+ }
+};
+
+/// Container for description of a global variable.
+struct DIGlobal {
+ std::string Name;
+ uint64_t Start = 0;
+ uint64_t Size = 0;
+
+ DIGlobal() : Name(DILineInfo::BadString) {}
+};
+
+struct DILocal {
+ std::string FunctionName;
+ std::string Name;
+ std::string DeclFile;
+ uint64_t DeclLine = 0;
+ Optional<int64_t> FrameOffset;
+ Optional<uint64_t> Size;
+ Optional<uint64_t> TagOffset;
+};
+
+/// A DINameKind is passed to name search methods to specify a
+/// preference regarding the type of name resolution the caller wants.
+enum class DINameKind { None, ShortName, LinkageName };
+
+/// Controls which fields of DILineInfo container should be filled
+/// with data.
+struct DILineInfoSpecifier {
+ enum class FileLineInfoKind { None, Default, AbsoluteFilePath };
+ using FunctionNameKind = DINameKind;
+
+ FileLineInfoKind FLIKind;
+ FunctionNameKind FNKind;
+
+ DILineInfoSpecifier(FileLineInfoKind FLIKind = FileLineInfoKind::Default,
+ FunctionNameKind FNKind = FunctionNameKind::None)
+ : FLIKind(FLIKind), FNKind(FNKind) {}
+};
+
+/// This is just a helper to programmatically construct DIDumpType.
+enum DIDumpTypeCounter {
+#define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME) \
+ DIDT_ID_##ENUM_NAME,
+#include "llvm/BinaryFormat/Dwarf.def"
+#undef HANDLE_DWARF_SECTION
+ DIDT_ID_UUID,
+ DIDT_ID_Count
+};
+static_assert(DIDT_ID_Count <= 32, "section types overflow storage");
+
+/// Selects which debug sections get dumped.
+enum DIDumpType : unsigned {
+ DIDT_Null,
+ DIDT_All = ~0U,
+#define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME) \
+ DIDT_##ENUM_NAME = 1U << DIDT_ID_##ENUM_NAME,
+#include "llvm/BinaryFormat/Dwarf.def"
+#undef HANDLE_DWARF_SECTION
+ DIDT_UUID = 1 << DIDT_ID_UUID,
+};
+
+/// Container for dump options that control which debug information will be
+/// dumped.
+struct DIDumpOptions {
+ unsigned DumpType = DIDT_All;
+ unsigned ChildRecurseDepth = -1U;
+ unsigned ParentRecurseDepth = -1U;
+ uint16_t Version = 0; // DWARF version to assume when extracting.
+ uint8_t AddrSize = 4; // Address byte size to assume when extracting.
+ bool ShowAddresses = true;
+ bool ShowChildren = false;
+ bool ShowParents = false;
+ bool ShowForm = false;
+ bool SummarizeTypes = false;
+ bool Verbose = false;
+ bool DisplayRawContents = false;
+
+ /// Return default option set for printing a single DIE without children.
+ static DIDumpOptions getForSingleDIE() {
+ DIDumpOptions Opts;
+ Opts.ChildRecurseDepth = 0;
+ Opts.ParentRecurseDepth = 0;
+ return Opts;
+ }
+
+ /// Return the options with RecurseDepth set to 0 unless explicitly required.
+ DIDumpOptions noImplicitRecursion() const {
+ DIDumpOptions Opts = *this;
+ if (ChildRecurseDepth == -1U && !ShowChildren)
+ Opts.ChildRecurseDepth = 0;
+ if (ParentRecurseDepth == -1U && !ShowParents)
+ Opts.ParentRecurseDepth = 0;
+ return Opts;
+ }
+};
+
+class DIContext {
+public:
+ enum DIContextKind {
+ CK_DWARF,
+ CK_PDB
+ };
+
+ DIContext(DIContextKind K) : Kind(K) {}
+ virtual ~DIContext() = default;
+
+ DIContextKind getKind() const { return Kind; }
+
+ virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
+
+ virtual bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) {
+ // No verifier? Just say things went well.
+ return true;
+ }
+
+ virtual DILineInfo getLineInfoForAddress(
+ object::SectionedAddress Address,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
+ virtual DILineInfoTable getLineInfoForAddressRange(
+ object::SectionedAddress Address, uint64_t Size,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
+ virtual DIInliningInfo getInliningInfoForAddress(
+ object::SectionedAddress Address,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
+
+ virtual std::vector<DILocal>
+ getLocalsForAddress(object::SectionedAddress Address) = 0;
+
+private:
+ const DIContextKind Kind;
+};
+
+/// An inferface for inquiring the load address of a loaded object file
+/// to be used by the DIContext implementations when applying relocations
+/// on the fly.
+class LoadedObjectInfo {
+protected:
+ LoadedObjectInfo() = default;
+ LoadedObjectInfo(const LoadedObjectInfo &) = default;
+
+public:
+ virtual ~LoadedObjectInfo() = default;
+
+ /// Obtain the Load Address of a section by SectionRef.
+ ///
+ /// Calculate the address of the given section.
+ /// The section need not be present in the local address space. The addresses
+ /// need to be consistent with the addresses used to query the DIContext and
+ /// the output of this function should be deterministic, i.e. repeated calls
+ /// with the same Sec should give the same address.
+ virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const {
+ return 0;
+ }
+
+ /// If conveniently available, return the content of the given Section.
+ ///
+ /// When the section is available in the local address space, in relocated
+ /// (loaded) form, e.g. because it was relocated by a JIT for execution, this
+ /// function should provide the contents of said section in `Data`. If the
+ /// loaded section is not available, or the cost of retrieving it would be
+ /// prohibitive, this function should return false. In that case, relocations
+ /// will be read from the local (unrelocated) object file and applied on the
+ /// fly. Note that this method is used purely for optimzation purposes in the
+ /// common case of JITting in the local address space, so returning false
+ /// should always be correct.
+ virtual bool getLoadedSectionContents(const object::SectionRef &Sec,
+ StringRef &Data) const {
+ return false;
+ }
+
+ // FIXME: This is untested and unused anywhere in the LLVM project, it's
+ // used/needed by Julia (an external project). It should have some coverage
+ // (at least tests, but ideally example functionality).
+ /// Obtain a copy of this LoadedObjectInfo.
+ virtual std::unique_ptr<LoadedObjectInfo> clone() const = 0;
+};
+
+template <typename Derived, typename Base = LoadedObjectInfo>
+struct LoadedObjectInfoHelper : Base {
+protected:
+ LoadedObjectInfoHelper(const LoadedObjectInfoHelper &) = default;
+ LoadedObjectInfoHelper() = default;
+
+public:
+ template <typename... Ts>
+ LoadedObjectInfoHelper(Ts &&... Args) : Base(std::forward<Ts>(Args)...) {}
+
+ std::unique_ptr<llvm::LoadedObjectInfo> clone() const override {
+ return std::make_unique<Derived>(static_cast<const Derived &>(*this));
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_DEBUGINFO_DICONTEXT_H