Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #include "acl_rt_impl.h"
12 :
13 : #include <cstring>
14 : #include "runtime/rts/rts_dfx.h"
15 :
16 : #include "common/log_inner.h"
17 : #include "common/error_codes_inner.h"
18 : #include "common/prof_reporter.h"
19 : #include "common/resource_statistics.h"
20 :
21 : #ifdef __cplusplus
22 : extern "C" {
23 : #endif
24 :
25 4 : aclError aclrtProfTraceImpl(void* userdata, int32_t length, aclrtStream stream)
26 : {
27 4 : ACL_PROFILING_REG(acl::AclProfType::AclrtProfTrace);
28 4 : ACL_LOG_INFO("start to execute AclrtProfTrace, length is [%d]", length);
29 4 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(userdata);
30 3 : ACL_REQUIRES_RTS_OK(rtsProfTrace(userdata, length, stream));
31 2 : return ACL_SUCCESS;
32 4 : }
33 :
34 : #ifdef ACL_RT_API_HOOK_ENABLE
35 : #if __GNUC__ >= 8
36 : #pragma GCC diagnostic push
37 : #pragma GCC diagnostic ignored "-Wcast-function-type"
38 : #endif // __GNUC__ >= 8
39 : ACL_RT_FUNC_MAP(ACL_HOOK_DEF)
40 : ACL_RT_ALLOCATOR_FUNC_MAP(ACL_HOOK_DEF)
41 : ACL_MDLRI_FUNC_MAP(ACL_HOOK_DEF)
42 : #if __GNUC__ >= 8
43 : #pragma GCC diagnostic pop
44 : #endif // __GNUC__ >= 8
45 :
46 : namespace {
47 : // Cold-path lookup table for SetFunc/GetFunc (string name -> entry pointer).
48 : // Linear scan is sufficient: ~250 entries, only invoked by tools at init time.
49 : struct AclrtApiLookupEntry {
50 : const char* name;
51 : aclrtApiEntry* entry;
52 : };
53 :
54 : #define ACL_HOOK_LOOKUP(ret, name, sig, args) {#name, &g_hook_##name},
55 : const AclrtApiLookupEntry g_aclrtApiLookup[] = {ACL_RT_FUNC_MAP(ACL_HOOK_LOOKUP) ACL_MDLRI_FUNC_MAP(ACL_HOOK_LOOKUP)
56 : ACL_RT_ALLOCATOR_FUNC_MAP(ACL_HOOK_LOOKUP)};
57 : #undef ACL_HOOK_LOOKUP
58 :
59 : constexpr size_t ACLRT_API_LOOKUP_COUNT = sizeof(g_aclrtApiLookup) / sizeof(g_aclrtApiLookup[0]);
60 :
61 31 : aclrtApiEntry* FindHookEntryByName(const char* name)
62 : {
63 31 : if (name == nullptr) {
64 0 : return nullptr;
65 : }
66 1940 : for (size_t i = 0; i < ACLRT_API_LOOKUP_COUNT; ++i) {
67 1937 : if (strcmp(name, g_aclrtApiLookup[i].name) == 0) {
68 28 : return g_aclrtApiLookup[i].entry;
69 : }
70 : }
71 3 : return nullptr;
72 : }
73 : } // namespace
74 : #endif // ACL_RT_API_HOOK_ENABLE
75 :
76 : #ifdef ACL_RT_API_HOOK_ENABLE
77 1 : __attribute__((constructor)) void RegisterApiHookToProf()
78 : {
79 1 : auto ret = MsprofSetInjectionFunc(
80 : static_cast<uint32_t>(PROF_HOOK_SET), reinterpret_cast<void*>(&aclrtApiInjectionSetFuncImpl));
81 1 : if (ret != 0) {
82 1 : ACL_LOG_WARN("MsprofSetInjectionFunc register set function failed, prof result = %d", ret);
83 : }
84 1 : ret = MsprofSetInjectionFunc(
85 : static_cast<uint32_t>(PROF_HOOK_GET), reinterpret_cast<void*>(&aclrtApiInjectionGetFuncImpl));
86 1 : if (ret != 0) {
87 1 : ACL_LOG_WARN("MsprofSetInjectionFunc register get function failed, prof result = %d", ret);
88 : }
89 1 : ret = MsprofInjectionInitialize();
90 1 : if (ret != 0) {
91 1 : ACL_LOG_WARN("MsprofInjectionInitialize failed, prof result = %d", ret);
92 : }
93 1 : }
94 : #endif // ACL_RT_API_HOOK_ENABLE
95 :
96 11 : aclError aclrtApiInjectionSetFuncImpl(const char* name, aclrtApiFunc func)
97 : {
98 : #ifdef ACL_RT_API_HOOK_ENABLE
99 11 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(name);
100 10 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(func);
101 9 : ACL_LOG_INFO("start to execute aclrtApiInjectionSetFunc, name is [%s].", name);
102 :
103 9 : aclrtApiEntry* entry = FindHookEntryByName(name);
104 9 : if (entry == nullptr) {
105 1 : ACL_LOG_ERROR("[aclrtApiInjectionSetFunc]This interface cannot be injected: [%s].", name);
106 1 : std::string funcName = acl::AclErrorLogManager::GetFuncNameWithoutImplSuffix(__func__);
107 4 : acl::AclErrorLogManager::ReportInputError(
108 : acl::INVALID_VALUE_MSG, {"func", "value", "param", "expect"},
109 1 : {funcName.c_str(), name, "name", "The API name is prefixed with aclrt or aclmdlRI"});
110 1 : return ACL_ERROR_INVALID_PARAM;
111 1 : }
112 8 : __atomic_store_n(&entry->currentFunc, func, __ATOMIC_RELEASE);
113 :
114 8 : ACL_LOG_INFO(
115 : "end to execute aclrtApiInjectionSetFunc, set to %s func, name is [%s].",
116 : ((func == entry->originalFunc) ? "original" : "hook"), name);
117 8 : return ACL_SUCCESS;
118 : #else // !ACL_RT_API_HOOK_ENABLE
119 : (void)name;
120 : (void)func;
121 : ACL_LOG_ERROR("[aclrtApiInjectionSetFunc]This feature is not supported.");
122 : acl::AclErrorLogManager::ReportInputError(acl::UNSUPPORTED_SYSTEM_MSG, {"func"}, {"aclrtApiInjectionSetFunc"});
123 : return ACL_ERROR_FEATURE_UNSUPPORTED;
124 : #endif // ACL_RT_API_HOOK_ENABLE
125 : }
126 :
127 23 : aclError aclrtApiInjectionGetFuncImpl(const char* name, aclrtApiFunc* originFunc, aclrtApiFunc* currentFunc)
128 : {
129 : #ifdef ACL_RT_API_HOOK_ENABLE
130 23 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(name);
131 22 : ACL_LOG_INFO("start to execute aclrtApiInjectionGetFunc, name is [%s].", name);
132 :
133 22 : aclrtApiEntry* entry = FindHookEntryByName(name);
134 22 : if (entry == nullptr) {
135 2 : ACL_LOG_ERROR("[aclrtApiInjectionGetFunc]This interface cannot be injected so cannot get: [%s].", name);
136 2 : std::string funcName = acl::AclErrorLogManager::GetFuncNameWithoutImplSuffix(__func__);
137 8 : acl::AclErrorLogManager::ReportInputError(
138 : acl::INVALID_VALUE_MSG, {"func", "value", "param", "expect"},
139 2 : {funcName.c_str(), name, "name", "The API name is prefixed with aclrt or aclmdlRI"});
140 2 : return ACL_ERROR_INVALID_PARAM;
141 2 : }
142 20 : if (originFunc != nullptr) {
143 16 : *originFunc = entry->originalFunc;
144 : }
145 20 : if (currentFunc != nullptr) {
146 16 : *currentFunc = __atomic_load_n(&entry->currentFunc, __ATOMIC_ACQUIRE);
147 : }
148 20 : ACL_LOG_INFO("end to execute aclrtApiInjectionGetFunc, name is [%s].", name);
149 20 : return ACL_SUCCESS;
150 : #else // !ACL_RT_API_HOOK_ENABLE
151 : (void)name;
152 : (void)originFunc;
153 : (void)currentFunc;
154 : ACL_LOG_ERROR("[aclrtApiInjectionGetFunc]This feature is not supported.");
155 : acl::AclErrorLogManager::ReportInputError(acl::UNSUPPORTED_SYSTEM_MSG, {"func"}, {"aclrtApiInjectionGetFunc"});
156 : return ACL_ERROR_FEATURE_UNSUPPORTED;
157 : #endif // ACL_RT_API_HOOK_ENABLE
158 : }
159 : #ifdef __cplusplus
160 : }
161 : #endif
|