This function splits and removes overlapping areas. Maps in tree are ordered by start address thus we could find first overlap and stop if next map does not overlap.
Signed-off-by: Konstantin Khlebnikov <[email protected]> --- tools/perf/util/map.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 89ac5b5dc218..9b3f4d244ad4 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -675,20 +675,35 @@ static void __map_groups__insert(struct map_groups *mg, struct map *map) static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) { struct rb_root *root; - struct rb_node *next; + struct rb_node *next, *first; int err = 0; down_write(&maps->lock); root = &maps->entries; - next = rb_first(root); + /* find first where end > map->start, same as find_vma() */ + next = root->rb_node; + first = NULL; + while (next) { + struct map *pos = rb_entry(next, struct map, rb_node); + + if (pos->end > map->start) { + first = next; + if (pos->start <= map->start) + break; + next = next->rb_left; + } else + next = next->rb_right; + } + + next = first; while (next) { struct map *pos = rb_entry(next, struct map, rb_node); next = rb_next(&pos->rb_node); if (!map__overlap(pos, map)) - continue; + break; if (verbose >= 2) {

