Zebin: allow undef symbols

Skip undefined symbols when decoding ELF symbol table
instead of treating them as error in zebin path in
order to support dynamic linking scenarios.

Signed-off-by: Krystian Chmielewski <krystian.chmielewski@intel.com>
This commit is contained in:
Krystian Chmielewski
2021-12-13 12:59:39 +00:00
committed by Compute-Runtime-Automation
parent 616580637b
commit 7e08e56d50
3 changed files with 9 additions and 7 deletions

View File

@@ -314,6 +314,7 @@ bool ModuleTranslationUnit::processUnpackedBinary() {
id++;
}
programInfo.prepareLinkerInputStorage();
programInfo.linkerInput->undefinedSymbolsAllowed = programInfo.levelZeroDynamicLinkProgram;
programInfo.linkerInput->decodeElfSymbolTableAndRelocations(programInfo.decodedElf, nameToKernelId);
}

View File

@@ -214,7 +214,7 @@ void LinkerInput::decodeElfSymbolTableAndRelocations(Elf::Elf<Elf::EI_CLASS_64>
auto bind = elf.extractSymbolBind(symbol);
if (bind == Elf::SYMBOL_TABLE_BIND::STB_GLOBAL) {
SymbolInfo &symbolInfo = symbols[elf.getSymbolName(symbol.name)];
SymbolInfo symbolInfo;
symbolInfo.offset = static_cast<uint32_t>(symbol.value);
symbolInfo.size = static_cast<uint32_t>(symbol.size);
auto type = elf.extractSymbolType(symbol);
@@ -224,8 +224,9 @@ void LinkerInput::decodeElfSymbolTableAndRelocations(Elf::Elf<Elf::EI_CLASS_64>
switch (type) {
default:
DEBUG_BREAK_IF(true);
break;
this->valid &= this->undefinedSymbolsAllowed;
DEBUG_BREAK_IF(false == this->undefinedSymbolsAllowed);
continue;
case Elf::SYMBOL_TABLE_TYPE::STT_OBJECT:
symbolInfo.segment = symbolSegment;
traits.exportsGlobalVariables |= symbolSegment == SegmentType::GlobalVariables;
@@ -243,6 +244,7 @@ void LinkerInput::decodeElfSymbolTableAndRelocations(Elf::Elf<Elf::EI_CLASS_64>
}
} break;
}
symbols.insert({elf.getSymbolName(symbol.name), symbolInfo});
}
}
}

View File

@@ -892,7 +892,7 @@ TEST(LinkerInputTests, GivenGlobalFunctionsInTwoSegementsWhenDecodingThenUnrecov
EXPECT_THROW(linkerInput.decodeElfSymbolTableAndRelocations(elf64, nameToKernelId), std::exception);
auto symbols = linkerInput.getSymbols();
ASSERT_EQ(2u, symbols.size());
ASSERT_EQ(1u, symbols.size());
EXPECT_EQ(0, linkerInput.getExportedFunctionsSegmentId());
}
@@ -928,7 +928,7 @@ TEST(LinkerInputTests, GivenNoKernelNameToIdWhenDecodingGlobalFunctionThenExport
EXPECT_EQ(-1, linkerInput.getExportedFunctionsSegmentId());
}
TEST(LinkerInputTests, GivenGlobalElfSymbolOfNoTypeWhenDecodingThenSymbolWithUnknownSegmentIsAddedAndDebugBreakCalled) {
TEST(LinkerInputTests, GivenGlobalElfSymbolOfNoTypeWhenDecodingThenDebugBreakCalled) {
NEO::LinkerInput linkerInput = {};
NEO::Elf::ElfFileHeader<NEO::Elf::EI_CLASS_64> header;
MockElf<NEO::Elf::EI_CLASS_64> elf64;
@@ -960,8 +960,7 @@ TEST(LinkerInputTests, GivenGlobalElfSymbolOfNoTypeWhenDecodingThenSymbolWithUnk
linkerInput.decodeElfSymbolTableAndRelocations(elf64, nameToKernelId);
auto symbols = linkerInput.getSymbols();
ASSERT_EQ(1u, symbols.size());
EXPECT_EQ(SegmentType::Unknown, symbols.begin()->second.segment);
ASSERT_EQ(0u, symbols.size());
EXPECT_FALSE(linkerInput.getTraits().exportsGlobalVariables);
EXPECT_FALSE(linkerInput.getTraits().exportsGlobalConstants);