15389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Copyright (C) 2007-2010 The Android Open Source Project
25389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine**
35389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine** This software is licensed under the terms of the GNU General Public
45389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine** License version 2, as published by the Free Software Foundation, and
55389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine** may be copied, distributed, and modified under those terms.
65389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine**
75389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine** This program is distributed in the hope that it will be useful,
85389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine** but WITHOUT ANY WARRANTY; without even the implied warranty of
95389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
105389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine** GNU General Public License for more details.
115389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine*/
125389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
135389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/*
145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Contains implementation of routines that implement a red-black tree of
155389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * memory mappings in the guest system.
165389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */
175389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
185389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#include "memcheck_mmrange_map.h"
195389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine#include "memcheck_logging.h"
205389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
215389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Memory range descriptor stored in the map. */
225389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinetypedef struct MMRangeMapEntry {
235389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* R-B tree entry. */
245389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    RB_ENTRY(MMRangeMapEntry)   rb_entry;
255389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
265389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* Memory range descriptor for this entry. */
275389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MMRangeDesc                 desc;
285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine} MMRangeMapEntry;
295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
305389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// =============================================================================
315389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// R-B Tree implementation
325389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// =============================================================================
335389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Compare routine for the map.
355389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Param:
365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  d1 - First map entry to compare.
375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  d2 - Second map entry to compare.
385389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Return:
395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  0 - Descriptors are equal. Note that descriptors are considered to be
405389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *      equal iff memory blocks they describe intersect in any part.
415389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  1 - d1 is greater than d2
425389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  -1 - d1 is less than d2.
435389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */
445389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinestatic inline int
455389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinecmp_rb(MMRangeMapEntry* d1, MMRangeMapEntry* d2)
465389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
475389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    const target_ulong start1 = d1->desc.map_start;
485389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    const target_ulong start2 = d2->desc.map_start;
495389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
505389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (start1 < start2) {
515389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return (d1->desc.map_end - 1) < start2 ? -1 : 0;
525389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
535389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    return (d2->desc.map_end - 1) < start1 ? 1 : 0;
545389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
555389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
565389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Expands RB macros here. */
575389aa19033153c09556d1362a8b8a56abccb8f5Vladimir ChtchetkineRB_GENERATE(MMRangeMap, MMRangeMapEntry, rb_entry, cmp_rb);
585389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
595389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// =============================================================================
605389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// Static routines
615389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// =============================================================================
625389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
635389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Inserts new (or replaces existing) entry into the map.
645389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * See comments on mmrangemap_insert routine in the header file for details
655389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * about this routine.
665389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */
675389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinestatic RBTMapResult
685389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinemmrangemap_insert_desc(MMRangeMap* map,
695389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                       MMRangeMapEntry* rdesc,
705389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                       MMRangeDesc* replaced)
715389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
725389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MMRangeMapEntry* existing = MMRangeMap_RB_INSERT(map, rdesc);
735389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (existing == NULL) {
745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return RBT_MAP_RESULT_ENTRY_INSERTED;
755389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    // Matching entry exists. Lets see if we need to replace it.
785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (replaced == NULL) {
795389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return RBT_MAP_RESULT_ENTRY_ALREADY_EXISTS;
805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
825389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    /* Copy existing entry to the provided buffer and replace it
835389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine     * with the new one. */
845389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    memcpy(replaced, &existing->desc, sizeof(MMRangeDesc));
855389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MMRangeMap_RB_REMOVE(map, existing);
865389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    qemu_free(existing);
875389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MMRangeMap_RB_INSERT(map, rdesc);
885389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    return RBT_MAP_RESULT_ENTRY_REPLACED;
895389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
905389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
915389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine/* Finds an entry in the map that matches the given address range.
925389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Param:
935389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  map - Map where to search for an entry.
945389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  start - Starting address of a mapping range.
955389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  end - Ending address of a mapping range.
965389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine * Return:
975389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  Address of a map entry that matches the given range, or NULL if no
985389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine *  such entry has been found.
995389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine */
1005389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinestatic inline MMRangeMapEntry*
1015389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinemmrangemap_find_entry(const MMRangeMap* map,
1025389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                      target_ulong start,
1035389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                      target_ulong end)
1045389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
1055389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MMRangeMapEntry rdesc;
1065389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    rdesc.desc.map_start = start;
1075389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    rdesc.desc.map_end = end;
1085389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    return MMRangeMap_RB_FIND((MMRangeMap*)map, &rdesc);
1095389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
1105389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1115389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// =============================================================================
1125389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// Map API
1135389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine// =============================================================================
1145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1155389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinevoid
1165389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinemmrangemap_init(MMRangeMap* map)
1175389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
1185389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    RB_INIT(map);
1195389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
1205389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1215389aa19033153c09556d1362a8b8a56abccb8f5Vladimir ChtchetkineRBTMapResult
1225389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinemmrangemap_insert(MMRangeMap* map,
1235389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                  const MMRangeDesc* desc,
1245389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                  MMRangeDesc* replaced)
1255389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
1265389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    RBTMapResult ret;
1275389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    // Allocate and initialize new map entry.
1295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MMRangeMapEntry* rdesc = qemu_malloc(sizeof(MMRangeMapEntry));
1305389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (rdesc == NULL) {
1315389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        ME("memcheck: Unable to allocate new MMRangeMapEntry on insert.");
1325389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return RBT_MAP_RESULT_ERROR;
1335389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
1345389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    memcpy(&rdesc->desc, desc, sizeof(MMRangeDesc));
1355389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1365389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    // Insert new entry into the map.
1375389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    ret = mmrangemap_insert_desc(map, rdesc, replaced);
1385389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (ret == RBT_MAP_RESULT_ENTRY_ALREADY_EXISTS ||
1395389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        ret == RBT_MAP_RESULT_ERROR) {
1405389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        /* Another descriptor already exists for this block, or an error
1415389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine         * occurred. We have to free new descriptor, as it wasn't inserted. */
1425389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        qemu_free(rdesc);
1435389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
1445389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    return ret;
1455389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
1465389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1475389aa19033153c09556d1362a8b8a56abccb8f5Vladimir ChtchetkineMMRangeDesc*
1485389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinemmrangemap_find(const MMRangeMap* map, target_ulong start, target_ulong end)
1495389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
1505389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MMRangeMapEntry* rdesc = mmrangemap_find_entry(map, start, end);
1515389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    return rdesc != NULL ? &rdesc->desc : NULL;
1525389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
1535389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1545389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineint
1555389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinemmrangemap_pull(MMRangeMap* map,
1565389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                target_ulong start,
1575389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                target_ulong end,
1585389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                MMRangeDesc* pulled)
1595389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
1605389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MMRangeMapEntry* rdesc = mmrangemap_find_entry(map, start, end);
1615389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (rdesc != NULL) {
1625389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        memcpy(pulled, &rdesc->desc, sizeof(MMRangeDesc));
1635389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        MMRangeMap_RB_REMOVE(map, rdesc);
1645389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        qemu_free(rdesc);
1655389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return 0;
1665389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    } else {
1675389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return -1;
1685389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
1695389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
1705389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1715389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineint
1725389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinemmrangemap_pull_first(MMRangeMap* map, MMRangeDesc* pulled)
1735389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
1745389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MMRangeMapEntry* first = RB_MIN(MMRangeMap, map);
1755389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    if (first != NULL) {
1765389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        memcpy(pulled, &first->desc, sizeof(MMRangeDesc));
1775389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        MMRangeMap_RB_REMOVE(map, first);
1785389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        qemu_free(first);
1795389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return 0;
1805389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    } else {
1815389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        return -1;
1825389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
1835389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
1845389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
1855389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineint
1865389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinemmrangemap_copy(MMRangeMap* to, const MMRangeMap* from)
1875389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
1885389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MMRangeMapEntry* entry;
1895389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    RB_FOREACH(entry, MMRangeMap, (MMRangeMap*)from) {
1905389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        RBTMapResult ins_res;
1915389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        MMRangeMapEntry* new_entry =
1925389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine                (MMRangeMapEntry*)qemu_malloc(sizeof(MMRangeMapEntry));
1935389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (new_entry == NULL) {
1945389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            ME("memcheck: Unable to allocate new MMRangeMapEntry on copy.");
1955389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            return -1;
1965389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
1975389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        memcpy(new_entry, entry, sizeof(MMRangeMapEntry));
1985389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        new_entry->desc.path = qemu_malloc(strlen(entry->desc.path) + 1);
1995389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (new_entry->desc.path == NULL) {
2005389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            ME("memcheck: Unable to allocate new path for MMRangeMapEntry on copy.");
2015389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            qemu_free(new_entry);
2025389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            return -1;
2035389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
2045389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        strcpy(new_entry->desc.path, entry->desc.path);
2055389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        ins_res = mmrangemap_insert_desc(to, new_entry, NULL);
2065389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        if (ins_res != RBT_MAP_RESULT_ENTRY_INSERTED) {
2075389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            ME("memcheck: Unable to insert new range map entry on copy. Insert returned %u",
2085389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine               ins_res);
2095389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            qemu_free(new_entry->desc.path);
2105389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            qemu_free(new_entry);
2115389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine            return -1;
2125389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        }
2135389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
2145389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2155389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    return 0;
2165389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
2175389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2185389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkineint
2195389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkinemmrangemap_empty(MMRangeMap* map)
2205389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine{
2215389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    MMRangeDesc pulled;
2225389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    int removed = 0;
2235389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2245389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    while (!mmrangemap_pull_first(map, &pulled)) {
2255389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        qemu_free(pulled.path);
2265389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine        removed++;
2275389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    }
2285389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine
2295389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine    return removed;
2305389aa19033153c09556d1362a8b8a56abccb8f5Vladimir Chtchetkine}
231