mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-04-24 14:53:34 +08:00
Implement "info proc mappings" for NetBSD
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.
This commit is contained in:
parent
0b07a19901
commit
54b8cbd0e4
@ -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
|
||||
|
149
gdb/nbsd-nat.c
149
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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user