forked from OSchip/llvm-project
[ORC][ORC_RT][COFF] Support dynamic VC runtime.
Supports dynamic VC runtime. It implements atexits handling which is required to load msvcrt.lib successfully. (the object file containing atexit symbol somehow resolves to static vc runtim symbols) It also default to dynamic vc runtime which tends to be more robust. Reviewed By: lhames Differential Revision: https://reviews.llvm.org/D132525
This commit is contained in:
parent
bc24e6ab7c
commit
73c4033987
|
@ -13,6 +13,7 @@ set(ORC_COMMON_SOURCES
|
|||
set(ALL_ORC_SOURCES
|
||||
${ORC_COMMON_SOURCES}
|
||||
coff_platform.cpp
|
||||
coff_platform.per_jd.cpp
|
||||
elfnix_platform.cpp
|
||||
macho_ehframe_registration.cpp
|
||||
macho_platform.cpp
|
||||
|
@ -128,7 +129,12 @@ else() # not Apple
|
|||
set(ORC_SOURCES
|
||||
${ORC_COMMON_SOURCES}
|
||||
coff_platform.cpp
|
||||
coff_platform.per_jd.cpp
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
set(ORC_CFLAGS "${ORC_CFLAGS} /MD")
|
||||
endif()
|
||||
else()
|
||||
set(ORC_BUILD_TYPE STATIC)
|
||||
|
||||
|
|
|
@ -81,6 +81,7 @@ private:
|
|||
size_t LinkedAgainstRefCount = 0;
|
||||
size_t DlRefCount = 0;
|
||||
std::vector<JITDylibState *> Deps;
|
||||
std::vector<void (*)(void)> AtExits;
|
||||
XtorSection CInitSection; // XIA~XIZ
|
||||
XtorSection CXXInitSection; // XCA~XCZ
|
||||
XtorSection CPreTermSection; // XPA~XPZ
|
||||
|
@ -94,6 +95,7 @@ private:
|
|||
public:
|
||||
static void initialize();
|
||||
static COFFPlatformRuntimeState &get();
|
||||
static bool isInitialized() { return CPS; }
|
||||
static void destroy();
|
||||
|
||||
COFFPlatformRuntimeState() = default;
|
||||
|
@ -113,6 +115,8 @@ public:
|
|||
Error registerJITDylib(std::string Name, void *Header);
|
||||
Error deregisterJITDylib(void *Header);
|
||||
|
||||
Error registerAtExit(ExecutorAddr HeaderAddr, void (*AtExit)(void));
|
||||
|
||||
Error registerObjectSections(
|
||||
ExecutorAddr HeaderAddr,
|
||||
std::vector<std::pair<std::string_view, ExecutorAddrRange>> Secs,
|
||||
|
@ -410,7 +414,10 @@ Error COFFPlatformRuntimeState::dlcloseDeinitialize(JITDylibState &JDS) {
|
|||
JDS.Name.c_str());
|
||||
});
|
||||
|
||||
// FIXME: call atexits.
|
||||
// Run atexits
|
||||
for (auto AtExit : JDS.AtExits)
|
||||
AtExit();
|
||||
JDS.AtExits.clear();
|
||||
|
||||
// Run static terminators.
|
||||
JDS.CPreTermSection.RunAllNewAndFlush();
|
||||
|
@ -454,8 +461,7 @@ Error COFFPlatformRuntimeState::registerObjectSections(
|
|||
auto I = JDStates.find(HeaderAddr.toPtr<void *>());
|
||||
if (I == JDStates.end()) {
|
||||
std::ostringstream ErrStream;
|
||||
ErrStream << "Attempted to register unrecognized header "
|
||||
<< HeaderAddr.getValue();
|
||||
ErrStream << "Unrecognized header " << HeaderAddr.getValue();
|
||||
return make_error<StringError>(ErrStream.str());
|
||||
}
|
||||
auto &JDState = I->second;
|
||||
|
@ -499,7 +505,7 @@ Error COFFPlatformRuntimeState::deregisterObjectSections(
|
|||
auto I = JDStates.find(HeaderAddr.toPtr<void *>());
|
||||
if (I == JDStates.end()) {
|
||||
std::ostringstream ErrStream;
|
||||
ErrStream << "Attempted to register unrecognized header "
|
||||
ErrStream << "Attempted to deregister unrecognized header "
|
||||
<< HeaderAddr.getValue();
|
||||
return make_error<StringError>(ErrStream.str());
|
||||
}
|
||||
|
@ -549,6 +555,19 @@ Error COFFPlatformRuntimeState::deregisterBlockRange(ExecutorAddr HeaderAddr,
|
|||
return Error::success();
|
||||
}
|
||||
|
||||
Error COFFPlatformRuntimeState::registerAtExit(ExecutorAddr HeaderAddr,
|
||||
void (*AtExit)(void)) {
|
||||
std::lock_guard<std::recursive_mutex> Lock(JDStatesMutex);
|
||||
auto I = JDStates.find(HeaderAddr.toPtr<void *>());
|
||||
if (I == JDStates.end()) {
|
||||
std::ostringstream ErrStream;
|
||||
ErrStream << "Unrecognized header " << HeaderAddr.getValue();
|
||||
return make_error<StringError>(ErrStream.str());
|
||||
}
|
||||
I->second.AtExits.push_back(AtExit);
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
void COFFPlatformRuntimeState::initialize() {
|
||||
assert(!CPS && "COFFPlatformRuntimeState should be null");
|
||||
CPS = new COFFPlatformRuntimeState();
|
||||
|
@ -691,6 +710,32 @@ ORC_RT_INTERFACE void __stdcall __orc_rt_coff_cxx_throw_exception(
|
|||
_countof(parameters), parameters);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// COFF atexits
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
typedef int (*OnExitFunction)(void);
|
||||
typedef void (*AtExitFunction)(void);
|
||||
|
||||
ORC_RT_INTERFACE OnExitFunction __orc_rt_coff_onexit(void *Header,
|
||||
OnExitFunction Func) {
|
||||
if (auto Err = COFFPlatformRuntimeState::get().registerAtExit(
|
||||
ExecutorAddr::fromPtr(Header), (void (*)(void))Func)) {
|
||||
consumeError(std::move(Err));
|
||||
return nullptr;
|
||||
}
|
||||
return Func;
|
||||
}
|
||||
|
||||
ORC_RT_INTERFACE int __orc_rt_coff_atexit(void *Header, AtExitFunction Func) {
|
||||
if (auto Err = COFFPlatformRuntimeState::get().registerAtExit(
|
||||
ExecutorAddr::fromPtr(Header), (void (*)(void))Func)) {
|
||||
consumeError(std::move(Err));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// COFF Run Program
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
//===- coff_platform.per_jd.cpp -------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains code that will be loaded per each JITDylib.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "compiler.h"
|
||||
|
||||
ORC_RT_INTERFACE void __orc_rt_coff_per_jd_marker() {}
|
||||
|
||||
typedef int (*OnExitFunction)(void);
|
||||
typedef void (*AtExitFunction)(void);
|
||||
|
||||
extern "C" void *__ImageBase;
|
||||
ORC_RT_INTERFACE OnExitFunction __orc_rt_coff_onexit(void *Header,
|
||||
OnExitFunction Func);
|
||||
ORC_RT_INTERFACE int __orc_rt_coff_atexit(void *Header, AtExitFunction Func);
|
||||
|
||||
ORC_RT_INTERFACE OnExitFunction
|
||||
__orc_rt_coff_onexit_per_jd(OnExitFunction Func) {
|
||||
return __orc_rt_coff_onexit(&__ImageBase, Func);
|
||||
}
|
||||
|
||||
ORC_RT_INTERFACE int __orc_rt_coff_atexit_per_jd(AtExitFunction Func) {
|
||||
return __orc_rt_coff_atexit(&__ImageBase, Func);
|
||||
}
|
|
@ -1,9 +1,13 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void Dtor() { printf("destructor\n"); }
|
||||
|
||||
int Ctor() {
|
||||
printf("constructor\n");
|
||||
atexit(Dtor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#pragma section(".CRT$XIV", long, read)
|
||||
__declspec(allocate(".CRT$XIV")) int (*i1)(void) = Ctor;
|
||||
__declspec(allocate(".CRT$XIV")) int (*i1)(void) = Ctor;
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang -c -o %t %s
|
||||
// RUN: %clang_cl -MD -c -o %t %s
|
||||
// RUN: %llvm_jitlink %t 2>&1 | FileCheck %s
|
||||
// CHECK: Hello, world!
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clangxx -c -o %t %s
|
||||
// RUN: %clang_cl -MD -c -o %t %s
|
||||
// RUN: %llvm_jitlink %t 2>&1 | FileCheck %s
|
||||
// CHECK: Hello, world!
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang -c -o %t %s
|
||||
// RUN: %clang_cl -MD -c -o %t %s
|
||||
// RUN: %llvm_jitlink %t 2>&1 | FileCheck %s
|
||||
// CHECK: init1
|
||||
// CHECK-NEXT: init2
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clang -c -o %t %s
|
||||
// RUN: %clang_cl -MD -c -o %t %s
|
||||
// RUN: %llvm_jitlink %t 2>&1 | FileCheck %s
|
||||
// CHECK: init1
|
||||
// CHECK-NEXT: init2
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clangxx -c -o %t %s
|
||||
// RUN: %clang_cl -EHsc -MD -c -o %t %s
|
||||
// RUN: %llvm_jitlink %t
|
||||
|
||||
extern "C" __declspec(dllimport) void llvm_jitlink_setTestResultOverride(
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: %clangxx -c -o %t %s
|
||||
// RUN: %clang_cl -MD -c -o %t %s
|
||||
// RUN: %llvm_jitlink %t
|
||||
|
||||
extern "C" __declspec(dllimport) void llvm_jitlink_setTestResultOverride(
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
// RUN: %clang_cl -MD -c -o %t %s
|
||||
// RUN: %llvm_jitlink %t 2>&1 | FileCheck %s
|
||||
// CHECK: Entering main
|
||||
// CHECK-NEXT: Meow
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void meow() {
|
||||
printf("Meow\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
atexit(meow);
|
||||
printf("Entering main\n");
|
||||
return 0;
|
||||
}
|
|
@ -1,10 +1,9 @@
|
|||
// XFAIL: *
|
||||
// Test that __orc_rt_coff_jit_dlopen and __orc_rt_coff_jit_dlclose work as
|
||||
// expected for a straightforward dlopen; dlclose sequence: first the
|
||||
// constructors should be run.
|
||||
//
|
||||
// RUN: %clang -c -o %t.inits.o %p/Inputs/standalone-dylib.c
|
||||
// RUN: %clang -c -o %t.test.o %s
|
||||
// RUN: %clang_cl -MD -c -o %t.inits.o %p/Inputs/standalone-dylib.c
|
||||
// RUN: %clang_cl -MD -c -o %t.test.o %s
|
||||
// RUN: %llvm_jitlink \
|
||||
// RUN: -alias dlopen=__orc_rt_coff_jit_dlopen \
|
||||
// RUN: -alias dlclose=__orc_rt_coff_jit_dlclose \
|
||||
|
@ -12,11 +11,12 @@
|
|||
|
||||
// CHECK: entering main
|
||||
// CHECK-NEXT: constructor
|
||||
// CHECK-NEXT: destructor
|
||||
// CHECK-NEXT: leaving main
|
||||
|
||||
#include <stdio.h>
|
||||
__declspec(dllimport) void *dlopen(const char *path, int mode);
|
||||
__declspec(dllimport) int dlclose(void *handle);
|
||||
void *dlopen(const char *path, int mode);
|
||||
int dlclose(void *handle);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
printf("entering main\n");
|
||||
|
|
|
@ -37,6 +37,9 @@ config.substitutions.append(
|
|||
config.substitutions.append(
|
||||
('%clangxx ',
|
||||
build_invocation(config.cxx_mode_flags + [config.target_cflags])))
|
||||
config.substitutions.append(
|
||||
('%clang_cl ',
|
||||
build_invocation(['--driver-mode=cl'] + [config.target_cflags])))
|
||||
if config.host_os == 'Windows':
|
||||
config.substitutions.append(
|
||||
('%llvm_jitlink', (llvm_jitlink + ' -orc-runtime=' +
|
||||
|
|
|
@ -42,7 +42,8 @@ public:
|
|||
static Expected<std::unique_ptr<COFFPlatform>>
|
||||
Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
|
||||
JITDylib &PlatformJD, const char *OrcRuntimePath,
|
||||
LoadDynamicLibrary LoadDynLibrary, const char *VCRuntimePath = nullptr,
|
||||
LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime = false,
|
||||
const char *VCRuntimePath = nullptr,
|
||||
Optional<SymbolAliasMap> RuntimeAliases = None);
|
||||
|
||||
Error bootstrap(JITDylib &PlatformJD);
|
||||
|
@ -141,11 +142,10 @@ private:
|
|||
|
||||
static bool supportedTarget(const Triple &TT);
|
||||
|
||||
COFFPlatform(
|
||||
ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
|
||||
JITDylib &PlatformJD,
|
||||
std::unique_ptr<StaticLibraryDefinitionGenerator> OrcRuntimeGenerator,
|
||||
LoadDynamicLibrary LoadDynLibrary, const char *VCRuntimePath, Error &Err);
|
||||
COFFPlatform(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
|
||||
JITDylib &PlatformJD, const char *OrcRuntimePath,
|
||||
LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime,
|
||||
const char *VCRuntimePath, Error &Err);
|
||||
|
||||
// Associate COFFPlatform JIT-side runtime support functions with handlers.
|
||||
Error associateRuntimeSupportFunctions(JITDylib &PlatformJD);
|
||||
|
@ -164,6 +164,8 @@ private:
|
|||
// Build dependency graph of a JITDylib
|
||||
Expected<JITDylibDepMap> buildJDDepMap(JITDylib &JD);
|
||||
|
||||
Expected<MemoryBufferRef> getPerJDObjectFile();
|
||||
|
||||
// Implements rt_pushInitializers by making repeat async lookups for
|
||||
// initializer symbols (each lookup may spawn more initializer symbols if
|
||||
// it pulls in new materializers, e.g. from objects in a static library).
|
||||
|
@ -181,6 +183,9 @@ private:
|
|||
|
||||
LoadDynamicLibrary LoadDynLibrary;
|
||||
std::unique_ptr<COFFVCRuntimeBootstrapper> VCRuntimeBootstrap;
|
||||
std::unique_ptr<MemoryBuffer> OrcRuntimeArchiveBuffer;
|
||||
std::unique_ptr<object::Archive> OrcRuntimeArchive;
|
||||
bool StaticVCRuntime;
|
||||
|
||||
SymbolStringPtr COFFHeaderStartSymbol;
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "llvm/ExecutionEngine/Orc/COFFPlatform.h"
|
||||
#include "llvm/ExecutionEngine/Orc/DebugUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/LookupAndRecordAddrs.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ObjectFileInterface.h"
|
||||
|
||||
#include "llvm/Object/COFF.h"
|
||||
|
||||
|
@ -161,7 +162,7 @@ namespace orc {
|
|||
Expected<std::unique_ptr<COFFPlatform>>
|
||||
COFFPlatform::Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
|
||||
JITDylib &PlatformJD, const char *OrcRuntimePath,
|
||||
LoadDynamicLibrary LoadDynLibrary,
|
||||
LoadDynamicLibrary LoadDynLibrary, bool StaticVCRuntime,
|
||||
const char *VCRuntimePath,
|
||||
Optional<SymbolAliasMap> RuntimeAliases) {
|
||||
auto &EPC = ES.getExecutorProcessControl();
|
||||
|
@ -192,23 +193,44 @@ COFFPlatform::Create(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
|
|||
JITSymbolFlags::Exported}}})))
|
||||
return std::move(Err);
|
||||
|
||||
// Create a generator for the ORC runtime archive.
|
||||
auto OrcRuntimeArchiveGenerator =
|
||||
StaticLibraryDefinitionGenerator::Load(ObjLinkingLayer, OrcRuntimePath);
|
||||
if (!OrcRuntimeArchiveGenerator)
|
||||
return OrcRuntimeArchiveGenerator.takeError();
|
||||
PlatformJD.addToLinkOrder(HostFuncJD);
|
||||
|
||||
// Create the instance.
|
||||
Error Err = Error::success();
|
||||
auto P = std::unique_ptr<COFFPlatform>(new COFFPlatform(
|
||||
ES, ObjLinkingLayer, PlatformJD, std::move(*OrcRuntimeArchiveGenerator),
|
||||
std::move(LoadDynLibrary), VCRuntimePath, Err));
|
||||
ES, ObjLinkingLayer, PlatformJD, OrcRuntimePath,
|
||||
std::move(LoadDynLibrary), StaticVCRuntime, VCRuntimePath, Err));
|
||||
if (Err)
|
||||
return std::move(Err);
|
||||
return std::move(P);
|
||||
}
|
||||
|
||||
Expected<MemoryBufferRef> COFFPlatform::getPerJDObjectFile() {
|
||||
auto PerJDObj = OrcRuntimeArchive->findSym("__orc_rt_coff_per_jd_marker");
|
||||
if (!PerJDObj)
|
||||
return PerJDObj.takeError();
|
||||
|
||||
if (!*PerJDObj)
|
||||
return make_error<StringError>("Could not find per jd object file",
|
||||
inconvertibleErrorCode());
|
||||
|
||||
auto Buffer = (*PerJDObj)->getAsBinary();
|
||||
if (!Buffer)
|
||||
return Buffer.takeError();
|
||||
|
||||
return (*Buffer)->getMemoryBufferRef();
|
||||
}
|
||||
|
||||
static void addAliases(ExecutionSession &ES, SymbolAliasMap &Aliases,
|
||||
ArrayRef<std::pair<const char *, const char *>> AL) {
|
||||
for (auto &KV : AL) {
|
||||
auto AliasName = ES.intern(KV.first);
|
||||
assert(!Aliases.count(AliasName) && "Duplicate symbol name in alias map");
|
||||
Aliases[std::move(AliasName)] = {ES.intern(KV.second),
|
||||
JITSymbolFlags::Exported};
|
||||
}
|
||||
}
|
||||
|
||||
Error COFFPlatform::setupJITDylib(JITDylib &JD) {
|
||||
if (auto Err = JD.define(std::make_unique<COFFHeaderMaterializationUnit>(
|
||||
*this, COFFHeaderStartSymbol)))
|
||||
|
@ -217,15 +239,36 @@ Error COFFPlatform::setupJITDylib(JITDylib &JD) {
|
|||
if (auto Err = ES.lookup({&JD}, COFFHeaderStartSymbol).takeError())
|
||||
return Err;
|
||||
|
||||
// Define the CXX aliases.
|
||||
SymbolAliasMap CXXAliases;
|
||||
addAliases(ES, CXXAliases, requiredCXXAliases());
|
||||
if (auto Err = JD.define(symbolAliases(std::move(CXXAliases))))
|
||||
return std::move(Err);
|
||||
|
||||
auto PerJDObj = getPerJDObjectFile();
|
||||
if (!PerJDObj)
|
||||
return PerJDObj.takeError();
|
||||
|
||||
auto I = getObjectFileInterface(ES, *PerJDObj);
|
||||
if (!I)
|
||||
return I.takeError();
|
||||
|
||||
if (auto Err = ObjLinkingLayer.add(
|
||||
JD, MemoryBuffer::getMemBuffer(*PerJDObj, false), std::move(*I)))
|
||||
return Err;
|
||||
|
||||
if (!Bootstrapping) {
|
||||
auto ImportedLibs = VCRuntimeBootstrap->loadStaticVCRuntime(JD);
|
||||
auto ImportedLibs = StaticVCRuntime
|
||||
? VCRuntimeBootstrap->loadStaticVCRuntime(JD)
|
||||
: VCRuntimeBootstrap->loadDynamicVCRuntime(JD);
|
||||
if (!ImportedLibs)
|
||||
return ImportedLibs.takeError();
|
||||
for (auto &Lib : *ImportedLibs)
|
||||
if (auto Err = LoadDynLibrary(JD, Lib))
|
||||
return Err;
|
||||
if (auto Err = VCRuntimeBootstrap->initializeStaticVCRuntime(JD))
|
||||
return Err;
|
||||
if (StaticVCRuntime)
|
||||
if (auto Err = VCRuntimeBootstrap->initializeStaticVCRuntime(JD))
|
||||
return Err;
|
||||
}
|
||||
|
||||
JD.addGenerator(DLLImportDefinitionGenerator::Create(ES, ObjLinkingLayer));
|
||||
|
@ -265,19 +308,8 @@ Error COFFPlatform::notifyRemoving(ResourceTracker &RT) {
|
|||
llvm_unreachable("Not supported yet");
|
||||
}
|
||||
|
||||
static void addAliases(ExecutionSession &ES, SymbolAliasMap &Aliases,
|
||||
ArrayRef<std::pair<const char *, const char *>> AL) {
|
||||
for (auto &KV : AL) {
|
||||
auto AliasName = ES.intern(KV.first);
|
||||
assert(!Aliases.count(AliasName) && "Duplicate symbol name in alias map");
|
||||
Aliases[std::move(AliasName)] = {ES.intern(KV.second),
|
||||
JITSymbolFlags::Exported};
|
||||
}
|
||||
}
|
||||
|
||||
SymbolAliasMap COFFPlatform::standardPlatformAliases(ExecutionSession &ES) {
|
||||
SymbolAliasMap Aliases;
|
||||
addAliases(ES, Aliases, requiredCXXAliases());
|
||||
addAliases(ES, Aliases, standardRuntimeUtilityAliases());
|
||||
return Aliases;
|
||||
}
|
||||
|
@ -286,7 +318,8 @@ ArrayRef<std::pair<const char *, const char *>>
|
|||
COFFPlatform::requiredCXXAliases() {
|
||||
static const std::pair<const char *, const char *> RequiredCXXAliases[] = {
|
||||
{"_CxxThrowException", "__orc_rt_coff_cxx_throw_exception"},
|
||||
};
|
||||
{"_onexit", "__orc_rt_coff_onexit_per_jd"},
|
||||
{"atexit", "__orc_rt_coff_atexit_per_jd"}};
|
||||
|
||||
return ArrayRef<std::pair<const char *, const char *>>(RequiredCXXAliases);
|
||||
}
|
||||
|
@ -315,16 +348,37 @@ bool COFFPlatform::supportedTarget(const Triple &TT) {
|
|||
}
|
||||
}
|
||||
|
||||
COFFPlatform::COFFPlatform(
|
||||
ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
|
||||
JITDylib &PlatformJD,
|
||||
std::unique_ptr<StaticLibraryDefinitionGenerator> OrcRuntimeGenerator,
|
||||
LoadDynamicLibrary LoadDynLibrary, const char *VCRuntimePath, Error &Err)
|
||||
COFFPlatform::COFFPlatform(ExecutionSession &ES,
|
||||
ObjectLinkingLayer &ObjLinkingLayer,
|
||||
JITDylib &PlatformJD, const char *OrcRuntimePath,
|
||||
LoadDynamicLibrary LoadDynLibrary,
|
||||
bool StaticVCRuntime, const char *VCRuntimePath,
|
||||
Error &Err)
|
||||
: ES(ES), ObjLinkingLayer(ObjLinkingLayer),
|
||||
LoadDynLibrary(std::move(LoadDynLibrary)),
|
||||
StaticVCRuntime(StaticVCRuntime),
|
||||
COFFHeaderStartSymbol(ES.intern("__ImageBase")) {
|
||||
ErrorAsOutParameter _(&Err);
|
||||
|
||||
// Create a generator for the ORC runtime archive.
|
||||
auto OrcRuntimeArchiveGenerator =
|
||||
StaticLibraryDefinitionGenerator::Load(ObjLinkingLayer, OrcRuntimePath);
|
||||
if (!OrcRuntimeArchiveGenerator) {
|
||||
Err = std::move(OrcRuntimeArchiveGenerator.takeError());
|
||||
return;
|
||||
}
|
||||
|
||||
auto ArchiveBuffer = MemoryBuffer::getFile(OrcRuntimePath);
|
||||
if (!ArchiveBuffer) {
|
||||
Err = createFileError(OrcRuntimePath, ArchiveBuffer.getError());
|
||||
return;
|
||||
}
|
||||
OrcRuntimeArchiveBuffer = std::move(*ArchiveBuffer);
|
||||
OrcRuntimeArchive =
|
||||
std::make_unique<object::Archive>(*OrcRuntimeArchiveBuffer, Err);
|
||||
if (Err)
|
||||
return;
|
||||
|
||||
Bootstrapping.store(true);
|
||||
ObjLinkingLayer.addPlugin(std::make_unique<COFFPlatformPlugin>(*this));
|
||||
|
||||
|
@ -337,10 +391,12 @@ COFFPlatform::COFFPlatform(
|
|||
}
|
||||
VCRuntimeBootstrap = std::move(*VCRT);
|
||||
|
||||
for (auto &Lib : OrcRuntimeGenerator->getImportedDynamicLibraries())
|
||||
for (auto &Lib : (*OrcRuntimeArchiveGenerator)->getImportedDynamicLibraries())
|
||||
DylibsToPreload.insert(Lib);
|
||||
|
||||
auto ImportedLibs = VCRuntimeBootstrap->loadStaticVCRuntime(PlatformJD);
|
||||
auto ImportedLibs =
|
||||
StaticVCRuntime ? VCRuntimeBootstrap->loadStaticVCRuntime(PlatformJD)
|
||||
: VCRuntimeBootstrap->loadDynamicVCRuntime(PlatformJD);
|
||||
if (!ImportedLibs) {
|
||||
Err = ImportedLibs.takeError();
|
||||
return;
|
||||
|
@ -349,14 +405,14 @@ COFFPlatform::COFFPlatform(
|
|||
for (auto &Lib : *ImportedLibs)
|
||||
DylibsToPreload.insert(Lib);
|
||||
|
||||
PlatformJD.addGenerator(std::move(*OrcRuntimeArchiveGenerator));
|
||||
|
||||
// PlatformJD hasn't been set up by the platform yet (since we're creating
|
||||
// the platform now), so set it up.
|
||||
if (auto E2 = setupJITDylib(PlatformJD)) {
|
||||
Err = std::move(E2);
|
||||
return;
|
||||
}
|
||||
|
||||
PlatformJD.addGenerator(std::move(OrcRuntimeGenerator));
|
||||
}
|
||||
|
||||
Error COFFPlatform::bootstrap(JITDylib &PlatformJD) {
|
||||
|
@ -364,8 +420,9 @@ Error COFFPlatform::bootstrap(JITDylib &PlatformJD) {
|
|||
if (auto Err = LoadDynLibrary(PlatformJD, Lib))
|
||||
return Err;
|
||||
|
||||
if (auto Err = VCRuntimeBootstrap->initializeStaticVCRuntime(PlatformJD))
|
||||
return Err;
|
||||
if (StaticVCRuntime)
|
||||
if (auto Err = VCRuntimeBootstrap->initializeStaticVCRuntime(PlatformJD))
|
||||
return Err;
|
||||
|
||||
// Associate wrapper function tags with JIT-side function implementations.
|
||||
if (auto Err = associateRuntimeSupportFunctions(PlatformJD)) {
|
||||
|
@ -636,13 +693,6 @@ Error COFFPlatform::bootstrapCOFFRuntime(JITDylib &PlatformJD) {
|
|||
}))
|
||||
return Err;
|
||||
|
||||
// Run static initializers collected in bootstrap stage.
|
||||
for (auto KV : JDBootstrapStates) {
|
||||
auto &JDBState = KV.second;
|
||||
if (auto Err = runBootstrapInitializers(JDBState))
|
||||
return Err;
|
||||
}
|
||||
|
||||
// Call bootstrap functions
|
||||
if (auto Err = ES.callSPSWrapper<void()>(orc_rt_coff_platform_bootstrap))
|
||||
return Err;
|
||||
|
@ -664,6 +714,13 @@ Error COFFPlatform::bootstrapCOFFRuntime(JITDylib &PlatformJD) {
|
|||
return Err;
|
||||
}
|
||||
|
||||
// Run static initializers collected in bootstrap stage.
|
||||
for (auto KV : JDBootstrapStates) {
|
||||
auto &JDBState = KV.second;
|
||||
if (auto Err = runBootstrapInitializers(JDBState))
|
||||
return Err;
|
||||
}
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
|
|
|
@ -1197,10 +1197,12 @@ Session::Session(std::unique_ptr<ExecutorProcessControl> EPC, Error &Err)
|
|||
ExitOnErr(loadProcessSymbols(*this));
|
||||
else {
|
||||
// This symbol is used in testcases.
|
||||
ExitOnErr(MainJD->define(absoluteSymbols(
|
||||
auto &TestResultJD = ES.createBareJITDylib("<TestResultJD>");
|
||||
ExitOnErr(TestResultJD.define(absoluteSymbols(
|
||||
{{ES.intern("llvm_jitlink_setTestResultOverride"),
|
||||
{pointerToJITTargetAddress(llvm_jitlink_setTestResultOverride),
|
||||
JITSymbolFlags::Exported}}})));
|
||||
MainJD->addToLinkOrder(TestResultJD);
|
||||
}
|
||||
|
||||
ExitOnErr(loadDylibs(*this));
|
||||
|
|
Loading…
Reference in New Issue