Cleanup: fix typo 'acces' -> 'access'
[lttng-ust.git] / liblttng-ust-dl / lttng-ust-dl.c
CommitLineData
b13d93c2
PW
1/*
2 * Copyright (C) 2013 Paul Woegerer <paul.woegerer@mentor.com>
8e2aed3f 3 * Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
97c7c238 4 * Copyright (C) 2016 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
b13d93c2
PW
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; version 2.1 of
9 * the License.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#define _GNU_SOURCE
1ddceb36 22#define _LGPL_SOURCE
13436238 23#include <limits.h>
8e2aed3f 24#include <stdio.h>
13436238 25#include <sys/types.h>
8e2aed3f
AB
26#include <unistd.h>
27
28#include <lttng/ust-dlfcn.h>
29#include <lttng/ust-elf.h>
97c7c238 30#include <lttng/ust-events.h>
171fcc6f 31#include <helper.h>
eb2b066f 32#include "usterr-signal-safe.h"
b13d93c2 33
8e2aed3f
AB
34/* Include link.h last else it conflicts with ust-dlfcn. */
35#include <link.h>
b13d93c2 36
13436238 37#define TRACEPOINT_DEFINE
6d4658aa 38#include "ust_dl.h"
13436238 39
7b0fdd83 40static void *(*__lttng_ust_plibc_dlopen)(const char *filename, int flags);
42330adc 41#ifdef HAVE_DLMOPEN
7b0fdd83
MD
42static void *(*__lttng_ust_plibc_dlmopen)(Lmid_t nsid, const char *filename,
43 int flags);
42330adc 44#endif
b13d93c2 45static int (*__lttng_ust_plibc_dlclose)(void *handle);
b13d93c2
PW
46
47static
7b0fdd83 48void *_lttng_ust_dl_libc_dlopen(const char *filename, int flags)
b13d93c2
PW
49{
50 if (!__lttng_ust_plibc_dlopen) {
51 __lttng_ust_plibc_dlopen = dlsym(RTLD_NEXT, "dlopen");
8e2aed3f 52 if (!__lttng_ust_plibc_dlopen) {
b13d93c2
PW
53 fprintf(stderr, "%s\n", dlerror());
54 return NULL;
55 }
56 }
7b0fdd83
MD
57 return __lttng_ust_plibc_dlopen(filename, flags);
58}
59
42330adc 60#ifdef HAVE_DLMOPEN
7b0fdd83
MD
61static
62void *_lttng_ust_dl_libc_dlmopen(Lmid_t nsid, const char *filename,
63 int flags)
64{
65 if (!__lttng_ust_plibc_dlmopen) {
66 __lttng_ust_plibc_dlmopen = dlsym(RTLD_NEXT, "dlmopen");
67 if (!__lttng_ust_plibc_dlmopen) {
68 fprintf(stderr, "%s\n", dlerror());
69 return NULL;
70 }
71 }
72 return __lttng_ust_plibc_dlmopen(nsid, filename, flags);
b13d93c2 73}
42330adc 74#endif
b13d93c2
PW
75
76static
77int _lttng_ust_dl_libc_dlclose(void *handle)
78{
79 if (!__lttng_ust_plibc_dlclose) {
80 __lttng_ust_plibc_dlclose = dlsym(RTLD_NEXT, "dlclose");
8e2aed3f 81 if (!__lttng_ust_plibc_dlclose) {
b13d93c2
PW
82 fprintf(stderr, "%s\n", dlerror());
83 return -1;
84 }
85 }
86 return __lttng_ust_plibc_dlclose(handle);
87}
88
89static
7b0fdd83
MD
90void lttng_ust_dl_dlopen(void *so_base, const char *so_name,
91 int flags, void *ip)
b13d93c2 92{
13436238 93 char resolved_path[PATH_MAX];
8e2aed3f
AB
94 struct lttng_ust_elf *elf;
95 uint64_t memsz;
83215d66 96 uint8_t *build_id = NULL;
8e2aed3f 97 size_t build_id_len;
83215d66 98 char *dbg_file = NULL;
8e2aed3f
AB
99 uint32_t crc;
100 int has_build_id = 0, has_debug_link = 0;
101 int ret;
b13d93c2 102
13436238
PW
103 if (!realpath(so_name, resolved_path)) {
104 ERR("could not resolve path '%s'", so_name);
105 return;
b13d93c2 106 }
b13d93c2 107
8e2aed3f
AB
108 elf = lttng_ust_elf_create(resolved_path);
109 if (!elf) {
09026ccf 110 ERR("could not access file %s", resolved_path);
13436238 111 return;
b13d93c2 112 }
13436238 113
8e2aed3f
AB
114 ret = lttng_ust_elf_get_memsz(elf, &memsz);
115 if (ret) {
116 goto end;
117 }
118 ret = lttng_ust_elf_get_build_id(
119 elf, &build_id, &build_id_len, &has_build_id);
120 if (ret) {
121 goto end;
122 }
123 ret = lttng_ust_elf_get_debug_link(
124 elf, &dbg_file, &crc, &has_debug_link);
125 if (ret) {
126 goto end;
127 }
128
6d4658aa 129 tracepoint(lttng_ust_dl, dlopen,
7b0fdd83 130 ip, so_base, resolved_path, flags, memsz,
c5c4fd82 131 has_build_id, has_debug_link);
8e2aed3f
AB
132
133 if (has_build_id) {
134 tracepoint(lttng_ust_dl, build_id,
135 ip, so_base, build_id, build_id_len);
8e2aed3f
AB
136 }
137
138 if (has_debug_link) {
139 tracepoint(lttng_ust_dl, debug_link,
140 ip, so_base, dbg_file, crc);
8e2aed3f
AB
141 }
142
143end:
83215d66
MD
144 free(dbg_file);
145 free(build_id);
8e2aed3f 146 lttng_ust_elf_destroy(elf);
13436238 147 return;
b13d93c2
PW
148}
149
42330adc 150#ifdef HAVE_DLMOPEN
7b0fdd83
MD
151static
152void lttng_ust_dl_dlmopen(void *so_base, Lmid_t nsid, const char *so_name,
153 int flags, void *ip)
154{
155 char resolved_path[PATH_MAX];
156 struct lttng_ust_elf *elf;
157 uint64_t memsz;
158 uint8_t *build_id = NULL;
159 size_t build_id_len;
160 char *dbg_file = NULL;
161 uint32_t crc;
162 int has_build_id = 0, has_debug_link = 0;
163 int ret;
164
165 if (!realpath(so_name, resolved_path)) {
166 ERR("could not resolve path '%s'", so_name);
167 return;
168 }
169
170 elf = lttng_ust_elf_create(resolved_path);
171 if (!elf) {
09026ccf 172 ERR("could not access file %s", resolved_path);
7b0fdd83
MD
173 return;
174 }
175
176 ret = lttng_ust_elf_get_memsz(elf, &memsz);
177 if (ret) {
178 goto end;
179 }
180 ret = lttng_ust_elf_get_build_id(
181 elf, &build_id, &build_id_len, &has_build_id);
182 if (ret) {
183 goto end;
184 }
185 ret = lttng_ust_elf_get_debug_link(
186 elf, &dbg_file, &crc, &has_debug_link);
187 if (ret) {
188 goto end;
189 }
190
191 tracepoint(lttng_ust_dl, dlmopen,
192 ip, so_base, nsid, resolved_path, flags, memsz,
193 has_build_id, has_debug_link);
194
195 if (has_build_id) {
196 tracepoint(lttng_ust_dl, build_id,
197 ip, so_base, build_id, build_id_len);
198 }
199
200 if (has_debug_link) {
201 tracepoint(lttng_ust_dl, debug_link,
202 ip, so_base, dbg_file, crc);
203 }
204
205end:
206 free(dbg_file);
207 free(build_id);
208 lttng_ust_elf_destroy(elf);
209 return;
210}
42330adc 211#endif
7b0fdd83
MD
212
213void *dlopen(const char *filename, int flags)
b13d93c2 214{
8e2aed3f
AB
215 void *handle;
216
7b0fdd83 217 handle = _lttng_ust_dl_libc_dlopen(filename, flags);
bd703713 218 if (__tracepoint_ptrs_registered && handle) {
b13d93c2 219 struct link_map *p = NULL;
8e2aed3f
AB
220 int ret;
221
222 ret = dlinfo(handle, RTLD_DI_LINKMAP, &p);
223 if (ret != -1 && p != NULL && p->l_addr != 0) {
97c7c238 224 lttng_ust_dl_dlopen((void *) p->l_addr,
7b0fdd83
MD
225 p->l_name, flags, LTTNG_UST_CALLER_IP());
226 }
227 }
228 lttng_ust_dl_update(LTTNG_UST_CALLER_IP());
229 return handle;
230}
231
42330adc 232#ifdef HAVE_DLMOPEN
7b0fdd83
MD
233void *dlmopen(Lmid_t nsid, const char *filename, int flags)
234{
235 void *handle;
236
237 handle = _lttng_ust_dl_libc_dlmopen(nsid, filename, flags);
238 if (__tracepoint_ptrs_registered && handle) {
239 struct link_map *p = NULL;
240 int ret;
241
242 ret = dlinfo(handle, RTLD_DI_LINKMAP, &p);
243 if (ret != -1 && p != NULL && p->l_addr != 0) {
244 lttng_ust_dl_dlmopen((void *) p->l_addr,
245 nsid, p->l_name, flags,
171fcc6f 246 LTTNG_UST_CALLER_IP());
8e2aed3f 247 }
b13d93c2 248 }
97c7c238 249 lttng_ust_dl_update(LTTNG_UST_CALLER_IP());
b13d93c2 250 return handle;
7b0fdd83 251
b13d93c2 252}
42330adc 253#endif
b13d93c2
PW
254
255int dlclose(void *handle)
256{
97c7c238
MD
257 int ret;
258
e7953e6e 259 if (__tracepoint_ptrs_registered) {
b13d93c2 260 struct link_map *p = NULL;
8e2aed3f
AB
261
262 ret = dlinfo(handle, RTLD_DI_LINKMAP, &p);
263 if (ret != -1 && p != NULL && p->l_addr != 0) {
264 tracepoint(lttng_ust_dl, dlclose,
171fcc6f 265 LTTNG_UST_CALLER_IP(),
8e2aed3f
AB
266 (void *) p->l_addr);
267 }
b13d93c2 268 }
97c7c238
MD
269 ret = _lttng_ust_dl_libc_dlclose(handle);
270 lttng_ust_dl_update(LTTNG_UST_CALLER_IP());
271 return ret;
b13d93c2 272}
This page took 0.036694 seconds and 4 git commands to generate.