From 38740c7b75fa245ef4d1dac0046b9db586154ab4 Mon Sep 17 00:00:00 2001 From: Filip Hazubski Date: Tue, 14 Jul 2020 16:44:28 +0200 Subject: [PATCH] Use blit when patching data segments with Linker Change-Id: I79e92add07f5bd7a68d4b03cf8069ed9c2cb907f Signed-off-by: Filip Hazubski --- level_zero/core/source/module/module_imp.cpp | 24 ++- .../source/program/process_device_binary.cpp | 27 ++- opencl/source/program/program.h | 2 +- .../unit_test/program/program_data_tests.cpp | 16 +- shared/source/compiler_interface/linker.cpp | 61 +++++-- shared/source/compiler_interface/linker.h | 15 +- shared/source/helpers/blit_commands_helper.h | 3 + .../compiler_interface/linker_tests.cpp | 164 ++++++++++-------- 8 files changed, 179 insertions(+), 133 deletions(-) diff --git a/level_zero/core/source/module/module_imp.cpp b/level_zero/core/source/module/module_imp.cpp index 23a5257fee..5a1414e578 100644 --- a/level_zero/core/source/module/module_imp.cpp +++ b/level_zero/core/source/module/module_imp.cpp @@ -410,19 +410,15 @@ bool ModuleImp::linkBinary() { Linker::SegmentInfo globals; Linker::SegmentInfo constants; Linker::SegmentInfo exportedFunctions; - Linker::PatchableSegment globalsForPatching; - Linker::PatchableSegment constantsForPatching; - if (translationUnit->globalVarBuffer != nullptr) { - globals.gpuAddress = static_cast(translationUnit->globalVarBuffer->getGpuAddress()); - globals.segmentSize = translationUnit->globalVarBuffer->getUnderlyingBufferSize(); - globalsForPatching.hostPointer = translationUnit->globalVarBuffer->getUnderlyingBuffer(); - globalsForPatching.segmentSize = translationUnit->globalVarBuffer->getUnderlyingBufferSize(); + GraphicsAllocation *globalsForPatching = translationUnit->globalVarBuffer; + GraphicsAllocation *constantsForPatching = translationUnit->globalConstBuffer; + if (globalsForPatching != nullptr) { + globals.gpuAddress = static_cast(globalsForPatching->getGpuAddress()); + globals.segmentSize = globalsForPatching->getUnderlyingBufferSize(); } - if (translationUnit->globalConstBuffer != nullptr) { - constants.gpuAddress = static_cast(translationUnit->globalConstBuffer->getGpuAddress()); - constants.segmentSize = translationUnit->globalConstBuffer->getUnderlyingBufferSize(); - constantsForPatching.hostPointer = translationUnit->globalConstBuffer->getUnderlyingBuffer(); - constantsForPatching.segmentSize = translationUnit->globalConstBuffer->getUnderlyingBufferSize(); + if (constantsForPatching != nullptr) { + constants.gpuAddress = static_cast(constantsForPatching->getGpuAddress()); + constants.segmentSize = constantsForPatching->getUnderlyingBufferSize(); } if (this->translationUnit->programInfo.linkerInput->getExportedFunctionsSegmentId() >= 0) { auto exportedFunctionHeapId = this->translationUnit->programInfo.linkerInput->getExportedFunctionsSegmentId(); @@ -445,7 +441,9 @@ bool ModuleImp::linkBinary() { Linker::UnresolvedExternals unresolvedExternalsInfo; bool linkSuccess = linker.link(globals, constants, exportedFunctions, globalsForPatching, constantsForPatching, - isaSegmentsForPatching, unresolvedExternalsInfo); + isaSegmentsForPatching, unresolvedExternalsInfo, this->device->getNEODevice(), + translationUnit->programInfo.globalConstants.initData, + translationUnit->programInfo.globalVariables.initData); this->symbols = linker.extractRelocatedSymbols(); if (false == linkSuccess) { std::vector kernelNames; diff --git a/opencl/source/program/process_device_binary.cpp b/opencl/source/program/process_device_binary.cpp index 4c58304780..6751b07255 100644 --- a/opencl/source/program/process_device_binary.cpp +++ b/opencl/source/program/process_device_binary.cpp @@ -51,7 +51,7 @@ const KernelInfo *Program::getKernelInfo(size_t ordinal) const { return kernelInfoArray[ordinal]; } -cl_int Program::linkBinary() { +cl_int Program::linkBinary(Device *pDevice, const void *constantsInitData, const void *variablesInitData) { if (linkerInput == nullptr) { return CL_SUCCESS; } @@ -59,19 +59,15 @@ cl_int Program::linkBinary() { Linker::SegmentInfo globals; Linker::SegmentInfo constants; Linker::SegmentInfo exportedFunctions; - Linker::PatchableSegment globalsForPatching; - Linker::PatchableSegment constantsForPatching; - if (this->globalSurface != nullptr) { - globals.gpuAddress = static_cast(this->globalSurface->getGpuAddress()); - globals.segmentSize = this->globalSurface->getUnderlyingBufferSize(); - globalsForPatching.hostPointer = this->globalSurface->getUnderlyingBuffer(); - globalsForPatching.segmentSize = this->globalSurface->getUnderlyingBufferSize(); + GraphicsAllocation *globalsForPatching = this->globalSurface; + GraphicsAllocation *constantsForPatching = this->constantSurface; + if (globalsForPatching != nullptr) { + globals.gpuAddress = static_cast(globalsForPatching->getGpuAddress()); + globals.segmentSize = globalsForPatching->getUnderlyingBufferSize(); } - if (this->constantSurface != nullptr) { - constants.gpuAddress = static_cast(this->constantSurface->getGpuAddress()); - constants.segmentSize = this->constantSurface->getUnderlyingBufferSize(); - constantsForPatching.hostPointer = this->constantSurface->getUnderlyingBuffer(); - constantsForPatching.segmentSize = this->constantSurface->getUnderlyingBufferSize(); + if (constantsForPatching != nullptr) { + constants.gpuAddress = static_cast(constantsForPatching->getGpuAddress()); + constants.segmentSize = constantsForPatching->getUnderlyingBufferSize(); } if (this->linkerInput->getExportedFunctionsSegmentId() >= 0) { // Exported functions reside in instruction heap of one of kernels @@ -95,7 +91,8 @@ cl_int Program::linkBinary() { Linker::UnresolvedExternals unresolvedExternalsInfo; bool linkSuccess = linker.link(globals, constants, exportedFunctions, globalsForPatching, constantsForPatching, - isaSegmentsForPatching, unresolvedExternalsInfo); + isaSegmentsForPatching, unresolvedExternalsInfo, + pDevice, constantsInitData, variablesInitData); this->symbols = linker.extractRelocatedSymbols(); if (false == linkSuccess) { std::vector kernelNames; @@ -212,7 +209,7 @@ cl_int Program::processProgramInfo(ProgramInfo &src) { kernelInfo->apply(deviceInfoConstants); } - return linkBinary(); + return linkBinary(this->pDevice, src.globalConstants.initData, src.globalVariables.initData); } void Program::processDebugData() { diff --git a/opencl/source/program/program.h b/opencl/source/program/program.h index 1fed0646f1..aed9f2f363 100644 --- a/opencl/source/program/program.h +++ b/opencl/source/program/program.h @@ -266,7 +266,7 @@ class Program : public BaseObject<_cl_program> { cl_int packDeviceBinary(); - MOCKABLE_VIRTUAL cl_int linkBinary(); + MOCKABLE_VIRTUAL cl_int linkBinary(Device *pDevice, const void *constantsInitData, const void *variablesInitData); void separateBlockKernels(); diff --git a/opencl/test/unit_test/program/program_data_tests.cpp b/opencl/test/unit_test/program/program_data_tests.cpp index 6381e64e8c..0adc60d0c2 100644 --- a/opencl/test/unit_test/program/program_data_tests.cpp +++ b/opencl/test/unit_test/program/program_data_tests.cpp @@ -470,7 +470,7 @@ TEST_F(ProgramDataTest, GivenProgramWith32bitPointerOptWhenProgramScopeConstantB constantSurfaceStorage[1] = sentinel; pProgram->linkerInput = std::move(programInfo.linkerInput); - pProgram->linkBinary(); + pProgram->linkBinary(pProgram->pDevice, programInfo.globalConstants.initData, programInfo.globalVariables.initData); uint32_t expectedAddr = static_cast(constantSurface.getGraphicsAllocation(pProgram->getDevice().getRootDeviceIndex())->getGpuAddressToPatch()); EXPECT_EQ(expectedAddr, constantSurfaceStorage[0]); EXPECT_EQ(sentinel, constantSurfaceStorage[1]); @@ -508,7 +508,7 @@ TEST_F(ProgramDataTest, GivenProgramWith32bitPointerOptWhenProgramScopeGlobalPoi globalSurfaceStorage[1] = sentinel; pProgram->linkerInput = std::move(programInfo.linkerInput); - pProgram->linkBinary(); + pProgram->linkBinary(pProgram->pDevice, programInfo.globalConstants.initData, programInfo.globalVariables.initData); uint32_t expectedAddr = static_cast(globalSurface.getGraphicsAllocation(pProgram->getDevice().getRootDeviceIndex())->getGpuAddressToPatch()); EXPECT_EQ(expectedAddr, globalSurfaceStorage[0]); EXPECT_EQ(sentinel, globalSurfaceStorage[1]); @@ -535,7 +535,7 @@ TEST(ProgramLinkBinaryTest, whenLinkerInputEmptyThenLinkSuccessful) { NEO::ExecutionEnvironment env; MockProgram program{env}; program.linkerInput = std::move(linkerInput); - auto ret = program.linkBinary(); + auto ret = program.linkBinary(program.pDevice, nullptr, nullptr); EXPECT_EQ(CL_SUCCESS, ret); } @@ -558,7 +558,7 @@ TEST(ProgramLinkBinaryTest, whenLinkerUnresolvedExternalThenLinkFailedAndBuildLo program.linkerInput = std::move(linkerInput); EXPECT_EQ(nullptr, program.getBuildLog(nullptr)); - auto ret = program.linkBinary(); + auto ret = program.linkBinary(program.pDevice, nullptr, nullptr); EXPECT_NE(CL_SUCCESS, ret); program.getKernelInfoArray().clear(); auto buildLog = program.getBuildLog(nullptr); @@ -599,12 +599,14 @@ TEST_F(ProgramDataTest, whenLinkerInputValidThenIsaIsProperlyPatched) { globalVariablesBuffer.resize(32, 7); std::vector globalConstantsBuffer; globalConstantsBuffer.resize(32, 7); + std::vector globalVariablesInitData{32, 0}; + std::vector globalConstantsInitData{32, 0}; program.globalSurface = new MockGraphicsAllocation(globalVariablesBuffer.data(), globalVariablesBuffer.size()); program.constantSurface = new MockGraphicsAllocation(globalConstantsBuffer.data(), globalConstantsBuffer.size()); program.pDevice = &this->pContext->getDevice(0)->getDevice(); - auto ret = program.linkBinary(); + auto ret = program.linkBinary(pProgram->pDevice, globalConstantsInitData.data(), globalVariablesInitData.data()); EXPECT_EQ(CL_SUCCESS, ret); linkerInput.reset(static_cast *>(program.linkerInput.release())); @@ -646,12 +648,14 @@ TEST_F(ProgramDataTest, whenRelocationsAreNotNeededThenIsaIsPreserved) { globalVariablesBuffer.resize(32, 7); std::vector globalConstantsBuffer; globalConstantsBuffer.resize(32, 7); + std::vector globalVariablesInitData{32, 0}; + std::vector globalConstantsInitData{32, 0}; program.globalSurface = new MockGraphicsAllocation(globalVariablesBuffer.data(), globalVariablesBuffer.size()); program.constantSurface = new MockGraphicsAllocation(globalConstantsBuffer.data(), globalConstantsBuffer.size()); program.pDevice = &this->pContext->getDevice(0)->getDevice(); - auto ret = program.linkBinary(); + auto ret = program.linkBinary(pProgram->pDevice, globalConstantsInitData.data(), globalVariablesInitData.data()); EXPECT_EQ(CL_SUCCESS, ret); EXPECT_EQ(kernelHeapData, kernelHeap); diff --git a/shared/source/compiler_interface/linker.cpp b/shared/source/compiler_interface/linker.cpp index 9520045e81..d4a04c4634 100644 --- a/shared/source/compiler_interface/linker.cpp +++ b/shared/source/compiler_interface/linker.cpp @@ -7,8 +7,13 @@ #include "linker.h" +#include "shared/source/device/device.h" +#include "shared/source/helpers/blit_commands_helper.h" #include "shared/source/helpers/debug_helpers.h" +#include "shared/source/helpers/hw_helper.h" #include "shared/source/helpers/ptr_math.h" +#include "shared/source/memory_manager/graphics_allocation.h" +#include "shared/source/memory_manager/memory_manager.h" #include "shared/source/utilities/compiler_support.h" #include "RelocationInfo.h" @@ -199,8 +204,9 @@ bool Linker::patchInstructionsSegments(const std::vector &inst } bool Linker::patchDataSegments(const SegmentInfo &globalVariablesSegInfo, const SegmentInfo &globalConstantsSegInfo, - PatchableSegment &globalVariablesSeg, PatchableSegment &globalConstantsSeg, - std::vector &outUnresolvedExternals) { + GraphicsAllocation *globalVariablesSeg, GraphicsAllocation *globalConstantsSeg, + std::vector &outUnresolvedExternals, Device *pDevice, + const void *constantsInitData, const void *variablesInitData) { if (false == (data.getTraits().requiresPatchingOfGlobalConstantsBuffer || data.getTraits().requiresPatchingOfGlobalVariablesBuffer)) { return true; } @@ -208,7 +214,8 @@ bool Linker::patchDataSegments(const SegmentInfo &globalVariablesSegInfo, const auto unresolvedExternalsPrev = outUnresolvedExternals.size(); for (const auto &relocation : data.getDataRelocations()) { const SegmentInfo *src = nullptr; - const PatchableSegment *dst = nullptr; + GraphicsAllocation *dst = nullptr; + const void *initData = nullptr; switch (relocation.symbolSegment) { default: outUnresolvedExternals.push_back(UnresolvedExternal{relocation}); @@ -225,14 +232,16 @@ bool Linker::patchDataSegments(const SegmentInfo &globalVariablesSegInfo, const outUnresolvedExternals.push_back(UnresolvedExternal{relocation}); continue; case SegmentType::GlobalVariables: - dst = &globalVariablesSeg; + dst = globalVariablesSeg; + initData = variablesInitData; break; case SegmentType::GlobalConstants: - dst = &globalConstantsSeg; + dst = globalConstantsSeg; + initData = constantsInitData; break; } - UNRECOVERABLE_IF(nullptr == dst->hostPointer); + UNRECOVERABLE_IF(nullptr == dst); if (RelocationInfo::Type::AddressHigh == relocation.type) { outUnresolvedExternals.push_back(UnresolvedExternal{relocation}); @@ -240,23 +249,43 @@ bool Linker::patchDataSegments(const SegmentInfo &globalVariablesSegInfo, const } auto relocType = (LinkerInput::Traits::PointerSize::Ptr32bit == data.getTraits().pointerSize) ? RelocationInfo::Type::AddressLow : relocation.type; - bool invalidOffset = relocation.offset + addressSizeInBytes(relocType) > dst->segmentSize; + bool invalidOffset = relocation.offset + addressSizeInBytes(relocType) > dst->getUnderlyingBufferSize(); DEBUG_BREAK_IF(invalidOffset); if (invalidOffset) { outUnresolvedExternals.push_back(UnresolvedExternal{relocation}); continue; } + UNRECOVERABLE_IF((RelocationInfo::Type::Address != relocType) && (RelocationInfo::Type::AddressLow != relocType)); uint64_t gpuAddressAs64bit = src->gpuAddress; - auto relocAddress = ptrOffset(dst->hostPointer, static_cast(relocation.offset)); - switch (relocType) { - default: - UNRECOVERABLE_IF(RelocationInfo::Type::Address != relocType); - patchIncrement(relocAddress, sizeof(uintptr_t), gpuAddressAs64bit); - break; - case RelocationInfo::Type::AddressLow: - patchIncrement(relocAddress, 4, static_cast(gpuAddressAs64bit & 0xffffffff)); - break; + uint32_t patchSize = (RelocationInfo::Type::AddressLow == relocType) ? 4 : sizeof(uintptr_t); + uint64_t incrementValue = (RelocationInfo::Type::AddressLow == relocType) + ? static_cast(gpuAddressAs64bit & 0xffffffff) + : gpuAddressAs64bit; + + bool useBlitter = false; + if (pDevice && initData) { + auto &hwInfo = pDevice->getHardwareInfo(); + auto &helper = HwHelper::get(hwInfo.platform.eRenderCoreFamily); + if (dst->isAllocatedInLocalMemoryPool() && helper.isBlitCopyRequiredForLocalMemory(hwInfo)) { + useBlitter = true; + } + } + + if (useBlitter) { + auto initValue = ptrOffset(initData, static_cast(relocation.offset)); + if (patchSize == sizeof(uint64_t)) { + uint64_t value = *reinterpret_cast(initValue) + incrementValue; + BlitHelperFunctions::blitMemoryToAllocation(*pDevice, dst, static_cast(relocation.offset), + &value, {sizeof(value), 1, 1}); + } else { + uint32_t value = *reinterpret_cast(initValue) + static_cast(incrementValue); + BlitHelperFunctions::blitMemoryToAllocation(*pDevice, dst, static_cast(relocation.offset), + &value, {sizeof(value), 1, 1}); + } + } else { + auto relocAddress = ptrOffset(dst->getUnderlyingBuffer(), static_cast(relocation.offset)); + patchIncrement(relocAddress, patchSize, incrementValue); } } return outUnresolvedExternals.size() == unresolvedExternalsPrev; diff --git a/shared/source/compiler_interface/linker.h b/shared/source/compiler_interface/linker.h index 8059ed63a5..ddb0b34d9d 100644 --- a/shared/source/compiler_interface/linker.h +++ b/shared/source/compiler_interface/linker.h @@ -16,6 +16,9 @@ namespace NEO { +class Device; +class GraphicsAllocation; + enum class SegmentType : uint32_t { Unknown, GlobalConstants, @@ -160,12 +163,13 @@ struct Linker { } bool link(const SegmentInfo &globalVariablesSegInfo, const SegmentInfo &globalConstantsSegInfo, const SegmentInfo &exportedFunctionsSegInfo, - PatchableSegment &globalVariablesSeg, PatchableSegment &globalConstantsSeg, const PatchableSegments &instructionsSegments, - UnresolvedExternals &outUnresolvedExternals) { + GraphicsAllocation *globalVariablesSeg, GraphicsAllocation *globalConstantsSeg, const PatchableSegments &instructionsSegments, + UnresolvedExternals &outUnresolvedExternals, Device *pDevice, const void *constantsInitData, const void *variablesInitData) { bool success = data.isValid(); success = success && processRelocations(globalVariablesSegInfo, globalConstantsSegInfo, exportedFunctionsSegInfo); success = success && patchInstructionsSegments(instructionsSegments, outUnresolvedExternals); - success = success && patchDataSegments(globalVariablesSegInfo, globalConstantsSegInfo, globalVariablesSeg, globalConstantsSeg, outUnresolvedExternals); + success = success && patchDataSegments(globalVariablesSegInfo, globalConstantsSegInfo, globalVariablesSeg, globalConstantsSeg, + outUnresolvedExternals, pDevice, constantsInitData, variablesInitData); return success; } @@ -183,8 +187,9 @@ struct Linker { bool patchInstructionsSegments(const std::vector &instructionsSegments, std::vector &outUnresolvedExternals); bool patchDataSegments(const SegmentInfo &globalVariablesSegInfo, const SegmentInfo &globalConstantsSegInfo, - PatchableSegment &globalVariablesSeg, PatchableSegment &globalConstantsSeg, - std::vector &outUnresolvedExternals); + GraphicsAllocation *globalVariablesSeg, GraphicsAllocation *globalConstantsSeg, + std::vector &outUnresolvedExternals, Device *pDevice, + const void *constantsInitData, const void *variablesInitData); }; std::string constructLinkerErrorMessage(const Linker::UnresolvedExternals &unresolvedExternals, const std::vector &instructionsSegmentsNames); diff --git a/shared/source/helpers/blit_commands_helper.h b/shared/source/helpers/blit_commands_helper.h index cbc1f30f00..5065e12b5d 100644 --- a/shared/source/helpers/blit_commands_helper.h +++ b/shared/source/helpers/blit_commands_helper.h @@ -92,11 +92,14 @@ using BlitMemoryToAllocationFunc = std::function size)>; extern BlitMemoryToAllocationFunc blitMemoryToAllocation; +extern BlitMemoryToAllocationFunc blitAllocationToMemory; } // namespace BlitHelperFunctions struct BlitHelper { static BlitOperationResult blitMemoryToAllocation(Device &device, GraphicsAllocation *memory, size_t offset, const void *hostPtr, Vec3 size); + static BlitOperationResult blitAllocationToMemory(Device &device, GraphicsAllocation *memory, size_t offset, const void *hostPtr, + Vec3 size); }; template diff --git a/shared/test/unit_test/compiler_interface/linker_tests.cpp b/shared/test/unit_test/compiler_interface/linker_tests.cpp index 29dbbb788a..7229c4e79b 100644 --- a/shared/test/unit_test/compiler_interface/linker_tests.cpp +++ b/shared/test/unit_test/compiler_interface/linker_tests.cpp @@ -6,6 +6,9 @@ */ #include "shared/source/helpers/ptr_math.h" +#include "shared/source/memory_manager/graphics_allocation.h" + +#include "opencl/test/unit_test/mocks/mock_graphics_allocation.h" #include "RelocationInfo.h" #include "gmock/gmock.h" @@ -260,12 +263,13 @@ TEST(LinkerTests, givenEmptyLinkerInputThenLinkerOutputIsEmpty) { NEO::LinkerInput linkerInput; NEO::Linker linker(linkerInput); NEO::Linker::SegmentInfo globalVar, globalConst, exportedFunc; - NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg; + NEO::GraphicsAllocation *patchableGlobalVarSeg = nullptr; + NEO::GraphicsAllocation *patchableConstVarSeg = nullptr; NEO::Linker::PatchableSegments patchableInstructionSegments; NEO::Linker::UnresolvedExternals unresolvedExternals; bool linkResult = linker.link(globalVar, globalConst, exportedFunc, patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, - unresolvedExternals); + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_TRUE(linkResult); EXPECT_EQ(0U, unresolvedExternals.size()); auto relocatedSymbols = linker.extractRelocatedSymbols(); @@ -277,12 +281,13 @@ TEST(LinkerTests, givenInvalidLinkerInputThenLinkerFails) { mockLinkerInput.valid = false; NEO::Linker linker(mockLinkerInput); NEO::Linker::SegmentInfo globalVar, globalConst, exportedFunc; - NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg; + NEO::GraphicsAllocation *patchableGlobalVarSeg = nullptr; + NEO::GraphicsAllocation *patchableConstVarSeg = nullptr; NEO::Linker::PatchableSegments patchableInstructionSegments; NEO::Linker::UnresolvedExternals unresolvedExternals; bool linkResult = linker.link(globalVar, globalConst, exportedFunc, patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, - unresolvedExternals); + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_FALSE(linkResult); } @@ -304,12 +309,13 @@ TEST(LinkerTests, givenUnresolvedExternalWhenPatchingInstructionsThenLinkerFails NEO::Linker::PatchableSegment seg0; seg0.hostPointer = instructionSegment.data(); seg0.segmentSize = instructionSegment.size(); - NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg; + NEO::GraphicsAllocation *patchableGlobalVarSeg = nullptr; + NEO::GraphicsAllocation *patchableConstVarSeg = nullptr; NEO::Linker::PatchableSegments patchableInstructionSegments{seg0}; bool linkResult = linker.link(globalVar, globalConst, exportedFunc, patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, - unresolvedExternals); + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_FALSE(linkResult); auto relocatedSymbols = linker.extractRelocatedSymbols(); EXPECT_EQ(0U, relocatedSymbols.size()); @@ -392,10 +398,12 @@ TEST(LinkerTests, givenValidSymbolsAndRelocationsThenInstructionSegmentsArePrope seg0.hostPointer = instructionSegment.data(); seg0.segmentSize = instructionSegment.size(); NEO::Linker::PatchableSegments patchableInstructionSegments{seg0}; - NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg; + NEO::GraphicsAllocation *patchableGlobalVarSeg = nullptr; + NEO::GraphicsAllocation *patchableConstVarSeg = nullptr; bool linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment, - patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, unresolvedExternals); + patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, unresolvedExternals, + nullptr, nullptr, nullptr); EXPECT_TRUE(linkResult); auto relocatedSymbols = linker.extractRelocatedSymbols(); EXPECT_EQ(0U, unresolvedExternals.size()); @@ -448,11 +456,12 @@ TEST(LinkerTests, givenInvalidSymbolOffsetWhenPatchingInstructionsThenRelocation seg0.hostPointer = instructionSegment.data(); seg0.segmentSize = instructionSegment.size(); NEO::Linker::PatchableSegments patchableInstructionSegments{seg0}; - NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg; + NEO::GraphicsAllocation *patchableGlobalVarSeg = nullptr; + NEO::GraphicsAllocation *patchableConstVarSeg = nullptr; bool linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment, patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, - unresolvedExternals); + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_FALSE(linkResult); auto relocatedSymbols = linker.extractRelocatedSymbols(); EXPECT_EQ(0U, unresolvedExternals.size()); @@ -460,7 +469,8 @@ TEST(LinkerTests, givenInvalidSymbolOffsetWhenPatchingInstructionsThenRelocation globalVarSegment.segmentSize = symGlobalVariable.s_offset + symGlobalVariable.s_size; linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment, - patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, unresolvedExternals); + patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, unresolvedExternals, + nullptr, nullptr, nullptr); EXPECT_TRUE(linkResult); } @@ -494,11 +504,12 @@ TEST(LinkerTests, givenInvalidRelocationOffsetThenPatchingOfInstructionsFails) { seg0.hostPointer = instructionSegment.data(); seg0.segmentSize = relocA.r_offset; NEO::Linker::PatchableSegments patchableInstructionSegments{seg0}; - NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg; + NEO::GraphicsAllocation *patchableGlobalVarSeg = nullptr; + NEO::GraphicsAllocation *patchableConstVarSeg = nullptr; bool linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment, patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, - unresolvedExternals); + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_FALSE(linkResult); auto relocatedSymbols = linker.extractRelocatedSymbols(); EXPECT_EQ(1U, relocatedSymbols.size()); @@ -508,7 +519,7 @@ TEST(LinkerTests, givenInvalidRelocationOffsetThenPatchingOfInstructionsFails) { patchableInstructionSegments[0].segmentSize = relocA.r_offset + sizeof(uintptr_t); linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment, patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, - unresolvedExternals); + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_TRUE(linkResult); } @@ -542,13 +553,14 @@ TEST(LinkerTests, givenUnknownSymbolTypeWhenPatchingInstructionsThenRelocationFa seg0.hostPointer = instructionSegment.data(); seg0.segmentSize = instructionSegment.size(); NEO::Linker::PatchableSegments patchableInstructionSegments{seg0}; - NEO::Linker::PatchableSegment patchableGlobalVarSeg, patchableConstVarSeg; + NEO::GraphicsAllocation *patchableGlobalVarSeg = nullptr; + NEO::GraphicsAllocation *patchableConstVarSeg = nullptr; ASSERT_EQ(1U, linkerInput.symbols.count("A")); linkerInput.symbols["A"].segment = NEO::SegmentType::Unknown; bool linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment, patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, - unresolvedExternals); + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_FALSE(linkResult); auto relocatedSymbols = linker.extractRelocatedSymbols(); EXPECT_EQ(0U, relocatedSymbols.size()); @@ -557,7 +569,7 @@ TEST(LinkerTests, givenUnknownSymbolTypeWhenPatchingInstructionsThenRelocationFa linkerInput.symbols["A"].segment = NEO::SegmentType::GlobalVariables; linkResult = linker.link(globalVarSegment, globalConstSegment, exportedFuncSegment, patchableGlobalVarSeg, patchableConstVarSeg, patchableInstructionSegments, - unresolvedExternals); + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_TRUE(linkResult); } @@ -566,14 +578,12 @@ TEST(LinkerTests, givenInvalidSourceSegmentWhenPatchingDataSegmentsThenLinkerFai NEO::Linker linker(linkerInput); NEO::Linker::SegmentInfo emptySegmentInfo; - NEO::Linker::PatchableSegment emptyPatchableSegment; + NEO::MockGraphicsAllocation emptyPatchableSegment; NEO::Linker::UnresolvedExternals unresolvedExternals; std::vector nonEmptypatchableSegmentData; nonEmptypatchableSegmentData.resize(64, 8U); - NEO::Linker::PatchableSegment nonEmptypatchableSegment; - nonEmptypatchableSegment.hostPointer = nonEmptypatchableSegmentData.data(); - nonEmptypatchableSegment.segmentSize = nonEmptypatchableSegmentData.size(); + NEO::MockGraphicsAllocation nonEmptypatchableSegment{nonEmptypatchableSegmentData.data(), nonEmptypatchableSegmentData.size()}; NEO::LinkerInput::RelocationInfo relocInfo; relocInfo.offset = 0U; @@ -587,8 +597,8 @@ TEST(LinkerTests, givenInvalidSourceSegmentWhenPatchingDataSegmentsThenLinkerFai linkerInput.dataRelocations[0].relocationSegment = NEO::SegmentType::GlobalVariables; linkerInput.dataRelocations[0].symbolSegment = NEO::SegmentType::Unknown; bool linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo, - nonEmptypatchableSegment, emptyPatchableSegment, {}, - unresolvedExternals); + &nonEmptypatchableSegment, &emptyPatchableSegment, {}, + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_FALSE(linkResult); EXPECT_EQ(1U, unresolvedExternals.size()); @@ -596,8 +606,8 @@ TEST(LinkerTests, givenInvalidSourceSegmentWhenPatchingDataSegmentsThenLinkerFai linkerInput.dataRelocations[0].symbolSegment = NEO::SegmentType::GlobalVariables; unresolvedExternals.clear(); linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo, - nonEmptypatchableSegment, emptyPatchableSegment, {}, - unresolvedExternals); + &nonEmptypatchableSegment, &emptyPatchableSegment, {}, + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_TRUE(linkResult); EXPECT_EQ(0U, unresolvedExternals.size()); @@ -610,8 +620,8 @@ TEST(LinkerTests, givenInvalidSourceSegmentWhenPatchingDataSegmentsThenLinkerFai linkerInput.dataRelocations[0].symbolSegment = NEO::SegmentType::Unknown; unresolvedExternals.clear(); bool linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo, - emptyPatchableSegment, nonEmptypatchableSegment, {}, - unresolvedExternals); + &emptyPatchableSegment, &nonEmptypatchableSegment, {}, + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_FALSE(linkResult); EXPECT_EQ(1U, unresolvedExternals.size()); @@ -619,8 +629,8 @@ TEST(LinkerTests, givenInvalidSourceSegmentWhenPatchingDataSegmentsThenLinkerFai linkerInput.dataRelocations[0].symbolSegment = NEO::SegmentType::GlobalVariables; unresolvedExternals.clear(); linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo, - emptyPatchableSegment, nonEmptypatchableSegment, {}, - unresolvedExternals); + &emptyPatchableSegment, &nonEmptypatchableSegment, {}, + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_TRUE(linkResult); EXPECT_EQ(0U, unresolvedExternals.size()); @@ -632,14 +642,12 @@ TEST(LinkerTests, givenUnknownRelocationSegmentWhenPatchingDataSegmentsThenLinke NEO::Linker linker(linkerInput); NEO::Linker::SegmentInfo emptySegmentInfo; - NEO::Linker::PatchableSegment emptyPatchableSegment; + NEO::MockGraphicsAllocation emptyPatchableSegment; NEO::Linker::UnresolvedExternals unresolvedExternals; std::vector nonEmptypatchableSegmentData; nonEmptypatchableSegmentData.resize(64, 8U); - NEO::Linker::PatchableSegment nonEmptypatchableSegment; - nonEmptypatchableSegment.hostPointer = nonEmptypatchableSegmentData.data(); - nonEmptypatchableSegment.segmentSize = nonEmptypatchableSegmentData.size(); + NEO::MockGraphicsAllocation nonEmptypatchableSegment{nonEmptypatchableSegmentData.data(), nonEmptypatchableSegmentData.size()}; NEO::LinkerInput::RelocationInfo relocInfo; relocInfo.offset = 0U; @@ -651,8 +659,8 @@ TEST(LinkerTests, givenUnknownRelocationSegmentWhenPatchingDataSegmentsThenLinke linkerInput.traits.requiresPatchingOfGlobalVariablesBuffer = true; bool linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo, - nonEmptypatchableSegment, emptyPatchableSegment, {}, - unresolvedExternals); + &nonEmptypatchableSegment, &emptyPatchableSegment, {}, + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_FALSE(linkResult); EXPECT_EQ(1U, unresolvedExternals.size()); @@ -660,8 +668,8 @@ TEST(LinkerTests, givenUnknownRelocationSegmentWhenPatchingDataSegmentsThenLinke linkerInput.dataRelocations[0].relocationSegment = NEO::SegmentType::GlobalVariables; unresolvedExternals.clear(); linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo, - nonEmptypatchableSegment, emptyPatchableSegment, {}, - unresolvedExternals); + &nonEmptypatchableSegment, &emptyPatchableSegment, {}, + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_TRUE(linkResult); EXPECT_EQ(0U, unresolvedExternals.size()); @@ -672,14 +680,12 @@ TEST(LinkerTests, givenRelocationTypeWithHighPartOfAddressWhenPatchingDataSegmen NEO::Linker linker(linkerInput); NEO::Linker::SegmentInfo emptySegmentInfo; - NEO::Linker::PatchableSegment emptyPatchableSegment; + NEO::MockGraphicsAllocation emptyPatchableSegment; NEO::Linker::UnresolvedExternals unresolvedExternals; std::vector nonEmptypatchableSegmentData; nonEmptypatchableSegmentData.resize(64, 8U); - NEO::Linker::PatchableSegment nonEmptypatchableSegment; - nonEmptypatchableSegment.hostPointer = nonEmptypatchableSegmentData.data(); - nonEmptypatchableSegment.segmentSize = nonEmptypatchableSegmentData.size(); + NEO::MockGraphicsAllocation nonEmptypatchableSegment{nonEmptypatchableSegmentData.data(), nonEmptypatchableSegmentData.size()}; NEO::LinkerInput::RelocationInfo relocInfo; relocInfo.offset = 0U; @@ -691,8 +697,8 @@ TEST(LinkerTests, givenRelocationTypeWithHighPartOfAddressWhenPatchingDataSegmen linkerInput.traits.requiresPatchingOfGlobalVariablesBuffer = true; bool linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo, - nonEmptypatchableSegment, emptyPatchableSegment, {}, - unresolvedExternals); + &nonEmptypatchableSegment, &emptyPatchableSegment, {}, + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_FALSE(linkResult); EXPECT_EQ(1U, unresolvedExternals.size()); @@ -700,8 +706,8 @@ TEST(LinkerTests, givenRelocationTypeWithHighPartOfAddressWhenPatchingDataSegmen linkerInput.dataRelocations[0].type = NEO::LinkerInput::RelocationInfo::Type::AddressLow; unresolvedExternals.clear(); linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo, - nonEmptypatchableSegment, emptyPatchableSegment, {}, - unresolvedExternals); + &nonEmptypatchableSegment, &emptyPatchableSegment, {}, + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_TRUE(linkResult); EXPECT_EQ(0U, unresolvedExternals.size()); @@ -720,16 +726,13 @@ TEST(LinkerTests, givenValidSymbolsAndRelocationsThenDataSegmentsAreProperlyPatc NEO::Linker::SegmentInfo globalConstantsSegmentInfo, globalVariablesSegmentInfo; NEO::Linker::UnresolvedExternals unresolvedExternals; - NEO::Linker::PatchableSegment globalConstantsPatchableSegment, globalVariablesPatchableSegment; globalConstantsSegmentInfo.gpuAddress = reinterpret_cast(globalConstantsSegmentData.data()); globalConstantsSegmentInfo.segmentSize = globalConstantsSegmentData.size(); - globalConstantsPatchableSegment.hostPointer = globalConstantsSegmentData.data(); - globalConstantsPatchableSegment.segmentSize = globalConstantsSegmentData.size(); + NEO::MockGraphicsAllocation globalConstantsPatchableSegment{globalConstantsSegmentData.data(), globalConstantsSegmentData.size()}; globalVariablesSegmentInfo.gpuAddress = reinterpret_cast(globalVariablesSegmentData.data()); globalVariablesSegmentInfo.segmentSize = globalVariablesSegmentData.size(); - globalVariablesPatchableSegment.hostPointer = globalVariablesSegmentData.data(); - globalVariablesPatchableSegment.segmentSize = globalVariablesSegmentData.size(); + NEO::MockGraphicsAllocation globalVariablesPatchableSegment{globalVariablesSegmentData.data(), globalVariablesSegmentData.size()}; NEO::LinkerInput::RelocationInfo relocationInfo[5]; // GlobalVar -> GlobalVar @@ -765,7 +768,9 @@ TEST(LinkerTests, givenValidSymbolsAndRelocationsThenDataSegmentsAreProperlyPatc uint32_t initValue = 0; for (const auto &reloc : relocationInfo) { linkerInput.addDataRelocationInfo(reloc); - void *dstRaw = (reloc.relocationSegment == NEO::SegmentType::GlobalVariables) ? globalVariablesPatchableSegment.hostPointer : globalConstantsPatchableSegment.hostPointer; + void *dstRaw = (reloc.relocationSegment == NEO::SegmentType::GlobalVariables) + ? globalVariablesPatchableSegment.getUnderlyingBuffer() + : globalConstantsPatchableSegment.getUnderlyingBuffer(); if (reloc.type == NEO::LinkerInput::RelocationInfo::Type::Address) { *reinterpret_cast(ptrOffset(dstRaw, static_cast(reloc.offset))) = initValue * 4; // relocations to global data are currently based on patchIncrement, simulate init data } else { @@ -775,17 +780,21 @@ TEST(LinkerTests, givenValidSymbolsAndRelocationsThenDataSegmentsAreProperlyPatc } auto linkResult = linker.link(globalVariablesSegmentInfo, globalConstantsSegmentInfo, {}, - globalVariablesPatchableSegment, globalConstantsPatchableSegment, {}, - unresolvedExternals); + &globalVariablesPatchableSegment, &globalConstantsPatchableSegment, {}, + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_TRUE(linkResult); EXPECT_EQ(0U, unresolvedExternals.size()); - EXPECT_EQ(7U, *reinterpret_cast(globalConstantsPatchableSegment.hostPointer)); - EXPECT_EQ(13U, *reinterpret_cast(globalVariablesPatchableSegment.hostPointer)); + EXPECT_EQ(7U, *reinterpret_cast(globalConstantsPatchableSegment.getUnderlyingBuffer())); + EXPECT_EQ(13U, *reinterpret_cast(globalVariablesPatchableSegment.getUnderlyingBuffer())); initValue = 0; for (const auto &reloc : relocationInfo) { - void *srcRaw = (reloc.symbolSegment == NEO::SegmentType::GlobalVariables) ? globalVariablesPatchableSegment.hostPointer : globalConstantsPatchableSegment.hostPointer; - void *dstRaw = (reloc.relocationSegment == NEO::SegmentType::GlobalVariables) ? globalVariablesPatchableSegment.hostPointer : globalConstantsPatchableSegment.hostPointer; + void *srcRaw = (reloc.symbolSegment == NEO::SegmentType::GlobalVariables) + ? globalVariablesPatchableSegment.getUnderlyingBuffer() + : globalConstantsPatchableSegment.getUnderlyingBuffer(); + void *dstRaw = (reloc.relocationSegment == NEO::SegmentType::GlobalVariables) + ? globalVariablesPatchableSegment.getUnderlyingBuffer() + : globalConstantsPatchableSegment.getUnderlyingBuffer(); uint8_t *src = reinterpret_cast(srcRaw); uint8_t *dst = reinterpret_cast(dstRaw); @@ -820,16 +829,13 @@ TEST(LinkerTests, givenValidSymbolsAndRelocationsWhenPatchin32bitBinaryThenDataS NEO::Linker::SegmentInfo globalConstantsSegmentInfo, globalVariablesSegmentInfo; NEO::Linker::UnresolvedExternals unresolvedExternals; - NEO::Linker::PatchableSegment globalConstantsPatchableSegment, globalVariablesPatchableSegment; globalConstantsSegmentInfo.gpuAddress = reinterpret_cast(globalConstantsSegmentData.data()); globalConstantsSegmentInfo.segmentSize = globalConstantsSegmentData.size(); - globalConstantsPatchableSegment.hostPointer = globalConstantsSegmentData.data(); - globalConstantsPatchableSegment.segmentSize = globalConstantsSegmentData.size(); + NEO::MockGraphicsAllocation globalConstantsPatchableSegment{globalConstantsSegmentData.data(), globalConstantsSegmentData.size()}; globalVariablesSegmentInfo.gpuAddress = reinterpret_cast(globalVariablesSegmentData.data()); globalVariablesSegmentInfo.segmentSize = globalVariablesSegmentData.size(); - globalVariablesPatchableSegment.hostPointer = globalVariablesSegmentData.data(); - globalVariablesPatchableSegment.segmentSize = globalVariablesSegmentData.size(); + NEO::MockGraphicsAllocation globalVariablesPatchableSegment{globalVariablesSegmentData.data(), globalVariablesSegmentData.size()}; NEO::LinkerInput::RelocationInfo relocationInfo[5]; // GlobalVar -> GlobalVar @@ -865,23 +871,29 @@ TEST(LinkerTests, givenValidSymbolsAndRelocationsWhenPatchin32bitBinaryThenDataS uint32_t initValue = 0; for (const auto &reloc : relocationInfo) { linkerInput.addDataRelocationInfo(reloc); - void *dstRaw = (reloc.relocationSegment == NEO::SegmentType::GlobalVariables) ? globalVariablesPatchableSegment.hostPointer : globalConstantsPatchableSegment.hostPointer; + void *dstRaw = (reloc.relocationSegment == NEO::SegmentType::GlobalVariables) + ? globalVariablesPatchableSegment.getUnderlyingBuffer() + : globalConstantsPatchableSegment.getUnderlyingBuffer(); *reinterpret_cast(ptrOffset(dstRaw, static_cast(reloc.offset))) = initValue * 4; // relocations to global data are currently based on patchIncrement, simulate init data ++initValue; } auto linkResult = linker.link(globalVariablesSegmentInfo, globalConstantsSegmentInfo, {}, - globalVariablesPatchableSegment, globalConstantsPatchableSegment, {}, - unresolvedExternals); + &globalVariablesPatchableSegment, &globalConstantsPatchableSegment, {}, + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_TRUE(linkResult); EXPECT_EQ(0U, unresolvedExternals.size()); - EXPECT_EQ(7U, *reinterpret_cast(globalConstantsPatchableSegment.hostPointer)); - EXPECT_EQ(13U, *reinterpret_cast(globalVariablesPatchableSegment.hostPointer)); + EXPECT_EQ(7U, *reinterpret_cast(globalConstantsPatchableSegment.getUnderlyingBuffer())); + EXPECT_EQ(13U, *reinterpret_cast(globalVariablesPatchableSegment.getUnderlyingBuffer())); initValue = 0; for (const auto &reloc : relocationInfo) { - void *srcRaw = (reloc.symbolSegment == NEO::SegmentType::GlobalVariables) ? globalVariablesPatchableSegment.hostPointer : globalConstantsPatchableSegment.hostPointer; - void *dstRaw = (reloc.relocationSegment == NEO::SegmentType::GlobalVariables) ? globalVariablesPatchableSegment.hostPointer : globalConstantsPatchableSegment.hostPointer; + void *srcRaw = (reloc.symbolSegment == NEO::SegmentType::GlobalVariables) + ? globalVariablesPatchableSegment.getUnderlyingBuffer() + : globalConstantsPatchableSegment.getUnderlyingBuffer(); + void *dstRaw = (reloc.relocationSegment == NEO::SegmentType::GlobalVariables) + ? globalVariablesPatchableSegment.getUnderlyingBuffer() + : globalConstantsPatchableSegment.getUnderlyingBuffer(); uint8_t *src = reinterpret_cast(srcRaw); uint8_t *dst = reinterpret_cast(dstRaw); @@ -900,14 +912,12 @@ TEST(LinkerTests, givenInvalidRelocationOffsetThenPatchingOfDataSegmentsFails) { NEO::Linker linker(linkerInput); NEO::Linker::SegmentInfo emptySegmentInfo; - NEO::Linker::PatchableSegment emptyPatchableSegment; + NEO::MockGraphicsAllocation emptyPatchableSegment; NEO::Linker::UnresolvedExternals unresolvedExternals; std::vector nonEmptypatchableSegmentData; nonEmptypatchableSegmentData.resize(64, 8U); - NEO::Linker::PatchableSegment nonEmptypatchableSegment; - nonEmptypatchableSegment.hostPointer = nonEmptypatchableSegmentData.data(); - nonEmptypatchableSegment.segmentSize = nonEmptypatchableSegmentData.size(); + NEO::MockGraphicsAllocation nonEmptypatchableSegment{nonEmptypatchableSegmentData.data(), nonEmptypatchableSegmentData.size()}; NEO::LinkerInput::RelocationInfo relocInfo; relocInfo.offset = 64U; @@ -919,8 +929,8 @@ TEST(LinkerTests, givenInvalidRelocationOffsetThenPatchingOfDataSegmentsFails) { linkerInput.traits.requiresPatchingOfGlobalVariablesBuffer = true; bool linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo, - nonEmptypatchableSegment, emptyPatchableSegment, {}, - unresolvedExternals); + &nonEmptypatchableSegment, &emptyPatchableSegment, {}, + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_FALSE(linkResult); EXPECT_EQ(1U, unresolvedExternals.size()); @@ -928,8 +938,8 @@ TEST(LinkerTests, givenInvalidRelocationOffsetThenPatchingOfDataSegmentsFails) { linkerInput.dataRelocations[0].offset = 32; unresolvedExternals.clear(); linkResult = linker.link(emptySegmentInfo, emptySegmentInfo, emptySegmentInfo, - nonEmptypatchableSegment, emptyPatchableSegment, {}, - unresolvedExternals); + &nonEmptypatchableSegment, &emptyPatchableSegment, {}, + unresolvedExternals, nullptr, nullptr, nullptr); EXPECT_TRUE(linkResult); EXPECT_EQ(0U, unresolvedExternals.size());