mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-08 22:12:59 +08:00
Patch all implicit args relocations within every kernel
Related-To: NEO-5081 Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
0089cb698f
commit
61e5e0687d
@@ -318,7 +318,10 @@ void Linker::patchInstructionsSegments(const std::vector<PatchableSegment> &inst
|
||||
UNRECOVERABLE_IF(nullptr == instSeg.hostPointer);
|
||||
auto relocAddress = ptrOffset(instSeg.hostPointer, static_cast<uintptr_t>(relocation.offset));
|
||||
if (relocation.symbolName == implicitArgsRelocationSymbolName) {
|
||||
pImplicitArgsRelocationAddresses.insert({segId, reinterpret_cast<uint32_t *>(relocAddress)});
|
||||
if (pImplicitArgsRelocationAddresses.find(segId) == pImplicitArgsRelocationAddresses.end()) {
|
||||
pImplicitArgsRelocationAddresses.insert({segId, {}});
|
||||
}
|
||||
pImplicitArgsRelocationAddresses[segId].push_back(reinterpret_cast<uint32_t *>(relocAddress));
|
||||
continue;
|
||||
}
|
||||
auto symbolIt = relocatedSymbols.find(relocation.symbolName);
|
||||
@@ -472,14 +475,16 @@ void Linker::resolveImplicitArgs(const KernelDescriptorsT &kernelDescriptors, De
|
||||
for (auto i = 0u; i < kernelDescriptors.size(); i++) {
|
||||
UNRECOVERABLE_IF(!kernelDescriptors[i]);
|
||||
KernelDescriptor &kernelDescriptor = *kernelDescriptors[i];
|
||||
auto pImplicitArgsReloc = pImplicitArgsRelocationAddresses.find(i);
|
||||
if (pImplicitArgsReloc != pImplicitArgsRelocationAddresses.end()) {
|
||||
auto pImplicitArgsRelocs = pImplicitArgsRelocationAddresses.find(i);
|
||||
if (pImplicitArgsRelocs != pImplicitArgsRelocationAddresses.end()) {
|
||||
for (const auto &pImplicitArgsReloc : pImplicitArgsRelocs->second) {
|
||||
UNRECOVERABLE_IF(!pDevice);
|
||||
kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs = kernelDescriptor.kernelAttributes.flags.useStackCalls || pDevice->getDebugger() != nullptr;
|
||||
if (kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs) {
|
||||
*pImplicitArgsReloc->second = sizeof(ImplicitArgs);
|
||||
*pImplicitArgsReloc = sizeof(ImplicitArgs);
|
||||
} else {
|
||||
*pImplicitArgsReloc->second = 0u;
|
||||
*pImplicitArgsReloc = 0u;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,7 +234,7 @@ struct Linker {
|
||||
template <typename PatchSizeT>
|
||||
void patchIncrement(Device *pDevice, GraphicsAllocation *dstAllocation, size_t relocationOffset, const void *initData, uint64_t incrementValue);
|
||||
|
||||
std::unordered_map<uint32_t /*ISA segment id*/, uint32_t * /*implicit args relocation address to patch*/> pImplicitArgsRelocationAddresses;
|
||||
std::unordered_map<uint32_t /*ISA segment id*/, StackVec<uint32_t *, 2> /*implicit args relocation address to patch*/> pImplicitArgsRelocationAddresses;
|
||||
};
|
||||
|
||||
std::string constructLinkerErrorMessage(const Linker::UnresolvedExternals &unresolvedExternals, const std::vector<std::string> &instructionsSegmentsNames);
|
||||
|
||||
@@ -2244,3 +2244,60 @@ TEST(LinkerTests, givenNoImplicitArgRelocationAndEnabledDebuggerThenImplicitArgs
|
||||
}
|
||||
EXPECT_FALSE(kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs);
|
||||
}
|
||||
|
||||
TEST(LinkerTests, givenMultipleImplicitArgsRelocationsWithinSingleKernelWhenLinkingThenPatchAllOfThem) {
|
||||
NEO::LinkerInput linkerInput;
|
||||
|
||||
vISA::GenRelocEntry reloc0 = {};
|
||||
std::string relocationName = implicitArgsRelocationSymbolName;
|
||||
memcpy_s(reloc0.r_symbol, 1024, relocationName.c_str(), relocationName.size());
|
||||
reloc0.r_offset = 8;
|
||||
reloc0.r_type = vISA::GenRelocType::R_SYM_ADDR_32;
|
||||
|
||||
vISA::GenRelocEntry reloc1 = reloc0;
|
||||
reloc1.r_offset = 24;
|
||||
|
||||
vISA::GenRelocEntry relocs[] = {reloc0, reloc1};
|
||||
constexpr uint32_t numRelocations = 2;
|
||||
bool decodeRelocSuccess = linkerInput.decodeRelocationTable(&relocs, numRelocations, 0);
|
||||
EXPECT_TRUE(decodeRelocSuccess);
|
||||
|
||||
NEO::Linker linker(linkerInput);
|
||||
NEO::Linker::SegmentInfo globalVarSegment, globalConstSegment, exportedFuncSegment;
|
||||
globalVarSegment.gpuAddress = 8;
|
||||
globalVarSegment.segmentSize = 64;
|
||||
globalConstSegment.gpuAddress = 128;
|
||||
globalConstSegment.segmentSize = 256;
|
||||
exportedFuncSegment.gpuAddress = 4096;
|
||||
exportedFuncSegment.segmentSize = 1024;
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
NEO::Linker::KernelDescriptorsT kernelDescriptors;
|
||||
KernelDescriptor kernelDescriptor;
|
||||
kernelDescriptors.push_back(&kernelDescriptor);
|
||||
kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs = false;
|
||||
kernelDescriptor.kernelAttributes.flags.useStackCalls = true;
|
||||
|
||||
UltDeviceFactory deviceFactory{1, 0};
|
||||
|
||||
std::vector<char> instructionSegment;
|
||||
char initData = 0x77;
|
||||
instructionSegment.resize(32, initData);
|
||||
NEO::Linker::PatchableSegment seg0;
|
||||
seg0.hostPointer = instructionSegment.data();
|
||||
seg0.segmentSize = instructionSegment.size();
|
||||
NEO::Linker::PatchableSegments patchableInstructionSegments{seg0};
|
||||
|
||||
auto linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment, {},
|
||||
nullptr, nullptr, patchableInstructionSegments, unresolvedExternals,
|
||||
deviceFactory.rootDevices[0], nullptr, nullptr, kernelDescriptors);
|
||||
EXPECT_EQ(NEO::LinkingStatus::LinkedFully, linkResult);
|
||||
auto relocatedSymbols = linker.extractRelocatedSymbols();
|
||||
EXPECT_EQ(0U, unresolvedExternals.size());
|
||||
EXPECT_EQ(0U, relocatedSymbols.size());
|
||||
|
||||
for (const auto &reloc : relocs) {
|
||||
auto addressToPatch = reinterpret_cast<const uint32_t *>(instructionSegment.data() + reloc.r_offset);
|
||||
EXPECT_EQ(sizeof(ImplicitArgs), *addressToPatch);
|
||||
EXPECT_TRUE(kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user