llvm-6502/tools/dsymutil/DebugMap.cpp
Frederic Riss 786b471cc6 [dsymutil] Use YAMLIO to dump debug map.
Doing so will allow us to also accept a YAML debug map in input as using
YAMLIO gives us the parsing for free. Being able to have textual debug
maps will in turn allow much more control over the tests, because 1/
no need to check-in a binary containing the debug map and 2/ it will allow
to use the same objects/IR files with made-up debug-maps to test
different scenari.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238781 91177308-0d34-0410-b5e6-96231b3b80d8
2015-06-01 21:12:45 +00:00

91 lines
2.9 KiB
C++

//===- 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"
#include "llvm/ADT/iterator_range.h"
#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,
uint64_t LinkedAddress, uint32_t Size) {
auto InsertResult = Symbols.insert(
std::make_pair(Name, SymbolMapping(ObjectAddress, LinkedAddress, Size)));
if (InsertResult.second)
AddressToMapping[ObjectAddress] = &*InsertResult.first;
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) {
OS << format("\t%016" PRIx64 " => %016" PRIx64 "+0x%x\t%s\n",
uint64_t(Sym.second.ObjectAddress),
uint64_t(Sym.second.BinaryAddress),
uint32_t(Sym.second.Size), Sym.first.data());
}
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();
}
const DebugMapObject::DebugMapEntry *
DebugMapObject::lookupSymbol(StringRef SymbolName) const {
StringMap<SymbolMapping>::const_iterator Sym = Symbols.find(SymbolName);
if (Sym == Symbols.end())
return nullptr;
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();
}
void DebugMap::print(raw_ostream &OS) const {
yaml::Output yout(OS, /* Ctxt = */ nullptr, /* WrapColumn = */ 0);
yout << const_cast<DebugMap&>(*this);
}
#ifndef NDEBUG
void DebugMap::dump() const { print(errs()); }
#endif
}
}