GCC Code Coverage Report


Directory: src/gate/
File: src/gate/libraries.c
Date: 2025-12-12 23:40:09
Exec Total Coverage
Lines: 51 65 78.5%
Functions: 6 7 85.7%
Branches: 17 30 56.7%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28
29 #include "gate/libraries.h"
30 #include "gate/results.h"
31 #include "gate/platforms.h"
32
33 #if defined(GATE_SYS_WIN)
34 # define GATE_CORE_LIBRARIES_USE_WINAPI 1
35 #elif defined(GATE_SYS_POSIX)
36 # define GATE_CORE_LIBRARIES_USE_POSIX 1
37 #else
38 # define GATE_CORE_LIBRARIES_NO_IMPL 1
39 #endif
40
41
42 gate_result_t gate_library_get_function_name(gate_library_t lib, char const* funcname, void* ptrfunc)
43 {
44 gate_library_function_t func;
45 gate_string_t name;
46 gate_result_t res;
47 gate_string_create_static(&name, funcname);
48 res = gate_library_get_function(lib, &name, &func);
49 if (GATE_SUCCEEDED(res))
50 {
51 *((gate_library_function_t*)ptrfunc) = func;
52 }
53 else
54 {
55 *((gate_library_function_t*)ptrfunc) = NULL;
56 }
57 return res;
58 }
59
60 24 gate_result_t gate_library_get_data_name(gate_library_t lib, char const* entryname, void* ptr_data)
61 {
62 void* data;
63 gate_string_t name;
64 gate_result_t res;
65 24 gate_string_create_static(&name, entryname);
66 24 res = gate_library_get_data(lib, &name, &data);
67
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if (GATE_SUCCEEDED(res))
68 {
69 24 *((void**)ptr_data) = data;
70 }
71 else
72 {
73 *((void**)ptr_data) = NULL;
74 }
75 24 return res;
76 }
77
78
79
80 #if defined(GATE_CORE_LIBRARIES_USE_WINAPI)
81
82 #ifndef DONT_RESOLVE_DLL_REFERENCES
83 #define DONT_RESOLVE_DLL_REFERENCES 0x00000001
84 #endif
85
86 static gate_bool_t is_hmodule_valid(HMODULE hmod)
87 {
88 #if defined(GATE_SYS_WIN16)
89 return (hmod > HINSTANCE_ERROR);
90 #else
91 return (hmod != NULL);
92 #endif
93 }
94
95 gate_bool_t gate_library_support()
96 {
97 return true;
98 }
99
100 gate_result_t gate_library_open(gate_string_t const* path, gate_library_t* lib, gate_enumint_t flags)
101 {
102 gate_result_t ret;
103 TCHAR libpath[GATE_MAX_FILEPATH_LENGTH];
104 HMODULE hmod;
105 DWORD dwflags = 0;
106 gate_size_t libpathlen = gate_win32_utf8_2_winstr(path->str, path->length, libpath, sizeof(libpath) / sizeof(libpath[0]));
107 if (libpathlen == 0)
108 {
109 return GATE_RESULT_INVALIDDATA;
110 }
111 if (GATE_FLAG_ENABLED(flags, GATE_LIBRARY_FLAG_DATA))
112 {
113 dwflags |= DONT_RESOLVE_DLL_REFERENCES;
114 }
115 hmod = gate_win32_load_library(libpath, dwflags);
116 if (is_hmodule_valid(hmod))
117 {
118 *lib = (gate_library_t)hmod;
119 ret = GATE_RESULT_OK;
120 }
121 else
122 {
123 gate_win32_print_lasterror(&ret, NULL, 0);
124 }
125 return ret;
126 }
127 gate_result_t gate_library_close(gate_library_t lib)
128 {
129 gate_result_t ret;
130 HMODULE hmod = (HMODULE)lib;
131 BOOL succeeded = true;
132 #if !defined(GATE_SYS_WIN16)
133 succeeded =
134 #endif
135 FreeLibrary(hmod);
136 if (succeeded)
137 {
138 ret = GATE_RESULT_OK;
139 }
140 else
141 {
142 gate_win32_print_lasterror(&ret, NULL, 0);
143 }
144 return ret;
145 }
146 gate_result_t gate_library_get_function(gate_library_t lib, gate_string_t const* entryname, gate_library_function_t* func)
147 {
148 gate_result_t ret;
149 HMODULE hmod = (HMODULE)lib;
150 gate_size_t procnamelen;
151 FARPROC proc;
152 #if defined(GATE_SYS_WINCE)
153 TCHAR procname[GATE_MAX_FILENAME_LENGTH];
154 procnamelen = gate_win32_utf8_2_winstr(entryname->str, entryname->length, procname, sizeof(procname) / sizeof(procname[0]));
155 #else
156 char procname[GATE_MAX_FILENAME_LENGTH];
157 procnamelen = gate_str_print_text(procname, sizeof(procname) / sizeof(procname[0]), entryname->str, entryname->length);
158 #endif
159 if (procnamelen == 0)
160 {
161 return GATE_RESULT_INVALIDDATA;
162 }
163 proc = GetProcAddress(hmod, procname);
164 if (proc == NULL)
165 {
166 gate_win32_print_lasterror(&ret, NULL, 0);
167 }
168 else
169 {
170 *func = (gate_library_function_t)proc;
171 ret = GATE_RESULT_OK;
172 }
173 return ret;
174 }
175 gate_result_t gate_library_get_data(gate_library_t lib, gate_string_t const* entryname, void** data)
176 {
177 gate_library_function_t ptr;
178 gate_result_t ret = gate_library_get_function(lib, entryname, &ptr);
179 if (GATE_SUCCEEDED(ret))
180 {
181 *data = (void*)ptr;
182 }
183 return ret;
184 }
185
186 #endif /* GATE_CORE_LIBRARIES_USE_WINAPI */
187
188
189
190 #if defined(GATE_CORE_LIBRARIES_USE_POSIX)
191
192 # include "dlfcn.h"
193
194 1 gate_bool_t gate_library_support()
195 {
196 static gate_bool_t volatile test_completed = false;
197 static gate_bool_t volatile test_result = false;
198
199
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!test_completed)
200 {
201 1 void* proc_handle = gate_posix_dlopen(NULL, RTLD_LAZY);
202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (NULL == proc_handle)
203 {
204 /* dlopen not supported (e.g. in a static binary) */
205 test_result = false;
206 }
207 else
208 {
209 1 test_result = true;
210 1 gate_posix_dlclose(proc_handle);
211 }
212 1 test_completed = true;
213 }
214 1 return test_result;
215 }
216
217 6 gate_result_t gate_library_open(gate_string_t const* path, gate_library_t* lib, gate_enumint_t flags)
218 {
219 gate_result_t ret;
220
221 do
222 {
223 void* handle;
224 6 int dlflags = 0;
225 char libpath[GATE_MAX_FILEPATH_LENGTH];
226 6 gate_size_t libpathlen = gate_str_print_text(libpath, sizeof(libpath) / sizeof(libpath[0]), path->str, path->length);
227
228
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (libpathlen == 0)
229 {
230 ret = GATE_RESULT_INVALIDARG;
231 3 break;
232 }
233
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (GATE_FLAG_ENABLED(flags, GATE_LIBRARY_FLAG_DATA))
234 {
235 dlflags |= RTLD_LAZY;
236 }
237 else
238 {
239 6 dlflags |= RTLD_NOW;
240 }
241
242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (GATE_FLAG_ENABLED(flags, GATE_LIBRARY_FLAG_LOCAL))
243 {
244 dlflags |= RTLD_LOCAL;
245 }
246 else
247 {
248 6 dlflags |= RTLD_GLOBAL;
249 }
250
251 6 handle = gate_posix_dlopen(libpath, dlflags);
252
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (handle == NULL)
253 {
254 3 ret = GATE_RESULT_FAILED;
255 3 break;
256 }
257
258 /* success: */
259 3 *lib = (gate_library_t)handle;
260 3 ret = GATE_RESULT_OK;
261
262 } while (0);
263
264 6 return ret;
265 }
266 3 gate_result_t gate_library_close(gate_library_t lib)
267 {
268 3 void* handle = (void*)lib;
269 3 int errcode = gate_posix_dlclose(handle);
270
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 return ((errcode == 0) ? GATE_RESULT_OK : GATE_RESULT_FAILED);
271 }
272 4 gate_result_t gate_library_get_function(gate_library_t lib, gate_string_t const* entryname, gate_library_function_t* func)
273 {
274 gate_result_t ret;
275 void* dataptr;
276 4 ret = gate_library_get_data(lib, entryname, &dataptr);
277
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
4 if (GATE_SUCCEEDED(ret) && (func != NULL))
278 {
279 2 *func = (gate_library_function_t)dataptr;
280 }
281 4 return ret;
282 }
283 30 gate_result_t gate_library_get_data(gate_library_t lib, gate_string_t const* entryname, void** data)
284 {
285 gate_result_t ret;
286 30 void* handle = (void*)lib;
287 void* dataptr;
288 char name[GATE_MAX_FILENAME_LENGTH];
289 30 gate_size_t entrylen = gate_str_print_text(name, sizeof(name) / sizeof(name[0]), entryname->str, entryname->length);
290 do
291 {
292
2/4
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 30 times.
30 if ((handle == NULL) || (entrylen == 0))
293 {
294 ret = GATE_RESULT_INVALIDARG;
295 break;
296 }
297
298 30 dataptr = gate_posix_dlsym(handle, name);
299
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 26 times.
30 if (dataptr == NULL)
300 {
301 4 ret = GATE_RESULT_FAILED;
302 4 break;
303 }
304
305 /*success case*/
306
1/2
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
26 if (data != NULL)
307 {
308 26 *data = dataptr;
309 }
310 26 ret = GATE_RESULT_OK;
311
312 } while (0);
313
314 30 return ret;
315 }
316
317 #endif /* GATE_SYS_POSIX */
318
319
320
321 #if defined(GATE_CORE_LIBRARIES_NO_IMPL)
322
323 gate_bool_t gate_library_support()
324 {
325 return false;
326 }
327
328 gate_result_t gate_library_open(gate_string_t const* path, gate_library_t* lib, gate_enumint_t flags)
329 {
330 (void)path;
331 (void)lib;
332 (void)flags;
333 return GATE_RESULT_NOTSUPPORTED;
334 }
335 gate_result_t gate_library_close(gate_library_t lib)
336 {
337 (void)lib;
338 return GATE_RESULT_NOTSUPPORTED;
339 }
340 gate_result_t gate_library_get_function(gate_library_t lib, gate_string_t const* entryname, gate_library_function_t* ptr_func)
341 {
342 (void)lib;
343 (void)entryname;
344 (void)ptr_func;
345 return GATE_RESULT_NOTSUPPORTED;
346 }
347 gate_result_t gate_library_get_data(gate_library_t lib, gate_string_t const* entryname, void** ptr_data)
348 {
349 (void)lib;
350 (void)entryname;
351 (void)ptr_data;
352 return GATE_RESULT_NOTSUPPORTED;
353 }
354
355 #endif /* GATE_CORE_LIBRARIES_NO_IMPL */
356
357
358
359