mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-08 14:02:58 +08:00
Zebin: Use strings section for printf
Resolves: NEO-6143 Signed-off-by: Krystian Chmielewski <krystian.chmielewski@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
5d1c3c98a4
commit
06eaef0352
@@ -635,6 +635,7 @@ bool ModuleImp::linkBinary() {
|
||||
Linker::SegmentInfo globals;
|
||||
Linker::SegmentInfo constants;
|
||||
Linker::SegmentInfo exportedFunctions;
|
||||
Linker::SegmentInfo strings;
|
||||
GraphicsAllocation *globalsForPatching = translationUnit->globalVarBuffer;
|
||||
GraphicsAllocation *constantsForPatching = translationUnit->globalConstBuffer;
|
||||
if (globalsForPatching != nullptr) {
|
||||
@@ -645,6 +646,10 @@ bool ModuleImp::linkBinary() {
|
||||
constants.gpuAddress = static_cast<uintptr_t>(constantsForPatching->getGpuAddress());
|
||||
constants.segmentSize = constantsForPatching->getUnderlyingBufferSize();
|
||||
}
|
||||
if (translationUnit->programInfo.globalStrings.initData != nullptr) {
|
||||
strings.gpuAddress = reinterpret_cast<uintptr_t>(translationUnit->programInfo.globalStrings.initData);
|
||||
strings.segmentSize = translationUnit->programInfo.globalStrings.size;
|
||||
}
|
||||
if (linkerInput->getExportedFunctionsSegmentId() >= 0) {
|
||||
auto exportedFunctionHeapId = linkerInput->getExportedFunctionsSegmentId();
|
||||
this->exportedFunctionsSurface = this->kernelImmDatas[exportedFunctionHeapId]->getIsaGraphicsAllocation();
|
||||
@@ -663,7 +668,7 @@ bool ModuleImp::linkBinary() {
|
||||
}
|
||||
}
|
||||
|
||||
auto linkStatus = linker.link(globals, constants, exportedFunctions,
|
||||
auto linkStatus = linker.link(globals, constants, exportedFunctions, strings,
|
||||
globalsForPatching, constantsForPatching,
|
||||
isaSegmentsForPatching, unresolvedExternalsInfo, this->device->getNEODevice(),
|
||||
translationUnit->programInfo.globalConstants.initData,
|
||||
|
||||
@@ -1859,6 +1859,42 @@ TEST_F(ModuleTests, whenCopyingPatchedSegmentsThenAllocationsAreSetWritableForTb
|
||||
EXPECT_TRUE(allocation->isAubWritable(std::numeric_limits<uint32_t>::max()));
|
||||
}
|
||||
|
||||
TEST_F(ModuleTests, givenConstDataStringSectionWhenLinkingModuleThenSegmentIsPatched) {
|
||||
auto pModule = std::make_unique<Module>(device, nullptr, ModuleType::User);
|
||||
|
||||
char data[64]{};
|
||||
auto kernelInfo = new KernelInfo();
|
||||
kernelInfo->heapInfo.KernelHeapSize = 64;
|
||||
kernelInfo->heapInfo.pKernelHeap = data;
|
||||
|
||||
std::unique_ptr<WhiteBox<::L0::KernelImmutableData>> kernelImmData{new WhiteBox<::L0::KernelImmutableData>(this->device)};
|
||||
kernelImmData->initialize(kernelInfo, device, 0, nullptr, nullptr, false);
|
||||
auto patchAddr = reinterpret_cast<uintptr_t>(ptrOffset(kernelImmData->isaGraphicsAllocation->getUnderlyingBuffer(), 0x8));
|
||||
pModule->kernelImmDatas.push_back(std::move(kernelImmData));
|
||||
pModule->translationUnit->programInfo.kernelInfos.push_back(kernelInfo);
|
||||
|
||||
auto linkerInput = std::make_unique<::WhiteBox<NEO::LinkerInput>>();
|
||||
linkerInput->relocations.push_back({{".str", 0x8, LinkerInput::RelocationInfo::Type::Address, SegmentType::Instructions}});
|
||||
linkerInput->symbols.insert({".str", {0x0, 0x8, SegmentType::GlobalStrings}});
|
||||
linkerInput->traits.requiresPatchingOfInstructionSegments = true;
|
||||
pModule->translationUnit->programInfo.linkerInput = std::move(linkerInput);
|
||||
|
||||
const char constStringData[] = "Hello World!\n";
|
||||
auto stringsAddr = reinterpret_cast<uintptr_t>(constStringData);
|
||||
pModule->translationUnit->programInfo.globalStrings.initData = constStringData;
|
||||
pModule->translationUnit->programInfo.globalStrings.size = sizeof(constStringData);
|
||||
|
||||
auto status = pModule->linkBinary();
|
||||
EXPECT_TRUE(status);
|
||||
|
||||
constexpr bool is64Bit = sizeof(void *) == 8;
|
||||
if (is64Bit) {
|
||||
EXPECT_EQ(static_cast<uint64_t>(stringsAddr), *reinterpret_cast<uint64_t *>(patchAddr));
|
||||
} else {
|
||||
EXPECT_EQ(static_cast<uint32_t>(stringsAddr), *reinterpret_cast<uint32_t *>(patchAddr));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ModuleTests, givenImplicitArgsRelocationWhenLinkingModuleThenSegmentIsPatchedAndImplicitArgsAreRequired) {
|
||||
auto pModule = std::make_unique<Module>(device, nullptr, ModuleType::User);
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ const KernelInfo *Program::getKernelInfo(size_t ordinal, uint32_t rootDeviceInde
|
||||
return kernelInfoArray[ordinal];
|
||||
}
|
||||
|
||||
cl_int Program::linkBinary(Device *pDevice, const void *constantsInitData, const void *variablesInitData) {
|
||||
cl_int Program::linkBinary(Device *pDevice, const void *constantsInitData, const void *variablesInitData, const ProgramInfo::GlobalSurfaceInfo &stringsInfo) {
|
||||
auto linkerInput = getLinkerInput(pDevice->getRootDeviceIndex());
|
||||
if (linkerInput == nullptr) {
|
||||
return CL_SUCCESS;
|
||||
@@ -65,6 +65,7 @@ cl_int Program::linkBinary(Device *pDevice, const void *constantsInitData, const
|
||||
Linker::SegmentInfo globals;
|
||||
Linker::SegmentInfo constants;
|
||||
Linker::SegmentInfo exportedFunctions;
|
||||
Linker::SegmentInfo strings;
|
||||
GraphicsAllocation *globalsForPatching = getGlobalSurface(rootDeviceIndex);
|
||||
GraphicsAllocation *constantsForPatching = getConstantSurface(rootDeviceIndex);
|
||||
if (globalsForPatching != nullptr) {
|
||||
@@ -75,6 +76,10 @@ cl_int Program::linkBinary(Device *pDevice, const void *constantsInitData, const
|
||||
constants.gpuAddress = static_cast<uintptr_t>(constantsForPatching->getGpuAddress());
|
||||
constants.segmentSize = constantsForPatching->getUnderlyingBufferSize();
|
||||
}
|
||||
if (stringsInfo.initData != nullptr) {
|
||||
strings.gpuAddress = reinterpret_cast<uintptr_t>(stringsInfo.initData);
|
||||
strings.segmentSize = stringsInfo.size;
|
||||
}
|
||||
if (linkerInput->getExportedFunctionsSegmentId() >= 0) {
|
||||
// Exported functions reside in instruction heap of one of kernels
|
||||
auto exportedFunctionHeapId = linkerInput->getExportedFunctionsSegmentId();
|
||||
@@ -95,7 +100,7 @@ cl_int Program::linkBinary(Device *pDevice, const void *constantsInitData, const
|
||||
}
|
||||
|
||||
Linker::UnresolvedExternals unresolvedExternalsInfo;
|
||||
bool linkSuccess = LinkingStatus::LinkedFully == linker.link(globals, constants, exportedFunctions,
|
||||
bool linkSuccess = LinkingStatus::LinkedFully == linker.link(globals, constants, exportedFunctions, strings,
|
||||
globalsForPatching, constantsForPatching,
|
||||
isaSegmentsForPatching, unresolvedExternalsInfo,
|
||||
pDevice, constantsInitData, variablesInitData);
|
||||
@@ -236,7 +241,7 @@ cl_int Program::processProgramInfo(ProgramInfo &src, const ClDevice &clDevice) {
|
||||
kernelInfo->apply(deviceInfoConstants);
|
||||
}
|
||||
|
||||
return linkBinary(&clDevice.getDevice(), src.globalConstants.initData, src.globalVariables.initData);
|
||||
return linkBinary(&clDevice.getDevice(), src.globalConstants.initData, src.globalVariables.initData, src.globalStrings);
|
||||
}
|
||||
|
||||
void Program::processDebugData(uint32_t rootDeviceIndex) {
|
||||
|
||||
@@ -287,7 +287,7 @@ class Program : public BaseObject<_cl_program> {
|
||||
|
||||
cl_int packDeviceBinary(ClDevice &clDevice);
|
||||
|
||||
MOCKABLE_VIRTUAL cl_int linkBinary(Device *pDevice, const void *constantsInitData, const void *variablesInitData);
|
||||
MOCKABLE_VIRTUAL cl_int linkBinary(Device *pDevice, const void *constantsInitData, const void *variablesInitData, const ProgramInfo::GlobalSurfaceInfo &stringInfo);
|
||||
|
||||
void separateBlockKernels(uint32_t rootDeviceIndex);
|
||||
|
||||
|
||||
@@ -1878,7 +1878,7 @@ HWTEST_TEMPLATED_F(BlitCopyTests, givenKernelAllocationInLocalMemoryWithoutCpuAc
|
||||
|
||||
auto initialTaskCount = bcsMockContext->bcsCsr->peekTaskCount();
|
||||
|
||||
auto ret = program.linkBinary(&device->getDevice(), nullptr, nullptr);
|
||||
auto ret = program.linkBinary(&device->getDevice(), nullptr, nullptr, {});
|
||||
EXPECT_EQ(CL_SUCCESS, ret);
|
||||
|
||||
EXPECT_EQ(initialTaskCount + 1, bcsMockContext->bcsCsr->peekTaskCount());
|
||||
|
||||
@@ -487,7 +487,7 @@ TEST_F(ProgramDataTest, GivenProgramWith32bitPointerOptWhenProgramScopeConstantB
|
||||
programInfo.globalConstants.initData = constantSurface.mockGfxAllocation.getUnderlyingBuffer();
|
||||
|
||||
pProgram->setLinkerInput(pClDevice->getRootDeviceIndex(), std::move(programInfo.linkerInput));
|
||||
pProgram->linkBinary(&pClDevice->getDevice(), programInfo.globalConstants.initData, programInfo.globalVariables.initData);
|
||||
pProgram->linkBinary(&pClDevice->getDevice(), programInfo.globalConstants.initData, programInfo.globalVariables.initData, {});
|
||||
uint32_t expectedAddr = static_cast<uint32_t>(constantSurface.getGraphicsAllocation(pClDevice->getRootDeviceIndex())->getGpuAddressToPatch());
|
||||
EXPECT_EQ(expectedAddr, constantSurfaceStorage[0]);
|
||||
EXPECT_EQ(sentinel, constantSurfaceStorage[1]);
|
||||
@@ -533,7 +533,7 @@ TEST_F(ProgramDataTest, GivenProgramWith32bitPointerOptWhenProgramScopeGlobalPoi
|
||||
programInfo.globalVariables.initData = globalSurface.mockGfxAllocation.getUnderlyingBuffer();
|
||||
|
||||
pProgram->setLinkerInput(pClDevice->getRootDeviceIndex(), std::move(programInfo.linkerInput));
|
||||
pProgram->linkBinary(&pClDevice->getDevice(), programInfo.globalConstants.initData, programInfo.globalVariables.initData);
|
||||
pProgram->linkBinary(&pClDevice->getDevice(), programInfo.globalConstants.initData, programInfo.globalVariables.initData, {});
|
||||
uint32_t expectedAddr = static_cast<uint32_t>(globalSurface.getGraphicsAllocation(pClDevice->getRootDeviceIndex())->getGpuAddressToPatch());
|
||||
EXPECT_EQ(expectedAddr, globalSurfaceStorage[0]);
|
||||
EXPECT_EQ(sentinel, globalSurfaceStorage[1]);
|
||||
@@ -560,7 +560,7 @@ TEST(ProgramLinkBinaryTest, whenLinkerInputEmptyThenLinkSuccessful) {
|
||||
auto device = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get()));
|
||||
MockProgram program{nullptr, false, toClDeviceVector(*device)};
|
||||
program.setLinkerInput(device->getRootDeviceIndex(), std::move(linkerInput));
|
||||
auto ret = program.linkBinary(&device->getDevice(), nullptr, nullptr);
|
||||
auto ret = program.linkBinary(&device->getDevice(), nullptr, nullptr, {});
|
||||
EXPECT_EQ(CL_SUCCESS, ret);
|
||||
}
|
||||
|
||||
@@ -585,7 +585,7 @@ TEST(ProgramLinkBinaryTest, whenLinkerUnresolvedExternalThenLinkFailedAndBuildLo
|
||||
|
||||
std::string buildLog = program.getBuildLog(device->getRootDeviceIndex());
|
||||
EXPECT_TRUE(buildLog.empty());
|
||||
auto ret = program.linkBinary(&device->getDevice(), nullptr, nullptr);
|
||||
auto ret = program.linkBinary(&device->getDevice(), nullptr, nullptr, {});
|
||||
EXPECT_NE(CL_SUCCESS, ret);
|
||||
program.getKernelInfoArray(rootDeviceIndex).clear();
|
||||
buildLog = program.getBuildLog(rootDeviceIndex);
|
||||
@@ -632,7 +632,7 @@ TEST_F(ProgramDataTest, whenLinkerInputValidThenIsaIsProperlyPatched) {
|
||||
buildInfo.globalSurface = new MockGraphicsAllocation(globalVariablesBuffer.data(), globalVariablesBuffer.size());
|
||||
buildInfo.constantSurface = new MockGraphicsAllocation(globalConstantsBuffer.data(), globalConstantsBuffer.size());
|
||||
|
||||
auto ret = program.linkBinary(&pClDevice->getDevice(), globalConstantsInitData.data(), globalVariablesInitData.data());
|
||||
auto ret = program.linkBinary(&pClDevice->getDevice(), globalConstantsInitData.data(), globalVariablesInitData.data(), {});
|
||||
EXPECT_EQ(CL_SUCCESS, ret);
|
||||
|
||||
linkerInput.reset(static_cast<WhiteBox<LinkerInput> *>(buildInfo.linkerInput.release()));
|
||||
@@ -680,7 +680,7 @@ TEST_F(ProgramDataTest, whenRelocationsAreNotNeededThenIsaIsPreserved) {
|
||||
buildInfo.globalSurface = new MockGraphicsAllocation(globalVariablesBuffer.data(), globalVariablesBuffer.size());
|
||||
buildInfo.constantSurface = new MockGraphicsAllocation(globalConstantsBuffer.data(), globalConstantsBuffer.size());
|
||||
|
||||
auto ret = program.linkBinary(&pClDevice->getDevice(), globalConstantsInitData.data(), globalVariablesInitData.data());
|
||||
auto ret = program.linkBinary(&pClDevice->getDevice(), globalConstantsInitData.data(), globalVariablesInitData.data(), {});
|
||||
EXPECT_EQ(CL_SUCCESS, ret);
|
||||
EXPECT_EQ(kernelHeapData, kernelHeap);
|
||||
|
||||
@@ -691,6 +691,49 @@ TEST_F(ProgramDataTest, whenRelocationsAreNotNeededThenIsaIsPreserved) {
|
||||
buildInfo.constantSurface = nullptr;
|
||||
}
|
||||
|
||||
TEST(ProgramStringSectionTest, WhenConstStringBufferIsPresentThenUseItForLinking) {
|
||||
auto device = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get()));
|
||||
auto rootDeviceIndex = device->getRootDeviceIndex();
|
||||
|
||||
MockProgram program{nullptr, false, toClDeviceVector(*device)};
|
||||
|
||||
uint8_t kernelHeapData[64] = {};
|
||||
MockGraphicsAllocation kernelIsa(kernelHeapData, 64);
|
||||
|
||||
KernelInfo kernelInfo = {};
|
||||
kernelInfo.kernelDescriptor.kernelMetadata.kernelName = "onlyKernel";
|
||||
kernelInfo.heapInfo.pKernelHeap = kernelHeapData;
|
||||
kernelInfo.heapInfo.KernelHeapSize = 64;
|
||||
kernelInfo.kernelAllocation = &kernelIsa;
|
||||
|
||||
program.getKernelInfoArray(rootDeviceIndex).push_back(&kernelInfo);
|
||||
|
||||
auto linkerInput = std::make_unique<WhiteBox<LinkerInput>>();
|
||||
linkerInput->relocations.push_back({{".str", 0x8, LinkerInput::RelocationInfo::Type::Address, SegmentType::Instructions}});
|
||||
linkerInput->symbols.insert({".str", {0x0, 0x8, SegmentType::GlobalStrings}});
|
||||
linkerInput->traits.requiresPatchingOfInstructionSegments = true;
|
||||
|
||||
program.setLinkerInput(rootDeviceIndex, std::move(linkerInput));
|
||||
|
||||
auto isaCpuPtr = reinterpret_cast<char *>(kernelInfo.getGraphicsAllocation()->getUnderlyingBuffer());
|
||||
auto patchAddr = ptrOffset(isaCpuPtr, 0x8);
|
||||
|
||||
const char constStringData[] = "Hello World!\n";
|
||||
auto stringsAddr = reinterpret_cast<uintptr_t>(constStringData);
|
||||
|
||||
auto ret = program.linkBinary(&device->getDevice(), nullptr, nullptr, {constStringData, sizeof(constStringData)});
|
||||
EXPECT_EQ(CL_SUCCESS, ret);
|
||||
|
||||
constexpr bool is64Bit = sizeof(void *) == 8;
|
||||
if (is64Bit) {
|
||||
EXPECT_EQ(static_cast<uint64_t>(stringsAddr), *reinterpret_cast<uint64_t *>(patchAddr));
|
||||
} else {
|
||||
EXPECT_EQ(static_cast<uint32_t>(stringsAddr), *reinterpret_cast<uint32_t *>(patchAddr));
|
||||
}
|
||||
|
||||
program.getKernelInfoArray(rootDeviceIndex).clear();
|
||||
}
|
||||
|
||||
TEST(ProgramImplicitArgsTest, whenImplicitRelocationIsPresentThenKernelRequiresImplicitArgs) {
|
||||
auto device = std::make_unique<MockClDevice>(MockDevice::createWithNewExecutionEnvironment<MockDevice>(defaultHwInfo.get()));
|
||||
auto rootDeviceIndex = device->getRootDeviceIndex();
|
||||
@@ -708,7 +751,7 @@ TEST(ProgramImplicitArgsTest, whenImplicitRelocationIsPresentThenKernelRequiresI
|
||||
linkerInput->relocations.push_back({{implicitArgsRelocationSymbolName, 0x8, LinkerInput::RelocationInfo::Type::AddressLow, SegmentType::Instructions}});
|
||||
linkerInput->traits.requiresPatchingOfInstructionSegments = true;
|
||||
program.setLinkerInput(rootDeviceIndex, std::move(linkerInput));
|
||||
auto ret = program.linkBinary(&device->getDevice(), nullptr, nullptr);
|
||||
auto ret = program.linkBinary(&device->getDevice(), nullptr, nullptr, {});
|
||||
EXPECT_EQ(CL_SUCCESS, ret);
|
||||
|
||||
EXPECT_TRUE(kernelInfo.kernelDescriptor.kernelAttributes.flags.requiresImplicitArgs);
|
||||
|
||||
@@ -29,6 +29,8 @@ SegmentType LinkerInput::getSegmentForSection(ConstStringRef name) {
|
||||
return NEO::SegmentType::GlobalConstants;
|
||||
} else if (name == NEO::Elf::SectionsNamesZebin::dataGlobal) {
|
||||
return NEO::SegmentType::GlobalVariables;
|
||||
} else if (name == NEO::Elf::SectionsNamesZebin::dataConstString) {
|
||||
return NEO::SegmentType::GlobalStrings;
|
||||
} else if (name.startsWith(NEO::Elf::SpecialSectionNames::text.data())) {
|
||||
return NEO::SegmentType::Instructions;
|
||||
}
|
||||
@@ -243,7 +245,7 @@ void LinkerInput::decodeElfSymbolTableAndRelocations(Elf::Elf<Elf::EI_CLASS_64>
|
||||
}
|
||||
}
|
||||
|
||||
bool Linker::processRelocations(const SegmentInfo &globalVariables, const SegmentInfo &globalConstants, const SegmentInfo &exportedFunctions) {
|
||||
bool Linker::processRelocations(const SegmentInfo &globalVariables, const SegmentInfo &globalConstants, const SegmentInfo &exportedFunctions, const SegmentInfo &globalStrings) {
|
||||
relocatedSymbols.reserve(data.getSymbols().size());
|
||||
for (auto &symbol : data.getSymbols()) {
|
||||
const SegmentInfo *seg = nullptr;
|
||||
@@ -257,6 +259,9 @@ bool Linker::processRelocations(const SegmentInfo &globalVariables, const Segmen
|
||||
case SegmentType::GlobalConstants:
|
||||
seg = &globalConstants;
|
||||
break;
|
||||
case SegmentType::GlobalStrings:
|
||||
seg = &globalStrings;
|
||||
break;
|
||||
case SegmentType::Instructions:
|
||||
seg = &exportedFunctions;
|
||||
break;
|
||||
|
||||
@@ -23,6 +23,7 @@ class GraphicsAllocation;
|
||||
enum class SegmentType : uint32_t {
|
||||
Unknown,
|
||||
GlobalConstants,
|
||||
GlobalStrings,
|
||||
GlobalVariables,
|
||||
Instructions,
|
||||
};
|
||||
@@ -182,12 +183,12 @@ struct Linker {
|
||||
: data(data) {
|
||||
}
|
||||
|
||||
LinkingStatus link(const SegmentInfo &globalVariablesSegInfo, const SegmentInfo &globalConstantsSegInfo, const SegmentInfo &exportedFunctionsSegInfo,
|
||||
LinkingStatus link(const SegmentInfo &globalVariablesSegInfo, const SegmentInfo &globalConstantsSegInfo, const SegmentInfo &exportedFunctionsSegInfo, const SegmentInfo &globalStringsSegInfo,
|
||||
GraphicsAllocation *globalVariablesSeg, GraphicsAllocation *globalConstantsSeg, const PatchableSegments &instructionsSegments,
|
||||
UnresolvedExternals &outUnresolvedExternals, Device *pDevice, const void *constantsInitData, const void *variablesInitData) {
|
||||
bool success = data.isValid();
|
||||
auto initialUnresolvedExternalsCount = outUnresolvedExternals.size();
|
||||
success = success && processRelocations(globalVariablesSegInfo, globalConstantsSegInfo, exportedFunctionsSegInfo);
|
||||
success = success && processRelocations(globalVariablesSegInfo, globalConstantsSegInfo, exportedFunctionsSegInfo, globalStringsSegInfo);
|
||||
if (!success) {
|
||||
return LinkingStatus::Error;
|
||||
}
|
||||
@@ -214,7 +215,7 @@ struct Linker {
|
||||
const LinkerInput &data;
|
||||
RelocatedSymbolsMap relocatedSymbols;
|
||||
|
||||
bool processRelocations(const SegmentInfo &globalVariables, const SegmentInfo &globalConstants, const SegmentInfo &exportedFunctions);
|
||||
bool processRelocations(const SegmentInfo &globalVariables, const SegmentInfo &globalConstants, const SegmentInfo &exportedFunctions, const SegmentInfo &globalStrings);
|
||||
|
||||
void patchInstructionsSegments(const std::vector<PatchableSegment> &instructionsSegments, std::vector<UnresolvedExternal> &outUnresolvedExternals);
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ static constexpr ConstStringRef textPrefix = ".text.";
|
||||
static constexpr ConstStringRef dataConst = ".data.const";
|
||||
static constexpr ConstStringRef dataGlobalConst = ".data.global_const";
|
||||
static constexpr ConstStringRef dataGlobal = ".data.global";
|
||||
static constexpr ConstStringRef dataConstString = ".data.const.string";
|
||||
static constexpr ConstStringRef symtab = ".symtab";
|
||||
static constexpr ConstStringRef relTablePrefix = ".rel.";
|
||||
static constexpr ConstStringRef spv = ".spv";
|
||||
|
||||
@@ -98,6 +98,8 @@ DecodeError extractZebinSections(NEO::Elf::Elf<Elf::EI_CLASS_64> &elf, ZebinSect
|
||||
out.constDataSections.push_back(&elfSectionHeader);
|
||||
} else if (sectionName == NEO::Elf::SectionsNamesZebin::dataGlobal) {
|
||||
out.globalDataSections.push_back(&elfSectionHeader);
|
||||
} else if (sectionName == NEO::Elf::SectionsNamesZebin::dataConstString) {
|
||||
out.constDataStringSections.push_back(&elfSectionHeader);
|
||||
} else if (sectionName.startsWith(NEO::Elf::SectionsNamesZebin::debugPrefix.data())) {
|
||||
// ignoring intentionally
|
||||
} else {
|
||||
@@ -164,6 +166,7 @@ DecodeError validateZebinSectionsCount(const ZebinSections §ions, std::strin
|
||||
bool valid = validateZebinSectionsCountAtMost(sections.zeInfoSections, NEO::Elf::SectionsNamesZebin::zeInfo, 1U, outErrReason, outWarning);
|
||||
valid &= validateZebinSectionsCountAtMost(sections.globalDataSections, NEO::Elf::SectionsNamesZebin::dataGlobal, 1U, outErrReason, outWarning);
|
||||
valid &= validateZebinSectionsCountAtMost(sections.constDataSections, NEO::Elf::SectionsNamesZebin::dataConst, 1U, outErrReason, outWarning);
|
||||
valid &= validateZebinSectionsCountAtMost(sections.constDataStringSections, NEO::Elf::SectionsNamesZebin::dataConstString, 1U, outErrReason, outWarning);
|
||||
valid &= validateZebinSectionsCountAtMost(sections.symtabSections, NEO::Elf::SectionsNamesZebin::symtab, 1U, outErrReason, outWarning);
|
||||
valid &= validateZebinSectionsCountAtMost(sections.spirvSections, NEO::Elf::SectionsNamesZebin::spv, 1U, outErrReason, outWarning);
|
||||
valid &= validateZebinSectionsCountAtMost(sections.noteIntelGTSections, NEO::Elf::SectionsNamesZebin::noteIntelGT, 1U, outErrReason, outWarning);
|
||||
@@ -1214,6 +1217,11 @@ DecodeError decodeSingleDeviceBinary<NEO::DeviceBinaryFormat::Zebin>(ProgramInfo
|
||||
dst.globalConstants.size = zebinSections.constDataSections[0]->data.size();
|
||||
}
|
||||
|
||||
if (false == zebinSections.constDataStringSections.empty()) {
|
||||
dst.globalStrings.initData = zebinSections.constDataStringSections[0]->data.begin();
|
||||
dst.globalStrings.size = zebinSections.constDataStringSections[0]->data.size();
|
||||
}
|
||||
|
||||
if (false == zebinSections.symtabSections.empty()) {
|
||||
outWarning.append("DeviceBinaryFormat::Zebin : Ignoring symbol table\n");
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ struct ZebinSections {
|
||||
StackVec<SectionHeaderData *, 1> zeInfoSections;
|
||||
StackVec<SectionHeaderData *, 1> globalDataSections;
|
||||
StackVec<SectionHeaderData *, 1> constDataSections;
|
||||
StackVec<SectionHeaderData *, 1> constDataStringSections;
|
||||
StackVec<SectionHeaderData *, 1> symtabSections;
|
||||
StackVec<SectionHeaderData *, 1> spirvSections;
|
||||
StackVec<SectionHeaderData *, 1> noteIntelGTSections;
|
||||
|
||||
@@ -37,6 +37,7 @@ struct ProgramInfo {
|
||||
|
||||
GlobalSurfaceInfo globalConstants;
|
||||
GlobalSurfaceInfo globalVariables;
|
||||
GlobalSurfaceInfo globalStrings;
|
||||
std::unique_ptr<LinkerInput> linkerInput;
|
||||
|
||||
std::vector<KernelInfo *> kernelInfos;
|
||||
|
||||
@@ -294,12 +294,14 @@ TEST(LinkerInputTests, WhenGettingSegmentForSectionNameThenCorrectSegmentIsRetur
|
||||
auto segmentConst = NEO::LinkerInput::getSegmentForSection(NEO::Elf::SectionsNamesZebin::dataConst.str());
|
||||
auto segmentGlobalConst = NEO::LinkerInput::getSegmentForSection(NEO::Elf::SectionsNamesZebin::dataGlobalConst.str());
|
||||
auto segmentGlobal = NEO::LinkerInput::getSegmentForSection(NEO::Elf::SectionsNamesZebin::dataGlobal.str());
|
||||
auto segmentConstString = NEO::LinkerInput::getSegmentForSection(NEO::Elf::SectionsNamesZebin::dataConstString.str());
|
||||
auto segmentInstructions = NEO::LinkerInput::getSegmentForSection(NEO::Elf::SectionsNamesZebin::textPrefix.str());
|
||||
auto segmentInstructions2 = NEO::LinkerInput::getSegmentForSection(".text.abc");
|
||||
|
||||
EXPECT_EQ(NEO::SegmentType::GlobalConstants, segmentConst);
|
||||
EXPECT_EQ(NEO::SegmentType::GlobalConstants, segmentGlobalConst);
|
||||
EXPECT_EQ(NEO::SegmentType::GlobalVariables, segmentGlobal);
|
||||
EXPECT_EQ(NEO::SegmentType::GlobalStrings, segmentConstString);
|
||||
EXPECT_EQ(NEO::SegmentType::Instructions, segmentInstructions);
|
||||
EXPECT_EQ(NEO::SegmentType::Instructions, segmentInstructions2);
|
||||
}
|
||||
@@ -972,9 +974,10 @@ TEST(LinkerTests, givenEmptyLinkerInputThenLinkerOutputIsEmpty) {
|
||||
NEO::GraphicsAllocation *patchableConstVarSeg = nullptr;
|
||||
NEO::Linker::PatchableSegments patchableInstructionSegments;
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
auto linkResult = linker.link(globalVar, globalConst, exportedFunc,
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals, nullptr, nullptr, nullptr);
|
||||
auto linkResult = linker.link(
|
||||
globalVar, globalConst, exportedFunc, {},
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals, nullptr, nullptr, nullptr);
|
||||
EXPECT_EQ(NEO::LinkingStatus::LinkedFully, linkResult);
|
||||
EXPECT_EQ(0U, unresolvedExternals.size());
|
||||
auto relocatedSymbols = linker.extractRelocatedSymbols();
|
||||
@@ -990,9 +993,10 @@ TEST(LinkerTests, givenInvalidLinkerInputThenLinkerFails) {
|
||||
NEO::GraphicsAllocation *patchableConstVarSeg = nullptr;
|
||||
NEO::Linker::PatchableSegments patchableInstructionSegments;
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
auto linkResult = linker.link(globalVar, globalConst, exportedFunc,
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals, nullptr, nullptr, nullptr);
|
||||
auto linkResult = linker.link(
|
||||
globalVar, globalConst, exportedFunc, {},
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals, nullptr, nullptr, nullptr);
|
||||
EXPECT_EQ(NEO::LinkingStatus::Error, linkResult);
|
||||
}
|
||||
|
||||
@@ -1018,9 +1022,10 @@ TEST(LinkerTests, givenUnresolvedExternalWhenPatchingInstructionsThenLinkPartial
|
||||
NEO::GraphicsAllocation *patchableConstVarSeg = nullptr;
|
||||
NEO::Linker::PatchableSegments patchableInstructionSegments{seg0};
|
||||
|
||||
auto linkResult = linker.link(globalVar, globalConst, exportedFunc,
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals, nullptr, nullptr, nullptr);
|
||||
auto linkResult = linker.link(
|
||||
globalVar, globalConst, exportedFunc, {},
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals, nullptr, nullptr, nullptr);
|
||||
EXPECT_EQ(NEO::LinkingStatus::LinkedPartially, linkResult);
|
||||
auto relocatedSymbols = linker.extractRelocatedSymbols();
|
||||
EXPECT_EQ(0U, relocatedSymbols.size());
|
||||
@@ -1112,9 +1117,10 @@ TEST(LinkerTests, givenValidSymbolsAndRelocationsThenInstructionSegmentsArePrope
|
||||
NEO::GraphicsAllocation *patchableGlobalVarSeg = nullptr;
|
||||
NEO::GraphicsAllocation *patchableConstVarSeg = nullptr;
|
||||
|
||||
auto linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, unresolvedExternals,
|
||||
nullptr, nullptr, nullptr);
|
||||
auto linkResult = linker.link(
|
||||
globalVarSegment, globalConstSegment, exportedFuncSegment, {},
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, unresolvedExternals,
|
||||
nullptr, nullptr, nullptr);
|
||||
EXPECT_EQ(NEO::LinkingStatus::LinkedFully, linkResult);
|
||||
auto relocatedSymbols = linker.extractRelocatedSymbols();
|
||||
EXPECT_EQ(0U, unresolvedExternals.size());
|
||||
@@ -1170,18 +1176,20 @@ TEST(LinkerTests, givenInvalidSymbolOffsetWhenPatchingInstructionsThenRelocation
|
||||
NEO::GraphicsAllocation *patchableGlobalVarSeg = nullptr;
|
||||
NEO::GraphicsAllocation *patchableConstVarSeg = nullptr;
|
||||
|
||||
auto linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals, nullptr, nullptr, nullptr);
|
||||
auto linkResult = linker.link(
|
||||
globalVarSegment, globalConstSegment, exportedFuncSegment, {},
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals, nullptr, nullptr, nullptr);
|
||||
EXPECT_EQ(NEO::LinkingStatus::Error, linkResult);
|
||||
auto relocatedSymbols = linker.extractRelocatedSymbols();
|
||||
EXPECT_EQ(0U, unresolvedExternals.size());
|
||||
EXPECT_EQ(0U, relocatedSymbols.size());
|
||||
|
||||
globalVarSegment.segmentSize = symGlobalVariable.s_offset + symGlobalVariable.s_size;
|
||||
linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, unresolvedExternals,
|
||||
nullptr, nullptr, nullptr);
|
||||
linkResult = linker.link(
|
||||
globalVarSegment, globalConstSegment, exportedFuncSegment, {},
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, unresolvedExternals,
|
||||
nullptr, nullptr, nullptr);
|
||||
EXPECT_EQ(NEO::LinkingStatus::LinkedFully, linkResult);
|
||||
}
|
||||
|
||||
@@ -1218,9 +1226,10 @@ TEST(LinkerTests, givenInvalidRelocationOffsetThenPatchingOfInstructionsFails) {
|
||||
NEO::GraphicsAllocation *patchableGlobalVarSeg = nullptr;
|
||||
NEO::GraphicsAllocation *patchableConstVarSeg = nullptr;
|
||||
|
||||
auto linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals, nullptr, nullptr, nullptr);
|
||||
auto linkResult = linker.link(
|
||||
globalVarSegment, globalConstSegment, exportedFuncSegment, {},
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals, nullptr, nullptr, nullptr);
|
||||
EXPECT_EQ(NEO::LinkingStatus::LinkedPartially, linkResult);
|
||||
auto relocatedSymbols = linker.extractRelocatedSymbols();
|
||||
EXPECT_EQ(1U, relocatedSymbols.size());
|
||||
@@ -1228,9 +1237,10 @@ TEST(LinkerTests, givenInvalidRelocationOffsetThenPatchingOfInstructionsFails) {
|
||||
EXPECT_TRUE(unresolvedExternals[0].internalError);
|
||||
|
||||
patchableInstructionSegments[0].segmentSize = relocA.r_offset + sizeof(uintptr_t);
|
||||
linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals, nullptr, nullptr, nullptr);
|
||||
linkResult = linker.link(
|
||||
globalVarSegment, globalConstSegment, exportedFuncSegment, {},
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals, nullptr, nullptr, nullptr);
|
||||
EXPECT_EQ(NEO::LinkingStatus::LinkedFully, linkResult);
|
||||
}
|
||||
|
||||
@@ -1269,21 +1279,71 @@ TEST(LinkerTests, givenUnknownSymbolTypeWhenPatchingInstructionsThenRelocationFa
|
||||
|
||||
ASSERT_EQ(1U, linkerInput.symbols.count("A"));
|
||||
linkerInput.symbols["A"].segment = NEO::SegmentType::Unknown;
|
||||
auto linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals, nullptr, nullptr, nullptr);
|
||||
auto linkResult = linker.link(
|
||||
globalVarSegment, globalConstSegment, exportedFuncSegment, {},
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals, nullptr, nullptr, nullptr);
|
||||
EXPECT_EQ(NEO::LinkingStatus::Error, linkResult);
|
||||
auto relocatedSymbols = linker.extractRelocatedSymbols();
|
||||
EXPECT_EQ(0U, relocatedSymbols.size());
|
||||
ASSERT_EQ(0U, unresolvedExternals.size());
|
||||
|
||||
linkerInput.symbols["A"].segment = NEO::SegmentType::GlobalVariables;
|
||||
linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
|
||||
linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment, {},
|
||||
patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments,
|
||||
unresolvedExternals, nullptr, nullptr, nullptr);
|
||||
EXPECT_EQ(NEO::LinkingStatus::LinkedFully, linkResult);
|
||||
}
|
||||
|
||||
TEST(LinkerTests, givenValidStringSymbolsAndRelocationsWhenPatchingThenItIsProperlyPatched) {
|
||||
NEO::Linker::SegmentInfo stringSegment;
|
||||
stringSegment.gpuAddress = 0x1234;
|
||||
stringSegment.segmentSize = 0x10;
|
||||
|
||||
uint8_t instructionSegment[32] = {};
|
||||
NEO::Linker::PatchableSegment seg0;
|
||||
seg0.hostPointer = instructionSegment;
|
||||
seg0.segmentSize = sizeof(instructionSegment);
|
||||
NEO::Linker::PatchableSegments patchableInstructionSegments{seg0};
|
||||
|
||||
WhiteBox<NEO::LinkerInput> linkerInput;
|
||||
|
||||
SymbolInfo strSymbol;
|
||||
strSymbol.segment = SegmentType::GlobalStrings;
|
||||
strSymbol.offset = 0U;
|
||||
strSymbol.size = 8U;
|
||||
linkerInput.symbols.insert({".str", strSymbol});
|
||||
|
||||
NEO::LinkerInput::RelocationInfo relocation;
|
||||
relocation.offset = 0x8U;
|
||||
relocation.relocationSegment = NEO::SegmentType::Instructions;
|
||||
relocation.symbolName = ".str";
|
||||
relocation.type = NEO::LinkerInput::RelocationInfo::Type::Address;
|
||||
linkerInput.relocations.push_back({relocation});
|
||||
|
||||
linkerInput.traits.requiresPatchingOfInstructionSegments = true;
|
||||
|
||||
NEO::Linker linker(linkerInput);
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
auto linkResult = linker.link(
|
||||
{}, {}, {}, stringSegment,
|
||||
nullptr, nullptr, patchableInstructionSegments, unresolvedExternals,
|
||||
nullptr, nullptr, nullptr);
|
||||
EXPECT_EQ(NEO::LinkingStatus::LinkedFully, linkResult);
|
||||
EXPECT_EQ(0U, unresolvedExternals.size());
|
||||
EXPECT_EQ(1U, linker.extractRelocatedSymbols().size());
|
||||
|
||||
uintptr_t strAddr = stringSegment.gpuAddress + strSymbol.offset;
|
||||
uintptr_t patchAddr = reinterpret_cast<uintptr_t>(instructionSegment) + static_cast<uintptr_t>(relocation.offset);
|
||||
|
||||
constexpr bool is64Bit = sizeof(void *) == 8;
|
||||
if (is64Bit) {
|
||||
EXPECT_EQ(static_cast<uint64_t>(strAddr), *reinterpret_cast<const uint64_t *>(patchAddr));
|
||||
} else {
|
||||
EXPECT_EQ(static_cast<uint32_t>(strAddr), *reinterpret_cast<const uint32_t *>(patchAddr));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(LinkerTests, givenValidSymbolsAndRelocationsWhenPatchingDataSegmentsThenTheyAreProperlyPatched) {
|
||||
uint64_t initGlobalConstantData[3];
|
||||
initGlobalConstantData[0] = 0x10; // var1 address will be added here
|
||||
@@ -1420,7 +1480,7 @@ TEST(LinkerTests, givenValidSymbolsAndRelocationsWhenPatchingDataSegmentsThenThe
|
||||
NEO::Linker linker(linkerInput);
|
||||
auto device = std::unique_ptr<NEO::MockDevice>(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(NEO::defaultHwInfo.get()));
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
auto linkResult = linker.link(globalVariablesSegmentInfo, globalConstantsSegmentInfo, exportedFunctionsSegmentInfo,
|
||||
auto linkResult = linker.link(globalVariablesSegmentInfo, globalConstantsSegmentInfo, exportedFunctionsSegmentInfo, {},
|
||||
&globalVariablesPatchableSegment, &globalConstantsPatchableSegment, {},
|
||||
unresolvedExternals, device.get(), initGlobalConstantData, initGlobalVariablesData);
|
||||
EXPECT_EQ(NEO::LinkingStatus::LinkedFully, linkResult);
|
||||
@@ -1477,7 +1537,7 @@ TEST(LinkerTests, givenInvalidSymbolWhenPatchingDataSegmentsThenRelocationIsUnre
|
||||
NEO::Linker linker(linkerInput);
|
||||
auto device = std::unique_ptr<NEO::MockDevice>(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(NEO::defaultHwInfo.get()));
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
auto linkResult = linker.link(globalVariablesSegmentInfo, globalConstantsSegmentInfo, {},
|
||||
auto linkResult = linker.link(globalVariablesSegmentInfo, globalConstantsSegmentInfo, {}, {},
|
||||
&globalVariablesPatchableSegment, &globalConstantsPatchableSegment, {},
|
||||
unresolvedExternals, device.get(), initGlobalConstantData, initGlobalVariablesData);
|
||||
EXPECT_EQ(NEO::LinkingStatus::LinkedPartially, linkResult);
|
||||
@@ -1514,7 +1574,7 @@ TEST(LinkerTests, givenInvalidRelocationOffsetWhenPatchingDataSegmentsThenReloca
|
||||
NEO::Linker linker(linkerInput);
|
||||
auto device = std::unique_ptr<NEO::MockDevice>(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(NEO::defaultHwInfo.get()));
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
auto linkResult = linker.link(globalVariablesSegmentInfo, globalConstantsSegmentInfo, {},
|
||||
auto linkResult = linker.link(globalVariablesSegmentInfo, globalConstantsSegmentInfo, {}, {},
|
||||
&globalVariablesPatchableSegment, &globalConstantsPatchableSegment, {},
|
||||
unresolvedExternals, device.get(), initGlobalConstantData, initGlobalVariablesData);
|
||||
EXPECT_EQ(NEO::LinkingStatus::LinkedPartially, linkResult);
|
||||
@@ -1536,7 +1596,7 @@ TEST(LinkerTests, givenInvalidRelocationSegmentWhenPatchingDataSegmentsThenReloc
|
||||
NEO::Linker linker(linkerInput);
|
||||
auto device = std::unique_ptr<NEO::MockDevice>(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(NEO::defaultHwInfo.get()));
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
auto linkResult = linker.link({}, {}, {},
|
||||
auto linkResult = linker.link({}, {}, {}, {},
|
||||
nullptr, nullptr, {},
|
||||
unresolvedExternals, device.get(), nullptr, nullptr);
|
||||
EXPECT_EQ(NEO::LinkingStatus::LinkedPartially, linkResult);
|
||||
@@ -1574,7 +1634,7 @@ TEST(LinkerTests, given32BitBinaryWithValidSymbolsAndRelocationsWhenPatchingData
|
||||
NEO::Linker linker(linkerInput);
|
||||
auto device = std::unique_ptr<NEO::MockDevice>(NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(NEO::defaultHwInfo.get()));
|
||||
NEO::Linker::UnresolvedExternals unresolvedExternals;
|
||||
auto linkResult = linker.link(globalVariablesSegmentInfo, globalConstantsSegmentInfo, {},
|
||||
auto linkResult = linker.link(globalVariablesSegmentInfo, globalConstantsSegmentInfo, {}, {},
|
||||
&globalVariablesPatchableSegment, &globalConstantsPatchableSegment, {},
|
||||
unresolvedExternals, device.get(), initGlobalConstantData, initGlobalVariablesData);
|
||||
EXPECT_EQ(NEO::LinkingStatus::LinkedFully, linkResult);
|
||||
@@ -1862,7 +1922,7 @@ TEST(LinkerTests, givenImplicitArgRelocationThenPatchRelocationWithSizeOfImplici
|
||||
seg0.segmentSize = instructionSegment.size();
|
||||
NEO::Linker::PatchableSegments patchableInstructionSegments{seg0};
|
||||
|
||||
auto linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment,
|
||||
auto linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment, {},
|
||||
nullptr, nullptr, patchableInstructionSegments, unresolvedExternals,
|
||||
nullptr, nullptr, nullptr);
|
||||
EXPECT_EQ(NEO::LinkingStatus::LinkedFully, linkResult);
|
||||
|
||||
@@ -86,6 +86,7 @@ TEST(ExtractZebinSections, GivenKnownSectionsThenCapturesThemProperly) {
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Elf::SectionsNamesZebin::textPrefix.str() + "someOtherKernel", std::string{});
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Elf::SectionsNamesZebin::dataConst, std::string{});
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Elf::SectionsNamesZebin::dataGlobal, std::string{});
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Elf::SectionsNamesZebin::dataConstString, std::string{});
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Elf::SectionsNamesZebin::debugInfo, std::string{});
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Elf::SectionsNamesZebin::debugAbbrev, std::string{});
|
||||
elfEncoder.appendSection(NEO::Elf::SHT_SYMTAB, NEO::Elf::SectionsNamesZebin::symtab, std::string{});
|
||||
@@ -112,6 +113,7 @@ TEST(ExtractZebinSections, GivenKnownSectionsThenCapturesThemProperly) {
|
||||
ASSERT_EQ(2U, sections.textKernelSections.size());
|
||||
ASSERT_EQ(1U, sections.globalDataSections.size());
|
||||
ASSERT_EQ(1U, sections.constDataSections.size());
|
||||
ASSERT_EQ(1U, sections.constDataStringSections.size());
|
||||
ASSERT_EQ(1U, sections.zeInfoSections.size());
|
||||
ASSERT_EQ(1U, sections.symtabSections.size());
|
||||
ASSERT_EQ(1U, sections.spirvSections.size());
|
||||
@@ -122,6 +124,7 @@ TEST(ExtractZebinSections, GivenKnownSectionsThenCapturesThemProperly) {
|
||||
EXPECT_STREQ((NEO::Elf::SectionsNamesZebin::textPrefix.str() + "someOtherKernel").c_str(), strings + sections.textKernelSections[1]->header->name);
|
||||
EXPECT_STREQ(NEO::Elf::SectionsNamesZebin::dataGlobal.data(), strings + sections.globalDataSections[0]->header->name);
|
||||
EXPECT_STREQ(NEO::Elf::SectionsNamesZebin::dataConst.data(), strings + sections.constDataSections[0]->header->name);
|
||||
EXPECT_STREQ(NEO::Elf::SectionsNamesZebin::dataConstString.data(), strings + sections.constDataStringSections[0]->header->name);
|
||||
EXPECT_STREQ(NEO::Elf::SectionsNamesZebin::zeInfo.data(), strings + sections.zeInfoSections[0]->header->name);
|
||||
EXPECT_STREQ(NEO::Elf::SectionsNamesZebin::symtab.data(), strings + sections.symtabSections[0]->header->name);
|
||||
EXPECT_STREQ(NEO::Elf::SectionsNamesZebin::spv.data(), strings + sections.spirvSections[0]->header->name);
|
||||
@@ -2210,6 +2213,26 @@ TEST(DecodeSingleDeviceBinaryZebin, GivenConstDataSectionThenSetsUpInitDataAndSi
|
||||
EXPECT_EQ(nullptr, programInfo.globalVariables.initData);
|
||||
}
|
||||
|
||||
TEST(DecodeSingleDeviceBinaryZebin, GivenConstDataStringsSectionThenSetsUpInitDataAndSize) {
|
||||
ZebinTestData::ValidEmptyProgram zebin;
|
||||
const uint8_t data[] = {'H', 'e', 'l', 'l', 'o', '!'};
|
||||
zebin.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Elf::SectionsNamesZebin::dataConstString, data);
|
||||
|
||||
NEO::ProgramInfo programInfo;
|
||||
NEO::SingleDeviceBinary singleBinary;
|
||||
singleBinary.deviceBinary = zebin.storage;
|
||||
std::string decodeErrors;
|
||||
std::string decodeWarnings;
|
||||
auto error = NEO::decodeSingleDeviceBinary<NEO::DeviceBinaryFormat::Zebin>(programInfo, singleBinary, decodeErrors, decodeWarnings);
|
||||
EXPECT_EQ(NEO::DecodeError::Success, error);
|
||||
EXPECT_TRUE(decodeWarnings.empty()) << decodeWarnings;
|
||||
EXPECT_TRUE(decodeErrors.empty()) << decodeErrors;
|
||||
EXPECT_EQ(sizeof(data), programInfo.globalStrings.size);
|
||||
EXPECT_NE(nullptr, programInfo.globalStrings.initData);
|
||||
EXPECT_EQ(sizeof(data), programInfo.globalStrings.size);
|
||||
EXPECT_EQ(0, memcmp(programInfo.globalStrings.initData, data, sizeof(data)));
|
||||
}
|
||||
|
||||
TEST(DecodeSingleDeviceBinaryZebin, GivenIntelGTNoteSectionThenAddsItToZebinSections) {
|
||||
ZebinTestData::ValidEmptyProgram zebin;
|
||||
NEO::Elf::IntelGTNote note = {};
|
||||
|
||||
Reference in New Issue
Block a user