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 "RelocationMap.h"
25 #include "llvm/ADT/DenseMap.h"
26 #include "llvm/ADT/StringMap.h"
27 #include "llvm/ADT/StringRef.h"
28 #include "llvm/ADT/iterator_range.h"
29 #include "llvm/Object/MachO.h"
30 #include "llvm/Support/Chrono.h"
31 #include "llvm/Support/ErrorOr.h"
32 #include "llvm/Support/YAMLTraits.h"
33 #include "llvm/TargetParser/Triple.h"
51 /// The DebugMap object stores the list of object files to query for debug
52 /// information along with the mapping between the symbols' addresses in the
53 /// object file to their linked address in the linked binary.
55 /// A DebugMap producer could look like this:
56 /// DebugMap *DM = new DebugMap();
57 /// for (const auto &Obj: LinkedObjects) {
58 /// DebugMapObject &DMO = DM->addDebugMapObject(Obj.getPath());
59 /// for (const auto &Sym: Obj.getLinkedSymbols())
60 /// DMO.addSymbol(Sym.getName(), Sym.getObjectFileAddress(),
61 /// Sym.getBinaryAddress());
64 /// A DebugMap consumer can then use the map to link the debug
65 /// information. For example something along the lines of:
66 /// for (const auto &DMO: DM->objects()) {
67 /// auto Obj = createBinary(DMO.getObjectFilename());
68 /// for (auto &DIE: Obj.getDwarfDIEs()) {
69 /// if (SymbolMapping *Sym = DMO.lookup(DIE.getName()))
70 /// DIE.relocate(Sym->ObjectAddress, Sym->BinaryAddress);
72 /// DIE.discardSubtree();
77 std::string BinaryPath
;
78 std::vector
<uint8_t> BinaryUUID
;
79 using ObjectContainer
= std::vector
<std::unique_ptr
<DebugMapObject
>>;
81 ObjectContainer Objects
;
83 /// For YAML IO support.
85 friend yaml::MappingTraits
<std::unique_ptr
<DebugMap
>>;
86 friend yaml::MappingTraits
<DebugMap
>;
92 DebugMap(const Triple
&BinaryTriple
, StringRef BinaryPath
,
93 ArrayRef
<uint8_t> BinaryUUID
= ArrayRef
<uint8_t>())
94 : BinaryTriple(BinaryTriple
), BinaryPath(std::string(BinaryPath
)),
95 BinaryUUID(BinaryUUID
.begin(), BinaryUUID
.end()) {}
97 using const_iterator
= ObjectContainer::const_iterator
;
99 iterator_range
<const_iterator
> objects() const {
100 return make_range(begin(), end());
103 const_iterator
begin() const { return Objects
.begin(); }
105 const_iterator
end() const { return Objects
.end(); }
107 unsigned getNumberOfObjects() const { return Objects
.size(); }
109 /// This function adds an DebugMapObject to the list owned by this
112 addDebugMapObject(StringRef ObjectFilePath
,
113 sys::TimePoint
<std::chrono::seconds
> Timestamp
,
114 uint8_t Type
= llvm::MachO::N_OSO
);
116 const Triple
&getTriple() const { return BinaryTriple
; }
118 ArrayRef
<uint8_t> getUUID() const { return ArrayRef
<uint8_t>(BinaryUUID
); }
120 StringRef
getBinaryPath() const { return BinaryPath
; }
122 void print(raw_ostream
&OS
) const;
128 /// Read a debug map for \a InputFile.
129 static ErrorOr
<std::vector
<std::unique_ptr
<DebugMap
>>>
130 parseYAMLDebugMap(StringRef InputFile
, StringRef PrependPath
, bool Verbose
);
133 /// The DebugMapObject represents one object file described by the DebugMap. It
134 /// contains a list of mappings between addresses in the object file and in the
135 /// linked binary for all the linked atoms in this object file.
136 class DebugMapObject
{
138 using YAMLSymbolMapping
= std::pair
<std::string
, SymbolMapping
>;
139 using DebugMapEntry
= StringMapEntry
<SymbolMapping
>;
141 /// Adds a symbol mapping to this DebugMapObject.
142 /// \returns false if the symbol was already registered. The request
143 /// is discarded in this case.
144 bool addSymbol(StringRef SymName
, std::optional
<uint64_t> ObjectAddress
,
145 uint64_t LinkedAddress
, uint32_t Size
);
147 /// Lookup a symbol mapping.
148 /// \returns null if the symbol isn't found.
149 const DebugMapEntry
*lookupSymbol(StringRef SymbolName
) const;
151 /// Lookup an object file address.
152 /// \returns null if the address isn't found.
153 const DebugMapEntry
*lookupObjectAddress(uint64_t Address
) const;
155 StringRef
getObjectFilename() const { return Filename
; }
157 sys::TimePoint
<std::chrono::seconds
> getTimestamp() const {
161 uint8_t getType() const { return Type
; }
163 bool empty() const { return Symbols
.empty(); }
165 void addWarning(StringRef Warning
) {
166 Warnings
.push_back(std::string(Warning
));
168 const std::vector
<std::string
> &getWarnings() const { return Warnings
; }
170 const std::optional
<RelocationMap
> &getRelocationMap() const {
173 void setRelocationMap(dsymutil::RelocationMap
&RM
);
175 const std::optional
<std::string
> &getInstallName() const {
178 void setInstallName(StringRef IN
);
180 void print(raw_ostream
&OS
) const;
186 friend class DebugMap
;
188 /// DebugMapObjects can only be constructed by the owning DebugMap.
189 DebugMapObject(StringRef ObjectFilename
,
190 sys::TimePoint
<std::chrono::seconds
> Timestamp
, uint8_t Type
);
192 std::string Filename
;
193 sys::TimePoint
<std::chrono::seconds
> Timestamp
;
194 StringMap
<struct SymbolMapping
> Symbols
;
195 DenseMap
<uint64_t, DebugMapEntry
*> AddressToMapping
;
198 std::optional
<RelocationMap
> RelocMap
;
199 std::optional
<std::string
> InstallName
;
201 std::vector
<std::string
> Warnings
;
203 /// For YAMLIO support.
205 friend yaml::MappingTraits
<dsymutil::DebugMapObject
>;
206 friend yaml::SequenceTraits
<std::vector
<std::unique_ptr
<DebugMapObject
>>>;
208 DebugMapObject() = default;
211 DebugMapObject(DebugMapObject
&&) = default;
212 DebugMapObject
&operator=(DebugMapObject
&&) = default;
216 } // end namespace dsymutil
217 } // end namespace llvm
219 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::dsymutil::DebugMapObject::YAMLSymbolMapping
)
224 using namespace llvm::dsymutil
;
226 template <> struct MappingTraits
<std::pair
<std::string
, SymbolMapping
>> {
227 static void mapping(IO
&io
, std::pair
<std::string
, SymbolMapping
> &s
);
228 static const bool flow
= true;
231 template <> struct MappingTraits
<dsymutil::DebugMapObject
> {
233 static void mapping(IO
&io
, dsymutil::DebugMapObject
&DMO
);
237 struct SequenceTraits
<std::vector
<std::unique_ptr
<dsymutil::DebugMapObject
>>> {
239 size(IO
&io
, std::vector
<std::unique_ptr
<dsymutil::DebugMapObject
>> &seq
);
240 static dsymutil::DebugMapObject
&
241 element(IO
&, std::vector
<std::unique_ptr
<dsymutil::DebugMapObject
>> &seq
,
245 template <> struct MappingTraits
<dsymutil::DebugMap
> {
246 static void mapping(IO
&io
, dsymutil::DebugMap
&DM
);
249 template <> struct MappingTraits
<std::unique_ptr
<dsymutil::DebugMap
>> {
250 static void mapping(IO
&io
, std::unique_ptr
<dsymutil::DebugMap
> &DM
);
253 } // end namespace yaml
254 } // end namespace llvm
256 #endif // LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H