Rename internal ust_err to lttng_ust_logging
[lttng-ust.git] / src / lib / lttng-ust-dl / lttng-ust-dl.c
1 /*
2 * SPDX-License-Identifier: LGPL-2.1-only
3 *
4 * Copyright (C) 2013 Paul Woegerer <paul.woegerer@mentor.com>
5 * Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
6 * Copyright (C) 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 */
8
9 #define _LGPL_SOURCE
10
11 /* Has to be included first to override dlfcn.h */
12 #include <common/compat/dlfcn.h>
13
14 #include <limits.h>
15 #include <stdio.h>
16 #include <stdint.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19
20 #include "common/elf.h"
21 #include <lttng/ust-events.h>
22 #include "common/macros.h"
23 #include "common/logging.h"
24
25 #include "lib/lttng-ust/ust-events-internal.h"
26
27 /* Include link.h last else it conflicts with ust-dlfcn. */
28 #include <link.h>
29
30 #define TRACEPOINT_DEFINE
31 #include "ust_dl.h"
32
33 static void *(*__lttng_ust_plibc_dlopen)(const char *filename, int flags);
34 #ifdef HAVE_DLMOPEN
35 static void *(*__lttng_ust_plibc_dlmopen)(Lmid_t nsid, const char *filename,
36 int flags);
37 #endif
38 static int (*__lttng_ust_plibc_dlclose)(void *handle);
39
40 static
41 void _lttng_ust_dl_init(void)
42 __attribute__((constructor));
43 static
44 void _lttng_ust_dl_init(void)
45 {
46 lttng_ust_logging_init();
47 }
48
49 static
50 void *_lttng_ust_dl_libc_dlopen(const char *filename, int flags)
51 {
52 if (!__lttng_ust_plibc_dlopen) {
53 __lttng_ust_plibc_dlopen = dlsym(RTLD_NEXT, "dlopen");
54 if (!__lttng_ust_plibc_dlopen) {
55 fprintf(stderr, "%s\n", dlerror());
56 return NULL;
57 }
58 }
59 return __lttng_ust_plibc_dlopen(filename, flags);
60 }
61
62 #ifdef HAVE_DLMOPEN
63 static
64 void *_lttng_ust_dl_libc_dlmopen(Lmid_t nsid, const char *filename,
65 int flags)
66 {
67 if (!__lttng_ust_plibc_dlmopen) {
68 __lttng_ust_plibc_dlmopen = dlsym(RTLD_NEXT, "dlmopen");
69 if (!__lttng_ust_plibc_dlmopen) {
70 fprintf(stderr, "%s\n", dlerror());
71 return NULL;
72 }
73 }
74 return __lttng_ust_plibc_dlmopen(nsid, filename, flags);
75 }
76 #endif
77
78 static
79 int _lttng_ust_dl_libc_dlclose(void *handle)
80 {
81 if (!__lttng_ust_plibc_dlclose) {
82 __lttng_ust_plibc_dlclose = dlsym(RTLD_NEXT, "dlclose");
83 if (!__lttng_ust_plibc_dlclose) {
84 fprintf(stderr, "%s\n", dlerror());
85 return -1;
86 }
87 }
88 return __lttng_ust_plibc_dlclose(handle);
89 }
90
91 static
92 void lttng_ust_dl_dlopen(void *so_base, const char *so_name,
93 int flags, void *ip)
94 {
95 char resolved_path[PATH_MAX];
96 struct lttng_ust_elf *elf;
97 uint64_t memsz;
98 uint8_t *build_id = NULL;
99 size_t build_id_len;
100 char *dbg_file = NULL;
101 uint32_t crc;
102 int has_build_id = 0, has_debug_link = 0;
103 int ret;
104
105 if (!realpath(so_name, resolved_path)) {
106 ERR("could not resolve path '%s'", so_name);
107 return;
108 }
109
110 elf = lttng_ust_elf_create(resolved_path);
111 if (!elf) {
112 ERR("could not access file %s", resolved_path);
113 return;
114 }
115
116 ret = lttng_ust_elf_get_memsz(elf, &memsz);
117 if (ret) {
118 goto end;
119 }
120 ret = lttng_ust_elf_get_build_id(
121 elf, &build_id, &build_id_len, &has_build_id);
122 if (ret) {
123 goto end;
124 }
125 ret = lttng_ust_elf_get_debug_link(
126 elf, &dbg_file, &crc, &has_debug_link);
127 if (ret) {
128 goto end;
129 }
130
131 tracepoint(lttng_ust_dl, dlopen,
132 ip, so_base, resolved_path, flags, memsz,
133 has_build_id, has_debug_link);
134
135 if (has_build_id) {
136 tracepoint(lttng_ust_dl, build_id,
137 ip, so_base, build_id, build_id_len);
138 }
139
140 if (has_debug_link) {
141 tracepoint(lttng_ust_dl, debug_link,
142 ip, so_base, dbg_file, crc);
143 }
144
145 end:
146 free(dbg_file);
147 free(build_id);
148 lttng_ust_elf_destroy(elf);
149 return;
150 }
151
152 #ifdef HAVE_DLMOPEN
153 static
154 void lttng_ust_dl_dlmopen(void *so_base, Lmid_t nsid, const char *so_name,
155 int flags, void *ip)
156 {
157 char resolved_path[PATH_MAX];
158 struct lttng_ust_elf *elf;
159 uint64_t memsz;
160 uint8_t *build_id = NULL;
161 size_t build_id_len;
162 char *dbg_file = NULL;
163 uint32_t crc;
164 int has_build_id = 0, has_debug_link = 0;
165 int ret;
166
167 if (!realpath(so_name, resolved_path)) {
168 ERR("could not resolve path '%s'", so_name);
169 return;
170 }
171
172 elf = lttng_ust_elf_create(resolved_path);
173 if (!elf) {
174 ERR("could not access file %s", resolved_path);
175 return;
176 }
177
178 ret = lttng_ust_elf_get_memsz(elf, &memsz);
179 if (ret) {
180 goto end;
181 }
182 ret = lttng_ust_elf_get_build_id(
183 elf, &build_id, &build_id_len, &has_build_id);
184 if (ret) {
185 goto end;
186 }
187 ret = lttng_ust_elf_get_debug_link(
188 elf, &dbg_file, &crc, &has_debug_link);
189 if (ret) {
190 goto end;
191 }
192
193 tracepoint(lttng_ust_dl, dlmopen,
194 ip, so_base, nsid, resolved_path, flags, memsz,
195 has_build_id, has_debug_link);
196
197 if (has_build_id) {
198 tracepoint(lttng_ust_dl, build_id,
199 ip, so_base, build_id, build_id_len);
200 }
201
202 if (has_debug_link) {
203 tracepoint(lttng_ust_dl, debug_link,
204 ip, so_base, dbg_file, crc);
205 }
206
207 end:
208 free(dbg_file);
209 free(build_id);
210 lttng_ust_elf_destroy(elf);
211 return;
212 }
213 #endif
214
215 void *dlopen(const char *filename, int flags)
216 {
217 void *handle;
218
219 handle = _lttng_ust_dl_libc_dlopen(filename, flags);
220 if (__tracepoint_ptrs_registered && handle) {
221 struct link_map *p = NULL;
222 int ret;
223
224 ret = dlinfo(handle, RTLD_DI_LINKMAP, &p);
225 if (ret != -1 && p != NULL && p->l_addr != 0) {
226 lttng_ust_dl_dlopen((void *) p->l_addr,
227 p->l_name, flags, LTTNG_UST_CALLER_IP());
228 }
229 }
230 lttng_ust_dl_update(LTTNG_UST_CALLER_IP());
231 return handle;
232 }
233
234 #ifdef HAVE_DLMOPEN
235 void *dlmopen(Lmid_t nsid, const char *filename, int flags)
236 {
237 void *handle;
238
239 handle = _lttng_ust_dl_libc_dlmopen(nsid, filename, flags);
240 if (__tracepoint_ptrs_registered && handle) {
241 struct link_map *p = NULL;
242 int ret;
243
244 ret = dlinfo(handle, RTLD_DI_LINKMAP, &p);
245 if (ret != -1 && p != NULL && p->l_addr != 0) {
246 lttng_ust_dl_dlmopen((void *) p->l_addr,
247 nsid, p->l_name, flags,
248 LTTNG_UST_CALLER_IP());
249 }
250 }
251 lttng_ust_dl_update(LTTNG_UST_CALLER_IP());
252 return handle;
253
254 }
255 #endif
256
257 int dlclose(void *handle)
258 {
259 int ret;
260
261 if (__tracepoint_ptrs_registered) {
262 struct link_map *p = NULL;
263
264 ret = dlinfo(handle, RTLD_DI_LINKMAP, &p);
265 if (ret != -1 && p != NULL && p->l_addr != 0) {
266 tracepoint(lttng_ust_dl, dlclose,
267 LTTNG_UST_CALLER_IP(),
268 (void *) p->l_addr);
269 }
270 }
271 ret = _lttng_ust_dl_libc_dlclose(handle);
272 lttng_ust_dl_update(LTTNG_UST_CALLER_IP());
273 return ret;
274 }
This page took 0.03607 seconds and 5 git commands to generate.