#ifndef LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H
#define LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/YAMLTraits.h"
#include <vector>
namespace llvm {
class raw_ostream;
namespace dsymutil {
class DebugMapObject;
class DebugMap {
Triple BinaryTriple;
std::string BinaryPath;
std::vector<uint8_t> BinaryUUID;
typedef std::vector<std::unique_ptr<DebugMapObject>> ObjectContainer;
ObjectContainer Objects;
friend yaml::MappingTraits<DebugMap>;
std::vector<std::unique_ptr<DebugMapObject>> &getObjects() { return Objects; }
public:
DebugMap(const Triple &BinaryTriple, StringRef BinaryPath = "",
ArrayRef<uint8_t> BinaryUUID = ArrayRef<uint8_t>())
: BinaryTriple(BinaryTriple), BinaryPath(BinaryPath),
BinaryUUID(BinaryUUID.begin(), BinaryUUID.end()) {}
DebugMap() {}
typedef ObjectContainer::const_iterator const_iterator;
iterator_range<const_iterator> objects() const {
return make_range(begin(), end());
}
const_iterator begin() const { return Objects.begin(); }
const_iterator end() const { return Objects.end(); }
DebugMapObject &back() { return *Objects.back(); }
DebugMapObject &addDebugMapObject(StringRef ObjectFilePath,
sys::TimeValue Timestamp,
bool SwiftModule = false);
void addSwiftModule(StringRef ModulePath, sys::TimeValue Timestamp);
const Triple &getTriple() const { return BinaryTriple; }
const ArrayRef<uint8_t> getUUID() const {
return ArrayRef<uint8_t>(BinaryUUID);
}
StringRef getBinaryPath() const { return BinaryPath; }
void print(raw_ostream &OS) const;
#ifndef NDEBUG
void dump() const;
#endif
};
class DebugMapObject {
public:
struct SymbolMapping {
yaml::Hex64 ObjectAddress;
yaml::Hex64 BinaryAddress;
std::string Section;
yaml::Hex32 Size;
bool FromAnotherObjectFile;
SymbolMapping(uint64_t ObjectAddress, uint64_t BinaryAddress,
StringRef Section, uint32_t Size,
bool FromAnotherObjectFile)
: ObjectAddress(ObjectAddress), BinaryAddress(BinaryAddress),
Section(Section), Size(Size),
FromAnotherObjectFile(FromAnotherObjectFile) {}
SymbolMapping() {}
};
typedef StringMapEntry<SymbolMapping> DebugMapEntry;
bool addSymbol(llvm::StringRef SymName, uint64_t ObjectAddress,
uint64_t LinkedAddress, uint32_t Size, StringRef Section,
bool FromAnotherObjectFile = false);
const DebugMapEntry *lookupSymbol(StringRef SymbolName) const;
const DebugMapEntry *lookupObjectAddress(uint64_t Address,
StringRef Section) const;
llvm::StringRef getObjectFilename() const { return Filename; }
sys::TimeValue getTimestamp() const { return Timestamp; }
bool isSwiftModule() const { return SwiftModule; }
iterator_range<StringMap<SymbolMapping>::const_iterator> symbols() const {
return make_range(Symbols.begin(), Symbols.end());
}
bool empty() { return Symbols.empty(); }
void print(raw_ostream &OS) const;
#ifndef NDEBUG
void dump() const;
#endif
void addWarning(StringRef Warning) { Warnings.push_back(Warning); }
const std::vector<std::string> &getWarnings() const { return Warnings; }
private:
friend class DebugMap;
DebugMapObject(StringRef ObjectFilename, sys::TimeValue Timestamp,
bool SwiftModule);
std::string Filename;
sys::TimeValue Timestamp;
bool SwiftModule;
StringMap<SymbolMapping> Symbols;
std::map<uint64_t, DebugMapEntry *> AddressToMapping;
std::vector<std::string> Warnings;
friend yaml::MappingTraits<dsymutil::DebugMapObject>;
friend yaml::SequenceTraits<std::vector<std::unique_ptr<DebugMapObject>>>;
DebugMapObject() {}
};
}
}
namespace llvm {
namespace yaml {
template <>
struct MappingTraits<
std::pair<std::string, dsymutil::DebugMapObject::SymbolMapping>> {
static void
mapping(IO &io,
std::pair<std::string, dsymutil::DebugMapObject::SymbolMapping> &s) {
io.mapRequired("sym", s.first);
io.mapRequired("objAddr", s.second.ObjectAddress);
io.mapRequired("binAddr", s.second.BinaryAddress);
}
};
template <>
struct SequenceTraits<std::vector<
std::pair<std::string, dsymutil::DebugMapObject::SymbolMapping>>> {
static size_t
size(IO &io,
std::vector<std::pair<std::string,
dsymutil::DebugMapObject::SymbolMapping>> &seq) {
return seq.size();
}
static std::pair<std::string, dsymutil::DebugMapObject::SymbolMapping> &
element(IO &,
std::vector<std::pair<std::string,
dsymutil::DebugMapObject::SymbolMapping>> &seq,
size_t index) {
if (index >= seq.size())
seq.resize(index + 1);
return seq[index];
}
};
template <> struct MappingTraits<dsymutil::DebugMapObject> {
struct SequencedStringMap {
public:
SequencedStringMap(IO &io) {}
SequencedStringMap(
IO &io, StringMap<dsymutil::DebugMapObject::SymbolMapping> &Map) {
Entries.reserve(Map.size());
for (auto &Entry : Map)
Entries.push_back(std::make_pair(Entry.getKey(), Entry.getValue()));
}
StringMap<dsymutil::DebugMapObject::SymbolMapping> denormalize(IO &) {
StringMap<dsymutil::DebugMapObject::SymbolMapping> Res;
for (auto &Entry : Entries)
Res[Entry.first] = Entry.second;
return std::move(Res);
}
std::vector<std::pair<std::string, dsymutil::DebugMapObject::SymbolMapping>>
Entries;
};
static void mapping(IO &io, dsymutil::DebugMapObject &s) {
MappingNormalization<SequencedStringMap,
StringMap<dsymutil::DebugMapObject::SymbolMapping>>
seq(io, s.Symbols);
io.mapRequired("filename", s.Filename);
io.mapRequired("symbols", seq->Entries);
}
};
template <> struct ScalarTraits<Triple> {
static void output(const Triple &val, void *, llvm::raw_ostream &out) {
out << val.str();
}
static StringRef input(StringRef scalar, void *, Triple &value) {
value = Triple(scalar);
return value.str();
}
static bool mustQuote(StringRef) { return true; }
};
template <>
struct SequenceTraits<std::vector<std::unique_ptr<dsymutil::DebugMapObject>>> {
static size_t
size(IO &io, std::vector<std::unique_ptr<dsymutil::DebugMapObject>> &seq) {
return seq.size();
}
static dsymutil::DebugMapObject &
element(IO &, std::vector<std::unique_ptr<dsymutil::DebugMapObject>> &seq,
size_t index) {
if (index >= seq.size()) {
seq.resize(index + 1);
seq[index].reset(new dsymutil::DebugMapObject);
}
return *seq[index];
}
};
template <> struct MappingTraits<dsymutil::DebugMap> {
static void mapping(IO &io, dsymutil::DebugMap &DM) {
io.mapRequired("triple", DM.BinaryTriple);
io.mapRequired("binary", DM.BinaryPath);
io.mapOptional("objects", DM.Objects);
}
};
}
}
#endif // LLVM_TOOLS_DSYMUTIL_DEBUGMAP_H