From: Kamil Rytarowski <n54@gmx.com>
To: gdb-patches@sourceware.org
Cc: simark@simark.ca, tom@tromey.com, Kamil Rytarowski <n54@gmx.com>
Subject: [PATCH v5] Implement "info proc mappings" for NetBSD
Date: Sun, 12 Apr 2020 02:09:07 +0200 [thread overview]
Message-ID: <20200412000907.2137-1-n54@gmx.com> (raw)
In-Reply-To: <20200411234507.17070-1-n54@gmx.com>
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" 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.
---
gdb/ChangeLog | 17 ++++++
gdb/nbsd-nat.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++
gdb/nbsd-nat.h | 3 +
gdb/nbsd-tdep.c | 89 +++++++++++++++++++++++++++++
gdb/nbsd-tdep.h | 18 ++++++
5 files changed, 276 insertions(+)
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 81102ee569b..336bd497413 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,20 @@
+2020-04-11 Kamil Rytarowski <n54@gmx.com>
+
+ * nbsd-nat.c; Include "nbsd-tdep.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-04-10 Artur Shepilko <nomadbyte@gmail.com>
* utils.c (copy_bitwise): Use unsigned 0 constant as operand of
diff --git a/gdb/nbsd-nat.c b/gdb/nbsd-nat.c
index 4423e19428d..2420153c7bc 100644
--- a/gdb/nbsd-nat.c
+++ b/gdb/nbsd-nat.c
@@ -21,7 +21,9 @@
#include "nbsd-nat.h"
#include "gdbthread.h"
+#include "nbsd-tdep.h"
#include "inferior.h"
+#include "gdbarch.h"
#include <sys/types.h>
#include <sys/ptrace.h>
@@ -199,3 +201,150 @@ nbsd_nat_target::pid_to_str (ptid_t ptid)
return normal_pid_to_str (ptid);
}
+
+/* Retrieve all the memory regions in the specified process. */
+
+static gdb::unique_xmalloc_ptr<struct kinfo_vmentry[]>
+nbsd_kinfo_get_vmmap (pid_t pid, size_t *size)
+{
+ int mib[5] = {CTL_VM, VM_PROC, VM_PROC_MAP, pid,
+ sizeof (struct kinfo_vmentry)};
+
+ size_t length = 0;
+ if (sysctl (mib, ARRAY_SIZE (mib), NULL, &length, NULL, 0))
+ {
+ *size = 0;
+ return NULL;
+ }
+
+ /* Prereserve more space. The length argument is volatile and can change
+ between the sysctl(3) calls as this function can be called against a
+ running process. */
+ length = length * 5 / 3;
+
+ gdb::unique_xmalloc_ptr<struct kinfo_vmentry[]> kiv
+ (XNEWVAR (kinfo_vmentry, length));
+
+ if (sysctl (mib, ARRAY_SIZE (mib), kiv.get (), &length, NULL, 0))
+ {
+ *size = 0;
+ return NULL;
+ }
+
+ *size = 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 = inferior_ptid.pid ();
+
+ size_t nitems;
+ gdb::unique_xmalloc_ptr<struct kinfo_vmentry[]> vmentl
+ = nbsd_kinfo_get_vmmap (pid, &nitems);
+ if (vmentl == NULL)
+ perror_with_name (_("Couldn't fetch VM map entries."));
+
+ for (size_t i = 0; i < nitems; i++)
+ {
+ struct kinfo_vmentry *kve = &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 = 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 = false;
+
+ switch (what)
+ {
+ case IP_MAPPINGS:
+ do_mappings = true;
+ break;
+ default:
+ error (_("Not supported on this target."));
+ }
+
+ gdb_argv built_argv (args);
+ if (built_argv.count () == 0)
+ {
+ pid = inferior_ptid.pid ();
+ if (pid == 0)
+ error (_("No current process: you must name one."));
+ }
+ else if (built_argv.count () == 1 && isdigit (built_argv[0][0]))
+ pid = 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<struct kinfo_vmentry[]> vmentl
+ = nbsd_kinfo_get_vmmap (pid, &nvment);
+
+ if (vmentl != nullptr)
+ {
+ int addr_bit = TARGET_CHAR_BIT * sizeof (void *);
+ nbsd_info_proc_mappings_header (addr_bit);
+
+ struct kinfo_vmentry *kve = vmentl.get ();
+ for (int i = 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 3606048cd07..256db4b9017 100644
--- a/gdb/nbsd-nat.h
+++ b/gdb/nbsd-nat.h
@@ -35,6 +35,9 @@ struct nbsd_nat_target : public inf_ptrace_target
void post_attach (int pid) override;
void update_thread_list () override;
std::string pid_to_str (ptid_t ptid) override;
+
+ int find_memory_regions (find_memory_region_ftype func, void *data) override;
+ 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 158a43bebaa..52e0640e35c 100644
--- a/gdb/nbsd-tdep.c
+++ b/gdb/nbsd-tdep.c
@@ -26,6 +26,23 @@
#include "gdbarch.h"
#include "objfiles.h"
+/* Flags in the 'kve_protection' field in struct kinfo_vmentry. These
+ match the KVME_PROT_* constants in <sys/sysctl.h>. */
+
+#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 <sys/sysctl.h>. */
+
+#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. */
@@ -357,6 +374,78 @@ nbsd_skip_solib_resolver (struct gdbarch *gdbarch, CORE_ADDR pc)
/* See nbsd-tdep.h. */
+void
+nbsd_info_proc_mappings_header (int addr_bit)
+{
+ printf_filtered (_("Mapped address spaces:\n\n"));
+ if (addr_bit == 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] = (kve_protection & KINFO_VME_PROT_READ) ? 'r' : '-';
+ vm_flags[1] = (kve_protection & KINFO_VME_PROT_WRITE) ? 'w' : '-';
+ vm_flags[2] = (kve_protection & KINFO_VME_PROT_EXEC) ? 'x' : '-';
+ vm_flags[3] = ' ';
+ vm_flags[4] = (kve_flags & KINFO_VME_FLAG_COW) ? 'C' : '-';
+ vm_flags[5] = (kve_flags & KINFO_VME_FLAG_NEEDS_COPY) ? 'N' : '-';
+ vm_flags[6] = (kve_flags & KINFO_VME_FLAG_PAGEABLE) ? 'P' : '-';
+ vm_flags[7] = (kve_flags & KINFO_VME_FLAG_GROWS_UP) ? 'U'
+ : (kve_flags & KINFO_VME_FLAG_GROWS_DOWN) ? 'D' : '-';
+ vm_flags[8] = '\0';
+
+ return vm_flags;
+}
+
+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 == 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);
+ }
+}
+
+/* See nbsd-tdep.h. */
+
void
nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
diff --git a/gdb/nbsd-tdep.h b/gdb/nbsd-tdep.h
index 4b06c13f87b..a6e3a8f0f3f 100644
--- a/gdb/nbsd-tdep.h
+++ b/gdb/nbsd-tdep.h
@@ -29,4 +29,22 @@ int nbsd_pc_in_sigtramp (CORE_ADDR, const char *);
void nbsd_init_abi (struct gdbarch_info, struct gdbarch *);
+/* 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_start,
+ ULONGEST kve_end,
+ ULONGEST kve_offset,
+ int kve_flags, int kve_protection,
+ const char *kve_path);
+
#endif /* NBSD_TDEP_H */
--
2.25.0
next prev parent reply other threads:[~2020-04-12 0:10 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-16 17:34 [PATCH] " Kamil Rytarowski
2020-03-19 13:07 ` Kamil Rytarowski
2020-03-20 15:36 ` Tom Tromey
2020-03-20 16:58 ` Kamil Rytarowski
2020-03-20 18:50 ` Tom Tromey
2020-03-20 19:13 ` Kamil Rytarowski
2020-03-25 16:36 ` John Baldwin
2020-03-26 23:24 ` Kamil Rytarowski
2020-03-20 16:58 ` [PATCH v2] " Kamil Rytarowski
2020-04-02 20:09 ` Kamil Rytarowski
2020-04-03 1:12 ` Kamil Rytarowski
2020-04-06 9:37 ` [PATCH v3] " Kamil Rytarowski
2020-04-10 10:20 ` Kamil Rytarowski
2020-04-11 21:05 ` Simon Marchi
2020-04-11 21:28 ` Kamil Rytarowski
2020-04-11 21:53 ` Simon Marchi
2020-04-11 23:45 ` [PATCH v4] " Kamil Rytarowski
2020-04-11 23:49 ` Simon Marchi
2020-04-12 0:09 ` Kamil Rytarowski
2020-04-12 0:09 ` Kamil Rytarowski [this message]
2020-04-12 0:56 ` [PATCH v5] " Simon Marchi
2020-04-12 10:17 ` Kamil Rytarowski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200412000907.2137-1-n54@gmx.com \
--to=n54@gmx.com \
--cc=gdb-patches@sourceware.org \
--cc=simark@simark.ca \
--cc=tom@tromey.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox