File indexing completed on 2026-05-10 08:43:41
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
0010 #define LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
0011
0012 #include "llvm/ADT/SmallVector.h"
0013 #include "llvm/ADT/StringExtras.h"
0014 #include "llvm/ADT/StringMap.h"
0015 #include "llvm/ADT/StringRef.h"
0016 #include "llvm/DebugInfo/DIContext.h"
0017 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
0018 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
0019 #include "llvm/DebugInfo/DWARF/DWARFObject.h"
0020 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
0021 #include "llvm/Object/Binary.h"
0022 #include "llvm/Object/ObjectFile.h"
0023 #include "llvm/Support/DataExtractor.h"
0024 #include "llvm/Support/Error.h"
0025 #include "llvm/TargetParser/Host.h"
0026 #include <cstdint>
0027 #include <memory>
0028 #include <mutex>
0029
0030 namespace llvm {
0031
0032 class MemoryBuffer;
0033 class AppleAcceleratorTable;
0034 class DWARFCompileUnit;
0035 class DWARFDebugAbbrev;
0036 class DWARFDebugAranges;
0037 class DWARFDebugFrame;
0038 class DWARFDebugLoc;
0039 class DWARFDebugMacro;
0040 class DWARFDebugNames;
0041 class DWARFGdbIndex;
0042 class DWARFTypeUnit;
0043 class DWARFUnitIndex;
0044
0045
0046
0047
0048 class DWARFContext : public DIContext {
0049 public:
0050
0051
0052
0053
0054
0055
0056
0057 class DWARFContextState {
0058 protected:
0059
0060
0061 enum MacroSecType {
0062 MacinfoSection,
0063 MacinfoDwoSection,
0064 MacroSection,
0065 MacroDwoSection
0066 };
0067
0068 DWARFContext &D;
0069 public:
0070 DWARFContextState(DWARFContext &DC) : D(DC) {}
0071 virtual ~DWARFContextState() = default;
0072 virtual DWARFUnitVector &getNormalUnits() = 0;
0073 virtual DWARFUnitVector &getDWOUnits(bool Lazy = false) = 0;
0074 virtual const DWARFDebugAbbrev *getDebugAbbrevDWO() = 0;
0075 virtual const DWARFUnitIndex &getCUIndex() = 0;
0076 virtual const DWARFUnitIndex &getTUIndex() = 0;
0077 virtual DWARFGdbIndex &getGdbIndex() = 0;
0078 virtual const DWARFDebugAbbrev *getDebugAbbrev() = 0;
0079 virtual const DWARFDebugLoc *getDebugLoc() = 0;
0080 virtual const DWARFDebugAranges *getDebugAranges() = 0;
0081 virtual Expected<const DWARFDebugLine::LineTable *>
0082 getLineTableForUnit(DWARFUnit *U,
0083 function_ref<void(Error)> RecoverableErrHandler) = 0;
0084 virtual void clearLineTableForUnit(DWARFUnit *U) = 0;
0085 virtual Expected<const DWARFDebugFrame *> getDebugFrame() = 0;
0086 virtual Expected<const DWARFDebugFrame *> getEHFrame() = 0;
0087 virtual const DWARFDebugMacro *getDebugMacinfo() = 0;
0088 virtual const DWARFDebugMacro *getDebugMacinfoDWO() = 0;
0089 virtual const DWARFDebugMacro *getDebugMacro() = 0;
0090 virtual const DWARFDebugMacro *getDebugMacroDWO() = 0;
0091 virtual const DWARFDebugNames &getDebugNames() = 0;
0092 virtual const AppleAcceleratorTable &getAppleNames() = 0;
0093 virtual const AppleAcceleratorTable &getAppleTypes() = 0;
0094 virtual const AppleAcceleratorTable &getAppleNamespaces() = 0;
0095 virtual const AppleAcceleratorTable &getAppleObjC() = 0;
0096 virtual std::shared_ptr<DWARFContext>
0097 getDWOContext(StringRef AbsolutePath) = 0;
0098 virtual const DenseMap<uint64_t, DWARFTypeUnit *> &
0099 getTypeUnitMap(bool IsDWO) = 0;
0100 virtual bool isThreadSafe() const = 0;
0101
0102
0103 std::unique_ptr<DWARFDebugMacro>
0104 parseMacroOrMacinfo(MacroSecType SectionType);
0105
0106 };
0107 friend class DWARFContextState;
0108
0109 private:
0110
0111
0112 std::unique_ptr<DWARFContextState> State;
0113
0114
0115 unsigned MaxVersion = 0;
0116
0117 std::function<void(Error)> RecoverableErrorHandler =
0118 WithColor::defaultErrorHandler;
0119 std::function<void(Error)> WarningHandler = WithColor::defaultWarningHandler;
0120
0121
0122
0123
0124
0125 enum { EagerParse = false, LazyParse = true };
0126 DWARFUnitVector &getDWOUnits(bool Lazy = false);
0127
0128 std::unique_ptr<const DWARFObject> DObj;
0129
0130
0131
0132 bool ParseCUTUIndexManually = false;
0133
0134 public:
0135 DWARFContext(std::unique_ptr<const DWARFObject> DObj,
0136 std::string DWPName = "",
0137 std::function<void(Error)> RecoverableErrorHandler =
0138 WithColor::defaultErrorHandler,
0139 std::function<void(Error)> WarningHandler =
0140 WithColor::defaultWarningHandler,
0141 bool ThreadSafe = false);
0142 ~DWARFContext() override;
0143
0144 DWARFContext(DWARFContext &) = delete;
0145 DWARFContext &operator=(DWARFContext &) = delete;
0146
0147 const DWARFObject &getDWARFObj() const { return *DObj; }
0148
0149 static bool classof(const DIContext *DICtx) {
0150 return DICtx->getKind() == CK_DWARF;
0151 }
0152
0153
0154
0155 void dump(raw_ostream &OS, DIDumpOptions DumpOpts,
0156 std::array<std::optional<uint64_t>, DIDT_ID_Count> DumpOffsets);
0157
0158 void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override {
0159 std::array<std::optional<uint64_t>, DIDT_ID_Count> DumpOffsets;
0160 dump(OS, DumpOpts, DumpOffsets);
0161 }
0162
0163 bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override;
0164
0165 using unit_iterator_range = DWARFUnitVector::iterator_range;
0166 using compile_unit_range = DWARFUnitVector::compile_unit_range;
0167
0168
0169 unit_iterator_range info_section_units() {
0170 DWARFUnitVector &NormalUnits = State->getNormalUnits();
0171 return unit_iterator_range(NormalUnits.begin(),
0172 NormalUnits.begin() +
0173 NormalUnits.getNumInfoUnits());
0174 }
0175
0176 const DWARFUnitVector &getNormalUnitsVector() {
0177 return State->getNormalUnits();
0178 }
0179
0180
0181 unit_iterator_range types_section_units() {
0182 DWARFUnitVector &NormalUnits = State->getNormalUnits();
0183 return unit_iterator_range(
0184 NormalUnits.begin() + NormalUnits.getNumInfoUnits(), NormalUnits.end());
0185 }
0186
0187
0188 compile_unit_range compile_units() {
0189 return make_filter_range(info_section_units(), isCompileUnit);
0190 }
0191
0192
0193
0194
0195
0196 unit_iterator_range normal_units() {
0197 DWARFUnitVector &NormalUnits = State->getNormalUnits();
0198 return unit_iterator_range(NormalUnits.begin(), NormalUnits.end());
0199 }
0200
0201
0202 unit_iterator_range dwo_info_section_units() {
0203 DWARFUnitVector &DWOUnits = State->getDWOUnits();
0204 return unit_iterator_range(DWOUnits.begin(),
0205 DWOUnits.begin() + DWOUnits.getNumInfoUnits());
0206 }
0207
0208 const DWARFUnitVector &getDWOUnitsVector() {
0209 return State->getDWOUnits();
0210 }
0211
0212
0213 bool isDWP() const;
0214
0215
0216 unit_iterator_range dwo_types_section_units() {
0217 DWARFUnitVector &DWOUnits = State->getDWOUnits();
0218 return unit_iterator_range(DWOUnits.begin() + DWOUnits.getNumInfoUnits(),
0219 DWOUnits.end());
0220 }
0221
0222
0223 compile_unit_range dwo_compile_units() {
0224 return make_filter_range(dwo_info_section_units(), isCompileUnit);
0225 }
0226
0227
0228
0229
0230
0231
0232 unit_iterator_range dwo_units() {
0233 DWARFUnitVector &DWOUnits = State->getDWOUnits();
0234 return unit_iterator_range(DWOUnits.begin(), DWOUnits.end());
0235 }
0236
0237
0238 unsigned getNumCompileUnits() {
0239 return State->getNormalUnits().getNumInfoUnits();
0240 }
0241
0242
0243 unsigned getNumTypeUnits() {
0244 return State->getNormalUnits().getNumTypesUnits();
0245 }
0246
0247
0248 unsigned getNumDWOCompileUnits() {
0249 return State->getDWOUnits().getNumInfoUnits();
0250 }
0251
0252
0253 unsigned getNumDWOTypeUnits() {
0254 return State->getDWOUnits().getNumTypesUnits();
0255 }
0256
0257
0258 DWARFUnit *getUnitAtIndex(unsigned index) {
0259 return State->getNormalUnits()[index].get();
0260 }
0261
0262
0263 DWARFUnit *getDWOUnitAtIndex(unsigned index) {
0264 return State->getDWOUnits()[index].get();
0265 }
0266
0267 DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash);
0268 DWARFTypeUnit *getTypeUnitForHash(uint64_t Hash, bool IsDWO);
0269
0270
0271 DWARFUnit *getUnitForOffset(uint64_t Offset);
0272
0273
0274 DWARFCompileUnit *getCompileUnitForOffset(uint64_t Offset);
0275
0276
0277 DWARFDie getDIEForOffset(uint64_t Offset);
0278
0279 unsigned getMaxVersion() {
0280
0281 info_section_units();
0282 return MaxVersion;
0283 }
0284
0285 unsigned getMaxDWOVersion() {
0286
0287 dwo_info_section_units();
0288 return MaxVersion;
0289 }
0290
0291 void setMaxVersionIfGreater(unsigned Version) {
0292 if (Version > MaxVersion)
0293 MaxVersion = Version;
0294 }
0295
0296 const DWARFUnitIndex &getCUIndex();
0297 DWARFGdbIndex &getGdbIndex();
0298 const DWARFUnitIndex &getTUIndex();
0299
0300
0301 const DWARFDebugAbbrev *getDebugAbbrev();
0302
0303
0304 const DWARFDebugLoc *getDebugLoc();
0305
0306
0307 const DWARFDebugAbbrev *getDebugAbbrevDWO();
0308
0309
0310 const DWARFDebugAranges *getDebugAranges();
0311
0312
0313 Expected<const DWARFDebugFrame *> getDebugFrame();
0314
0315
0316 Expected<const DWARFDebugFrame *> getEHFrame();
0317
0318
0319 const DWARFDebugMacro *getDebugMacinfo();
0320
0321
0322 const DWARFDebugMacro *getDebugMacinfoDWO();
0323
0324
0325 const DWARFDebugMacro *getDebugMacro();
0326
0327
0328 const DWARFDebugMacro *getDebugMacroDWO();
0329
0330
0331 const DWARFDebugNames &getDebugNames();
0332
0333
0334 const AppleAcceleratorTable &getAppleNames();
0335
0336
0337 const AppleAcceleratorTable &getAppleTypes();
0338
0339
0340 const AppleAcceleratorTable &getAppleNamespaces();
0341
0342
0343 const AppleAcceleratorTable &getAppleObjC();
0344
0345
0346
0347 const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *U);
0348
0349
0350
0351 Expected<const DWARFDebugLine::LineTable *>
0352 getLineTableForUnit(DWARFUnit *U,
0353 function_ref<void(Error)> RecoverableErrorHandler);
0354
0355
0356
0357 void clearLineTableForUnit(DWARFUnit *U);
0358
0359 DataExtractor getStringExtractor() const {
0360 return DataExtractor(DObj->getStrSection(), false, 0);
0361 }
0362 DataExtractor getStringDWOExtractor() const {
0363 return DataExtractor(DObj->getStrDWOSection(), false, 0);
0364 }
0365 DataExtractor getLineStringExtractor() const {
0366 return DataExtractor(DObj->getLineStrSection(), false, 0);
0367 }
0368
0369
0370 struct DIEsForAddress {
0371 DWARFCompileUnit *CompileUnit = nullptr;
0372 DWARFDie FunctionDIE;
0373 DWARFDie BlockDIE;
0374 explicit operator bool() const { return CompileUnit != nullptr; }
0375 };
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387 DIEsForAddress getDIEsForAddress(uint64_t Address, bool CheckDWO = false);
0388
0389 DILineInfo getLineInfoForAddress(
0390 object::SectionedAddress Address,
0391 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
0392 DILineInfo
0393 getLineInfoForDataAddress(object::SectionedAddress Address) override;
0394 DILineInfoTable getLineInfoForAddressRange(
0395 object::SectionedAddress Address, uint64_t Size,
0396 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
0397 DIInliningInfo getInliningInfoForAddress(
0398 object::SectionedAddress Address,
0399 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
0400
0401 std::vector<DILocal>
0402 getLocalsForAddress(object::SectionedAddress Address) override;
0403
0404 bool isLittleEndian() const { return DObj->isLittleEndian(); }
0405 static unsigned getMaxSupportedVersion() { return 5; }
0406 static bool isSupportedVersion(unsigned version) {
0407 return version >= 2 && version <= getMaxSupportedVersion();
0408 }
0409
0410 static SmallVector<uint8_t, 3> getSupportedAddressSizes() {
0411 return {2, 4, 8};
0412 }
0413 static bool isAddressSizeSupported(unsigned AddressSize) {
0414 return llvm::is_contained(getSupportedAddressSizes(), AddressSize);
0415 }
0416 template <typename... Ts>
0417 static Error checkAddressSizeSupported(unsigned AddressSize,
0418 std::error_code EC, char const *Fmt,
0419 const Ts &...Vals) {
0420 if (isAddressSizeSupported(AddressSize))
0421 return Error::success();
0422 std::string Buffer;
0423 raw_string_ostream Stream(Buffer);
0424 Stream << format(Fmt, Vals...)
0425 << " has unsupported address size: " << AddressSize
0426 << " (supported are ";
0427 ListSeparator LS;
0428 for (unsigned Size : DWARFContext::getSupportedAddressSizes())
0429 Stream << LS << Size;
0430 Stream << ')';
0431 return make_error<StringError>(Buffer, EC);
0432 }
0433
0434 std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath);
0435
0436 function_ref<void(Error)> getRecoverableErrorHandler() {
0437 return RecoverableErrorHandler;
0438 }
0439
0440 function_ref<void(Error)> getWarningHandler() { return WarningHandler; }
0441
0442 enum class ProcessDebugRelocations { Process, Ignore };
0443
0444 static std::unique_ptr<DWARFContext>
0445 create(const object::ObjectFile &Obj,
0446 ProcessDebugRelocations RelocAction = ProcessDebugRelocations::Process,
0447 const LoadedObjectInfo *L = nullptr, std::string DWPName = "",
0448 std::function<void(Error)> RecoverableErrorHandler =
0449 WithColor::defaultErrorHandler,
0450 std::function<void(Error)> WarningHandler =
0451 WithColor::defaultWarningHandler,
0452 bool ThreadSafe = false);
0453
0454 static std::unique_ptr<DWARFContext>
0455 create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
0456 uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost,
0457 std::function<void(Error)> RecoverableErrorHandler =
0458 WithColor::defaultErrorHandler,
0459 std::function<void(Error)> WarningHandler =
0460 WithColor::defaultWarningHandler,
0461 bool ThreadSafe = false);
0462
0463
0464
0465 uint8_t getCUAddrSize();
0466
0467 Triple::ArchType getArch() const {
0468 return getDWARFObj().getFile()->getArch();
0469 }
0470
0471
0472
0473
0474
0475 DWARFCompileUnit *getCompileUnitForCodeAddress(uint64_t Address);
0476
0477
0478
0479
0480
0481
0482
0483
0484 DWARFCompileUnit *getCompileUnitForDataAddress(uint64_t Address);
0485
0486
0487
0488 bool getParseCUTUIndexManually() const { return ParseCUTUIndexManually; }
0489
0490
0491
0492 void setParseCUTUIndexManually(bool PCUTU) { ParseCUTUIndexManually = PCUTU; }
0493
0494 private:
0495 void addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram, DWARFDie Die,
0496 std::vector<DILocal> &Result);
0497 };
0498
0499 }
0500
0501 #endif