From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mout.gmx.net (mout.gmx.net [212.227.15.15]) by sourceware.org (Postfix) with ESMTPS id 400B6385B831 for ; Mon, 6 Apr 2020 09:39:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 400B6385B831 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=gmx.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=n54@gmx.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1586165927; bh=P83oOgc6qNegzwW8xzM83ne32zfDc4ZPyGGOCwH8f88=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=dHYRiBu4L2oiKFDkM2rYv41gp/coEyJTY4vi+DZ7O4cGw5AOfGYDJAAaLD1Cply0L xD1d+5xJqQlIpIUmdQhPEK+rQkb/qtBm+1u+Lq9xKvVAYO2kLzUGQkWrcm65fAXwMi 2i7HtINOhEUJmP+HbWGDWNQr65JmaKAMXmbkeVNs= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from localhost.localdomain ([89.79.191.25]) by mail.gmx.com (mrgmx005 [212.227.17.184]) with ESMTPSA (Nemesis) id 1MkYc0-1itAOf2178-00m1CX; Mon, 06 Apr 2020 11:38:47 +0200 From: Kamil Rytarowski To: gdb-patches@sourceware.org Cc: tom@tromey.com, jhb@FreeBSD.org, Kamil Rytarowski Subject: [PATCH v3] Implement "info proc mappings" for NetBSD Date: Mon, 6 Apr 2020 11:37:51 +0200 Message-Id: <20200406093753.13772-1-n54@gmx.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200402200916.26504-1-n54@gmx.com> References: <20200402200916.26504-1-n54@gmx.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:KZspCcbacNxmThkVOsx/fNhw8Lx1oJ8+IRsoQkqGvTAJ2fIZSoo yofg2X/3PU/QM+Y3ZepYVv7e79B9s4Yxepw7bR34o8DD0uHNnt9w8+Du6qXpaq0vzVok1o+ XxFfI0R474EN7Z60kyI6n8Lv3m2E2qsvGMCKpyaZhaJPvfF9QHX78eG6OGHgmaFFRoh3gQ8 Db17Mv+o3GFxqqxJhAijA== X-UI-Out-Filterresults: notjunk:1;V03:K0:E1KaNAsSP5Y=:KHk+VuNpjngLRWZVePNy/I 95B00dggcbV48RjlUrpgpSbp9XHEU96L5tqH24vk1kOx5QS/R4a0HqmQRJN7ytrpa6+Vq8BH2 QAVz/PF02sWum/snv4Fo0Dys7BMTgaWF+j+Zzfug6Il6zY7JTu35YBIPFOjyhx1A+RRHIrRsR MZGVXMknapdkdDkYyQvOtysuZA/tewNkPbyJUWSDCSzBw6Mcgj8KGRPVm3i9FwouBaXZlLDRu oikJK6VrdA9zNpaOSHlb+ji9HJo+NXJ9qEqscBZ4Nd2BvmAryLPkztE/4xojIkEacEeAN91lh v8UIb6ZXSSLRxVCb0Bg8+y6uRaEb6IhE/rZ0/vCLik28QdUsGc74kXJ2F7bP6ohSrI0GlZ4U4 /fNO5rKnKJYbWTuTbkZXmgj8OkXdnoCvqpIpoLO0CiWtnr8OIxdGvXgwDlVrr8bEnmpeYIYiY jvJH8m+48ogtIGZjZ7JrBNzgh7vBI6Z1yTiTf1zLqHxhQY/qHDa8fEG5KkUq2gHTxKgmHmEXe gBOhGj5EWKPP5oEDb/cwfHsMkEduoB50yoUWbKx6p6M8PGEwyLELAvKGzI9zT3OJKHMFhqj+B h9/b2XI4r8HTDwIId2berZfnC3MF8NeKxZSr0sKz8hM99rE7ms0pF4QHVR5whIkEIiRre8Wq4 /G7OUAizQ6GHgLRB0VAM1dA7WS9tjMcuK7EKVzfesxH9wGbire9em1jFIfJepdq7QxpoYrU/P iSav0Q9LW/1Q/YUjxvs0xFg9MyrEtiwXJjNLzBFJHvBLhIERfUyDFjDplPQjCYpjo3c3Urtpf RoazFXqFp8a5u2Iu7aHi+zHxPEyoK8FymJLAfs5a6fvi7Rgoy1nSUwNjnRLkOX+W77XhtxDFn 3DFADB3Pf6aBZhhDzhMF7InnU1IdGDR8QsRbC6M5ah45NVseEb9V4EvA07wnvXG2Fq2tb8izo a1R7KvDZ1tdU8ES8jr1IiM0UxkmFv8V4LhAdz0ag+2IPX9qd3ymZSMIlQzBTHVBlRKZ7YYpQv gOQJTJF6ZMcaQu1PLsMOKYJLcQxNtrm2YZ/UPG+B+62boZTdPTXlHmx4xktoTZPITJoPiN/S/ BNp0hWRJBb/gx40qn6rmGc3peaLHi1cBmbRzf3enKsJAOyg5HqmqCPAKbZnf14QTRPDIpibSe 9gF4vC+8JoUbj2KD+c0eRhIuNAL8P6fv9QU0ieHnxB6fr8AQ4dBnarFP/Kss3PTD6viwI= X-Spam-Status: No, score=-28.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Apr 2020 09:39:07 -0000 Define nbsd_nat_target::find_memory_regions and nbsd_nat_target::info_proc. info_proc handles as of now only the "mappings" command. Define a local static function kinfo_get_vmmap() that reads the process memory layout of a specified process. kinfo_get_vmmap() wraps the sysctl(3) call. nbsd-tdep.c defines now utility functions for printing the process memory layout: * nbsd_info_proc_mappings_header() * nbsd_vm_map_entry_flags() * nbsd_info_proc_mappings_entry() gdb/ChangeLog: * nbsd-nat.c; Include "nbsd-tdep.h", "inferior.h" and "gdbarch.h". * nbsd-nat.c (nbsd_nat_target::find_memory_regions) (nbsd_nat_target::info_proc): New functions. * nbsd-nat.c (kinfo_get_vmmap): New function. * nbsd-nat.c (nbsd_nat_target::info_proc) Use nbsd_info_proc_mappings_header and nbsd_info_proc_mappings_entry. * nbsd-tdep.c (nbsd_info_proc_mappings_header) (nbsd_info_proc_mappings_entry, nbsd_vm_map_entry_flags): New functions. * nbsd-tdep.c (KINFO_VME_PROT_READ, KINFO_VME_PROT_WRITE) (KINFO_VME_PROT_EXEC, KINFO_VME_FLAG_COW) (KINFO_VME_FLAG_NEEDS_COPY, KINFO_VME_FLAG_NOCOREDUMP) (KINFO_VME_FLAG_PAGEABLE, KINFO_VME_FLAG_GROWS_UP) (KINFO_VME_FLAG_GROWS_DOWN): New. =2D-- gdb/ChangeLog | 17 ++++++ gdb/nbsd-nat.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++ gdb/nbsd-nat.h | 2 + gdb/nbsd-tdep.c | 91 +++++++++++++++++++++++++++++ gdb/nbsd-tdep.h | 18 ++++++ 5 files changed, 276 insertions(+) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 650b74bae4a..b12965e41bb 100644 =2D-- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,20 @@ +2020-03-20 Kamil Rytarowski + + * nbsd-nat.c; Include "nbsd-tdep.h", "inferior.h" and "gdbarch.h". + * nbsd-nat.c (nbsd_nat_target::find_memory_regions) + (nbsd_nat_target::info_proc): New functions. + * nbsd-nat.c (kinfo_get_vmmap): New function. + * nbsd-nat.c (nbsd_nat_target::info_proc) Use + nbsd_info_proc_mappings_header and nbsd_info_proc_mappings_entry. + * nbsd-tdep.c (nbsd_info_proc_mappings_header) + (nbsd_info_proc_mappings_entry, nbsd_vm_map_entry_flags): New + functions. + * nbsd-tdep.c (KINFO_VME_PROT_READ, KINFO_VME_PROT_WRITE) + (KINFO_VME_PROT_EXEC, KINFO_VME_FLAG_COW) + (KINFO_VME_FLAG_NEEDS_COPY, KINFO_VME_FLAG_NOCOREDUMP) + (KINFO_VME_FLAG_PAGEABLE, KINFO_VME_FLAG_GROWS_UP) + (KINFO_VME_FLAG_GROWS_DOWN): New. + 2020-03-20 Kamil Rytarowski * amd64-bsd-nat.c (gdb_ptrace): Change return type from `int' to diff --git a/gdb/nbsd-nat.c b/gdb/nbsd-nat.c index 326bbe3aec3..82f9837b775 100644 =2D-- a/gdb/nbsd-nat.c +++ b/gdb/nbsd-nat.c @@ -20,6 +20,9 @@ #include "defs.h" #include "nbsd-nat.h" +#include "nbsd-tdep.h" +#include "inferior.h" +#include "gdbarch.h" #include #include @@ -39,3 +42,148 @@ nbsd_nat_target::pid_to_exec_file (int pid) return NULL; return buf; } + +/* Retrieve all the memory regions in the specified process. */ + +static gdb::unique_xmalloc_ptr +nbsd_kinfo_get_vmmap (pid_t pid, size_t *size) +{ + int mib[5] =3D {CTL_VM, VM_PROC, VM_PROC_MAP, pid, + sizeof (struct kinfo_vmentry)}; + + size_t length =3D 0; + if (sysctl (mib, ARRAY_SIZE (mib), NULL, &length, NULL, 0)) + { + *size =3D 0; + return NULL; + } + + /* Prereserve more space. */ + length =3D length * 5 / 3; + + gdb::unique_xmalloc_ptr kiv + ((struct kinfo_vmentry *) xcalloc (length, 1)); + + if (sysctl (mib, ARRAY_SIZE (mib), kiv.get (), &length, NULL, 0)) + { + *size =3D 0; + return NULL; + } + + *size =3D length / sizeof (struct kinfo_vmentry); + return kiv; +} + +/* Iterate over all the memory regions in the current inferior, + calling FUNC for each memory region. OBFD is passed as the last + argument to FUNC. */ + +int +nbsd_nat_target::find_memory_regions (find_memory_region_ftype func, + void *data) +{ + pid_t pid =3D inferior_ptid.pid (); + + size_t nitems; + gdb::unique_xmalloc_ptr vmentl + =3D nbsd_kinfo_get_vmmap (pid, &nitems); + if (vmentl =3D=3D NULL) + perror_with_name (_("Couldn't fetch VM map entries.")); + + for (size_t i =3D 0; i < nitems; i++) + { + struct kinfo_vmentry *kve =3D &vmentl[i]; + + /* Skip unreadable segments and those where MAP_NOCORE has been set= . */ + if (!(kve->kve_protection & KVME_PROT_READ) + || kve->kve_flags & KVME_FLAG_NOCOREDUMP) + continue; + + /* Skip segments with an invalid type. */ + switch (kve->kve_type) + { + case KVME_TYPE_VNODE: + case KVME_TYPE_ANON: + case KVME_TYPE_SUBMAP: + case KVME_TYPE_OBJECT: + break; + default: + continue; + } + + size_t size =3D kve->kve_end - kve->kve_start; + if (info_verbose) + { + fprintf_filtered (gdb_stdout, + "Save segment, %ld bytes at %s (%c%c%c)\n", + (long) size, + paddress (target_gdbarch (), kve->kve_start), + kve->kve_protection & KVME_PROT_READ ? 'r' : '-', + kve->kve_protection & KVME_PROT_WRITE ? 'w' : '-', + kve->kve_protection & KVME_PROT_EXEC ? 'x' : '-'); + } + + /* Invoke the callback function to create the corefile segment. + Pass MODIFIED as true, we do not know the real modification state. */ + func (kve->kve_start, size, kve->kve_protection & KVME_PROT_READ, + kve->kve_protection & KVME_PROT_WRITE, + kve->kve_protection & KVME_PROT_EXEC, 1, data); + } + return 0; +} + +/* Implement the "info_proc" target_ops method. */ + +bool +nbsd_nat_target::info_proc (const char *args, enum info_proc_what what) +{ + pid_t pid; + bool do_mappings =3D false; + + switch (what) + { + case IP_MAPPINGS: + do_mappings =3D true; + break; + default: + error (_("Not supported on this target.")); + } + + gdb_argv built_argv (args); + if (built_argv.count () =3D=3D 0) + { + pid =3D inferior_ptid.pid (); + if (pid =3D=3D 0) + error (_("No current process: you must name one.")); + } + else if (built_argv.count () =3D=3D 1 && isdigit (built_argv[0][0])) + pid =3D strtol (built_argv[0], NULL, 10); + else + error (_("Invalid arguments.")); + + printf_filtered (_("process %d\n"), pid); + + if (do_mappings) + { + size_t nvment; + gdb::unique_xmalloc_ptr vmentl + =3D nbsd_kinfo_get_vmmap (pid, &nvment); + + if (vmentl !=3D nullptr) + { + int addr_bit =3D TARGET_CHAR_BIT * sizeof (void *); + nbsd_info_proc_mappings_header (addr_bit); + + struct kinfo_vmentry *kve =3D vmentl.get (); + for (int i =3D 0; i < nvment; i++, kve++) + nbsd_info_proc_mappings_entry (addr_bit, kve->kve_start, + kve->kve_end, kve->kve_offset, + kve->kve_flags, kve->kve_protection, + kve->kve_path); + } + else + warning (_("unable to fetch virtual memory map")); + } + + return true; +} diff --git a/gdb/nbsd-nat.h b/gdb/nbsd-nat.h index a752fbe572d..98af21d0bda 100644 =2D-- a/gdb/nbsd-nat.h +++ b/gdb/nbsd-nat.h @@ -27,6 +27,8 @@ struct nbsd_nat_target : public inf_ptrace_target { char *pid_to_exec_file (int pid) override; + int find_memory_regions (find_memory_region_ftype func, void *data) ove= rride; + bool info_proc (const char *, enum info_proc_what) override; }; #endif /* nbsd-nat.h */ diff --git a/gdb/nbsd-tdep.c b/gdb/nbsd-tdep.c index 49bb2b706bd..29dc9172306 100644 =2D-- a/gdb/nbsd-tdep.c +++ b/gdb/nbsd-tdep.c @@ -23,6 +23,23 @@ #include "solib-svr4.h" #include "nbsd-tdep.h" +/* Flags in the 'kve_protection' field in struct kinfo_vmentry. These + match the KVME_PROT_* constants in . */ + +#define KINFO_VME_PROT_READ 0x00000001 +#define KINFO_VME_PROT_WRITE 0x00000002 +#define KINFO_VME_PROT_EXEC 0x00000004 + +/* Flags in the 'kve_flags' field in struct kinfo_vmentry. These + match the KVME_FLAG_* constants in . */ + +#define KINFO_VME_FLAG_COW 0x00000001 +#define KINFO_VME_FLAG_NEEDS_COPY 0x00000002 +#define KINFO_VME_FLAG_NOCOREDUMP 0x00000004 +#define KINFO_VME_FLAG_PAGEABLE 0x00000008 +#define KINFO_VME_FLAG_GROWS_UP 0x00000010 +#define KINFO_VME_FLAG_GROWS_DOWN 0x00000020 + /* FIXME: kettenis/20060115: We should really eliminate the next two functions completely. */ @@ -47,3 +64,77 @@ nbsd_pc_in_sigtramp (CORE_ADDR pc, const char *func_nam= e) return (func_name !=3D NULL && startswith (func_name, "__sigtramp")); } + +/* See nbsd-tdep.h. */ + +void +nbsd_info_proc_mappings_header (int addr_bit) +{ + printf_filtered (_("Mapped address spaces:\n\n")); + if (addr_bit =3D=3D 64) + { + printf_filtered (" %18s %18s %10s %10s %9s %s\n", + "Start Addr", + " End Addr", + " Size", " Offset", "Flags ", "File"); + } + else + { + printf_filtered ("\t%10s %10s %10s %10s %9s %s\n", + "Start Addr", + " End Addr", + " Size", " Offset", "Flags ", "File"); + } +} + +/* Helper function to generate mappings flags for a single VM map + entry in 'info proc mappings'. */ + +static const char * +nbsd_vm_map_entry_flags (int kve_flags, int kve_protection) +{ + static char vm_flags[9]; + + vm_flags[0] =3D (kve_protection & KINFO_VME_PROT_READ) ? 'r' : '-'; + vm_flags[1] =3D (kve_protection & KINFO_VME_PROT_WRITE) ? 'w' : '-'; + vm_flags[2] =3D (kve_protection & KINFO_VME_PROT_EXEC) ? 'x' : '-'; + vm_flags[3] =3D ' '; + vm_flags[4] =3D (kve_flags & KINFO_VME_FLAG_COW) ? 'C' : '-'; + vm_flags[5] =3D (kve_flags & KINFO_VME_FLAG_NEEDS_COPY) ? 'N' : '-'; + vm_flags[6] =3D (kve_flags & KINFO_VME_FLAG_PAGEABLE) ? 'P' : '-'; + vm_flags[7] =3D (kve_flags & KINFO_VME_FLAG_GROWS_UP) ? 'U' + : (kve_flags & KINFO_VME_FLAG_GROWS_DOWN) ? 'D' : '-'; + vm_flags[8] =3D '\0'; + + return vm_flags; +} + +/* See nbsd-tdep.h. */ + +void +nbsd_info_proc_mappings_entry (int addr_bit, ULONGEST kve_start, + ULONGEST kve_end, ULONGEST kve_offset, + int kve_flags, int kve_protection, + const void *kve_path) +{ + if (addr_bit =3D=3D 64) + { + printf_filtered (" %18s %18s %10s %10s %9s %s\n", + hex_string (kve_start), + hex_string (kve_end), + hex_string (kve_end - kve_start), + hex_string (kve_offset), + nbsd_vm_map_entry_flags (kve_flags, kve_protection), + reinterpret_cast (kve_path)); + } + else + { + printf_filtered ("\t%10s %10s %10s %10s %9s %s\n", + hex_string (kve_start), + hex_string (kve_end), + hex_string (kve_end - kve_start), + hex_string (kve_offset), + nbsd_vm_map_entry_flags (kve_flags, kve_protection), + reinterpret_cast (kve_path)); + } +} diff --git a/gdb/nbsd-tdep.h b/gdb/nbsd-tdep.h index c99a8b537b6..81bdb2510f5 100644 =2D-- a/gdb/nbsd-tdep.h +++ b/gdb/nbsd-tdep.h @@ -25,4 +25,22 @@ struct link_map_offsets *nbsd_lp64_solib_svr4_fetch_lin= k_map_offsets (void); int nbsd_pc_in_sigtramp (CORE_ADDR, const char *); +/* Output the header for "info proc mappings". ADDR_BIT is the size + of a virtual address in bits. */ + +extern void nbsd_info_proc_mappings_header (int addr_bit); + +/* Output description of a single memory range for "info proc + mappings". ADDR_BIT is the size of a virtual address in bits. The + KVE_START, KVE_END, KVE_OFFSET, KVE_FLAGS, and KVE_PROTECTION + parameters should contain the value of the corresponding fields in + a 'struct kinfo_vmentry'. The KVE_PATH parameter should contain a + pointer to the 'kve_path' field in a 'struct kinfo_vmentry'. */ + +extern void nbsd_info_proc_mappings_entry (int addr_bit, ULONGEST kve_sta= rt, + ULONGEST kve_end, + ULONGEST kve_offset, + int kve_flags, int kve_protection, + const void *kve_path); + #endif /* NBSD_TDEP_H */ =2D- 2.25.0