DebugMap.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. //=- tools/dsymutil/DebugMap.h - Generic debug map representation -*- 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. /// \file
  10. ///
  11. /// This file contains the class declaration of the DebugMap
  12. /// entity. A DebugMap lists all the object files linked together to
  13. /// produce an executable along with the linked address of all the
  14. /// atoms used in these object files.
  15. /// The DebugMap is an input to the DwarfLinker class that will
  16. /// extract the Dwarf debug information from the referenced object
  17. /// files and link their usefull debug info together.
  18. //
  19. //===----------------------------------------------------------------------===//
  20. #ifndef LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H
  21. #define LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H
  22. #include "llvm/ADT/DenseMap.h"
  23. #include "llvm/ADT/Optional.h"
  24. #include "llvm/ADT/StringMap.h"
  25. #include "llvm/ADT/StringRef.h"
  26. #include "llvm/ADT/Triple.h"
  27. #include "llvm/ADT/iterator_range.h"
  28. #include "llvm/Object/MachO.h"
  29. #include "llvm/Support/Chrono.h"
  30. #include "llvm/Support/ErrorOr.h"
  31. #include "llvm/Support/YAMLTraits.h"
  32. #include <chrono>
  33. #include <cstddef>
  34. #include <cstdint>
  35. #include <memory>
  36. #include <string>
  37. #include <utility>
  38. #include <vector>
  39. namespace llvm {
  40. class raw_ostream;
  41. namespace dsymutil {
  42. class DebugMapObject;
  43. /// The DebugMap object stores the list of object files to query for debug
  44. /// information along with the mapping between the symbols' addresses in the
  45. /// object file to their linked address in the linked binary.
  46. ///
  47. /// A DebugMap producer could look like this:
  48. /// DebugMap *DM = new DebugMap();
  49. /// for (const auto &Obj: LinkedObjects) {
  50. /// DebugMapObject &DMO = DM->addDebugMapObject(Obj.getPath());
  51. /// for (const auto &Sym: Obj.getLinkedSymbols())
  52. /// DMO.addSymbol(Sym.getName(), Sym.getObjectFileAddress(),
  53. /// Sym.getBinaryAddress());
  54. /// }
  55. ///
  56. /// A DebugMap consumer can then use the map to link the debug
  57. /// information. For example something along the lines of:
  58. /// for (const auto &DMO: DM->objects()) {
  59. /// auto Obj = createBinary(DMO.getObjectFilename());
  60. /// for (auto &DIE: Obj.getDwarfDIEs()) {
  61. /// if (SymbolMapping *Sym = DMO.lookup(DIE.getName()))
  62. /// DIE.relocate(Sym->ObjectAddress, Sym->BinaryAddress);
  63. /// else
  64. /// DIE.discardSubtree();
  65. /// }
  66. /// }
  67. class DebugMap {
  68. Triple BinaryTriple;
  69. std::string BinaryPath;
  70. std::vector<uint8_t> BinaryUUID;
  71. using ObjectContainer = std::vector<std::unique_ptr<DebugMapObject>>;
  72. ObjectContainer Objects;
  73. /// For YAML IO support.
  74. ///@{
  75. friend yaml::MappingTraits<std::unique_ptr<DebugMap>>;
  76. friend yaml::MappingTraits<DebugMap>;
  77. DebugMap() = default;
  78. ///@}
  79. public:
  80. DebugMap(const Triple &BinaryTriple, StringRef BinaryPath,
  81. ArrayRef<uint8_t> BinaryUUID = ArrayRef<uint8_t>())
  82. : BinaryTriple(BinaryTriple), BinaryPath(std::string(BinaryPath)),
  83. BinaryUUID(BinaryUUID.begin(), BinaryUUID.end()) {}
  84. using const_iterator = ObjectContainer::const_iterator;
  85. iterator_range<const_iterator> objects() const {
  86. return make_range(begin(), end());
  87. }
  88. const_iterator begin() const { return Objects.begin(); }
  89. const_iterator end() const { return Objects.end(); }
  90. unsigned getNumberOfObjects() const { return Objects.size(); }
  91. /// This function adds an DebugMapObject to the list owned by this
  92. /// debug map.
  93. DebugMapObject &
  94. addDebugMapObject(StringRef ObjectFilePath,
  95. sys::TimePoint<std::chrono::seconds> Timestamp,
  96. uint8_t Type = llvm::MachO::N_OSO);
  97. const Triple &getTriple() const { return BinaryTriple; }
  98. ArrayRef<uint8_t> getUUID() const { return ArrayRef<uint8_t>(BinaryUUID); }
  99. StringRef getBinaryPath() const { return BinaryPath; }
  100. void print(raw_ostream &OS) const;
  101. #ifndef NDEBUG
  102. void dump() const;
  103. #endif
  104. /// Read a debug map for \a InputFile.
  105. static ErrorOr<std::vector<std::unique_ptr<DebugMap>>>
  106. parseYAMLDebugMap(StringRef InputFile, StringRef PrependPath, bool Verbose);
  107. };
  108. /// The DebugMapObject represents one object file described by the DebugMap. It
  109. /// contains a list of mappings between addresses in the object file and in the
  110. /// linked binary for all the linked atoms in this object file.
  111. class DebugMapObject {
  112. public:
  113. struct SymbolMapping {
  114. Optional<yaml::Hex64> ObjectAddress;
  115. yaml::Hex64 BinaryAddress;
  116. yaml::Hex32 Size;
  117. SymbolMapping(Optional<uint64_t> ObjectAddr, uint64_t BinaryAddress,
  118. uint32_t Size)
  119. : BinaryAddress(BinaryAddress), Size(Size) {
  120. if (ObjectAddr)
  121. ObjectAddress = *ObjectAddr;
  122. }
  123. /// For YAML IO support
  124. SymbolMapping() = default;
  125. };
  126. using YAMLSymbolMapping = std::pair<std::string, SymbolMapping>;
  127. using DebugMapEntry = StringMapEntry<SymbolMapping>;
  128. /// Adds a symbol mapping to this DebugMapObject.
  129. /// \returns false if the symbol was already registered. The request
  130. /// is discarded in this case.
  131. bool addSymbol(StringRef SymName, Optional<uint64_t> ObjectAddress,
  132. uint64_t LinkedAddress, uint32_t Size);
  133. /// Lookup a symbol mapping.
  134. /// \returns null if the symbol isn't found.
  135. const DebugMapEntry *lookupSymbol(StringRef SymbolName) const;
  136. /// Lookup an object file address.
  137. /// \returns null if the address isn't found.
  138. const DebugMapEntry *lookupObjectAddress(uint64_t Address) const;
  139. StringRef getObjectFilename() const { return Filename; }
  140. sys::TimePoint<std::chrono::seconds> getTimestamp() const {
  141. return Timestamp;
  142. }
  143. uint8_t getType() const { return Type; }
  144. iterator_range<StringMap<SymbolMapping>::const_iterator> symbols() const {
  145. return make_range(Symbols.begin(), Symbols.end());
  146. }
  147. bool empty() const { return Symbols.empty(); }
  148. void addWarning(StringRef Warning) {
  149. Warnings.push_back(std::string(Warning));
  150. }
  151. const std::vector<std::string> &getWarnings() const { return Warnings; }
  152. void print(raw_ostream &OS) const;
  153. #ifndef NDEBUG
  154. void dump() const;
  155. #endif
  156. private:
  157. friend class DebugMap;
  158. /// DebugMapObjects can only be constructed by the owning DebugMap.
  159. DebugMapObject(StringRef ObjectFilename,
  160. sys::TimePoint<std::chrono::seconds> Timestamp, uint8_t Type);
  161. std::string Filename;
  162. sys::TimePoint<std::chrono::seconds> Timestamp;
  163. StringMap<SymbolMapping> Symbols;
  164. DenseMap<uint64_t, DebugMapEntry *> AddressToMapping;
  165. uint8_t Type;
  166. std::vector<std::string> Warnings;
  167. /// For YAMLIO support.
  168. ///@{
  169. friend yaml::MappingTraits<dsymutil::DebugMapObject>;
  170. friend yaml::SequenceTraits<std::vector<std::unique_ptr<DebugMapObject>>>;
  171. DebugMapObject() = default;
  172. public:
  173. DebugMapObject(DebugMapObject &&) = default;
  174. DebugMapObject &operator=(DebugMapObject &&) = default;
  175. ///@}
  176. };
  177. } // end namespace dsymutil
  178. } // end namespace llvm
  179. LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::dsymutil::DebugMapObject::YAMLSymbolMapping)
  180. namespace llvm {
  181. namespace yaml {
  182. using namespace llvm::dsymutil;
  183. template <>
  184. struct MappingTraits<std::pair<std::string, DebugMapObject::SymbolMapping>> {
  185. static void mapping(IO &io,
  186. std::pair<std::string, DebugMapObject::SymbolMapping> &s);
  187. static const bool flow = true;
  188. };
  189. template <> struct MappingTraits<dsymutil::DebugMapObject> {
  190. struct YamlDMO;
  191. static void mapping(IO &io, dsymutil::DebugMapObject &DMO);
  192. };
  193. template <> struct ScalarTraits<Triple> {
  194. static void output(const Triple &val, void *, raw_ostream &out);
  195. static StringRef input(StringRef scalar, void *, Triple &value);
  196. static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
  197. };
  198. template <>
  199. struct SequenceTraits<std::vector<std::unique_ptr<dsymutil::DebugMapObject>>> {
  200. static size_t
  201. size(IO &io, std::vector<std::unique_ptr<dsymutil::DebugMapObject>> &seq);
  202. static dsymutil::DebugMapObject &
  203. element(IO &, std::vector<std::unique_ptr<dsymutil::DebugMapObject>> &seq,
  204. size_t index);
  205. };
  206. template <> struct MappingTraits<dsymutil::DebugMap> {
  207. static void mapping(IO &io, dsymutil::DebugMap &DM);
  208. };
  209. template <> struct MappingTraits<std::unique_ptr<dsymutil::DebugMap>> {
  210. static void mapping(IO &io, std::unique_ptr<dsymutil::DebugMap> &DM);
  211. };
  212. } // end namespace yaml
  213. } // end namespace llvm
  214. #endif // LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H