]> git.proxmox.com Git - rustc.git/blob - src/rustllvm/ExecutionEngineWrapper.cpp
Imported Upstream version 1.2.0+dfsg1
[rustc.git] / src / rustllvm / ExecutionEngineWrapper.cpp
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #include "rustllvm.h"
12
13 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
14
15 using namespace llvm;
16 using namespace llvm::sys;
17 using namespace llvm::object;
18
19 // libmorestack is not used on other platforms
20 #if defined(__linux__) || defined(__APPLE__)
21 extern "C" void __morestack(void);
22
23 static void* morestack_addr() {
24 return reinterpret_cast<void*>(__morestack);
25 }
26 #endif
27
28 class RustJITMemoryManager : public SectionMemoryManager
29 {
30 typedef SectionMemoryManager Base;
31
32 public:
33
34 RustJITMemoryManager() {}
35
36 uint64_t getSymbolAddress(const std::string &Name) override
37 {
38 #if defined(__linux__) || defined(__APPLE__)
39 if (Name == "__morestack" || Name == "___morestack")
40 return reinterpret_cast<uint64_t>(__morestack);
41 if (Name == "__morestack_addr" || Name == "___morestack_addr")
42 return reinterpret_cast<uint64_t>(morestack_addr);
43 #endif
44
45 return Base::getSymbolAddress(Name);
46 }
47 };
48
49 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(RustJITMemoryManager, LLVMRustJITMemoryManagerRef)
50
51 extern "C" LLVMBool LLVMRustLoadDynamicLibrary(const char *path)
52 {
53 std::string err;
54 DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(path, &err);
55
56 if (!lib.isValid())
57 LLVMRustSetLastError(err.c_str());
58
59 return lib.isValid();
60 }
61
62 // Calls LLVMAddModule;
63 // exists for consistency with LLVMExecutionEngineRemoveModule
64 extern "C" void LLVMExecutionEngineAddModule(
65 LLVMExecutionEngineRef eeref, LLVMModuleRef mref)
66 {
67 #ifdef _WIN32
68 // On Windows, MCJIT must generate ELF objects
69 std::string target = getProcessTriple();
70 target += "-elf";
71 target = Triple::normalize(target);
72 unwrap(mref)->setTargetTriple(target);
73 #endif
74 LLVMAddModule(eeref, mref);
75 }
76
77 // LLVMRemoveModule exists in LLVM's C bindings,
78 // but it requires pointless parameters
79 extern "C" LLVMBool LLVMExecutionEngineRemoveModule(
80 LLVMExecutionEngineRef eeref, LLVMModuleRef mref)
81 {
82 ExecutionEngine *ee = unwrap(eeref);
83 Module *m = unwrap(mref);
84
85 return ee->removeModule(m);
86 }
87
88 extern "C" LLVMExecutionEngineRef LLVMBuildExecutionEngine(LLVMModuleRef mod)
89 {
90 // These are necessary for code generation to work properly.
91 InitializeNativeTarget();
92 InitializeNativeTargetAsmPrinter();
93 InitializeNativeTargetAsmParser();
94
95 #ifdef _WIN32
96 // On Windows, MCJIT must generate ELF objects
97 std::string target = getProcessTriple();
98 target += "-elf";
99 target = Triple::normalize(target);
100 unwrap(mod)->setTargetTriple(target);
101 #endif
102
103 std::string error_str;
104 TargetOptions options;
105
106 RustJITMemoryManager *mm = new RustJITMemoryManager;
107
108 ExecutionEngine *ee =
109 #if LLVM_VERSION_MINOR >= 6
110 EngineBuilder(std::unique_ptr<Module>(unwrap(mod)))
111 .setMCJITMemoryManager(std::unique_ptr<RustJITMemoryManager>(mm))
112 #else
113 EngineBuilder(unwrap(mod))
114 .setMCJITMemoryManager(mm)
115 #endif
116 .setEngineKind(EngineKind::JIT)
117 .setErrorStr(&error_str)
118 .setTargetOptions(options)
119 .create();
120
121 if (!ee)
122 LLVMRustSetLastError(error_str.c_str());
123
124 return wrap(ee);
125 }
126
127 extern "C" void LLVMExecutionEngineFinalizeObject(LLVMExecutionEngineRef eeref)
128 {
129 ExecutionEngine *ee = unwrap(eeref);
130
131 ee->finalizeObject();
132 }