From nobody Tue Feb 10 03:40:30 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1586275066; cv=none; d=zohomail.com; s=zohoarc; b=InpvCXBzy/JO/G2OQAso9fr/j5rmarSy7tEJDmTDWevVt4MndvVdspgDhE4sMXE8OzOm7AMpnDNvie+XLTfhH8dlZJoBCmd/79N2Hbx4cI6nqTbJ7XFB5p1R6F8GVaGruO3IKv98ByO+iBS4hsJF529XLHPbXUSOntT7bBFW89M= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1586275066; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=1J4Mb00cD/gBndme3KRwMHmDdy2oCcZCIa8IBou3aHg=; b=Dn8JFL4/wszqUP2DJjACmSnPGaTV92bUZ2kDm4tNioii8P4EPxrfjM1EmkKgBpY83aUem93Rjp3fKOWjErXyH31PwyPRjM5GNMmARuzcI8DdyQuVauDtUCuBW1vQi3z8WDUTRpIgQLlXezUVSE0iaObwVaOARvyACiE4ooEakdA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1586275066383761.8323545873673; Tue, 7 Apr 2020 08:57:46 -0700 (PDT) Received: from localhost ([::1]:49802 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jLqbg-0005nM-Rm for importer@patchew.org; Tue, 07 Apr 2020 11:57:44 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43716) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jLqVi-0003d4-5j for qemu-devel@nongnu.org; Tue, 07 Apr 2020 11:51:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jLqVg-0004OV-F1 for qemu-devel@nongnu.org; Tue, 07 Apr 2020 11:51:34 -0400 Received: from mail-wm1-x343.google.com ([2a00:1450:4864:20::343]:55527) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1jLqVg-0004Nu-8M for qemu-devel@nongnu.org; Tue, 07 Apr 2020 11:51:32 -0400 Received: by mail-wm1-x343.google.com with SMTP id e26so2232323wmk.5 for ; Tue, 07 Apr 2020 08:51:32 -0700 (PDT) Received: from zen.linaroharston ([51.148.130.216]) by smtp.gmail.com with ESMTPSA id p22sm2849817wmc.42.2020.04.07.08.51.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Apr 2020 08:51:26 -0700 (PDT) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 165AD1FF98; Tue, 7 Apr 2020 16:51:19 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=1J4Mb00cD/gBndme3KRwMHmDdy2oCcZCIa8IBou3aHg=; b=GpDLWiHOKc9NuiNI7Z/GbclUEwnk9F1uroe7YWurmeYHOylclPEBBoN0mPwRqDnI73 skZfvA/M3g3CvUyYsQFcCkOo2ufbemcf7ZXhenFjutLgAIXnbXhjSEjWqqJ8UELNrCVe XEK7wrKmlySAQefuSXKDlAluJo9l2VsOaUydQa49MvuMoLjcrWay2RSDI3iS/F1D5iPN pBTyuDu0lLXzQSkf9BqEc/za62i416Dl0wfyJwIgAnof1fZmSb1c8L+z0l+NQVd8vj/h 4d5itWKb4vRDKEvOAs1wE3PpfJMK3uv5hc50drqA/K595xqM/foF/2CaC1KlQ34u3nWZ yW1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1J4Mb00cD/gBndme3KRwMHmDdy2oCcZCIa8IBou3aHg=; b=dVcMkzQ4/vLwq15pEGRLbHEXl7JSMbIAF8CIeZso/JiS04wO6BMeSzRxwkCa0Dsn7M 1K9msRDIFR/V7+AstIEBzfh42TifN8ogBAbJaKjE9+4PcK8EQmWmzumWAujkdgV64qfo ldlu5PJGNmYzCaIdYIPLcBvvjOWEKNJzq+3T3Z2MF6D4ysiZXAHDnjiL1hbTwWGxixL4 bBgs6SiIpEITbb+wp8UG6S7DaPGCIDNV0uZCbOQaT0qKRaCvHKUN/rZu8so1ZnthP50E ppMXod1vNEEqBiL9rH1i2kD7brjUQlO7XzvaeAYaXqBxPUOM/VILyYdJrVNhSHcoSzP8 j7WQ== X-Gm-Message-State: AGi0PubYOuCDXq9P/Mx2ymmfc4/nBrWnhl1qZ7W1JGtej97516iY7JMN zy3E2nmJSVPmtFsNrlE3ICp8GgpTwJ4= X-Google-Smtp-Source: APiQypKC1zBU/34fmCdCAJ+GiqRzDVXYcqkGz0tWTvPZUnQx73ZuuJtvf7NwhvlP1nM0mPZej4brBQ== X-Received: by 2002:a7b:c3ce:: with SMTP id t14mr3167701wmj.9.1586274691083; Tue, 07 Apr 2020 08:51:31 -0700 (PDT) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: peter.maydell@linaro.org Subject: [PULL 09/13] linux-user: factor out reading of /proc/self/maps Date: Tue, 7 Apr 2020 16:51:14 +0100 Message-Id: <20200407155118.20139-10-alex.bennee@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200407155118.20139-1-alex.bennee@linaro.org> References: <20200407155118.20139-1-alex.bennee@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::343 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Riku Voipio , =?UTF-8?q?Alex=20Benn=C3=A9e?= , qemu-devel@nongnu.org, Laurent Vivier Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Unfortunately reading /proc/self/maps is still considered the gold standard for a process finding out about it's own memory layout. As we will want this data in other contexts soon factor out the code to read and parse the data. Rather than just blindly copying the existing sscanf based code we use a more modern glib version of the parsing code to make a more general purpose map structure. Signed-off-by: Alex Benn=C3=A9e Message-Id: <20200403191150.863-9-alex.bennee@linaro.org> diff --git a/include/qemu/selfmap.h b/include/qemu/selfmap.h new file mode 100644 index 00000000000..8382c4c779d --- /dev/null +++ b/include/qemu/selfmap.h @@ -0,0 +1,44 @@ +/* + * Utility functions to read our own memory map + * + * Copyright (c) 2020 Linaro Ltd + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef _SELFMAP_H_ +#define _SELFMAP_H_ + +typedef struct { + unsigned long start; + unsigned long end; + + /* flags */ + bool is_read; + bool is_write; + bool is_exec; + bool is_priv; + + unsigned long offset; + gchar *dev; + uint64_t inode; + gchar *path; +} MapInfo; + + +/** + * read_self_maps: + * + * Read /proc/self/maps and return a list of MapInfo structures. + */ +GSList *read_self_maps(void); + +/** + * free_self_maps: + * @info: a GSlist + * + * Free a list of MapInfo structures. + */ +void free_self_maps(GSList *info); + +#endif /* _SELFMAP_H_ */ diff --git a/linux-user/syscall.c b/linux-user/syscall.c index b679bc6b136..5f117872947 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -117,6 +117,7 @@ =20 #include "qemu.h" #include "qemu/guest-random.h" +#include "qemu/selfmap.h" #include "user/syscall-trace.h" #include "qapi/error.h" #include "fd-trans.h" @@ -7232,45 +7233,45 @@ static int open_self_maps(void *cpu_env, int fd) { CPUState *cpu =3D env_cpu((CPUArchState *)cpu_env); TaskState *ts =3D cpu->opaque; - FILE *fp; - char *line =3D NULL; - size_t len =3D 0; - ssize_t read; + GSList *map_info =3D read_self_maps(); + GSList *s; =20 - fp =3D fopen("/proc/self/maps", "r"); - if (fp =3D=3D NULL) { - return -1; - } + for (s =3D map_info; s; s =3D g_slist_next(s)) { + MapInfo *e =3D (MapInfo *) s->data; =20 - while ((read =3D getline(&line, &len, fp)) !=3D -1) { - int fields, dev_maj, dev_min, inode; - uint64_t min, max, offset; - char flag_r, flag_w, flag_x, flag_p; - char path[512] =3D ""; - fields =3D sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x= :%x %d" - " %512s", &min, &max, &flag_r, &flag_w, &flag_x, - &flag_p, &offset, &dev_maj, &dev_min, &inode, path= ); - - if ((fields < 10) || (fields > 11)) { - continue; - } - if (h2g_valid(min)) { + if (h2g_valid(e->start)) { + unsigned long min =3D e->start; + unsigned long max =3D e->end; int flags =3D page_get_flags(h2g(min)); - max =3D h2g_valid(max - 1) ? max : (uintptr_t)g2h(GUEST_ADDR_M= AX) + 1; + const char *path; + + max =3D h2g_valid(max - 1) ? + max : (uintptr_t) g2h(GUEST_ADDR_MAX) + 1; + if (page_check_range(h2g(min), max - min, flags) =3D=3D -1) { continue; } + if (h2g(min) =3D=3D ts->info->stack_limit) { - pstrcpy(path, sizeof(path), " [stack]"); + path =3D " [stack]"; + } else { + path =3D e->path; } + dprintf(fd, TARGET_ABI_FMT_ptr "-" TARGET_ABI_FMT_ptr - " %c%c%c%c %08" PRIx64 " %02x:%02x %d %s%s\n", - h2g(min), h2g(max - 1) + 1, flag_r, flag_w, - flag_x, flag_p, offset, dev_maj, dev_min, inode, - path[0] ? " " : "", path); + " %c%c%c%c %08" PRIx64 " %s %"PRId64" %s%s\n", + h2g(min), h2g(max - 1) + 1, + e->is_read ? 'r' : '-', + e->is_write ? 'w' : '-', + e->is_exec ? 'x' : '-', + e->is_priv ? 'p' : '-', + (uint64_t) e->offset, e->dev, e->inode, + path ? " " : "", path ? path : ""); } } =20 + free_self_maps(map_info); + #ifdef TARGET_VSYSCALL_PAGE /* * We only support execution from the vsyscall page. @@ -7281,9 +7282,6 @@ static int open_self_maps(void *cpu_env, int fd) TARGET_VSYSCALL_PAGE, TARGET_VSYSCALL_PAGE + TARGET_PAGE_SIZE); #endif =20 - free(line); - fclose(fp); - return 0; } =20 diff --git a/util/selfmap.c b/util/selfmap.c new file mode 100644 index 00000000000..2ec99dfdda1 --- /dev/null +++ b/util/selfmap.c @@ -0,0 +1,78 @@ +/* + * 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" + +GSList *read_self_maps(void) +{ + gchar *maps; + GSList *map_info =3D NULL; + + if (g_file_get_contents("/proc/self/maps", &maps, NULL, NULL)) { + gchar **lines =3D g_strsplit(maps, "\n", 0); + int i, entries =3D g_strv_length(lines); + + for (i =3D 0; i < entries; i++) { + gchar **fields =3D g_strsplit(lines[i], " ", 6); + if (g_strv_length(fields) > 4) { + MapInfo *e =3D g_new0(MapInfo, 1); + int errors; + const char *end; + + errors =3D qemu_strtoul(fields[0], &end, 16, &e->start); + errors +=3D qemu_strtoul(end + 1, NULL, 16, &e->end); + + e->is_read =3D fields[1][0] =3D=3D 'r'; + e->is_write =3D fields[1][1] =3D=3D 'w'; + e->is_exec =3D fields[1][2] =3D=3D 'x'; + e->is_priv =3D fields[1][3] =3D=3D 'p'; + + errors +=3D qemu_strtoul(fields[2], NULL, 16, &e->offset); + e->dev =3D g_strdup(fields[3]); + errors +=3D qemu_strtou64(fields[4], NULL, 10, &e->inode); + + /* + * The last field may have leading spaces which we + * need to strip. + */ + if (g_strv_length(fields) =3D=3D 6) { + e->path =3D g_strdup(g_strchug(fields[5])); + } + map_info =3D g_slist_prepend(map_info, e); + } + + g_strfreev(fields); + } + g_strfreev(lines); + g_free(maps); + } + + /* ensure the map data is in the same order we collected it */ + return g_slist_reverse(map_info); +} + +/** + * free_self_maps: + * @info: a GSlist + * + * Free a list of MapInfo structures. + */ +static void free_info(gpointer data) +{ + MapInfo *e =3D (MapInfo *) data; + g_free(e->dev); + g_free(e->path); + g_free(e); +} + +void free_self_maps(GSList *info) +{ + g_slist_free_full(info, &free_info); +} diff --git a/util/Makefile.objs b/util/Makefile.objs index 6718a38b616..fe339c2636b 100644 --- a/util/Makefile.objs +++ b/util/Makefile.objs @@ -63,3 +63,4 @@ util-obj-y +=3D guest-random.o util-obj-$(CONFIG_GIO) +=3D dbus.o dbus.o-cflags =3D $(GIO_CFLAGS) dbus.o-libs =3D $(GIO_LIBS) +util-obj-$(CONFIG_USER_ONLY) +=3D selfmap.o --=20 2.20.1