]>
Commit | Line | Data |
---|---|---|
01ef6b9e AB |
1 | /* |
2 | * Utility function to get QEMU's own process map | |
3 | * | |
4 | * Copyright (c) 2020 Linaro Ltd | |
5 | * | |
6 | * SPDX-License-Identifier: GPL-2.0-or-later | |
7 | */ | |
8 | ||
9 | #include "qemu/osdep.h" | |
10 | #include "qemu/cutils.h" | |
11 | #include "qemu/selfmap.h" | |
12 | ||
13 | GSList *read_self_maps(void) | |
14 | { | |
15 | gchar *maps; | |
16 | GSList *map_info = NULL; | |
17 | ||
18 | if (g_file_get_contents("/proc/self/maps", &maps, NULL, NULL)) { | |
19 | gchar **lines = g_strsplit(maps, "\n", 0); | |
20 | int i, entries = g_strv_length(lines); | |
21 | ||
22 | for (i = 0; i < entries; i++) { | |
23 | gchar **fields = g_strsplit(lines[i], " ", 6); | |
24 | if (g_strv_length(fields) > 4) { | |
25 | MapInfo *e = g_new0(MapInfo, 1); | |
53645dc4 | 26 | int errors = 0; |
01ef6b9e AB |
27 | const char *end; |
28 | ||
53645dc4 RH |
29 | errors |= qemu_strtoul(fields[0], &end, 16, &e->start); |
30 | errors |= qemu_strtoul(end + 1, NULL, 16, &e->end); | |
01ef6b9e AB |
31 | |
32 | e->is_read = fields[1][0] == 'r'; | |
33 | e->is_write = fields[1][1] == 'w'; | |
34 | e->is_exec = fields[1][2] == 'x'; | |
35 | e->is_priv = fields[1][3] == 'p'; | |
36 | ||
53645dc4 | 37 | errors |= qemu_strtoul(fields[2], NULL, 16, &e->offset); |
01ef6b9e | 38 | e->dev = g_strdup(fields[3]); |
53645dc4 | 39 | errors |= qemu_strtou64(fields[4], NULL, 10, &e->inode); |
01ef6b9e | 40 | |
53645dc4 RH |
41 | if (!errors) { |
42 | /* | |
43 | * The last field may have leading spaces which we | |
44 | * need to strip. | |
45 | */ | |
46 | if (g_strv_length(fields) == 6) { | |
47 | e->path = g_strdup(g_strchug(fields[5])); | |
48 | } | |
49 | map_info = g_slist_prepend(map_info, e); | |
50 | } else { | |
51 | g_free(e->dev); | |
52 | g_free(e); | |
01ef6b9e | 53 | } |
01ef6b9e AB |
54 | } |
55 | ||
56 | g_strfreev(fields); | |
57 | } | |
58 | g_strfreev(lines); | |
59 | g_free(maps); | |
60 | } | |
61 | ||
62 | /* ensure the map data is in the same order we collected it */ | |
63 | return g_slist_reverse(map_info); | |
64 | } | |
65 | ||
66 | /** | |
67 | * free_self_maps: | |
68 | * @info: a GSlist | |
69 | * | |
70 | * Free a list of MapInfo structures. | |
71 | */ | |
72 | static void free_info(gpointer data) | |
73 | { | |
74 | MapInfo *e = (MapInfo *) data; | |
75 | g_free(e->dev); | |
76 | g_free(e->path); | |
77 | g_free(e); | |
78 | } | |
79 | ||
80 | void free_self_maps(GSList *info) | |
81 | { | |
82 | g_slist_free_full(info, &free_info); | |
83 | } |