[llvm-jitlink] Teach InProcessDeltaMapper to honor -slab-page-size option.

The -slab-page-size option is used to set a simulated page size in -no-exec
tests. In order for this to work we need to use read/write permissions only
on all simulated pages in order to ensure that no simulated page is made
read-only by a permission change to the underlying real page.

The aim of this patch is to make it safe to enable ExecutionEngine regression
tests on arm64. Those tests will be enabled in a follow-up patch.
This commit is contained in:
Lang Hames 2022-10-03 19:28:56 -07:00
parent 3019f488f4
commit 7ec6dde83a
1 changed files with 31 additions and 14 deletions

View File

@ -469,10 +469,19 @@ public:
DeltaAddr(0) {} DeltaAddr(0) {}
static Expected<std::unique_ptr<InProcessDeltaMapper>> Create() { static Expected<std::unique_ptr<InProcessDeltaMapper>> Create() {
auto PageSize = sys::Process::getPageSize(); size_t PageSize = SlabPageSize;
if (!PageSize) if (!PageSize) {
return PageSize.takeError(); if (auto PageSizeOrErr = sys::Process::getPageSize())
return std::make_unique<InProcessDeltaMapper>(*PageSize, SlabAddress); PageSize = *PageSizeOrErr;
else
return PageSizeOrErr.takeError();
}
if (PageSize == 0)
return make_error<StringError>("Page size is zero",
inconvertibleErrorCode());
return std::make_unique<InProcessDeltaMapper>(PageSize, SlabAddress);
} }
void reserve(size_t NumBytes, OnReservedFunction OnReserved) override { void reserve(size_t NumBytes, OnReservedFunction OnReserved) override {
@ -497,8 +506,12 @@ public:
} }
void initialize(AllocInfo &AI, OnInitializedFunction OnInitialized) override { void initialize(AllocInfo &AI, OnInitializedFunction OnInitialized) override {
// Slide mapping based on delta and make all segments read-writable.
auto FixedAI = AI; auto FixedAI = AI;
FixedAI.MappingBase -= DeltaAddr; FixedAI.MappingBase -= DeltaAddr;
for (auto &Seg : FixedAI.Segments)
Seg.AG = AllocGroup(MemProt::Read | MemProt::Write,
Seg.AG.getMemDeallocPolicy());
InProcessMemoryMapper::initialize( InProcessMemoryMapper::initialize(
FixedAI, [this, OnInitialized = std::move(OnInitialized)]( FixedAI, [this, OnInitialized = std::move(OnInitialized)](
Expected<ExecutorAddr> Result) mutable { Expected<ExecutorAddr> Result) mutable {
@ -557,23 +570,27 @@ Expected<uint64_t> getSlabAllocSize(StringRef SizeString) {
} }
static std::unique_ptr<JITLinkMemoryManager> createInProcessMemoryManager() { static std::unique_ptr<JITLinkMemoryManager> createInProcessMemoryManager() {
if (!SlabAllocateSizeString.empty()) { uint64_t SlabSize;
auto SlabSize = ExitOnErr(getSlabAllocSize(SlabAllocateSizeString)); #ifdef _WIN32
SlabSize = 1024 * 1024;
#else
SlabSize = 1024 * 1024 * 1024;
#endif
if (!SlabAllocateSizeString.empty())
SlabSize = ExitOnErr(getSlabAllocSize(SlabAllocateSizeString));
// If this is a -no-exec case and we're tweaking the slab address or size then
// use the delta mapper.
if (NoExec && (SlabAddress || SlabPageSize))
return ExitOnErr( return ExitOnErr(
MapperJITLinkMemoryManager::CreateWithMapper<InProcessDeltaMapper>( MapperJITLinkMemoryManager::CreateWithMapper<InProcessDeltaMapper>(
SlabSize)); SlabSize));
}
#ifdef _WIN32 // Otherwise use the standard in-process mapper.
return ExitOnErr( return ExitOnErr(
MapperJITLinkMemoryManager::CreateWithMapper<InProcessMemoryMapper>( MapperJITLinkMemoryManager::CreateWithMapper<InProcessMemoryMapper>(
1024 * 1024)); SlabSize));
#else
return ExitOnErr(
MapperJITLinkMemoryManager::CreateWithMapper<InProcessMemoryMapper>(
1024 * 1024 * 1024));
#endif
} }
Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>> Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>