From 47b7fd54481d25aff90bfe772d54435bbea0908f Mon Sep 17 00:00:00 2001 From: Andrew Kaylor Date: Tue, 29 Oct 2013 01:29:56 +0000 Subject: Adding a workaround for __main linking with remote lli and Cygwin/MinGW git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193570 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/lli.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'tools/lli') diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index 9e0a78f661..808a95a599 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -27,8 +27,10 @@ #include "llvm/ExecutionEngine/JITMemoryManager.h" #include "llvm/ExecutionEngine/MCJIT.h" #include "llvm/ExecutionEngine/SectionMemoryManager.h" +#include "llvm/IR/IRBuilder.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" +#include "llvm/IR/TypeBuilder.h" #include "llvm/IRReader/IRReader.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -227,6 +229,46 @@ static void do_shutdown() { #endif } +// On Mingw and Cygwin, an external symbol named '__main' is called from the +// generated 'main' function to allow static intialization. To avoid linking +// problems with remote targets (because lli's remote target support does not +// currently handle external linking) we add a secondary module which defines +// an empty '__main' function. +static void addCygMingExtraModule(ExecutionEngine *EE, + LLVMContext &Context, + StringRef TargetTripleStr) { + IRBuilder<> Builder(Context); + Triple TargetTriple(TargetTripleStr); + + // Create a new module. + Module *M = new Module("CygMingHelper", Context); + M->setTargetTriple(TargetTripleStr); + + // Create an empty function named "__main". + Function *Result; + if (TargetTriple.isArch64Bit()) { + Result = Function::Create( + TypeBuilder::get(Context), + GlobalValue::ExternalLinkage, "__main", M); + } else { + Result = Function::Create( + TypeBuilder::get(Context), + GlobalValue::ExternalLinkage, "__main", M); + } + BasicBlock *BB = BasicBlock::Create(Context, "__main", Result); + Builder.SetInsertPoint(BB); + Value *ReturnVal; + if (TargetTriple.isArch64Bit()) + ReturnVal = ConstantInt::get(Context, APInt(64, 0)); + else + ReturnVal = ConstantInt::get(Context, APInt(32, 0)); + Builder.CreateRet(ReturnVal); + + // Add this new module to the ExecutionEngine. + EE->addModule(M); +} + + //===----------------------------------------------------------------------===// // main Driver function // @@ -359,6 +401,12 @@ int main(int argc, char **argv, char * const *envp) { EE->addModule(XMod); } + // If the target is Cygwin/MingW and we are generating remote code, we + // need an extra module to help out with linking. + if (RemoteMCJIT && Triple(Mod->getTargetTriple()).isOSCygMing()) { + addCygMingExtraModule(EE, Context, Mod->getTargetTriple()); + } + // The following functions have no effect if their respective profiling // support wasn't enabled in the build configuration. EE->RegisterJITEventListener( -- cgit v1.2.3