xref: /linux/tools/perf/util/maps.c (revision 75a4888b7029a1f98613aef91f517b2ee1f03d43)
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 
27 DECLARE_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 
72 static 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 
121 static struct map **maps__maps_by_address(const struct maps *maps)
122 {
123 	return RC_CHK_ACCESS(maps)->maps_by_address;
124 }
125 
126 static 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 
132 static 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 
137 static 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. */
143 static struct map **maps__maps_by_name(const struct maps *maps)
144 {
145 	return RC_CHK_ACCESS(maps)->maps_by_name;
146 
147 }
148 
149 static 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 
155 static bool maps__maps_by_address_sorted(const struct maps *maps)
156 {
157 	return RC_CHK_ACCESS(maps)->maps_by_address_sorted;
158 }
159 
160 static 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 
165 static bool maps__maps_by_name_sorted(const struct maps *maps)
166 {
167 	return RC_CHK_ACCESS(maps)->maps_by_name_sorted;
168 }
169 
170 static 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 
175 struct machine *maps__machine(const struct maps *maps)
176 {
177 	return RC_CHK_ACCESS(maps)->machine;
178 }
179 
180 unsigned int maps__nr_maps(const struct maps *maps)
181 {
182 	return RC_CHK_ACCESS(maps)->nr_maps;
183 }
184 
185 refcount_t *maps__refcnt(struct maps *maps)
186 {
187 	return &RC_CHK_ACCESS(maps)->refcnt;
188 }
189 
190 #ifdef HAVE_LIBUNWIND_SUPPORT
191 void *maps__addr_space(const struct maps *maps)
192 {
193 	return RC_CHK_ACCESS(maps)->addr_space;
194 }
195 
196 void maps__set_addr_space(struct maps *maps, void *addr_space)
197 {
198 	RC_CHK_ACCESS(maps)->addr_space = addr_space;
199 }
200 
201 uint16_t maps__e_machine(const struct maps *maps)
202 {
203 	return RC_CHK_ACCESS(maps)->e_machine;
204 }
205 
206 void 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
212 void *maps__libdw_addr_space_dwfl(const struct maps *maps)
213 {
214 	return RC_CHK_ACCESS(maps)->libdw_addr_space_dwfl;
215 }
216 
217 void 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 
223 static struct rw_semaphore *maps__lock(struct maps *maps)
224 {
225 	return &RC_CHK_ACCESS(maps)->lock;
226 }
227 
228 static 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 
249 static 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 
267 struct 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 
278 static void maps__delete(struct maps *maps)
279 {
280 	maps__exit(maps);
281 	RC_CHK_FREE(maps);
282 }
283 
284 struct 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 
294 void 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 
302 static 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 
319 static 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 
342 static 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 
354 static 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 
361 static 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 
376 static 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 
411 static 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 
432 static 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 
453 static 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 
472 static 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 
531 int 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 
542 static 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 
568 void 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  */
596 int 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 
621 bool 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 
632 bool maps__equal(struct maps *a, struct maps *b)
633 {
634 	return RC_CHK_EQUAL(a, b);
635 }
636 
637 int 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 
671 int 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 
706 void 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 
731 struct 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 
748 struct 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 
801 int 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 
818 struct maps__fprintf_args {
819 	FILE *fp;
820 	size_t printed;
821 };
822 
823 static 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 
836 size_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  */
852 static 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 
878 static 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  */
939 static 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);
1113 out_err:
1114 	return err;
1115 }
1116 
1117 int 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 
1127 int 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 
1208 static 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 
1220 struct 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 
1247 static 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 
1254 struct 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 
1320 struct 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 
1339 void 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  */
1375 int 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 
1460 void 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 }
1469