File indexing completed on 2026-05-10 08:43:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_DEBUGINFO_DICONTEXT_H
0015 #define LLVM_DEBUGINFO_DICONTEXT_H
0016
0017 #include "llvm/ADT/SmallVector.h"
0018 #include "llvm/Object/ObjectFile.h"
0019 #include "llvm/Support/WithColor.h"
0020 #include "llvm/Support/raw_ostream.h"
0021 #include <cassert>
0022 #include <cstdint>
0023 #include <memory>
0024 #include <optional>
0025 #include <string>
0026 #include <tuple>
0027 #include <utility>
0028
0029 namespace llvm {
0030
0031
0032 struct DILineInfo {
0033 static constexpr const char *const ApproxString = "(approximate)";
0034
0035 static constexpr const char *const BadString = "<invalid>";
0036
0037 static constexpr const char *const Addr2LineBadString = "??";
0038 std::string FileName;
0039 std::string FunctionName;
0040 std::string StartFileName;
0041
0042 std::optional<StringRef> Source;
0043
0044
0045 std::optional<StringRef> LineSource;
0046 uint32_t Line = 0;
0047 uint32_t Column = 0;
0048 uint32_t StartLine = 0;
0049 std::optional<uint64_t> StartAddress;
0050
0051
0052 uint32_t Discriminator = 0;
0053
0054 bool IsApproximateLine = false;
0055 DILineInfo()
0056 : FileName(BadString), FunctionName(BadString), StartFileName(BadString) {
0057 }
0058
0059 bool operator==(const DILineInfo &RHS) const {
0060 return Line == RHS.Line && Column == RHS.Column &&
0061 FileName == RHS.FileName && FunctionName == RHS.FunctionName &&
0062 StartFileName == RHS.StartFileName && StartLine == RHS.StartLine &&
0063 Discriminator == RHS.Discriminator;
0064 }
0065
0066 bool operator!=(const DILineInfo &RHS) const { return !(*this == RHS); }
0067
0068 bool operator<(const DILineInfo &RHS) const {
0069 return std::tie(FileName, FunctionName, StartFileName, Line, Column,
0070 StartLine, Discriminator) <
0071 std::tie(RHS.FileName, RHS.FunctionName, RHS.StartFileName, RHS.Line,
0072 RHS.Column, RHS.StartLine, RHS.Discriminator);
0073 }
0074
0075 explicit operator bool() const { return *this != DILineInfo(); }
0076
0077 void dump(raw_ostream &OS) {
0078 OS << "Line info: ";
0079 if (FileName != BadString)
0080 OS << "file '" << FileName << "', ";
0081 if (FunctionName != BadString)
0082 OS << "function '" << FunctionName << "', ";
0083 OS << "line " << Line << ", ";
0084 OS << "column " << Column << ", ";
0085 if (StartFileName != BadString)
0086 OS << "start file '" << StartFileName << "', ";
0087 OS << "start line " << StartLine << '\n';
0088 }
0089 };
0090
0091 using DILineInfoTable = SmallVector<std::pair<uint64_t, DILineInfo>, 16>;
0092
0093
0094 class DIInliningInfo {
0095 SmallVector<DILineInfo, 4> Frames;
0096
0097 public:
0098 DIInliningInfo() = default;
0099
0100
0101
0102 const DILineInfo &getFrame(unsigned Index) const {
0103 assert(Index < Frames.size());
0104 return Frames[Index];
0105 }
0106
0107 DILineInfo *getMutableFrame(unsigned Index) {
0108 assert(Index < Frames.size());
0109 return &Frames[Index];
0110 }
0111
0112 uint32_t getNumberOfFrames() const { return Frames.size(); }
0113
0114 void addFrame(const DILineInfo &Frame) { Frames.push_back(Frame); }
0115
0116 void resize(unsigned i) { Frames.resize(i); }
0117 };
0118
0119
0120 struct DIGlobal {
0121 std::string Name;
0122 uint64_t Start = 0;
0123 uint64_t Size = 0;
0124 std::string DeclFile;
0125 uint64_t DeclLine = 0;
0126
0127 DIGlobal() : Name(DILineInfo::BadString) {}
0128 };
0129
0130 struct DILocal {
0131 std::string FunctionName;
0132 std::string Name;
0133 std::string DeclFile;
0134 uint64_t DeclLine = 0;
0135 std::optional<int64_t> FrameOffset;
0136 std::optional<uint64_t> Size;
0137 std::optional<uint64_t> TagOffset;
0138 };
0139
0140
0141
0142 enum class DINameKind { None, ShortName, LinkageName };
0143
0144
0145
0146 struct DILineInfoSpecifier {
0147 enum class FileLineInfoKind {
0148 None,
0149
0150
0151 RawValue,
0152 BaseNameOnly,
0153
0154 RelativeFilePath,
0155 AbsoluteFilePath
0156 };
0157 using FunctionNameKind = DINameKind;
0158 FileLineInfoKind FLIKind;
0159 FunctionNameKind FNKind;
0160 bool ApproximateLine;
0161
0162 DILineInfoSpecifier(FileLineInfoKind FLIKind = FileLineInfoKind::RawValue,
0163 FunctionNameKind FNKind = FunctionNameKind::None,
0164 bool ApproximateLine = false)
0165 : FLIKind(FLIKind), FNKind(FNKind), ApproximateLine(ApproximateLine) {}
0166
0167 inline bool operator==(const DILineInfoSpecifier &RHS) const {
0168 return FLIKind == RHS.FLIKind && FNKind == RHS.FNKind;
0169 }
0170 };
0171
0172
0173 enum DIDumpTypeCounter {
0174 #define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME, OPTION) \
0175 DIDT_ID_##ENUM_NAME,
0176 #include "llvm/BinaryFormat/Dwarf.def"
0177 #undef HANDLE_DWARF_SECTION
0178 DIDT_ID_UUID,
0179 DIDT_ID_Count
0180 };
0181 static_assert(DIDT_ID_Count <= 32, "section types overflow storage");
0182
0183
0184 enum DIDumpType : unsigned {
0185 DIDT_Null,
0186 DIDT_All = ~0U,
0187 #define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME, OPTION) \
0188 DIDT_##ENUM_NAME = 1U << DIDT_ID_##ENUM_NAME,
0189 #include "llvm/BinaryFormat/Dwarf.def"
0190 #undef HANDLE_DWARF_SECTION
0191 DIDT_UUID = 1 << DIDT_ID_UUID,
0192 };
0193
0194
0195
0196 struct DIDumpOptions {
0197 unsigned DumpType = DIDT_All;
0198 unsigned ChildRecurseDepth = -1U;
0199 unsigned ParentRecurseDepth = -1U;
0200 uint16_t Version = 0;
0201 uint8_t AddrSize = 4;
0202 bool ShowAddresses = true;
0203 bool ShowChildren = false;
0204 bool ShowParents = false;
0205 bool ShowForm = false;
0206 bool SummarizeTypes = false;
0207 bool Verbose = false;
0208 bool DisplayRawContents = false;
0209 bool IsEH = false;
0210 bool DumpNonSkeleton = false;
0211 bool ShowAggregateErrors = false;
0212 std::string JsonErrSummaryFile;
0213 std::function<llvm::StringRef(uint64_t DwarfRegNum, bool IsEH)>
0214 GetNameForDWARFReg;
0215
0216
0217 static DIDumpOptions getForSingleDIE() {
0218 DIDumpOptions Opts;
0219 Opts.ChildRecurseDepth = 0;
0220 Opts.ParentRecurseDepth = 0;
0221 return Opts;
0222 }
0223
0224
0225 DIDumpOptions noImplicitRecursion() const {
0226 DIDumpOptions Opts = *this;
0227 if (ChildRecurseDepth == -1U && !ShowChildren)
0228 Opts.ChildRecurseDepth = 0;
0229 if (ParentRecurseDepth == -1U && !ShowParents)
0230 Opts.ParentRecurseDepth = 0;
0231 return Opts;
0232 }
0233
0234 std::function<void(Error)> RecoverableErrorHandler =
0235 WithColor::defaultErrorHandler;
0236 std::function<void(Error)> WarningHandler = WithColor::defaultWarningHandler;
0237 };
0238
0239 class DIContext {
0240 public:
0241 enum DIContextKind { CK_DWARF, CK_PDB, CK_BTF };
0242
0243 DIContext(DIContextKind K) : Kind(K) {}
0244 virtual ~DIContext() = default;
0245
0246 DIContextKind getKind() const { return Kind; }
0247
0248 virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
0249
0250 virtual bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) {
0251
0252 return true;
0253 }
0254
0255 virtual DILineInfo getLineInfoForAddress(
0256 object::SectionedAddress Address,
0257 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
0258 virtual DILineInfo
0259 getLineInfoForDataAddress(object::SectionedAddress Address) = 0;
0260 virtual DILineInfoTable getLineInfoForAddressRange(
0261 object::SectionedAddress Address, uint64_t Size,
0262 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
0263 virtual DIInliningInfo getInliningInfoForAddress(
0264 object::SectionedAddress Address,
0265 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
0266
0267 virtual std::vector<DILocal>
0268 getLocalsForAddress(object::SectionedAddress Address) = 0;
0269
0270 private:
0271 const DIContextKind Kind;
0272 };
0273
0274
0275
0276
0277 class LoadedObjectInfo {
0278 protected:
0279 LoadedObjectInfo() = default;
0280 LoadedObjectInfo(const LoadedObjectInfo &) = default;
0281
0282 public:
0283 virtual ~LoadedObjectInfo() = default;
0284
0285
0286
0287
0288
0289
0290
0291
0292 virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const {
0293 return 0;
0294 }
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307 virtual bool getLoadedSectionContents(const object::SectionRef &Sec,
0308 StringRef &Data) const {
0309 return false;
0310 }
0311
0312
0313
0314
0315
0316 virtual std::unique_ptr<LoadedObjectInfo> clone() const = 0;
0317 };
0318
0319 template <typename Derived, typename Base = LoadedObjectInfo>
0320 struct LoadedObjectInfoHelper : Base {
0321 protected:
0322 LoadedObjectInfoHelper(const LoadedObjectInfoHelper &) = default;
0323 LoadedObjectInfoHelper() = default;
0324
0325 public:
0326 template <typename... Ts>
0327 LoadedObjectInfoHelper(Ts &&...Args) : Base(std::forward<Ts>(Args)...) {}
0328
0329 std::unique_ptr<llvm::LoadedObjectInfo> clone() const override {
0330 return std::make_unique<Derived>(static_cast<const Derived &>(*this));
0331 }
0332 };
0333
0334 }
0335
0336 #endif