xref: /aosp_15_r20/external/deqp/framework/delibs/deutil/deDynamicLibrary.c (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * drawElements Utility Library
3  * ----------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Dynamic link library abstraction.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "deDynamicLibrary.h"
25 #include "deMemory.h"
26 
27 #if (DE_OS == DE_OS_UNIX) || (DE_OS == DE_OS_ANDROID) || (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_SYMBIAN) || \
28     (DE_OS == DE_OS_IOS) || (DE_OS == DE_OS_QNX) || (DE_OS == DE_OS_FUCHSIA)
29 /* Posix implementation. */
30 
31 #include <dlfcn.h>
32 #include <libgen.h>
33 #include <stdlib.h>
34 
35 struct deDynamicLibrary_s
36 {
37     void *libHandle;
38 };
39 
deDynamicLibrary_open(const char * fileName)40 deDynamicLibrary *deDynamicLibrary_open(const char *fileName)
41 {
42     deDynamicLibrary *library = (deDynamicLibrary *)deCalloc(sizeof(deDynamicLibrary));
43     if (!library)
44         return DE_NULL;
45 
46     if (getenv("LD_LIBRARY_PATH"))
47     {
48         // basename() requires a non-const string because it may modify the its contents, so we cannot pass fileName to
49         // it directly. The string may be coming from statically allocated memory. E.g. this segfaulted in FreeBSD.
50         char *aux = deStrdup(fileName);
51         if (!aux)
52             return NULL;
53         library->libHandle = dlopen(basename(aux), RTLD_LAZY);
54         deFree(aux);
55     }
56     else
57         library->libHandle = dlopen(fileName, RTLD_LAZY);
58 
59     if (!library->libHandle)
60     {
61         deFree(library);
62         return DE_NULL;
63     }
64 
65     return library;
66 }
67 
deDynamicLibrary_close(deDynamicLibrary * library)68 void deDynamicLibrary_close(deDynamicLibrary *library)
69 {
70     if (library && library->libHandle)
71         dlclose(library->libHandle);
72     deFree(library);
73 }
74 
deDynamicLibrary_getFunction(const deDynamicLibrary * library,const char * symbolName)75 deFunctionPtr deDynamicLibrary_getFunction(const deDynamicLibrary *library, const char *symbolName)
76 {
77     /* C forbids direct cast from object pointer to function pointer */
78     union
79     {
80         deFunctionPtr funcPtr;
81         void *objPtr;
82     } ptr;
83 
84     DE_ASSERT(library && library->libHandle && symbolName);
85     ptr.objPtr = dlsym(library->libHandle, symbolName);
86     return ptr.funcPtr;
87 }
88 
89 #elif (DE_OS == DE_OS_WIN32)
90 /* Win32 implementation. */
91 
92 #define WIN32_LEAN_AND_MEAN
93 #define VC_EXTRALEAN
94 #include <windows.h>
95 
96 struct deDynamicLibrary_s
97 {
98     HINSTANCE handle;
99 };
100 
deDynamicLibrary_open(const char * fileName)101 deDynamicLibrary *deDynamicLibrary_open(const char *fileName)
102 {
103     deDynamicLibrary *library = (deDynamicLibrary *)deCalloc(sizeof(deDynamicLibrary));
104     if (!library)
105         return DE_NULL;
106 
107     library->handle = LoadLibrary(fileName);
108     if (!library->handle)
109     {
110         deFree(library);
111         return DE_NULL;
112     }
113 
114     return library;
115 }
116 
deDynamicLibrary_close(deDynamicLibrary * library)117 void deDynamicLibrary_close(deDynamicLibrary *library)
118 {
119     if (library && library->handle)
120         FreeLibrary(library->handle);
121     deFree(library);
122 }
123 
deDynamicLibrary_getFunction(const deDynamicLibrary * library,const char * symbolName)124 deFunctionPtr deDynamicLibrary_getFunction(const deDynamicLibrary *library, const char *symbolName)
125 {
126     DE_ASSERT(library && library->handle && symbolName);
127     return (deFunctionPtr)GetProcAddress(library->handle, symbolName);
128 }
129 
130 #else
131 #error deDynamicLibrary is not implemented on this OS
132 #endif
133