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