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/AbsoluteSymbols.h" 23 #include "llvm/ExecutionEngine/Orc/LLJIT.h" 24 #include "llvm/Support/InitLLVM.h" 25 #include "llvm/Support/TargetSelect.h" 26 #include "llvm/Support/raw_ostream.h" 27 28 #include "../ExampleModules.h" 29 30 using namespace llvm; 31 using namespace llvm::orc; 32 33 ExitOnError ExitOnErr; 34 35 const llvm::StringRef ModuleWithInitializer = 36 R"( 37 38 @InitializersRunFlag = external global i32 39 @DeinitializersRunFlag = external global i32 40 41 declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*) 42 @__dso_handle = external hidden global i8 43 44 @llvm.global_ctors = 45 appending global [1 x { i32, void ()*, i8* }] 46 [{ i32, void ()*, i8* } { i32 65535, void ()* @init_func, i8* null }] 47 48 define internal void @init_func() { 49 entry: 50 store i32 1, i32* @InitializersRunFlag 51 %0 = call i32 @__cxa_atexit(void (i8*)* @deinit_func, i8* null, 52 i8* @__dso_handle) 53 ret void 54 } 55 56 define internal void @deinit_func(i8* %0) { 57 store i32 1, i32* @DeinitializersRunFlag 58 ret void 59 } 60 61 )"; 62 63 int main(int argc, char *argv[]) { 64 // Initialize LLVM. 65 InitLLVM X(argc, argv); 66 67 InitializeNativeTarget(); 68 InitializeNativeTargetAsmPrinter(); 69 70 cl::ParseCommandLineOptions(argc, argv, "LLJITWithInitializers"); 71 ExitOnErr.setBanner(std::string(argv[0]) + ": "); 72 73 auto J = ExitOnErr(LLJITBuilder().create()); 74 auto M = ExitOnErr(parseExampleModule(ModuleWithInitializer, "M")); 75 76 // Load the module. 77 ExitOnErr(J->addIRModule(std::move(M))); 78 79 int32_t InitializersRunFlag = 0; 80 int32_t DeinitializersRunFlag = 0; 81 82 ExitOnErr(J->getMainJITDylib().define( 83 absoluteSymbols({{J->mangleAndIntern("InitializersRunFlag"), 84 {ExecutorAddr::fromPtr(&InitializersRunFlag), 85 JITSymbolFlags::Exported}}, 86 {J->mangleAndIntern("DeinitializersRunFlag"), 87 {ExecutorAddr::fromPtr(&DeinitializersRunFlag), 88 JITSymbolFlags::Exported}}}))); 89 90 // Run static initializers. 91 ExitOnErr(J->initialize(J->getMainJITDylib())); 92 93 // Run deinitializers. 94 ExitOnErr(J->deinitialize(J->getMainJITDylib())); 95 96 outs() << "InitializerRanFlag = " << InitializersRunFlag << "\n" 97 << "DeinitializersRunFlag = " << DeinitializersRunFlag << "\n"; 98 99 return 0; 100 } 101