From 27023e7b328aacb415c7920d690696ce89865a26 Mon Sep 17 00:00:00 2001 From: Georgiy Krylov Date: Sun, 21 Jun 2020 23:46:03 -0300 Subject: [PATCH] OMR AOT: Relocation Record files addition The added files are: OMRRelocationRecord.hpp, OMRRelocationRecord.cpp. These files contain RelocationRecord, RelocationRecordGroup, RelocationRecordBinaryTemplate classes. The RelocationRecordGroup is an iterator for application of relocations. The RelocationRecordBinaryTemplate is the class that has RelocationRecord information. Those classes realize core relocations storage functiona- lity in OpenJ9, but are language independent and thus are worth inclu- ding into OMR. Compared to OpenJ9, the RelocationRecord classes became extensible. Another proposed change is in the creation of relocation records: the implementation of TR::RelocationRecord::create function is proposed to be done as a function in corresponding relocationRecord class. The RelocationRecordBinaryTemplate, has undergone changes to improve readability and portability: the setSize() and setType(), as well as x64 architecture specific setExtra() and their corresponding accessor methods are now RelocationTarget API calls, as advised in Issue #3031 Signed-off-by: Georgiy Krylov --- compiler/runtime/OMRRelocationRecord.cpp | 386 +++++++++++++++++++++++ compiler/runtime/OMRRelocationRecord.hpp | 216 +++++++++++++ compiler/runtime/TRRelocationRecord.hpp | 61 ++++ 3 files changed, 663 insertions(+) create mode 100644 compiler/runtime/OMRRelocationRecord.cpp create mode 100644 compiler/runtime/OMRRelocationRecord.hpp create mode 100644 compiler/runtime/TRRelocationRecord.hpp diff --git a/compiler/runtime/OMRRelocationRecord.cpp b/compiler/runtime/OMRRelocationRecord.cpp new file mode 100644 index 00000000000..19f1792a2b8 --- /dev/null +++ b/compiler/runtime/OMRRelocationRecord.cpp @@ -0,0 +1,386 @@ +/******************************************************************************* + * Copyright (c) 2021, 2021 IBM Corp. and others + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] http://openjdk.java.net/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception + *******************************************************************************/ + +#include +#include "omrcfg.h" +#include "codegen/CodeGenerator.hpp" +#include "env/FrontEnd.hpp" +#include "codegen/Relocation.hpp" +#include "compile/ResolvedMethod.hpp" +#include "control/Options.hpp" +#include "control/Options_inlines.hpp" +#include "infra/Assert.hpp" +#include "env/jittypes.h" +#include "env/VMAccessCriticalSection.hpp" +#include "infra/SimpleRegex.hpp" +#include "runtime/CodeCache.hpp" +#include "runtime/CodeCacheManager.hpp" +#include "runtime/TRRelocationRecord.hpp" +#include "runtime/TRRelocationRuntime.hpp" +#include "runtime/TRRelocationTarget.hpp" + +#if defined(__IBMCPP__) && !defined(AIXPPC) && !defined(LINUXPPC) +#define ASM_CALL __cdecl +#else +#define ASM_CALL +#endif +#if defined(TR_HOST_S390) || defined(TR_HOST_X86) // gotten from RuntimeAssumptions.cpp, should common these up +extern "C" void _patchVirtualGuard(uint8_t *locationAddr, uint8_t *destinationAddr, int32_t smpFlag); +#else +extern "C" void ASM_CALL _patchVirtualGuard(uint8_t*, uint8_t*, uint32_t); +#endif + +uint8_t +OMR::RelocationRecordBinaryTemplate::type(TR::RelocationTarget *reloTarget) + { + return reloTarget->loadUnsigned8b(&_type); + } + +void +OMR::RelocationRecordBinaryTemplate::setSize(TR::RelocationTarget *reloTarget,uint16_t size) + { + return reloTarget->storeUnsigned16b(size, reinterpret_cast(&_size)); + } +void +OMR::RelocationRecordBinaryTemplate::setType(TR::RelocationTarget *reloTarget, uint8_t type) + { + return reloTarget->storeUnsigned8b(type,&_type); + } + +void +OMR::RelocationRecordBinaryTemplate::setFlags(TR::RelocationTarget *reloTarget,uint8_t flags) + { + return reloTarget->storeUnsigned8b(flags,&_flags); + } + + +TR::RelocationRecord * +OMR::RelocationRecord::self() + { + return static_cast(this); + } + +void +OMR::RelocationRecordGroup::setSize(TR::RelocationTarget *reloTarget,uintptr_t size) + { + reloTarget->storePointer((uint8_t *)size, (uint8_t *) _dataBuffer); + } + +uintptr_t +OMR::RelocationRecordGroup::size(TR::RelocationTarget *reloTarget) + { + return (uintptr_t)reloTarget->loadPointer((uint8_t *) _dataBuffer); + } + +TR::RelocationRecordBinaryTemplate * +OMR::RelocationRecordGroup::firstRecord(TR::RelocationTarget *reloTarget) + { + // first word of the group is a pointer size field for the entire group + return (TR::RelocationRecordBinaryTemplate *) (((uintptr_t *)_dataBuffer)+1); + } + +TR::RelocationRecordBinaryTemplate * +OMR::RelocationRecordGroup::pastLastRecord(TR::RelocationTarget *reloTarget) + { + return (TR::RelocationRecordBinaryTemplate *) ((uint8_t *)_dataBuffer + size(reloTarget)); + } + +int32_t +OMR::RelocationRecordGroup::applyRelocations(TR::RelocationRuntime *reloRuntime, + TR::RelocationTarget *reloTarget, + uint8_t *reloOrigin) + { + TR::RelocationRecordBinaryTemplate *recordPointer = firstRecord(reloTarget); + TR::RelocationRecordBinaryTemplate *endOfRecords = pastLastRecord(reloTarget); + + while (recordPointer < endOfRecords) + { + TR::RelocationRecord storage; + // Create a specific type of relocation record based on the information + // in the binary record pointed to by `recordPointer` + TR::RelocationRecord *reloRecord = TR::RelocationRecord::create(&storage, reloRuntime, reloTarget, recordPointer); + int32_t rc = handleRelocation(reloRuntime, reloTarget, reloRecord, reloOrigin); + if (rc != 0) + return rc; + + recordPointer = reloRecord->nextBinaryRecord(reloTarget); + } + + return 0; + } + +int32_t +OMR::RelocationRecordGroup::handleRelocation(TR::RelocationRuntime *reloRuntime, + TR::RelocationTarget *reloTarget, + TR::RelocationRecord *reloRecord, + uint8_t *reloOrigin) + { + reloRecord->preparePrivateData(reloRuntime, reloTarget); + return reloRecord->applyRelocationAtAllOffsets(reloRuntime, reloTarget, reloOrigin); + } + +#define FLAGS_RELOCATION_WIDE_OFFSETS 0x80 +#define FLAGS_RELOCATION_EIP_OFFSET 0x40 +#define FLAGS_RELOCATION_TYPE_MASK (TR::ExternalRelocationTargetKindMask) +#define FLAGS_RELOCATION_FLAG_MASK ((uint8_t) (FLAGS_RELOCATION_WIDE_OFFSETS | FLAGS_RELOCATION_EIP_OFFSET)) + +OMR::RelocationRecordAction +OMR::RelocationRecord::action(OMR::RelocationRuntime *reloRuntime) + { + return RelocationRecordAction::apply; + } + + +TR::RelocationRecord * +OMR::RelocationRecord::create(TR::RelocationRecord *storage, TR::RelocationRuntime *reloRuntime, TR::RelocationTarget *reloTarget, TR::RelocationRecordBinaryTemplate *record) + { + OMR::RelocationRecord *reloRecord = NULL; + // based on the type of the relocation record, create an object of a particular variety of OMR::RelocationRecord object + uint8_t reloType = record->type(reloTarget); + switch (reloType) + { + // an example switch-case; the implementations is runtime-specific + case TR_ExternalRelocationTargetKind::TR_MethodCallAddress: + TR_UNIMPLEMENTED(); + break; + default: + // TODO: error condition + TR_UNIMPLEMENTED(); + exit(0); + } + + return static_cast(reloRecord); + } + +void +OMR::RelocationRecord::clean(TR::RelocationTarget *reloTarget) + { + self()->setSize(reloTarget, 0); + self()->setType(reloTarget,(OMR::RelocationRecordType)_record->_type); + self()->setReloFlags(reloTarget, _record->_flags); + } + +int32_t +OMR::RelocationRecord::bytesInHeader(TR::RelocationTarget *reloTarget) + { + return OMR::RelocationRecord::getSizeOfAOTRelocationHeader(self()->type(reloTarget)); + } + +TR::RelocationRecordBinaryTemplate * +OMR::RelocationRecordBinaryTemplate::self() + { + return static_cast(this); + } + +TR::RelocationRecordBinaryTemplate * +OMR::RelocationRecord::nextBinaryRecord(TR::RelocationTarget *reloTarget) + { + return (TR::RelocationRecordBinaryTemplate*) (((uint8_t*)self()->_record) + self()->size(reloTarget)); + } + +void +OMR::RelocationRecord::setSize(TR::RelocationTarget *reloTarget, uint16_t size) + { + reloTarget->storeUnsigned16b(size,(uint8_t *) &_record->_size); + } + +uint16_t +OMR::RelocationRecord::size(TR::RelocationTarget *reloTarget) + { + return reloTarget->loadUnsigned16b((uint8_t *) &_record->_size); + } + + +void +OMR::RelocationRecord::setType(TR::RelocationTarget *reloTarget, OMR::RelocationRecordType type) + { + reloTarget->storeUnsigned8b(type, (uint8_t *) &_record->_type); + } + +OMR::RelocationRecordType +OMR::RelocationRecord::type(TR::RelocationTarget *reloTarget) + { + return (OMR::RelocationRecordType)_record->type(reloTarget); + } + + +void +OMR::RelocationRecord::setWideOffsets(TR::RelocationTarget *reloTarget) + { + self()->setFlag(reloTarget, FLAGS_RELOCATION_WIDE_OFFSETS); + } + +bool +OMR::RelocationRecord::wideOffsets(TR::RelocationTarget *reloTarget) + { + return (self()->flags(reloTarget) & FLAGS_RELOCATION_WIDE_OFFSETS) != 0; + } + +void +OMR::RelocationRecord::setPcRelative(TR::RelocationTarget *reloTarget) + { + self()->setFlag(reloTarget, FLAGS_RELOCATION_EIP_OFFSET); + } + +bool +OMR::RelocationRecord::pcRelative(TR::RelocationTarget *reloTarget) + { + return (self()->flags(reloTarget) & FLAGS_RELOCATION_EIP_OFFSET) != 0; + } + +void +OMR::RelocationRecord::setFlag(TR::RelocationTarget *reloTarget, uint8_t flag) + { + uint8_t flags = reloTarget->loadUnsigned8b((uint8_t *) &_record->_flags) | (flag & FLAGS_RELOCATION_FLAG_MASK); + reloTarget->storeUnsigned8b(flags, (uint8_t *) &_record->_flags); + } + +uint8_t +OMR::RelocationRecord::flags(TR::RelocationTarget *reloTarget) + { + return reloTarget->loadUnsigned8b((uint8_t *) &_record->_flags) & FLAGS_RELOCATION_FLAG_MASK; + } + +void +OMR::RelocationRecord::setReloFlags(TR::RelocationTarget *reloTarget, uint8_t reloFlags) + { + TR_ASSERT((reloFlags & ~FLAGS_RELOCATION_FLAG_MASK) == 0, "reloFlags bits overlap cross-platform flags bits\n"); + uint8_t crossPlatFlags = self()->flags(reloTarget); + uint8_t flags = crossPlatFlags | (reloFlags & ~FLAGS_RELOCATION_FLAG_MASK); + reloTarget->storeUnsigned8b(flags, (uint8_t *) &_record->_flags); + } + +uint8_t +OMR::RelocationRecord::reloFlags(TR::RelocationTarget *reloTarget) + { + return reloTarget->loadUnsigned8b((uint8_t *) &_record->_flags) & ~FLAGS_RELOCATION_FLAG_MASK; + } + +void +OMR::RelocationRecord::preparePrivateData(TR::RelocationRuntime *reloRuntime, TR::RelocationTarget *reloTarget) + { + // This function can be used to query the value that should be inserted in the compiled code from the runtime + // just once, instead of repeating the querying process every time the value is required. + // The retrived value can be cached in _privateData field + TR_UNIMPLEMENTED(); + } + +#undef FLAGS_RELOCATION_WIDE_OFFSETS +#undef FLAGS_RELOCATION_EIP_OFFSET +#undef FLAGS_RELOCATION_ORDERED_PAIR +#undef FLAGS_RELOCATION_TYPE_MASK +#undef FLAGS_RELOCATION_FLAG_MASK + + +bool +OMR::RelocationRecord::ignore(TR::RelocationRuntime *reloRuntime) + { + return false; + } + +int32_t +OMR::RelocationRecord::applyRelocationAtAllOffsets(TR::RelocationRuntime *reloRuntime, TR::RelocationTarget *reloTarget, uint8_t *reloOrigin) + { + if (self()->ignore(reloRuntime)) + { + return 0; + } + + if (reloTarget->isOrderedPairRelocation(self(), reloTarget)) + { + if (self()->wideOffsets(reloTarget)) + { + int32_t *offsetsBase = (int32_t *) (((uint8_t*)_record) + self()->bytesInHeader(reloTarget)); + int32_t *endOfOffsets = (int32_t *) self()->nextBinaryRecord(reloTarget); + for (int32_t *offsetPtr = offsetsBase;offsetPtr < endOfOffsets; offsetPtr+=2) + { + int32_t offsetHigh = *offsetPtr; + int32_t offsetLow = *(offsetPtr+1); + uint8_t *reloLocationHigh = reloOrigin + offsetHigh + 2; // Add 2 to skip the first 16 bits of instruction + uint8_t *reloLocationLow = reloOrigin + offsetLow + 2; // Add 2 to skip the first 16 bits of instruction + int32_t rc = self()->applyRelocation(reloRuntime, reloTarget, reloLocationHigh, reloLocationLow); + if (rc != 0) + { + return rc; + } + } + } + else + { + int16_t *offsetsBase = (int16_t *) (((uint8_t*)_record) + self()->bytesInHeader(reloTarget)); + int16_t *endOfOffsets = (int16_t *) self()->nextBinaryRecord(reloTarget); + for (int16_t *offsetPtr = offsetsBase;offsetPtr < endOfOffsets; offsetPtr+=2) + { + int16_t offsetHigh = *offsetPtr; + int16_t offsetLow = *(offsetPtr+1); + uint8_t *reloLocationHigh = reloOrigin + offsetHigh + 2; // Add 2 to skip the first 16 bits of instruction + uint8_t *reloLocationLow = reloOrigin + offsetLow + 2; // Add 2 to skip the first 16 bits of instruction + int32_t rc = self()->applyRelocation(reloRuntime, reloTarget, reloLocationHigh, reloLocationLow); + if (rc != 0) + { + return rc; + } + } + } + } + else + { + if (self()->wideOffsets(reloTarget)) + { + int32_t *offsetsBase = (int32_t *) (((uint8_t*)_record) + self()->bytesInHeader(reloTarget)); + int32_t *endOfOffsets = (int32_t *) self()->nextBinaryRecord(reloTarget); + for (int32_t *offsetPtr = offsetsBase;offsetPtr < endOfOffsets; offsetPtr++) + { + int32_t offset = *offsetPtr; + uint8_t *reloLocation = reloOrigin + offset; + int32_t rc = self()->applyRelocation(reloRuntime, reloTarget, reloLocation); + if (rc != 0) + { + return rc; + } + } + } + else + { + int16_t *offsetsBase = (int16_t *) (((uint8_t*)_record) + self()->bytesInHeader(reloTarget)); + int16_t *endOfOffsets = (int16_t *) self()->nextBinaryRecord(reloTarget); + for (int16_t *offsetPtr = offsetsBase;offsetPtr < endOfOffsets; offsetPtr++) + { + int16_t offset = *offsetPtr; + uint8_t *reloLocation = reloOrigin + offset; + int32_t rc = self()->applyRelocation(reloRuntime, reloTarget, reloLocation); + if (rc != 0) + { + return rc; + } + } + } + } + return 0; + } + + +uint32_t OMR::RelocationRecord::_relocationRecordHeaderSizeTable[TR_NumExternalRelocationKinds] = + { + //This will be removed with further work on openJ9. + (uint32_t) -1, + }; diff --git a/compiler/runtime/OMRRelocationRecord.hpp b/compiler/runtime/OMRRelocationRecord.hpp new file mode 100644 index 00000000000..221754c97d2 --- /dev/null +++ b/compiler/runtime/OMRRelocationRecord.hpp @@ -0,0 +1,216 @@ +/******************************************************************************* + * Copyright (c) 2021, 2021 IBM Corp. and others + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at https://www.eclipse.org/legal/epl-2.0/ + * or the Apache License, Version 2.0 which accompanies this distribution and + * is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following + * Secondary Licenses when the conditions for such availability set + * forth in the Eclipse Public License, v. 2.0 are satisfied: GNU + * General Public License, version 2 with the GNU Classpath + * Exception [1] and GNU General Public License, version 2 with the + * OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] http://openjdk.java.net/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception + *******************************************************************************/ + +#ifndef OMR_RELOCATION_RECORD_INCL +#define OMR_RELOCATION_RECORD_INCL +/* + * The following #define(s) and typedef(s) must appear before any #includes in this file + */ +#ifndef OMR_RELOCATION_RECORD_CONNECTOR +#define OMR_RELOCATION_RECORD_CONNECTOR +namespace OMR { class RelocationRecord; } +namespace OMR { typedef OMR::RelocationRecord RelocationRecordConnector; } +#else + #error OMR::RelocationRecord expected to be a primary connector, but another connector is already defined +#endif + + +#ifndef OMR_RELOCATION_RECORD_BINARY_TEMPLATE_CONNECTOR +#define OMR_RELOCATION_RECORD_BINARY_TEMPLATE_CONNECTOR +namespace OMR { class RelocationRecordBinaryTemplate; } +namespace OMR { typedef OMR::RelocationRecordBinaryTemplate RelocationRecordBinaryTemplateConnector; } +#else + #error OMR::RelocationRecordBinaryTemplate expected to be a primary connector, but another connector is already defined +#endif + + +#include +#include "compile/Compilation.hpp" +#include "env/jittypes.h" +#include "infra/Link.hpp" +#include "infra/Flags.hpp" +#include "runtime/TRRelocationRuntime.hpp" +#include "runtime/Runtime.hpp" + +namespace TR { +class RelocationRuntime; +class RelocationTarget; +class RelocationRecord; +class RelocationRecordBinaryTemplate; +struct RelocationRecordMethodCallPrivateData + { + uintptr_t callTargetOffset; + }; + +union RelocationRecordPrivateData + { + int storage; + }; + +} + +namespace OMR { typedef TR_ExternalRelocationTargetKind RelocationRecordType;} +namespace TR { typedef TR_ExternalRelocationTargetKind RelocationRecordType;} +namespace TR { class RelocationRecordBinaryTemplate;} +extern char* AOTcgDiagOn; + +// TR::RelocationRecord is the base class for all relocation records. It is used for all queries on relocation +// records as well as holding all the "wrapper" parts. These classes are an interface to the *BinaryTemplate +// classes which are simply structs that can be used to directly access the binary representation of the relocation +// records stored in the cache (*BinaryTemplate structs are defined near the end of this file after the +// RelocationRecord* classes. The RelocationRecord* classes permit virtual function calls access to the +// *BinaryTemplate classes and must access the binary structs via the _record field in the TR::RelocationRecord +// class. Most consumers should directly manipulate the TR::RelocationRecord* classes since they offer +// the most flexibility. +// No class that derives from TR::RelocationRecord should define any state: all state variables should be declared +// in TR::RelocationRecord or the constructor/decode() mechanisms will not work properly +// Relocation record classes for "real" relocation record types +// should be defined on the level of consuming project + +namespace OMR +{ + +class OMR_EXTENSIBLE RelocationRecordBinaryTemplate + { +public: + RelocationRecordBinaryTemplate(){}; + void setType(TR::RelocationTarget*, uint8_t kind); + void setSize(TR::RelocationTarget*, uint16_t size); + void setFlags(TR::RelocationTarget*, uint8_t flags); + uint8_t type(TR::RelocationTarget *reloTarget); + uint16_t _size; + uint8_t _type; + uint8_t _flags; +protected: + TR::RelocationRecordBinaryTemplate* self(); + }; + +enum RelocationRecordAction + { + ignore, + apply, + failCompilation + }; + +class OMR_EXTENSIBLE RelocationRecord + { +public: + RelocationRecord() {} + RelocationRecord(TR::RelocationRuntime *reloRuntime, TR::RelocationRecordBinaryTemplate *record) + { + _reloRuntime= reloRuntime; + _record =record; + } + + void * operator new (size_t s, RelocationRecord *p) { return p; } + char *name() { return "RelocationRecord"; } + + bool isValidationRecord() { return false; } + + + static TR::RelocationRecord *create(TR::RelocationRecord *storage, TR::RelocationRuntime *reloRuntime, TR::RelocationTarget *reloTarget, TR::RelocationRecordBinaryTemplate *recordPointer); + + void clean(TR::RelocationTarget *reloTarget); + int32_t bytesInHeader(TR::RelocationTarget *reloTarget); + /** + * @brief This function is used to cache the values that are retrieved at run-time, during the code loading + * Sometimes, computing the values required for updating the code is non-trivial and might add extra cost. + * To avoid repeated computation, this function is used + * + * @param reloRuntime - a reference to relocation runtime to query the runtime for the required values + * @param reloTarget - a reference to the cross-platform API to store/load values at various machine dependent granularity + */ + void preparePrivateData(TR::RelocationRuntime *reloRuntime, TR::RelocationTarget *reloTarget); + + int32_t applyRelocationAtAllOffsets(TR::RelocationRuntime *reloRuntime, TR::RelocationTarget *reloTarget, uint8_t *relocationOrigin); + + int32_t applyRelocation(TR::RelocationRuntime *reloRuntime, TR::RelocationTarget *reloTarget, uint8_t *reloLocation) {return -1;} + int32_t applyRelocation(TR::RelocationRuntime *reloRuntime, TR::RelocationTarget *reloTarget, uint8_t *reloLocationHigh, uint8_t *reloLocationLow) {return -1;} + + TR::RelocationRecordBinaryTemplate *nextBinaryRecord(TR::RelocationTarget *reloTarget); + TR::RelocationRecordBinaryTemplate *binaryRecord(); + + void setSize(TR::RelocationTarget *reloTarget, uint16_t size); + uint16_t size(TR::RelocationTarget *reloTarget); + + void setType(TR::RelocationTarget *reloTarget, TR::RelocationRecordType type); + RelocationRecordType type(TR::RelocationTarget *reloTarget); + + void setWideOffsets(TR::RelocationTarget *reloTarget); + bool wideOffsets(TR::RelocationTarget *reloTarget); + + void setPcRelative(TR::RelocationTarget *reloTarget); + bool pcRelative(TR::RelocationTarget *reloTarget); + + void setFlag(TR::RelocationTarget *reloTarget, uint8_t flag); + uint8_t flags(TR::RelocationTarget *reloTarget); + + void setReloFlags(TR::RelocationTarget *reloTarget, uint8_t reloFlags); + uint8_t reloFlags(TR::RelocationTarget *reloTarget); + + TR::RelocationRuntime *_reloRuntime; + bool ignore(TR::RelocationRuntime *reloRuntime); + RelocationRecordAction action(RelocationRuntime *reloRuntime); + static uint32_t getSizeOfAOTRelocationHeader(TR_ExternalRelocationTargetKind k) + { + return _relocationRecordHeaderSizeTable[k]; + } + +protected: + TR::RelocationRecord* self(); + + TR::RelocationRecordPrivateData *privateData() + { + return &_privateData; + } + + TR::RelocationRecordBinaryTemplate *_record; + + TR::RelocationRecordPrivateData _privateData; + + static uint32_t _relocationRecordHeaderSizeTable[TR_NumExternalRelocationKinds]; + }; + + +class RelocationRecordGroup + { +public: + RelocationRecordGroup(TR::RelocationRecordBinaryTemplate *groupData) : _dataBuffer(groupData) {}; + + void setSize(TR::RelocationTarget *reloTarget, uintptr_t size); + uintptr_t size(TR::RelocationTarget *reloTarget); + + TR::RelocationRecordBinaryTemplate *firstRecord(TR::RelocationTarget *reloTarget); + TR::RelocationRecordBinaryTemplate *pastLastRecord(TR::RelocationTarget *reloTarget); + + int32_t applyRelocations(TR::RelocationRuntime *reloRuntime, + TR::RelocationTarget *reloTarget, + uint8_t *reloOrigin); +private: + int32_t handleRelocation(TR::RelocationRuntime *reloRuntime, TR::RelocationTarget *reloTarget, TR::RelocationRecord *reloRecord, uint8_t *reloOrigin); + + TR::RelocationRecordBinaryTemplate *_dataBuffer; + }; + +} //namespace OMR + +#endif // OMR_RELOCATION_RECORD_INCL diff --git a/compiler/runtime/TRRelocationRecord.hpp b/compiler/runtime/TRRelocationRecord.hpp new file mode 100644 index 00000000000..d1c0e0aea14 --- /dev/null +++ b/compiler/runtime/TRRelocationRecord.hpp @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2021, 2021 IBM Corp. and others + * + * This program and the accompanying materials are made available under + * the terms of the Eclipse Public License 2.0 which accompanies this + * distribution and is available at http://eclipse.org/legal/epl-2.0 + * or the Apache License, Version 2.0 which accompanies this distribution + * and is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * This Source Code may also be made available under the following Secondary + * Licenses when the conditions for such availability set forth in the + * Eclipse Public License, v. 2.0 are satisfied: GNU General Public License, + * version 2 with the GNU Classpath Exception [1] and GNU General Public + * License, version 2 with the OpenJDK Assembly Exception [2]. + * + * [1] https://www.gnu.org/software/classpath/license.html + * [2] http://openjdk.java.net/legal/assembly-exception.html + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception + *******************************************************************************/ + +#ifndef TR_RELOCATION_RECORD_INCL +#define TR_RELOCATION_RECORD_INCL + +#include "runtime/OMRRelocationRecord.hpp" + +namespace TR +{ + +class OMR_EXTENSIBLE RelocationRecord: public OMR::RelocationRecordConnector + { +public: + RelocationRecord(TR::RelocationRuntime *reloRuntime, TR::RelocationRecordBinaryTemplate *record) + : OMR::RelocationRecordConnector(reloRuntime,record) + { } + + RelocationRecord(): OMR::RelocationRecordConnector() + { } + + + }; + +class OMR_EXTENSIBLE RelocationRecordBinaryTemplate: public OMR::RelocationRecordBinaryTemplateConnector + { +public: + RelocationRecordBinaryTemplate() + : OMR::RelocationRecordBinaryTemplateConnector() + { }; + }; + +class RelocationRecordGroup: public OMR::RelocationRecordGroup + { +public: + RelocationRecordGroup(TR::RelocationRecordBinaryTemplate *groupData) + : OMR::RelocationRecordGroup(groupData) + { }; + }; + +} // namespace TR + +#endif /* TR_RELOCATION_RECORD_INCL */