257 lines · c
1//=- tools/dsymutil/DebugMap.h - Generic debug map representation -*- C++ -*-=//2//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-exception6//7//===----------------------------------------------------------------------===//8//9/// \file10///11/// This file contains the class declaration of the DebugMap12/// entity. A DebugMap lists all the object files linked together to13/// produce an executable along with the linked address of all the14/// atoms used in these object files.15/// The DebugMap is an input to the DwarfLinker class that will16/// extract the Dwarf debug information from the referenced object17/// files and link their usefull debug info together.18//19//===----------------------------------------------------------------------===//20 21#ifndef LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H22#define LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H23 24#include "BinaryHolder.h"25#include "RelocationMap.h"26#include "llvm/ADT/DenseMap.h"27#include "llvm/ADT/StringMap.h"28#include "llvm/ADT/StringRef.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"34#include "llvm/TargetParser/Triple.h"35#include <chrono>36#include <cstddef>37#include <cstdint>38#include <memory>39#include <optional>40#include <string>41#include <utility>42#include <vector>43 44namespace llvm {45 46class raw_ostream;47 48namespace dsymutil {49 50class DebugMapObject;51 52/// The DebugMap object stores the list of object files to query for debug53/// information along with the mapping between the symbols' addresses in the54/// object file to their linked address in the linked binary.55///56/// A DebugMap producer could look like this:57/// DebugMap *DM = new DebugMap();58/// for (const auto &Obj: LinkedObjects) {59/// DebugMapObject &DMO = DM->addDebugMapObject(Obj.getPath());60/// for (const auto &Sym: Obj.getLinkedSymbols())61/// DMO.addSymbol(Sym.getName(), Sym.getObjectFileAddress(),62/// Sym.getBinaryAddress());63/// }64///65/// A DebugMap consumer can then use the map to link the debug66/// information. For example something along the lines of:67/// for (const auto &DMO: DM->objects()) {68/// auto Obj = createBinary(DMO.getObjectFilename());69/// for (auto &DIE: Obj.getDwarfDIEs()) {70/// if (SymbolMapping *Sym = DMO.lookup(DIE.getName()))71/// DIE.relocate(Sym->ObjectAddress, Sym->BinaryAddress);72/// else73/// DIE.discardSubtree();74/// }75/// }76class DebugMap {77 Triple BinaryTriple;78 std::string BinaryPath;79 std::vector<uint8_t> BinaryUUID;80 using ObjectContainer = std::vector<std::unique_ptr<DebugMapObject>>;81 82 ObjectContainer Objects;83 84 /// For YAML IO support.85 ///@{86 friend yaml::MappingTraits<std::unique_ptr<DebugMap>>;87 friend yaml::MappingTraits<DebugMap>;88 89 DebugMap() = default;90 ///@}91 92public:93 DebugMap(const Triple &BinaryTriple, StringRef BinaryPath,94 ArrayRef<uint8_t> BinaryUUID = ArrayRef<uint8_t>());95 96 using const_iterator = ObjectContainer::const_iterator;97 98 iterator_range<const_iterator> objects() const {99 return make_range(begin(), end());100 }101 102 const_iterator begin() const { return Objects.begin(); }103 104 const_iterator end() const { return Objects.end(); }105 106 unsigned getNumberOfObjects() const { return Objects.size(); }107 108 /// This function adds an DebugMapObject to the list owned by this109 /// debug map.110 DebugMapObject &111 addDebugMapObject(StringRef ObjectFilePath,112 sys::TimePoint<std::chrono::seconds> Timestamp,113 uint8_t Type = llvm::MachO::N_OSO);114 115 const Triple &getTriple() const { return BinaryTriple; }116 117 ArrayRef<uint8_t> getUUID() const { return ArrayRef<uint8_t>(BinaryUUID); }118 119 StringRef getBinaryPath() const { return BinaryPath; }120 121 void print(raw_ostream &OS) const;122 123#ifndef NDEBUG124 void dump() const;125#endif126 127 /// Read a debug map for \a InputFile.128 static ErrorOr<std::vector<std::unique_ptr<DebugMap>>>129 parseYAMLDebugMap(BinaryHolder &BinHolder, StringRef InputFile,130 StringRef PrependPath, bool Verbose);131};132 133/// The DebugMapObject represents one object file described by the DebugMap. It134/// contains a list of mappings between addresses in the object file and in the135/// linked binary for all the linked atoms in this object file.136class DebugMapObject {137public:138 using YAMLSymbolMapping = std::pair<std::string, SymbolMapping>;139 using DebugMapEntry = StringMapEntry<SymbolMapping>;140 141 /// Adds a symbol mapping to this DebugMapObject.142 /// \returns false if the symbol was already registered. The request143 /// is discarded in this case.144 bool addSymbol(StringRef SymName, std::optional<uint64_t> ObjectAddress,145 uint64_t LinkedAddress, uint32_t Size);146 147 /// Lookup a symbol mapping.148 /// \returns null if the symbol isn't found.149 const DebugMapEntry *lookupSymbol(StringRef SymbolName) const;150 151 /// Lookup an object file address.152 /// \returns null if the address isn't found.153 const DebugMapEntry *lookupObjectAddress(uint64_t Address) const;154 155 StringRef getObjectFilename() const { return Filename; }156 157 sys::TimePoint<std::chrono::seconds> getTimestamp() const {158 return Timestamp;159 }160 161 uint8_t getType() const { return Type; }162 163 bool empty() const { return Symbols.empty(); }164 165 void addWarning(StringRef Warning) {166 Warnings.push_back(std::string(Warning));167 }168 const std::vector<std::string> &getWarnings() const { return Warnings; }169 170 const std::optional<RelocationMap> &getRelocationMap() const {171 return RelocMap;172 }173 void setRelocationMap(dsymutil::RelocationMap &RM);174 175 const std::optional<std::string> &getInstallName() const {176 return InstallName;177 }178 void setInstallName(StringRef IN);179 180 void print(raw_ostream &OS) const;181#ifndef NDEBUG182 void dump() const;183#endif184 185private:186 friend class DebugMap;187 188 /// DebugMapObjects can only be constructed by the owning DebugMap.189 DebugMapObject(StringRef ObjectFilename,190 sys::TimePoint<std::chrono::seconds> Timestamp, uint8_t Type);191 192 std::string Filename;193 sys::TimePoint<std::chrono::seconds> Timestamp;194 StringMap<struct SymbolMapping> Symbols;195 DenseMap<uint64_t, DebugMapEntry *> AddressToMapping;196 uint8_t Type;197 198 std::optional<RelocationMap> RelocMap;199 std::optional<std::string> InstallName;200 201 std::vector<std::string> Warnings;202 203 /// For YAMLIO support.204 ///@{205 friend yaml::MappingTraits<dsymutil::DebugMapObject>;206 friend yaml::SequenceTraits<std::vector<std::unique_ptr<DebugMapObject>>>;207 208 DebugMapObject() = default;209 210public:211 DebugMapObject(DebugMapObject &&) = default;212 DebugMapObject &operator=(DebugMapObject &&) = default;213 ///@}214};215 216} // end namespace dsymutil217} // end namespace llvm218 219LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::dsymutil::DebugMapObject::YAMLSymbolMapping)220 221namespace llvm {222namespace yaml {223 224using namespace llvm::dsymutil;225 226template <> 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;229};230 231template <> struct MappingTraits<dsymutil::DebugMapObject> {232 struct YamlDMO;233 static void mapping(IO &io, dsymutil::DebugMapObject &DMO);234};235 236template <>237struct SequenceTraits<std::vector<std::unique_ptr<dsymutil::DebugMapObject>>> {238 static size_t239 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,242 size_t index);243};244 245template <> struct MappingTraits<dsymutil::DebugMap> {246 static void mapping(IO &io, dsymutil::DebugMap &DM);247};248 249template <> struct MappingTraits<std::unique_ptr<dsymutil::DebugMap>> {250 static void mapping(IO &io, std::unique_ptr<dsymutil::DebugMap> &DM);251};252 253} // end namespace yaml254} // end namespace llvm255 256#endif // LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H257