1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include <dlfcn.h>
10 #include <unistd.h>
11 #include "hdf_log.h"
12 #include "osal_mem.h"
13 #include "securec.h"
14 #include "hdf_load_vdi.h"
15
16 #define HDF_LOG_TAG dev_load_vdi
17
18 #ifdef __ARCH64__
19 #define VDI_PATH HDF_LIBRARY_DIR"64/"
20 #else
21 #define VDI_PATH HDF_LIBRARY_DIR"/"
22 #endif
23
HdfLoadVdi(const char * libName)24 struct HdfVdiObject *HdfLoadVdi(const char *libName)
25 {
26 char path[PATH_MAX + 1] = {0};
27 char resolvedPath[PATH_MAX + 1] = {0};
28
29 if (libName == NULL) {
30 HDF_LOGE("%{public}s libName is NULL", __func__);
31 return NULL;
32 }
33
34 if (snprintf_s(path, sizeof(path), sizeof(path) - 1, "%s/%s", VDI_PATH, libName) < 0) {
35 HDF_LOGE("%{public}s %{public}s snprintf_s failed", __func__, libName);
36 return NULL;
37 }
38
39 if (realpath(path, resolvedPath) == NULL || strncmp(resolvedPath, VDI_PATH, strlen(VDI_PATH)) != 0) {
40 HDF_LOGE("%{public}s %{public}s %{public}s realpath file name failed %{public}d",
41 __func__, path, resolvedPath, errno);
42 return NULL;
43 }
44
45 struct HdfVdiObject *vdiObj = (struct HdfVdiObject *)OsalMemCalloc(sizeof(*vdiObj));
46 if (vdiObj == NULL) {
47 HDF_LOGE("%{public}s malloc failed", __func__);
48 return NULL;
49 }
50
51 void *handler = dlopen(resolvedPath, RTLD_LAZY);
52 if (handler == NULL) {
53 HDF_LOGE("%{public}s dlopen failed %{public}s", __func__, dlerror());
54 OsalMemFree(vdiObj);
55 return NULL;
56 }
57
58 struct HdfVdiBase **vdiBase = (struct HdfVdiBase **)dlsym(handler, "hdfVdiDesc");
59 if (vdiBase == NULL || *vdiBase == NULL) {
60 HDF_LOGE("%{public}s dlsym hdfVdiDesc failed %{public}s", __func__, dlerror());
61 dlclose(handler);
62 OsalMemFree(vdiObj);
63 return NULL;
64 }
65
66 if ((*vdiBase)->CreateVdiInstance) {
67 (*vdiBase)->CreateVdiInstance(*vdiBase);
68 }
69
70 vdiObj->dlHandler = (uintptr_t)handler;
71 vdiObj->vdiBase = *vdiBase;
72
73 return vdiObj;
74 }
75
HdfGetVdiVersion(const struct HdfVdiObject * vdiObj)76 uint32_t HdfGetVdiVersion(const struct HdfVdiObject *vdiObj)
77 {
78 if (vdiObj == NULL || vdiObj->vdiBase == NULL) {
79 HDF_LOGE("%{public}s para is invalid", __func__);
80 return HDF_INVALID_VERSION;
81 }
82
83 return vdiObj->vdiBase->moduleVersion;
84 }
85
HdfCloseVdi(struct HdfVdiObject * vdiObj)86 void HdfCloseVdi(struct HdfVdiObject *vdiObj)
87 {
88 if (vdiObj == NULL || vdiObj->dlHandler == 0 || vdiObj->vdiBase == NULL) {
89 HDF_LOGE("%{public}s para invalid", __func__);
90 return;
91 }
92
93 struct HdfVdiBase *vdiBase = vdiObj->vdiBase;
94 if (vdiBase->DestoryVdiInstance) {
95 vdiBase->DestoryVdiInstance(vdiBase);
96 }
97
98 dlclose((void *)vdiObj->dlHandler);
99 vdiObj->dlHandler = 0;
100 vdiObj->vdiBase = NULL;
101 OsalMemFree(vdiObj);
102 }
103
104