Skip to content

Commit

Permalink
Don't apply IMAGE_REL_BASED_REL32 when address doesn't belong to curr…
Browse files Browse the repository at this point in the history
…ent section (#66855)

* Don't attempt to apply IMAGE_REL_BASED_REL32 when address doesn't belong to current block in src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp

* Update "Exit Codes" section in the superpmi help command output
  • Loading branch information
echesakov authored Mar 27, 2022
1 parent ef4773c commit 4019e83
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 30 deletions.
57 changes: 27 additions & 30 deletions src/coreclr/tools/superpmi/superpmi-shared/compileresult.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -884,13 +884,14 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o
continue;

// Now do all-platform relocations.

switch (tmp.fRelocType)
if (tmp.fRelocType == IMAGE_REL_BASED_REL32)
{
case IMAGE_REL_BASED_REL32:
DWORDLONG fixupLocation = tmp.location + tmp.slotNum;

size_t address = section_begin + (size_t)fixupLocation - (size_t)originalAddr;
if ((section_begin <= address) && (address < section_end)) // A reloc for our section?
{
DWORDLONG target = tmp.target + tmp.addlDelta;
DWORDLONG fixupLocation = tmp.location + tmp.slotNum;
DWORDLONG baseAddr = fixupLocation + sizeof(INT32);
INT64 delta = (INT64)(target - baseAddr);

Expand All @@ -899,13 +900,12 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o
if (delta != (INT64)(int)delta)
{
// This isn't going to fit in a signed 32-bit address. Use something that will fit,
// since we assume that original compilation fit fine. This is only an issue for
// 32-bit offsets on 64-bit targets.
// since we assume that original compilation fit fine.
// This is only an issue for 32-bit offsets on 64-bit targets.
target = (DWORDLONG)originalAddr + (DWORDLONG)blocksize1;
INT64 newdelta = (INT64)(target - baseAddr);

LogDebug(" REL32 overflow. Mapping target to %016llX. Mapping delta: %016llX => %016llX", target,
delta, newdelta);
LogDebug(" REL32 overflow. Mapping target to %016llX. Mapping delta: %016llX => %016llX", target, delta, newdelta);

delta = newdelta;
}
Expand All @@ -916,32 +916,29 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o
LogError("REL32 relocation overflows field! delta=0x%016llX", delta);
}

// Write 32-bits into location
size_t address = section_begin + (size_t)fixupLocation - (size_t)originalAddr;
if ((section_begin <= address) && (address < section_end)) // A reloc for our section?
if (targetArch == SPMI_TARGET_ARCHITECTURE_AMD64)
{
if (targetArch == SPMI_TARGET_ARCHITECTURE_AMD64)
{
// During an actual compile, recordRelocation() will be called before the compile
// is actually finished, and it will write the relative offset into the fixupLocation.
// Then, emitEndCodeGen() will patch forward jumps by subtracting any adjustment due
// to overestimation of instruction sizes. Because we're applying the relocs after the
// compile has finished, we need to reverse that: i.e. add in the (negative) adjustment
// that's now in the fixupLocation.
INT32 adjustment = *(INT32*)address;
delta += adjustment;
}

LogDebug(" fixupLoc-%016llX (@%p) : %08X => %08X", fixupLocation, address, *(DWORD*)address,
delta);
*(DWORD*)address = (DWORD)delta;
// During an actual compile, recordRelocation() will be called before the compile
// is actually finished, and it will write the relative offset into the fixupLocation.
// Then, emitEndCodeGen() will patch forward jumps by subtracting any adjustment due
// to overestimation of instruction sizes. Because we're applying the relocs after the
// compile has finished, we need to reverse that: i.e. add in the (negative) adjustment
// that's now in the fixupLocation.
INT32 adjustment = *(INT32*)address;
delta += adjustment;
}

// Write 32-bits into location
LogDebug(" fixupLoc-%016llX (@%p) : %08X => %08X", fixupLocation, address, *(DWORD*)address, delta);
*(DWORD*)address = (DWORD)delta;
}
break;

default:
LogError("Unknown reloc type %u", tmp.fRelocType);
break;
wasRelocHandled = true;
}

if (!wasRelocHandled)
{
LogError("Unknown reloc type %u", tmp.fRelocType);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/tools/superpmi/superpmi/commandline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ void CommandLine::DumpHelp(const char* program)
printf("-2 : JIT failed to initialize\n");
printf("1 : there were compilation failures\n");
printf("2 : there were assembly diffs\n");
printf("3 : there were missing values in method context\n");
printf("\n");
printf("Examples:\n");
printf(" %s " MAKEDLLNAME_A("clrjit") " test.mch\n", program);
Expand Down

0 comments on commit 4019e83

Please sign in to comment.