mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-14 07:00:43 +02:00
Avoid double offset relocations
FEX Relocations now live at an offset from the `CodeData.BlockBegin` of the code. Regardless of where the relocation moves to, it should always be relative to that address. This is what makes it PIC compatible. We were preemptively offsetting the relocation location to be relative to the memory base in the buffer, which is unnecessary and causes code caching to basically relocate twice to get the real location. So in JIT.cpp, stop relocating the offsets, they're already relative to `BlockBegin`, which is offset 0. Then when storing the relocation, stop relocating offsets AGAIN because it's already relative to the code being serialized. Then when loading the relocations in `CodeCache::ApplyCodeRelocations` stop relocating offsets YET ANOTHER TIME. All this is to say that relocation offsets are already PIC and relative to offset 0, so we don't need to do it three times.
This commit is contained in:
5 files changed
+15
-42
No files matched your search
@@ -363,7 +363,7 @@ bool CodeCache::SaveData(Core::InternalThreadState& Thread, int fd, const Execut
|
||||
// Dump the host code (relocated for position-independent serialization)
|
||||
std::span CodeBufferData(reinterpret_cast<std::byte*>(CodeBuffer->GetBufferBase()),
|
||||
reinterpret_cast<std::byte*>(CodeBuffer->GetBufferBase()) + CodeBuffer->AllocatedSpaceUsed());
|
||||
if (!ApplyCodeRelocations(SerializedBaseAddress, CodeBufferData, Relocations, 0, true)) {
|
||||
if (!ApplyCodeRelocations(SerializedBaseAddress, CodeBufferData, Relocations, true)) {
|
||||
LOGMAN_THROW_A_FMT(false, "Failed to apply code relocations");
|
||||
return false;
|
||||
}
|
||||
@@ -446,7 +446,7 @@ void CodeCache::Validate(const ExecutableFileSectionInfo& Section, fextl::set<ui
|
||||
NewRelocations.erase(std::remove_if(NewRelocations.begin(), NewRelocations.end(), [](const CPU::Relocation& Reloc) {
|
||||
return Reloc.Header.Type != CPU::RelocationTypes::RELOC_NAMED_SYMBOL_LITERAL && Reloc.Header.Type != CPU::RelocationTypes::RELOC_NAMED_THUNK_MOVE;
|
||||
}));
|
||||
(void)ApplyCodeRelocations(Section.FileStartVA, CodeBufferRangeRef, NewRelocations, 0, false);
|
||||
(void)ApplyCodeRelocations(Section.FileStartVA, CodeBufferRangeRef, NewRelocations, false);
|
||||
|
||||
if (NewCodeBuffer->AllocatedSpaceUsed() <= CodeBufferRangeRef.size()) {
|
||||
// Reference compilation produced fewer bytes than our cache, so validation is going to fail.
|
||||
@@ -508,13 +508,12 @@ void CodeCache::Validate(const ExecutableFileSectionInfo& Section, fextl::set<ui
|
||||
}
|
||||
|
||||
bool CodeCache::ApplyCodeRelocations(uint64_t GuestEntry, std::span<std::byte> Code,
|
||||
std::span<const FEXCore::CPU::Relocation> EntryRelocations, uint32_t RelocationOffset, bool ForStorage) {
|
||||
std::span<const FEXCore::CPU::Relocation> EntryRelocations, bool ForStorage) {
|
||||
CPU::Arm64Emitter Emitter(&CTX, Code.data(), Code.size_bytes());
|
||||
for (size_t j = 0; j < EntryRelocations.size(); ++j) {
|
||||
const FEXCore::CPU::Relocation& Reloc = EntryRelocations[j];
|
||||
LOGMAN_THROW_A_FMT(Reloc.Header.Offset >= RelocationOffset, "Invalid relocation offset");
|
||||
LOGMAN_THROW_A_FMT(Reloc.Header.Offset - RelocationOffset < Code.size_bytes(), "Invalid relocation offset");
|
||||
Emitter.SetCursorOffset(Reloc.Header.Offset - RelocationOffset);
|
||||
LOGMAN_THROW_A_FMT(Reloc.Header.Offset < Code.size_bytes(), "Invalid relocation offset");
|
||||
Emitter.SetCursorOffset(Reloc.Header.Offset);
|
||||
|
||||
switch (Reloc.Header.Type) {
|
||||
case FEXCore::CPU::RelocationTypes::RELOC_NAMED_SYMBOL_LITERAL: {
|
||||
@@ -873,7 +872,7 @@ void CodeCache::FinalizeCodePages(MappedCodeCacheFile& Code, std::span<std::byte
|
||||
auto StagingSpan = std::span {Staging, Size};
|
||||
for (size_t i = StartPage; i < EndPage; ++i) {
|
||||
auto PageRelocations = SpanPageRelocations(Code, i);
|
||||
(void)ApplyCodeRelocations(Code.GuestBase, StagingSpan, PageRelocations, static_cast<uint32_t>(StartOffset), false);
|
||||
(void)ApplyCodeRelocations(Code.GuestBase, StagingSpan, PageRelocations, false);
|
||||
Code.LoadedPages[i] = true;
|
||||
}
|
||||
|
||||
@@ -896,7 +895,7 @@ void CodeCache::FinalizeCodePages(MappedCodeCacheFile& Code, std::span<std::byte
|
||||
#endif
|
||||
for (size_t i = StartPage; i < EndPage; ++i) {
|
||||
auto PageRelocations = SpanPageRelocations(Code, i);
|
||||
(void)ApplyCodeRelocations(Code.GuestBase, Code.CodeBuffer, PageRelocations, 0, false);
|
||||
(void)ApplyCodeRelocations(Code.GuestBase, Code.CodeBuffer, PageRelocations, false);
|
||||
Code.LoadedPages[i] = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in new issue
Block a user