Zebin: don't fail when extfunc caller cannot be found

This commit removes early fail in linking with zebin and external
functions which happens when, there's a relocation to external functions
section, but it's not modifying any external function. And only treats
GLOBAL FUNC symbols pointing to external functions section as external
function symbols.

Signed-off-by: Krystian Chmielewski <krystian.chmielewski@intel.com>
This commit is contained in:
Krystian Chmielewski 2022-03-29 19:28:59 +00:00 committed by Compute-Runtime-Automation
parent 7cd4ca5ce7
commit 6023a5b58e
3 changed files with 8 additions and 24 deletions

View File

@ -170,15 +170,6 @@ void LinkerInput::decodeElfSymbolTableAndRelocations(Elf::Elf<Elf::EI_CLASS_64>
auto bind = elf.extractSymbolBind(symbol); auto bind = elf.extractSymbolBind(symbol);
auto type = elf.extractSymbolType(symbol); auto type = elf.extractSymbolType(symbol);
if (type == Elf::SYMBOL_TABLE_TYPE::STT_FUNC) {
SymbolInfo symbolInfo;
symbolInfo.offset = static_cast<uint32_t>(symbol.value);
symbolInfo.size = static_cast<uint32_t>(symbol.size);
symbolInfo.bind = static_cast<SymbolBind>(bind);
extFuncSymbols.push_back({elf.getSymbolName(symbol.name), symbolInfo});
}
if (bind == Elf::SYMBOL_TABLE_BIND::STB_GLOBAL) { if (bind == Elf::SYMBOL_TABLE_BIND::STB_GLOBAL) {
SymbolInfo symbolInfo; SymbolInfo symbolInfo;
symbolInfo.offset = static_cast<uint32_t>(symbol.value); symbolInfo.offset = static_cast<uint32_t>(symbol.value);
@ -205,6 +196,7 @@ void LinkerInput::decodeElfSymbolTableAndRelocations(Elf::Elf<Elf::EI_CLASS_64>
int32_t instructionsSegmentId = static_cast<int32_t>(segmentIdIter->second); int32_t instructionsSegmentId = static_cast<int32_t>(segmentIdIter->second);
UNRECOVERABLE_IF((this->exportedFunctionsSegmentId != -1) && (this->exportedFunctionsSegmentId != instructionsSegmentId)); UNRECOVERABLE_IF((this->exportedFunctionsSegmentId != -1) && (this->exportedFunctionsSegmentId != instructionsSegmentId));
this->exportedFunctionsSegmentId = instructionsSegmentId; this->exportedFunctionsSegmentId = instructionsSegmentId;
extFuncSymbols.push_back({elf.getSymbolName(symbol.name), symbolInfo});
} }
} break; } break;
} }
@ -253,7 +245,7 @@ void LinkerInput::decodeElfSymbolTableAndRelocations(Elf::Elf<Elf::EI_CLASS_64>
} }
} }
void LinkerInput::parseRelocationForExtFuncUsage(RelocationInfo relocInfo, 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) { auto extFuncSymIt = std::find_if(extFuncSymbols.begin(), extFuncSymbols.end(), [relocInfo](auto &pair) {
return pair.first == relocInfo.symbolName; return pair.first == relocInfo.symbolName;
}); });
@ -263,11 +255,9 @@ void LinkerInput::parseRelocationForExtFuncUsage(RelocationInfo relocInfo, std::
auto &symbol = pair.second; auto &symbol = pair.second;
return relocInfo.offset >= symbol.offset && relocInfo.offset < symbol.offset + symbol.size; return relocInfo.offset >= symbol.offset && relocInfo.offset < symbol.offset + symbol.size;
}); });
if (callerIt == extFuncSymbols.end()) { if (callerIt != extFuncSymbols.end()) {
this->valid = false; extFunDependencies.push_back({relocInfo.symbolName, callerIt->first});
return;
} }
extFunDependencies.push_back({relocInfo.symbolName, callerIt->first});
} else { } else {
kernelDependencies.push_back({relocInfo.symbolName, kernelName}); kernelDependencies.push_back({relocInfo.symbolName, kernelName});
} }

View File

@ -35,10 +35,6 @@ enum class LinkingStatus : uint32_t {
LinkedFully, LinkedFully,
LinkedPartially LinkedPartially
}; };
enum class SymbolBind : uint8_t {
Local,
Global
};
inline const char *asString(SegmentType segment) { inline const char *asString(SegmentType segment) {
switch (segment) { switch (segment) {
@ -57,7 +53,6 @@ struct SymbolInfo {
uint32_t offset = std::numeric_limits<uint32_t>::max(); uint32_t offset = std::numeric_limits<uint32_t>::max();
uint32_t size = std::numeric_limits<uint32_t>::max(); uint32_t size = std::numeric_limits<uint32_t>::max();
SegmentType segment = SegmentType::Unknown; SegmentType segment = SegmentType::Unknown;
SymbolBind bind = SymbolBind::Local;
}; };
struct LinkerInput { struct LinkerInput {
@ -156,7 +151,7 @@ struct LinkerInput {
} }
protected: protected:
void parseRelocationForExtFuncUsage(RelocationInfo relocInfo, std::string kernelName); void parseRelocationForExtFuncUsage(const RelocationInfo &relocInfo, const std::string &kernelName);
Traits traits; Traits traits;
SymbolMap symbols; SymbolMap symbols;

View File

@ -954,7 +954,7 @@ TEST(LinkerInputTests, GivenGlobalElfSymbolOfNoTypeWhenDecodingThenDebugBreakCal
EXPECT_FALSE(linkerInput.getTraits().exportsFunctions); EXPECT_FALSE(linkerInput.getTraits().exportsFunctions);
} }
TEST(LinkerInputTests, GivenInvalidFunctionsSymbolsUsedInFunctionsRelocationsWhenParsingRelocationsForExtFuncUsageThenSetValidToFalse) { TEST(LinkerInputTests, GivenInvalidFunctionsSymbolsUsedInFunctionsRelocationsWhenParsingRelocationsForExtFuncUsageThenDoNotAddDependency) {
WhiteBox<NEO::LinkerInput> mockLinkerInput; WhiteBox<NEO::LinkerInput> mockLinkerInput;
auto &extFuncSymbols = mockLinkerInput.extFuncSymbols; auto &extFuncSymbols = mockLinkerInput.extFuncSymbols;
@ -969,12 +969,11 @@ TEST(LinkerInputTests, GivenInvalidFunctionsSymbolsUsedInFunctionsRelocationsWhe
relocInfo.offset = 0U; relocInfo.offset = 0U;
mockLinkerInput.parseRelocationForExtFuncUsage(relocInfo, NEO::Elf::SectionsNamesZebin::externalFunctions.str()); mockLinkerInput.parseRelocationForExtFuncUsage(relocInfo, NEO::Elf::SectionsNamesZebin::externalFunctions.str());
EXPECT_FALSE(mockLinkerInput.isValid()); EXPECT_TRUE(mockLinkerInput.extFunDependencies.empty());
mockLinkerInput.valid = true;
relocInfo.offset = 0x10U; relocInfo.offset = 0x10U;
mockLinkerInput.parseRelocationForExtFuncUsage(relocInfo, NEO::Elf::SectionsNamesZebin::externalFunctions.str()); mockLinkerInput.parseRelocationForExtFuncUsage(relocInfo, NEO::Elf::SectionsNamesZebin::externalFunctions.str());
EXPECT_FALSE(mockLinkerInput.isValid()); EXPECT_TRUE(mockLinkerInput.extFunDependencies.empty());
} }
TEST(LinkerTests, givenEmptyLinkerInputThenLinkerOutputIsEmpty) { TEST(LinkerTests, givenEmptyLinkerInputThenLinkerOutputIsEmpty) {