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