MachOPlatform used to make an EPC-call (registerObjectSections) to register the eh-frame and thread-data sections for each linked object with the ORC runtime. Now that JITLinkMemoryManager supports allocation actions we can use these instead of an EPC call. This saves us one EPC-call per object linked, and manages registration/deregistration in the executor, rather than the controller process. In the future we may use this to allow JIT'd code in the executor to outlive the controller object while still being able to be cleanly destroyed. Since the code for allocation actions must be available when the actions are run, and since the eh-frame registration code lives in the ORC runtime itself, this change required that MachO eh-frame support be split out of macho_platform.cpp and into its own macho_ehframe_registration.cpp file that has no other dependencies. During bootstrap we start by forcing emission of macho_ehframe_registration.cpp so that eh-frame registration is guaranteed to be available for the rest of the bootstrap process. Then we load the rest of the MachO-platform runtime support, erroring out if there is any attempt to use TLVs. Once the bootstrap process is complete all subsequent code can use all features.
104 lines
3.5 KiB
C++
104 lines
3.5 KiB
C++
//===- macho_platform.h -----------------------------------------*- C++ -*-===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// ORC Runtime support for Darwin dynamic loading features.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef ORC_RT_MACHO_PLATFORM_H
|
|
#define ORC_RT_MACHO_PLATFORM_H
|
|
|
|
#include "common.h"
|
|
#include "executor_address.h"
|
|
|
|
// Atexit functions.
|
|
ORC_RT_INTERFACE int __orc_rt_macho_cxa_atexit(void (*func)(void *), void *arg,
|
|
void *dso_handle);
|
|
ORC_RT_INTERFACE void __orc_rt_macho_cxa_finalize(void *dso_handle);
|
|
|
|
// dlfcn functions.
|
|
ORC_RT_INTERFACE const char *__orc_rt_macho_jit_dlerror();
|
|
ORC_RT_INTERFACE void *__orc_rt_macho_jit_dlopen(const char *path, int mode);
|
|
ORC_RT_INTERFACE int __orc_rt_macho_jit_dlclose(void *dso_handle);
|
|
ORC_RT_INTERFACE void *__orc_rt_macho_jit_dlsym(void *dso_handle,
|
|
const char *symbol);
|
|
|
|
namespace __orc_rt {
|
|
namespace macho {
|
|
|
|
struct MachOJITDylibInitializers {
|
|
using SectionList = std::vector<ExecutorAddrRange>;
|
|
|
|
MachOJITDylibInitializers() = default;
|
|
MachOJITDylibInitializers(std::string Name, ExecutorAddr MachOHeaderAddress)
|
|
: Name(std::move(Name)),
|
|
MachOHeaderAddress(std::move(MachOHeaderAddress)) {}
|
|
|
|
std::string Name;
|
|
ExecutorAddr MachOHeaderAddress;
|
|
ExecutorAddr ObjCImageInfoAddress;
|
|
|
|
std::unordered_map<std::string, SectionList> InitSections;
|
|
};
|
|
|
|
class MachOJITDylibDeinitializers {};
|
|
|
|
using MachOJITDylibInitializerSequence = std::vector<MachOJITDylibInitializers>;
|
|
|
|
using MachOJITDylibDeinitializerSequence =
|
|
std::vector<MachOJITDylibDeinitializers>;
|
|
|
|
enum dlopen_mode : int {
|
|
ORC_RT_RTLD_LAZY = 0x1,
|
|
ORC_RT_RTLD_NOW = 0x2,
|
|
ORC_RT_RTLD_LOCAL = 0x4,
|
|
ORC_RT_RTLD_GLOBAL = 0x8
|
|
};
|
|
|
|
} // end namespace macho
|
|
|
|
using SPSNamedExecutorAddrRangeSequenceMap =
|
|
SPSSequence<SPSTuple<SPSString, SPSExecutorAddrRangeSequence>>;
|
|
|
|
using SPSMachOJITDylibInitializers =
|
|
SPSTuple<SPSString, SPSExecutorAddr, SPSExecutorAddr,
|
|
SPSNamedExecutorAddrRangeSequenceMap>;
|
|
|
|
using SPSMachOJITDylibInitializerSequence =
|
|
SPSSequence<SPSMachOJITDylibInitializers>;
|
|
|
|
/// Serialization traits for MachOJITDylibInitializers.
|
|
template <>
|
|
class SPSSerializationTraits<SPSMachOJITDylibInitializers,
|
|
macho::MachOJITDylibInitializers> {
|
|
public:
|
|
static size_t size(const macho::MachOJITDylibInitializers &MOJDIs) {
|
|
return SPSMachOJITDylibInitializers::AsArgList::size(
|
|
MOJDIs.Name, MOJDIs.MachOHeaderAddress, MOJDIs.ObjCImageInfoAddress,
|
|
MOJDIs.InitSections);
|
|
}
|
|
|
|
static bool serialize(SPSOutputBuffer &OB,
|
|
const macho::MachOJITDylibInitializers &MOJDIs) {
|
|
return SPSMachOJITDylibInitializers::AsArgList::serialize(
|
|
OB, MOJDIs.Name, MOJDIs.MachOHeaderAddress, MOJDIs.ObjCImageInfoAddress,
|
|
MOJDIs.InitSections);
|
|
}
|
|
|
|
static bool deserialize(SPSInputBuffer &IB,
|
|
macho::MachOJITDylibInitializers &MOJDIs) {
|
|
return SPSMachOJITDylibInitializers::AsArgList::deserialize(
|
|
IB, MOJDIs.Name, MOJDIs.MachOHeaderAddress, MOJDIs.ObjCImageInfoAddress,
|
|
MOJDIs.InitSections);
|
|
}
|
|
};
|
|
|
|
} // end namespace __orc_rt
|
|
|
|
#endif // ORC_RT_MACHO_PLATFORM_H
|