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