Coverage Report

Created: 2025-03-06 06:58

/src/gnutls/lib/dlwrap/zlib.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copying and distribution of this file, with or without modification,
3
 * are permitted in any medium without royalty provided the copyright
4
 * notice and this notice are preserved.  This file is offered as-is,
5
 * without any warranty.
6
 */
7
8
#ifdef HAVE_CONFIG_H
9
#include "config.h"
10
#endif
11
12
#include "zlib.h"
13
14
#if defined(GNUTLS_ZLIB_ENABLE_DLOPEN) && GNUTLS_ZLIB_ENABLE_DLOPEN
15
16
#include <assert.h>
17
#include <dlfcn.h>
18
#include <errno.h>
19
#include <stdlib.h>
20
21
/* If Z_LIBRARY_SONAME_UNUSED is defined, dlopen handle can be automatically
22
 * set; otherwise, the caller needs to call
23
 * gnutls_zlib_ensure_library with soname determined at run time.
24
 */
25
#ifdef Z_LIBRARY_SONAME_UNUSED
26
27
static void
28
ensure_library (void)
29
{
30
  if (gnutls_zlib_ensure_library (Z_LIBRARY_SONAME_UNUSED, RTLD_LAZY | RTLD_LOCAL) < 0)
31
    abort ();
32
}
33
34
#if defined(GNUTLS_ZLIB_ENABLE_PTHREAD) && GNUTLS_ZLIB_ENABLE_PTHREAD
35
#include <pthread.h>
36
37
static pthread_once_t dlopen_once = PTHREAD_ONCE_INIT;
38
39
#define ENSURE_LIBRARY pthread_once(&dlopen_once, ensure_library)
40
41
#else /* GNUTLS_ZLIB_ENABLE_PTHREAD */
42
43
#define ENSURE_LIBRARY do {     \
44
    if (!gnutls_zlib_dlhandle) \
45
      ensure_library();       \
46
  } while (0)
47
48
#endif /* !GNUTLS_ZLIB_ENABLE_PTHREAD */
49
50
#else /* Z_LIBRARY_SONAME_UNUSED */
51
52
0
#define ENSURE_LIBRARY do {} while (0)
53
54
#endif /* !Z_LIBRARY_SONAME_UNUSED */
55
56
static void *gnutls_zlib_dlhandle;
57
58
/* Define redirection symbols */
59
#pragma GCC diagnostic push
60
#pragma GCC diagnostic ignored "-Wunused-macros"
61
62
#if (2 <= __GNUC__ || (4 <= __clang_major__))
63
#define FUNC(ret, name, args, cargs)      \
64
  static __typeof__(name)(*gnutls_zlib_sym_##name);
65
#else
66
#define FUNC(ret, name, args, cargs)    \
67
  static ret(*gnutls_zlib_sym_##name)args;
68
#endif
69
#define VOID_FUNC FUNC
70
#include "zlibfuncs.h"
71
#undef VOID_FUNC
72
#undef FUNC
73
74
#pragma GCC diagnostic pop
75
76
/* Define redirection wrapper functions */
77
#pragma GCC diagnostic push
78
#pragma GCC diagnostic ignored "-Wunused-macros"
79
80
#define FUNC(ret, name, args, cargs)        \
81
0
ret gnutls_zlib_func_##name args           \
82
0
{             \
83
0
  ENSURE_LIBRARY;         \
84
0
  assert (gnutls_zlib_sym_##name);      \
85
0
  return gnutls_zlib_sym_##name cargs;     \
86
0
}
Unexecuted instantiation: gnutls_zlib_func_compress
Unexecuted instantiation: gnutls_zlib_func_compressBound
Unexecuted instantiation: gnutls_zlib_func_uncompress
87
#define VOID_FUNC(ret, name, args, cargs)   \
88
ret gnutls_zlib_func_##name args           \
89
{             \
90
  ENSURE_LIBRARY;         \
91
  assert (gnutls_zlib_sym_##name);      \
92
  gnutls_zlib_sym_##name cargs;       \
93
}
94
#include "zlibfuncs.h"
95
#undef VOID_FUNC
96
#undef FUNC
97
98
#pragma GCC diagnostic pop
99
100
static int
101
ensure_symbol (const char *name, void **symp)
102
0
{
103
0
  if (!*symp)
104
0
    {
105
0
      void *sym = dlsym (gnutls_zlib_dlhandle, name);
106
0
      if (!sym)
107
0
  return -EINVAL;
108
0
      *symp = sym;
109
0
    }
110
0
  return 0;
111
0
}
112
113
int
114
gnutls_zlib_ensure_library (const char *soname, int flags)
115
0
{
116
0
  int err;
117
118
0
  if (!gnutls_zlib_dlhandle)
119
0
    {
120
0
      gnutls_zlib_dlhandle = dlopen (soname, flags);
121
0
      if (!gnutls_zlib_dlhandle)
122
0
  return -EINVAL;
123
0
    }
124
125
0
#define ENSURE_SYMBOL(name)         \
126
0
  ensure_symbol(#name, (void **)&gnutls_zlib_sym_##name)
127
128
0
#pragma GCC diagnostic push
129
0
#pragma GCC diagnostic ignored "-Wunused-macros"
130
131
0
#define FUNC(ret, name, args, cargs)    \
132
0
  err = ENSURE_SYMBOL(name);     \
133
0
  if (err < 0)         \
134
0
    {           \
135
0
      dlclose (gnutls_zlib_dlhandle); \
136
0
      gnutls_zlib_dlhandle = NULL;    \
137
0
      return err;       \
138
0
    }
139
0
#define VOID_FUNC FUNC
140
0
#include "zlibfuncs.h"
141
0
#undef VOID_FUNC
142
0
#undef FUNC
143
144
0
#pragma GCC diagnostic pop
145
146
0
#undef ENSURE_SYMBOL
147
0
  return 0;
148
0
}
149
150
void
151
gnutls_zlib_unload_library (void)
152
0
{
153
0
  if (gnutls_zlib_dlhandle)
154
0
    {
155
0
      dlclose (gnutls_zlib_dlhandle);
156
0
      gnutls_zlib_dlhandle = NULL;
157
0
    }
158
159
0
#pragma GCC diagnostic push
160
0
#pragma GCC diagnostic ignored "-Wunused-macros"
161
162
0
#define FUNC(ret, name, args, cargs)    \
163
0
  gnutls_zlib_sym_##name = NULL;
164
0
#define VOID_FUNC FUNC
165
0
#include "zlibfuncs.h"
166
0
#undef VOID_FUNC
167
0
#undef FUNC
168
169
0
#pragma GCC diagnostic pop
170
0
}
171
172
unsigned
173
gnutls_zlib_is_usable (void)
174
0
{
175
0
  return gnutls_zlib_dlhandle != NULL;
176
0
}
177
178
#else /* GNUTLS_ZLIB_ENABLE_DLOPEN */
179
180
int
181
gnutls_zlib_ensure_library (const char *soname, int flags)
182
{
183
  (void) soname;
184
  (void) flags;
185
  return 0;
186
}
187
188
void
189
gnutls_zlib_unload_library (void)
190
{
191
}
192
193
unsigned
194
gnutls_zlib_is_usable (void)
195
{
196
  /* The library is linked at build time, thus always usable */
197
  return 1;
198
}
199
200
#endif /* !GNUTLS_ZLIB_ENABLE_DLOPEN */