Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- DWARFContext.h -------------------------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===/
  8.  
  9. #ifndef LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
  10. #define LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
  11.  
  12. #include "llvm/ADT/SmallVector.h"
  13. #include "llvm/ADT/StringMap.h"
  14. #include "llvm/ADT/StringRef.h"
  15. #include "llvm/DebugInfo/DIContext.h"
  16. #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
  17. #include "llvm/DebugInfo/DWARF/DWARFDie.h"
  18. #include "llvm/DebugInfo/DWARF/DWARFObject.h"
  19. #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
  20. #include "llvm/Object/Binary.h"
  21. #include "llvm/Object/ObjectFile.h"
  22. #include "llvm/Support/DataExtractor.h"
  23. #include "llvm/Support/Error.h"
  24. #include "llvm/Support/Host.h"
  25. #include <cstdint>
  26. #include <memory>
  27.  
  28. namespace llvm {
  29.  
  30. class MemoryBuffer;
  31. class AppleAcceleratorTable;
  32. class DWARFCompileUnit;
  33. class DWARFDebugAbbrev;
  34. class DWARFDebugAranges;
  35. class DWARFDebugFrame;
  36. class DWARFDebugLoc;
  37. class DWARFDebugMacro;
  38. class DWARFDebugNames;
  39. class DWARFGdbIndex;
  40. class DWARFTypeUnit;
  41. class DWARFUnitIndex;
  42.  
  43. /// DWARFContext
  44. /// This data structure is the top level entity that deals with dwarf debug
  45. /// information parsing. The actual data is supplied through DWARFObj.
  46. class DWARFContext : public DIContext {
  47.   DWARFUnitVector NormalUnits;
  48.   std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> NormalTypeUnits;
  49.   std::unique_ptr<DWARFUnitIndex> CUIndex;
  50.   std::unique_ptr<DWARFGdbIndex> GdbIndex;
  51.   std::unique_ptr<DWARFUnitIndex> TUIndex;
  52.   std::unique_ptr<DWARFDebugAbbrev> Abbrev;
  53.   std::unique_ptr<DWARFDebugLoc> Loc;
  54.   std::unique_ptr<DWARFDebugAranges> Aranges;
  55.   std::unique_ptr<DWARFDebugLine> Line;
  56.   std::unique_ptr<DWARFDebugFrame> DebugFrame;
  57.   std::unique_ptr<DWARFDebugFrame> EHFrame;
  58.   std::unique_ptr<DWARFDebugMacro> Macro;
  59.   std::unique_ptr<DWARFDebugMacro> Macinfo;
  60.   std::unique_ptr<DWARFDebugNames> Names;
  61.   std::unique_ptr<AppleAcceleratorTable> AppleNames;
  62.   std::unique_ptr<AppleAcceleratorTable> AppleTypes;
  63.   std::unique_ptr<AppleAcceleratorTable> AppleNamespaces;
  64.   std::unique_ptr<AppleAcceleratorTable> AppleObjC;
  65.  
  66.   DWARFUnitVector DWOUnits;
  67.   std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> DWOTypeUnits;
  68.   std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
  69.   std::unique_ptr<DWARFDebugMacro> MacinfoDWO;
  70.   std::unique_ptr<DWARFDebugMacro> MacroDWO;
  71.  
  72.   /// The maximum DWARF version of all units.
  73.   unsigned MaxVersion = 0;
  74.  
  75.   struct DWOFile {
  76.     object::OwningBinary<object::ObjectFile> File;
  77.     std::unique_ptr<DWARFContext> Context;
  78.   };
  79.   StringMap<std::weak_ptr<DWOFile>> DWOFiles;
  80.   std::weak_ptr<DWOFile> DWP;
  81.   bool CheckedForDWP = false;
  82.   std::string DWPName;
  83.   std::function<void(Error)> RecoverableErrorHandler =
  84.       WithColor::defaultErrorHandler;
  85.   std::function<void(Error)> WarningHandler = WithColor::defaultWarningHandler;
  86.  
  87.   /// Read compile units from the debug_info section (if necessary)
  88.   /// and type units from the debug_types sections (if necessary)
  89.   /// and store them in NormalUnits.
  90.   void parseNormalUnits();
  91.  
  92.   /// Read compile units from the debug_info.dwo section (if necessary)
  93.   /// and type units from the debug_types.dwo section (if necessary)
  94.   /// and store them in DWOUnits.
  95.   /// If \p Lazy is true, set up to parse but don't actually parse them.
  96.   enum { EagerParse = false, LazyParse = true };
  97.   void parseDWOUnits(bool Lazy = false);
  98.  
  99.   std::unique_ptr<const DWARFObject> DObj;
  100.  
  101.   /// Helper enum to distinguish between macro[.dwo] and macinfo[.dwo]
  102.   /// section.
  103.   enum MacroSecType {
  104.     MacinfoSection,
  105.     MacinfoDwoSection,
  106.     MacroSection,
  107.     MacroDwoSection
  108.   };
  109.  
  110.   // When set parses debug_info.dwo/debug_abbrev.dwo manually and populates CU
  111.   // Index, and TU Index for DWARF5.
  112.   bool ParseCUTUIndexManually = false;
  113.  
  114. public:
  115.   DWARFContext(std::unique_ptr<const DWARFObject> DObj,
  116.                std::string DWPName = "",
  117.                std::function<void(Error)> RecoverableErrorHandler =
  118.                    WithColor::defaultErrorHandler,
  119.                std::function<void(Error)> WarningHandler =
  120.                    WithColor::defaultWarningHandler);
  121.   ~DWARFContext() override;
  122.  
  123.   DWARFContext(DWARFContext &) = delete;
  124.   DWARFContext &operator=(DWARFContext &) = delete;
  125.  
  126.   const DWARFObject &getDWARFObj() const { return *DObj; }
  127.  
  128.   static bool classof(const DIContext *DICtx) {
  129.     return DICtx->getKind() == CK_DWARF;
  130.   }
  131.  
  132.   /// Dump a textual representation to \p OS. If any \p DumpOffsets are present,
  133.   /// dump only the record at the specified offset.
  134.   void dump(raw_ostream &OS, DIDumpOptions DumpOpts,
  135.             std::array<std::optional<uint64_t>, DIDT_ID_Count> DumpOffsets);
  136.  
  137.   void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override {
  138.     std::array<std::optional<uint64_t>, DIDT_ID_Count> DumpOffsets;
  139.     dump(OS, DumpOpts, DumpOffsets);
  140.   }
  141.  
  142.   bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override;
  143.  
  144.   using unit_iterator_range = DWARFUnitVector::iterator_range;
  145.   using compile_unit_range = DWARFUnitVector::compile_unit_range;
  146.  
  147.   /// Get units from .debug_info in this context.
  148.   unit_iterator_range info_section_units() {
  149.     parseNormalUnits();
  150.     return unit_iterator_range(NormalUnits.begin(),
  151.                                NormalUnits.begin() +
  152.                                    NormalUnits.getNumInfoUnits());
  153.   }
  154.  
  155.   const DWARFUnitVector &getNormalUnitsVector() {
  156.     parseNormalUnits();
  157.     return NormalUnits;
  158.   }
  159.  
  160.   /// Get units from .debug_types in this context.
  161.   unit_iterator_range types_section_units() {
  162.     parseNormalUnits();
  163.     return unit_iterator_range(
  164.         NormalUnits.begin() + NormalUnits.getNumInfoUnits(), NormalUnits.end());
  165.   }
  166.  
  167.   /// Get compile units in this context.
  168.   compile_unit_range compile_units() {
  169.     return make_filter_range(info_section_units(), isCompileUnit);
  170.   }
  171.  
  172.   // If you want type_units(), it'll need to be a concat iterator of a filter of
  173.   // TUs in info_section + all the (all type) units in types_section
  174.  
  175.   /// Get all normal compile/type units in this context.
  176.   unit_iterator_range normal_units() {
  177.     parseNormalUnits();
  178.     return unit_iterator_range(NormalUnits.begin(), NormalUnits.end());
  179.   }
  180.  
  181.   /// Get units from .debug_info..dwo in the DWO context.
  182.   unit_iterator_range dwo_info_section_units() {
  183.     parseDWOUnits();
  184.     return unit_iterator_range(DWOUnits.begin(),
  185.                                DWOUnits.begin() + DWOUnits.getNumInfoUnits());
  186.   }
  187.  
  188.   const DWARFUnitVector &getDWOUnitsVector() {
  189.     parseDWOUnits();
  190.     return DWOUnits;
  191.   }
  192.  
  193.   /// Get units from .debug_types.dwo in the DWO context.
  194.   unit_iterator_range dwo_types_section_units() {
  195.     parseDWOUnits();
  196.     return unit_iterator_range(DWOUnits.begin() + DWOUnits.getNumInfoUnits(),
  197.                                DWOUnits.end());
  198.   }
  199.  
  200.   /// Get compile units in the DWO context.
  201.   compile_unit_range dwo_compile_units() {
  202.     return make_filter_range(dwo_info_section_units(), isCompileUnit);
  203.   }
  204.  
  205.   // If you want dwo_type_units(), it'll need to be a concat iterator of a
  206.   // filter of TUs in dwo_info_section + all the (all type) units in
  207.   // dwo_types_section.
  208.  
  209.   /// Get all units in the DWO context.
  210.   unit_iterator_range dwo_units() {
  211.     parseDWOUnits();
  212.     return unit_iterator_range(DWOUnits.begin(), DWOUnits.end());
  213.   }
  214.  
  215.   /// Get the number of compile units in this context.
  216.   unsigned getNumCompileUnits() {
  217.     parseNormalUnits();
  218.     return NormalUnits.getNumInfoUnits();
  219.   }
  220.  
  221.   /// Get the number of type units in this context.
  222.   unsigned getNumTypeUnits() {
  223.     parseNormalUnits();
  224.     return NormalUnits.getNumTypesUnits();
  225.   }
  226.  
  227.   /// Get the number of compile units in the DWO context.
  228.   unsigned getNumDWOCompileUnits() {
  229.     parseDWOUnits();
  230.     return DWOUnits.getNumInfoUnits();
  231.   }
  232.  
  233.   /// Get the number of type units in the DWO context.
  234.   unsigned getNumDWOTypeUnits() {
  235.     parseDWOUnits();
  236.     return DWOUnits.getNumTypesUnits();
  237.   }
  238.  
  239.   /// Get the unit at the specified index.
  240.   DWARFUnit *getUnitAtIndex(unsigned index) {
  241.     parseNormalUnits();
  242.     return NormalUnits[index].get();
  243.   }
  244.  
  245.   /// Get the unit at the specified index for the DWO units.
  246.   DWARFUnit *getDWOUnitAtIndex(unsigned index) {
  247.     parseDWOUnits();
  248.     return DWOUnits[index].get();
  249.   }
  250.  
  251.   DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash);
  252.   DWARFTypeUnit *getTypeUnitForHash(uint16_t Version, uint64_t Hash, bool IsDWO);
  253.  
  254.   /// Return the compile unit that includes an offset (relative to .debug_info).
  255.   DWARFCompileUnit *getCompileUnitForOffset(uint64_t Offset);
  256.  
  257.   /// Get a DIE given an exact offset.
  258.   DWARFDie getDIEForOffset(uint64_t Offset);
  259.  
  260.   unsigned getMaxVersion() {
  261.     // Ensure info units have been parsed to discover MaxVersion
  262.     info_section_units();
  263.     return MaxVersion;
  264.   }
  265.  
  266.   unsigned getMaxDWOVersion() {
  267.     // Ensure DWO info units have been parsed to discover MaxVersion
  268.     dwo_info_section_units();
  269.     return MaxVersion;
  270.   }
  271.  
  272.   void setMaxVersionIfGreater(unsigned Version) {
  273.     if (Version > MaxVersion)
  274.       MaxVersion = Version;
  275.   }
  276.  
  277.   const DWARFUnitIndex &getCUIndex();
  278.   DWARFGdbIndex &getGdbIndex();
  279.   const DWARFUnitIndex &getTUIndex();
  280.  
  281.   /// Get a pointer to the parsed DebugAbbrev object.
  282.   const DWARFDebugAbbrev *getDebugAbbrev();
  283.  
  284.   /// Get a pointer to the parsed DebugLoc object.
  285.   const DWARFDebugLoc *getDebugLoc();
  286.  
  287.   /// Get a pointer to the parsed dwo abbreviations object.
  288.   const DWARFDebugAbbrev *getDebugAbbrevDWO();
  289.  
  290.   /// Get a pointer to the parsed DebugAranges object.
  291.   const DWARFDebugAranges *getDebugAranges();
  292.  
  293.   /// Get a pointer to the parsed frame information object.
  294.   Expected<const DWARFDebugFrame *> getDebugFrame();
  295.  
  296.   /// Get a pointer to the parsed eh frame information object.
  297.   Expected<const DWARFDebugFrame *> getEHFrame();
  298.  
  299.   /// Get a pointer to the parsed DebugMacinfo information object.
  300.   const DWARFDebugMacro *getDebugMacinfo();
  301.  
  302.   /// Get a pointer to the parsed DebugMacinfoDWO information object.
  303.   const DWARFDebugMacro *getDebugMacinfoDWO();
  304.  
  305.   /// Get a pointer to the parsed DebugMacro information object.
  306.   const DWARFDebugMacro *getDebugMacro();
  307.  
  308.   /// Get a pointer to the parsed DebugMacroDWO information object.
  309.   const DWARFDebugMacro *getDebugMacroDWO();
  310.  
  311.   /// Get a reference to the parsed accelerator table object.
  312.   const DWARFDebugNames &getDebugNames();
  313.  
  314.   /// Get a reference to the parsed accelerator table object.
  315.   const AppleAcceleratorTable &getAppleNames();
  316.  
  317.   /// Get a reference to the parsed accelerator table object.
  318.   const AppleAcceleratorTable &getAppleTypes();
  319.  
  320.   /// Get a reference to the parsed accelerator table object.
  321.   const AppleAcceleratorTable &getAppleNamespaces();
  322.  
  323.   /// Get a reference to the parsed accelerator table object.
  324.   const AppleAcceleratorTable &getAppleObjC();
  325.  
  326.   /// Get a pointer to a parsed line table corresponding to a compile unit.
  327.   /// Report any parsing issues as warnings on stderr.
  328.   const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *U);
  329.  
  330.   /// Get a pointer to a parsed line table corresponding to a compile unit.
  331.   /// Report any recoverable parsing problems using the handler.
  332.   Expected<const DWARFDebugLine::LineTable *>
  333.   getLineTableForUnit(DWARFUnit *U,
  334.                       function_ref<void(Error)> RecoverableErrorHandler);
  335.  
  336.   // Clear the line table object corresponding to a compile unit for memory
  337.   // management purpose. When it's referred to again, it'll be re-populated.
  338.   void clearLineTableForUnit(DWARFUnit *U);
  339.  
  340.   DataExtractor getStringExtractor() const {
  341.     return DataExtractor(DObj->getStrSection(), false, 0);
  342.   }
  343.   DataExtractor getStringDWOExtractor() const {
  344.     return DataExtractor(DObj->getStrDWOSection(), false, 0);
  345.   }
  346.   DataExtractor getLineStringExtractor() const {
  347.     return DataExtractor(DObj->getLineStrSection(), false, 0);
  348.   }
  349.  
  350.   /// Wraps the returned DIEs for a given address.
  351.   struct DIEsForAddress {
  352.     DWARFCompileUnit *CompileUnit = nullptr;
  353.     DWARFDie FunctionDIE;
  354.     DWARFDie BlockDIE;
  355.     explicit operator bool() const { return CompileUnit != nullptr; }
  356.   };
  357.  
  358.   /// Get the compilation unit, the function DIE and lexical block DIE for the
  359.   /// given address where applicable.
  360.   /// TODO: change input parameter from "uint64_t Address"
  361.   ///       into "SectionedAddress Address"
  362.   DIEsForAddress getDIEsForAddress(uint64_t Address);
  363.  
  364.   DILineInfo getLineInfoForAddress(
  365.       object::SectionedAddress Address,
  366.       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
  367.   DILineInfo
  368.   getLineInfoForDataAddress(object::SectionedAddress Address) override;
  369.   DILineInfoTable getLineInfoForAddressRange(
  370.       object::SectionedAddress Address, uint64_t Size,
  371.       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
  372.   DIInliningInfo getInliningInfoForAddress(
  373.       object::SectionedAddress Address,
  374.       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
  375.  
  376.   std::vector<DILocal>
  377.   getLocalsForAddress(object::SectionedAddress Address) override;
  378.  
  379.   bool isLittleEndian() const { return DObj->isLittleEndian(); }
  380.   static unsigned getMaxSupportedVersion() { return 5; }
  381.   static bool isSupportedVersion(unsigned version) {
  382.     return version >= 2 && version <= getMaxSupportedVersion();
  383.   }
  384.  
  385.   static SmallVector<uint8_t, 3> getSupportedAddressSizes() {
  386.     return {2, 4, 8};
  387.   }
  388.   static bool isAddressSizeSupported(unsigned AddressSize) {
  389.     return llvm::is_contained(getSupportedAddressSizes(), AddressSize);
  390.   }
  391.   template <typename... Ts>
  392.   static Error checkAddressSizeSupported(unsigned AddressSize,
  393.                                          std::error_code EC, char const *Fmt,
  394.                                          const Ts &...Vals) {
  395.     if (isAddressSizeSupported(AddressSize))
  396.       return Error::success();
  397.     std::string Buffer;
  398.     raw_string_ostream Stream(Buffer);
  399.     Stream << format(Fmt, Vals...)
  400.            << " has unsupported address size: " << AddressSize
  401.            << " (supported are ";
  402.     ListSeparator LS;
  403.     for (unsigned Size : DWARFContext::getSupportedAddressSizes())
  404.       Stream << LS << Size;
  405.     Stream << ')';
  406.     return make_error<StringError>(Stream.str(), EC);
  407.   }
  408.  
  409.   std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath);
  410.  
  411.   function_ref<void(Error)> getRecoverableErrorHandler() {
  412.     return RecoverableErrorHandler;
  413.   }
  414.  
  415.   function_ref<void(Error)> getWarningHandler() { return WarningHandler; }
  416.  
  417.   enum class ProcessDebugRelocations { Process, Ignore };
  418.  
  419.   static std::unique_ptr<DWARFContext>
  420.   create(const object::ObjectFile &Obj,
  421.          ProcessDebugRelocations RelocAction = ProcessDebugRelocations::Process,
  422.          const LoadedObjectInfo *L = nullptr, std::string DWPName = "",
  423.          std::function<void(Error)> RecoverableErrorHandler =
  424.              WithColor::defaultErrorHandler,
  425.          std::function<void(Error)> WarningHandler =
  426.              WithColor::defaultWarningHandler);
  427.  
  428.   static std::unique_ptr<DWARFContext>
  429.   create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
  430.          uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost,
  431.          std::function<void(Error)> RecoverableErrorHandler =
  432.              WithColor::defaultErrorHandler,
  433.          std::function<void(Error)> WarningHandler =
  434.              WithColor::defaultWarningHandler);
  435.  
  436.   /// Get address size from CUs.
  437.   /// TODO: refactor compile_units() to make this const.
  438.   uint8_t getCUAddrSize();
  439.  
  440.   Triple::ArchType getArch() const {
  441.     return getDWARFObj().getFile()->getArch();
  442.   }
  443.  
  444.   /// Return the compile unit which contains instruction with provided
  445.   /// address.
  446.   /// TODO: change input parameter from "uint64_t Address"
  447.   ///       into "SectionedAddress Address"
  448.   DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
  449.  
  450.   /// Returns whether CU/TU should be populated manually. TU Index populated
  451.   /// manually only for DWARF5.
  452.   bool getParseCUTUIndexManually() const { return ParseCUTUIndexManually; }
  453.  
  454.   /// Sets whether CU/TU should be populated manually. TU Index populated
  455.   /// manually only for DWARF5.
  456.   void setParseCUTUIndexManually(bool PCUTU) { ParseCUTUIndexManually = PCUTU; }
  457.  
  458. private:
  459.   /// Parse a macro[.dwo] or macinfo[.dwo] section.
  460.   std::unique_ptr<DWARFDebugMacro>
  461.   parseMacroOrMacinfo(MacroSecType SectionType);
  462.  
  463.   void addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram, DWARFDie Die,
  464.                        std::vector<DILocal> &Result);
  465. };
  466.  
  467. } // end namespace llvm
  468.  
  469. #endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
  470.