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:
Mateusz Jablonski
2022-01-11 10:09:44 +00:00
committed by Compute-Runtime-Automation
parent 0089cb698f
commit 61e5e0687d
3 changed files with 72 additions and 10 deletions

View File

@@ -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;
}
}
}
}

View File

@@ -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);

View File

@@ -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);
}
}