1*480093f4SDimitry Andric //===---------- DebugUtils.cpp - Utilities for debugging ORC JITs ---------===// 2*480093f4SDimitry Andric // 3*480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*480093f4SDimitry Andric // 7*480093f4SDimitry Andric //===----------------------------------------------------------------------===// 8*480093f4SDimitry Andric 9*480093f4SDimitry Andric #include "llvm/ExecutionEngine/Orc/DebugUtils.h" 10*480093f4SDimitry Andric #include "llvm/Support/Debug.h" 11*480093f4SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 12*480093f4SDimitry Andric #include "llvm/Support/Path.h" 13*480093f4SDimitry Andric #include "llvm/Support/raw_ostream.h" 14*480093f4SDimitry Andric 15*480093f4SDimitry Andric #define DEBUG_TYPE "orc" 16*480093f4SDimitry Andric 17*480093f4SDimitry Andric namespace llvm { 18*480093f4SDimitry Andric namespace orc { 19*480093f4SDimitry Andric 20*480093f4SDimitry Andric DumpObjects::DumpObjects(std::string DumpDir, std::string IdentifierOverride) 21*480093f4SDimitry Andric : DumpDir(std::move(DumpDir)), 22*480093f4SDimitry Andric IdentifierOverride(std::move(IdentifierOverride)) { 23*480093f4SDimitry Andric 24*480093f4SDimitry Andric /// Discard any trailing separators. 25*480093f4SDimitry Andric while (!this->DumpDir.empty() && 26*480093f4SDimitry Andric sys::path::is_separator(this->DumpDir.back())) 27*480093f4SDimitry Andric this->DumpDir.pop_back(); 28*480093f4SDimitry Andric } 29*480093f4SDimitry Andric 30*480093f4SDimitry Andric Expected<std::unique_ptr<MemoryBuffer>> 31*480093f4SDimitry Andric DumpObjects::operator()(std::unique_ptr<MemoryBuffer> Obj) { 32*480093f4SDimitry Andric size_t Idx = 1; 33*480093f4SDimitry Andric 34*480093f4SDimitry Andric std::string DumpPathStem; 35*480093f4SDimitry Andric raw_string_ostream(DumpPathStem) 36*480093f4SDimitry Andric << DumpDir << (DumpDir.empty() ? "" : "/") << getBufferIdentifier(*Obj); 37*480093f4SDimitry Andric 38*480093f4SDimitry Andric std::string DumpPath = DumpPathStem + ".o"; 39*480093f4SDimitry Andric while (sys::fs::exists(DumpPath)) { 40*480093f4SDimitry Andric DumpPath.clear(); 41*480093f4SDimitry Andric raw_string_ostream(DumpPath) << DumpPathStem << "." << (++Idx) << ".o"; 42*480093f4SDimitry Andric } 43*480093f4SDimitry Andric 44*480093f4SDimitry Andric LLVM_DEBUG({ 45*480093f4SDimitry Andric dbgs() << "Dumping object buffer [ " << (const void *)Obj->getBufferStart() 46*480093f4SDimitry Andric << " -- " << (const void *)(Obj->getBufferEnd() - 1) << " ] to " 47*480093f4SDimitry Andric << DumpPath << "\n"; 48*480093f4SDimitry Andric }); 49*480093f4SDimitry Andric 50*480093f4SDimitry Andric std::error_code EC; 51*480093f4SDimitry Andric raw_fd_ostream DumpStream(DumpPath, EC); 52*480093f4SDimitry Andric if (EC) 53*480093f4SDimitry Andric return errorCodeToError(EC); 54*480093f4SDimitry Andric DumpStream.write(Obj->getBufferStart(), Obj->getBufferSize()); 55*480093f4SDimitry Andric 56*480093f4SDimitry Andric return std::move(Obj); 57*480093f4SDimitry Andric } 58*480093f4SDimitry Andric 59*480093f4SDimitry Andric StringRef DumpObjects::getBufferIdentifier(MemoryBuffer &B) { 60*480093f4SDimitry Andric if (!IdentifierOverride.empty()) 61*480093f4SDimitry Andric return IdentifierOverride; 62*480093f4SDimitry Andric StringRef Identifier = B.getBufferIdentifier(); 63*480093f4SDimitry Andric Identifier.consume_back(".o"); 64*480093f4SDimitry Andric return Identifier; 65*480093f4SDimitry Andric } 66*480093f4SDimitry Andric 67*480093f4SDimitry Andric } // End namespace orc. 68*480093f4SDimitry Andric } // End namespace llvm. 69