Adding a workaround for __main linking with remote lli and Cygwin/MinGW
authorAndrew Kaylor <andrew.kaylor@intel.com>
Tue, 29 Oct 2013 01:29:56 +0000 (01:29 +0000)
committerAndrew Kaylor <andrew.kaylor@intel.com>
Tue, 29 Oct 2013 01:29:56 +0000 (01:29 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193570 91177308-0d34-0410-b5e6-96231b3b80d8

test/ExecutionEngine/MCJIT/remote/cross-module-a.ll
test/ExecutionEngine/MCJIT/remote/multi-module-a.ll
test/ExecutionEngine/MCJIT/remote/simpletest-remote.ll
test/ExecutionEngine/MCJIT/remote/test-common-symbols-remote.ll
test/ExecutionEngine/MCJIT/remote/test-data-align-remote.ll
test/ExecutionEngine/MCJIT/remote/test-fp-no-external-funcs-remote.ll
test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-remote.ll
test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-remote.ll
tools/lli/lli.cpp

index 79efb3cfc77a361a1fc72f54ccb4135be49d1374..094d362262c5c5fd3d5ebc915405fbaabacca95a 100644 (file)
@@ -1,8 +1,5 @@
 ; RUN: %lli_mcjit -extra-module=%p/Inputs/cross-module-b.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target %s > /dev/null
 
-; This fails because __main is not resolved in remote mcjit.
-; XFAIL: cygwin,mingw32
-
 declare i32 @FB()
 
 define i32 @FA() {
index d7c282914f32a5873826cab88bc8c576b7b8c55e..91d0387376ca6b1780e656a3ebaf640da2419c50 100644 (file)
@@ -1,8 +1,5 @@
 ; RUN: %lli_mcjit -extra-module=%p/Inputs/multi-module-b.ll -extra-module=%p/Inputs/multi-module-c.ll -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target %s > /dev/null
 
-; This fails because __main is not resolved in remote mcjit.
-; XFAIL: cygwin,mingw32
-
 declare i32 @FB()
 
 define i32 @main() {
index f717fde4f9efee58e0f8c84743c291e635eda134..d10a4117a0ddaaac95d991e38c15c17dbb771b3f 100644 (file)
@@ -1,8 +1,5 @@
 ; RUN: %lli_mcjit -remote-mcjit -mcjit-remote-process=lli-child-target %s > /dev/null
 
-; This fails because __main is not resolved in remote mcjit on cygming.
-; XFAIL: cygwin,mingw32,mips
-
 define i32 @bar() {
        ret i32 0
 }
index c3dbac3269359dc9a9346667c1b8c0c995f0ac53..63280895a9a3f264736e6188f9fe1c0bd863b0eb 100644 (file)
@@ -1,8 +1,5 @@
 ; RUN: %lli_mcjit -remote-mcjit -O0 -disable-lazy-compilation=false -mcjit-remote-process=lli-child-target %s
 
-; This fails because __main is not resolved in remote mcjit on cygming.
-; XFAIL: cygwin,mingw32,mips
-
 ; The intention of this test is to verify that symbols mapped to COMMON in ELF
 ; work as expected.
 ;
index 8583bfe87870be3dccf529c2f99b0b4b786577bf..297925498fb46364e2c535a68e76ac11aa6e3711 100644 (file)
@@ -1,7 +1,6 @@
 ; RUN:  %lli_mcjit -remote-mcjit -O0 -mcjit-remote-process=lli-child-target %s
 
-; This fails because __main is not resolved in remote mcjit on cygming.
-; XFAIL: cygwin,mingw32,mips
+; XFAIL: mips
 
 ; Check that a variable is always aligned as specified.
 
index 4f658ac92068a35a5c940f9924b44a7ab1ae31d8..6bad7a2584196223cabc13299c7fe8be91e8a1cb 100644 (file)
@@ -1,7 +1,6 @@
 ; RUN: %lli_mcjit -remote-mcjit -mcjit-remote-process=lli-child-target %s > /dev/null
 
-; This fails because __main is not resolved in remote mcjit on cygming.
-; XFAIL: cygwin,mingw32,mips
+; XFAIL: mips
 
 define double @test(double* %DP, double %Arg) {
        %D = load double* %DP           ; <double> [#uses=1]
index 77868b91830088a68e4be001c0f6c5174a42dc34..cdb577938c8605a26a865be5f52fb6a2c8fddb8f 100644 (file)
@@ -1,7 +1,6 @@
 ; RUN: %lli_mcjit -remote-mcjit -mcjit-remote-process=lli-child-target %s > /dev/null
 
-; This fails because __main is not resolved in remote mcjit on cygming.
-; XFAIL: cygwin,mingw32,mips
+; XFAIL: mips
 
 @count = global i32 1, align 4
 
index 3b542c39b16bf6fe054bd105a62986dcbed13123..8b562972b5d18089f775f1c8d1412bdb9ae7f2d2 100644 (file)
@@ -1,8 +1,5 @@
 ; RUN: %lli_mcjit -remote-mcjit -O0 -mcjit-remote-process=lli-child-target %s
 
-; This fails because __main is not resolved in remote mcjit.
-; XFAIL: cygwin,mingw32
-
 @.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1
 @ptr = global i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0), align 4
 @.str1 = private unnamed_addr constant [6 x i8] c"data2\00", align 1
index 9e0a78f66188e83239329f56db77c10ad2a42bc7..808a95a599e862b3ae4786da4e2f88d9f8885b36 100644 (file)
 #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<int64_t(void), false>::get(Context),
+      GlobalValue::ExternalLinkage, "__main", M);
+  } else {
+    Result = Function::Create(
+      TypeBuilder<int32_t(void), false>::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(