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.
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.
13 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
16 using namespace llvm::sys
;
17 using namespace llvm::object
;
19 // libmorestack is not used on other platforms
20 #if defined(__linux__) || defined(__APPLE__)
21 extern "C" void __morestack(void);
23 static void* morestack_addr() {
24 return reinterpret_cast<void*>(__morestack
);
28 class RustJITMemoryManager
: public SectionMemoryManager
30 typedef SectionMemoryManager Base
;
34 RustJITMemoryManager() {}
36 uint64_t getSymbolAddress(const std::string
&Name
) override
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
);
45 return Base::getSymbolAddress(Name
);
49 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(RustJITMemoryManager
, LLVMRustJITMemoryManagerRef
)
51 extern "C" LLVMBool
LLVMRustLoadDynamicLibrary(const char *path
)
54 DynamicLibrary lib
= DynamicLibrary::getPermanentLibrary(path
, &err
);
57 LLVMRustSetLastError(err
.c_str());
62 // Calls LLVMAddModule;
63 // exists for consistency with LLVMExecutionEngineRemoveModule
64 extern "C" void LLVMExecutionEngineAddModule(
65 LLVMExecutionEngineRef eeref
, LLVMModuleRef mref
)
68 // On Windows, MCJIT must generate ELF objects
69 std::string target
= getProcessTriple();
71 target
= Triple::normalize(target
);
72 unwrap(mref
)->setTargetTriple(target
);
74 LLVMAddModule(eeref
, mref
);
77 // LLVMRemoveModule exists in LLVM's C bindings,
78 // but it requires pointless parameters
79 extern "C" LLVMBool
LLVMExecutionEngineRemoveModule(
80 LLVMExecutionEngineRef eeref
, LLVMModuleRef mref
)
82 ExecutionEngine
*ee
= unwrap(eeref
);
83 Module
*m
= unwrap(mref
);
85 return ee
->removeModule(m
);
88 extern "C" LLVMExecutionEngineRef
LLVMBuildExecutionEngine(LLVMModuleRef mod
)
90 // These are necessary for code generation to work properly.
91 InitializeNativeTarget();
92 InitializeNativeTargetAsmPrinter();
93 InitializeNativeTargetAsmParser();
96 // On Windows, MCJIT must generate ELF objects
97 std::string target
= getProcessTriple();
99 target
= Triple::normalize(target
);
100 unwrap(mod
)->setTargetTriple(target
);
103 std::string error_str
;
104 TargetOptions options
;
106 RustJITMemoryManager
*mm
= new RustJITMemoryManager
;
108 ExecutionEngine
*ee
=
109 #if LLVM_VERSION_MINOR >= 6
110 EngineBuilder(std::unique_ptr
<Module
>(unwrap(mod
)))
111 .setMCJITMemoryManager(std::unique_ptr
<RustJITMemoryManager
>(mm
))
113 EngineBuilder(unwrap(mod
))
114 .setMCJITMemoryManager(mm
)
116 .setEngineKind(EngineKind::JIT
)
117 .setErrorStr(&error_str
)
118 .setTargetOptions(options
)
122 LLVMRustSetLastError(error_str
.c_str());
127 extern "C" void LLVMExecutionEngineFinalizeObject(LLVMExecutionEngineRef eeref
)
129 ExecutionEngine
*ee
= unwrap(eeref
);
131 ee
->finalizeObject();