| Frederic Weisbecker | 66e274f | 2009-08-12 11:07:25 +0200 | [diff] [blame] | 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) | 
| Arnaldo Carvalho de Melo | ed52ce2 | 2009-10-19 17:17:57 -0200 | [diff] [blame^] | 57 | self->map_ip = self->unmap_ip = identity__map_ip; | 
|  | 58 | else { | 
| Frederic Weisbecker | 66e274f | 2009-08-12 11:07:25 +0200 | [diff] [blame] | 59 | self->map_ip = map__map_ip; | 
| Arnaldo Carvalho de Melo | ed52ce2 | 2009-10-19 17:17:57 -0200 | [diff] [blame^] | 60 | self->unmap_ip = map__unmap_ip; | 
|  | 61 | } | 
| Frederic Weisbecker | 66e274f | 2009-08-12 11:07:25 +0200 | [diff] [blame] | 62 | } | 
|  | 63 | return self; | 
|  | 64 | out_delete: | 
|  | 65 | free(self); | 
|  | 66 | return NULL; | 
|  | 67 | } | 
|  | 68 |  | 
|  | 69 | struct map *map__clone(struct map *self) | 
|  | 70 | { | 
|  | 71 | struct map *map = malloc(sizeof(*self)); | 
|  | 72 |  | 
|  | 73 | if (!map) | 
|  | 74 | return NULL; | 
|  | 75 |  | 
|  | 76 | memcpy(map, self, sizeof(*self)); | 
|  | 77 |  | 
|  | 78 | return map; | 
|  | 79 | } | 
|  | 80 |  | 
|  | 81 | int map__overlap(struct map *l, struct map *r) | 
|  | 82 | { | 
|  | 83 | if (l->start > r->start) { | 
|  | 84 | struct map *t = l; | 
|  | 85 | l = r; | 
|  | 86 | r = t; | 
|  | 87 | } | 
|  | 88 |  | 
|  | 89 | if (l->end > r->start) | 
|  | 90 | return 1; | 
|  | 91 |  | 
|  | 92 | return 0; | 
|  | 93 | } | 
|  | 94 |  | 
|  | 95 | size_t map__fprintf(struct map *self, FILE *fp) | 
|  | 96 | { | 
|  | 97 | return fprintf(fp, " %Lx-%Lx %Lx %s\n", | 
|  | 98 | self->start, self->end, self->pgoff, self->dso->name); | 
|  | 99 | } |