xref: /openbmc/linux/tools/perf/util/map.c (revision fd589a8f)
1 #include "event.h"
2 #include "symbol.h"
3 #include <stdlib.h>
4 #include <string.h>
5 #include <stdio.h>
6 
7 static inline int is_anon_memory(const char *filename)
8 {
9 	return strcmp(filename, "//anon") == 0;
10 }
11 
12 static int strcommon(const char *pathname, char *cwd, int cwdlen)
13 {
14 	int n = 0;
15 
16 	while (n < cwdlen && pathname[n] == cwd[n])
17 		++n;
18 
19 	return n;
20 }
21 
22  struct map *map__new(struct mmap_event *event, char *cwd, int cwdlen)
23 {
24 	struct map *self = malloc(sizeof(*self));
25 
26 	if (self != NULL) {
27 		const char *filename = event->filename;
28 		char newfilename[PATH_MAX];
29 		int anon;
30 
31 		if (cwd) {
32 			int n = strcommon(filename, cwd, cwdlen);
33 
34 			if (n == cwdlen) {
35 				snprintf(newfilename, sizeof(newfilename),
36 					 ".%s", filename + n);
37 				filename = newfilename;
38 			}
39 		}
40 
41 		anon = is_anon_memory(filename);
42 
43 		if (anon) {
44 			snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", event->pid);
45 			filename = newfilename;
46 		}
47 
48 		self->start = event->start;
49 		self->end   = event->start + event->len;
50 		self->pgoff = event->pgoff;
51 
52 		self->dso = dsos__findnew(filename);
53 		if (self->dso == NULL)
54 			goto out_delete;
55 
56 		if (self->dso == vdso || anon)
57 			self->map_ip = vdso__map_ip;
58 		else
59 			self->map_ip = map__map_ip;
60 	}
61 	return self;
62 out_delete:
63 	free(self);
64 	return NULL;
65 }
66 
67 struct map *map__clone(struct map *self)
68 {
69 	struct map *map = malloc(sizeof(*self));
70 
71 	if (!map)
72 		return NULL;
73 
74 	memcpy(map, self, sizeof(*self));
75 
76 	return map;
77 }
78 
79 int map__overlap(struct map *l, struct map *r)
80 {
81 	if (l->start > r->start) {
82 		struct map *t = l;
83 		l = r;
84 		r = t;
85 	}
86 
87 	if (l->end > r->start)
88 		return 1;
89 
90 	return 0;
91 }
92 
93 size_t map__fprintf(struct map *self, FILE *fp)
94 {
95 	return fprintf(fp, " %Lx-%Lx %Lx %s\n",
96 		       self->start, self->end, self->pgoff, self->dso->name);
97 }
98