From: Frederic Riss Date: Mon, 1 Jun 2015 21:12:45 +0000 (+0000) Subject: [dsymutil] Use YAMLIO to dump debug map. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=786b471cc65c830eae0117f6e63936b0d065034d;p=oota-llvm.git [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 --- diff --git a/test/tools/dsymutil/debug-map-parsing.test b/test/tools/dsymutil/debug-map-parsing.test index 3422316191f..180689ba68a 100644 --- a/test/tools/dsymutil/debug-map-parsing.test +++ b/test/tools/dsymutil/debug-map-parsing.test @@ -8,33 +8,35 @@ RUN: not llvm-dsymutil -v -parse-only %p/Inputs/inexistant 2>&1 | FileCheck %s - Check that We can parse the debug map of the basic executable. CHECK-NOT: error -CHECK: DEBUG MAP: x86_64-unknown-unknown-macho -CHECK: /Inputs/basic1.macho.x86_64.o: -CHECK: 0000000000000000 => 0000000100000ea0+0x24 _main -CHECK: /Inputs/basic2.macho.x86_64.o: -CHECK: 0000000000000310 => 0000000100001000+0x0 _baz -CHECK: 0000000000000020 => 0000000100000ed0+0x50 _foo -CHECK: 0000000000000070 => 0000000100000f20+0x17 _inc -CHECK: 0000000000000560 => 0000000100001008+0x0 _private_int -CHECK: /Inputs/basic3.macho.x86_64.o: -CHECK: 0000000000000020 => 0000000100000f40+0x50 _bar -CHECK: 0000000000000070 => 0000000100000f90+0x19 _inc -CHECK: 0000000000000004 => 0000000100001004+0x0 _val -CHECK: END DEBUG MAP +CHECK: --- +CHECK: triple: 'x86_64-unknown-unknown-macho' +CHECK: filename:{{.*}}/Inputs/basic1.macho.x86_64.o +CHECK-DAG: sym: _main, objAddr: 0x0000000000000000, binAddr: 0x0000000100000EA0, size: 0x00000024 +CHECK: filename{{.*}}/Inputs/basic2.macho.x86_64.o +CHECK-DAG: sym: _baz, objAddr: 0x0000000000000310, binAddr: 0x0000000100001000, size: 0x00000000 +CHECK-DAG: sym: _foo, objAddr: 0x0000000000000020, binAddr: 0x0000000100000ED0, size: 0x00000050 +CHECK-DAG: sym: _inc, objAddr: 0x0000000000000070, binAddr: 0x0000000100000F20, size: 0x00000017 +CHECK-DAG: sym: _private_int, objAddr: 0x0000000000000560, binAddr: 0x0000000100001008, size: 0x00000000 +CHECK: filename{{.*}}/Inputs/basic3.macho.x86_64.o +CHECK-DAG: sym: _bar, objAddr: 0x0000000000000020, binAddr: 0x0000000100000F40, size: 0x00000050 +CHECK-DAG: sym: _inc, objAddr: 0x0000000000000070, binAddr: 0x0000000100000F90, size: 0x00000019 +CHECK-DAG: sym: _val, objAddr: 0x0000000000000004, binAddr: 0x0000000100001004, size: 0x00000000 +CHECK: ... Check that we can parse the debug-map of the basic-lto executable CHECK-LTO-NOT: error -CHECK-LTO: DEBUG MAP: x86_64-unknown-unknown-macho -CHECK-LTO: /Inputs/basic-lto.macho.x86_64.o: -CHECK-LTO: 0000000000000050 => 0000000100000f90+0x24 _bar -CHECK-LTO: 0000000000000658 => 0000000100001000+0x0 _baz -CHECK-LTO: 0000000000000010 => 0000000100000f50+0x40 _foo -CHECK-LTO: 0000000000000000 => 0000000100000f40+0x10 _main -CHECK-LTO: 00000000000008e8 => 0000000100001008+0x0 _private_int -CHECK-LTO: 00000000000008ec => 0000000100001004+0x0 _val -CHECK-LTO: END DEBUG MAP +CHECK-LTO: --- +CHECK-LTO: triple: 'x86_64-unknown-unknown-macho' +CHECK-LTO: /Inputs/basic-lto.macho.x86_64.o +CHECK-LTO-DAG: sym: _bar, objAddr: 0x0000000000000050, binAddr: 0x0000000100000F90, size: 0x00000024 +CHECK-LTO-DAG: sym: _baz, objAddr: 0x0000000000000658, binAddr: 0x0000000100001000, size: 0x00000000 +CHECK-LTO-DAG: sym: _foo, objAddr: 0x0000000000000010, binAddr: 0x0000000100000F50, size: 0x00000040 +CHECK-LTO-DAG: sym: _main, objAddr: 0x0000000000000000, binAddr: 0x0000000100000F40, size: 0x00000010 +CHECK-LTO-DAG: sym: _private_int, objAddr: 0x00000000000008E8, binAddr: 0x0000000100001008, size: 0x00000000 +CHECK-LTO-DAG: sym: _val, objAddr: 0x00000000000008EC, binAddr: 0x0000000100001004, size: 0x00000000 +CHECK-LTO: ... Check thet we correctly handle debug maps with archive members (including only opening the archive once if mulitple of its members are used). @@ -48,20 +50,20 @@ CHECK-ARCHIVE-NEXT: opened new archive {{.*}}/libbasic.a' CHECK-ARCHIVE-NEXT: found member in current archive. CHECK-ARCHIVE-NEXT: trying to open {{.*}}/libbasic.a(basic3.macho.x86_64.o)' CHECK-ARCHIVE-NEXT: found member in current archive. -CHECK-ARCHIVE: DEBUG MAP: x86_64-unknown-unknown-macho -CHECK-ARCHIVE: object addr => executable addr symbol name -CHECK-ARCHIVE: /Inputs/basic1.macho.x86_64.o: -CHECK-ARCHIVE: 0000000000000000 => 0000000100000ea0+0x24 _main -CHECK-ARCHIVE: /Inputs/./libbasic.a(basic2.macho.x86_64.o): -CHECK-ARCHIVE: 0000000000000310 => 0000000100001000+0x0 _baz -CHECK-ARCHIVE: 0000000000000020 => 0000000100000ed0+0x50 _foo -CHECK-ARCHIVE: 0000000000000070 => 0000000100000f20+0x17 _inc -CHECK-ARCHIVE: 0000000000000560 => 0000000100001004+0x0 _private_int -CHECK-ARCHIVE: /Inputs/./libbasic.a(basic3.macho.x86_64.o): -CHECK-ARCHIVE: 0000000000000020 => 0000000100000f40+0x50 _bar -CHECK-ARCHIVE: 0000000000000070 => 0000000100000f90+0x19 _inc -CHECK-ARCHIVE: 0000000000000004 => 0000000100001008+0x0 _val -CHECK-ARCHIVE: END DEBUG MAP +CHECK-ARCHIVE: --- +CHECK-ARCHIVE: triple: 'x86_64-unknown-unknown-macho' +CHECK-ARCHIVE: /Inputs/basic1.macho.x86_64.o +CHECK-ARCHIVE-DAG: sym: _main, objAddr: 0x0000000000000000, binAddr: 0x0000000100000EA0, size: 0x00000024 +CHECK-ARCHIVE: /Inputs/./libbasic.a(basic2.macho.x86_64.o) +CHECK-ARCHIVE-DAG: sym: _baz, objAddr: 0x0000000000000310, binAddr: 0x0000000100001000, size: 0x00000000 +CHECK-ARCHIVE-DAG: sym: _foo, objAddr: 0x0000000000000020, binAddr: 0x0000000100000ED0, size: 0x00000050 +CHECK-ARCHIVE-DAG: sym: _inc, objAddr: 0x0000000000000070, binAddr: 0x0000000100000F20, size: 0x00000017 +CHECK-ARCHIVE-DAG: sym: _private_int, objAddr: 0x0000000000000560, binAddr: 0x0000000100001004, size: 0x00000000 +CHECK-ARCHIVE: /Inputs/./libbasic.a(basic3.macho.x86_64.o) +CHECK-ARCHIVE-DAG: sym: _bar, objAddr: 0x0000000000000020, binAddr: 0x0000000100000F40, size: 0x00000050 +CHECK-ARCHIVE-DAG: sym: _inc, objAddr: 0x0000000000000070, binAddr: 0x0000000100000F90, size: 0x00000019 +CHECK-ARCHIVE-DAG: sym: _val, objAddr: 0x0000000000000004, binAddr: 0x0000000100001008, size: 0x00000000 +CHECK-ARCHIVE: ... Check that we warn about missing object files (this presumes that the files aren't present in the machine's /Inputs/ folder, which should be a pretty safe bet). @@ -69,11 +71,11 @@ present in the machine's /Inputs/ folder, which should be a pretty safe bet). NOT-FOUND: cannot open{{.*}}"/Inputs/basic1.macho.x86_64.o": {{[Nn]o}} such file NOT-FOUND: cannot open{{.*}}"/Inputs/basic2.macho.x86_64.o": {{[Nn]o}} such file NOT-FOUND: cannot open{{.*}}"/Inputs/basic3.macho.x86_64.o": {{[Nn]o}} such file -NOT-FOUND: DEBUG MAP: -NOT-FOUND-NEXT: object addr => executable addr symbol name -NOT-FOUND-NEXT: END DEBUG MAP +NOT-FOUND: --- +NOT-FOUND-NEXT: triple: 'x86_64-unknown-unknown-macho' +NOT-FOUND-NEXT: ... Check that we correctly error out on invalid executatble. NO-EXECUTABLE: cannot parse{{.*}}/inexistant": {{[Nn]o}} such file -NO-EXECUTABLE-NOT: DEBUG MAP +NO-EXECUTABLE-NOT: --- diff --git a/tools/dsymutil/DebugMap.cpp b/tools/dsymutil/DebugMap.cpp index 9fa3f788a89..dcbba19b107 100644 --- a/tools/dsymutil/DebugMap.cpp +++ b/tools/dsymutil/DebugMap.cpp @@ -46,8 +46,9 @@ void DebugMapObject::print(raw_ostream &OS) const { [](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", - Sym.second.ObjectAddress, Sym.second.BinaryAddress, - Sym.second.Size, Sym.first.data()); + uint64_t(Sym.second.ObjectAddress), + uint64_t(Sym.second.BinaryAddress), + uint32_t(Sym.second.Size), Sym.first.data()); } OS << '\n'; } @@ -78,11 +79,8 @@ DebugMapObject::lookupObjectAddress(uint64_t Address) const { } void DebugMap::print(raw_ostream &OS) const { - OS << "DEBUG MAP: " << BinaryTriple.getTriple() - << "\n\tobject addr => executable addr\tsymbol name\n"; - for (const auto &Obj : objects()) - Obj->print(OS); - OS << "END DEBUG MAP\n"; + yaml::Output yout(OS, /* Ctxt = */ nullptr, /* WrapColumn = */ 0); + yout << const_cast(*this); } #ifndef NDEBUG diff --git a/tools/dsymutil/DebugMap.h b/tools/dsymutil/DebugMap.h index ee48b093d4f..ab806c9cd1c 100644 --- a/tools/dsymutil/DebugMap.h +++ b/tools/dsymutil/DebugMap.h @@ -28,6 +28,7 @@ #include "llvm/Object/ObjectFile.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/Format.h" +#include "llvm/Support/YAMLTraits.h" #include namespace llvm { @@ -66,6 +67,11 @@ class DebugMap { typedef std::vector> ObjectContainer; ObjectContainer Objects; + /// For YAML IO support. + ///@{ + friend yaml::MappingTraits; + DebugMap() = default; + ///@} public: DebugMap(const Triple &BinaryTriple) : BinaryTriple(BinaryTriple) {} @@ -99,12 +105,14 @@ public: class DebugMapObject { public: struct SymbolMapping { - uint64_t ObjectAddress; - uint64_t BinaryAddress; - uint32_t Size; + yaml::Hex64 ObjectAddress; + yaml::Hex64 BinaryAddress; + yaml::Hex32 Size; SymbolMapping(uint64_t ObjectAddress, uint64_t BinaryAddress, uint32_t Size) : ObjectAddress(ObjectAddress), BinaryAddress(BinaryAddress), Size(Size) {} + /// For YAML IO support + SymbolMapping() = default; }; typedef StringMapEntry DebugMapEntry; @@ -141,6 +149,109 @@ private: std::string Filename; StringMap Symbols; DenseMap AddressToMapping; + + /// For YAMLIO support. + ///@{ + typedef std::pair YAMLSymbolMapping; + friend yaml::MappingTraits; + friend yaml::SequenceTraits>>; + friend yaml::SequenceTraits>; + DebugMapObject() = default; + ///@} +}; +} +} + +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::dsymutil::DebugMapObject::YAMLSymbolMapping); + +namespace llvm { +namespace yaml { + +using namespace llvm::dsymutil; + +template <> +struct MappingTraits> { + + static void + mapping(IO &io, std::pair &s) { + io.mapRequired("sym", s.first); + io.mapRequired("objAddr", s.second.ObjectAddress); + io.mapRequired("binAddr", s.second.BinaryAddress); + io.mapOptional("size", s.second.Size); + } + + static const bool flow = true; +}; + +template <> struct MappingTraits { + typedef StringMap SymbolMap; + + struct SequencedStringMap { + SequencedStringMap(IO &io) {} + + SequencedStringMap(IO &io, SymbolMap &Map) { + Entries.reserve(Map.size()); + for (auto &Entry : Map) + Entries.push_back(std::make_pair(Entry.getKey(), Entry.getValue())); + } + + SymbolMap denormalize(IO &) { + SymbolMap Res; + + for (auto &Entry : Entries) + Res[Entry.first] = Entry.second; + + return std::move(Res); + } + + std::vector Entries; + }; + + static void mapping(IO &io, dsymutil::DebugMapObject &s) { + MappingNormalization seq(io, s.Symbols); + io.mapRequired("filename", s.Filename); + io.mapRequired("symbols", seq->Entries); + } +}; + +template <> struct ScalarTraits { + + 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>> { + + static size_t + size(IO &io, std::vector> &seq) { + return seq.size(); + } + + static dsymutil::DebugMapObject & + element(IO &, std::vector> &seq, + size_t index) { + if (index >= seq.size()) { + seq.resize(index + 1); + seq[index].reset(new dsymutil::DebugMapObject); + } + return *seq[index]; + } +}; + +template <> struct MappingTraits { + static void mapping(IO &io, dsymutil::DebugMap &DM) { + io.mapRequired("triple", DM.BinaryTriple); + io.mapOptional("objects", DM.Objects); + } }; } } diff --git a/tools/dsymutil/DwarfLinker.cpp b/tools/dsymutil/DwarfLinker.cpp index e3e7e82eab6..fd79526fbac 100644 --- a/tools/dsymutil/DwarfLinker.cpp +++ b/tools/dsymutil/DwarfLinker.cpp @@ -1508,15 +1508,15 @@ bool DwarfLinker::hasValidRelocation(uint32_t StartOffset, uint32_t EndOffset, return false; const auto &ValidReloc = ValidRelocs[NextValidReloc++]; + const auto &Mapping = ValidReloc.Mapping->getValue(); if (Options.Verbose) outs() << "Found valid debug map entry: " << ValidReloc.Mapping->getKey() << " " << format("\t%016" PRIx64 " => %016" PRIx64, - ValidReloc.Mapping->getValue().ObjectAddress, - ValidReloc.Mapping->getValue().BinaryAddress); + uint64_t(Mapping.ObjectAddress), + uint64_t(Mapping.BinaryAddress)); - Info.AddrAdjust = int64_t(ValidReloc.Mapping->getValue().BinaryAddress) + - ValidReloc.Addend - - ValidReloc.Mapping->getValue().ObjectAddress; + Info.AddrAdjust = int64_t(Mapping.BinaryAddress) + + ValidReloc.Addend - Mapping.ObjectAddress; Info.InDebugMap = true; return true; }