841223349a146e3c5f1d821dab92c5abc20bfecb
[lttng-ust.git] / liblttng-ust-baddr / lttng-ust-baddr.c
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; either
7 * version 2.1 of the License, or (at your option) any later version.
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 <dlfcn.h>
21 #include <link.h>
22
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include <limits.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <stdint.h>
30 #include <stddef.h>
31 #include <stdio.h>
32 #include "usterr.h"
33
34 #include "lttng-ust-baddr.h"
35
36 #define TRACEPOINT_DEFINE
37 #include "ust_baddr_statedump.h"
38
39 static int
40 extract_soinfo_events(struct dl_phdr_info *info, size_t size, void *data)
41 {
42 int j;
43 int num_loadable_segment = 0;
44
45 for (j = 0; j < info->dlpi_phnum; j++) {
46 char resolved_path[PATH_MAX];
47 struct stat sostat;
48 void *base_addr_ptr;
49
50 if (info->dlpi_phdr[j].p_type != PT_LOAD)
51 continue;
52
53 /* Calculate virtual memory address of the loadable segment */
54 base_addr_ptr = (void *) info->dlpi_addr
55 + info->dlpi_phdr[j].p_vaddr;
56
57 num_loadable_segment += 1;
58 if ((info->dlpi_name == NULL || info->dlpi_name[0] == 0)
59 && num_loadable_segment == 1) {
60 /*
61 * If the iterated element is the executable itself we
62 * have to use Dl_info to determine its full path
63 */
64 Dl_info dl_info = { 0 };
65 if (!dladdr(base_addr_ptr, &dl_info))
66 return 0;
67 if (!realpath(dl_info.dli_fname, resolved_path))
68 return 0;
69 } else {
70 /*
71 * For regular dl_phdr_info entries we have to check if
72 * the path to the shared object really exists
73 */
74 if (!realpath(info->dlpi_name, resolved_path)) {
75 /* Found vDSO, put the 'path' into brackets */
76 snprintf(resolved_path, PATH_MAX - 1, "[%s]",
77 info->dlpi_name);
78 }
79 }
80
81 if (stat(resolved_path, &sostat)) {
82 sostat.st_size = 0;
83 sostat.st_mtime = -1;
84 }
85
86 tracepoint(ust_baddr_statedump, soinfo,
87 (struct lttng_session *) data, base_addr_ptr,
88 resolved_path, sostat.st_size, sostat.st_mtime);
89
90 /*
91 * We are only interested in the base address (lowest virtual
92 * address associated with the memory image), skip the rest
93 */
94 break;
95 }
96 return 0;
97 }
98
99 int
100 lttng_ust_baddr_statedump(struct lttng_session *session)
101 {
102 /*
103 * Iterate through the list of currently loaded shared objects and
104 * generate events for loadable segments using extract_soinfo_events
105 */
106 dl_iterate_phdr(extract_soinfo_events, session);
107 return 0;
108 }
This page took 0.031443 seconds and 3 git commands to generate.