1 //===---- DebugObjectManagerPlugin.h - JITLink debug objects ---*- C++ -*-===//
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 // ObjectLinkingLayer plugin for emitting debug objects.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_EXECUTIONENGINE_ORC_DEBUGOBJECTMANAGERPLUGIN_H
14 #define LLVM_EXECUTIONENGINE_ORC_DEBUGOBJECTMANAGERPLUGIN_H
15 
16 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
17 #include "llvm/ExecutionEngine/Orc/Core.h"
18 #include "llvm/ExecutionEngine/Orc/EPCDebugObjectRegistrar.h"
19 #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
20 #include "llvm/Support/Error.h"
21 #include "llvm/Support/Memory.h"
22 #include "llvm/Support/MemoryBufferRef.h"
23 #include "llvm/TargetParser/Triple.h"
24 
25 #include <functional>
26 #include <map>
27 #include <memory>
28 #include <mutex>
29 
30 namespace llvm {
31 namespace orc {
32 
33 class DebugObject;
34 
35 /// Creates and manages DebugObjects for JITLink artifacts.
36 ///
37 /// DebugObjects are created when linking for a MaterializationResponsibility
38 /// starts. They are pending as long as materialization is in progress.
39 ///
40 /// There can only be one pending DebugObject per MaterializationResponsibility.
41 /// If materialization fails, pending DebugObjects are discarded.
42 ///
43 /// Once executable code for the MaterializationResponsibility is emitted, the
44 /// corresponding DebugObject is finalized to target memory and the provided
45 /// DebugObjectRegistrar is notified. Ownership of DebugObjects remains with the
46 /// plugin.
47 ///
48 class DebugObjectManagerPlugin : public ObjectLinkingLayer::Plugin {
49 public:
50   // DEPRECATED - Please specify options explicitly
51   DebugObjectManagerPlugin(ExecutionSession &ES,
52                            std::unique_ptr<DebugObjectRegistrar> Target);
53 
54   /// Create the plugin to submit DebugObjects for JITLink artifacts. For all
55   /// options the recommended setting is true.
56   ///
57   /// RequireDebugSections:
58   ///   Submit debug objects to the executor only if they contain actual debug
59   ///   info. Turning this off may allow minimal debugging based on raw symbol
60   ///   names. Note that this may cause significant memory and transport
61   ///   overhead for objects built with a release configuration.
62   ///
63   /// AutoRegisterCode:
64   ///   Notify the debugger for each new debug object. This is a good default
65   ///   mode, but it may cause significant overhead when adding many modules in
66   ///   sequence. When turning this off, the user has to issue the call to
67   ///   __jit_debug_register_code() on the executor side manually.
68   ///
69   DebugObjectManagerPlugin(ExecutionSession &ES,
70                            std::unique_ptr<DebugObjectRegistrar> Target,
71                            bool RequireDebugSections, bool AutoRegisterCode);
72   ~DebugObjectManagerPlugin();
73 
74   void notifyMaterializing(MaterializationResponsibility &MR,
75                            jitlink::LinkGraph &G, jitlink::JITLinkContext &Ctx,
76                            MemoryBufferRef InputObject) override;
77 
78   Error notifyEmitted(MaterializationResponsibility &MR) override;
79   Error notifyFailed(MaterializationResponsibility &MR) override;
80   Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override;
81 
82   void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
83                                    ResourceKey SrcKey) override;
84 
85   void modifyPassConfig(MaterializationResponsibility &MR,
86                         jitlink::LinkGraph &LG,
87                         jitlink::PassConfiguration &PassConfig) override;
88 
89 private:
90   ExecutionSession &ES;
91 
92   using OwnedDebugObject = std::unique_ptr<DebugObject>;
93   std::map<MaterializationResponsibility *, OwnedDebugObject> PendingObjs;
94   std::map<ResourceKey, std::vector<OwnedDebugObject>> RegisteredObjs;
95 
96   std::mutex PendingObjsLock;
97   std::mutex RegisteredObjsLock;
98 
99   std::unique_ptr<DebugObjectRegistrar> Target;
100   bool RequireDebugSections;
101   bool AutoRegisterCode;
102 };
103 
104 } // namespace orc
105 } // namespace llvm
106 
107 #endif // LLVM_EXECUTIONENGINE_ORC_DEBUGOBJECTMANAGERPLUGIN_H
108