perf tools: Recognize hugetlb mapping as anon mapping
[cascardo/linux.git] / tools / perf / util / map.c
1 #include "symbol.h"
2 #include <errno.h>
3 #include <inttypes.h>
4 #include <limits.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <sys/mman.h>
10 #include "map.h"
11 #include "thread.h"
12 #include "strlist.h"
13 #include "vdso.h"
14 #include "build-id.h"
15 #include "util.h"
16 #include "debug.h"
17 #include "machine.h"
18 #include <linux/string.h>
19 #include "unwind.h"
20
21 static void __maps__insert(struct maps *maps, struct map *map);
22
23 const char *map_type__name[MAP__NR_TYPES] = {
24         [MAP__FUNCTION] = "Functions",
25         [MAP__VARIABLE] = "Variables",
26 };
27
28 static inline int is_anon_memory(const char *filename, u32 flags)
29 {
30         u32 anon_flags = 0;
31
32 #ifdef MAP_HUGETLB
33         anon_flags |= MAP_HUGETLB;
34 #endif
35         return flags & anon_flags ||
36                !strcmp(filename, "//anon") ||
37                !strncmp(filename, "/dev/zero", sizeof("/dev/zero") - 1) ||
38                !strncmp(filename, "/anon_hugepage", sizeof("/anon_hugepage") - 1);
39 }
40
41 static inline int is_no_dso_memory(const char *filename)
42 {
43         return !strncmp(filename, "[stack", 6) ||
44                !strncmp(filename, "/SYSV",5)   ||
45                !strcmp(filename, "[heap]");
46 }
47
48 static inline int is_android_lib(const char *filename)
49 {
50         return !strncmp(filename, "/data/app-lib", 13) ||
51                !strncmp(filename, "/system/lib", 11);
52 }
53
54 static inline bool replace_android_lib(const char *filename, char *newfilename)
55 {
56         const char *libname;
57         char *app_abi;
58         size_t app_abi_length, new_length;
59         size_t lib_length = 0;
60
61         libname  = strrchr(filename, '/');
62         if (libname)
63                 lib_length = strlen(libname);
64
65         app_abi = getenv("APP_ABI");
66         if (!app_abi)
67                 return false;
68
69         app_abi_length = strlen(app_abi);
70
71         if (!strncmp(filename, "/data/app-lib", 13)) {
72                 char *apk_path;
73
74                 if (!app_abi_length)
75                         return false;
76
77                 new_length = 7 + app_abi_length + lib_length;
78
79                 apk_path = getenv("APK_PATH");
80                 if (apk_path) {
81                         new_length += strlen(apk_path) + 1;
82                         if (new_length > PATH_MAX)
83                                 return false;
84                         snprintf(newfilename, new_length,
85                                  "%s/libs/%s/%s", apk_path, app_abi, libname);
86                 } else {
87                         if (new_length > PATH_MAX)
88                                 return false;
89                         snprintf(newfilename, new_length,
90                                  "libs/%s/%s", app_abi, libname);
91                 }
92                 return true;
93         }
94
95         if (!strncmp(filename, "/system/lib/", 11)) {
96                 char *ndk, *app;
97                 const char *arch;
98                 size_t ndk_length;
99                 size_t app_length;
100
101                 ndk = getenv("NDK_ROOT");
102                 app = getenv("APP_PLATFORM");
103
104                 if (!(ndk && app))
105                         return false;
106
107                 ndk_length = strlen(ndk);
108                 app_length = strlen(app);
109
110                 if (!(ndk_length && app_length && app_abi_length))
111                         return false;
112
113                 arch = !strncmp(app_abi, "arm", 3) ? "arm" :
114                        !strncmp(app_abi, "mips", 4) ? "mips" :
115                        !strncmp(app_abi, "x86", 3) ? "x86" : NULL;
116
117                 if (!arch)
118                         return false;
119
120                 new_length = 27 + ndk_length +
121                              app_length + lib_length
122                            + strlen(arch);
123
124                 if (new_length > PATH_MAX)
125                         return false;
126                 snprintf(newfilename, new_length,
127                         "%s/platforms/%s/arch-%s/usr/lib/%s",
128                         ndk, app, arch, libname);
129
130                 return true;
131         }
132         return false;
133 }
134
135 void map__init(struct map *map, enum map_type type,
136                u64 start, u64 end, u64 pgoff, struct dso *dso)
137 {
138         map->type     = type;
139         map->start    = start;
140         map->end      = end;
141         map->pgoff    = pgoff;
142         map->reloc    = 0;
143         map->dso      = dso__get(dso);
144         map->map_ip   = map__map_ip;
145         map->unmap_ip = map__unmap_ip;
146         RB_CLEAR_NODE(&map->rb_node);
147         map->groups   = NULL;
148         map->erange_warned = false;
149         atomic_set(&map->refcnt, 1);
150 }
151
152 struct map *map__new(struct machine *machine, u64 start, u64 len,
153                      u64 pgoff, u32 pid, u32 d_maj, u32 d_min, u64 ino,
154                      u64 ino_gen, u32 prot, u32 flags, char *filename,
155                      enum map_type type, struct thread *thread)
156 {
157         struct map *map = malloc(sizeof(*map));
158
159         if (map != NULL) {
160                 char newfilename[PATH_MAX];
161                 struct dso *dso;
162                 int anon, no_dso, vdso, android;
163
164                 android = is_android_lib(filename);
165                 anon = is_anon_memory(filename, flags);
166                 vdso = is_vdso_map(filename);
167                 no_dso = is_no_dso_memory(filename);
168
169                 map->maj = d_maj;
170                 map->min = d_min;
171                 map->ino = ino;
172                 map->ino_generation = ino_gen;
173                 map->prot = prot;
174                 map->flags = flags;
175
176                 if ((anon || no_dso) && type == MAP__FUNCTION) {
177                         snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid);
178                         filename = newfilename;
179                 }
180
181                 if (android) {
182                         if (replace_android_lib(filename, newfilename))
183                                 filename = newfilename;
184                 }
185
186                 if (vdso) {
187                         pgoff = 0;
188                         dso = machine__findnew_vdso(machine, thread);
189                 } else
190                         dso = machine__findnew_dso(machine, filename);
191
192                 if (dso == NULL)
193                         goto out_delete;
194
195                 map__init(map, type, start, start + len, pgoff, dso);
196
197                 if (anon || no_dso) {
198                         map->map_ip = map->unmap_ip = identity__map_ip;
199
200                         /*
201                          * Set memory without DSO as loaded. All map__find_*
202                          * functions still return NULL, and we avoid the
203                          * unnecessary map__load warning.
204                          */
205                         if (type != MAP__FUNCTION)
206                                 dso__set_loaded(dso, map->type);
207                 }
208                 dso__put(dso);
209         }
210         return map;
211 out_delete:
212         free(map);
213         return NULL;
214 }
215
216 /*
217  * Constructor variant for modules (where we know from /proc/modules where
218  * they are loaded) and for vmlinux, where only after we load all the
219  * symbols we'll know where it starts and ends.
220  */
221 struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
222 {
223         struct map *map = calloc(1, (sizeof(*map) +
224                                      (dso->kernel ? sizeof(struct kmap) : 0)));
225         if (map != NULL) {
226                 /*
227                  * ->end will be filled after we load all the symbols
228                  */
229                 map__init(map, type, start, 0, 0, dso);
230         }
231
232         return map;
233 }
234
235 /*
236  * Use this and __map__is_kmodule() for map instances that are in
237  * machine->kmaps, and thus have map->groups->machine all properly set, to
238  * disambiguate between the kernel and modules.
239  *
240  * When the need arises, introduce map__is_{kernel,kmodule)() that
241  * checks (map->groups != NULL && map->groups->machine != NULL &&
242  * map->dso->kernel) before calling __map__is_{kernel,kmodule}())
243  */
244 bool __map__is_kernel(const struct map *map)
245 {
246         return __machine__kernel_map(map->groups->machine, map->type) == map;
247 }
248
249 static void map__exit(struct map *map)
250 {
251         BUG_ON(!RB_EMPTY_NODE(&map->rb_node));
252         dso__zput(map->dso);
253 }
254
255 void map__delete(struct map *map)
256 {
257         map__exit(map);
258         free(map);
259 }
260
261 void map__put(struct map *map)
262 {
263         if (map && atomic_dec_and_test(&map->refcnt))
264                 map__delete(map);
265 }
266
267 void map__fixup_start(struct map *map)
268 {
269         struct rb_root *symbols = &map->dso->symbols[map->type];
270         struct rb_node *nd = rb_first(symbols);
271         if (nd != NULL) {
272                 struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
273                 map->start = sym->start;
274         }
275 }
276
277 void map__fixup_end(struct map *map)
278 {
279         struct rb_root *symbols = &map->dso->symbols[map->type];
280         struct rb_node *nd = rb_last(symbols);
281         if (nd != NULL) {
282                 struct symbol *sym = rb_entry(nd, struct symbol, rb_node);
283                 map->end = sym->end;
284         }
285 }
286
287 #define DSO__DELETED "(deleted)"
288
289 int map__load(struct map *map)
290 {
291         const char *name = map->dso->long_name;
292         int nr;
293
294         if (dso__loaded(map->dso, map->type))
295                 return 0;
296
297         nr = dso__load(map->dso, map);
298         if (nr < 0) {
299                 if (map->dso->has_build_id) {
300                         char sbuild_id[SBUILD_ID_SIZE];
301
302                         build_id__sprintf(map->dso->build_id,
303                                           sizeof(map->dso->build_id),
304                                           sbuild_id);
305                         pr_warning("%s with build id %s not found",
306                                    name, sbuild_id);
307                 } else
308                         pr_warning("Failed to open %s", name);
309
310                 pr_warning(", continuing without symbols\n");
311                 return -1;
312         } else if (nr == 0) {
313 #ifdef HAVE_LIBELF_SUPPORT
314                 const size_t len = strlen(name);
315                 const size_t real_len = len - sizeof(DSO__DELETED);
316
317                 if (len > sizeof(DSO__DELETED) &&
318                     strcmp(name + real_len + 1, DSO__DELETED) == 0) {
319                         pr_warning("%.*s was updated (is prelink enabled?). "
320                                 "Restart the long running apps that use it!\n",
321                                    (int)real_len, name);
322                 } else {
323                         pr_warning("no symbols found in %s, maybe install "
324                                    "a debug package?\n", name);
325                 }
326 #endif
327                 return -1;
328         }
329
330         return 0;
331 }
332
333 int __weak arch__compare_symbol_names(const char *namea, const char *nameb)
334 {
335         return strcmp(namea, nameb);
336 }
337
338 struct symbol *map__find_symbol(struct map *map, u64 addr)
339 {
340         if (map__load(map) < 0)
341                 return NULL;
342
343         return dso__find_symbol(map->dso, map->type, addr);
344 }
345
346 struct symbol *map__find_symbol_by_name(struct map *map, const char *name)
347 {
348         if (map__load(map) < 0)
349                 return NULL;
350
351         if (!dso__sorted_by_name(map->dso, map->type))
352                 dso__sort_by_name(map->dso, map->type);
353
354         return dso__find_symbol_by_name(map->dso, map->type, name);
355 }
356
357 struct map *map__clone(struct map *from)
358 {
359         struct map *map = memdup(from, sizeof(*map));
360
361         if (map != NULL) {
362                 atomic_set(&map->refcnt, 1);
363                 RB_CLEAR_NODE(&map->rb_node);
364                 dso__get(map->dso);
365                 map->groups = NULL;
366         }
367
368         return map;
369 }
370
371 int map__overlap(struct map *l, struct map *r)
372 {
373         if (l->start > r->start) {
374                 struct map *t = l;
375                 l = r;
376                 r = t;
377         }
378
379         if (l->end > r->start)
380                 return 1;
381
382         return 0;
383 }
384
385 size_t map__fprintf(struct map *map, FILE *fp)
386 {
387         return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n",
388                        map->start, map->end, map->pgoff, map->dso->name);
389 }
390
391 size_t map__fprintf_dsoname(struct map *map, FILE *fp)
392 {
393         const char *dsoname = "[unknown]";
394
395         if (map && map->dso && (map->dso->name || map->dso->long_name)) {
396                 if (symbol_conf.show_kernel_path && map->dso->long_name)
397                         dsoname = map->dso->long_name;
398                 else if (map->dso->name)
399                         dsoname = map->dso->name;
400         }
401
402         return fprintf(fp, "%s", dsoname);
403 }
404
405 int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix,
406                          FILE *fp)
407 {
408         char *srcline;
409         int ret = 0;
410
411         if (map && map->dso) {
412                 srcline = get_srcline(map->dso,
413                                       map__rip_2objdump(map, addr), NULL, true);
414                 if (srcline != SRCLINE_UNKNOWN)
415                         ret = fprintf(fp, "%s%s", prefix, srcline);
416                 free_srcline(srcline);
417         }
418         return ret;
419 }
420
421 /**
422  * map__rip_2objdump - convert symbol start address to objdump address.
423  * @map: memory map
424  * @rip: symbol start address
425  *
426  * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN.
427  * map->dso->adjust_symbols==1 for ET_EXEC-like cases except ET_REL which is
428  * relative to section start.
429  *
430  * Return: Address suitable for passing to "objdump --start-address="
431  */
432 u64 map__rip_2objdump(struct map *map, u64 rip)
433 {
434         if (!map->dso->adjust_symbols)
435                 return rip;
436
437         if (map->dso->rel)
438                 return rip - map->pgoff;
439
440         /*
441          * kernel modules also have DSO_TYPE_USER in dso->kernel,
442          * but all kernel modules are ET_REL, so won't get here.
443          */
444         if (map->dso->kernel == DSO_TYPE_USER)
445                 return rip + map->dso->text_offset;
446
447         return map->unmap_ip(map, rip) - map->reloc;
448 }
449
450 /**
451  * map__objdump_2mem - convert objdump address to a memory address.
452  * @map: memory map
453  * @ip: objdump address
454  *
455  * Closely related to map__rip_2objdump(), this function takes an address from
456  * objdump and converts it to a memory address.  Note this assumes that @map
457  * contains the address.  To be sure the result is valid, check it forwards
458  * e.g. map__rip_2objdump(map->map_ip(map, map__objdump_2mem(map, ip))) == ip
459  *
460  * Return: Memory address.
461  */
462 u64 map__objdump_2mem(struct map *map, u64 ip)
463 {
464         if (!map->dso->adjust_symbols)
465                 return map->unmap_ip(map, ip);
466
467         if (map->dso->rel)
468                 return map->unmap_ip(map, ip + map->pgoff);
469
470         /*
471          * kernel modules also have DSO_TYPE_USER in dso->kernel,
472          * but all kernel modules are ET_REL, so won't get here.
473          */
474         if (map->dso->kernel == DSO_TYPE_USER)
475                 return map->unmap_ip(map, ip - map->dso->text_offset);
476
477         return ip + map->reloc;
478 }
479
480 static void maps__init(struct maps *maps)
481 {
482         maps->entries = RB_ROOT;
483         pthread_rwlock_init(&maps->lock, NULL);
484 }
485
486 void map_groups__init(struct map_groups *mg, struct machine *machine)
487 {
488         int i;
489         for (i = 0; i < MAP__NR_TYPES; ++i) {
490                 maps__init(&mg->maps[i]);
491         }
492         mg->machine = machine;
493         atomic_set(&mg->refcnt, 1);
494 }
495
496 static void __maps__purge(struct maps *maps)
497 {
498         struct rb_root *root = &maps->entries;
499         struct rb_node *next = rb_first(root);
500
501         while (next) {
502                 struct map *pos = rb_entry(next, struct map, rb_node);
503
504                 next = rb_next(&pos->rb_node);
505                 rb_erase_init(&pos->rb_node, root);
506                 map__put(pos);
507         }
508 }
509
510 static void maps__exit(struct maps *maps)
511 {
512         pthread_rwlock_wrlock(&maps->lock);
513         __maps__purge(maps);
514         pthread_rwlock_unlock(&maps->lock);
515 }
516
517 void map_groups__exit(struct map_groups *mg)
518 {
519         int i;
520
521         for (i = 0; i < MAP__NR_TYPES; ++i)
522                 maps__exit(&mg->maps[i]);
523 }
524
525 bool map_groups__empty(struct map_groups *mg)
526 {
527         int i;
528
529         for (i = 0; i < MAP__NR_TYPES; ++i) {
530                 if (maps__first(&mg->maps[i]))
531                         return false;
532         }
533
534         return true;
535 }
536
537 struct map_groups *map_groups__new(struct machine *machine)
538 {
539         struct map_groups *mg = malloc(sizeof(*mg));
540
541         if (mg != NULL)
542                 map_groups__init(mg, machine);
543
544         return mg;
545 }
546
547 void map_groups__delete(struct map_groups *mg)
548 {
549         map_groups__exit(mg);
550         free(mg);
551 }
552
553 void map_groups__put(struct map_groups *mg)
554 {
555         if (mg && atomic_dec_and_test(&mg->refcnt))
556                 map_groups__delete(mg);
557 }
558
559 struct symbol *map_groups__find_symbol(struct map_groups *mg,
560                                        enum map_type type, u64 addr,
561                                        struct map **mapp)
562 {
563         struct map *map = map_groups__find(mg, type, addr);
564
565         /* Ensure map is loaded before using map->map_ip */
566         if (map != NULL && map__load(map) >= 0) {
567                 if (mapp != NULL)
568                         *mapp = map;
569                 return map__find_symbol(map, map->map_ip(map, addr));
570         }
571
572         return NULL;
573 }
574
575 struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name,
576                                          struct map **mapp)
577 {
578         struct symbol *sym;
579         struct rb_node *nd;
580
581         pthread_rwlock_rdlock(&maps->lock);
582
583         for (nd = rb_first(&maps->entries); nd; nd = rb_next(nd)) {
584                 struct map *pos = rb_entry(nd, struct map, rb_node);
585
586                 sym = map__find_symbol_by_name(pos, name);
587
588                 if (sym == NULL)
589                         continue;
590                 if (mapp != NULL)
591                         *mapp = pos;
592                 goto out;
593         }
594
595         sym = NULL;
596 out:
597         pthread_rwlock_unlock(&maps->lock);
598         return sym;
599 }
600
601 struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
602                                                enum map_type type,
603                                                const char *name,
604                                                struct map **mapp)
605 {
606         struct symbol *sym = maps__find_symbol_by_name(&mg->maps[type], name, mapp);
607
608         return sym;
609 }
610
611 int map_groups__find_ams(struct addr_map_symbol *ams)
612 {
613         if (ams->addr < ams->map->start || ams->addr >= ams->map->end) {
614                 if (ams->map->groups == NULL)
615                         return -1;
616                 ams->map = map_groups__find(ams->map->groups, ams->map->type,
617                                             ams->addr);
618                 if (ams->map == NULL)
619                         return -1;
620         }
621
622         ams->al_addr = ams->map->map_ip(ams->map, ams->addr);
623         ams->sym = map__find_symbol(ams->map, ams->al_addr);
624
625         return ams->sym ? 0 : -1;
626 }
627
628 static size_t maps__fprintf(struct maps *maps, FILE *fp)
629 {
630         size_t printed = 0;
631         struct rb_node *nd;
632
633         pthread_rwlock_rdlock(&maps->lock);
634
635         for (nd = rb_first(&maps->entries); nd; nd = rb_next(nd)) {
636                 struct map *pos = rb_entry(nd, struct map, rb_node);
637                 printed += fprintf(fp, "Map:");
638                 printed += map__fprintf(pos, fp);
639                 if (verbose > 2) {
640                         printed += dso__fprintf(pos->dso, pos->type, fp);
641                         printed += fprintf(fp, "--\n");
642                 }
643         }
644
645         pthread_rwlock_unlock(&maps->lock);
646
647         return printed;
648 }
649
650 size_t __map_groups__fprintf_maps(struct map_groups *mg, enum map_type type,
651                                   FILE *fp)
652 {
653         size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
654         return printed += maps__fprintf(&mg->maps[type], fp);
655 }
656
657 size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
658 {
659         size_t printed = 0, i;
660         for (i = 0; i < MAP__NR_TYPES; ++i)
661                 printed += __map_groups__fprintf_maps(mg, i, fp);
662         return printed;
663 }
664
665 static void __map_groups__insert(struct map_groups *mg, struct map *map)
666 {
667         __maps__insert(&mg->maps[map->type], map);
668         map->groups = mg;
669 }
670
671 static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
672 {
673         struct rb_root *root;
674         struct rb_node *next;
675         int err = 0;
676
677         pthread_rwlock_wrlock(&maps->lock);
678
679         root = &maps->entries;
680         next = rb_first(root);
681
682         while (next) {
683                 struct map *pos = rb_entry(next, struct map, rb_node);
684                 next = rb_next(&pos->rb_node);
685
686                 if (!map__overlap(pos, map))
687                         continue;
688
689                 if (verbose >= 2) {
690                         fputs("overlapping maps:\n", fp);
691                         map__fprintf(map, fp);
692                         map__fprintf(pos, fp);
693                 }
694
695                 rb_erase_init(&pos->rb_node, root);
696                 /*
697                  * Now check if we need to create new maps for areas not
698                  * overlapped by the new map:
699                  */
700                 if (map->start > pos->start) {
701                         struct map *before = map__clone(pos);
702
703                         if (before == NULL) {
704                                 err = -ENOMEM;
705                                 goto put_map;
706                         }
707
708                         before->end = map->start;
709                         __map_groups__insert(pos->groups, before);
710                         if (verbose >= 2)
711                                 map__fprintf(before, fp);
712                         map__put(before);
713                 }
714
715                 if (map->end < pos->end) {
716                         struct map *after = map__clone(pos);
717
718                         if (after == NULL) {
719                                 err = -ENOMEM;
720                                 goto put_map;
721                         }
722
723                         after->start = map->end;
724                         __map_groups__insert(pos->groups, after);
725                         if (verbose >= 2)
726                                 map__fprintf(after, fp);
727                         map__put(after);
728                 }
729 put_map:
730                 map__put(pos);
731
732                 if (err)
733                         goto out;
734         }
735
736         err = 0;
737 out:
738         pthread_rwlock_unlock(&maps->lock);
739         return err;
740 }
741
742 int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
743                                    FILE *fp)
744 {
745         return maps__fixup_overlappings(&mg->maps[map->type], map, fp);
746 }
747
748 /*
749  * XXX This should not really _copy_ te maps, but refcount them.
750  */
751 int map_groups__clone(struct thread *thread,
752                       struct map_groups *parent, enum map_type type)
753 {
754         struct map_groups *mg = thread->mg;
755         int err = -ENOMEM;
756         struct map *map;
757         struct maps *maps = &parent->maps[type];
758
759         pthread_rwlock_rdlock(&maps->lock);
760
761         for (map = maps__first(maps); map; map = map__next(map)) {
762                 struct map *new = map__clone(map);
763                 if (new == NULL)
764                         goto out_unlock;
765
766                 err = unwind__prepare_access(thread, new, NULL);
767                 if (err)
768                         goto out_unlock;
769
770                 map_groups__insert(mg, new);
771                 map__put(new);
772         }
773
774         err = 0;
775 out_unlock:
776         pthread_rwlock_unlock(&maps->lock);
777         return err;
778 }
779
780 static void __maps__insert(struct maps *maps, struct map *map)
781 {
782         struct rb_node **p = &maps->entries.rb_node;
783         struct rb_node *parent = NULL;
784         const u64 ip = map->start;
785         struct map *m;
786
787         while (*p != NULL) {
788                 parent = *p;
789                 m = rb_entry(parent, struct map, rb_node);
790                 if (ip < m->start)
791                         p = &(*p)->rb_left;
792                 else
793                         p = &(*p)->rb_right;
794         }
795
796         rb_link_node(&map->rb_node, parent, p);
797         rb_insert_color(&map->rb_node, &maps->entries);
798         map__get(map);
799 }
800
801 void maps__insert(struct maps *maps, struct map *map)
802 {
803         pthread_rwlock_wrlock(&maps->lock);
804         __maps__insert(maps, map);
805         pthread_rwlock_unlock(&maps->lock);
806 }
807
808 static void __maps__remove(struct maps *maps, struct map *map)
809 {
810         rb_erase_init(&map->rb_node, &maps->entries);
811         map__put(map);
812 }
813
814 void maps__remove(struct maps *maps, struct map *map)
815 {
816         pthread_rwlock_wrlock(&maps->lock);
817         __maps__remove(maps, map);
818         pthread_rwlock_unlock(&maps->lock);
819 }
820
821 struct map *maps__find(struct maps *maps, u64 ip)
822 {
823         struct rb_node **p, *parent = NULL;
824         struct map *m;
825
826         pthread_rwlock_rdlock(&maps->lock);
827
828         p = &maps->entries.rb_node;
829         while (*p != NULL) {
830                 parent = *p;
831                 m = rb_entry(parent, struct map, rb_node);
832                 if (ip < m->start)
833                         p = &(*p)->rb_left;
834                 else if (ip >= m->end)
835                         p = &(*p)->rb_right;
836                 else
837                         goto out;
838         }
839
840         m = NULL;
841 out:
842         pthread_rwlock_unlock(&maps->lock);
843         return m;
844 }
845
846 struct map *maps__first(struct maps *maps)
847 {
848         struct rb_node *first = rb_first(&maps->entries);
849
850         if (first)
851                 return rb_entry(first, struct map, rb_node);
852         return NULL;
853 }
854
855 struct map *map__next(struct map *map)
856 {
857         struct rb_node *next = rb_next(&map->rb_node);
858
859         if (next)
860                 return rb_entry(next, struct map, rb_node);
861         return NULL;
862 }
863
864 struct kmap *map__kmap(struct map *map)
865 {
866         if (!map->dso || !map->dso->kernel) {
867                 pr_err("Internal error: map__kmap with a non-kernel map\n");
868                 return NULL;
869         }
870         return (struct kmap *)(map + 1);
871 }
872
873 struct map_groups *map__kmaps(struct map *map)
874 {
875         struct kmap *kmap = map__kmap(map);
876
877         if (!kmap || !kmap->kmaps) {
878                 pr_err("Internal error: map__kmaps with a non-kernel map\n");
879                 return NULL;
880         }
881         return kmap->kmaps;
882 }