2014-11-24 12:55:14 -06:00
|
|
|
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
|
|
|
#include "rustllvm.h"
|
|
|
|
|
|
|
|
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
using namespace llvm::sys;
|
|
|
|
using namespace llvm::object;
|
|
|
|
|
2015-06-11 01:12:07 -05:00
|
|
|
// libmorestack is not used on other platforms
|
|
|
|
#if defined(__linux__) || defined(__APPLE__)
|
2015-05-19 18:00:59 -05:00
|
|
|
extern "C" void __morestack(void);
|
|
|
|
|
|
|
|
static void* morestack_addr() {
|
|
|
|
return reinterpret_cast<void*>(__morestack);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-11-24 12:55:14 -06:00
|
|
|
class RustJITMemoryManager : public SectionMemoryManager
|
|
|
|
{
|
|
|
|
typedef SectionMemoryManager Base;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
2015-05-19 18:00:59 -05:00
|
|
|
RustJITMemoryManager() {}
|
2014-11-24 12:55:14 -06:00
|
|
|
|
|
|
|
uint64_t getSymbolAddress(const std::string &Name) override
|
|
|
|
{
|
2015-06-11 01:12:07 -05:00
|
|
|
#if defined(__linux__) || defined(__APPLE__)
|
2014-11-24 12:55:14 -06:00
|
|
|
if (Name == "__morestack" || Name == "___morestack")
|
2015-05-19 18:00:59 -05:00
|
|
|
return reinterpret_cast<uint64_t>(__morestack);
|
|
|
|
if (Name == "__morestack_addr" || Name == "___morestack_addr")
|
|
|
|
return reinterpret_cast<uint64_t>(morestack_addr);
|
|
|
|
#endif
|
2014-11-24 12:55:14 -06:00
|
|
|
|
|
|
|
return Base::getSymbolAddress(Name);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(RustJITMemoryManager, LLVMRustJITMemoryManagerRef)
|
|
|
|
|
|
|
|
extern "C" LLVMBool LLVMRustLoadDynamicLibrary(const char *path)
|
|
|
|
{
|
|
|
|
std::string err;
|
|
|
|
DynamicLibrary lib = DynamicLibrary::getPermanentLibrary(path, &err);
|
|
|
|
|
|
|
|
if (!lib.isValid())
|
|
|
|
LLVMRustSetLastError(err.c_str());
|
|
|
|
|
|
|
|
return lib.isValid();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Calls LLVMAddModule;
|
|
|
|
// exists for consistency with LLVMExecutionEngineRemoveModule
|
|
|
|
extern "C" void LLVMExecutionEngineAddModule(
|
|
|
|
LLVMExecutionEngineRef eeref, LLVMModuleRef mref)
|
|
|
|
{
|
2015-05-19 18:00:59 -05:00
|
|
|
#ifdef _WIN32
|
|
|
|
// On Windows, MCJIT must generate ELF objects
|
|
|
|
std::string target = getProcessTriple();
|
|
|
|
target += "-elf";
|
|
|
|
target = Triple::normalize(target);
|
|
|
|
unwrap(mref)->setTargetTriple(target);
|
|
|
|
#endif
|
2014-11-24 12:55:14 -06:00
|
|
|
LLVMAddModule(eeref, mref);
|
|
|
|
}
|
|
|
|
|
|
|
|
// LLVMRemoveModule exists in LLVM's C bindings,
|
|
|
|
// but it requires pointless parameters
|
|
|
|
extern "C" LLVMBool LLVMExecutionEngineRemoveModule(
|
|
|
|
LLVMExecutionEngineRef eeref, LLVMModuleRef mref)
|
|
|
|
{
|
|
|
|
ExecutionEngine *ee = unwrap(eeref);
|
|
|
|
Module *m = unwrap(mref);
|
|
|
|
|
|
|
|
return ee->removeModule(m);
|
|
|
|
}
|
|
|
|
|
2015-05-19 18:00:59 -05:00
|
|
|
extern "C" LLVMExecutionEngineRef LLVMBuildExecutionEngine(LLVMModuleRef mod)
|
2014-11-24 12:55:14 -06:00
|
|
|
{
|
|
|
|
// These are necessary for code generation to work properly.
|
|
|
|
InitializeNativeTarget();
|
|
|
|
InitializeNativeTargetAsmPrinter();
|
|
|
|
InitializeNativeTargetAsmParser();
|
|
|
|
|
2015-05-19 18:00:59 -05:00
|
|
|
#ifdef _WIN32
|
|
|
|
// On Windows, MCJIT must generate ELF objects
|
|
|
|
std::string target = getProcessTriple();
|
|
|
|
target += "-elf";
|
|
|
|
target = Triple::normalize(target);
|
|
|
|
unwrap(mod)->setTargetTriple(target);
|
|
|
|
#endif
|
|
|
|
|
2014-11-24 12:55:14 -06:00
|
|
|
std::string error_str;
|
|
|
|
TargetOptions options;
|
|
|
|
|
2015-05-19 18:00:59 -05:00
|
|
|
RustJITMemoryManager *mm = new RustJITMemoryManager;
|
|
|
|
|
2015-01-30 12:25:07 -06:00
|
|
|
ExecutionEngine *ee =
|
2015-04-20 12:19:02 -05:00
|
|
|
#if LLVM_VERSION_MINOR >= 6
|
2015-01-30 12:25:07 -06:00
|
|
|
EngineBuilder(std::unique_ptr<Module>(unwrap(mod)))
|
2015-05-19 18:00:59 -05:00
|
|
|
.setMCJITMemoryManager(std::unique_ptr<RustJITMemoryManager>(mm))
|
2015-04-20 12:19:02 -05:00
|
|
|
#else
|
|
|
|
EngineBuilder(unwrap(mod))
|
2015-05-19 18:00:59 -05:00
|
|
|
.setMCJITMemoryManager(mm)
|
2015-01-30 12:25:07 -06:00
|
|
|
#endif
|
|
|
|
.setEngineKind(EngineKind::JIT)
|
|
|
|
.setErrorStr(&error_str)
|
|
|
|
.setTargetOptions(options)
|
|
|
|
.create();
|
2014-11-24 12:55:14 -06:00
|
|
|
|
|
|
|
if (!ee)
|
|
|
|
LLVMRustSetLastError(error_str.c_str());
|
|
|
|
|
|
|
|
return wrap(ee);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void LLVMExecutionEngineFinalizeObject(LLVMExecutionEngineRef eeref)
|
|
|
|
{
|
|
|
|
ExecutionEngine *ee = unwrap(eeref);
|
|
|
|
|
|
|
|
ee->finalizeObject();
|
|
|
|
}
|