xref: /llvm-project/llvm/lib/ExecutionEngine/Orc/DebugUtils.cpp (revision af450eabb925a8735434282d4cab6280911c229a)
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/FileSystem.h"
12 #include "llvm/Support/MemoryBuffer.h"
13 #include "llvm/Support/Path.h"
14 #include "llvm/Support/raw_ostream.h"
15 
16 #define DEBUG_TYPE "orc"
17 
18 namespace llvm {
19 namespace orc {
20 
21 DumpObjects::DumpObjects(std::string DumpDir, std::string IdentifierOverride)
22     : DumpDir(std::move(DumpDir)),
23       IdentifierOverride(std::move(IdentifierOverride)) {
24 
25   /// Discard any trailing separators.
26   while (!this->DumpDir.empty() &&
27          sys::path::is_separator(this->DumpDir.back()))
28     this->DumpDir.pop_back();
29 }
30 
31 Expected<std::unique_ptr<MemoryBuffer>>
32 DumpObjects::operator()(std::unique_ptr<MemoryBuffer> Obj) {
33   size_t Idx = 1;
34 
35   std::string DumpPathStem;
36   raw_string_ostream(DumpPathStem)
37       << DumpDir << (DumpDir.empty() ? "" : "/") << getBufferIdentifier(*Obj);
38 
39   std::string DumpPath = DumpPathStem + ".o";
40   while (sys::fs::exists(DumpPath)) {
41     DumpPath.clear();
42     raw_string_ostream(DumpPath) << DumpPathStem << "." << (++Idx) << ".o";
43   }
44 
45   LLVM_DEBUG({
46     dbgs() << "Dumping object buffer [ " << (const void *)Obj->getBufferStart()
47            << " -- " << (const void *)(Obj->getBufferEnd() - 1) << " ] to "
48            << DumpPath << "\n";
49   });
50 
51   std::error_code EC;
52   raw_fd_ostream DumpStream(DumpPath, EC);
53   if (EC)
54     return errorCodeToError(EC);
55   DumpStream.write(Obj->getBufferStart(), Obj->getBufferSize());
56 
57   return std::move(Obj);
58 }
59 
60 StringRef DumpObjects::getBufferIdentifier(MemoryBuffer &B) {
61   if (!IdentifierOverride.empty())
62     return IdentifierOverride;
63   StringRef Identifier = B.getBufferIdentifier();
64   Identifier.consume_back(".o");
65   return Identifier;
66 }
67 
68 } // End namespace orc.
69 } // End namespace llvm.
70