xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/DebugUtils.cpp (revision 480093f4440d54b30b3025afeac24b48f2ba7a2e)
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