Decode zebin reloc types

Change LinkerInput::RelocationInfo::Type to be compliant with zebin
relocation types.
Add support for setting relocation type if zebin relocation
type is set.
Continue supporting R_AMD64_64 and R_AMD64_32 relocation types for
backward compatibility

Signed-off-by: Krystian Chmielewski <krystian.chmielewski@intel.com>
This commit is contained in:
Krystian Chmielewski
2021-07-15 12:03:00 +00:00
committed by Compute-Runtime-Automation
parent 3c88492229
commit 9c7d8a183b
4 changed files with 87 additions and 3 deletions

View File

@@ -171,7 +171,11 @@ void LinkerInput::decodeElfSymbolTableAndRelocations(Elf::Elf<Elf::EI_CLASS_64>
break;
case uint32_t(Elf::RELOCATION_X8664_TYPE::R_X8664_32):
relocationInfo.type = NEO::LinkerInput::RelocationInfo::Type::AddressLow;
default:
break;
default: // Zebin relocation type
relocationInfo.type = reloc.relocType < uint32_t(NEO::LinkerInput::RelocationInfo::Type::RelocTypeMax)
? static_cast<NEO::LinkerInput::RelocationInfo::Type>(reloc.relocType)
: NEO::LinkerInput::RelocationInfo::Type::Unknown;
break;
}
auto name = elf.getSectionName(reloc.targetSectionIndex);

View File

@@ -78,9 +78,10 @@ struct LinkerInput {
enum class Type : uint32_t {
Unknown,
Address,
AddressHigh,
AddressLow,
PerThreadPayloadOffset
AddressHigh,
PerThreadPayloadOffset,
RelocTypeMax
};
std::string symbolName;

View File

@@ -30,6 +30,14 @@ enum SHT_ZEBIN : uint32_t {
SHT_ZEBIN_GTPIN_INFO = 0xff000012 // .gtpin_info section
};
enum RELOC_TYPE_ZEBIN : uint32_t {
R_ZE_NONE,
R_ZE_SYM_ADDR,
R_ZE_SYM_ADDR_32,
R_ZE_SYM_ADDR_32_HI,
R_PER_THREAD_PAYLOAD_OFFSET
};
namespace SectionsNamesZebin {
static constexpr ConstStringRef textPrefix = ".text.";
static constexpr ConstStringRef dataConst = ".data.const";

View File

@@ -469,6 +469,77 @@ TEST(LinkerInputTests, GivenInvalidTextSectionNameWhenDecodingElfTextRelocations
ASSERT_EQ(0u, relocations.size());
}
TEST(LinkerInputTests, GivenValidZebinRelocationTypesWhenDecodingElfTextRelocationsThenCorrectTypeIsSet) {
NEO::LinkerInput linkerInput = {};
NEO::Elf::ElfFileHeader<NEO::Elf::EI_CLASS_64> header;
MockElf<NEO::Elf::EI_CLASS_64> elf64;
elf64.elfFileHeader = &header;
std::unordered_map<uint32_t, std::string> sectionNames;
sectionNames[0] = ".text.abc";
sectionNames[1] = ".data.const";
elf64.setupSecionNames(std::move(sectionNames));
NEO::Elf::Elf<NEO::Elf::EI_CLASS_64>::RelocationInfo reloc1;
reloc1.offset = 0;
reloc1.relocType = NEO::Elf::RELOC_TYPE_ZEBIN::R_ZE_NONE;
reloc1.symbolName = "symbol1";
reloc1.symbolSectionIndex = 1;
reloc1.symbolTableIndex = 0;
reloc1.targetSectionIndex = 0;
elf64.relocations.emplace_back(reloc1);
NEO::Elf::Elf<NEO::Elf::EI_CLASS_64>::RelocationInfo reloc2;
reloc2.offset = 0;
reloc2.relocType = NEO::Elf::RELOC_TYPE_ZEBIN::R_ZE_SYM_ADDR;
reloc2.symbolName = "symbol2";
reloc2.symbolSectionIndex = 1;
reloc2.symbolTableIndex = 0;
reloc2.targetSectionIndex = 0;
elf64.relocations.emplace_back(reloc2);
NEO::Elf::Elf<NEO::Elf::EI_CLASS_64>::RelocationInfo reloc3;
reloc3.offset = 0;
reloc3.relocType = NEO::Elf::RELOC_TYPE_ZEBIN::R_ZE_SYM_ADDR_32;
reloc3.symbolName = "symbol3";
reloc3.symbolSectionIndex = 1;
reloc3.symbolTableIndex = 0;
reloc3.targetSectionIndex = 0;
elf64.relocations.emplace_back(reloc3);
NEO::Elf::Elf<NEO::Elf::EI_CLASS_64>::RelocationInfo reloc4;
reloc4.offset = 0;
reloc4.relocType = NEO::Elf::RELOC_TYPE_ZEBIN::R_ZE_SYM_ADDR_32_HI;
reloc4.symbolName = "symbol4";
reloc4.symbolSectionIndex = 1;
reloc4.symbolTableIndex = 0;
reloc4.targetSectionIndex = 0;
elf64.relocations.emplace_back(reloc4);
NEO::Elf::Elf<NEO::Elf::EI_CLASS_64>::RelocationInfo reloc5;
reloc5.offset = 0;
reloc5.relocType = NEO::Elf::RELOC_TYPE_ZEBIN::R_PER_THREAD_PAYLOAD_OFFSET;
reloc5.symbolName = "symbol5";
reloc5.symbolSectionIndex = 1;
reloc5.symbolTableIndex = 0;
reloc5.targetSectionIndex = 0;
elf64.relocations.emplace_back(reloc5);
NEO::LinkerInput::SectionNameToSegmentIdMap nameToKernelId;
nameToKernelId["abc"] = 0;
linkerInput.decodeElfSymbolTableAndRelocations(elf64, nameToKernelId);
auto relocations = linkerInput.getRelocationsInInstructionSegments();
ASSERT_EQ(1u, relocations.size());
ASSERT_EQ(5u, relocations[0].size());
EXPECT_EQ(NEO::LinkerInput::RelocationInfo::Type::Unknown, relocations[0][0].type);
EXPECT_EQ(NEO::LinkerInput::RelocationInfo::Type::Address, relocations[0][1].type);
EXPECT_EQ(NEO::LinkerInput::RelocationInfo::Type::AddressLow, relocations[0][2].type);
EXPECT_EQ(NEO::LinkerInput::RelocationInfo::Type::AddressHigh, relocations[0][3].type);
EXPECT_EQ(NEO::LinkerInput::RelocationInfo::Type::PerThreadPayloadOffset, relocations[0][4].type);
}
TEST(LinkerInputTests, GivenInvalidRelocationTypeWhenDecodingElfTextRelocationsThenUnknownTypeIsSet) {
NEO::LinkerInput linkerInput = {};
NEO::Elf::ElfFileHeader<NEO::Elf::EI_CLASS_64> header;