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:
parent
7cd4ca5ce7
commit
6023a5b58e
|
@ -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});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue