1 //===- tools/dsymutil/DebugMap.h - Generic debug map representation -------===// 2 // 3 // The LLVM Linker 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// 12 /// This file contains the class declaration of the DebugMap 13 /// entity. A DebugMap lists all the object files linked together to 14 /// produce an executable along with the linked address of all the 15 /// atoms used in these object files. 16 /// The DebugMap is an input to the DwarfLinker class that will 17 /// extract the Dwarf debug information from the referenced object 18 /// files and link their usefull debug info together. 19 /// 20 //===----------------------------------------------------------------------===// 21 #ifndef LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H 22 #define LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H 23 24 #include "llvm/ADT/DenseMap.h" 25 #include "llvm/ADT/StringMap.h" 26 #include "llvm/ADT/Triple.h" 27 #include "llvm/ADT/iterator_range.h" 28 #include "llvm/Object/ObjectFile.h" 29 #include "llvm/Support/ErrorOr.h" 30 #include "llvm/Support/Format.h" 31 #include <vector> 32 33 namespace llvm { 34 class raw_ostream; 35 36 namespace dsymutil { 37 class DebugMapObject; 38 39 /// \brief The DebugMap object stores the list of object files to 40 /// query for debug information along with the mapping between the 41 /// symbols' addresses in the object file to their linked address in 42 /// the linked binary. 43 /// 44 /// A DebugMap producer could look like this: 45 /// DebugMap *DM = new DebugMap(); 46 /// for (const auto &Obj: LinkedObjects) { 47 /// DebugMapObject &DMO = DM->addDebugMapObject(Obj.getPath()); 48 /// for (const auto &Sym: Obj.getLinkedSymbols()) 49 /// DMO.addSymbol(Sym.getName(), Sym.getObjectFileAddress(), 50 /// Sym.getBinaryAddress()); 51 /// } 52 /// 53 /// A DebugMap consumer can then use the map to link the debug 54 /// information. For example something along the lines of: 55 /// for (const auto &DMO: DM->objects()) { 56 /// auto Obj = createBinary(DMO.getObjectFilename()); 57 /// for (auto &DIE: Obj.getDwarfDIEs()) { 58 /// if (SymbolMapping *Sym = DMO.lookup(DIE.getName())) 59 /// DIE.relocate(Sym->ObjectAddress, Sym->BinaryAddress); 60 /// else 61 /// DIE.discardSubtree(); 62 /// } 63 /// } 64 class DebugMap { 65 Triple BinaryTriple; 66 typedef std::vector<std::unique_ptr<DebugMapObject>> ObjectContainer; 67 ObjectContainer Objects; 68 69 public: DebugMap(const Triple & BinaryTriple)70 DebugMap(const Triple &BinaryTriple) : BinaryTriple(BinaryTriple) {} 71 72 typedef ObjectContainer::const_iterator const_iterator; 73 objects()74 iterator_range<const_iterator> objects() const { 75 return make_range(begin(), end()); 76 } 77 begin()78 const_iterator begin() const { return Objects.begin(); } 79 end()80 const_iterator end() const { return Objects.end(); } 81 82 /// This function adds an DebugMapObject to the list owned by this 83 /// debug map. 84 DebugMapObject &addDebugMapObject(StringRef ObjectFilePath); 85 getTriple()86 const Triple &getTriple() const { return BinaryTriple; } 87 88 void print(raw_ostream &OS) const; 89 90 #ifndef NDEBUG 91 void dump() const; 92 #endif 93 }; 94 95 /// \brief The DebugMapObject represents one object file described by 96 /// the DebugMap. It contains a list of mappings between addresses in 97 /// the object file and in the linked binary for all the linked atoms 98 /// in this object file. 99 class DebugMapObject { 100 public: 101 struct SymbolMapping { 102 uint64_t ObjectAddress; 103 uint64_t BinaryAddress; 104 uint32_t Size; SymbolMappingSymbolMapping105 SymbolMapping(uint64_t ObjectAddress, uint64_t BinaryAddress, uint32_t Size) 106 : ObjectAddress(ObjectAddress), BinaryAddress(BinaryAddress), 107 Size(Size) {} 108 }; 109 110 typedef StringMapEntry<SymbolMapping> DebugMapEntry; 111 112 /// \brief Adds a symbol mapping to this DebugMapObject. 113 /// \returns false if the symbol was already registered. The request 114 /// is discarded in this case. 115 bool addSymbol(llvm::StringRef SymName, uint64_t ObjectAddress, 116 uint64_t LinkedAddress, uint32_t Size); 117 118 /// \brief Lookup a symbol mapping. 119 /// \returns null if the symbol isn't found. 120 const DebugMapEntry *lookupSymbol(StringRef SymbolName) const; 121 122 /// \brief Lookup an objectfile address. 123 /// \returns null if the address isn't found. 124 const DebugMapEntry *lookupObjectAddress(uint64_t Address) const; 125 getObjectFilename()126 llvm::StringRef getObjectFilename() const { return Filename; } 127 symbols()128 iterator_range<StringMap<SymbolMapping>::const_iterator> symbols() const { 129 return make_range(Symbols.begin(), Symbols.end()); 130 } 131 132 void print(raw_ostream &OS) const; 133 #ifndef NDEBUG 134 void dump() const; 135 #endif 136 private: 137 friend class DebugMap; 138 /// DebugMapObjects can only be constructed by the owning DebugMap. 139 DebugMapObject(StringRef ObjectFilename); 140 141 std::string Filename; 142 StringMap<SymbolMapping> Symbols; 143 DenseMap<uint64_t, DebugMapEntry *> AddressToMapping; 144 }; 145 } 146 } 147 148 #endif // LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H 149