1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 12:43:36 +01:00

[JITLink] Add a -slab-address option to llvm-jitlink.

This option can be used to for JITLink to link as-if the target memory slab were
allocated at a specific start address. This can be used to both verify that
cross-address space linking is working correctly, and to ensure that certain
address-sensitive optimizations (e.g. GOT and stub elimination) either do or do
not fire, depending on the requirements of the test case.

This argument is only valid for testing in conjunction with -noexec -slab-alloc,
and will produce an error if used without those arguments.
This commit is contained in:
Lang Hames 2020-03-03 14:18:12 -08:00
parent 1e680749e8
commit 6ba74a0e2f
2 changed files with 37 additions and 10 deletions

View File

@ -1,8 +1,12 @@
# RUN: rm -rf %t && mkdir -p %t
# RUN: llvm-mc -triple=x86_64-apple-macosx10.9 -filetype=obj -o %t/macho_reloc.o %s
# RUN: llvm-jitlink -noexec -define-abs external_data=0xffffffffdeadbeef \
# RUN: -define-abs external_func=0xffffffffcafef00d \
# RUN: -define-abs lowaddr_symbol=0x1000 -check=%s %t/macho_reloc.o
# RUN: llvm-jitlink -noexec -slab-allocate 100Kb -slab-address 0xfff00000 \
# RUN: -define-abs external_data=0x1 -define-abs external_func=0x2 \
# RUN: -check=%s %t/macho_reloc.o
#
# Test standard MachO relocations. Simulates slab allocation in the top 1Mb of
# memory and places external symbols in the lowest page to prevent GOT and stub
# elimination.
.section __TEXT,__text,regular,pure_instructions
@ -172,11 +176,11 @@ named_func_addr_quad:
# Check X86_64_RELOC_UNSIGNED / long / extern handling by putting the address of
# an external function (defined to reside in the low 4Gb) into a long symbol.
#
# jitlink-check: *{4}named_lowaddr_symbol_long = lowaddr_symbol
.globl named_lowaddr_symbol_long
# jitlink-check: *{4}named_func_addr_long = external_func
.globl named_func_addr_long
.p2align 2
named_lowaddr_symbol_long:
.long lowaddr_symbol
named_func_addr_long:
.long external_func
# Check X86_64_RELOC_UNSIGNED / quad / non-extern handling by putting the
# address of a local anonymous function into a quad symbol.

View File

@ -112,6 +112,11 @@ static cl::opt<std::string> SlabAllocateSizeString(
"Kb)"),
cl::init(""));
static cl::opt<uint64_t> SlabAddress(
"slab-address",
cl::desc("Set slab target address (requires -slab-allocate and -noexec)"),
cl::init(~0ULL));
static cl::opt<bool> ShowRelocatedSectionContents(
"show-relocated-section-contents",
cl::desc("show section contents after fixups have been applied"),
@ -250,7 +255,8 @@ public:
// Local class for allocation.
class IPMMAlloc : public Allocation {
public:
IPMMAlloc(AllocationMap SegBlocks) : SegBlocks(std::move(SegBlocks)) {}
IPMMAlloc(JITLinkSlabAllocator &Parent, AllocationMap SegBlocks)
: Parent(Parent), SegBlocks(std::move(SegBlocks)) {}
MutableArrayRef<char> getWorkingMemory(ProtectionFlags Seg) override {
assert(SegBlocks.count(Seg) && "No allocation for segment");
return {static_cast<char *>(SegBlocks[Seg].base()),
@ -258,7 +264,8 @@ public:
}
JITTargetAddress getTargetMemory(ProtectionFlags Seg) override {
assert(SegBlocks.count(Seg) && "No allocation for segment");
return reinterpret_cast<JITTargetAddress>(SegBlocks[Seg].base());
return pointerToJITTargetAddress(SegBlocks[Seg].base()) +
Parent.TargetDelta;
}
void finalizeAsync(FinalizeContinuation OnFinalize) override {
OnFinalize(applyProtections());
@ -284,6 +291,7 @@ public:
return Error::success();
}
JITLinkSlabAllocator &Parent;
AllocationMap SegBlocks;
};
@ -329,7 +337,7 @@ public:
Blocks[KV.first] = std::move(SegMem);
}
return std::unique_ptr<InProcessMemoryManager::Allocation>(
new IPMMAlloc(std::move(Blocks)));
new IPMMAlloc(*this, std::move(Blocks)));
}
private:
@ -359,10 +367,17 @@ private:
Err = errorCodeToError(EC);
return;
}
// Calculate the target address delta to link as-if slab were at
// SlabAddress.
if (SlabAddress != ~0ULL)
TargetDelta =
SlabAddress - pointerToJITTargetAddress(SlabRemaining.base());
}
sys::MemoryBlock SlabRemaining;
uint64_t PageSize = 0;
int64_t TargetDelta = 0;
};
Expected<uint64_t> getSlabAllocSize(StringRef SizeString) {
@ -566,6 +581,14 @@ Error sanitizeArguments(const Session &S) {
if (NoExec && !InputArgv.empty())
outs() << "Warning: --args passed to -noexec run will be ignored.\n";
// If -slab-address is passed, require -slab-allocate and -noexec
if (SlabAddress != ~0ULL) {
if (SlabAllocateSizeString == "" || !NoExec)
return make_error<StringError>(
"-slab-address requires -slab-allocate and -noexec",
inconvertibleErrorCode());
}
return Error::success();
}