blob: 55079c0200e0835d2b1867d2874e66833d6d8810 [file] [log] [blame]
Frederic Weisbecker66e274f2009-08-12 11:07:25 +02001#include "event.h"
2#include "symbol.h"
3#include <stdlib.h>
4#include <string.h>
5#include <stdio.h>
Arnaldo Carvalho de Meloe4204992009-10-20 14:25:40 -02006#include "debug.h"
Frederic Weisbecker66e274f2009-08-12 11:07:25 +02007
8static inline int is_anon_memory(const char *filename)
9{
10 return strcmp(filename, "//anon") == 0;
11}
12
13static int strcommon(const char *pathname, char *cwd, int cwdlen)
14{
15 int n = 0;
16
17 while (n < cwdlen && pathname[n] == cwd[n])
18 ++n;
19
20 return n;
21}
22
Arnaldo Carvalho de Meloe4204992009-10-20 14:25:40 -020023struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen,
24 unsigned int sym_priv_size, symbol_filter_t filter,
25 int v)
Frederic Weisbecker66e274f2009-08-12 11:07:25 +020026{
27 struct map *self = malloc(sizeof(*self));
28
29 if (self != NULL) {
30 const char *filename = event->filename;
31 char newfilename[PATH_MAX];
32 int anon;
Arnaldo Carvalho de Meloe4204992009-10-20 14:25:40 -020033 bool new_dso;
Frederic Weisbecker66e274f2009-08-12 11:07:25 +020034
35 if (cwd) {
36 int n = strcommon(filename, cwd, cwdlen);
37
38 if (n == cwdlen) {
39 snprintf(newfilename, sizeof(newfilename),
40 ".%s", filename + n);
41 filename = newfilename;
42 }
43 }
44
45 anon = is_anon_memory(filename);
46
47 if (anon) {
48 snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", event->pid);
49 filename = newfilename;
50 }
51
52 self->start = event->start;
53 self->end = event->start + event->len;
54 self->pgoff = event->pgoff;
55
Arnaldo Carvalho de Meloe4204992009-10-20 14:25:40 -020056 self->dso = dsos__findnew(filename, sym_priv_size, &new_dso);
Frederic Weisbecker66e274f2009-08-12 11:07:25 +020057 if (self->dso == NULL)
58 goto out_delete;
59
Arnaldo Carvalho de Meloe4204992009-10-20 14:25:40 -020060 if (new_dso) {
61 int nr = dso__load(self->dso, self, filter, v);
62
63 if (nr < 0)
64 eprintf("Failed to open %s, continuing "
65 "without symbols\n",
66 self->dso->long_name);
67 else if (nr == 0)
68 eprintf("No symbols found in %s, maybe "
69 "install a debug package?\n",
70 self->dso->long_name);
71 }
72
Frederic Weisbecker66e274f2009-08-12 11:07:25 +020073 if (self->dso == vdso || anon)
Arnaldo Carvalho de Meloed52ce22009-10-19 17:17:57 -020074 self->map_ip = self->unmap_ip = identity__map_ip;
75 else {
Frederic Weisbecker66e274f2009-08-12 11:07:25 +020076 self->map_ip = map__map_ip;
Arnaldo Carvalho de Meloed52ce22009-10-19 17:17:57 -020077 self->unmap_ip = map__unmap_ip;
78 }
Frederic Weisbecker66e274f2009-08-12 11:07:25 +020079 }
80 return self;
81out_delete:
82 free(self);
83 return NULL;
84}
85
86struct map *map__clone(struct map *self)
87{
88 struct map *map = malloc(sizeof(*self));
89
90 if (!map)
91 return NULL;
92
93 memcpy(map, self, sizeof(*self));
94
95 return map;
96}
97
98int map__overlap(struct map *l, struct map *r)
99{
100 if (l->start > r->start) {
101 struct map *t = l;
102 l = r;
103 r = t;
104 }
105
106 if (l->end > r->start)
107 return 1;
108
109 return 0;
110}
111
112size_t map__fprintf(struct map *self, FILE *fp)
113{
114 return fprintf(fp, " %Lx-%Lx %Lx %s\n",
115 self->start, self->end, self->pgoff, self->dso->name);
116}