-
Notifications
You must be signed in to change notification settings - Fork 775
Description
When generating a TR_RelativeMethodAddress relo reocrd, the eipRelative flag is set.
| rmaRecord->setEipRelative(reloTarget); |
When relocating, the TR_RelocationRecordMethodAddress API class is used:
openj9/runtime/compiler/runtime/RelocationRecord.cpp
Lines 655 to 658 in e1d5e6b
| case TR_RelativeMethodAddress: | |
| case TR_AbsoluteMethodAddress: | |
| case TR_AbsoluteMethodAddressOrderedPair: | |
| reloRecord = new (storage) TR_RelocationRecordMethodAddress(reloRuntime, record); |
Because the eipRelative flag is set, loadCallTarget is called:
openj9/runtime/compiler/runtime/RelocationRecord.cpp
Lines 1873 to 1879 in e1d5e6b
| TR_RelocationRecordMethodAddress::applyRelocation(TR_RelocationRuntime *reloRuntime, TR_RelocationTarget *reloTarget, uint8_t *reloLocation) | |
| { | |
| bool eipRel = eipRelative(reloTarget); | |
| uint8_t *oldAddress; | |
| if (eipRel) | |
| oldAddress = reloTarget->loadCallTarget(reloLocation); |
openj9/runtime/compiler/runtime/RelocationTarget.cpp
Lines 70 to 74 in e1d5e6b
| uint8_t * | |
| TR_RelocationTarget::loadCallTarget(uint8_t *reloLocation) | |
| { | |
| return loadPointer(reloLocation); | |
| } |
which in turn calls loadPointer:
| virtual uint8_t *loadPointer(uint8_t *address) { return *(uint8_t**) address; } |
So, in 64 bit, it loads a 64bit value out of the instruction in the code. It relocates it via the call to currentMethodAddress:
openj9/runtime/compiler/runtime/RelocationRecord.cpp
Lines 1866 to 1870 in e1d5e6b
| TR_RelocationRecordMethodAddress::currentMethodAddress(TR_RelocationRuntime *reloRuntime, uint8_t *oldMethodAddress) | |
| { | |
| TR_AOTMethodHeader *methodHdr = reloRuntime->aotMethodHeaderEntry(); | |
| return oldMethodAddress - methodHdr->compileMethodCodeStartPC + (uintptr_t) reloRuntime->newMethodCodeStart(); | |
| } |
and then updates the code via:
openj9/runtime/compiler/runtime/RelocationRecord.cpp
Lines 1887 to 1888 in e1d5e6b
| if (eipRel) | |
| reloTarget->storeCallTarget((uintptr_t)newAddress, reloLocation); |
which calls
storeCallTarget:openj9/runtime/compiler/x/runtime/X86RelocationTarget.cpp
Lines 54 to 58 in e1d5e6b
| TR_X86RelocationTarget::storeCallTarget(uintptr_t callTarget, uint8_t *reloLocation) | |
| { | |
| // reloLocation points at the start of the call offset, so just store the uint8_t * at reloLocation | |
| storeUnsigned32b((uint32_t)callTarget, reloLocation); | |
| } |
However,
storeCallTarget stores a 32-bit unsigned value.
The fact that a 32-bit value is stored is not necessarily the problem, but it's the fact that a 64 bit value was loaded, had arithmetic performed on it, and then a 32-bit value is stored back. As such, I don't think this relocation is correct.
The only place this relocation is generated is in https://github.com/eclipse/omr/blob/83e28dc0dcdcf8d9a751cc2b8567fcc8acc30e84/compiler/x/codegen/X86BinaryEncoding.cpp#L1111