GCC Code Coverage Report


Directory: src/gate/
File: src/gate/libraries.c
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 50 65 76.9%
Functions: 6 7 85.7%
Branches: 16 30 53.3%

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 22 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 22 gate_string_create_static(&name, entryname);
66 22 res = gate_library_get_data(lib, &name, &data);
67
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
22 if (GATE_SUCCEEDED(res))
68 {
69 22 *((void**)ptr_data) = data;
70 }
71 else
72 {
73 *((void**)ptr_data) = NULL;
74 }
75 22 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 void* handle;
221 6 int dlflags = 0;
222 char libpath[GATE_MAX_FILEPATH_LENGTH];
223 6 gate_size_t libpathlen = gate_str_print_text(libpath, sizeof(libpath) / sizeof(libpath[0]), path->str, path->length);
224
225 do
226 {
227
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (libpathlen == 0)
228 {
229 ret = GATE_RESULT_INVALIDARG;
230 break;
231 }
232
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (GATE_FLAG_ENABLED(flags, GATE_LIBRARY_FLAG_DATA))
233 {
234 dlflags |= RTLD_LAZY;
235 }
236 else
237 {
238 6 dlflags |= RTLD_NOW;
239 }
240
241
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (GATE_FLAG_ENABLED(flags, GATE_LIBRARY_FLAG_LOCAL))
242 {
243 dlflags |= RTLD_LOCAL;
244 }
245 else
246 {
247 6 dlflags |= RTLD_GLOBAL;
248 }
249
250 6 handle = gate_posix_dlopen(libpath, dlflags);
251
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (handle == NULL)
252 {
253 3 ret = GATE_RESULT_FAILED;
254 3 break;
255 }
256
257 /* success: */
258 3 *lib = (gate_library_t)handle;
259 3 ret = GATE_RESULT_OK;
260
261 } while (0);
262
263 6 return ret;
264 }
265 3 gate_result_t gate_library_close(gate_library_t lib)
266 {
267 3 void* handle = (void*)lib;
268 3 int errcode = gate_posix_dlclose(handle);
269
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 return ((errcode == 0) ? GATE_RESULT_OK : GATE_RESULT_FAILED);
270 }
271 2 gate_result_t gate_library_get_function(gate_library_t lib, gate_string_t const* entryname, gate_library_function_t* func)
272 {
273 gate_result_t ret;
274 void* dataptr;
275 2 ret = gate_library_get_data(lib, entryname, &dataptr);
276
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 if (GATE_SUCCEEDED(ret) && (func != NULL))
277 {
278 2 *func = (gate_library_function_t)dataptr;
279 }
280 2 return ret;
281 }
282 26 gate_result_t gate_library_get_data(gate_library_t lib, gate_string_t const* entryname, void** data)
283 {
284 gate_result_t ret;
285 26 void* handle = (void*)lib;
286 void* dataptr;
287 char name[GATE_MAX_FILENAME_LENGTH];
288 26 gate_size_t entrylen = gate_str_print_text(name, sizeof(name) / sizeof(name[0]), entryname->str, entryname->length);
289 do
290 {
291
2/4
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 26 times.
26 if ((handle == NULL) || (entrylen == 0))
292 {
293 ret = GATE_RESULT_INVALIDARG;
294 break;
295 }
296
297 26 dataptr = gate_posix_dlsym(handle, name);
298
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 24 times.
26 if (dataptr == NULL)
299 {
300 2 ret = GATE_RESULT_FAILED;
301 2 break;
302 }
303
304 /*success case*/
305
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if (data != NULL)
306 {
307 24 *data = dataptr;
308 }
309 24 ret = GATE_RESULT_OK;
310
311 } while (0);
312
313 26 return ret;
314 }
315
316 #endif /* GATE_SYS_POSIX */
317
318
319
320 #if defined(GATE_CORE_LIBRARIES_NO_IMPL)
321
322 gate_bool_t gate_library_support()
323 {
324 return false;
325 }
326
327 gate_result_t gate_library_open(gate_string_t const* path, gate_library_t* lib, gate_enumint_t flags)
328 {
329 (void)path;
330 (void)lib;
331 (void)flags;
332 return GATE_RESULT_NOTSUPPORTED;
333 }
334 gate_result_t gate_library_close(gate_library_t lib)
335 {
336 (void)lib;
337 return GATE_RESULT_NOTSUPPORTED;
338 }
339 gate_result_t gate_library_get_function(gate_library_t lib, gate_string_t const* entryname, gate_library_function_t* ptr_func)
340 {
341 (void)lib;
342 (void)entryname;
343 (void)ptr_func;
344 return GATE_RESULT_NOTSUPPORTED;
345 }
346 gate_result_t gate_library_get_data(gate_library_t lib, gate_string_t const* entryname, void** ptr_data)
347 {
348 (void)lib;
349 (void)entryname;
350 (void)ptr_data;
351 return GATE_RESULT_NOTSUPPORTED;
352 }
353
354 #endif /* GATE_CORE_LIBRARIES_NO_IMPL */
355
356
357
358