//===----- LLJITDumpObjects.cpp - How to dump JIT'd objects with LLJIT ----===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// /// \file /// /// This example demonstrates how to use LLJIT to: /// - Add absolute symbol definitions. /// - Run static constructors for a JITDylib. /// - Run static destructors for a JITDylib. /// /// This example does not call any functions (e.g. main or equivalent) between /// running the static constructors and running the static destructors. /// //===----------------------------------------------------------------------===// #include "llvm/ADT/StringMap.h" #include "llvm/ExecutionEngine/Orc/LLJIT.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" #include "../ExampleModules.h" using namespace llvm; using namespace llvm::orc; ExitOnError ExitOnErr; const llvm::StringRef ModuleWithInitializer = R"( @InitializersRunFlag = external global i32 @DeinitializersRunFlag = external global i32 declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*) @__dso_handle = external hidden global i8 @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @init_func, i8* null }] define internal void @init_func() { entry: store i32 1, i32* @InitializersRunFlag %0 = call i32 @__cxa_atexit(void (i8*)* @deinit_func, i8* null, i8* @__dso_handle) ret void } define internal void @deinit_func(i8* %0) { store i32 1, i32* @DeinitializersRunFlag ret void } )"; int main(int argc, char *argv[]) { // Initialize LLVM. InitLLVM X(argc, argv); InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); cl::ParseCommandLineOptions(argc, argv, "LLJITWithInitializers"); ExitOnErr.setBanner(std::string(argv[0]) + ": "); auto J = ExitOnErr(LLJITBuilder().create()); auto M = ExitOnErr(parseExampleModule(ModuleWithInitializer, "M")); // Load the module. ExitOnErr(J->addIRModule(std::move(M))); int32_t InitializersRunFlag = 0; int32_t DeinitializersRunFlag = 0; ExitOnErr(J->getMainJITDylib().define(absoluteSymbols( {{J->mangleAndIntern("InitializersRunFlag"), JITEvaluatedSymbol::fromPointer(&InitializersRunFlag)}, {J->mangleAndIntern("DeinitializersRunFlag"), JITEvaluatedSymbol::fromPointer(&DeinitializersRunFlag)}}))); // Run static initializers. ExitOnErr(J->initialize(J->getMainJITDylib())); // Run deinitializers. ExitOnErr(J->deinitialize(J->getMainJITDylib())); outs() << "InitializerRanFlag = " << InitializersRunFlag << "\n" << "DeinitializersRunFlag = " << DeinitializersRunFlag << "\n"; return 0; }