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:
parent
1e680749e8
commit
6ba74a0e2f
@ -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.
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user