mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-08 22:12:59 +08:00
fix: correct resolving external functions dependencies
respect scenario when dependency comes from separate module Related-To: NEO-15211 Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
a0ff19823b
commit
8310b10987
@@ -297,21 +297,41 @@ void LinkerInput::decodeElfSymbolTableAndRelocations(Elf::Elf<numBits> &elf, con
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LinkerInput::parseRelocationForExtFuncUsage(const RelocationInfo &relocInfo, const std::string &kernelName) {
|
void LinkerInput::parseRelocationForExtFuncUsage(const RelocationInfo &relocInfo, const std::string &kernelName) {
|
||||||
auto extFuncSymIt = std::find_if(extFuncSymbols.begin(), extFuncSymbols.end(), [relocInfo](auto &pair) {
|
|
||||||
return pair.first == relocInfo.symbolName;
|
auto shouldIgnoreRelocation = [&](const RelocationInfo &relocInfo) {
|
||||||
});
|
if (relocInfo.symbolName.empty()) {
|
||||||
if (extFuncSymIt != extFuncSymbols.end()) {
|
return true;
|
||||||
if (kernelName == Zebin::Elf::SectionNames::externalFunctions.str()) {
|
|
||||||
auto callerIt = std::find_if(extFuncSymbols.begin(), extFuncSymbols.end(), [relocInfo](auto &pair) {
|
|
||||||
auto &symbol = pair.second;
|
|
||||||
return relocInfo.offset >= symbol.offset && relocInfo.offset < symbol.offset + symbol.size;
|
|
||||||
});
|
|
||||||
if (callerIt != extFuncSymbols.end()) {
|
|
||||||
extFunDependencies.push_back({relocInfo.symbolName, callerIt->first});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
kernelDependencies.push_back({relocInfo.symbolName, kernelName});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ignore relocations for non-instruction symbols
|
||||||
|
if (std::find_if(symbols.begin(), symbols.end(), [relocInfo](auto &pair) {
|
||||||
|
auto &symbol = pair.second;
|
||||||
|
return relocInfo.symbolName == pair.first && symbol.segment != SegmentType::instructions;
|
||||||
|
}) != symbols.end()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto specialRelocationName : {implicitArgsRelocationSymbolName, Linker::perThreadOff, Linker::subDeviceID}) {
|
||||||
|
if (relocInfo.symbolName == specialRelocationName) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (shouldIgnoreRelocation(relocInfo)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (kernelName == Zebin::Elf::SectionNames::externalFunctions.str()) {
|
||||||
|
auto callerIt = std::find_if(extFuncSymbols.begin(), extFuncSymbols.end(), [relocInfo](auto &pair) {
|
||||||
|
auto &symbol = pair.second;
|
||||||
|
return relocInfo.offset >= symbol.offset && relocInfo.offset < symbol.offset + symbol.size;
|
||||||
|
});
|
||||||
|
if (callerIt != extFuncSymbols.end()) {
|
||||||
|
extFunDependencies.push_back({relocInfo.symbolName, callerIt->first});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
kernelDependencies.push_back({relocInfo.symbolName, kernelName});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2021-2024 Intel Corporation
|
* Copyright (C) 2021-2025 Intel Corporation
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*
|
*
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace NEO {
|
namespace NEO {
|
||||||
@@ -19,7 +20,7 @@ namespace NEO {
|
|||||||
struct KernelDescriptor;
|
struct KernelDescriptor;
|
||||||
struct RootDeviceEnvironment;
|
struct RootDeviceEnvironment;
|
||||||
|
|
||||||
inline constexpr const char *implicitArgsRelocationSymbolName = "__INTEL_PATCH_CROSS_THREAD_OFFSET_OFF_R0";
|
inline const std::string implicitArgsRelocationSymbolName = "__INTEL_PATCH_CROSS_THREAD_OFFSET_OFF_R0";
|
||||||
|
|
||||||
namespace ImplicitArgsHelper {
|
namespace ImplicitArgsHelper {
|
||||||
std::array<uint8_t, 3> getDimensionOrderForLocalIds(const uint8_t *workgroupDimensionsOrder, std::optional<std::pair<bool /* localIdsGeneratedByRuntime */, uint32_t /* walkOrderForHwGenerationOfLocalIds */>> hwGenerationOfLocalIdsParams);
|
std::array<uint8_t, 3> getDimensionOrderForLocalIds(const uint8_t *workgroupDimensionsOrder, std::optional<std::pair<bool /* localIdsGeneratedByRuntime */, uint32_t /* walkOrderForHwGenerationOfLocalIds */>> hwGenerationOfLocalIdsParams);
|
||||||
|
|||||||
@@ -745,6 +745,83 @@ TEST(LinkerInputTests, GivenInvalidFunctionsSymbolsUsedInFunctionsRelocationsWhe
|
|||||||
EXPECT_TRUE(mockLinkerInput.extFunDependencies.empty());
|
EXPECT_TRUE(mockLinkerInput.extFunDependencies.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(LinkerInputTests, GivenFunctionSymbolsUsedInFunctionsRelocationsWhenParsingRelocationsForExtFuncUsageThenAddDependency) {
|
||||||
|
WhiteBox<NEO::LinkerInput> mockLinkerInput;
|
||||||
|
|
||||||
|
auto &extFuncSymbols = mockLinkerInput.extFuncSymbols;
|
||||||
|
extFuncSymbols.resize(2);
|
||||||
|
auto &funSym = extFuncSymbols[0];
|
||||||
|
funSym.first = "fun";
|
||||||
|
funSym.second.offset = 4U;
|
||||||
|
funSym.second.size = 4U;
|
||||||
|
|
||||||
|
auto &fun2Sym = extFuncSymbols[1];
|
||||||
|
fun2Sym.first = "fun2";
|
||||||
|
fun2Sym.second.offset = 8U;
|
||||||
|
fun2Sym.second.size = 4U;
|
||||||
|
|
||||||
|
NEO::LinkerInput::RelocationInfo relocInfo{};
|
||||||
|
relocInfo.symbolName = "fun3";
|
||||||
|
|
||||||
|
relocInfo.offset = 6U;
|
||||||
|
mockLinkerInput.parseRelocationForExtFuncUsage(relocInfo, NEO::Zebin::Elf::SectionNames::externalFunctions.str());
|
||||||
|
EXPECT_EQ(1u, mockLinkerInput.extFunDependencies.size());
|
||||||
|
EXPECT_EQ(relocInfo.symbolName, mockLinkerInput.extFunDependencies[0].usedFuncName);
|
||||||
|
EXPECT_EQ(funSym.first, mockLinkerInput.extFunDependencies[0].callerFuncName);
|
||||||
|
|
||||||
|
mockLinkerInput.extFunDependencies.clear();
|
||||||
|
relocInfo.offset = 8U;
|
||||||
|
mockLinkerInput.parseRelocationForExtFuncUsage(relocInfo, NEO::Zebin::Elf::SectionNames::externalFunctions.str());
|
||||||
|
EXPECT_EQ(1u, mockLinkerInput.extFunDependencies.size());
|
||||||
|
EXPECT_EQ(relocInfo.symbolName, mockLinkerInput.extFunDependencies[0].usedFuncName);
|
||||||
|
EXPECT_EQ(fun2Sym.first, mockLinkerInput.extFunDependencies[0].callerFuncName);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(LinkerInputTests, GivenExternalFunctionsSymbolsUsedInKernelRelocationsWhenParsingRelocationsForExtFuncUsageForKernelThenAddKernelDependency) {
|
||||||
|
WhiteBox<NEO::LinkerInput> mockLinkerInput;
|
||||||
|
|
||||||
|
NEO::LinkerInput::RelocationInfo relocInfo{};
|
||||||
|
relocInfo.symbolName = "fun";
|
||||||
|
|
||||||
|
std::string kernelName = "kernel";
|
||||||
|
mockLinkerInput.parseRelocationForExtFuncUsage(relocInfo, kernelName);
|
||||||
|
EXPECT_TRUE(mockLinkerInput.extFunDependencies.empty());
|
||||||
|
EXPECT_EQ(1u, mockLinkerInput.kernelDependencies.size());
|
||||||
|
EXPECT_EQ(relocInfo.symbolName, mockLinkerInput.kernelDependencies[0].usedFuncName);
|
||||||
|
EXPECT_EQ(kernelName, mockLinkerInput.kernelDependencies[0].kernelName);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(LinkerInputTests, GivenNonFunctionRelocationInKernelRelocationsWhenParsingRelocationsForExtFuncUsageForKernelThenDoNotAddKernelDependency) {
|
||||||
|
WhiteBox<NEO::LinkerInput> mockLinkerInput;
|
||||||
|
|
||||||
|
auto &symbols = mockLinkerInput.symbols;
|
||||||
|
SymbolInfo symbol0 = {
|
||||||
|
.segment = SegmentType::globalStrings};
|
||||||
|
SymbolInfo symbol1 = {
|
||||||
|
.segment = SegmentType::globalVariables};
|
||||||
|
SymbolInfo symbol2 = {
|
||||||
|
.segment = SegmentType::instructions};
|
||||||
|
symbols.emplace(".str", symbol0);
|
||||||
|
symbols.emplace("globalVar", symbol1);
|
||||||
|
symbols.emplace("fun", symbol2);
|
||||||
|
|
||||||
|
for (auto nonFuncRelocationName : {
|
||||||
|
implicitArgsRelocationSymbolName,
|
||||||
|
std::string(".str"),
|
||||||
|
std::string("globalVar"),
|
||||||
|
Linker::perThreadOff,
|
||||||
|
Linker::subDeviceID,
|
||||||
|
std::string("")}) {
|
||||||
|
|
||||||
|
NEO::LinkerInput::RelocationInfo relocInfo{};
|
||||||
|
relocInfo.symbolName = nonFuncRelocationName;
|
||||||
|
|
||||||
|
std::string kernelName = "kernel";
|
||||||
|
mockLinkerInput.parseRelocationForExtFuncUsage(relocInfo, kernelName);
|
||||||
|
EXPECT_TRUE(mockLinkerInput.extFunDependencies.empty());
|
||||||
|
EXPECT_EQ(0u, mockLinkerInput.kernelDependencies.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
HWTEST_F(LinkerTests, givenEmptyLinkerInputThenLinkerOutputIsEmpty) {
|
HWTEST_F(LinkerTests, givenEmptyLinkerInputThenLinkerOutputIsEmpty) {
|
||||||
NEO::LinkerInput linkerInput;
|
NEO::LinkerInput linkerInput;
|
||||||
NEO::Linker linker(linkerInput);
|
NEO::Linker linker(linkerInput);
|
||||||
|
|||||||
Reference in New Issue
Block a user