projects/linux·blob master · refs

1468 lines · 38.4 KiB

1// SPDX-License-Identifier: GPL-2.0
2#include <errno.h>
3#include <stdlib.h>
4#include <linux/zalloc.h>
5#include "debug.h"
6#include "dso.h"
7#include "map.h"
8#include "maps.h"
9#include "rwsem.h"
10#include "thread.h"
11#include "ui/ui.h"
12#include "unwind.h"
13#include "unwind-libdw.h"
14#include <internal/rc_check.h>
15
16/*
17 * Locking/sorting note:
18 *
19 * Sorting is done with the write lock, iteration and binary searching happens
20 * under the read lock requiring being sorted. There is a race between sorting
21 * releasing the write lock and acquiring the read lock for iteration/searching
22 * where another thread could insert and break the sorting of the maps. In
23 * practice inserting maps should be rare meaning that the race shouldn't lead
24 * to live lock. Removal of maps doesn't break being sorted.
25 */
26
27DECLARE_RC_STRUCT(maps) {
28 struct rw_semaphore lock;
29 /**
30 * @maps_by_address: array of maps sorted by their starting address if
31 * maps_by_address_sorted is true.
32 */
33 struct map **maps_by_address;
34 /**
35 * @maps_by_name: optional array of maps sorted by their dso name if
36 * maps_by_name_sorted is true.
37 */
38 struct map **maps_by_name;
39 struct machine *machine;
40#ifdef HAVE_LIBUNWIND_SUPPORT
41 void *addr_space;
42 const struct unwind_libunwind_ops *unwind_libunwind_ops;
43 uint16_t e_machine;
44#endif
45#ifdef HAVE_LIBDW_SUPPORT
46 void *libdw_addr_space_dwfl;
47#endif
48 refcount_t refcnt;
49 /**
50 * @nr_maps: number of maps_by_address, and possibly maps_by_name,
51 * entries that contain maps.
52 */
53 unsigned int nr_maps;
54 /**
55 * @nr_maps_allocated: number of entries in maps_by_address and possibly
56 * maps_by_name.
57 */
58 unsigned int nr_maps_allocated;
59 /**
60 * @last_search_by_name_idx: cache of last found by name entry's index
61 * as frequent searches for the same dso name are common.
62 */
63 unsigned int last_search_by_name_idx;
64 /** @maps_by_address_sorted: is maps_by_address sorted. */
65 bool maps_by_address_sorted;
66 /** @maps_by_name_sorted: is maps_by_name sorted. */
67 bool maps_by_name_sorted;
68 /** @ends_broken: does the map contain a map where end values are unset/unsorted? */
69 bool ends_broken;
70};
71
72static void check_invariants(const struct maps *maps __maybe_unused)
73{
74#ifndef NDEBUG
75 assert(RC_CHK_ACCESS(maps)->nr_maps <= RC_CHK_ACCESS(maps)->nr_maps_allocated);
76 for (unsigned int i = 0; i < RC_CHK_ACCESS(maps)->nr_maps; i++) {
77 struct map *map = RC_CHK_ACCESS(maps)->maps_by_address[i];
78
79 /* Check map is well-formed. */
80 assert(map__end(map) == 0 || map__start(map) <= map__end(map));
81 /* Expect at least 1 reference count. */
82 assert(refcount_read(map__refcnt(map)) > 0);
83
84 if (map__dso(map) && dso__kernel(map__dso(map)))
85 assert(RC_CHK_EQUAL(map__kmap(map)->kmaps, maps));
86
87 if (i > 0) {
88 struct map *prev = RC_CHK_ACCESS(maps)->maps_by_address[i - 1];
89
90 /* If addresses are sorted... */
91 if (RC_CHK_ACCESS(maps)->maps_by_address_sorted) {
92 /* Maps should be in start address order. */
93 assert(map__start(prev) <= map__start(map));
94 /*
95 * If the ends of maps aren't broken (during
96 * construction) then they should be ordered
97 * too.
98 */
99 if (!RC_CHK_ACCESS(maps)->ends_broken) {
100 assert(map__end(prev) <= map__end(map));
101 assert(map__end(prev) <= map__start(map) ||
102 map__start(prev) == map__start(map));
103 }
104 }
105 }
106 }
107 if (RC_CHK_ACCESS(maps)->maps_by_name) {
108 for (unsigned int i = 0; i < RC_CHK_ACCESS(maps)->nr_maps; i++) {
109 struct map *map = RC_CHK_ACCESS(maps)->maps_by_name[i];
110
111 /*
112 * Maps by name maps should be in maps_by_address, so
113 * the reference count should be higher.
114 */
115 assert(refcount_read(map__refcnt(map)) > 1);
116 }
117 }
118#endif
119}
120
121static struct map **maps__maps_by_address(const struct maps *maps)
122{
123 return RC_CHK_ACCESS(maps)->maps_by_address;
124}
125
126static void maps__set_maps_by_address(struct maps *maps, struct map **new)
127{
128 RC_CHK_ACCESS(maps)->maps_by_address = new;
129
130}
131
132static void maps__set_nr_maps_allocated(struct maps *maps, unsigned int nr_maps_allocated)
133{
134 RC_CHK_ACCESS(maps)->nr_maps_allocated = nr_maps_allocated;
135}
136
137static void maps__set_nr_maps(struct maps *maps, unsigned int nr_maps)
138{
139 RC_CHK_ACCESS(maps)->nr_maps = nr_maps;
140}
141
142/* Not in the header, to aid reference counting. */
143static struct map **maps__maps_by_name(const struct maps *maps)
144{
145 return RC_CHK_ACCESS(maps)->maps_by_name;
146
147}
148
149static void maps__set_maps_by_name(struct maps *maps, struct map **new)
150{
151 RC_CHK_ACCESS(maps)->maps_by_name = new;
152
153}
154
155static bool maps__maps_by_address_sorted(const struct maps *maps)
156{
157 return RC_CHK_ACCESS(maps)->maps_by_address_sorted;
158}
159
160static void maps__set_maps_by_address_sorted(struct maps *maps, bool value)
161{
162 RC_CHK_ACCESS(maps)->maps_by_address_sorted = value;
163}
164
165static bool maps__maps_by_name_sorted(const struct maps *maps)
166{
167 return RC_CHK_ACCESS(maps)->maps_by_name_sorted;
168}
169
170static void maps__set_maps_by_name_sorted(struct maps *maps, bool value)
171{
172 RC_CHK_ACCESS(maps)->maps_by_name_sorted = value;
173}
174
175struct machine *maps__machine(const struct maps *maps)
176{
177 return RC_CHK_ACCESS(maps)->machine;
178}
179
180unsigned int maps__nr_maps(const struct maps *maps)
181{
182 return RC_CHK_ACCESS(maps)->nr_maps;
183}
184
185refcount_t *maps__refcnt(struct maps *maps)
186{
187 return &RC_CHK_ACCESS(maps)->refcnt;
188}
189
190#ifdef HAVE_LIBUNWIND_SUPPORT
191void *maps__addr_space(const struct maps *maps)
192{
193 return RC_CHK_ACCESS(maps)->addr_space;
194}
195
196void maps__set_addr_space(struct maps *maps, void *addr_space)
197{
198 RC_CHK_ACCESS(maps)->addr_space = addr_space;
199}
200
201uint16_t maps__e_machine(const struct maps *maps)
202{
203 return RC_CHK_ACCESS(maps)->e_machine;
204}
205
206void maps__set_e_machine(struct maps *maps, uint16_t e_machine)
207{
208 RC_CHK_ACCESS(maps)->e_machine = e_machine;
209}
210#endif
211#ifdef HAVE_LIBDW_SUPPORT
212void *maps__libdw_addr_space_dwfl(const struct maps *maps)
213{
214 return RC_CHK_ACCESS(maps)->libdw_addr_space_dwfl;
215}
216
217void maps__set_libdw_addr_space_dwfl(struct maps *maps, void *dwfl)
218{
219 RC_CHK_ACCESS(maps)->libdw_addr_space_dwfl = dwfl;
220}
221#endif
222
223static struct rw_semaphore *maps__lock(struct maps *maps)
224{
225 return &RC_CHK_ACCESS(maps)->lock;
226}
227
228static void maps__init(struct maps *maps, struct machine *machine)
229{
230 init_rwsem(maps__lock(maps));
231 RC_CHK_ACCESS(maps)->maps_by_address = NULL;
232 RC_CHK_ACCESS(maps)->maps_by_name = NULL;
233 RC_CHK_ACCESS(maps)->machine = machine;
234#ifdef HAVE_LIBUNWIND_SUPPORT
235 RC_CHK_ACCESS(maps)->addr_space = NULL;
236 RC_CHK_ACCESS(maps)->unwind_libunwind_ops = NULL;
237#endif
238#ifdef HAVE_LIBDW_SUPPORT
239 RC_CHK_ACCESS(maps)->libdw_addr_space_dwfl = NULL;
240#endif
241 refcount_set(maps__refcnt(maps), 1);
242 RC_CHK_ACCESS(maps)->nr_maps = 0;
243 RC_CHK_ACCESS(maps)->nr_maps_allocated = 0;
244 RC_CHK_ACCESS(maps)->last_search_by_name_idx = 0;
245 RC_CHK_ACCESS(maps)->maps_by_address_sorted = true;
246 RC_CHK_ACCESS(maps)->maps_by_name_sorted = false;
247}
248
249static void maps__exit(struct maps *maps)
250{
251 struct map **maps_by_address = maps__maps_by_address(maps);
252 struct map **maps_by_name = maps__maps_by_name(maps);
253
254 for (unsigned int i = 0; i < maps__nr_maps(maps); i++) {
255 map__zput(maps_by_address[i]);
256 if (maps_by_name)
257 map__zput(maps_by_name[i]);
258 }
259 zfree(&maps_by_address);
260 zfree(&maps_by_name);
261 unwind__finish_access(maps);
262#ifdef HAVE_LIBDW_SUPPORT
263 libdw__invalidate_dwfl(maps, maps__libdw_addr_space_dwfl(maps));
264#endif
265}
266
267struct maps *maps__new(struct machine *machine)
268{
269 struct maps *result;
270 RC_STRUCT(maps) *maps = zalloc(sizeof(*maps));
271
272 if (ADD_RC_CHK(result, maps))
273 maps__init(result, machine);
274
275 return result;
276}
277
278static void maps__delete(struct maps *maps)
279{
280 maps__exit(maps);
281 RC_CHK_FREE(maps);
282}
283
284struct maps *maps__get(struct maps *maps)
285{
286 struct maps *result;
287
288 if (RC_CHK_GET(result, maps))
289 refcount_inc(maps__refcnt(maps));
290
291 return result;
292}
293
294void maps__put(struct maps *maps)
295{
296 if (maps && refcount_dec_and_test(maps__refcnt(maps)))
297 maps__delete(maps);
298 else
299 RC_CHK_PUT(maps);
300}
301
302static void __maps__free_maps_by_name(struct maps *maps)
303{
304 if (!maps__maps_by_name(maps))
305 return;
306
307 /*
308 * Free everything to try to do it from the rbtree in the next search
309 */
310 for (unsigned int i = 0; i < maps__nr_maps(maps); i++)
311 map__put(maps__maps_by_name(maps)[i]);
312
313 zfree(&RC_CHK_ACCESS(maps)->maps_by_name);
314
315 /* Consistent with maps__init(). When maps_by_name == NULL, maps_by_name_sorted == false */
316 maps__set_maps_by_name_sorted(maps, false);
317}
318
319static int map__start_cmp(const void *a, const void *b)
320{
321 const struct map *map_a = *(const struct map * const *)a;
322 const struct map *map_b = *(const struct map * const *)b;
323 u64 map_a_start = map__start(map_a);
324 u64 map_b_start = map__start(map_b);
325
326 if (map_a_start == map_b_start) {
327 u64 map_a_end = map__end(map_a);
328 u64 map_b_end = map__end(map_b);
329
330 if (map_a_end == map_b_end) {
331 /* Ensure maps with the same addresses have a fixed order. */
332 if (RC_CHK_ACCESS(map_a) == RC_CHK_ACCESS(map_b))
333 return 0;
334 return (intptr_t)RC_CHK_ACCESS(map_a) > (intptr_t)RC_CHK_ACCESS(map_b)
335 ? 1 : -1;
336 }
337 return map_a_end > map_b_end ? 1 : -1;
338 }
339 return map_a_start > map_b_start ? 1 : -1;
340}
341
342static void __maps__sort_by_address(struct maps *maps)
343{
344 if (maps__maps_by_address_sorted(maps))
345 return;
346
347 qsort(maps__maps_by_address(maps),
348 maps__nr_maps(maps),
349 sizeof(struct map *),
350 map__start_cmp);
351 maps__set_maps_by_address_sorted(maps, true);
352}
353
354static void maps__sort_by_address(struct maps *maps)
355{
356 down_write(maps__lock(maps));
357 __maps__sort_by_address(maps);
358 up_write(maps__lock(maps));
359}
360
361static int map__strcmp(const void *a, const void *b)
362{
363 const struct map *map_a = *(const struct map * const *)a;
364 const struct map *map_b = *(const struct map * const *)b;
365 const struct dso *dso_a = map__dso(map_a);
366 const struct dso *dso_b = map__dso(map_b);
367 int ret = strcmp(dso__short_name(dso_a), dso__short_name(dso_b));
368
369 if (ret == 0 && RC_CHK_ACCESS(map_a) != RC_CHK_ACCESS(map_b)) {
370 /* Ensure distinct but name equal maps have an order. */
371 return map__start_cmp(a, b);
372 }
373 return ret;
374}
375
376static int maps__sort_by_name(struct maps *maps)
377{
378 int err = 0;
379
380 down_write(maps__lock(maps));
381 if (!maps__maps_by_name_sorted(maps)) {
382 struct map **maps_by_name = maps__maps_by_name(maps);
383
384 if (!maps_by_name) {
385 maps_by_name = malloc(RC_CHK_ACCESS(maps)->nr_maps_allocated *
386 sizeof(*maps_by_name));
387 if (!maps_by_name)
388 err = -ENOMEM;
389 else {
390 struct map **maps_by_address = maps__maps_by_address(maps);
391 unsigned int n = maps__nr_maps(maps);
392
393 maps__set_maps_by_name(maps, maps_by_name);
394 for (unsigned int i = 0; i < n; i++)
395 maps_by_name[i] = map__get(maps_by_address[i]);
396 }
397 }
398 if (!err) {
399 qsort(maps_by_name,
400 maps__nr_maps(maps),
401 sizeof(struct map *),
402 map__strcmp);
403 maps__set_maps_by_name_sorted(maps, true);
404 }
405 }
406 check_invariants(maps);
407 up_write(maps__lock(maps));
408 return err;
409}
410
411static unsigned int maps__by_address_index(const struct maps *maps, const struct map *map)
412{
413 struct map **maps_by_address = maps__maps_by_address(maps);
414
415 if (maps__maps_by_address_sorted(maps)) {
416 struct map **mapp =
417 bsearch(&map, maps__maps_by_address(maps), maps__nr_maps(maps),
418 sizeof(*mapp), map__start_cmp);
419
420 if (mapp)
421 return mapp - maps_by_address;
422 } else {
423 for (unsigned int i = 0; i < maps__nr_maps(maps); i++) {
424 if (RC_CHK_ACCESS(maps_by_address[i]) == RC_CHK_ACCESS(map))
425 return i;
426 }
427 }
428 pr_err("Map missing from maps");
429 return -1;
430}
431
432static unsigned int maps__by_name_index(const struct maps *maps, const struct map *map)
433{
434 struct map **maps_by_name = maps__maps_by_name(maps);
435
436 if (maps__maps_by_name_sorted(maps)) {
437 struct map **mapp =
438 bsearch(&map, maps_by_name, maps__nr_maps(maps),
439 sizeof(*mapp), map__strcmp);
440
441 if (mapp)
442 return mapp - maps_by_name;
443 } else {
444 for (unsigned int i = 0; i < maps__nr_maps(maps); i++) {
445 if (RC_CHK_ACCESS(maps_by_name[i]) == RC_CHK_ACCESS(map))
446 return i;
447 }
448 }
449 pr_err("Map missing from maps");
450 return -1;
451}
452
453static void map__set_kmap_maps(struct map *map, struct maps *maps)
454{
455 struct dso *dso;
456
457 if (map == NULL)
458 return;
459
460 dso = map__dso(map);
461
462 if (dso && dso__kernel(dso)) {
463 struct kmap *kmap = map__kmap(map);
464
465 if (kmap)
466 kmap->kmaps = maps;
467 else
468 pr_err("Internal error: kernel dso with non kernel map\n");
469 }
470}
471
472static int __maps__insert(struct maps *maps, struct map *new)
473{
474 struct map **maps_by_address = maps__maps_by_address(maps);
475 struct map **maps_by_name = maps__maps_by_name(maps);
476 unsigned int nr_maps = maps__nr_maps(maps);
477 unsigned int nr_allocate = RC_CHK_ACCESS(maps)->nr_maps_allocated;
478
479 if (nr_maps + 1 > nr_allocate) {
480 nr_allocate = !nr_allocate ? 32 : nr_allocate * 2;
481
482 maps_by_address = realloc(maps_by_address, nr_allocate * sizeof(new));
483 if (!maps_by_address)
484 return -ENOMEM;
485
486 maps__set_maps_by_address(maps, maps_by_address);
487 if (maps_by_name) {
488 maps_by_name = realloc(maps_by_name, nr_allocate * sizeof(new));
489 if (!maps_by_name) {
490 /*
491 * If by name fails, just disable by name and it will
492 * recompute next time it is required.
493 */
494 __maps__free_maps_by_name(maps);
495 }
496 maps__set_maps_by_name(maps, maps_by_name);
497 }
498 RC_CHK_ACCESS(maps)->nr_maps_allocated = nr_allocate;
499 }
500 /* Insert the value at the end. */
501 maps_by_address[nr_maps] = map__get(new);
502 map__set_kmap_maps(new, maps);
503 if (maps_by_name)
504 maps_by_name[nr_maps] = map__get(new);
505
506 nr_maps++;
507 RC_CHK_ACCESS(maps)->nr_maps = nr_maps;
508
509 /*
510 * Recompute if things are sorted. If things are inserted in a sorted
511 * manner, for example by processing /proc/pid/maps, then no
512 * sorting/resorting will be necessary.
513 */
514 if (nr_maps == 1) {
515 /* If there's just 1 entry then maps are sorted. */
516 maps__set_maps_by_address_sorted(maps, true);
517 maps__set_maps_by_name_sorted(maps, maps_by_name != NULL);
518 } else {
519 /* Sorted if maps were already sorted and this map starts after the last one. */
520 maps__set_maps_by_address_sorted(maps,
521 maps__maps_by_address_sorted(maps) &&
522 map__end(maps_by_address[nr_maps - 2]) <= map__start(new));
523 maps__set_maps_by_name_sorted(maps, false);
524 }
525 if (map__end(new) < map__start(new))
526 RC_CHK_ACCESS(maps)->ends_broken = true;
527
528 return 0;
529}
530
531int maps__insert(struct maps *maps, struct map *map)
532{
533 int ret;
534
535 down_write(maps__lock(maps));
536 ret = __maps__insert(maps, map);
537 check_invariants(maps);
538 up_write(maps__lock(maps));
539 return ret;
540}
541
542static void __maps__remove(struct maps *maps, struct map *map)
543{
544 struct map **maps_by_address = maps__maps_by_address(maps);
545 struct map **maps_by_name = maps__maps_by_name(maps);
546 unsigned int nr_maps = maps__nr_maps(maps);
547 unsigned int address_idx;
548
549 /* Slide later mappings over the one to remove */
550 address_idx = maps__by_address_index(maps, map);
551 map__put(maps_by_address[address_idx]);
552 memmove(&maps_by_address[address_idx],
553 &maps_by_address[address_idx + 1],
554 (nr_maps - address_idx - 1) * sizeof(*maps_by_address));
555
556 if (maps_by_name) {
557 unsigned int name_idx = maps__by_name_index(maps, map);
558
559 map__put(maps_by_name[name_idx]);
560 memmove(&maps_by_name[name_idx],
561 &maps_by_name[name_idx + 1],
562 (nr_maps - name_idx - 1) * sizeof(*maps_by_name));
563 }
564
565 --RC_CHK_ACCESS(maps)->nr_maps;
566}
567
568void maps__remove(struct maps *maps, struct map *map)
569{
570 down_write(maps__lock(maps));
571 __maps__remove(maps, map);
572 check_invariants(maps);
573 up_write(maps__lock(maps));
574#ifdef HAVE_LIBDW_SUPPORT
575 libdw__invalidate_dwfl(maps, maps__libdw_addr_space_dwfl(maps));
576#endif
577}
578
579/**
580 * maps__mutate_mapping - Apply write-protected mutations to a map.
581 * @maps: The maps collection containing the map.
582 * @map: The map to mutate.
583 * @mutate_cb: Callback function that performs the actual mutations.
584 * @data: Private data passed to the callback.
585 *
586 * This acquires the write lock on the maps semaphore to safely protect
587 * concurrent readers from seeing partially mutated or unsorted map boundaries.
588 *
589 * WARNING: Acquiring down_write() here can trigger a recursive self-deadlock if
590 * the caller already holds the read lock (e.g., during maps__for_each_map() or
591 * maps__find() iteration paths that trigger lazy symbol loading). To completely
592 * avoid this deadlock, all kernel/module maps must be pre-loaded up-front (via
593 * maps__load_maps()) under a clean, single-threaded context before entering
594 * multi-threaded event processing loops.
595 */
596int maps__mutate_mapping(struct maps *maps, struct map *map,
597 int (*mutate_cb)(struct map *map, void *data), void *data)
598{
599 int err = 0;
600
601 if (maps) {
602 down_write(maps__lock(maps));
603
604 err = mutate_cb(map, data);
605
606 RC_CHK_ACCESS(maps)->maps_by_address_sorted = false;
607 RC_CHK_ACCESS(maps)->maps_by_name_sorted = false;
608
609 up_write(maps__lock(maps));
610
611#ifdef HAVE_LIBDW_SUPPORT
612 libdw__invalidate_dwfl(maps, maps__libdw_addr_space_dwfl(maps));
613#endif
614 } else {
615 err = mutate_cb(map, data);
616 }
617
618 return err;
619}
620
621bool maps__empty(struct maps *maps)
622{
623 bool res;
624
625 down_read(maps__lock(maps));
626 res = maps__nr_maps(maps) == 0;
627 up_read(maps__lock(maps));
628
629 return res;
630}
631
632bool maps__equal(struct maps *a, struct maps *b)
633{
634 return RC_CHK_EQUAL(a, b);
635}
636
637int maps__for_each_map(struct maps *maps, int (*cb)(struct map *map, void *data), void *data)
638{
639 bool done = false;
640 int ret = 0;
641
642 /* See locking/sorting note. */
643 while (!done) {
644 down_read(maps__lock(maps));
645 if (maps__maps_by_address_sorted(maps)) {
646 /*
647 * maps__for_each_map callbacks may buggily/unsafely
648 * insert into maps_by_address. Deliberately reload
649 * maps__nr_maps and maps_by_address on each iteration
650 * to avoid using memory freed by maps__insert growing
651 * the array - this may cause maps to be skipped or
652 * repeated.
653 */
654 for (unsigned int i = 0; i < maps__nr_maps(maps); i++) {
655 struct map **maps_by_address = maps__maps_by_address(maps);
656 struct map *map = maps_by_address[i];
657
658 ret = cb(map, data);
659 if (ret)
660 break;
661 }
662 done = true;
663 }
664 up_read(maps__lock(maps));
665 if (!done)
666 maps__sort_by_address(maps);
667 }
668 return ret;
669}
670
671int maps__load_maps(struct maps *maps)
672{
673 struct map **maps_copy;
674 unsigned int nr_maps;
675 int err = 0;
676
677 if (!maps)
678 return 0;
679
680 down_read(maps__lock(maps));
681 nr_maps = maps__nr_maps(maps);
682 if (nr_maps == 0) {
683 up_read(maps__lock(maps));
684 return 0;
685 }
686 maps_copy = calloc(nr_maps, sizeof(*maps_copy));
687 if (!maps_copy) {
688 up_read(maps__lock(maps));
689 return -ENOMEM;
690 }
691 for (unsigned int i = 0; i < nr_maps; i++)
692 maps_copy[i] = map__get(maps__maps_by_address(maps)[i]);
693 up_read(maps__lock(maps));
694
695 for (unsigned int i = 0; i < nr_maps; i++) {
696 if (map__load(maps_copy[i]) < 0) {
697 pr_warning("Failed to load map %s\n", dso__name(map__dso(maps_copy[i])));
698 err = -1;
699 }
700 map__put(maps_copy[i]);
701 }
702 free(maps_copy);
703 return err;
704}
705
706void maps__remove_maps(struct maps *maps, bool (*cb)(struct map *map, void *data), void *data)
707{
708 struct map **maps_by_address;
709 bool removed = false;
710
711 down_write(maps__lock(maps));
712
713 maps_by_address = maps__maps_by_address(maps);
714 for (unsigned int i = 0; i < maps__nr_maps(maps);) {
715 if (cb(maps_by_address[i], data)) {
716 __maps__remove(maps, maps_by_address[i]);
717 removed = true;
718 } else {
719 i++;
720 }
721 }
722 check_invariants(maps);
723 up_write(maps__lock(maps));
724 if (removed) {
725#ifdef HAVE_LIBDW_SUPPORT
726 libdw__invalidate_dwfl(maps, maps__libdw_addr_space_dwfl(maps));
727#endif
728 }
729}
730
731struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map **mapp)
732{
733 struct map *map = maps__find(maps, addr);
734 struct symbol *result = NULL;
735
736 /* Ensure map is loaded before using map->map_ip */
737 if (map != NULL && map__load(map) >= 0)
738 result = map__find_symbol(map, map__map_ip(map, addr));
739
740 if (mapp)
741 *mapp = map;
742 else
743 map__put(map);
744
745 return result;
746}
747
748struct symbol *maps__find_symbol_by_name(struct maps *maps, const char *name, struct map **mapp)
749{
750 struct map **maps_copy;
751 unsigned int nr_maps;
752 struct symbol *sym = NULL;
753
754 if (!maps)
755 return NULL;
756
757 /*
758 * First, ensure all maps are loaded. We pre-load them outside of any
759 * read-to-write locks to avoid deadlocks. Even if some fail, we proceed.
760 */
761 maps__load_maps(maps);
762
763 /*
764 * Create a local snapshot of the maps while holding the read lock.
765 * This prevents deadlocking if iteration triggers further map insertions.
766 */
767 down_read(maps__lock(maps));
768 nr_maps = maps__nr_maps(maps);
769 maps_copy = calloc(nr_maps, sizeof(*maps_copy));
770 if (maps_copy) {
771 for (unsigned int i = 0; i < nr_maps; i++) {
772 struct map *map = maps__maps_by_address(maps)[i];
773
774 maps_copy[i] = map__get(map);
775 }
776 }
777 up_read(maps__lock(maps));
778
779 if (!maps_copy)
780 return NULL;
781
782 for (unsigned int i = 0; i < nr_maps; i++) {
783 struct map *map = maps_copy[i];
784
785 sym = map__find_symbol_by_name(map, name);
786 if (sym && map__contains_symbol(map, sym)) {
787 if (mapp)
788 *mapp = map__get(map);
789 break;
790 }
791 sym = NULL;
792 }
793
794 for (unsigned int i = 0; i < nr_maps; i++)
795 map__put(maps_copy[i]);
796
797 free(maps_copy);
798 return sym;
799}
800
801int maps__find_ams(struct maps *maps, struct addr_map_symbol *ams)
802{
803 if (ams->addr < map__start(ams->ms.map) || ams->addr >= map__end(ams->ms.map)) {
804 if (maps == NULL)
805 return -1;
806 map__put(ams->ms.map);
807 ams->ms.map = maps__find(maps, ams->addr);
808 if (ams->ms.map == NULL)
809 return -1;
810 }
811
812 ams->al_addr = map__map_ip(ams->ms.map, ams->addr);
813 ams->ms.sym = map__find_symbol(ams->ms.map, ams->al_addr);
814
815 return ams->ms.sym ? 0 : -1;
816}
817
818struct maps__fprintf_args {
819 FILE *fp;
820 size_t printed;
821};
822
823static int maps__fprintf_cb(struct map *map, void *data)
824{
825 struct maps__fprintf_args *args = data;
826
827 args->printed += fprintf(args->fp, "Map:");
828 args->printed += map__fprintf(map, args->fp);
829 if (verbose > 2) {
830 args->printed += dso__fprintf(map__dso(map), args->fp);
831 args->printed += fprintf(args->fp, "--\n");
832 }
833 return 0;
834}
835
836size_t maps__fprintf(struct maps *maps, FILE *fp)
837{
838 struct maps__fprintf_args args = {
839 .fp = fp,
840 .printed = 0,
841 };
842
843 maps__for_each_map(maps, maps__fprintf_cb, &args);
844
845 return args.printed;
846}
847
848/*
849 * Find first map where end > map->start.
850 * Same as find_vma() in kernel.
851 */
852static unsigned int first_ending_after(struct maps *maps, const struct map *map)
853{
854 struct map **maps_by_address = maps__maps_by_address(maps);
855 int low = 0, high = (int)maps__nr_maps(maps) - 1, first = high + 1;
856
857 assert(maps__maps_by_address_sorted(maps));
858 if (low <= high && map__end(maps_by_address[0]) > map__start(map))
859 return 0;
860
861 while (low <= high) {
862 int mid = (low + high) / 2;
863 struct map *pos = maps_by_address[mid];
864
865 if (map__end(pos) > map__start(map)) {
866 first = mid;
867 if (map__start(pos) <= map__start(map)) {
868 /* Entry overlaps map. */
869 break;
870 }
871 high = mid - 1;
872 } else
873 low = mid + 1;
874 }
875 return first;
876}
877
878static int __maps__insert_sorted(struct maps *maps, unsigned int first_after_index,
879 struct map *new1, struct map *new2)
880{
881 struct map **maps_by_address = maps__maps_by_address(maps);
882 struct map **maps_by_name = maps__maps_by_name(maps);
883 unsigned int nr_maps = maps__nr_maps(maps);
884 unsigned int nr_allocate = RC_CHK_ACCESS(maps)->nr_maps_allocated;
885 unsigned int to_add = new2 ? 2 : 1;
886
887 assert(maps__maps_by_address_sorted(maps));
888 assert(first_after_index == nr_maps ||
889 map__end(new1) <= map__start(maps_by_address[first_after_index]));
890 assert(!new2 || map__end(new1) <= map__start(new2));
891 assert(first_after_index == nr_maps || !new2 ||
892 map__end(new2) <= map__start(maps_by_address[first_after_index]));
893
894 if (nr_maps + to_add > nr_allocate) {
895 nr_allocate = !nr_allocate ? 32 : nr_allocate * 2;
896
897 maps_by_address = realloc(maps_by_address, nr_allocate * sizeof(new1));
898 if (!maps_by_address)
899 return -ENOMEM;
900
901 maps__set_maps_by_address(maps, maps_by_address);
902 if (maps_by_name) {
903 maps_by_name = realloc(maps_by_name, nr_allocate * sizeof(new1));
904 if (!maps_by_name) {
905 /*
906 * If by name fails, just disable by name and it will
907 * recompute next time it is required.
908 */
909 __maps__free_maps_by_name(maps);
910 }
911 maps__set_maps_by_name(maps, maps_by_name);
912 }
913 RC_CHK_ACCESS(maps)->nr_maps_allocated = nr_allocate;
914 }
915 memmove(&maps_by_address[first_after_index+to_add],
916 &maps_by_address[first_after_index],
917 (nr_maps - first_after_index) * sizeof(new1));
918 maps_by_address[first_after_index] = map__get(new1);
919 if (maps_by_name)
920 maps_by_name[nr_maps] = map__get(new1);
921 if (new2) {
922 maps_by_address[first_after_index + 1] = map__get(new2);
923 if (maps_by_name)
924 maps_by_name[nr_maps + 1] = map__get(new2);
925 }
926 RC_CHK_ACCESS(maps)->nr_maps = nr_maps + to_add;
927 maps__set_maps_by_name_sorted(maps, false);
928 map__set_kmap_maps(new1, maps);
929 map__set_kmap_maps(new2, maps);
930
931 check_invariants(maps);
932 return 0;
933}
934
935/*
936 * Adds new to maps, if new overlaps existing entries then the existing maps are
937 * adjusted or removed so that new fits without overlapping any entries.
938 */
939static int __maps__fixup_overlap_and_insert(struct maps *maps, struct map *new)
940{
941 int err = 0;
942 unsigned int i, ni = INT_MAX; // Some gcc complain, but depends on maps_by_name...
943
944 if (!maps__maps_by_address_sorted(maps))
945 __maps__sort_by_address(maps);
946
947 /*
948 * Iterate through entries where the end of the existing entry is
949 * greater-than the new map's start.
950 */
951 for (i = first_ending_after(maps, new); i < maps__nr_maps(maps); ) {
952 struct map **maps_by_address = maps__maps_by_address(maps);
953 struct map **maps_by_name = maps__maps_by_name(maps);
954 struct map *pos = maps_by_address[i];
955 struct map *before = NULL, *after = NULL;
956
957 /*
958 * Stop if current map starts after map->end.
959 * Maps are ordered by start: next will not overlap for sure.
960 */
961 if (map__start(pos) >= map__end(new))
962 break;
963
964 if (use_browser) {
965 pr_debug("overlapping maps in %s (disable tui for more info)\n",
966 dso__name(map__dso(new)));
967 } else if (verbose >= 2) {
968 pr_debug("overlapping maps:\n");
969 map__fprintf(new, debug_file());
970 map__fprintf(pos, debug_file());
971 }
972
973 if (maps_by_name)
974 ni = maps__by_name_index(maps, pos);
975
976 /*
977 * Now check if we need to create new maps for areas not
978 * overlapped by the new map:
979 */
980 if (map__start(new) > map__start(pos)) {
981 /* Map starts within existing map. Need to shorten the existing map. */
982 before = map__clone(pos);
983
984 if (before == NULL) {
985 err = -ENOMEM;
986 goto out_err;
987 }
988 map__set_end(before, map__start(new));
989
990 if (verbose >= 2 && !use_browser)
991 map__fprintf(before, debug_file());
992 }
993 if (map__end(new) < map__end(pos)) {
994 /* The new map isn't as long as the existing map. */
995 after = map__clone(pos);
996
997 if (after == NULL) {
998 map__zput(before);
999 err = -ENOMEM;
1000 goto out_err;
1001 }
1002
1003 map__set_start(after, map__end(new));
1004 map__add_pgoff(after, map__end(new) - map__start(pos));
1005 assert(map__map_ip(pos, map__end(new)) ==
1006 map__map_ip(after, map__end(new)));
1007
1008 if (verbose >= 2 && !use_browser)
1009 map__fprintf(after, debug_file());
1010 }
1011 /*
1012 * If adding one entry, for `before` or `after`, we can replace
1013 * the existing entry. If both `before` and `after` are
1014 * necessary than an insert is needed. If the existing entry
1015 * entirely overlaps the existing entry it can just be removed.
1016 */
1017 if (before) {
1018 map__put(maps_by_address[i]);
1019 maps_by_address[i] = before;
1020 map__set_kmap_maps(before, maps);
1021
1022 if (maps_by_name) {
1023 map__put(maps_by_name[ni]);
1024 maps_by_name[ni] = map__get(before);
1025 }
1026
1027 /* Maps are still ordered, go to next one. */
1028 i++;
1029 if (after) {
1030 /*
1031 * 'before' and 'after' mean 'new' split the
1032 * 'pos' mapping and therefore there are no
1033 * later mappings.
1034 */
1035 err = __maps__insert_sorted(maps, i, new, after);
1036 map__put(after);
1037 check_invariants(maps);
1038 return err;
1039 }
1040 check_invariants(maps);
1041 } else if (after) {
1042 /*
1043 * 'after' means 'new' split 'pos' and there are no
1044 * later mappings.
1045 */
1046 map__put(maps_by_address[i]);
1047 maps_by_address[i] = map__get(new);
1048 map__set_kmap_maps(new, maps);
1049
1050 if (maps_by_name) {
1051 map__put(maps_by_name[ni]);
1052 maps_by_name[ni] = map__get(new);
1053 maps__set_maps_by_name_sorted(maps, false);
1054 }
1055
1056 err = __maps__insert_sorted(maps, i + 1, after, NULL);
1057 map__put(after);
1058 check_invariants(maps);
1059 return err;
1060 } else {
1061 struct map *next = NULL;
1062 unsigned int nr_maps = maps__nr_maps(maps);
1063
1064 if (i + 1 < nr_maps)
1065 next = maps_by_address[i + 1];
1066
1067 if (!next || map__start(next) >= map__end(new)) {
1068 /*
1069 * Replace existing mapping and end knowing
1070 * there aren't later overlapping or any
1071 * mappings.
1072 */
1073 map__put(maps_by_address[i]);
1074 maps_by_address[i] = map__get(new);
1075 map__set_kmap_maps(new, maps);
1076
1077 if (maps_by_name) {
1078 map__put(maps_by_name[ni]);
1079 maps_by_name[ni] = map__get(new);
1080 maps__set_maps_by_name_sorted(maps, false);
1081 }
1082
1083 check_invariants(maps);
1084 return err;
1085 }
1086 /*
1087 * pos fully covers the previous mapping so remove
1088 * it. The following is an inlined version of
1089 * maps__remove that reuses the already computed
1090 * indices.
1091 */
1092 map__put(maps_by_address[i]);
1093 memmove(&maps_by_address[i],
1094 &maps_by_address[i + 1],
1095 (nr_maps - i - 1) * sizeof(*maps_by_address));
1096
1097 if (maps_by_name) {
1098 map__put(maps_by_name[ni]);
1099 memmove(&maps_by_name[ni],
1100 &maps_by_name[ni + 1],
1101 (nr_maps - ni - 1) * sizeof(*maps_by_name));
1102 }
1103 --RC_CHK_ACCESS(maps)->nr_maps;
1104 check_invariants(maps);
1105 /*
1106 * Maps are ordered but no need to increase `i` as the
1107 * later maps were moved down.
1108 */
1109 }
1110 }
1111 /* Add the map. */
1112 err = __maps__insert_sorted(maps, i, new, NULL);
1113out_err:
1114 return err;
1115}
1116
1117int maps__fixup_overlap_and_insert(struct maps *maps, struct map *new)
1118{
1119 int err;
1120
1121 down_write(maps__lock(maps));
1122 err = __maps__fixup_overlap_and_insert(maps, new);
1123 up_write(maps__lock(maps));
1124 return err;
1125}
1126
1127int maps__copy_from(struct maps *dest, struct maps *parent)
1128{
1129 /* Note, if struct map were immutable then cloning could use ref counts. */
1130 struct map **parent_maps_by_address;
1131 int err = 0;
1132 unsigned int n;
1133
1134 down_write(maps__lock(dest));
1135 down_read(maps__lock(parent));
1136
1137#ifdef HAVE_LIBUNWIND_SUPPORT
1138 err = unwind__prepare_access(dest, maps__e_machine(parent));
1139 if (err) {
1140 up_read(maps__lock(parent));
1141 up_write(maps__lock(dest));
1142 return err;
1143 }
1144#endif
1145 parent_maps_by_address = maps__maps_by_address(parent);
1146 n = maps__nr_maps(parent);
1147 if (maps__nr_maps(dest) == 0) {
1148 /* No existing mappings so just copy from parent to avoid reallocs in insert. */
1149 unsigned int nr_maps_allocated = RC_CHK_ACCESS(parent)->nr_maps_allocated;
1150 struct map **dest_maps_by_address =
1151 malloc(nr_maps_allocated * sizeof(struct map *));
1152 struct map **dest_maps_by_name = NULL;
1153
1154 if (!dest_maps_by_address)
1155 err = -ENOMEM;
1156 else {
1157 if (maps__maps_by_name(parent)) {
1158 dest_maps_by_name =
1159 malloc(nr_maps_allocated * sizeof(struct map *));
1160 }
1161
1162 RC_CHK_ACCESS(dest)->maps_by_address = dest_maps_by_address;
1163 RC_CHK_ACCESS(dest)->maps_by_name = dest_maps_by_name;
1164 RC_CHK_ACCESS(dest)->nr_maps_allocated = nr_maps_allocated;
1165 }
1166
1167 for (unsigned int i = 0; !err && i < n; i++) {
1168 struct map *pos = parent_maps_by_address[i];
1169 struct map *new = map__clone(pos);
1170
1171 if (!new)
1172 err = -ENOMEM;
1173 else {
1174 dest_maps_by_address[i] = new;
1175 map__set_kmap_maps(new, dest);
1176 if (dest_maps_by_name)
1177 dest_maps_by_name[i] = map__get(new);
1178 RC_CHK_ACCESS(dest)->nr_maps = i + 1;
1179 }
1180 if (err)
1181 map__put(new);
1182 }
1183 maps__set_maps_by_address_sorted(dest, maps__maps_by_address_sorted(parent));
1184 RC_CHK_ACCESS(dest)->last_search_by_name_idx = 0;
1185 /* Values were copied into the name array in address order. */
1186 maps__set_maps_by_name_sorted(dest, false);
1187 } else {
1188 /* Unexpected copying to a maps containing entries. */
1189 for (unsigned int i = 0; !err && i < n; i++) {
1190 struct map *pos = parent_maps_by_address[i];
1191 struct map *new = map__clone(pos);
1192
1193 if (!new)
1194 err = -ENOMEM;
1195 else {
1196 err = __maps__insert(dest, new);
1197 }
1198 map__put(new);
1199 }
1200 }
1201 check_invariants(dest);
1202
1203 up_read(maps__lock(parent));
1204 up_write(maps__lock(dest));
1205 return err;
1206}
1207
1208static int map__addr_cmp(const void *key, const void *entry)
1209{
1210 const u64 ip = *(const u64 *)key;
1211 const struct map *map = *(const struct map * const *)entry;
1212
1213 if (ip < map__start(map))
1214 return -1;
1215 if (ip >= map__end(map))
1216 return 1;
1217 return 0;
1218}
1219
1220struct map *maps__find(struct maps *maps, u64 ip)
1221{
1222 struct map *result = NULL;
1223 bool done = false;
1224
1225 /* See locking/sorting note. */
1226 while (!done) {
1227 down_read(maps__lock(maps));
1228 if (maps__maps_by_address_sorted(maps)) {
1229 struct map **mapp = NULL;
1230 struct map **maps_by_address = maps__maps_by_address(maps);
1231 unsigned int nr_maps = maps__nr_maps(maps);
1232
1233 if (maps_by_address && nr_maps)
1234 mapp = bsearch(&ip, maps_by_address, nr_maps, sizeof(*mapp),
1235 map__addr_cmp);
1236 if (mapp)
1237 result = map__get(*mapp);
1238 done = true;
1239 }
1240 up_read(maps__lock(maps));
1241 if (!done)
1242 maps__sort_by_address(maps);
1243 }
1244 return result;
1245}
1246
1247static int map__strcmp_name(const void *name, const void *b)
1248{
1249 const struct dso *dso = map__dso(*(const struct map **)b);
1250
1251 return strcmp(name, dso__short_name(dso));
1252}
1253
1254struct map *maps__find_by_name(struct maps *maps, const char *name)
1255{
1256 struct map *result = NULL;
1257 bool done = false;
1258
1259 /* See locking/sorting note. */
1260 while (!done) {
1261 unsigned int i;
1262
1263 down_read(maps__lock(maps));
1264
1265 /* First check last found entry. */
1266 i = RC_CHK_ACCESS(maps)->last_search_by_name_idx;
1267 if (i < maps__nr_maps(maps) && maps__maps_by_name(maps)) {
1268 struct dso *dso = map__dso(maps__maps_by_name(maps)[i]);
1269
1270 if (dso && strcmp(dso__short_name(dso), name) == 0) {
1271 result = map__get(maps__maps_by_name(maps)[i]);
1272 done = true;
1273 }
1274 }
1275
1276 /* Second search sorted array. */
1277 if (!done && maps__maps_by_name_sorted(maps)) {
1278 struct map **mapp =
1279 bsearch(name, maps__maps_by_name(maps), maps__nr_maps(maps),
1280 sizeof(*mapp), map__strcmp_name);
1281
1282 if (mapp) {
1283 result = map__get(*mapp);
1284 i = mapp - maps__maps_by_name(maps);
1285 RC_CHK_ACCESS(maps)->last_search_by_name_idx = i;
1286 }
1287 done = true;
1288 }
1289 up_read(maps__lock(maps));
1290 if (!done) {
1291 /* Sort and retry binary search. */
1292 if (maps__sort_by_name(maps)) {
1293 /*
1294 * Memory allocation failed do linear search
1295 * through address sorted maps.
1296 */
1297 struct map **maps_by_address;
1298 unsigned int n;
1299
1300 down_read(maps__lock(maps));
1301 maps_by_address = maps__maps_by_address(maps);
1302 n = maps__nr_maps(maps);
1303 for (i = 0; i < n; i++) {
1304 struct map *pos = maps_by_address[i];
1305 struct dso *dso = map__dso(pos);
1306
1307 if (dso && strcmp(dso__short_name(dso), name) == 0) {
1308 result = map__get(pos);
1309 break;
1310 }
1311 }
1312 up_read(maps__lock(maps));
1313 done = true;
1314 }
1315 }
1316 }
1317 return result;
1318}
1319
1320struct map *maps__find_next_entry(struct maps *maps, struct map *map)
1321{
1322 unsigned int i;
1323 struct map *result = NULL;
1324
1325 down_read(maps__lock(maps));
1326 while (!maps__maps_by_address_sorted(maps)) {
1327 up_read(maps__lock(maps));
1328 maps__sort_by_address(maps);
1329 down_read(maps__lock(maps));
1330 }
1331 i = maps__by_address_index(maps, map);
1332 if (++i < maps__nr_maps(maps))
1333 result = map__get(maps__maps_by_address(maps)[i]);
1334
1335 up_read(maps__lock(maps));
1336 return result;
1337}
1338
1339void maps__fixup_end(struct maps *maps)
1340{
1341 struct map **maps_by_address;
1342 unsigned int n;
1343
1344 down_write(maps__lock(maps));
1345 if (!maps__maps_by_address_sorted(maps))
1346 __maps__sort_by_address(maps);
1347
1348 maps_by_address = maps__maps_by_address(maps);
1349 n = maps__nr_maps(maps);
1350 for (unsigned int i = 1; i < n; i++) {
1351 struct map *prev = maps_by_address[i - 1];
1352 struct map *curr = maps_by_address[i];
1353
1354 if (!map__end(prev) || map__end(prev) > map__start(curr))
1355 map__set_end(prev, map__start(curr));
1356 }
1357
1358 /*
1359 * We still haven't the actual symbols, so guess the
1360 * last map final address.
1361 */
1362 if (n > 0 && !map__end(maps_by_address[n - 1]))
1363 map__set_end(maps_by_address[n - 1], ~0ULL);
1364
1365 RC_CHK_ACCESS(maps)->ends_broken = false;
1366 check_invariants(maps);
1367
1368 up_write(maps__lock(maps));
1369}
1370
1371/*
1372 * Merges map into maps by splitting the new map within the existing map
1373 * regions.
1374 */
1375int maps__merge_in(struct maps *kmaps, struct map *new_map)
1376{
1377 unsigned int first_after_, kmaps__nr_maps;
1378 struct map **kmaps_maps_by_address;
1379 struct map **merged_maps_by_address;
1380 unsigned int merged_nr_maps_allocated;
1381
1382 /* First try under a read lock. */
1383 while (true) {
1384 down_read(maps__lock(kmaps));
1385 if (maps__maps_by_address_sorted(kmaps))
1386 break;
1387
1388 up_read(maps__lock(kmaps));
1389
1390 /* First after binary search requires sorted maps. Sort and try again. */
1391 maps__sort_by_address(kmaps);
1392 }
1393 first_after_ = first_ending_after(kmaps, new_map);
1394 kmaps_maps_by_address = maps__maps_by_address(kmaps);
1395
1396 if (first_after_ >= maps__nr_maps(kmaps) ||
1397 map__start(kmaps_maps_by_address[first_after_]) >= map__end(new_map)) {
1398 /* No overlap so regular insert suffices. */
1399 up_read(maps__lock(kmaps));
1400 return maps__insert(kmaps, new_map);
1401 }
1402 up_read(maps__lock(kmaps));
1403
1404 /* Plain insert with a read-lock failed, try again now with the write lock. */
1405 down_write(maps__lock(kmaps));
1406 if (!maps__maps_by_address_sorted(kmaps))
1407 __maps__sort_by_address(kmaps);
1408
1409 first_after_ = first_ending_after(kmaps, new_map);
1410 kmaps_maps_by_address = maps__maps_by_address(kmaps);
1411 kmaps__nr_maps = maps__nr_maps(kmaps);
1412
1413 if (first_after_ >= kmaps__nr_maps ||
1414 map__start(kmaps_maps_by_address[first_after_]) >= map__end(new_map)) {
1415 /* No overlap so regular insert suffices. */
1416 int ret = __maps__insert(kmaps, new_map);
1417
1418 check_invariants(kmaps);
1419 up_write(maps__lock(kmaps));
1420 return ret;
1421 }
1422 /* Array to merge into, possibly 1 more for the sake of new_map. */
1423 merged_nr_maps_allocated = RC_CHK_ACCESS(kmaps)->nr_maps_allocated;
1424 if (kmaps__nr_maps + 1 == merged_nr_maps_allocated)
1425 merged_nr_maps_allocated++;
1426
1427 merged_maps_by_address = malloc(merged_nr_maps_allocated * sizeof(*merged_maps_by_address));
1428 if (!merged_maps_by_address) {
1429 up_write(maps__lock(kmaps));
1430 return -ENOMEM;
1431 }
1432 maps__set_maps_by_address(kmaps, merged_maps_by_address);
1433 maps__set_maps_by_address_sorted(kmaps, true);
1434 __maps__free_maps_by_name(kmaps);
1435 maps__set_nr_maps_allocated(kmaps, merged_nr_maps_allocated);
1436
1437 /* Copy entries before the new_map that can't overlap. */
1438 for (unsigned int i = 0; i < first_after_; i++)
1439 merged_maps_by_address[i] = map__get(kmaps_maps_by_address[i]);
1440
1441 maps__set_nr_maps(kmaps, first_after_);
1442
1443 /* Add the new map, it will be split when the later overlapping mappings are added. */
1444 __maps__insert(kmaps, new_map);
1445
1446 /* Insert mappings after new_map, splitting new_map in the process. */
1447 for (unsigned int i = first_after_; i < kmaps__nr_maps; i++)
1448 __maps__fixup_overlap_and_insert(kmaps, kmaps_maps_by_address[i]);
1449
1450 /* Copy the maps from merged into kmaps. */
1451 for (unsigned int i = 0; i < kmaps__nr_maps; i++)
1452 map__zput(kmaps_maps_by_address[i]);
1453
1454 free(kmaps_maps_by_address);
1455 check_invariants(kmaps);
1456 up_write(maps__lock(kmaps));
1457 return 0;
1458}
1459
1460void maps__load_first(struct maps *maps)
1461{
1462 down_read(maps__lock(maps));
1463
1464 if (maps__nr_maps(maps) > 0)
1465 map__load(maps__maps_by_address(maps)[0]);
1466
1467 up_read(maps__lock(maps));
1468}