1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef API_CORE_PLUGIN_INTF_STATIC_PLUGIN_DECL_H
17 #define API_CORE_PLUGIN_INTF_STATIC_PLUGIN_DECL_H
18 
19 #include <core/namespace.h>
20 #include <core/plugin/intf_plugin.h>
21 
22 // clang-format off
23 #if !defined(CORE_PLUGIN) || (CORE_PLUGIN == 0)
24 // Static plugin
25 #if defined(CORE_USE_COMPILER_GENERATED_STATIC_LIST) && (CORE_USE_COMPILER_GENERATED_STATIC_LIST == 1)
26 // linker/compiler generated initialized list..
27 #if _MSC_VER
28 #define PLUGIN_DATA(NAME) static constexpr const CORE_NS::IPlugin NAME##_pluginData
29 #define DEFINE_STATIC_PLUGIN(NAME)                                                              \
30     __pragma(section("spd$d", long, read))                                                      \
31     __declspec(allocate("spd$d"))                                                               \
32     extern constexpr CORE_NS::IPlugin const* const NAME##_StaticPlugin = &NAME##_pluginData;
33 #else
34 #define PLUGIN_DATA(NAME) __attribute__((used)) constexpr const CORE_NS::IPlugin NAME##_pluginData
35 #if __aarch64__
36 #define SECTION(NAME) #NAME",\"wa\"\n .align 3\n"
37 #elif __x86_64__
38 #define SECTION(NAME) #NAME",\"wa\"\n .align 8\n"
39 #elif __arm__
40 #define SECTION(NAME) #NAME",\"wa\"\n .align 2\n"
41 #elif __i386__
42 #define SECTION(NAME) #NAME",\"wa\"\n .align 4\n"
43 #endif
44 #define DEFINE_STATIC_PLUGIN(NAME)                                                                                    \
45     __asm__(                                                                                                          \
46         " .pushsection " SECTION(spl.1)                                                                               \
47         " .weak static_plugin_list\n"                                                                                 \
48         " static_plugin_list:\n"                                                                                      \
49         ".section " SECTION(spl.2)                                                                                    \
50         " .global "#NAME"_StaticPlugin\n"                                                                             \
51         ""#NAME"_StaticPlugin:\n"                                                                                     \
52         " .dc.a "#NAME"_pluginData\n"                                                                                 \
53         ".section " SECTION(spl.3)                                                                                    \
54         " .weak static_plugin_list_end\n"                                                                             \
55         " static_plugin_list_end:\n"                                                                                  \
56         " .popsection\n");                                                                                            \
57     extern const CORE_NS::IPlugin* const NAME##_StaticPlugin;                                                         \
58     __attribute__((visibility("hidden"), used)) CORE_NS::IPlugin const* const NAME##_DATA_ref = NAME##_StaticPlugin;  \
59     extern CORE_NS::IPlugin const* const static_plugin_list;                                                          \
60     extern __attribute__((visibility("hidden"), used, weak)) CORE_NS::IPlugin const* const static_plugin_list_ref =   \
61         static_plugin_list;                                                                                           \
62     extern CORE_NS::IPlugin const* const static_plugin_list_end;                                                      \
63     extern __attribute__((visibility("hidden"), used, weak))                                                          \
64         CORE_NS::IPlugin const* const static_plugin_list_end_ref = static_plugin_list_end;
65 #endif
66 #else
67 
68 namespace CORE_NS {
69 namespace StaticPluginRegistry {
70 void RegisterStaticPlugin(const CORE_NS::IPlugin& plugin);
71 } // namespace StaticPluginRegistry
72 } // namespace CORE_NS
73 
74 #define PLUGIN_DATA(NAME) static constexpr const CORE_NS::IPlugin NAME##_pluginData
75 
76 #if _MSC_VER
77     // Use static class "constructor" to call a function during initialization.
78     // ("safer", should work with ANY compiler, but with dynamic runtime init/memory cost)
79 #define DEFINE_STATIC_PLUGIN(NAME)                                                   \
80     static struct magic {                                                            \
81         magic()                                                                      \
82         {                                                                            \
83             CORE_NS::StaticPluginRegistry::RegisterStaticPlugin(NAME##_pluginData); \
84         }                                                                            \
85     } magic;
86 #else
87     // Use "constructor" attribute to call a function during initialization.
88     // ("safer", but with dynamic runtime init/memory cost)
89 #define DEFINE_STATIC_PLUGIN(NAME)                                                                  \
90     __attribute__((visibility("hidden"))) __attribute__((constructor)) static void registerStatic() \
91     {                                                                                               \
92         CORE_NS::StaticPluginRegistry::RegisterStaticPlugin(NAME##_pluginData);                    \
93     }
94 #endif
95 #endif
96 #endif
97 // clang-format on
98 #endif // API_CORE_PLUGIN_INTF_STATIC_PLUGIN_DECL_H
99