• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "dynamic_loader.h"
17 
18 #include <cstdio>
19 #include <dlfcn.h>
20 #include <securec.h>
21 #include <string>
22 #include <unordered_set>
23 
24 #include "hilog_tag_wrapper.h"
25 
26 namespace OHOS {
27 namespace EtsEnv {
28 namespace {
29 constexpr int32_t ERROR_BUF_SIZE = 255;
30 static char g_dlError[ERROR_BUF_SIZE];
31 static std::unordered_set<std::string> g_hasInited;
32 static std::string g_sharedLibsSonames = "";
33 constexpr int32_t OUT_OF_MEMORY = 12;
34 constexpr int32_t FILE_EXISTS = 17;
35 constexpr int32_t INVALID_ARGUMENT = 22;
36 
ReadDlError()37 static void ReadDlError()
38 {
39     char *errMsg = dlerror();
40     if (!errMsg) {
41         return;
42     }
43     auto ends = sprintf_s(g_dlError, sizeof(g_dlError), "%s", errMsg);
44     if (ends < 0) {
45         return;
46     } else if (ends >= ERROR_BUF_SIZE) {
47         g_dlError[ERROR_BUF_SIZE - 1] = '\0';
48     } else {
49         g_dlError[ends] = '\0';
50     }
51 }
52 
InitSharedLibsSonames()53 static void InitSharedLibsSonames()
54 {
55     if (!g_sharedLibsSonames.empty()) {
56         return;
57     }
58     g_sharedLibsSonames =
59         // bionic library
60         "libc.so:"
61         "libdl.so:"
62         "libm.so:"
63         "libz.so:"
64         "libclang_rt.asan.so:"
65         "libclang_rt.tsan.so:"
66         // z library
67         "libace_napi.z.so:"
68         "libace_ndk.z.so:"
69         "libbundle_ndk.z.so:"
70         "libdeviceinfo_ndk.z.so:"
71         "libEGL.so:"
72         "libGLESv3.so:"
73         "libhiappevent_ndk.z.so:"
74         "libhuks_ndk.z.so:"
75         "libhukssdk.z.so:"
76         "libnative_drawing.so:"
77         "libnative_window.so:"
78         "libnative_buffer.so:"
79         "libnative_vsync.so:"
80         "libOpenSLES.so:"
81         "libpixelmap_ndk.z.so:"
82         "libimage_ndk.z.so:"
83         "libimage_receiver_ndk.z.so:"
84         "libimage_source_ndk.z.so:"
85         "librawfile.z.so:"
86         "libuv.so:"
87         "libhilog.so:"
88         "libnative_image.so:"
89         "libnative_media_adec.so:"
90         "libnative_media_aenc.so:"
91         "libnative_media_codecbase.so:"
92         "libnative_media_core.so:"
93         "libnative_media_vdec.so:"
94         "libnative_media_venc.so:"
95         "libnative_media_avmuxer.so:"
96         "libnative_media_avdemuxer.so:"
97         "libnative_media_avsource.so:"
98         "libnative_avscreen_capture.so:"
99         "libavplayer.so:"
100         // adaptor library
101         "libohosadaptor.so:"
102         "libusb_ndk.z.so:"
103         "libvulkan.so:"
104         // runtime library
105         "libarkaotmanager.so:"
106         "libarktarget_options.so:"
107         "libhmicui18n.z.so:"
108         "libes2panda-public.so:"
109         "libes2panda-lib.so:"
110         "libhmicuuc.z.so:"
111         "libarkcompiler.so:"
112         "libarkassembler.so:"
113         "libarkfile.so:"
114         "libarkziparchive.so:"
115         "libarkbase.so:"
116         "libc_secshared.so:"
117         "libhilog_ndk.z.so:"
118         "libarkplatform.so";
119 }
120 } // namespace
121 
DynamicInitNamespace(Dl_namespace * ns,void * parent,const char * entries,const char * name)122 void DynamicInitNamespace(Dl_namespace *ns, void *parent, const char *entries, const char *name)
123 {
124     if (ns == nullptr || entries == nullptr || name == nullptr) {
125         TAG_LOGE(AAFwkTag::ETSRUNTIME, "Invaild args for init namespace.");
126         return;
127     }
128     if (g_hasInited.count(std::string(name))) {
129         return;
130     }
131     dlns_init(ns, name);
132     auto status = dlns_create2(ns, entries, 0);
133     std::string errMsg;
134     if (status != 0) {
135         switch (status) {
136             case FILE_EXISTS:
137                 errMsg = "dlns_create failed: File exists";
138                 break;
139             case INVALID_ARGUMENT:
140                 errMsg = "dlns_create failed: Invalid argument";
141                 break;
142             case OUT_OF_MEMORY:
143                 errMsg = "dlns_create failed: Out of memory";
144                 break;
145             default:
146                 errMsg = "dlns_create failed, status: " + std::to_string(status);
147         }
148         if (sprintf_s(g_dlError, sizeof(g_dlError), errMsg.c_str()) == -1) {
149             TAG_LOGE(AAFwkTag::ETSRUNTIME, "Fail to generate error msg.");
150             return;
151         }
152         return;
153     }
154     if (parent) {
155         dlns_inherit((Dl_namespace *)parent, ns, "allow_all_shared_libs");
156     }
157     Dl_namespace current;
158     dlns_get(nullptr, &current);
159     if (strcmp(name, "ets_app") != 0) {
160         dlns_inherit(ns, &current, "allow_all_shared_libs");
161     } else {
162         InitSharedLibsSonames();
163         dlns_inherit(ns, &current, g_sharedLibsSonames.c_str());
164     }
165     g_hasInited.insert(std::string(name));
166 }
167 
DynamicLoadLibrary(Dl_namespace * ns,const char * dlPath,uint32_t mode)168 void *DynamicLoadLibrary(Dl_namespace *ns, const char *dlPath, uint32_t mode)
169 {
170     if (ns == nullptr) {
171         dlns_get("ets_app", ns);
172     }
173 
174     auto result = dlopen_ns(ns, dlPath, mode | RTLD_GLOBAL | RTLD_NOW);
175     if (!result) {
176         ReadDlError();
177     }
178     return result;
179 }
180 
DynamicFindSymbol(void * so,const char * symbol)181 void *DynamicFindSymbol(void *so, const char *symbol)
182 {
183     return dlsym(so, symbol);
184 }
185 
DynamicFreeLibrary(void * so)186 void DynamicFreeLibrary(void *so)
187 {
188     (void)dlclose(so);
189 }
190 
DynamicGetError()191 const char *DynamicGetError()
192 {
193     return g_dlError;
194 }
195 } // namespace EtsEnv
196 } // namespace OHOS