Skip to content

Commit e1758a2

Browse files
Register ELF for every kernel allocation for zebin format
- every isa allocation will have ELF linked - fix for debug elf from patchtoken binary: pass relocated ELF when exists - simplify code Related-To: NEO-5571 Signed-off-by: Mateusz Hoppe <[email protected]>
1 parent d49c5d6 commit e1758a2

File tree

5 files changed

+89
-14
lines changed

5 files changed

+89
-14
lines changed

level_zero/core/source/kernel/kernel_imp.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,10 @@ void KernelImmutableData::initialize(NEO::KernelInfo *kernelInfo, Device *device
110110

111111
isaGraphicsAllocation.reset(allocation);
112112

113+
if (neoDevice->getDebugger() && kernelInfo->kernelDescriptor.external.debugData.get()) {
114+
createRelocatedDebugData(globalConstBuffer, globalVarBuffer);
115+
}
116+
113117
this->crossThreadDataSize = this->kernelDescriptor->kernelAttributes.crossThreadDataSize;
114118

115119
ArrayRef<uint8_t> crossThredDataArrayRef;
@@ -193,6 +197,8 @@ void KernelImmutableData::createRelocatedDebugData(NEO::GraphicsAllocation *glob
193197
outErrReason, outWarning);
194198

195199
if (decodedElf.getDebugInfoRelocations().size() > 1) {
200+
UNRECOVERABLE_IF(kernelInfo->kernelDescriptor.external.relocatedDebugData.get() != nullptr);
201+
196202
auto size = kernelInfo->kernelDescriptor.external.debugData->vIsaSize;
197203
kernelInfo->kernelDescriptor.external.relocatedDebugData = std::make_unique<uint8_t[]>(size);
198204

level_zero/core/source/module/module_imp.cpp

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ bool ModuleImp::initialize(const ze_module_desc_t *desc, NEO::Device *neoDevice)
536536
kernelImmDatas.push_back(std::move(kernelImmData));
537537
}
538538

539-
registerElfInDebuggerL0(neoDevice);
539+
registerElfInDebuggerL0();
540540
this->maxGroupSize = static_cast<uint32_t>(this->translationUnit->device->getNEODevice()->getDeviceInfo().maxWorkGroupSize);
541541

542542
checkIfPrivateMemoryPerDispatchIsNeeded();
@@ -992,28 +992,36 @@ ze_result_t ModuleImp::performDynamicLink(uint32_t numModules,
992992
return ZE_RESULT_SUCCESS;
993993
}
994994

995-
void ModuleImp::registerElfInDebuggerL0(NEO::Device *neoDevice) {
996-
if (neoDevice->getDebugger() == nullptr) {
995+
void ModuleImp::registerElfInDebuggerL0() {
996+
if (device->getL0Debugger() == nullptr) {
997997
return;
998998
}
999999

10001000
auto refBin = ArrayRef<const uint8_t>(reinterpret_cast<const uint8_t *>(translationUnit->unpackedDeviceBinary.get()), translationUnit->unpackedDeviceBinarySize);
10011001
if (NEO::isDeviceBinaryFormat<NEO::DeviceBinaryFormat::Zebin>(refBin)) {
10021002
size_t debugDataSize = 0;
10031003
getDebugInfo(&debugDataSize, nullptr);
1004-
if (device->getL0Debugger()) {
1005-
NEO::DebugData debugData; // pass debug zebin in vIsa field
1006-
debugData.vIsa = reinterpret_cast<const char *>(translationUnit->debugData.get());
1007-
debugData.vIsaSize = static_cast<uint32_t>(translationUnit->debugDataSize);
1008-
device->getL0Debugger()->registerElf(&debugData, kernelImmDatas[0]->getIsaGraphicsAllocation());
1004+
1005+
NEO::DebugData debugData; // pass debug zebin in vIsa field
1006+
debugData.vIsa = reinterpret_cast<const char *>(translationUnit->debugData.get());
1007+
debugData.vIsaSize = static_cast<uint32_t>(translationUnit->debugDataSize);
1008+
for (auto &kernImmData : kernelImmDatas) {
1009+
device->getL0Debugger()->registerElf(&debugData, kernImmData->getIsaGraphicsAllocation());
10091010
}
10101011
} else {
10111012
for (auto &kernImmData : kernelImmDatas) {
10121013
if (kernImmData->getKernelInfo()->kernelDescriptor.external.debugData.get()) {
1013-
kernImmData->createRelocatedDebugData(translationUnit->globalConstBuffer, translationUnit->globalVarBuffer);
1014-
if (device->getL0Debugger()) {
1015-
device->getL0Debugger()->registerElf(kernImmData->getKernelInfo()->kernelDescriptor.external.debugData.get(), kernImmData->getIsaGraphicsAllocation());
1014+
NEO::DebugData *notifyDebugData = kernImmData->getKernelInfo()->kernelDescriptor.external.debugData.get();
1015+
NEO::DebugData relocatedDebugData;
1016+
1017+
if (kernImmData->getKernelInfo()->kernelDescriptor.external.relocatedDebugData.get()) {
1018+
relocatedDebugData.genIsa = kernImmData->getKernelInfo()->kernelDescriptor.external.debugData->genIsa;
1019+
relocatedDebugData.genIsaSize = kernImmData->getKernelInfo()->kernelDescriptor.external.debugData->genIsaSize;
1020+
relocatedDebugData.vIsa = reinterpret_cast<char *>(kernImmData->getKernelInfo()->kernelDescriptor.external.relocatedDebugData.get());
1021+
relocatedDebugData.vIsaSize = kernImmData->getKernelInfo()->kernelDescriptor.external.debugData->vIsaSize;
1022+
notifyDebugData = &relocatedDebugData;
10161023
}
1024+
device->getL0Debugger()->registerElf(notifyDebugData, kernImmData->getIsaGraphicsAllocation());
10171025
}
10181026
}
10191027
}

level_zero/core/source/module/module_imp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ struct ModuleImp : public Module {
141141
NEO::Debug::Segments getZebinSegments();
142142
void passDebugData();
143143
void createDebugZebin();
144-
void registerElfInDebuggerL0(NEO::Device *neoDevice);
144+
void registerElfInDebuggerL0();
145145

146146
Device *device = nullptr;
147147
PRODUCT_FAMILY productFamily{};

level_zero/core/test/unit_tests/mocks/mock_l0_debugger.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
*/
77

88
#pragma once
9+
#include "shared/source/kernel/debug_data.h"
10+
911
#include "level_zero/core/source/debugger/debugger_l0.h"
1012
#include "level_zero/core/test/unit_tests/white_box.h"
1113

@@ -43,13 +45,15 @@ class MockDebuggerL0Hw : public L0::DebuggerL0Hw<GfxFamily> {
4345

4446
void registerElf(NEO::DebugData *debugData, NEO::GraphicsAllocation *isaAllocation) override {
4547
registerElfCount++;
48+
lastReceivedElf = debugData->vIsa;
4649
L0::DebuggerL0Hw<GfxFamily>::registerElf(debugData, isaAllocation);
4750
}
4851

4952
uint32_t captureStateBaseAddressCount = 0;
5053
uint32_t programSbaTrackingCommandsCount = 0;
5154
uint32_t getSbaTrackingCommandsSizeCount = 0;
5255
uint32_t registerElfCount = 0;
56+
const char *lastReceivedElf = nullptr;
5357
};
5458

5559
template <uint32_t productFamily, typename GfxFamily>

level_zero/core/test/unit_tests/sources/debugger/test_module_with_debug.cpp

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ TEST_F(KernelInitializeTest, givenDebuggingEnabledWhenKernelsAreInitializedThenA
416416
EXPECT_THAT(isa, testing::Not(MemCompare(&kernelHeap, sizeof(kernelHeap))));
417417
};
418418

419-
HWTEST_F(ModuleWithDebuggerL0Test, GivenDebugDataWhenInitializingModuleThenRegisterElf) {
419+
HWTEST_F(ModuleWithDebuggerL0Test, GivenDebugDataWithRelocationsWhenInitializingModuleThenRegisterElfWithRelocatedElf) {
420420
NEO::MockCompilerEnableGuard mock(true);
421421
auto cip = new NEO::MockCompilerInterfaceCaptureBuildOptions();
422422
neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[device->getRootDeviceIndex()]->compilerInterface.reset(cip);
@@ -455,6 +455,59 @@ HWTEST_F(ModuleWithDebuggerL0Test, GivenDebugDataWhenInitializingModuleThenRegis
455455
EXPECT_EQ(0u, getMockDebuggerL0Hw<FamilyType>()->registerElfCount);
456456
EXPECT_TRUE(moduleMock->initialize(&moduleDesc, neoDevice));
457457
EXPECT_EQ(1u, getMockDebuggerL0Hw<FamilyType>()->registerElfCount);
458+
459+
EXPECT_NE(nullptr, kernelInfo->kernelDescriptor.external.relocatedDebugData.get());
460+
EXPECT_EQ(reinterpret_cast<char *>(kernelInfo->kernelDescriptor.external.relocatedDebugData.get()), getMockDebuggerL0Hw<FamilyType>()->lastReceivedElf);
461+
}
462+
463+
HWTEST_F(ModuleWithDebuggerL0Test, GivenDebugDataWithoutRelocationsWhenInitializingModuleThenRegisterElfWithUnrelocatedElf) {
464+
NEO::MockCompilerEnableGuard mock(true);
465+
auto cip = new NEO::MockCompilerInterfaceCaptureBuildOptions();
466+
neoDevice->getExecutionEnvironment()->rootDeviceEnvironments[device->getRootDeviceIndex()]->compilerInterface.reset(cip);
467+
468+
uint8_t binary[10];
469+
ze_module_desc_t moduleDesc = {};
470+
moduleDesc.format = ZE_MODULE_FORMAT_IL_SPIRV;
471+
moduleDesc.pInputModule = binary;
472+
moduleDesc.inputSize = 10;
473+
ModuleBuildLog *moduleBuildLog = nullptr;
474+
475+
std::unique_ptr<MockModule> moduleMock = std::make_unique<MockModule>(device, moduleBuildLog, ModuleType::User);
476+
moduleMock->translationUnit = std::make_unique<MockModuleTranslationUnit>(device);
477+
478+
uint32_t kernelHeap = 0;
479+
auto kernelInfo = new KernelInfo();
480+
kernelInfo->heapInfo.KernelHeapSize = 1;
481+
kernelInfo->heapInfo.pKernelHeap = &kernelHeap;
482+
483+
Mock<::L0::Kernel> kernelMock;
484+
kernelMock.module = moduleMock.get();
485+
kernelMock.immutableData.kernelInfo = kernelInfo;
486+
kernelInfo->kernelDescriptor.payloadMappings.implicitArgs.systemThreadSurfaceAddress.bindful = 0;
487+
488+
moduleMock->kernelImmData = &kernelMock.immutableData;
489+
moduleMock->translationUnit->programInfo.kernelInfos.push_back(kernelInfo);
490+
491+
kernelInfo->kernelDescriptor.external.debugData = std::make_unique<NEO::DebugData>();
492+
493+
std::vector<uint8_t> data;
494+
data.resize(4);
495+
NEO::Elf::ElfEncoder<> elfEncoder;
496+
elfEncoder.getElfFileHeader().type = NEO::Elf::SHT_PROGBITS;
497+
elfEncoder.appendSection(NEO::Elf::SHT_PROGBITS, NEO::Elf::SectionsNamesZebin::textPrefix, data);
498+
auto elfBinary = elfEncoder.encode();
499+
500+
kernelInfo->kernelDescriptor.external.debugData->vIsaSize = static_cast<uint32_t>(elfBinary.size());
501+
kernelInfo->kernelDescriptor.external.debugData->vIsa = reinterpret_cast<char *>(elfBinary.data());
502+
kernelInfo->kernelDescriptor.external.debugData->genIsa = nullptr;
503+
kernelInfo->kernelDescriptor.external.debugData->genIsaSize = 0;
504+
505+
EXPECT_EQ(0u, getMockDebuggerL0Hw<FamilyType>()->registerElfCount);
506+
EXPECT_TRUE(moduleMock->initialize(&moduleDesc, neoDevice));
507+
EXPECT_EQ(1u, getMockDebuggerL0Hw<FamilyType>()->registerElfCount);
508+
509+
EXPECT_EQ(nullptr, kernelInfo->kernelDescriptor.external.relocatedDebugData.get());
510+
EXPECT_EQ(kernelInfo->kernelDescriptor.external.debugData->vIsa, getMockDebuggerL0Hw<FamilyType>()->lastReceivedElf);
458511
}
459512

460513
HWTEST_F(ModuleWithDebuggerL0Test, GivenNoDebugDataWhenInitializingModuleThenDoNotRegisterElf) {
@@ -513,6 +566,10 @@ HWTEST_F(ModuleWithZebinAndL0DebuggerTest, GivenZebinDebugDataWhenInitializingMo
513566
moduleMock->translationUnit = std::make_unique<MockModuleTranslationUnit>(device);
514567
moduleMock->kernelImmDatas.push_back(std::move(kernelImmutableData));
515568

569+
kernelImmutableData = ::std::make_unique<KernelImmutableData>(device);
570+
kernelImmutableData->initialize(kernelInfo.get(), device, 0, nullptr, nullptr, false);
571+
moduleMock->kernelImmDatas.push_back(std::move(kernelImmutableData));
572+
516573
auto zebin = ZebinTestData::ValidEmptyProgram();
517574
moduleMock->translationUnit = std::make_unique<MockModuleTranslationUnit>(device);
518575
moduleMock->translationUnit->unpackedDeviceBinarySize = zebin.storage.size();
@@ -521,7 +578,7 @@ HWTEST_F(ModuleWithZebinAndL0DebuggerTest, GivenZebinDebugDataWhenInitializingMo
521578
zebin.storage.data(), zebin.storage.size());
522579
EXPECT_EQ(0u, getMockDebuggerL0Hw<FamilyType>()->registerElfCount);
523580
EXPECT_TRUE(moduleMock->initialize(&moduleDesc, neoDevice));
524-
EXPECT_EQ(1u, getMockDebuggerL0Hw<FamilyType>()->registerElfCount);
581+
EXPECT_EQ(2u, getMockDebuggerL0Hw<FamilyType>()->registerElfCount);
525582
}
526583

527584
HWTEST_F(ModuleWithZebinAndL0DebuggerTest, GivenZebinNoDebugDataWhenInitializingModuleThenDoNotRegisterElf) {

0 commit comments

Comments
 (0)