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