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