2014-12-13 01:31:24 +08:00
|
|
|
//===- tools/dsymutil/DebugMap.cpp - Generic debug map representation -----===//
|
|
|
|
//
|
|
|
|
// The LLVM Linker
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "DebugMap.h"
|
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2015-01-14 19:23:27 +08:00
|
|
|
#include "llvm/ADT/iterator_range.h"
|
2014-12-13 01:31:24 +08:00
|
|
|
#include "llvm/Support/DataTypes.h"
|
|
|
|
#include "llvm/Support/Format.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
namespace llvm {
|
|
|
|
namespace dsymutil {
|
|
|
|
|
|
|
|
using namespace llvm::object;
|
|
|
|
|
|
|
|
DebugMapObject::DebugMapObject(StringRef ObjectFilename)
|
|
|
|
: Filename(ObjectFilename) {}
|
|
|
|
|
|
|
|
bool DebugMapObject::addSymbol(StringRef Name, uint64_t ObjectAddress,
|
2015-03-15 09:29:30 +08:00
|
|
|
uint64_t LinkedAddress, uint32_t Size) {
|
2014-12-13 01:31:24 +08:00
|
|
|
auto InsertResult = Symbols.insert(
|
2015-03-15 09:29:30 +08:00
|
|
|
std::make_pair(Name, SymbolMapping(ObjectAddress, LinkedAddress, Size)));
|
2015-02-14 07:18:16 +08:00
|
|
|
|
|
|
|
if (InsertResult.second)
|
|
|
|
AddressToMapping[ObjectAddress] = &*InsertResult.first;
|
2014-12-13 01:31:24 +08:00
|
|
|
return InsertResult.second;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DebugMapObject::print(raw_ostream &OS) const {
|
|
|
|
OS << getObjectFilename() << ":\n";
|
|
|
|
// Sort the symbols in alphabetical order, like llvm-nm (and to get
|
|
|
|
// deterministic output for testing).
|
|
|
|
typedef std::pair<StringRef, SymbolMapping> Entry;
|
|
|
|
std::vector<Entry> Entries;
|
|
|
|
Entries.reserve(Symbols.getNumItems());
|
|
|
|
for (const auto &Sym : make_range(Symbols.begin(), Symbols.end()))
|
|
|
|
Entries.push_back(std::make_pair(Sym.getKey(), Sym.getValue()));
|
|
|
|
std::sort(
|
|
|
|
Entries.begin(), Entries.end(),
|
|
|
|
[](const Entry &LHS, const Entry &RHS) { return LHS.first < RHS.first; });
|
|
|
|
for (const auto &Sym : Entries) {
|
2015-03-15 09:29:30 +08:00
|
|
|
OS << format("\t%016" PRIx64 " => %016" PRIx64 "+0x%x\t%s\n",
|
2015-06-02 05:12:45 +08:00
|
|
|
uint64_t(Sym.second.ObjectAddress),
|
|
|
|
uint64_t(Sym.second.BinaryAddress),
|
|
|
|
uint32_t(Sym.second.Size), Sym.first.data());
|
2014-12-13 01:31:24 +08:00
|
|
|
}
|
|
|
|
OS << '\n';
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
void DebugMapObject::dump() const { print(errs()); }
|
|
|
|
#endif
|
|
|
|
|
|
|
|
DebugMapObject &DebugMap::addDebugMapObject(StringRef ObjectFilePath) {
|
|
|
|
Objects.emplace_back(new DebugMapObject(ObjectFilePath));
|
|
|
|
return *Objects.back();
|
|
|
|
}
|
|
|
|
|
2015-02-14 07:18:16 +08:00
|
|
|
const DebugMapObject::DebugMapEntry *
|
2014-12-13 01:31:24 +08:00
|
|
|
DebugMapObject::lookupSymbol(StringRef SymbolName) const {
|
|
|
|
StringMap<SymbolMapping>::const_iterator Sym = Symbols.find(SymbolName);
|
|
|
|
if (Sym == Symbols.end())
|
|
|
|
return nullptr;
|
2015-02-14 07:18:16 +08:00
|
|
|
return &*Sym;
|
|
|
|
}
|
|
|
|
|
|
|
|
const DebugMapObject::DebugMapEntry *
|
|
|
|
DebugMapObject::lookupObjectAddress(uint64_t Address) const {
|
|
|
|
auto Mapping = AddressToMapping.find(Address);
|
|
|
|
if (Mapping == AddressToMapping.end())
|
|
|
|
return nullptr;
|
|
|
|
return Mapping->getSecond();
|
2014-12-13 01:31:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void DebugMap::print(raw_ostream &OS) const {
|
2015-06-02 05:12:45 +08:00
|
|
|
yaml::Output yout(OS, /* Ctxt = */ nullptr, /* WrapColumn = */ 0);
|
|
|
|
yout << const_cast<DebugMap&>(*this);
|
2014-12-13 01:31:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
void DebugMap::dump() const { print(errs()); }
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|