xref: /freebsd-src/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/DebugUtils.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1480093f4SDimitry Andric //===---------- DebugUtils.cpp - Utilities for debugging ORC JITs ---------===//
2480093f4SDimitry Andric //
3480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6480093f4SDimitry Andric //
7480093f4SDimitry Andric //===----------------------------------------------------------------------===//
8480093f4SDimitry Andric 
9480093f4SDimitry Andric #include "llvm/ExecutionEngine/Orc/DebugUtils.h"
105ffd83dbSDimitry Andric 
115ffd83dbSDimitry Andric #include "llvm/ExecutionEngine/Orc/Core.h"
125ffd83dbSDimitry Andric #include "llvm/Support/CommandLine.h"
13480093f4SDimitry Andric #include "llvm/Support/Debug.h"
145ffd83dbSDimitry Andric #include "llvm/Support/FileSystem.h"
155ffd83dbSDimitry Andric #include "llvm/Support/Format.h"
16480093f4SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
17480093f4SDimitry Andric #include "llvm/Support/Path.h"
18480093f4SDimitry Andric #include "llvm/Support/raw_ostream.h"
19480093f4SDimitry Andric 
20480093f4SDimitry Andric #define DEBUG_TYPE "orc"
21480093f4SDimitry Andric 
225ffd83dbSDimitry Andric using namespace llvm;
235ffd83dbSDimitry Andric 
245ffd83dbSDimitry Andric namespace {
255ffd83dbSDimitry Andric 
265ffd83dbSDimitry Andric #ifndef NDEBUG
275ffd83dbSDimitry Andric 
285ffd83dbSDimitry Andric cl::opt<bool> PrintHidden("debug-orc-print-hidden", cl::init(true),
295ffd83dbSDimitry Andric                           cl::desc("debug print hidden symbols defined by "
305ffd83dbSDimitry Andric                                    "materialization units"),
315ffd83dbSDimitry Andric                           cl::Hidden);
325ffd83dbSDimitry Andric 
335ffd83dbSDimitry Andric cl::opt<bool> PrintCallable("debug-orc-print-callable", cl::init(true),
345ffd83dbSDimitry Andric                             cl::desc("debug print callable symbols defined by "
355ffd83dbSDimitry Andric                                      "materialization units"),
365ffd83dbSDimitry Andric                             cl::Hidden);
375ffd83dbSDimitry Andric 
385ffd83dbSDimitry Andric cl::opt<bool> PrintData("debug-orc-print-data", cl::init(true),
395ffd83dbSDimitry Andric                         cl::desc("debug print data symbols defined by "
405ffd83dbSDimitry Andric                                  "materialization units"),
415ffd83dbSDimitry Andric                         cl::Hidden);
425ffd83dbSDimitry Andric 
435ffd83dbSDimitry Andric #endif // NDEBUG
445ffd83dbSDimitry Andric 
455ffd83dbSDimitry Andric // SetPrinter predicate that prints every element.
465ffd83dbSDimitry Andric template <typename T> struct PrintAll {
475ffd83dbSDimitry Andric   bool operator()(const T &E) { return true; }
485ffd83dbSDimitry Andric };
495ffd83dbSDimitry Andric 
505ffd83dbSDimitry Andric bool anyPrintSymbolOptionSet() {
515ffd83dbSDimitry Andric #ifndef NDEBUG
525ffd83dbSDimitry Andric   return PrintHidden || PrintCallable || PrintData;
535ffd83dbSDimitry Andric #else
545ffd83dbSDimitry Andric   return false;
555ffd83dbSDimitry Andric #endif // NDEBUG
565ffd83dbSDimitry Andric }
575ffd83dbSDimitry Andric 
585ffd83dbSDimitry Andric bool flagsMatchCLOpts(const JITSymbolFlags &Flags) {
595ffd83dbSDimitry Andric #ifndef NDEBUG
605ffd83dbSDimitry Andric   // Bail out early if this is a hidden symbol and we're not printing hiddens.
615ffd83dbSDimitry Andric   if (!PrintHidden && !Flags.isExported())
625ffd83dbSDimitry Andric     return false;
635ffd83dbSDimitry Andric 
645ffd83dbSDimitry Andric   // Return true if this is callable and we're printing callables.
655ffd83dbSDimitry Andric   if (PrintCallable && Flags.isCallable())
665ffd83dbSDimitry Andric     return true;
675ffd83dbSDimitry Andric 
685ffd83dbSDimitry Andric   // Return true if this is data and we're printing data.
695ffd83dbSDimitry Andric   if (PrintData && !Flags.isCallable())
705ffd83dbSDimitry Andric     return true;
715ffd83dbSDimitry Andric 
725ffd83dbSDimitry Andric   // otherwise return false.
735ffd83dbSDimitry Andric   return false;
745ffd83dbSDimitry Andric #else
755ffd83dbSDimitry Andric   return false;
765ffd83dbSDimitry Andric #endif // NDEBUG
775ffd83dbSDimitry Andric }
785ffd83dbSDimitry Andric 
795ffd83dbSDimitry Andric // Prints a sequence of items, filtered by an user-supplied predicate.
805ffd83dbSDimitry Andric template <typename Sequence,
815ffd83dbSDimitry Andric           typename Pred = PrintAll<typename Sequence::value_type>>
825ffd83dbSDimitry Andric class SequencePrinter {
835ffd83dbSDimitry Andric public:
845ffd83dbSDimitry Andric   SequencePrinter(const Sequence &S, char OpenSeq, char CloseSeq,
855ffd83dbSDimitry Andric                   Pred ShouldPrint = Pred())
865ffd83dbSDimitry Andric       : S(S), OpenSeq(OpenSeq), CloseSeq(CloseSeq),
875ffd83dbSDimitry Andric         ShouldPrint(std::move(ShouldPrint)) {}
885ffd83dbSDimitry Andric 
895ffd83dbSDimitry Andric   void printTo(llvm::raw_ostream &OS) const {
905ffd83dbSDimitry Andric     bool PrintComma = false;
915ffd83dbSDimitry Andric     OS << OpenSeq;
925ffd83dbSDimitry Andric     for (auto &E : S) {
935ffd83dbSDimitry Andric       if (ShouldPrint(E)) {
945ffd83dbSDimitry Andric         if (PrintComma)
955ffd83dbSDimitry Andric           OS << ',';
965ffd83dbSDimitry Andric         OS << ' ' << E;
975ffd83dbSDimitry Andric         PrintComma = true;
985ffd83dbSDimitry Andric       }
995ffd83dbSDimitry Andric     }
1005ffd83dbSDimitry Andric     OS << ' ' << CloseSeq;
1015ffd83dbSDimitry Andric   }
1025ffd83dbSDimitry Andric 
1035ffd83dbSDimitry Andric private:
1045ffd83dbSDimitry Andric   const Sequence &S;
1055ffd83dbSDimitry Andric   char OpenSeq;
1065ffd83dbSDimitry Andric   char CloseSeq;
1075ffd83dbSDimitry Andric   mutable Pred ShouldPrint;
1085ffd83dbSDimitry Andric };
1095ffd83dbSDimitry Andric 
1105ffd83dbSDimitry Andric template <typename Sequence, typename Pred>
1115ffd83dbSDimitry Andric SequencePrinter<Sequence, Pred> printSequence(const Sequence &S, char OpenSeq,
1125ffd83dbSDimitry Andric                                               char CloseSeq, Pred P = Pred()) {
1135ffd83dbSDimitry Andric   return SequencePrinter<Sequence, Pred>(S, OpenSeq, CloseSeq, std::move(P));
1145ffd83dbSDimitry Andric }
1155ffd83dbSDimitry Andric 
1165ffd83dbSDimitry Andric // Render a SequencePrinter by delegating to its printTo method.
1175ffd83dbSDimitry Andric template <typename Sequence, typename Pred>
1185ffd83dbSDimitry Andric llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
1195ffd83dbSDimitry Andric                               const SequencePrinter<Sequence, Pred> &Printer) {
1205ffd83dbSDimitry Andric   Printer.printTo(OS);
1215ffd83dbSDimitry Andric   return OS;
1225ffd83dbSDimitry Andric }
1235ffd83dbSDimitry Andric 
1245ffd83dbSDimitry Andric struct PrintSymbolFlagsMapElemsMatchingCLOpts {
1255ffd83dbSDimitry Andric   bool operator()(const orc::SymbolFlagsMap::value_type &KV) {
1265ffd83dbSDimitry Andric     return flagsMatchCLOpts(KV.second);
1275ffd83dbSDimitry Andric   }
1285ffd83dbSDimitry Andric };
1295ffd83dbSDimitry Andric 
1305ffd83dbSDimitry Andric struct PrintSymbolMapElemsMatchingCLOpts {
1315ffd83dbSDimitry Andric   bool operator()(const orc::SymbolMap::value_type &KV) {
1325ffd83dbSDimitry Andric     return flagsMatchCLOpts(KV.second.getFlags());
1335ffd83dbSDimitry Andric   }
1345ffd83dbSDimitry Andric };
1355ffd83dbSDimitry Andric 
1365ffd83dbSDimitry Andric } // end anonymous namespace
1375ffd83dbSDimitry Andric 
138480093f4SDimitry Andric namespace llvm {
139480093f4SDimitry Andric namespace orc {
140480093f4SDimitry Andric 
1415ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPtr &Sym) {
1425ffd83dbSDimitry Andric   return OS << *Sym;
1435ffd83dbSDimitry Andric }
1445ffd83dbSDimitry Andric 
145*0fca6ea1SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, NonOwningSymbolStringPtr Sym) {
146*0fca6ea1SDimitry Andric   return OS << *Sym;
147*0fca6ea1SDimitry Andric }
148*0fca6ea1SDimitry Andric 
1495ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const SymbolNameSet &Symbols) {
1505ffd83dbSDimitry Andric   return OS << printSequence(Symbols, '{', '}', PrintAll<SymbolStringPtr>());
1515ffd83dbSDimitry Andric }
1525ffd83dbSDimitry Andric 
1535ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const SymbolNameVector &Symbols) {
1545ffd83dbSDimitry Andric   return OS << printSequence(Symbols, '[', ']', PrintAll<SymbolStringPtr>());
1555ffd83dbSDimitry Andric }
1565ffd83dbSDimitry Andric 
1575ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, ArrayRef<SymbolStringPtr> Symbols) {
1585ffd83dbSDimitry Andric   return OS << printSequence(Symbols, '[', ']', PrintAll<SymbolStringPtr>());
1595ffd83dbSDimitry Andric }
1605ffd83dbSDimitry Andric 
1615ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const JITSymbolFlags &Flags) {
1625ffd83dbSDimitry Andric   if (Flags.hasError())
1635ffd83dbSDimitry Andric     OS << "[*ERROR*]";
1645ffd83dbSDimitry Andric   if (Flags.isCallable())
1655ffd83dbSDimitry Andric     OS << "[Callable]";
1665ffd83dbSDimitry Andric   else
1675ffd83dbSDimitry Andric     OS << "[Data]";
1685ffd83dbSDimitry Andric   if (Flags.isWeak())
1695ffd83dbSDimitry Andric     OS << "[Weak]";
1705ffd83dbSDimitry Andric   else if (Flags.isCommon())
1715ffd83dbSDimitry Andric     OS << "[Common]";
1725ffd83dbSDimitry Andric 
1735ffd83dbSDimitry Andric   if (!Flags.isExported())
1745ffd83dbSDimitry Andric     OS << "[Hidden]";
1755ffd83dbSDimitry Andric 
1765ffd83dbSDimitry Andric   return OS;
1775ffd83dbSDimitry Andric }
1785ffd83dbSDimitry Andric 
17906c3fb27SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const ExecutorSymbolDef &Sym) {
18006c3fb27SDimitry Andric   return OS << Sym.getAddress() << " " << Sym.getFlags();
1815ffd83dbSDimitry Andric }
1825ffd83dbSDimitry Andric 
1835ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap::value_type &KV) {
1845ffd83dbSDimitry Andric   return OS << "(\"" << KV.first << "\", " << KV.second << ")";
1855ffd83dbSDimitry Andric }
1865ffd83dbSDimitry Andric 
1875ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const SymbolMap::value_type &KV) {
1885ffd83dbSDimitry Andric   return OS << "(\"" << KV.first << "\": " << KV.second << ")";
1895ffd83dbSDimitry Andric }
1905ffd83dbSDimitry Andric 
1915ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap &SymbolFlags) {
1925ffd83dbSDimitry Andric   return OS << printSequence(SymbolFlags, '{', '}',
1935ffd83dbSDimitry Andric                              PrintSymbolFlagsMapElemsMatchingCLOpts());
1945ffd83dbSDimitry Andric }
1955ffd83dbSDimitry Andric 
1965ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const SymbolMap &Symbols) {
1975ffd83dbSDimitry Andric   return OS << printSequence(Symbols, '{', '}',
1985ffd83dbSDimitry Andric                              PrintSymbolMapElemsMatchingCLOpts());
1995ffd83dbSDimitry Andric }
2005ffd83dbSDimitry Andric 
2015ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS,
2025ffd83dbSDimitry Andric                         const SymbolDependenceMap::value_type &KV) {
2035ffd83dbSDimitry Andric   return OS << "(" << KV.first->getName() << ", " << KV.second << ")";
2045ffd83dbSDimitry Andric }
2055ffd83dbSDimitry Andric 
2065ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const SymbolDependenceMap &Deps) {
2075ffd83dbSDimitry Andric   return OS << printSequence(Deps, '{', '}',
2085ffd83dbSDimitry Andric                              PrintAll<SymbolDependenceMap::value_type>());
2095ffd83dbSDimitry Andric }
2105ffd83dbSDimitry Andric 
2115ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const MaterializationUnit &MU) {
2125ffd83dbSDimitry Andric   OS << "MU@" << &MU << " (\"" << MU.getName() << "\"";
2135ffd83dbSDimitry Andric   if (anyPrintSymbolOptionSet())
2145ffd83dbSDimitry Andric     OS << ", " << MU.getSymbols();
2155ffd83dbSDimitry Andric   return OS << ")";
2165ffd83dbSDimitry Andric }
2175ffd83dbSDimitry Andric 
2185ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const LookupKind &K) {
2195ffd83dbSDimitry Andric   switch (K) {
2205ffd83dbSDimitry Andric   case LookupKind::Static:
2215ffd83dbSDimitry Andric     return OS << "Static";
2225ffd83dbSDimitry Andric   case LookupKind::DLSym:
2235ffd83dbSDimitry Andric     return OS << "DLSym";
2245ffd83dbSDimitry Andric   }
2255ffd83dbSDimitry Andric   llvm_unreachable("Invalid lookup kind");
2265ffd83dbSDimitry Andric }
2275ffd83dbSDimitry Andric 
2285ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS,
2295ffd83dbSDimitry Andric                         const JITDylibLookupFlags &JDLookupFlags) {
2305ffd83dbSDimitry Andric   switch (JDLookupFlags) {
2315ffd83dbSDimitry Andric   case JITDylibLookupFlags::MatchExportedSymbolsOnly:
2325ffd83dbSDimitry Andric     return OS << "MatchExportedSymbolsOnly";
2335ffd83dbSDimitry Andric   case JITDylibLookupFlags::MatchAllSymbols:
2345ffd83dbSDimitry Andric     return OS << "MatchAllSymbols";
2355ffd83dbSDimitry Andric   }
2365ffd83dbSDimitry Andric   llvm_unreachable("Invalid JITDylib lookup flags");
2375ffd83dbSDimitry Andric }
2385ffd83dbSDimitry Andric 
2395ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LookupFlags) {
2405ffd83dbSDimitry Andric   switch (LookupFlags) {
2415ffd83dbSDimitry Andric   case SymbolLookupFlags::RequiredSymbol:
2425ffd83dbSDimitry Andric     return OS << "RequiredSymbol";
2435ffd83dbSDimitry Andric   case SymbolLookupFlags::WeaklyReferencedSymbol:
2445ffd83dbSDimitry Andric     return OS << "WeaklyReferencedSymbol";
2455ffd83dbSDimitry Andric   }
2465ffd83dbSDimitry Andric   llvm_unreachable("Invalid symbol lookup flags");
2475ffd83dbSDimitry Andric }
2485ffd83dbSDimitry Andric 
2495ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS,
2505ffd83dbSDimitry Andric                         const SymbolLookupSet::value_type &KV) {
2515ffd83dbSDimitry Andric   return OS << "(" << KV.first << ", " << KV.second << ")";
2525ffd83dbSDimitry Andric }
2535ffd83dbSDimitry Andric 
2545ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupSet &LookupSet) {
2555ffd83dbSDimitry Andric   return OS << printSequence(LookupSet, '{', '}',
2565ffd83dbSDimitry Andric                              PrintAll<SymbolLookupSet::value_type>());
2575ffd83dbSDimitry Andric }
2585ffd83dbSDimitry Andric 
2595ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS,
2605ffd83dbSDimitry Andric                         const JITDylibSearchOrder &SearchOrder) {
2615ffd83dbSDimitry Andric   OS << "[";
2625ffd83dbSDimitry Andric   if (!SearchOrder.empty()) {
2635ffd83dbSDimitry Andric     assert(SearchOrder.front().first &&
2645ffd83dbSDimitry Andric            "JITDylibList entries must not be null");
2655ffd83dbSDimitry Andric     OS << " (\"" << SearchOrder.front().first->getName() << "\", "
2665ffd83dbSDimitry Andric        << SearchOrder.begin()->second << ")";
267fe6060f1SDimitry Andric     for (auto &KV : llvm::drop_begin(SearchOrder)) {
2685ffd83dbSDimitry Andric       assert(KV.first && "JITDylibList entries must not be null");
2695ffd83dbSDimitry Andric       OS << ", (\"" << KV.first->getName() << "\", " << KV.second << ")";
2705ffd83dbSDimitry Andric     }
2715ffd83dbSDimitry Andric   }
2725ffd83dbSDimitry Andric   OS << " ]";
2735ffd83dbSDimitry Andric   return OS;
2745ffd83dbSDimitry Andric }
2755ffd83dbSDimitry Andric 
2765ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const SymbolAliasMap &Aliases) {
2775ffd83dbSDimitry Andric   OS << "{";
2785ffd83dbSDimitry Andric   for (auto &KV : Aliases)
2795ffd83dbSDimitry Andric     OS << " " << *KV.first << ": " << KV.second.Aliasee << " "
2805ffd83dbSDimitry Andric        << KV.second.AliasFlags;
2815ffd83dbSDimitry Andric   OS << " }";
2825ffd83dbSDimitry Andric   return OS;
2835ffd83dbSDimitry Andric }
2845ffd83dbSDimitry Andric 
2855ffd83dbSDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const SymbolState &S) {
2865ffd83dbSDimitry Andric   switch (S) {
2875ffd83dbSDimitry Andric   case SymbolState::Invalid:
2885ffd83dbSDimitry Andric     return OS << "Invalid";
2895ffd83dbSDimitry Andric   case SymbolState::NeverSearched:
2905ffd83dbSDimitry Andric     return OS << "Never-Searched";
2915ffd83dbSDimitry Andric   case SymbolState::Materializing:
2925ffd83dbSDimitry Andric     return OS << "Materializing";
2935ffd83dbSDimitry Andric   case SymbolState::Resolved:
2945ffd83dbSDimitry Andric     return OS << "Resolved";
2955ffd83dbSDimitry Andric   case SymbolState::Emitted:
2965ffd83dbSDimitry Andric     return OS << "Emitted";
2975ffd83dbSDimitry Andric   case SymbolState::Ready:
2985ffd83dbSDimitry Andric     return OS << "Ready";
2995ffd83dbSDimitry Andric   }
3005ffd83dbSDimitry Andric   llvm_unreachable("Invalid state");
3015ffd83dbSDimitry Andric }
3025ffd83dbSDimitry Andric 
30381ad6265SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPool &SSP) {
30481ad6265SDimitry Andric   std::lock_guard<std::mutex> Lock(SSP.PoolMutex);
30506c3fb27SDimitry Andric   SmallVector<std::pair<StringRef, int>, 0> Vec;
30681ad6265SDimitry Andric   for (auto &KV : SSP.Pool)
30706c3fb27SDimitry Andric     Vec.emplace_back(KV.first(), KV.second);
30806c3fb27SDimitry Andric   llvm::sort(Vec, less_first());
30906c3fb27SDimitry Andric   for (auto &[K, V] : Vec)
31006c3fb27SDimitry Andric     OS << K << ": " << V << "\n";
31181ad6265SDimitry Andric   return OS;
31281ad6265SDimitry Andric }
31381ad6265SDimitry Andric 
314480093f4SDimitry Andric DumpObjects::DumpObjects(std::string DumpDir, std::string IdentifierOverride)
315480093f4SDimitry Andric     : DumpDir(std::move(DumpDir)),
316480093f4SDimitry Andric       IdentifierOverride(std::move(IdentifierOverride)) {
317480093f4SDimitry Andric 
318480093f4SDimitry Andric   /// Discard any trailing separators.
319480093f4SDimitry Andric   while (!this->DumpDir.empty() &&
320480093f4SDimitry Andric          sys::path::is_separator(this->DumpDir.back()))
321480093f4SDimitry Andric     this->DumpDir.pop_back();
322480093f4SDimitry Andric }
323480093f4SDimitry Andric 
324480093f4SDimitry Andric Expected<std::unique_ptr<MemoryBuffer>>
325480093f4SDimitry Andric DumpObjects::operator()(std::unique_ptr<MemoryBuffer> Obj) {
326480093f4SDimitry Andric   size_t Idx = 1;
327480093f4SDimitry Andric 
328480093f4SDimitry Andric   std::string DumpPathStem;
329480093f4SDimitry Andric   raw_string_ostream(DumpPathStem)
330480093f4SDimitry Andric       << DumpDir << (DumpDir.empty() ? "" : "/") << getBufferIdentifier(*Obj);
331480093f4SDimitry Andric 
332480093f4SDimitry Andric   std::string DumpPath = DumpPathStem + ".o";
333480093f4SDimitry Andric   while (sys::fs::exists(DumpPath)) {
334480093f4SDimitry Andric     DumpPath.clear();
335480093f4SDimitry Andric     raw_string_ostream(DumpPath) << DumpPathStem << "." << (++Idx) << ".o";
336480093f4SDimitry Andric   }
337480093f4SDimitry Andric 
338480093f4SDimitry Andric   LLVM_DEBUG({
339480093f4SDimitry Andric     dbgs() << "Dumping object buffer [ " << (const void *)Obj->getBufferStart()
340480093f4SDimitry Andric            << " -- " << (const void *)(Obj->getBufferEnd() - 1) << " ] to "
341480093f4SDimitry Andric            << DumpPath << "\n";
342480093f4SDimitry Andric   });
343480093f4SDimitry Andric 
344480093f4SDimitry Andric   std::error_code EC;
345480093f4SDimitry Andric   raw_fd_ostream DumpStream(DumpPath, EC);
346480093f4SDimitry Andric   if (EC)
347480093f4SDimitry Andric     return errorCodeToError(EC);
348480093f4SDimitry Andric   DumpStream.write(Obj->getBufferStart(), Obj->getBufferSize());
349480093f4SDimitry Andric 
350480093f4SDimitry Andric   return std::move(Obj);
351480093f4SDimitry Andric }
352480093f4SDimitry Andric 
353480093f4SDimitry Andric StringRef DumpObjects::getBufferIdentifier(MemoryBuffer &B) {
354480093f4SDimitry Andric   if (!IdentifierOverride.empty())
355480093f4SDimitry Andric     return IdentifierOverride;
356480093f4SDimitry Andric   StringRef Identifier = B.getBufferIdentifier();
357480093f4SDimitry Andric   Identifier.consume_back(".o");
358480093f4SDimitry Andric   return Identifier;
359480093f4SDimitry Andric }
360480093f4SDimitry Andric 
361480093f4SDimitry Andric } // End namespace orc.
362480093f4SDimitry Andric } // End namespace llvm.
363