diff --git a/level_zero/core/test/unit_tests/sources/module/test_module.cpp b/level_zero/core/test/unit_tests/sources/module/test_module.cpp index 5ae3e32222..96943b446d 100644 --- a/level_zero/core/test/unit_tests/sources/module/test_module.cpp +++ b/level_zero/core/test/unit_tests/sources/module/test_module.cpp @@ -2375,7 +2375,7 @@ TEST_F(ModuleTests, givenImplicitArgsRelocationAndStackCallsWhenLinkingModuleThe pModule->translationUnit->programInfo.kernelInfos.push_back(kernelInfo); auto linkerInput = std::make_unique<::WhiteBox>(); linkerInput->traits.requiresPatchingOfInstructionSegments = true; - linkerInput->relocations.push_back({{implicitArgsRelocationSymbolName, 0x8, LinkerInput::RelocationInfo::Type::AddressLow, SegmentType::Instructions}}); + linkerInput->relocations.push_back({{implicitArgsRelocationSymbolNames[0], 0x8, LinkerInput::RelocationInfo::Type::AddressLow, SegmentType::Instructions}}); pModule->translationUnit->programInfo.linkerInput = std::move(linkerInput); EXPECT_FALSE(kernelInfo->kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs); @@ -2412,7 +2412,7 @@ TEST_F(ModuleTests, givenImplicitArgsRelocationAndDebuggerEnabledWhenLinkingModu pModule->translationUnit->programInfo.kernelInfos.push_back(kernelInfo); auto linkerInput = std::make_unique<::WhiteBox>(); linkerInput->traits.requiresPatchingOfInstructionSegments = true; - linkerInput->relocations.push_back({{implicitArgsRelocationSymbolName, 0x8, LinkerInput::RelocationInfo::Type::AddressLow, SegmentType::Instructions}}); + linkerInput->relocations.push_back({{implicitArgsRelocationSymbolNames[0], 0x8, LinkerInput::RelocationInfo::Type::AddressLow, SegmentType::Instructions}}); pModule->translationUnit->programInfo.linkerInput = std::move(linkerInput); EXPECT_FALSE(kernelInfo->kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs); @@ -2442,7 +2442,7 @@ TEST_F(ModuleTests, givenImplicitArgsRelocationAndNoDebuggerOrStackCallsWhenLink pModule->translationUnit->programInfo.kernelInfos.push_back(kernelInfo); auto linkerInput = std::make_unique<::WhiteBox>(); linkerInput->traits.requiresPatchingOfInstructionSegments = true; - linkerInput->relocations.push_back({{implicitArgsRelocationSymbolName, 0x8, LinkerInput::RelocationInfo::Type::AddressLow, SegmentType::Instructions}}); + linkerInput->relocations.push_back({{implicitArgsRelocationSymbolNames[0], 0x8, LinkerInput::RelocationInfo::Type::AddressLow, SegmentType::Instructions}}); pModule->translationUnit->programInfo.linkerInput = std::move(linkerInput); EXPECT_FALSE(kernelInfo->kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs); diff --git a/opencl/test/unit_test/program/program_data_tests.cpp b/opencl/test/unit_test/program/program_data_tests.cpp index 89195fa89f..fa35426fb5 100644 --- a/opencl/test/unit_test/program/program_data_tests.cpp +++ b/opencl/test/unit_test/program/program_data_tests.cpp @@ -744,7 +744,7 @@ TEST(ProgramImplicitArgsTest, givenImplicitRelocationAndStackCallsThenKernelRequ program.getKernelInfoArray(rootDeviceIndex).push_back(&kernelInfo); auto linkerInput = std::make_unique>(); - linkerInput->relocations.push_back({{implicitArgsRelocationSymbolName, 0x8, LinkerInput::RelocationInfo::Type::AddressLow, SegmentType::Instructions}}); + linkerInput->relocations.push_back({{implicitArgsRelocationSymbolNames[0], 0x8, LinkerInput::RelocationInfo::Type::AddressLow, SegmentType::Instructions}}); linkerInput->traits.requiresPatchingOfInstructionSegments = true; program.setLinkerInput(rootDeviceIndex, std::move(linkerInput)); auto ret = program.linkBinary(&device->getDevice(), nullptr, nullptr, {}, program.externalFunctions); @@ -776,7 +776,7 @@ TEST(ProgramImplicitArgsTest, givenImplicitRelocationAndEnabledDebuggerThenKerne program.getKernelInfoArray(rootDeviceIndex).push_back(&kernelInfo); auto linkerInput = std::make_unique>(); - linkerInput->relocations.push_back({{implicitArgsRelocationSymbolName, 0x8, LinkerInput::RelocationInfo::Type::AddressLow, SegmentType::Instructions}}); + linkerInput->relocations.push_back({{implicitArgsRelocationSymbolNames[0], 0x8, LinkerInput::RelocationInfo::Type::AddressLow, SegmentType::Instructions}}); linkerInput->traits.requiresPatchingOfInstructionSegments = true; program.setLinkerInput(rootDeviceIndex, std::move(linkerInput)); auto ret = program.linkBinary(&device->getDevice(), nullptr, nullptr, {}, program.externalFunctions); @@ -802,7 +802,7 @@ TEST(ProgramImplicitArgsTest, givenImplicitRelocationAndNoStackCallsAndDisabledD program.getKernelInfoArray(rootDeviceIndex).push_back(&kernelInfo); auto linkerInput = std::make_unique>(); - linkerInput->relocations.push_back({{implicitArgsRelocationSymbolName, 0x8, LinkerInput::RelocationInfo::Type::AddressLow, SegmentType::Instructions}}); + linkerInput->relocations.push_back({{implicitArgsRelocationSymbolNames[0], 0x8, LinkerInput::RelocationInfo::Type::AddressLow, SegmentType::Instructions}}); linkerInput->traits.requiresPatchingOfInstructionSegments = true; program.setLinkerInput(rootDeviceIndex, std::move(linkerInput)); auto ret = program.linkBinary(&device->getDevice(), nullptr, nullptr, {}, program.externalFunctions); diff --git a/shared/source/compiler_interface/linker.cpp b/shared/source/compiler_interface/linker.cpp index 322e3779bb..9a4b7f81ea 100644 --- a/shared/source/compiler_interface/linker.cpp +++ b/shared/source/compiler_interface/linker.cpp @@ -342,11 +342,17 @@ void Linker::patchInstructionsSegments(const std::vector &inst } UNRECOVERABLE_IF(nullptr == instSeg.hostPointer); auto relocAddress = ptrOffset(instSeg.hostPointer, static_cast(relocation.offset)); - if (relocation.symbolName == implicitArgsRelocationSymbolName) { - if (pImplicitArgsRelocationAddresses.find(segId) == pImplicitArgsRelocationAddresses.end()) { - pImplicitArgsRelocationAddresses.insert({segId, {}}); + bool isImplicitArgsRelocation = false; + for (const auto &implicitArgsRelocationSymbolName : implicitArgsRelocationSymbolNames) { + if (relocation.symbolName == implicitArgsRelocationSymbolName) { + if (pImplicitArgsRelocationAddresses.find(segId) == pImplicitArgsRelocationAddresses.end()) { + pImplicitArgsRelocationAddresses.insert({segId, {}}); + } + pImplicitArgsRelocationAddresses[segId].push_back(reinterpret_cast(relocAddress)); + isImplicitArgsRelocation = true; } - pImplicitArgsRelocationAddresses[segId].push_back(reinterpret_cast(relocAddress)); + } + if (isImplicitArgsRelocation) { continue; } auto symbolIt = relocatedSymbols.find(relocation.symbolName); diff --git a/shared/source/kernel/implicit_args.h b/shared/source/kernel/implicit_args.h index daf1a1d102..537fdb8ff4 100644 --- a/shared/source/kernel/implicit_args.h +++ b/shared/source/kernel/implicit_args.h @@ -41,7 +41,7 @@ struct ImplicitArgs { static_assert((sizeof(ImplicitArgs) & 31) == 0, "Implicit args size need to be aligned to 32"); static_assert(std::is_pod::value); -constexpr const char *implicitArgsRelocationSymbolName = "INTEL_PATCH_CROSS_THREAD_OFFSET_OFF_R0"; +constexpr const char *implicitArgsRelocationSymbolNames[] = {"INTEL_PATCH_CROSS_THREAD_OFFSET_OFF_R0", "__INTEL_PATCH_CROSS_THREAD_OFFSET_OFF_R0"}; namespace ImplicitArgsHelper { std::array getDimensionOrderForLocalIds(const uint8_t *workgroupDimensionsOrder, std::optional> hwGenerationOfLocalIdsParams); diff --git a/shared/test/unit_test/compiler_interface/linker_tests.cpp b/shared/test/unit_test/compiler_interface/linker_tests.cpp index 23f404e8f1..58318dfa4e 100644 --- a/shared/test/unit_test/compiler_interface/linker_tests.cpp +++ b/shared/test/unit_test/compiler_interface/linker_tests.cpp @@ -2009,177 +2009,183 @@ TEST(LinkerTests, GivenDebugDataWhenApplyingDebugDataRelocationsThenRelocationsA } TEST(LinkerTests, givenImplicitArgRelocationAndStackCallsThenPatchRelocationWithSizeOfImplicitArgStructAndUpdateKernelDescriptor) { - NEO::LinkerInput linkerInput; + for (const auto &implicitArgsRelocationSymbolName : implicitArgsRelocationSymbolNames) { + NEO::LinkerInput linkerInput; - vISA::GenRelocEntry reloc = {}; - std::string relocationName = implicitArgsRelocationSymbolName; - memcpy_s(reloc.r_symbol, 1024, relocationName.c_str(), relocationName.size()); - reloc.r_offset = 8; - reloc.r_type = vISA::GenRelocType::R_SYM_ADDR_32; + vISA::GenRelocEntry reloc = {}; + std::string relocationName = implicitArgsRelocationSymbolName; + memcpy_s(reloc.r_symbol, 1024, relocationName.c_str(), relocationName.size()); + reloc.r_offset = 8; + reloc.r_type = vISA::GenRelocType::R_SYM_ADDR_32; - vISA::GenRelocEntry relocs[] = {reloc}; - constexpr uint32_t numRelocations = 1; - bool decodeRelocSuccess = linkerInput.decodeRelocationTable(&relocs, numRelocations, 0); - EXPECT_TRUE(decodeRelocSuccess); + vISA::GenRelocEntry relocs[] = {reloc}; + constexpr uint32_t numRelocations = 1; + 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; - NEO::Linker::ExternalFunctionsT externalFunctions; - KernelDescriptor kernelDescriptor; - kernelDescriptors.push_back(&kernelDescriptor); - kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs = false; - kernelDescriptor.kernelAttributes.flags.useStackCalls = true; + 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; + NEO::Linker::ExternalFunctionsT externalFunctions; + KernelDescriptor kernelDescriptor; + kernelDescriptors.push_back(&kernelDescriptor); + kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs = false; + kernelDescriptor.kernelAttributes.flags.useStackCalls = true; - UltDeviceFactory deviceFactory{1, 0}; + UltDeviceFactory deviceFactory{1, 0}; - std::vector instructionSegment; - uint32_t initData = 0x77777777; - instructionSegment.resize(32, static_cast(initData)); - NEO::Linker::PatchableSegment seg0; - seg0.hostPointer = instructionSegment.data(); - seg0.segmentSize = instructionSegment.size(); - NEO::Linker::PatchableSegments patchableInstructionSegments{seg0}; + std::vector instructionSegment; + uint32_t initData = 0x77777777; + instructionSegment.resize(32, static_cast(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, externalFunctions); - EXPECT_EQ(NEO::LinkingStatus::LinkedFully, linkResult); - auto relocatedSymbols = linker.extractRelocatedSymbols(); - EXPECT_EQ(0U, unresolvedExternals.size()); - EXPECT_EQ(0U, relocatedSymbols.size()); + auto linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment, {}, + nullptr, nullptr, patchableInstructionSegments, unresolvedExternals, + deviceFactory.rootDevices[0], nullptr, nullptr, kernelDescriptors, externalFunctions); + EXPECT_EQ(NEO::LinkingStatus::LinkedFully, linkResult); + auto relocatedSymbols = linker.extractRelocatedSymbols(); + EXPECT_EQ(0U, unresolvedExternals.size()); + EXPECT_EQ(0U, relocatedSymbols.size()); - auto addressToPatch = reinterpret_cast(instructionSegment.data() + reloc.r_offset); - EXPECT_EQ(sizeof(ImplicitArgs), *addressToPatch); - EXPECT_EQ(initData, *(addressToPatch - 1)); - EXPECT_EQ(initData, *(addressToPatch + 1)); - EXPECT_TRUE(kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs); + auto addressToPatch = reinterpret_cast(instructionSegment.data() + reloc.r_offset); + EXPECT_EQ(sizeof(ImplicitArgs), *addressToPatch); + EXPECT_EQ(initData, *(addressToPatch - 1)); + EXPECT_EQ(initData, *(addressToPatch + 1)); + EXPECT_TRUE(kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs); + } } TEST(LinkerTests, givenImplicitArgRelocationAndEnabledDebuggerThenPatchRelocationWithSizeOfImplicitArgStructAndUpdateKernelDescriptor) { if (!defaultHwInfo->capabilityTable.debuggerSupported) { GTEST_SKIP(); } - NEO::LinkerInput linkerInput; + for (const auto &implicitArgsRelocationSymbolName : implicitArgsRelocationSymbolNames) { + NEO::LinkerInput linkerInput; - vISA::GenRelocEntry reloc = {}; - std::string relocationName = implicitArgsRelocationSymbolName; - memcpy_s(reloc.r_symbol, 1024, relocationName.c_str(), relocationName.size()); - reloc.r_offset = 8; - reloc.r_type = vISA::GenRelocType::R_SYM_ADDR_32; + vISA::GenRelocEntry reloc = {}; + std::string relocationName = implicitArgsRelocationSymbolName; + memcpy_s(reloc.r_symbol, 1024, relocationName.c_str(), relocationName.size()); + reloc.r_offset = 8; + reloc.r_type = vISA::GenRelocType::R_SYM_ADDR_32; - vISA::GenRelocEntry relocs[] = {reloc}; - constexpr uint32_t numRelocations = 1; - bool decodeRelocSuccess = linkerInput.decodeRelocationTable(&relocs, numRelocations, 0); - EXPECT_TRUE(decodeRelocSuccess); + vISA::GenRelocEntry relocs[] = {reloc}; + constexpr uint32_t numRelocations = 1; + 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; - NEO::Linker::ExternalFunctionsT externalFunctions; - KernelDescriptor kernelDescriptor; - kernelDescriptors.push_back(&kernelDescriptor); - kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs = false; - kernelDescriptor.kernelAttributes.flags.useStackCalls = false; + 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; + NEO::Linker::ExternalFunctionsT externalFunctions; + KernelDescriptor kernelDescriptor; + kernelDescriptors.push_back(&kernelDescriptor); + kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs = false; + kernelDescriptor.kernelAttributes.flags.useStackCalls = false; - DebugManagerStateRestore restorer; - DebugManager.flags.EnableMockSourceLevelDebugger.set(1); - UltDeviceFactory deviceFactory{1, 0}; - auto device = deviceFactory.rootDevices[0]; - EXPECT_NE(nullptr, device->getDebugger()); + DebugManagerStateRestore restorer; + DebugManager.flags.EnableMockSourceLevelDebugger.set(1); + UltDeviceFactory deviceFactory{1, 0}; + auto device = deviceFactory.rootDevices[0]; + EXPECT_NE(nullptr, device->getDebugger()); - std::vector instructionSegment; - uint32_t initData = 0x77777777; - instructionSegment.resize(32, static_cast(initData)); - NEO::Linker::PatchableSegment seg0; - seg0.hostPointer = instructionSegment.data(); - seg0.segmentSize = instructionSegment.size(); - NEO::Linker::PatchableSegments patchableInstructionSegments{seg0}; + std::vector instructionSegment; + uint32_t initData = 0x77777777; + instructionSegment.resize(32, static_cast(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, - device, nullptr, nullptr, kernelDescriptors, externalFunctions); - EXPECT_EQ(NEO::LinkingStatus::LinkedFully, linkResult); - auto relocatedSymbols = linker.extractRelocatedSymbols(); - EXPECT_EQ(0U, unresolvedExternals.size()); - EXPECT_EQ(0U, relocatedSymbols.size()); + auto linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment, {}, + nullptr, nullptr, patchableInstructionSegments, unresolvedExternals, + device, nullptr, nullptr, kernelDescriptors, externalFunctions); + EXPECT_EQ(NEO::LinkingStatus::LinkedFully, linkResult); + auto relocatedSymbols = linker.extractRelocatedSymbols(); + EXPECT_EQ(0U, unresolvedExternals.size()); + EXPECT_EQ(0U, relocatedSymbols.size()); - auto addressToPatch = reinterpret_cast(instructionSegment.data() + reloc.r_offset); - EXPECT_EQ(sizeof(ImplicitArgs), *addressToPatch); - EXPECT_EQ(initData, *(addressToPatch - 1)); - EXPECT_EQ(initData, *(addressToPatch + 1)); - EXPECT_TRUE(kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs); + auto addressToPatch = reinterpret_cast(instructionSegment.data() + reloc.r_offset); + EXPECT_EQ(sizeof(ImplicitArgs), *addressToPatch); + EXPECT_EQ(initData, *(addressToPatch - 1)); + EXPECT_EQ(initData, *(addressToPatch + 1)); + EXPECT_TRUE(kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs); + } } TEST(LinkerTests, givenImplicitArgRelocationWithoutStackCallsAndDisabledDebuggerThenPatchRelocationWithZeroAndUpdateKernelDescriptor) { - NEO::LinkerInput linkerInput; + for (const auto &implicitArgsRelocationSymbolName : implicitArgsRelocationSymbolNames) { + NEO::LinkerInput linkerInput; - vISA::GenRelocEntry reloc = {}; - std::string relocationName = implicitArgsRelocationSymbolName; - memcpy_s(reloc.r_symbol, 1024, relocationName.c_str(), relocationName.size()); - reloc.r_offset = 8; - reloc.r_type = vISA::GenRelocType::R_SYM_ADDR_32; + vISA::GenRelocEntry reloc = {}; + std::string relocationName = implicitArgsRelocationSymbolName; + memcpy_s(reloc.r_symbol, 1024, relocationName.c_str(), relocationName.size()); + reloc.r_offset = 8; + reloc.r_type = vISA::GenRelocType::R_SYM_ADDR_32; - vISA::GenRelocEntry relocs[] = {reloc}; - constexpr uint32_t numRelocations = 1; - bool decodeRelocSuccess = linkerInput.decodeRelocationTable(&relocs, numRelocations, 0); - EXPECT_TRUE(decodeRelocSuccess); + vISA::GenRelocEntry relocs[] = {reloc}; + constexpr uint32_t numRelocations = 1; + 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; - NEO::Linker::ExternalFunctionsT externalFunctions; - KernelDescriptor kernelDescriptor; - kernelDescriptors.push_back(&kernelDescriptor); - kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs = false; - kernelDescriptor.kernelAttributes.flags.useStackCalls = false; + 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; + NEO::Linker::ExternalFunctionsT externalFunctions; + KernelDescriptor kernelDescriptor; + kernelDescriptors.push_back(&kernelDescriptor); + kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs = false; + kernelDescriptor.kernelAttributes.flags.useStackCalls = false; - UltDeviceFactory deviceFactory{1, 0}; - auto device = deviceFactory.rootDevices[0]; - EXPECT_EQ(nullptr, device->getDebugger()); + UltDeviceFactory deviceFactory{1, 0}; + auto device = deviceFactory.rootDevices[0]; + EXPECT_EQ(nullptr, device->getDebugger()); - std::vector instructionSegment; - uint32_t initData = 0x77777777; - instructionSegment.resize(32, static_cast(initData)); - NEO::Linker::PatchableSegment seg0; - seg0.hostPointer = instructionSegment.data(); - seg0.segmentSize = instructionSegment.size(); - NEO::Linker::PatchableSegments patchableInstructionSegments{seg0}; + std::vector instructionSegment; + uint32_t initData = 0x77777777; + instructionSegment.resize(32, static_cast(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, - device, nullptr, nullptr, kernelDescriptors, externalFunctions); - EXPECT_EQ(NEO::LinkingStatus::LinkedFully, linkResult); - auto relocatedSymbols = linker.extractRelocatedSymbols(); - EXPECT_EQ(0U, unresolvedExternals.size()); - EXPECT_EQ(0U, relocatedSymbols.size()); + auto linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment, {}, + nullptr, nullptr, patchableInstructionSegments, unresolvedExternals, + device, nullptr, nullptr, kernelDescriptors, externalFunctions); + EXPECT_EQ(NEO::LinkingStatus::LinkedFully, linkResult); + auto relocatedSymbols = linker.extractRelocatedSymbols(); + EXPECT_EQ(0U, unresolvedExternals.size()); + EXPECT_EQ(0U, relocatedSymbols.size()); - auto addressToPatch = reinterpret_cast(instructionSegment.data() + reloc.r_offset); - EXPECT_EQ(0u, *addressToPatch); - EXPECT_EQ(initData, *(addressToPatch - 1)); - EXPECT_EQ(initData, *(addressToPatch + 1)); - EXPECT_FALSE(kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs); + auto addressToPatch = reinterpret_cast(instructionSegment.data() + reloc.r_offset); + EXPECT_EQ(0u, *addressToPatch); + EXPECT_EQ(initData, *(addressToPatch - 1)); + EXPECT_EQ(initData, *(addressToPatch + 1)); + EXPECT_FALSE(kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs); + } } TEST(LinkerTests, givenNoImplicitArgRelocationAndStackCallsThenImplicitArgsAreNotRequired) { @@ -2276,60 +2282,62 @@ TEST(LinkerTests, givenNoImplicitArgRelocationAndEnabledDebuggerThenImplicitArgs } TEST(LinkerTests, givenMultipleImplicitArgsRelocationsWithinSingleKernelWhenLinkingThenPatchAllOfThem) { - NEO::LinkerInput linkerInput; + for (const auto &implicitArgsRelocationSymbolName : implicitArgsRelocationSymbolNames) { + 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 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 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); + 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::ExternalFunctionsT externalFunctions; - NEO::Linker::KernelDescriptorsT kernelDescriptors; - KernelDescriptor kernelDescriptor; - kernelDescriptors.push_back(&kernelDescriptor); - kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs = false; - kernelDescriptor.kernelAttributes.flags.useStackCalls = true; + 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::ExternalFunctionsT externalFunctions; + NEO::Linker::KernelDescriptorsT kernelDescriptors; + KernelDescriptor kernelDescriptor; + kernelDescriptors.push_back(&kernelDescriptor); + kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs = false; + kernelDescriptor.kernelAttributes.flags.useStackCalls = true; - UltDeviceFactory deviceFactory{1, 0}; + UltDeviceFactory deviceFactory{1, 0}; - std::vector 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}; + std::vector 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, externalFunctions); - EXPECT_EQ(NEO::LinkingStatus::LinkedFully, linkResult); - auto relocatedSymbols = linker.extractRelocatedSymbols(); - EXPECT_EQ(0U, unresolvedExternals.size()); - EXPECT_EQ(0U, relocatedSymbols.size()); + auto linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment, {}, + nullptr, nullptr, patchableInstructionSegments, unresolvedExternals, + deviceFactory.rootDevices[0], nullptr, nullptr, kernelDescriptors, externalFunctions); + 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(instructionSegment.data() + reloc.r_offset); - EXPECT_EQ(sizeof(ImplicitArgs), *addressToPatch); - EXPECT_TRUE(kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs); + for (const auto &reloc : relocs) { + auto addressToPatch = reinterpret_cast(instructionSegment.data() + reloc.r_offset); + EXPECT_EQ(sizeof(ImplicitArgs), *addressToPatch); + EXPECT_TRUE(kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs); + } } }