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