Skip to content

Instantly share code, notes, and snippets.

@gmarkall
Forked from gligneul/mcjit.cpp
Created February 10, 2021 13:03
Show Gist options
  • Save gmarkall/2e2b3a6d1d7e8b888b6bc613fd7976b9 to your computer and use it in GitHub Desktop.
Save gmarkall/2e2b3a6d1d7e8b888b6bc613fd7976b9 to your computer and use it in GitHub Desktop.
LLVM MCJIT Code Samples (Working!)
/*
* To compile, execute on terminal:
* g++ -o mcjit mcjit.cpp `llvm-config --cxxflags --ldflags --libs all --system-libs`
*/
#include <iostream>
#include <memory>
#include <llvm/ADT/StringRef.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/IR/Constant.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Verifier.h>
#include <llvm/Support/DynamicLibrary.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/Support/TargetSelect.h>
void foo() {
std::cout << "foo()\n";
}
int main() {
llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmPrinter();
llvm::InitializeNativeTargetAsmParser();
llvm::LLVMContext context;
auto module = new llvm::Module("top", context);
llvm::IRBuilder<> builder(context);
auto footype = llvm::FunctionType::get(builder.getVoidTy(), false);
auto foofunc = llvm::Function::Create(footype,
llvm::Function::ExternalLinkage, "foo", module);
// Line commented to mess up resolution of relocation and cause a jump to 0x0
//llvm::sys::DynamicLibrary::AddSymbol("foo", reinterpret_cast<void*>(foo));
auto functype = llvm::FunctionType::get(builder.getInt32Ty(), false);
auto mainfunc = llvm::Function::Create(functype,
llvm::Function::ExternalLinkage, "main", module);
auto entryblock = llvm::BasicBlock::Create(context, "entry", mainfunc);
builder.SetInsertPoint(entryblock);
builder.CreateCall(foofunc);
builder.CreateRet(llvm::ConstantInt::get(builder.getInt32Ty(), 0));
std::string error;
llvm::raw_string_ostream error_os(error);
if (llvm::verifyModule(*module, &error_os)) {
std::cerr << "Module Error: " << error << '\n';
return 1;
}
module->print(llvm::errs(), nullptr);
auto engine = llvm::EngineBuilder(std::unique_ptr<llvm::Module>(module))
.setErrorStr(&error)
.setOptLevel(llvm::CodeGenOpt::Aggressive)
.setEngineKind(llvm::EngineKind::JIT)
.create();
if (!engine) {
std::cerr << "EE Error: " << error << '\n';
return 1;
}
engine->finalizeObject();
typedef void (*Function)();
Function f = reinterpret_cast<Function>(
engine->getPointerToNamedFunction("main"));
f();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment