2019-07-04 23:14:51 +08:00
|
|
|
/*
|
2022-03-01 01:44:06 +08:00
|
|
|
* Copyright (C) 2019-2022 Intel Corporation
|
2019-07-04 23:14:51 +08:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: MIT
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2020-02-24 05:44:01 +08:00
|
|
|
#include "shared/source/compiler_interface/linker.h"
|
2019-07-04 23:14:51 +08:00
|
|
|
|
2020-01-12 01:25:26 +08:00
|
|
|
#include <functional>
|
|
|
|
#include <tuple>
|
|
|
|
|
2019-07-04 23:14:51 +08:00
|
|
|
template <class BaseClass>
|
|
|
|
struct WhiteBox;
|
|
|
|
|
2020-01-12 01:25:26 +08:00
|
|
|
template <class BaseClass>
|
|
|
|
struct Mock;
|
|
|
|
|
2019-07-04 23:14:51 +08:00
|
|
|
template <>
|
|
|
|
struct WhiteBox<NEO::LinkerInput> : NEO::LinkerInput {
|
|
|
|
using BaseClass = NEO::LinkerInput;
|
|
|
|
|
2020-01-12 01:25:26 +08:00
|
|
|
using BaseClass::dataRelocations;
|
2019-07-04 23:14:51 +08:00
|
|
|
using BaseClass::exportedFunctionsSegmentId;
|
2022-03-01 01:44:06 +08:00
|
|
|
using BaseClass::extFuncSymbols;
|
|
|
|
using BaseClass::extFunDependencies;
|
|
|
|
using BaseClass::kernelDependencies;
|
2022-09-06 08:10:18 +08:00
|
|
|
using BaseClass::localSymbols;
|
2022-03-01 01:44:06 +08:00
|
|
|
using BaseClass::parseRelocationForExtFuncUsage;
|
2019-07-04 23:14:51 +08:00
|
|
|
using BaseClass::symbols;
|
2022-04-15 20:59:44 +08:00
|
|
|
using BaseClass::textRelocations;
|
2019-07-04 23:14:51 +08:00
|
|
|
using BaseClass::traits;
|
2020-01-12 01:25:26 +08:00
|
|
|
using BaseClass::valid;
|
|
|
|
};
|
|
|
|
|
2022-03-01 01:44:06 +08:00
|
|
|
template <>
|
|
|
|
struct WhiteBox<NEO::Linker> : NEO::Linker {
|
|
|
|
using BaseClass = NEO::Linker;
|
|
|
|
using BaseClass::BaseClass;
|
2022-09-06 08:10:18 +08:00
|
|
|
using BaseClass::localRelocatedSymbols;
|
2022-04-15 20:59:44 +08:00
|
|
|
using BaseClass::patchDataSegments;
|
|
|
|
using BaseClass::patchInstructionsSegments;
|
2022-09-06 08:10:18 +08:00
|
|
|
using BaseClass::processRelocations;
|
2022-04-15 20:59:44 +08:00
|
|
|
using BaseClass::relocatedSymbols;
|
2022-03-01 01:44:06 +08:00
|
|
|
using BaseClass::resolveExternalFunctions;
|
|
|
|
};
|
|
|
|
|
2020-01-12 01:25:26 +08:00
|
|
|
template <typename MockT, typename ReturnT, typename... ArgsT>
|
|
|
|
struct LightMockConfig {
|
|
|
|
using MockReturnT = ReturnT;
|
|
|
|
using OverrideT = std::function<ReturnT(MockT *, ArgsT...)>;
|
|
|
|
|
|
|
|
uint32_t timesCalled = 0U;
|
|
|
|
OverrideT overrideFunc;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename ConfigT, typename ObjT, typename... ArgsT>
|
2021-03-15 19:39:58 +08:00
|
|
|
typename ConfigT::MockReturnT invokeMocked(ConfigT &config, ObjT obj, ArgsT &&...args) {
|
2020-01-12 01:25:26 +08:00
|
|
|
config.timesCalled += 1;
|
|
|
|
if (config.overrideFunc) {
|
|
|
|
return config.overrideFunc(obj, std::forward<ArgsT>(args)...);
|
|
|
|
} else {
|
|
|
|
return config.originalFunc(obj, std::forward<ArgsT>(args)...);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#define LIGHT_MOCK_OVERRIDE_2(NAME, MOCK_T, BASE_T, RETURN_T, ARG0_T, ARG1_T) \
|
|
|
|
struct : LightMockConfig<MOCK_T, RETURN_T, ARG0_T, ARG1_T> { \
|
|
|
|
OverrideT originalFunc = +[](BaseT *obj, ARG0_T arg0, ARG1_T arg1) -> RETURN_T { \
|
|
|
|
return obj->BaseT::NAME(std::forward<ARG0_T>(arg0), std::forward<ARG1_T>(arg1)); \
|
|
|
|
}; \
|
|
|
|
} NAME##MockConfig; \
|
|
|
|
\
|
|
|
|
RETURN_T NAME(ARG0_T arg0, ARG1_T arg1) override { \
|
|
|
|
return invokeMocked(NAME##MockConfig, this, std::forward<ARG0_T>(arg0), std::forward<ARG1_T>(arg1)); \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define LIGHT_MOCK_OVERRIDE_3(NAME, MOCK_T, BASE_T, RETURN_T, ARG0_T, ARG1_T, ARG2_T) \
|
|
|
|
struct : LightMockConfig<MOCK_T, RETURN_T, ARG0_T, ARG1_T, ARG2_T> { \
|
|
|
|
OverrideT originalFunc = +[](BaseT *obj, ARG0_T arg0, ARG1_T arg1, ARG2_T arg2) -> RETURN_T { \
|
|
|
|
return obj->BaseT::NAME(std::forward<ARG0_T>(arg0), std::forward<ARG1_T>(arg1), std::forward<ARG2_T>(arg2)); \
|
|
|
|
}; \
|
|
|
|
} NAME##MockConfig; \
|
|
|
|
\
|
|
|
|
RETURN_T NAME(ARG0_T arg0, ARG1_T arg1, ARG2_T arg2) override { \
|
|
|
|
return invokeMocked(NAME##MockConfig, this, std::forward<ARG0_T>(arg0), std::forward<ARG1_T>(arg1), std::forward<ARG2_T>(arg2)); \
|
|
|
|
}
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct Mock<NEO::LinkerInput> : WhiteBox<NEO::LinkerInput> {
|
|
|
|
using ThisT = Mock<NEO::LinkerInput>;
|
|
|
|
using BaseT = NEO::LinkerInput;
|
|
|
|
using WhiteBoxBaseT = WhiteBox<BaseT>;
|
|
|
|
|
|
|
|
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);
|
2019-07-04 23:14:51 +08:00
|
|
|
};
|