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