blob: d8de37e33d559539d05c96a504c4207766b428a1 [file] [log] [blame]
Eugene Zelenko66f724e2017-11-01 21:16:06 +00001//=- tools/dsymutil/DebugMap.h - Generic debug map representation -*- C++ -*-=//
Frederic Riss31e081e2014-12-12 17:31:24 +00002//
Jonas Devlieghere928fea22018-06-27 16:13:40 +00003// The LLVM Compiler Infrastructure
Frederic Riss31e081e2014-12-12 17:31:24 +00004//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
Eugene Zelenko66f724e2017-11-01 21:16:06 +00009//
Frederic Riss31e081e2014-12-12 17:31:24 +000010/// \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.
Eugene Zelenko66f724e2017-11-01 21:16:06 +000019//
Frederic Riss31e081e2014-12-12 17:31:24 +000020//===----------------------------------------------------------------------===//
Eugene Zelenko66f724e2017-11-01 21:16:06 +000021
Frederic Riss31e081e2014-12-12 17:31:24 +000022#ifndef LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H
23#define LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H
24
Frederic Risse9483b82015-02-13 23:18:16 +000025#include "llvm/ADT/DenseMap.h"
Eugene Zelenko66f724e2017-11-01 21:16:06 +000026#include "llvm/ADT/Optional.h"
Frederic Riss31e081e2014-12-12 17:31:24 +000027#include "llvm/ADT/StringMap.h"
Eugene Zelenko66f724e2017-11-01 21:16:06 +000028#include "llvm/ADT/StringRef.h"
Frederic Riss87320272015-01-19 23:33:14 +000029#include "llvm/ADT/Triple.h"
Chandler Carruth1b279142015-01-14 11:23:27 +000030#include "llvm/ADT/iterator_range.h"
Jonas Devlieghere61693462018-02-08 10:48:54 +000031#include "llvm/Object/MachO.h"
Pavel Labath73ce0c02016-11-09 11:43:52 +000032#include "llvm/Support/Chrono.h"
Frederic Riss31e081e2014-12-12 17:31:24 +000033#include "llvm/Support/ErrorOr.h"
Frederic Riss786b4712015-06-01 21:12:45 +000034#include "llvm/Support/YAMLTraits.h"
Eugene Zelenko66f724e2017-11-01 21:16:06 +000035#include <chrono>
36#include <cstddef>
37#include <cstdint>
38#include <memory>
39#include <string>
40#include <utility>
Frederic Riss31e081e2014-12-12 17:31:24 +000041#include <vector>
42
43namespace llvm {
Eugene Zelenko66f724e2017-11-01 21:16:06 +000044
Frederic Riss31e081e2014-12-12 17:31:24 +000045class raw_ostream;
46
47namespace dsymutil {
Eugene Zelenko66f724e2017-11-01 21:16:06 +000048
Frederic Riss31e081e2014-12-12 17:31:24 +000049class DebugMapObject;
50
Jonas Devlieghere92a76c52018-02-22 11:43:43 +000051/// 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.
Frederic Riss31e081e2014-12-12 17:31:24 +000054///
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());
62/// }
63///
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);
71/// else
72/// DIE.discardSubtree();
73/// }
74/// }
75class DebugMap {
Frederic Riss87320272015-01-19 23:33:14 +000076 Triple BinaryTriple;
Frederic Riss65ce0b12015-08-26 05:09:59 +000077 std::string BinaryPath;
Jonas Devlieghere20767d12019-01-07 23:27:25 +000078 std::vector<uint8_t> BinaryUUID;
Eugene Zelenko66f724e2017-11-01 21:16:06 +000079 using ObjectContainer = std::vector<std::unique_ptr<DebugMapObject>>;
80
Frederic Riss31e081e2014-12-12 17:31:24 +000081 ObjectContainer Objects;
82
Frederic Riss786b4712015-06-01 21:12:45 +000083 /// For YAML IO support.
84 ///@{
Frederic Riss696c93c2015-06-03 20:29:24 +000085 friend yaml::MappingTraits<std::unique_ptr<DebugMap>>;
Frederic Riss786b4712015-06-01 21:12:45 +000086 friend yaml::MappingTraits<DebugMap>;
Eugene Zelenko66f724e2017-11-01 21:16:06 +000087
Frederic Riss786b4712015-06-01 21:12:45 +000088 DebugMap() = default;
89 ///@}
Eugene Zelenko66f724e2017-11-01 21:16:06 +000090
Frederic Riss31e081e2014-12-12 17:31:24 +000091public:
Jonas Devlieghere20767d12019-01-07 23:27:25 +000092 DebugMap(const Triple &BinaryTriple, StringRef BinaryPath,
93 ArrayRef<uint8_t> BinaryUUID = ArrayRef<uint8_t>())
94 : BinaryTriple(BinaryTriple), BinaryPath(BinaryPath),
95 BinaryUUID(BinaryUUID.begin(), BinaryUUID.end()) {}
Frederic Riss87320272015-01-19 23:33:14 +000096
Eugene Zelenko66f724e2017-11-01 21:16:06 +000097 using const_iterator = ObjectContainer::const_iterator;
Frederic Riss31e081e2014-12-12 17:31:24 +000098
99 iterator_range<const_iterator> objects() const {
100 return make_range(begin(), end());
101 }
102
103 const_iterator begin() const { return Objects.begin(); }
104
105 const_iterator end() const { return Objects.end(); }
106
Jonas Devliegherea4c60c42018-03-13 10:52:49 +0000107 unsigned getNumberOfObjects() const { return Objects.size(); }
108
Frederic Riss31e081e2014-12-12 17:31:24 +0000109 /// This function adds an DebugMapObject to the list owned by this
110 /// debug map.
Pavel Labath73ce0c02016-11-09 11:43:52 +0000111 DebugMapObject &
112 addDebugMapObject(StringRef ObjectFilePath,
Francis Ricci6f200df2017-10-06 14:49:20 +0000113 sys::TimePoint<std::chrono::seconds> Timestamp,
Jonas Devlieghere61693462018-02-08 10:48:54 +0000114 uint8_t Type = llvm::MachO::N_OSO);
Frederic Riss31e081e2014-12-12 17:31:24 +0000115
Frederic Rissa646d272015-02-28 00:28:56 +0000116 const Triple &getTriple() const { return BinaryTriple; }
Frederic Riss87320272015-01-19 23:33:14 +0000117
Jonas Devlieghere20767d12019-01-07 23:27:25 +0000118 const ArrayRef<uint8_t> getUUID() const {
119 return ArrayRef<uint8_t>(BinaryUUID);
120 }
121
Frederic Riss65ce0b12015-08-26 05:09:59 +0000122 StringRef getBinaryPath() const { return BinaryPath; }
123
Frederic Riss31e081e2014-12-12 17:31:24 +0000124 void print(raw_ostream &OS) const;
125
126#ifndef NDEBUG
127 void dump() const;
128#endif
Frederic Riss527bb612015-06-05 20:27:04 +0000129
130 /// Read a debug map for \a InputFile.
Frederic Riss7a425782015-08-05 18:27:44 +0000131 static ErrorOr<std::vector<std::unique_ptr<DebugMap>>>
Frederic Riss527bb612015-06-05 20:27:04 +0000132 parseYAMLDebugMap(StringRef InputFile, StringRef PrependPath, bool Verbose);
Frederic Riss31e081e2014-12-12 17:31:24 +0000133};
134
Jonas Devlieghere92a76c52018-02-22 11:43:43 +0000135/// The DebugMapObject represents one object file described by the DebugMap. It
136/// contains a list of mappings between addresses in the object file and in the
137/// linked binary for all the linked atoms in this object file.
Frederic Riss31e081e2014-12-12 17:31:24 +0000138class DebugMapObject {
139public:
140 struct SymbolMapping {
Frederic Rissc5413fc2016-01-31 04:29:22 +0000141 Optional<yaml::Hex64> ObjectAddress;
Frederic Riss786b4712015-06-01 21:12:45 +0000142 yaml::Hex64 BinaryAddress;
143 yaml::Hex32 Size;
Eugene Zelenko66f724e2017-11-01 21:16:06 +0000144
Frederic Rissc5413fc2016-01-31 04:29:22 +0000145 SymbolMapping(Optional<uint64_t> ObjectAddr, uint64_t BinaryAddress,
146 uint32_t Size)
147 : BinaryAddress(BinaryAddress), Size(Size) {
148 if (ObjectAddr)
149 ObjectAddress = *ObjectAddr;
150 }
Eugene Zelenko66f724e2017-11-01 21:16:06 +0000151
Frederic Riss786b4712015-06-01 21:12:45 +0000152 /// For YAML IO support
153 SymbolMapping() = default;
Frederic Riss31e081e2014-12-12 17:31:24 +0000154 };
155
Eugene Zelenko66f724e2017-11-01 21:16:06 +0000156 using YAMLSymbolMapping = std::pair<std::string, SymbolMapping>;
157 using DebugMapEntry = StringMapEntry<SymbolMapping>;
Frederic Risse9483b82015-02-13 23:18:16 +0000158
Jonas Devlieghere92a76c52018-02-22 11:43:43 +0000159 /// Adds a symbol mapping to this DebugMapObject.
Frederic Riss31e081e2014-12-12 17:31:24 +0000160 /// \returns false if the symbol was already registered. The request
161 /// is discarded in this case.
Eugene Zelenko66f724e2017-11-01 21:16:06 +0000162 bool addSymbol(StringRef SymName, Optional<uint64_t> ObjectAddress,
Frederic Risse7a35642015-03-15 01:29:30 +0000163 uint64_t LinkedAddress, uint32_t Size);
Frederic Riss31e081e2014-12-12 17:31:24 +0000164
Jonas Devlieghere92a76c52018-02-22 11:43:43 +0000165 /// Lookup a symbol mapping.
Frederic Riss31e081e2014-12-12 17:31:24 +0000166 /// \returns null if the symbol isn't found.
Frederic Risse9483b82015-02-13 23:18:16 +0000167 const DebugMapEntry *lookupSymbol(StringRef SymbolName) const;
168
Jonas Devlieghere92a76c52018-02-22 11:43:43 +0000169 /// Lookup an object file address.
Frederic Risse9483b82015-02-13 23:18:16 +0000170 /// \returns null if the address isn't found.
171 const DebugMapEntry *lookupObjectAddress(uint64_t Address) const;
Frederic Riss31e081e2014-12-12 17:31:24 +0000172
Eugene Zelenko66f724e2017-11-01 21:16:06 +0000173 StringRef getObjectFilename() const { return Filename; }
Frederic Riss31e081e2014-12-12 17:31:24 +0000174
Pavel Labath73ce0c02016-11-09 11:43:52 +0000175 sys::TimePoint<std::chrono::seconds> getTimestamp() const {
176 return Timestamp;
177 }
Frederic Riss00d14dd2015-07-22 23:24:00 +0000178
Francis Ricci6f200df2017-10-06 14:49:20 +0000179 uint8_t getType() const { return Type; }
180
Frederic Riss469f4382015-03-15 02:02:53 +0000181 iterator_range<StringMap<SymbolMapping>::const_iterator> symbols() const {
182 return make_range(Symbols.begin(), Symbols.end());
183 }
184
Jonas Devlieghere67eb8fd2018-04-02 10:40:43 +0000185 bool empty() const { return Symbols.empty(); }
186
187 void addWarning(StringRef Warning) { Warnings.push_back(Warning); }
188 const std::vector<std::string> &getWarnings() const { return Warnings; }
189
Frederic Riss31e081e2014-12-12 17:31:24 +0000190 void print(raw_ostream &OS) const;
191#ifndef NDEBUG
192 void dump() const;
193#endif
Eugene Zelenko66f724e2017-11-01 21:16:06 +0000194
Frederic Riss31e081e2014-12-12 17:31:24 +0000195private:
196 friend class DebugMap;
Eugene Zelenko66f724e2017-11-01 21:16:06 +0000197
Frederic Riss31e081e2014-12-12 17:31:24 +0000198 /// DebugMapObjects can only be constructed by the owning DebugMap.
Pavel Labath73ce0c02016-11-09 11:43:52 +0000199 DebugMapObject(StringRef ObjectFilename,
Francis Ricci6f200df2017-10-06 14:49:20 +0000200 sys::TimePoint<std::chrono::seconds> Timestamp, uint8_t Type);
Frederic Riss31e081e2014-12-12 17:31:24 +0000201
202 std::string Filename;
Pavel Labath73ce0c02016-11-09 11:43:52 +0000203 sys::TimePoint<std::chrono::seconds> Timestamp;
Frederic Riss31e081e2014-12-12 17:31:24 +0000204 StringMap<SymbolMapping> Symbols;
Frederic Risse9483b82015-02-13 23:18:16 +0000205 DenseMap<uint64_t, DebugMapEntry *> AddressToMapping;
Francis Ricci6f200df2017-10-06 14:49:20 +0000206 uint8_t Type;
Frederic Riss786b4712015-06-01 21:12:45 +0000207
Jonas Devlieghere67eb8fd2018-04-02 10:40:43 +0000208 std::vector<std::string> Warnings;
209
Frederic Riss786b4712015-06-01 21:12:45 +0000210 /// For YAMLIO support.
211 ///@{
Frederic Riss786b4712015-06-01 21:12:45 +0000212 friend yaml::MappingTraits<dsymutil::DebugMapObject>;
213 friend yaml::SequenceTraits<std::vector<std::unique_ptr<DebugMapObject>>>;
Eugene Zelenko66f724e2017-11-01 21:16:06 +0000214
Frederic Riss786b4712015-06-01 21:12:45 +0000215 DebugMapObject() = default;
Frederic Riss0f58c382015-06-05 20:27:07 +0000216
217public:
Benjamin Kramerbf85e052016-10-27 15:23:44 +0000218 DebugMapObject(DebugMapObject &&) = default;
219 DebugMapObject &operator=(DebugMapObject &&) = default;
Frederic Riss786b4712015-06-01 21:12:45 +0000220 ///@}
221};
Eugene Zelenko66f724e2017-11-01 21:16:06 +0000222
223} // end namespace dsymutil
Eugene Zelenko66f724e2017-11-01 21:16:06 +0000224} // end namespace llvm
Frederic Riss786b4712015-06-01 21:12:45 +0000225
Frederic Riss1392cf22015-06-01 21:25:53 +0000226LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::dsymutil::DebugMapObject::YAMLSymbolMapping)
Frederic Riss786b4712015-06-01 21:12:45 +0000227
228namespace llvm {
229namespace yaml {
230
231using namespace llvm::dsymutil;
232
233template <>
234struct MappingTraits<std::pair<std::string, DebugMapObject::SymbolMapping>> {
Frederic Riss527bb612015-06-05 20:27:04 +0000235 static void mapping(IO &io,
236 std::pair<std::string, DebugMapObject::SymbolMapping> &s);
Frederic Riss786b4712015-06-01 21:12:45 +0000237 static const bool flow = true;
238};
239
240template <> struct MappingTraits<dsymutil::DebugMapObject> {
Frederic Riss527bb612015-06-05 20:27:04 +0000241 struct YamlDMO;
242 static void mapping(IO &io, dsymutil::DebugMapObject &DMO);
Frederic Riss786b4712015-06-01 21:12:45 +0000243};
244
245template <> struct ScalarTraits<Triple> {
Eugene Zelenko66f724e2017-11-01 21:16:06 +0000246 static void output(const Triple &val, void *, raw_ostream &out);
Frederic Riss527bb612015-06-05 20:27:04 +0000247 static StringRef input(StringRef scalar, void *, Triple &value);
Francis Visoiu Mistrih65ad22d2017-12-18 17:38:03 +0000248 static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
Frederic Riss786b4712015-06-01 21:12:45 +0000249};
250
251template <>
252struct SequenceTraits<std::vector<std::unique_ptr<dsymutil::DebugMapObject>>> {
Frederic Riss786b4712015-06-01 21:12:45 +0000253 static size_t
Frederic Riss527bb612015-06-05 20:27:04 +0000254 size(IO &io, std::vector<std::unique_ptr<dsymutil::DebugMapObject>> &seq);
Frederic Riss786b4712015-06-01 21:12:45 +0000255 static dsymutil::DebugMapObject &
256 element(IO &, std::vector<std::unique_ptr<dsymutil::DebugMapObject>> &seq,
Frederic Riss527bb612015-06-05 20:27:04 +0000257 size_t index);
Frederic Riss786b4712015-06-01 21:12:45 +0000258};
259
260template <> struct MappingTraits<dsymutil::DebugMap> {
Frederic Riss527bb612015-06-05 20:27:04 +0000261 static void mapping(IO &io, dsymutil::DebugMap &DM);
Frederic Riss31e081e2014-12-12 17:31:24 +0000262};
Frederic Riss696c93c2015-06-03 20:29:24 +0000263
Frederic Riss527bb612015-06-05 20:27:04 +0000264template <> struct MappingTraits<std::unique_ptr<dsymutil::DebugMap>> {
265 static void mapping(IO &io, std::unique_ptr<dsymutil::DebugMap> &DM);
Frederic Riss696c93c2015-06-03 20:29:24 +0000266};
Eugene Zelenko66f724e2017-11-01 21:16:06 +0000267
268} // end namespace yaml
269} // end namespace llvm
Frederic Riss31e081e2014-12-12 17:31:24 +0000270
271#endif // LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H