mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-19 09:14:14 +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:
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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user