1 /*
2 * Copyright (c) 2021 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 <dlfcn.h>
17 #include <unistd.h>
18 #include "hdf_base.h"
19 #include "hdf_load_hdi.h"
20 #include "hdf_log.h"
21 #include "osal_mem.h"
22 #include "securec.h"
23
24 #define HDF_LOG_TAG dev_load_hdi
25
26 #ifdef __ARM64__
27 #define HDI_SO_PATH HDF_LIBRARY_DIR"64"
28 #else
29 #define HDI_SO_PATH HDF_LIBRARY_DIR
30 #endif
LoadHdi(const char * name,uint32_t version)31 struct HdiObject *LoadHdi(const char *name, uint32_t version)
32 {
33 char path[PATH_MAX + 1] = {0};
34 char resolvedPath[PATH_MAX + 1] = {0};
35
36 if (name == NULL) {
37 HDF_LOGE("name is NULL");
38 return NULL;
39 }
40
41 if (snprintf_s(path, sizeof(path), sizeof(path) - 1, "%s/%s", HDI_SO_PATH, name) < 0) {
42 HDF_LOGE("%{public}s snprintf_s failed", __func__);
43 return NULL;
44 }
45 if (realpath(path, resolvedPath) == NULL) {
46 HDF_LOGE("%{public}s file name invalid", __func__);
47 return NULL;
48 }
49
50 struct HdiObject *hdi = (struct HdiObject *)OsalMemCalloc(sizeof(*hdi));
51 if (hdi == NULL) {
52 HDF_LOGE("%{public}s malloc failed", __func__);
53 return NULL;
54 }
55 void *handler = dlopen(resolvedPath, RTLD_LAZY);
56 if (handler == NULL) {
57 HDF_LOGE("%{public}s dlopen failed %{public}s", __func__, dlerror());
58 OsalMemFree(hdi);
59 return NULL;
60 }
61 struct HdiBase *base = *(struct HdiBase **)dlsym(handler, "hdfHdiDesc");
62 if (base == NULL) {
63 HDF_LOGE("%{public}s dlsym failed %{public}s", __func__, dlerror());
64 dlclose(handler);
65 OsalMemFree(hdi);
66 return NULL;
67 }
68 if (version != base->moduleVersion) {
69 dlclose(handler);
70 OsalMemFree(hdi);
71 return NULL;
72 }
73 if (base->OpenHdi) {
74 base->OpenHdi();
75 }
76 hdi->dlHandler = (uintptr_t)handler;
77 hdi->hdiBase = base;
78 return hdi;
79 }
80
CloseHdi(struct HdiObject * hdi)81 void CloseHdi(struct HdiObject *hdi)
82 {
83 if (hdi == NULL || hdi->dlHandler == 0 || hdi->hdiBase == NULL) {
84 HDF_LOGE("%{public}s para invalid", __func__);
85 return;
86 }
87
88 struct HdiBase *base = hdi->hdiBase;
89
90 if (base->CloseHdi) {
91 base->CloseHdi();
92 }
93
94 dlclose((void *)hdi->dlHandler);
95 hdi->dlHandler = 0;
96 hdi->hdiBase = NULL;
97 OsalMemFree(hdi);
98 }
99
100