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 AE1D3387703A for ; Fri, 20 Mar 2020 16:59:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org AE1D3387703A 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=1584723552; bh=vYZvfgsQCqVJ4k1MpAMmxUA+X70XhseylroJBXri9/g=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=VTLNnkGWGWRhwjZTmBoVR+rFMsTKizR1xHFdQyF2FKd+y856MvFDUKn72w3TCoMnL 8j103faflltsnByxJu6m8VDGbMdz3Jg+JWeS88R7miLv1a4pm1P0Ppg6F5Vm58o9Fl Z20n+Mg4mow+GnsaT06ehRdrRj9E7vlArYly5N5A= 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 1Mof5H-1jddFm3c0v-00p1w8; Fri, 20 Mar 2020 17:59:12 +0100 From: Kamil Rytarowski To: gdb-patches@sourceware.org Cc: tom@tromey.com, Kamil Rytarowski Subject: [PATCH v2] Implement "info proc mappings" for NetBSD Date: Fri, 20 Mar 2020 17:58:31 +0100 Message-Id: <20200320165831.18904-1-n54@gmx.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200316173424.25375-1-n54@gmx.com> References: <20200316173424.25375-1-n54@gmx.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:ookTXozyWqYC7UsgXtp4isMy7GCxJ1J9oArfbb1w35S0KzCGLZQ j8ETl48/8rWa16gUQWmpwlAvQ5VWd/OMRCC+M5i0FAAUF2uAfTzxK8/QSAl0HzTDI0SvIpB yezpxVH9WuKJMhdBT9jpj2piCNTN0bXAk0DNGprv4bIY/5BSvKaB+mIEzct2MwKJWKj//ts 1pca8KMOAxTCkyybTUINA== X-UI-Out-Filterresults: notjunk:1;V03:K0:BpHegDg7Lyg=:t+MtdEBpuixQa6CzIWN04o mrIkjxW1tTQsFiIyaTFiqbRD19RWvx5MASsbP5k9QXKT1YjY+2Xqs9METiMSz9O/VEY0BPtnV 6WNA4PlggYhwUD1j/tRqbHqQkfBbLf65Zpk4+vIvYZcsFkdUwIuFHiDyPnPbI/sgimht/XYtR G5TUnwYaeFBNdZJwGcg43TAe7FB5Kc/MDt7UuLaLGK9yOL7daCQKQdyFJyFPZGioxf0ejmr9l U4ped0//KsAD++MPwAwU3TO+Vblq560GKFAlB5efVv/fxE7zy/AyryCxD8ky0GW+rk8qfY5LC UsBubjcbW9YPNAn4w5MRDh+vgTMMe+lLQfNMekYjLl3aGN8FjTtJU9CZra9NonOfZiRexiP4p Y7swWWq3BAofd9AaRjYnG8vWpkUTcOodGj7HbBRi/lYrBqNcgzYiK3dU7i+KL1m7AooTaT9Wi KkDcPBWBe5XOFhx1KY8ONzGBxiONAu8xMNhAiCZ9wt+kqHHTHq75BQO+YK77alJuJRg3Pq9T5 KwlcPZhugLo2nzC/XcPGgFwDjSaRsEjL0ypGiSVzvk+IxY7Ahf8QfqDzINyBS+GoChKmNl8Af F2jAbe9tpsnH2ZXDaSnbtu7Gv0Yzm7p3CWJT+/qltHGXSiH9fvTParTcFpBOPriKvTeNQoEXG L2NkXCCL/1SQ3QOwBacdNpdi5SWQ+k2xSdenMuNavqjSE8a5z8lnXHGT3ZVgmHbPobi4PiIRc u/A7NqtRshuaPm9VuYWFih/eanE1JoMzDRc6xbYYnrdUBaz5HySNm2Zgg0U6Bgl0CH7hHAxca NI6XrrGcsxueC+UUFIv6YAbeQgVipZu831tV13fr6EDzbQ0b4c3h8KjUbSTVaPTGCzzyvyZ86 wbHqIt9KctTvJIk1gnv61IODfTHs73VL4osZoxkX4cGITxhgEfuHlpzl9Dpr23UvMzkTMS0Vg jUBKdRtw2gFxlRTU2qeoy+JuNrLv3fKhHDEqSRVKwe6EYGLAVpwLy1ejr/yinLKlyndDiTdzM 57Df3i1z1OkUIDmyquOq73KRbe7u2XmWBWTv1RDeh5t5lyCsgw2gZY21EOZg4EA41H85s3gNL 4vxBFaMubN9fBvgqPbzqlNu2/GRu6QPlXan216isXS4HCTunNx0WPLYQAQ94v1nmeYtKXp/No LEzIJz52pdD/auLjj9FtWayL0ZF9bIVFUuxPo2AopNu4RXLlSOMz6iMxo9PGBO4h1gllg= X-Spam-Status: No, score=-24.3 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, SPF_HELO_NONE, SPF_PASS 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: Fri, 20 Mar 2020 16:59:30 -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() This code is based on the FreeBSD implementation. 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 | 153 ++++++++++++++++++++++++++++++++++++++++++++++++ gdb/nbsd-nat.h | 2 + gdb/nbsd-tdep.c | 91 ++++++++++++++++++++++++++++ gdb/nbsd-tdep.h | 18 ++++++ 5 files changed, 281 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..26115948aa9 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,153 @@ 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 +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 (kiv =3D=3D NULL) + { + *size =3D 0; + return NULL; + } + + if (sysctl (mib, ARRAY_SIZE (mib), kiv.get (), &length, NULL, 0)) + { + *size =3D 0; + return NULL; + } + + *size =3D length / sizeof (*kiv); + 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 *obfd) +{ + pid_t pid =3D inferior_ptid.pid (); + struct kinfo_vmentry *kve; + uint64_t size; + int i; + size_t nitems; + + gdb::unique_xmalloc_ptr + vmentl (kinfo_get_vmmap (pid, &nitems)); + if (vmentl =3D=3D NULL) + perror_with_name (_("Couldn't fetch VM map entries.")); + + for (i =3D 0, kve =3D vmentl.get (); i < nitems; i++, kve++) + { + /* 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 =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, obfd); + } + 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 (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..23732854172 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 fbsd-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