1*82d56013Sjoerg //===----- LLJITDumpObjects.cpp - How to dump JIT'd objects with LLJIT ----===//
2*82d56013Sjoerg //
3*82d56013Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*82d56013Sjoerg // See https://llvm.org/LICENSE.txt for license information.
5*82d56013Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*82d56013Sjoerg //
7*82d56013Sjoerg //===----------------------------------------------------------------------===//
8*82d56013Sjoerg ///
9*82d56013Sjoerg /// \file
10*82d56013Sjoerg ///
11*82d56013Sjoerg /// This example demonstrates how to use LLJIT to:
12*82d56013Sjoerg ///   - Add absolute symbol definitions.
13*82d56013Sjoerg ///   - Run static constructors for a JITDylib.
14*82d56013Sjoerg ///   - Run static destructors for a JITDylib.
15*82d56013Sjoerg ///
16*82d56013Sjoerg /// This example does not call any functions (e.g. main or equivalent)  between
17*82d56013Sjoerg /// running the static constructors and running the static destructors.
18*82d56013Sjoerg ///
19*82d56013Sjoerg //===----------------------------------------------------------------------===//
20*82d56013Sjoerg 
21*82d56013Sjoerg #include "llvm/ADT/StringMap.h"
22*82d56013Sjoerg #include "llvm/ExecutionEngine/Orc/LLJIT.h"
23*82d56013Sjoerg #include "llvm/Support/InitLLVM.h"
24*82d56013Sjoerg #include "llvm/Support/TargetSelect.h"
25*82d56013Sjoerg #include "llvm/Support/raw_ostream.h"
26*82d56013Sjoerg 
27*82d56013Sjoerg #include "../ExampleModules.h"
28*82d56013Sjoerg 
29*82d56013Sjoerg using namespace llvm;
30*82d56013Sjoerg using namespace llvm::orc;
31*82d56013Sjoerg 
32*82d56013Sjoerg ExitOnError ExitOnErr;
33*82d56013Sjoerg 
34*82d56013Sjoerg const llvm::StringRef ModuleWithInitializer =
35*82d56013Sjoerg     R"(
36*82d56013Sjoerg 
37*82d56013Sjoerg   @InitializersRunFlag = external global i32
38*82d56013Sjoerg   @DeinitializersRunFlag = external global i32
39*82d56013Sjoerg 
40*82d56013Sjoerg   declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*)
41*82d56013Sjoerg   @__dso_handle = external hidden global i8
42*82d56013Sjoerg 
43*82d56013Sjoerg   @llvm.global_ctors =
44*82d56013Sjoerg     appending global [1 x { i32, void ()*, i8* }]
45*82d56013Sjoerg       [{ i32, void ()*, i8* } { i32 65535, void ()* @init_func, i8* null }]
46*82d56013Sjoerg 
47*82d56013Sjoerg   define internal void @init_func() {
48*82d56013Sjoerg   entry:
49*82d56013Sjoerg     store i32 1, i32* @InitializersRunFlag
50*82d56013Sjoerg     %0 = call i32 @__cxa_atexit(void (i8*)* @deinit_func, i8* null,
51*82d56013Sjoerg                                 i8* @__dso_handle)
52*82d56013Sjoerg     ret void
53*82d56013Sjoerg   }
54*82d56013Sjoerg 
55*82d56013Sjoerg   define internal void @deinit_func(i8* %0) {
56*82d56013Sjoerg     store i32 1, i32* @DeinitializersRunFlag
57*82d56013Sjoerg     ret void
58*82d56013Sjoerg   }
59*82d56013Sjoerg 
60*82d56013Sjoerg )";
61*82d56013Sjoerg 
main(int argc,char * argv[])62*82d56013Sjoerg int main(int argc, char *argv[]) {
63*82d56013Sjoerg   // Initialize LLVM.
64*82d56013Sjoerg   InitLLVM X(argc, argv);
65*82d56013Sjoerg 
66*82d56013Sjoerg   InitializeNativeTarget();
67*82d56013Sjoerg   InitializeNativeTargetAsmPrinter();
68*82d56013Sjoerg 
69*82d56013Sjoerg   cl::ParseCommandLineOptions(argc, argv, "LLJITWithInitializers");
70*82d56013Sjoerg   ExitOnErr.setBanner(std::string(argv[0]) + ": ");
71*82d56013Sjoerg 
72*82d56013Sjoerg   auto J = ExitOnErr(LLJITBuilder().create());
73*82d56013Sjoerg   auto M = ExitOnErr(parseExampleModule(ModuleWithInitializer, "M"));
74*82d56013Sjoerg 
75*82d56013Sjoerg   // Load the module.
76*82d56013Sjoerg   ExitOnErr(J->addIRModule(std::move(M)));
77*82d56013Sjoerg 
78*82d56013Sjoerg   int32_t InitializersRunFlag = 0;
79*82d56013Sjoerg   int32_t DeinitializersRunFlag = 0;
80*82d56013Sjoerg 
81*82d56013Sjoerg   ExitOnErr(J->getMainJITDylib().define(absoluteSymbols(
82*82d56013Sjoerg       {{J->mangleAndIntern("InitializersRunFlag"),
83*82d56013Sjoerg         JITEvaluatedSymbol::fromPointer(&InitializersRunFlag)},
84*82d56013Sjoerg        {J->mangleAndIntern("DeinitializersRunFlag"),
85*82d56013Sjoerg         JITEvaluatedSymbol::fromPointer(&DeinitializersRunFlag)}})));
86*82d56013Sjoerg 
87*82d56013Sjoerg   // Run static initializers.
88*82d56013Sjoerg   ExitOnErr(J->initialize(J->getMainJITDylib()));
89*82d56013Sjoerg 
90*82d56013Sjoerg   // Run deinitializers.
91*82d56013Sjoerg   ExitOnErr(J->deinitialize(J->getMainJITDylib()));
92*82d56013Sjoerg 
93*82d56013Sjoerg   outs() << "InitializerRanFlag = " << InitializersRunFlag << "\n"
94*82d56013Sjoerg          << "DeinitializersRunFlag = " << DeinitializersRunFlag << "\n";
95*82d56013Sjoerg 
96*82d56013Sjoerg   return 0;
97*82d56013Sjoerg }
98