Fix: eliminate timestamp overlap between packets
[lttng-ust.git] / liblttng-ust-dl / ustdl.c
CommitLineData
b13d93c2
PW
1/*
2 * Copyright (C) 2013 Paul Woegerer <paul.woegerer@mentor.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; version 2.1 of
7 * the License.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#define _GNU_SOURCE
20#include <inttypes.h>
21#include <dlfcn.h>
22#include <link.h>
23#include <unistd.h>
24#include <stdio.h>
25#include <signal.h>
26#include <sched.h>
27#include <stdarg.h>
28#include "usterr.h"
29
30#include <lttng/ust-compiler.h>
31#include <lttng/ust.h>
32
33static void *(*__lttng_ust_plibc_dlopen)(const char *filename, int flag);
34static int (*__lttng_ust_plibc_dlclose)(void *handle);
35static void *__lttng_ust_baddr_handle;
36
37static
38void *_lttng_ust_dl_libc_dlopen(const char *filename, int flag)
39{
40 if (!__lttng_ust_plibc_dlopen) {
41 __lttng_ust_plibc_dlopen = dlsym(RTLD_NEXT, "dlopen");
42 if (__lttng_ust_plibc_dlopen == NULL) {
43 fprintf(stderr, "%s\n", dlerror());
44 return NULL;
45 }
46 }
47 return __lttng_ust_plibc_dlopen(filename, flag);
48}
49
50static
51int _lttng_ust_dl_libc_dlclose(void *handle)
52{
53 if (!__lttng_ust_plibc_dlclose) {
54 __lttng_ust_plibc_dlclose = dlsym(RTLD_NEXT, "dlclose");
55 if (__lttng_ust_plibc_dlclose == NULL) {
56 fprintf(stderr, "%s\n", dlerror());
57 return -1;
58 }
59 }
60 return __lttng_ust_plibc_dlclose(handle);
61}
62
63static
64void *lttng_ust_baddr_handle(void)
65{
66 if (!__lttng_ust_baddr_handle) {
67 __lttng_ust_baddr_handle = _lttng_ust_dl_libc_dlopen(
68 "liblttng-ust-baddr.so.0", RTLD_NOW | RTLD_GLOBAL);
69 if (__lttng_ust_baddr_handle == NULL)
70 fprintf(stderr, "%s\n", dlerror());
71 }
72 return __lttng_ust_baddr_handle;
73}
74
75static
76int lttng_ust_baddr_push(void *so_base, const char *so_name)
77{
78 static int
79 (*lttng_ust_baddr_push_fn)(void *so_base, const char *so_name);
80 if (!lttng_ust_baddr_push_fn) {
81 void *baddr_handle = lttng_ust_baddr_handle();
82 if (baddr_handle) {
83 lttng_ust_baddr_push_fn = dlsym(baddr_handle,
84 "lttng_ust_push_baddr");
85 if (lttng_ust_baddr_push_fn == NULL)
86 fprintf(stderr, "%s\n", dlerror());
87 }
88 if (!lttng_ust_baddr_push_fn)
89 return -1;
90 }
91 return lttng_ust_baddr_push_fn(so_base, so_name);
92}
93
94static
95int lttng_ust_baddr_pop(void *so_base)
96{
97 static int
98 (*lttng_ust_baddr_pop_fn)(void *so_base);
99 if (!lttng_ust_baddr_pop_fn) {
100 void *baddr_handle = lttng_ust_baddr_handle();
101 if (baddr_handle) {
102 lttng_ust_baddr_pop_fn = dlsym(baddr_handle,
103 "lttng_ust_pop_baddr");
104 if (lttng_ust_baddr_pop_fn == NULL)
105 fprintf(stderr, "%s\n", dlerror());
106 }
107 if (!lttng_ust_baddr_pop_fn)
108 return -1;
109 }
110 return lttng_ust_baddr_pop_fn(so_base);
111}
112
113void *dlopen(const char *filename, int flag)
114{
115 void *handle = _lttng_ust_dl_libc_dlopen(filename, flag);
116 if (handle) {
117 struct link_map *p = NULL;
118 if (dlinfo(handle, RTLD_DI_LINKMAP, &p) != -1 && p != NULL
119 && p->l_addr != 0)
120 lttng_ust_baddr_push((void *) p->l_addr, p->l_name);
121 }
122 return handle;
123}
124
125int dlclose(void *handle)
126{
127 if (handle) {
128 struct link_map *p = NULL;
129 if (dlinfo(handle, RTLD_DI_LINKMAP, &p) != -1 && p != NULL
130 && p->l_addr != 0)
131 lttng_ust_baddr_pop((void *) p->l_addr);
132 }
133 return _lttng_ust_dl_libc_dlclose(handle);
134}
135
136static void __attribute__((destructor))
137lttng_ust_baddr_handle_fini(void);
138static void
139lttng_ust_baddr_handle_fini(void)
140{
141 if (__lttng_ust_baddr_handle) {
142 int ret = _lttng_ust_dl_libc_dlclose(__lttng_ust_baddr_handle);
143 if (ret)
144 fprintf(stderr, "%s\n", dlerror());
145 }
146}
This page took 0.028567 seconds and 4 git commands to generate.