1 //===--------------- LLJITWithGDBRegistrationListener.cpp -----------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file shows how to switch LLJIT to use a custom object linking layer (we
10 // use ObjectLinkingLayer, which is backed by JITLink, as an example).
12 //===----------------------------------------------------------------------===//
14 #include "llvm/ADT/StringMap.h"
15 #include "llvm/ExecutionEngine/JITEventListener.h"
16 #include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
17 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
18 #include "llvm/ExecutionEngine/Orc/LLJIT.h"
19 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
20 #include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h"
21 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
22 #include "llvm/Support/InitLLVM.h"
23 #include "llvm/Support/TargetSelect.h"
24 #include "llvm/Support/raw_ostream.h"
26 #include "../ExampleModules.h"
29 using namespace llvm::orc
;
31 ExitOnError ExitOnErr
;
33 static cl::opt
<std::string
>
34 EntryPointName("entry", cl::desc("Symbol to call as main entry point"),
37 static cl::list
<std::string
> InputFiles(cl::Positional
, cl::OneOrMore
,
38 cl::desc("input files"));
40 static cl::list
<std::string
> InputArgv("args", cl::Positional
,
41 cl::desc("<program arguments>..."),
42 cl::PositionalEatsArgs
);
44 int main(int argc
, char *argv
[]) {
46 InitLLVM
X(argc
, argv
);
48 InitializeNativeTarget();
49 InitializeNativeTargetAsmPrinter();
51 cl::ParseCommandLineOptions(argc
, argv
, "LLJITWithGDBRegistrationListener");
52 ExitOnErr
.setBanner(std::string(argv
[0]) + ": ");
54 // Detect the host and set code model to small.
55 auto JTMB
= ExitOnErr(JITTargetMachineBuilder::detectHost());
56 if (!JTMB
.getTargetTriple().isOSLinux())
58 << "Warning: This demo may not work for platforms other than Linux.\n";
60 // Create an LLJIT instance and use a custom object linking layer creator to
61 // register the GDBRegistrationListener with our RTDyldObjectLinkingLayer.
63 ExitOnErr(LLJITBuilder()
64 .setJITTargetMachineBuilder(std::move(JTMB
))
65 .setObjectLinkingLayerCreator([&](ExecutionSession
&ES
,
67 auto GetMemMgr
= []() {
68 return std::make_unique
<SectionMemoryManager
>();
70 auto ObjLinkingLayer
=
71 std::make_unique
<RTDyldObjectLinkingLayer
>(
72 ES
, std::move(GetMemMgr
));
74 // Register the event listener.
75 ObjLinkingLayer
->registerJITEventListener(
76 *JITEventListener::createGDBRegistrationListener());
78 // Make sure the debug info sections aren't stripped.
79 ObjLinkingLayer
->setProcessAllSections(true);
81 return ObjLinkingLayer
;
85 // Load the input modules.
86 for (auto &InputFile
: InputFiles
) {
87 auto Ctx
= std::make_unique
<LLVMContext
>();
89 std::unique_ptr
<Module
> M
= parseIRFile(InputFile
, Err
, *Ctx
);
91 Err
.print(argv
[0], errs());
95 ExitOnErr(J
->addIRModule(ThreadSafeModule(std::move(M
), std::move(Ctx
))));
98 // Look up the entry point, cast it to a C main function pointer, then use
99 // runAsMain to call it.
100 auto EntryAddr
= ExitOnErr(J
->lookup(EntryPointName
));
101 auto EntryFn
= EntryAddr
.toPtr
<int(int, char *[])>();
103 return runAsMain(EntryFn
, InputArgv
, StringRef(InputFiles
.front()));