From 76bfd96638e543aa15a1be4f021b9dafa6a1dc22 Mon Sep 17 00:00:00 2001 From: Georgiy Krylov Date: Thu, 16 Jun 2022 16:35: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 | 358 +++++++++++++++++++++++ compiler/runtime/OMRRelocationRecord.hpp | 234 +++++++++++++++ compiler/runtime/TRRelocationRecord.hpp | 66 +++++ 3 files changed, 658 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..08b87e3e458 --- /dev/null +++ b/compiler/runtime/OMRRelocationRecord.cpp @@ -0,0 +1,358 @@ +/******************************************************************************* + * Copyright (c) 2000, 2022 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) + { + TR::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(); + /** Example implementation would be to implement relocations here / overload this file following extensible classes technology. + * For instance, if TR_MethodCallAddress is used in OtherProject, the line in OtherProjectRelocationRecord.cpp + * (which includes TRRelocationRecord.hpp or, when adjusted - RelocationRecord.hpp) would be: + * reloRecord =reinterpret_cast( new (storage) OtherProject::RelocationRecordMethodCallAddress(reloRuntime,record)); + * The current assumption is that if a relocation is common enough, it could be added to OMR directly + */ + break; + default: + // TODO: error condition + TR_UNIMPLEMENTED(); + exit(0); + } + + return 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) + { + /** + * Private data is used for caching computed data from what's stored in the record's binary representation + * and the current runtime state, to prevent computing this value at every offset where this value should + * be applied. + * + * 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 (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..8425af02473 --- /dev/null +++ b/compiler/runtime/OMRRelocationRecord.hpp @@ -0,0 +1,234 @@ +/******************************************************************************* + * Copyright (c) 2000, 2022 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; +/** + * @brief RelocationRecords can specify a struct for caching all the related values + * for accellerating relocation application process through avoiding multiple computations + * of the same value when applying the relocation at different offsets. + */ +struct RelocationRecordMethodCallPrivateData + { + uintptr_t callTargetOffset; + }; +/** + * @brief This union is supposed to be a union of all possible PrivateData structs + * allowing RelocationRecords allocating enough space for all kinds of RelocationRecordPrivateData + */ +union RelocationRecordPrivateData + { + struct RelocationRecordMethodCallPrivateData; + }; + +} + +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; } + + /** + * @brief Using a pre-specified location (storage), create an instance of relocationRecord, + * as it is described by its serialized version RelocationRecordBinaryTemplate. The operation + * varies between architecture, hence RelocationTarget is made available + * + * @param storage - location where to create relocation record + * @param reloRuntime - class for manipulations on relocations + * @param reloTarget - class for performing operations on relocations on binary level + * @param recordPointer - pointer to a binary template - sequence of bytes describing the relocation + * @return TR::RelocationRecord* - pointer cast to the generic relocationRecord. + */ + 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..7260aec38c1 --- /dev/null +++ b/compiler/runtime/TRRelocationRecord.hpp @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2000, 2022 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 +{ +/** NOTE: This class is supposed to be inherited by RelocationRecord in consuming projects + * In the proper OMR extensible classes technology way, the file name should be RelocationRecord.hpp + * However, calling it this name shadows includes in production projects (e.g., in OpenJ9), + * so renaming this file happen when both projects are ready. + * See also: https://github.com/eclipse/omr/issues/5469 + */ +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 */