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 312E4385DC22 for ; Sat, 11 Apr 2020 23:46:07 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 312E4385DC22 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=1586648750; bh=mkxCQDzhjaHq1xMqcpU+x6uHC4dhDxz/zK0G8vcvF58=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=iQQkWGTp+Z6W9C0gnpTEgrSPIJjDKc2Pxvr5Pcj3ErMJhaBrYjAtI9oU36dq8thST O0l7lp+Nbo+A/+zl+UdxQtXsfCQnoHoXc8+C4l2O+4difVntj5tTWRhuqV5csdOAJj p9cFnL3rz8ZDPvjfzJ89wlEjYjCAm9bQwUZnO7Tw= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from localhost.localdomain ([89.79.191.25]) by mail.gmx.com (mrgmx004 [212.227.17.184]) with ESMTPSA (Nemesis) id 1MwfWa-1j37mW1zSc-00y8pq; Sun, 12 Apr 2020 01:45:50 +0200 From: Kamil Rytarowski To: gdb-patches@sourceware.org Cc: simark@simark.ca, tom@tromey.com, Kamil Rytarowski Subject: [PATCH v4] Implement "info proc mappings" for NetBSD Date: Sun, 12 Apr 2020 01:45:07 +0200 Message-Id: <20200411234507.17070-1-n54@gmx.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200406093753.13772-1-n54@gmx.com> References: <20200406093753.13772-1-n54@gmx.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K1:unt8AvvhszfcJwj/QYZVoUhcQ/sfyj3KdGegPmj1qVosvWLmPTS ZNhmWA5/YyExPLeXwQDunaSq48gG5Tjqfbh1yYIRRNFCC0WbvrubiNc4+WXYHCmJUX79gUZ AckoP4Hdv+ZAlSb1d9Tga77jUgQu/dFdanAQVmKNROVUC/+d4R90eSIrnEr2whrhC7pnYyz sLBnRCOXEuFrFh/OlXW6Q== X-UI-Out-Filterresults: notjunk:1;V03:K0:MhD1gtX+mr4=:YR6zG0kRhE4rzuXD4JUAoX ObsVusqf7eA1HniOODbi6w2dfrpmnol7ymiiuk2zqKyNuL0wRfdhIr14uMOvw2esEcpov5Et9 zs8wuOyoxkpoDHEk+QaVScUf3bunl3WSg7ZyjRcZ0G/BfCT6GjK8fIJbuJ/poVocJ+vnx9QWY pN+kEbMv6rJ4Vu2YbMvI3vrr10uib0y1VNKmcIIA7iLMlpm7FoLU0SraZcFvRphChzIn1cwdW olQPO08qdKfLa57xDKHra/WvSMoYG1izsWIPdAnyjVTD4JxYeXu6PtolQ6yw9Gdl8NnxNrmvU bhaYZ8/z+IpRs4fqQUn052dOomejJknNTP8qBj/gaPkzRso4YAXXw5WKc2iNS8DDpSmrKSqQt 5LNwP8L4GDbRpUE+uImj9aivzqQqQ8F/Ot6Ld9g1+bwViEiJOTvOj2AvGIf390JXjTTC+vBq8 bLhIKJTSJwtZJeSHyc/OiS3yLvGLSNZ4HNauLbRgozqg5dG1EXkKT3NQ6nuDUfBfPj655ZUGs rID4pUP1vvasvlBVDLiTa1GetzSfx/X9q8IxSl3mLsie1bDqE3OLITw5OZHhHrBonsXYomg+a hUSTu/zp+mThstfjXW2/XEJUideqeaXrYeFCA6EqIooQUJhrrd7McbyNMZIt/LBAF9UMQKqxJ 9ZmS5fPLNyiQ9z5u8l63IEW/D7NJ/HNEosRmaBRNUD7puzF92I+xy/wb7YIoPqf9Pc3EFB40H wTRjfRowZsDJYGYEPiA9bkry2yFVjq+tB2fZlRCbHW8PdkktqL0Z2SbTWMXGmg60FeFbC01ho 6T9CgotAVCJYUnVSNSrykpybOlR6L+ZqFYtwe6Nix/GLboS1DAHJA4Wxub+mz+sp9HgYe1VBU +elFD0JOgQNlmtiBaDQatofk8SCRnYLflWp/9VQSzfR29eLMgSH3wRH+w9qm6PmUaUW+VYBMe w2AVD5sDhIezMGbakKEtJ+U0JiLOAQT5ef+4oziP/++BHNZoTwGgyXcX8fAUSTNfNM+Q3PPQX +8JU2TntfB8n4MR4+dFZFu7wQs4DM3ilqe/LjRooCyc+9SY2LRjw9rvs7SWmPNbGg4Y4ND5Fy W29T0izhlKjSJZezSoJDuc8ZdLZ5v3Vn2vrXGZJy9+vXEswwHk3C6NTOiCuw/zL7Tk3QplfEK 2Ee6+V8X8ug179QKOQggv4WR3fiOqb21Dx1UPwvnYa+lnW+ruzwMTlOa1SiFJhAa0ZLxc= X-Spam-Status: No, score=-28.5 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, 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: Sat, 11 Apr 2020 23:46:10 -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 | 150 ++++++++++++++++++++++++++++++++++++++++++++++++ gdb/nbsd-nat.h | 2 + gdb/nbsd-tdep.c | 91 +++++++++++++++++++++++++++++ gdb/nbsd-tdep.h | 18 ++++++ 5 files changed, 278 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..1651f2033e3 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,150 @@ 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. The length argument is volatile and can chan= ge + between the sysctl(3) calls as this function can be called against a + running process. */ + length =3D length * 5 / 3; + + gdb::unique_xmalloc_ptr kiv + (XNEWVAR (kinfo_vmentry, length)); + + 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..4f24b62a8a7 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 char *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), + 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), + kve_path); + } +} diff --git a/gdb/nbsd-tdep.h b/gdb/nbsd-tdep.h index c99a8b537b6..581ffb4455a 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 char *kve_path); + #endif /* NBSD_TDEP_H */ =2D- 2.25.0