1 //=- tools/dsymutil/DebugMap.h - Generic debug map representation -*- C++ -*-=//
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
7 //===----------------------------------------------------------------------===//
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.
19 //===----------------------------------------------------------------------===//
21 #ifndef LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H
22 #define LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H
24 #include "llvm/ADT/DenseMap.h"
25 #include "llvm/ADT/Optional.h"
26 #include "llvm/ADT/StringMap.h"
27 #include "llvm/ADT/StringRef.h"
28 #include "llvm/ADT/Triple.h"
29 #include "llvm/ADT/iterator_range.h"
30 #include "llvm/Object/MachO.h"
31 #include "llvm/Support/Chrono.h"
32 #include "llvm/Support/ErrorOr.h"
33 #include "llvm/Support/YAMLTraits.h"
50 /// The DebugMap object stores the list of object files to query for debug
51 /// information along with the mapping between the symbols' addresses in the
52 /// object file to their linked address in the linked binary.
54 /// A DebugMap producer could look like this:
55 /// DebugMap *DM = new DebugMap();
56 /// for (const auto &Obj: LinkedObjects) {
57 /// DebugMapObject &DMO = DM->addDebugMapObject(Obj.getPath());
58 /// for (const auto &Sym: Obj.getLinkedSymbols())
59 /// DMO.addSymbol(Sym.getName(), Sym.getObjectFileAddress(),
60 /// Sym.getBinaryAddress());
63 /// A DebugMap consumer can then use the map to link the debug
64 /// information. For example something along the lines of:
65 /// for (const auto &DMO: DM->objects()) {
66 /// auto Obj = createBinary(DMO.getObjectFilename());
67 /// for (auto &DIE: Obj.getDwarfDIEs()) {
68 /// if (SymbolMapping *Sym = DMO.lookup(DIE.getName()))
69 /// DIE.relocate(Sym->ObjectAddress, Sym->BinaryAddress);
71 /// DIE.discardSubtree();
76 std::string BinaryPath
;
77 std::vector
<uint8_t> BinaryUUID
;
78 using ObjectContainer
= std::vector
<std::unique_ptr
<DebugMapObject
>>;
80 ObjectContainer Objects
;
82 /// For YAML IO support.
84 friend yaml::MappingTraits
<std::unique_ptr
<DebugMap
>>;
85 friend yaml::MappingTraits
<DebugMap
>;
91 DebugMap(const Triple
&BinaryTriple
, StringRef BinaryPath
,
92 ArrayRef
<uint8_t> BinaryUUID
= ArrayRef
<uint8_t>())
93 : BinaryTriple(BinaryTriple
), BinaryPath(BinaryPath
),
94 BinaryUUID(BinaryUUID
.begin(), BinaryUUID
.end()) {}
96 using const_iterator
= ObjectContainer::const_iterator
;
98 iterator_range
<const_iterator
> objects() const {
99 return make_range(begin(), end());
102 const_iterator
begin() const { return Objects
.begin(); }
104 const_iterator
end() const { return Objects
.end(); }
106 unsigned getNumberOfObjects() const { return Objects
.size(); }
108 /// This function adds an DebugMapObject to the list owned by this
111 addDebugMapObject(StringRef ObjectFilePath
,
112 sys::TimePoint
<std::chrono::seconds
> Timestamp
,
113 uint8_t Type
= llvm::MachO::N_OSO
);
115 const Triple
&getTriple() const { return BinaryTriple
; }
117 const ArrayRef
<uint8_t> getUUID() const {
118 return ArrayRef
<uint8_t>(BinaryUUID
);
121 StringRef
getBinaryPath() const { return BinaryPath
; }
123 void print(raw_ostream
&OS
) const;
129 /// Read a debug map for \a InputFile.
130 static ErrorOr
<std::vector
<std::unique_ptr
<DebugMap
>>>
131 parseYAMLDebugMap(StringRef InputFile
, StringRef PrependPath
, bool Verbose
);
134 /// The DebugMapObject represents one object file described by the DebugMap. It
135 /// contains a list of mappings between addresses in the object file and in the
136 /// linked binary for all the linked atoms in this object file.
137 class DebugMapObject
{
139 struct SymbolMapping
{
140 Optional
<yaml::Hex64
> ObjectAddress
;
141 yaml::Hex64 BinaryAddress
;
144 SymbolMapping(Optional
<uint64_t> ObjectAddr
, uint64_t BinaryAddress
,
146 : BinaryAddress(BinaryAddress
), Size(Size
) {
148 ObjectAddress
= *ObjectAddr
;
151 /// For YAML IO support
152 SymbolMapping() = default;
155 using YAMLSymbolMapping
= std::pair
<std::string
, SymbolMapping
>;
156 using DebugMapEntry
= StringMapEntry
<SymbolMapping
>;
158 /// Adds a symbol mapping to this DebugMapObject.
159 /// \returns false if the symbol was already registered. The request
160 /// is discarded in this case.
161 bool addSymbol(StringRef SymName
, Optional
<uint64_t> ObjectAddress
,
162 uint64_t LinkedAddress
, uint32_t Size
);
164 /// Lookup a symbol mapping.
165 /// \returns null if the symbol isn't found.
166 const DebugMapEntry
*lookupSymbol(StringRef SymbolName
) const;
168 /// Lookup an object file address.
169 /// \returns null if the address isn't found.
170 const DebugMapEntry
*lookupObjectAddress(uint64_t Address
) const;
172 StringRef
getObjectFilename() const { return Filename
; }
174 sys::TimePoint
<std::chrono::seconds
> getTimestamp() const {
178 uint8_t getType() const { return Type
; }
180 iterator_range
<StringMap
<SymbolMapping
>::const_iterator
> symbols() const {
181 return make_range(Symbols
.begin(), Symbols
.end());
184 bool empty() const { return Symbols
.empty(); }
186 void addWarning(StringRef Warning
) { Warnings
.push_back(Warning
); }
187 const std::vector
<std::string
> &getWarnings() const { return Warnings
; }
189 void print(raw_ostream
&OS
) const;
195 friend class DebugMap
;
197 /// DebugMapObjects can only be constructed by the owning DebugMap.
198 DebugMapObject(StringRef ObjectFilename
,
199 sys::TimePoint
<std::chrono::seconds
> Timestamp
, uint8_t Type
);
201 std::string Filename
;
202 sys::TimePoint
<std::chrono::seconds
> Timestamp
;
203 StringMap
<SymbolMapping
> Symbols
;
204 DenseMap
<uint64_t, DebugMapEntry
*> AddressToMapping
;
207 std::vector
<std::string
> Warnings
;
209 /// For YAMLIO support.
211 friend yaml::MappingTraits
<dsymutil::DebugMapObject
>;
212 friend yaml::SequenceTraits
<std::vector
<std::unique_ptr
<DebugMapObject
>>>;
214 DebugMapObject() = default;
217 DebugMapObject(DebugMapObject
&&) = default;
218 DebugMapObject
&operator=(DebugMapObject
&&) = default;
222 } // end namespace dsymutil
223 } // end namespace llvm
225 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::dsymutil::DebugMapObject::YAMLSymbolMapping
)
230 using namespace llvm::dsymutil
;
233 struct MappingTraits
<std::pair
<std::string
, DebugMapObject::SymbolMapping
>> {
234 static void mapping(IO
&io
,
235 std::pair
<std::string
, DebugMapObject::SymbolMapping
> &s
);
236 static const bool flow
= true;
239 template <> struct MappingTraits
<dsymutil::DebugMapObject
> {
241 static void mapping(IO
&io
, dsymutil::DebugMapObject
&DMO
);
244 template <> struct ScalarTraits
<Triple
> {
245 static void output(const Triple
&val
, void *, raw_ostream
&out
);
246 static StringRef
input(StringRef scalar
, void *, Triple
&value
);
247 static QuotingType
mustQuote(StringRef
) { return QuotingType::Single
; }
251 struct SequenceTraits
<std::vector
<std::unique_ptr
<dsymutil::DebugMapObject
>>> {
253 size(IO
&io
, std::vector
<std::unique_ptr
<dsymutil::DebugMapObject
>> &seq
);
254 static dsymutil::DebugMapObject
&
255 element(IO
&, std::vector
<std::unique_ptr
<dsymutil::DebugMapObject
>> &seq
,
259 template <> struct MappingTraits
<dsymutil::DebugMap
> {
260 static void mapping(IO
&io
, dsymutil::DebugMap
&DM
);
263 template <> struct MappingTraits
<std::unique_ptr
<dsymutil::DebugMap
>> {
264 static void mapping(IO
&io
, std::unique_ptr
<dsymutil::DebugMap
> &DM
);
267 } // end namespace yaml
268 } // end namespace llvm
270 #endif // LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H