/* * Copyright (C) 2019-2023 Intel Corporation * * SPDX-License-Identifier: MIT * */ #pragma once #include "shared/source/compiler_interface/linker.h" #include #include template struct WhiteBox; template struct Mock; template <> struct WhiteBox : NEO::LinkerInput { using BaseClass = NEO::LinkerInput; using BaseClass::dataRelocations; using BaseClass::exportedFunctionsSegmentId; using BaseClass::extFuncSymbols; using BaseClass::extFunDependencies; using BaseClass::kernelDependencies; using BaseClass::parseRelocationForExtFuncUsage; using BaseClass::symbols; using BaseClass::textRelocations; using BaseClass::traits; using BaseClass::valid; }; template <> struct WhiteBox : NEO::Linker { using BaseClass = NEO::Linker; using BaseClass::BaseClass; using BaseClass::patchDataSegments; using BaseClass::patchInstructionsSegments; using BaseClass::relocatedSymbols; using BaseClass::relocateSymbols; using BaseClass::resolveExternalFunctions; }; template struct LightMockConfig { using MockReturnT = ReturnT; using OverrideT = std::function; uint32_t timesCalled = 0U; OverrideT overrideFunc; }; template typename ConfigT::MockReturnT invokeMocked(ConfigT &config, ObjT obj, ArgsT &&...args) { config.timesCalled += 1; if (config.overrideFunc) { return config.overrideFunc(obj, std::forward(args)...); } else { return config.originalFunc(obj, std::forward(args)...); } } #define LIGHT_MOCK_OVERRIDE_2(NAME, MOCK_T, BASE_T, RETURN_T, ARG0_T, ARG1_T) \ struct : LightMockConfig { \ OverrideT originalFunc = +[](BaseT *obj, ARG0_T arg0, ARG1_T arg1) -> RETURN_T { \ return obj->BaseT::NAME(std::forward(arg0), std::forward(arg1)); \ }; \ } NAME##MockConfig; \ \ RETURN_T NAME(ARG0_T arg0, ARG1_T arg1) override { \ return invokeMocked(NAME##MockConfig, this, std::forward(arg0), std::forward(arg1)); \ } #define LIGHT_MOCK_OVERRIDE_3(NAME, MOCK_T, BASE_T, RETURN_T, ARG0_T, ARG1_T, ARG2_T) \ struct : LightMockConfig { \ OverrideT originalFunc = +[](BaseT *obj, ARG0_T arg0, ARG1_T arg1, ARG2_T arg2) -> RETURN_T { \ return obj->BaseT::NAME(std::forward(arg0), std::forward(arg1), std::forward(arg2)); \ }; \ } NAME##MockConfig; \ \ RETURN_T NAME(ARG0_T arg0, ARG1_T arg1, ARG2_T arg2) override { \ return invokeMocked(NAME##MockConfig, this, std::forward(arg0), std::forward(arg1), std::forward(arg2)); \ } template <> struct Mock : WhiteBox { using ThisT = Mock; using BaseT = NEO::LinkerInput; using WhiteBoxBaseT = WhiteBox; LIGHT_MOCK_OVERRIDE_2(decodeGlobalVariablesSymbolTable, ThisT, BaseT, bool, const void *, uint32_t); LIGHT_MOCK_OVERRIDE_3(decodeExportedFunctionsSymbolTable, ThisT, BaseT, bool, const void *, uint32_t, uint32_t); LIGHT_MOCK_OVERRIDE_3(decodeRelocationTable, ThisT, BaseT, bool, const void *, uint32_t, uint32_t); };