/*
 * Utility function to get QEMU's own process map
 *
 * Copyright (c) 2020 Linaro Ltd
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "qemu/selfmap.h"

IntervalTreeRoot *read_self_maps(void)
{
    IntervalTreeRoot *root;
    gchar *maps, **lines;
    guint i, nlines;

    if (!g_file_get_contents("/proc/self/maps", &maps, NULL, NULL)) {
        return NULL;
    }

    root = g_new0(IntervalTreeRoot, 1);
    lines = g_strsplit(maps, "\n", 0);
    nlines = g_strv_length(lines);

    for (i = 0; i < nlines; i++) {
        gchar **fields = g_strsplit(lines[i], " ", 6);
        guint nfields = g_strv_length(fields);

        if (nfields > 4) {
            uint64_t start, end, offset, inode;
            unsigned dev_maj, dev_min;
            int errors = 0;
            const char *p;

            errors |= qemu_strtou64(fields[0], &p, 16, &start);
            errors |= qemu_strtou64(p + 1, NULL, 16, &end);
            errors |= qemu_strtou64(fields[2], NULL, 16, &offset);
            errors |= qemu_strtoui(fields[3], &p, 16, &dev_maj);
            errors |= qemu_strtoui(p + 1, NULL, 16, &dev_min);
            errors |= qemu_strtou64(fields[4], NULL, 10, &inode);

            if (!errors) {
                size_t path_len;
                MapInfo *e;

                if (nfields == 6) {
                    p = fields[5];
                    p += strspn(p, " ");
                    path_len = strlen(p) + 1;
                } else {
                    p = NULL;
                    path_len = 0;
                }

                e = g_malloc0(sizeof(*e) + path_len);

                e->itree.start = start;
                e->itree.last = end - 1;
                e->offset = offset;
                e->dev = makedev(dev_maj, dev_min);
                e->inode = inode;

                e->is_read  = fields[1][0] == 'r';
                e->is_write = fields[1][1] == 'w';
                e->is_exec  = fields[1][2] == 'x';
                e->is_priv  = fields[1][3] == 'p';

                if (path_len) {
                    e->path = memcpy(e + 1, p, path_len);
                }

                interval_tree_insert(&e->itree, root);
            }
        }
        g_strfreev(fields);
    }
    g_strfreev(lines);
    g_free(maps);

    return root;
}

/**
 * free_self_maps:
 * @root: an interval tree
 *
 * Free a tree of MapInfo structures.
 * Since we allocated each MapInfo in one chunk, we need not consider the
 * contents and can simply free each RBNode.
 */

static void free_rbnode(RBNode *n)
{
    if (n) {
        free_rbnode(n->rb_left);
        free_rbnode(n->rb_right);
        g_free(n);
    }
}

void free_self_maps(IntervalTreeRoot *root)
{
    if (root) {
        free_rbnode(root->rb_root.rb_node);
        g_free(root);
    }
}
