1 /**
2 * Copyright (c) 2025 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 #include <cstring>
17 #include "plugins/ets/runtime/ets_namespace_manager_impl.h"
18 #include "libpandabase/utils/logger.h"
19
20 namespace ark::ets {
21
~EtsNamespaceManagerImpl()22 EtsNamespaceManagerImpl::~EtsNamespaceManagerImpl()
23 {
24 os::memory::WriteLockHolder lock(lock_);
25 namespaceNames_.clear();
26 }
27
GetInstance()28 EtsNamespaceManagerImpl &EtsNamespaceManagerImpl::GetInstance()
29 {
30 static EtsNamespaceManagerImpl instance;
31 return instance;
32 }
33
RegisterNamespaceName(const std::string & key,const std::string & value)34 void EtsNamespaceManagerImpl::RegisterNamespaceName(const std::string &key, const std::string &value)
35 {
36 os::memory::WriteLockHolder lock(lock_);
37 namespaceNames_[key] = value;
38 }
39
LoadNativeLibraryFromNs(const std::string & pathKey,const char * name)40 Expected<EtsNativeLibrary, os::Error> EtsNamespaceManagerImpl::LoadNativeLibraryFromNs(const std::string &pathKey,
41 const char *name)
42 {
43 LOG(INFO, RUNTIME) << "EtsNamespaceManagerImpl::LoadNativeLibraryFromNs pathKey :" << pathKey.c_str()
44 << " loading library name :" << name;
45 #if defined(PANDA_TARGET_OHOS) && !defined(PANDA_CMAKE_SDK)
46 PandaString errInfo = "EtsNamespaceManagerImpl::LoadNativeLibraryFromNs: ";
47 std::string abcPath = pathKey;
48 std::string namespaceName;
49 os::memory::ReadLockHolder lock(lock_);
50 if (namespaceNames_.find(abcPath) != namespaceNames_.end()) {
51 namespaceName = namespaceNames_[abcPath];
52 } else {
53 abcPath = "default";
54 if (namespaceNames_.find(abcPath) != namespaceNames_.end()) {
55 LOG(WARNING, RUNTIME) << "EtsNamespaceManagerImpl::LoadNativeLibraryFromNs: " << abcPath.c_str()
56 << "not find namespaceNames_, use `pathNS_default` ns";
57 namespaceName = namespaceNames_[abcPath];
58 } else {
59 errInfo += "pathKey: " + abcPath + " and `default` not found in namespaceNames_";
60 return Unexpected(os::Error(errInfo.c_str()));
61 }
62 }
63 Dl_namespace ns;
64 if (dlns_get(namespaceName.data(), &ns) != 0) {
65 errInfo += "pathKey: " + abcPath + "namespaceName: " + namespaceName + " not found";
66 return Unexpected(os::Error(errInfo.c_str()));
67 }
68 void *nativeHandle = nullptr;
69 nativeHandle = dlopen_ns(&ns, name, RTLD_LAZY);
70 if (nativeHandle == nullptr) {
71 char *dlerr = dlerror();
72 auto dlerrMsg = dlerr != nullptr ? dlerr
73 : "Error loading path " + std::string(name) + "in namespace" +
74 std::string(namespaceName) + ":No such file or directory";
75 errInfo += "load app library failed. " + std::string(dlerrMsg);
76 return Unexpected(os::Error(errInfo.c_str()));
77 }
78 os::library_loader::LibraryHandle handle(nativeHandle);
79 return EtsNativeLibrary(PandaString(name), std::move(handle));
80 #endif
81 return Unexpected(os::Error("not support platform"));
82 }
83 } // namespace ark::ets