X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Ffbsd-nat.c;h=0274ff542eaf419a605884a2a18f0e51ba8bdd59;hb=d0801dd8f22a3e739c6a7d126d45829df981794d;hp=08976da2263acfed599ca6571c542e8242fc7a7f;hpb=f6ac5f3d63e03a81c4ff3749aba234961cc9090e;p=deliverable%2Fbinutils-gdb.git
diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c
index 08976da226..0274ff542e 100644
--- a/gdb/fbsd-nat.c
+++ b/gdb/fbsd-nat.c
@@ -1,6 +1,6 @@
/* Native-dependent code for FreeBSD.
- Copyright (C) 2002-2018 Free Software Foundation, Inc.
+ Copyright (C) 2002-2019 Free Software Foundation, Inc.
This file is part of GDB.
@@ -18,14 +18,15 @@
along with this program. If not, see . */
#include "defs.h"
-#include "byte-vector.h"
+#include "gdbsupport/byte-vector.h"
#include "gdbcore.h"
#include "inferior.h"
#include "regcache.h"
#include "regset.h"
+#include "gdbarch.h"
#include "gdbcmd.h"
#include "gdbthread.h"
-#include "gdb_wait.h"
+#include "gdbsupport/gdb_wait.h"
#include "inf-ptrace.h"
#include
#include
@@ -37,7 +38,7 @@
#include
#endif
#if !defined(HAVE_KINFO_GETVMMAP)
-#include "filestuff.h"
+#include "gdbsupport/filestuff.h"
#endif
#include "elf-bfd.h"
@@ -92,7 +93,7 @@ int
fbsd_nat_target::find_memory_regions (find_memory_region_ftype func,
void *obfd)
{
- pid_t pid = ptid_get_pid (inferior_ptid);
+ pid_t pid = inferior_ptid.pid ();
struct kinfo_vmentry *kve;
uint64_t size;
int i, nitems;
@@ -166,7 +167,7 @@ int
fbsd_nat_target::find_memory_regions (find_memory_region_ftype func,
void *obfd)
{
- pid_t pid = ptid_get_pid (inferior_ptid);
+ pid_t pid = inferior_ptid.pid ();
unsigned long start, end, size;
char protection[4];
int read, write, exec;
@@ -231,6 +232,13 @@ fbsd_fetch_cmdline (pid_t pid)
if (sysctl (mib, 4, cmdline.get (), &len, NULL, 0) == -1)
return nullptr;
+ /* Join the arguments with spaces to form a single string. */
+ char *cp = cmdline.get ();
+ for (size_t i = 0; i < len - 1; i++)
+ if (cp[i] == '\0')
+ cp[i] = ' ';
+ cp[len - 1] = '\0';
+
return cmdline;
}
@@ -261,11 +269,13 @@ fbsd_nat_target::info_proc (const char *args, enum info_proc_what what)
int nfd = 0;
#endif
struct kinfo_proc kp;
- char *tmp;
pid_t pid;
bool do_cmdline = false;
bool do_cwd = false;
bool do_exe = false;
+#ifdef HAVE_KINFO_GETFILE
+ bool do_files = false;
+#endif
#ifdef HAVE_KINFO_GETVMMAP
bool do_mappings = false;
#endif
@@ -296,10 +306,18 @@ fbsd_nat_target::info_proc (const char *args, enum info_proc_what what)
case IP_CWD:
do_cwd = true;
break;
+#ifdef HAVE_KINFO_GETFILE
+ case IP_FILES:
+ do_files = true;
+ break;
+#endif
case IP_ALL:
do_cmdline = true;
do_cwd = true;
do_exe = true;
+#ifdef HAVE_KINFO_GETFILE
+ do_files = true;
+#endif
#ifdef HAVE_KINFO_GETVMMAP
do_mappings = true;
#endif
@@ -312,7 +330,7 @@ fbsd_nat_target::info_proc (const char *args, enum info_proc_what what)
gdb_argv built_argv (args);
if (built_argv.count () == 0)
{
- pid = ptid_get_pid (inferior_ptid);
+ pid = inferior_ptid.pid ();
if (pid == 0)
error (_("No current process: you must name one."));
}
@@ -323,7 +341,7 @@ fbsd_nat_target::info_proc (const char *args, enum info_proc_what what)
printf_filtered (_("process %d\n"), pid);
#ifdef HAVE_KINFO_GETFILE
- if (do_cwd || do_exe)
+ if (do_cwd || do_exe || do_files)
fdtbl.reset (kinfo_getfile (pid, &nfd));
#endif
@@ -375,6 +393,25 @@ fbsd_nat_target::info_proc (const char *args, enum info_proc_what what)
else
warning (_("unable to fetch executable path name"));
}
+#ifdef HAVE_KINFO_GETFILE
+ if (do_files)
+ {
+ struct kinfo_file *kf = fdtbl.get ();
+
+ if (nfd > 0)
+ {
+ fbsd_info_proc_files_header ();
+ for (int i = 0; i < nfd; i++, kf++)
+ fbsd_info_proc_files_entry (kf->kf_type, kf->kf_fd, kf->kf_flags,
+ kf->kf_offset, kf->kf_vnode_type,
+ kf->kf_sock_domain, kf->kf_sock_type,
+ kf->kf_sock_protocol, &kf->kf_sa_local,
+ &kf->kf_sa_peer, kf->kf_path);
+ }
+ else
+ warning (_("unable to fetch list of open files"));
+ }
+#endif
#ifdef HAVE_KINFO_GETVMMAP
if (do_mappings)
{
@@ -384,46 +421,15 @@ fbsd_nat_target::info_proc (const char *args, enum info_proc_what what)
if (vmentl != nullptr)
{
- printf_filtered (_("Mapped address spaces:\n\n"));
-#ifdef __LP64__
- 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");
-#endif
+ int addr_bit = TARGET_CHAR_BIT * sizeof (void *);
+ fbsd_info_proc_mappings_header (addr_bit);
struct kinfo_vmentry *kve = vmentl.get ();
for (int i = 0; i < nvment; i++, kve++)
- {
- ULONGEST start, end;
-
- start = kve->kve_start;
- end = kve->kve_end;
-#ifdef __LP64__
- printf_filtered (" %18s %18s %10s %10s %9s %s\n",
- hex_string (start),
- hex_string (end),
- hex_string (end - start),
- hex_string (kve->kve_offset),
- fbsd_vm_map_entry_flags (kve->kve_flags,
- kve->kve_protection),
- kve->kve_path);
-#else
- printf_filtered ("\t%10s %10s %10s %10s %9s %s\n",
- hex_string (start),
- hex_string (end),
- hex_string (end - start),
- hex_string (kve->kve_offset),
- fbsd_vm_map_entry_flags (kve->kve_flags,
- kve->kve_protection),
- kve->kve_path);
-#endif
- }
+ fbsd_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"));
@@ -534,9 +540,17 @@ fbsd_nat_target::info_proc (const char *args, enum info_proc_what what)
return true;
}
-#ifdef KERN_PROC_AUXV
+/*
+ * The current layout of siginfo_t on FreeBSD was adopted in SVN
+ * revision 153154 which shipped in FreeBSD versions 7.0 and later.
+ * Don't bother supporting the older layout on older kernels. The
+ * older format was also never used in core dump notes.
+ */
+#if __FreeBSD_version >= 700009
+#define USE_SIGINFO
+#endif
-#ifdef PT_LWPINFO
+#ifdef USE_SIGINFO
/* Return the size of siginfo for the current inferior. */
#ifdef __LP64__
@@ -674,11 +688,11 @@ fbsd_nat_target::xfer_partial (enum target_object object,
ULONGEST offset, ULONGEST len,
ULONGEST *xfered_len)
{
- pid_t pid = ptid_get_pid (inferior_ptid);
+ pid_t pid = inferior_ptid.pid ();
switch (object)
{
-#ifdef PT_LWPINFO
+#ifdef USE_SIGINFO
case TARGET_OBJECT_SIGNAL_INFO:
{
struct ptrace_lwpinfo pl;
@@ -710,6 +724,7 @@ fbsd_nat_target::xfer_partial (enum target_object object,
return TARGET_XFER_OK;
}
#endif
+#ifdef KERN_PROC_AUXV
case TARGET_OBJECT_AUXV:
{
gdb::byte_vector buf_storage;
@@ -751,17 +766,74 @@ fbsd_nat_target::xfer_partial (enum target_object object,
}
return TARGET_XFER_E_IO;
}
+#endif
+#if defined(KERN_PROC_VMMAP) && defined(KERN_PROC_PS_STRINGS)
+ case TARGET_OBJECT_FREEBSD_VMMAP:
+ case TARGET_OBJECT_FREEBSD_PS_STRINGS:
+ {
+ gdb::byte_vector buf_storage;
+ gdb_byte *buf;
+ size_t buflen;
+ int mib[4];
+
+ int proc_target;
+ uint32_t struct_size;
+ switch (object)
+ {
+ case TARGET_OBJECT_FREEBSD_VMMAP:
+ proc_target = KERN_PROC_VMMAP;
+ struct_size = sizeof (struct kinfo_vmentry);
+ break;
+ case TARGET_OBJECT_FREEBSD_PS_STRINGS:
+ proc_target = KERN_PROC_PS_STRINGS;
+ struct_size = sizeof (void *);
+ break;
+ }
+
+ if (writebuf != NULL)
+ return TARGET_XFER_E_IO;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = proc_target;
+ mib[3] = pid;
+
+ if (sysctl (mib, 4, NULL, &buflen, NULL, 0) != 0)
+ return TARGET_XFER_E_IO;
+ buflen += sizeof (struct_size);
+
+ if (offset >= buflen)
+ {
+ *xfered_len = 0;
+ return TARGET_XFER_EOF;
+ }
+
+ buf_storage.resize (buflen);
+ buf = buf_storage.data ();
+
+ memcpy (buf, &struct_size, sizeof (struct_size));
+ buflen -= sizeof (struct_size);
+ if (sysctl (mib, 4, buf + sizeof (struct_size), &buflen, NULL, 0) != 0)
+ return TARGET_XFER_E_IO;
+ buflen += sizeof (struct_size);
+
+ if (buflen - offset < len)
+ len = buflen - offset;
+ memcpy (readbuf, buf + offset, len);
+ *xfered_len = len;
+ return TARGET_XFER_OK;
+ }
+#endif
default:
return inf_ptrace_target::xfer_partial (object, annex,
readbuf, writebuf, offset,
len, xfered_len);
}
}
-#endif
#ifdef PT_LWPINFO
-static int debug_fbsd_lwp;
-static int debug_fbsd_nat;
+static bool debug_fbsd_lwp;
+static bool debug_fbsd_nat;
static void
show_fbsd_lwp_debug (struct ui_file *file, int from_tty,
@@ -807,41 +879,38 @@ show_fbsd_nat_debug (struct ui_file *file, int from_tty,
/* Return true if PTID is still active in the inferior. */
-int
+bool
fbsd_nat_target::thread_alive (ptid_t ptid)
{
- if (ptid_lwp_p (ptid))
+ if (ptid.lwp_p ())
{
struct ptrace_lwpinfo pl;
- if (ptrace (PT_LWPINFO, ptid_get_lwp (ptid), (caddr_t) &pl, sizeof pl)
+ if (ptrace (PT_LWPINFO, ptid.lwp (), (caddr_t) &pl, sizeof pl)
== -1)
- return 0;
+ return false;
#ifdef PL_FLAG_EXITED
if (pl.pl_flags & PL_FLAG_EXITED)
- return 0;
+ return false;
#endif
}
- return 1;
+ return true;
}
-/* Convert PTID to a string. Returns the string in a static
- buffer. */
+/* Convert PTID to a string. */
-const char *
+std::string
fbsd_nat_target::pid_to_str (ptid_t ptid)
{
lwpid_t lwp;
- lwp = ptid_get_lwp (ptid);
+ lwp = ptid.lwp ();
if (lwp != 0)
{
- static char buf[64];
- int pid = ptid_get_pid (ptid);
+ int pid = ptid.pid ();
- xsnprintf (buf, sizeof buf, "LWP %d of process %d", lwp, pid);
- return buf;
+ return string_printf ("LWP %d of process %d", lwp, pid);
}
return normal_pid_to_str (ptid);
@@ -856,8 +925,8 @@ fbsd_nat_target::thread_name (struct thread_info *thr)
{
struct ptrace_lwpinfo pl;
struct kinfo_proc kp;
- int pid = ptid_get_pid (thr->ptid);
- long lwp = ptid_get_lwp (thr->ptid);
+ int pid = thr->ptid.pid ();
+ long lwp = thr->ptid.lwp ();
static char buf[sizeof pl.pl_tdname + 1];
/* Note that ptrace_lwpinfo returns the process command in pl_tdname
@@ -926,7 +995,7 @@ fbsd_add_threads (pid_t pid)
{
int i, nlwps;
- gdb_assert (!in_thread_list (pid_to_ptid (pid)));
+ gdb_assert (!in_thread_list (ptid_t (pid)));
nlwps = ptrace (PT_GETNUMLWPS, pid, NULL, 0);
if (nlwps == -1)
perror_with_name (("ptrace"));
@@ -939,7 +1008,7 @@ fbsd_add_threads (pid_t pid)
for (i = 0; i < nlwps; i++)
{
- ptid_t ptid = ptid_build (pid, lwps[i], 0);
+ ptid_t ptid = ptid_t (pid, lwps[i], 0);
if (!in_thread_list (ptid))
{
@@ -974,7 +1043,7 @@ fbsd_nat_target::update_thread_list ()
#else
prune_threads ();
- fbsd_add_threads (ptid_get_pid (inferior_ptid));
+ fbsd_add_threads (inferior_ptid.pid ());
#endif
}
@@ -1089,10 +1158,10 @@ fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
pid_t pid;
/* Don't PT_CONTINUE a process which has a pending vfork done event. */
- if (ptid_equal (minus_one_ptid, ptid))
- pid = ptid_get_pid (inferior_ptid);
+ if (minus_one_ptid == ptid)
+ pid = inferior_ptid.pid ();
else
- pid = ptid_get_pid (ptid);
+ pid = ptid.pid ();
if (fbsd_is_vfork_done_pending (pid))
return;
#endif
@@ -1100,25 +1169,23 @@ fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
if (debug_fbsd_lwp)
fprintf_unfiltered (gdb_stdlog,
"FLWP: fbsd_resume for ptid (%d, %ld, %ld)\n",
- ptid_get_pid (ptid), ptid_get_lwp (ptid),
- ptid_get_tid (ptid));
- if (ptid_lwp_p (ptid))
+ ptid.pid (), ptid.lwp (),
+ ptid.tid ());
+ if (ptid.lwp_p ())
{
/* If ptid is a specific LWP, suspend all other LWPs in the process. */
- struct thread_info *tp;
- int request;
+ inferior *inf = find_inferior_ptid (ptid);
- ALL_NON_EXITED_THREADS (tp)
+ for (thread_info *tp : inf->non_exited_threads ())
{
- if (ptid_get_pid (tp->ptid) != ptid_get_pid (ptid))
- continue;
+ int request;
- if (ptid_get_lwp (tp->ptid) == ptid_get_lwp (ptid))
+ if (tp->ptid.lwp () == ptid.lwp ())
request = PT_RESUME;
else
request = PT_SUSPEND;
- if (ptrace (request, ptid_get_lwp (tp->ptid), NULL, 0) == -1)
+ if (ptrace (request, tp->ptid.lwp (), NULL, 0) == -1)
perror_with_name (("ptrace"));
}
}
@@ -1126,16 +1193,9 @@ fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
{
/* If ptid is a wildcard, resume all matching threads (they won't run
until the process is continued however). */
- struct thread_info *tp;
-
- ALL_NON_EXITED_THREADS (tp)
- {
- if (!ptid_match (tp->ptid, ptid))
- continue;
-
- if (ptrace (PT_RESUME, ptid_get_lwp (tp->ptid), NULL, 0) == -1)
- perror_with_name (("ptrace"));
- }
+ for (thread_info *tp : all_non_exited_threads (ptid))
+ if (ptrace (PT_RESUME, tp->ptid.lwp (), NULL, 0) == -1)
+ perror_with_name (("ptrace"));
ptid = inferior_ptid;
}
@@ -1183,8 +1243,14 @@ fbsd_handle_debug_trap (ptid_t ptid, const struct ptrace_lwpinfo &pl)
{
/* Ignore traps without valid siginfo or for signals other than
- SIGTRAP. */
- if (! (pl.pl_flags & PL_FLAG_SI) || pl.pl_siginfo.si_signo != SIGTRAP)
+ SIGTRAP.
+
+ FreeBSD kernels prior to r341800 can return stale siginfo for at
+ least some events, but those events can be identified by
+ additional flags set in pl_flags. True breakpoint and
+ single-step traps should not have other flags set in
+ pl_flags. */
+ if (pl.pl_flags != PL_FLAG_SI || pl.pl_siginfo.si_signo != SIGTRAP)
return false;
/* Trace traps are either a single step or a hardware watchpoint or
@@ -1236,7 +1302,7 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
{
#ifndef PTRACE_VFORK
wptid = fbsd_next_vfork_done ();
- if (!ptid_equal (wptid, null_ptid))
+ if (wptid != null_ptid)
{
ourstatus->kind = TARGET_WAITKIND_VFORK_DONE;
return wptid;
@@ -1249,11 +1315,11 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
pid_t pid;
int status;
- pid = ptid_get_pid (wptid);
+ pid = wptid.pid ();
if (ptrace (PT_LWPINFO, pid, (caddr_t) &pl, sizeof pl) == -1)
perror_with_name (("ptrace"));
- wptid = ptid_build (pid, pl.pl_lwpid, 0);
+ wptid = ptid_t (pid, pl.pl_lwpid, 0);
if (debug_fbsd_nat)
{
@@ -1274,16 +1340,17 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
threads might be skipped during post_attach that
have not yet reported their PL_FLAG_EXITED event.
Ignore EXITED events for an unknown LWP. */
- if (in_thread_list (wptid))
+ thread_info *thr = find_thread_ptid (wptid);
+ if (thr != nullptr)
{
if (debug_fbsd_lwp)
fprintf_unfiltered (gdb_stdlog,
"FLWP: deleting thread for LWP %u\n",
pl.pl_lwpid);
if (print_thread_events)
- printf_unfiltered (_("[%s exited]\n"), target_pid_to_str
- (wptid));
- delete_thread (wptid);
+ printf_unfiltered (_("[%s exited]\n"),
+ target_pid_to_str (wptid).c_str ());
+ delete_thread (thr);
}
if (ptrace (PT_CONTINUE, pid, (caddr_t) 1, 0) == -1)
perror_with_name (("ptrace"));
@@ -1297,13 +1364,13 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
PL_FLAG_BORN in case the first stop reported after
attaching to an existing process is a PL_FLAG_BORN
event. */
- if (in_thread_list (pid_to_ptid (pid)))
+ if (in_thread_list (ptid_t (pid)))
{
if (debug_fbsd_lwp)
fprintf_unfiltered (gdb_stdlog,
"FLWP: using LWP %u for first thread\n",
pl.pl_lwpid);
- thread_change_ptid (pid_to_ptid (pid), wptid);
+ thread_change_ptid (ptid_t (pid), wptid);
}
#ifdef PT_LWP_EVENTS
@@ -1344,7 +1411,7 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
/* Make sure the other end of the fork is stopped too. */
child_ptid = fbsd_is_child_pending (child);
- if (ptid_equal (child_ptid, null_ptid))
+ if (child_ptid == null_ptid)
{
pid = waitpid (child, &status, 0);
if (pid == -1)
@@ -1356,11 +1423,11 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
perror_with_name (("ptrace"));
gdb_assert (pl.pl_flags & PL_FLAG_CHILD);
- child_ptid = ptid_build (child, pl.pl_lwpid, 0);
+ child_ptid = ptid_t (child, pl.pl_lwpid, 0);
}
/* Enable additional events on the child process. */
- fbsd_enable_proc_events (ptid_get_pid (child_ptid));
+ fbsd_enable_proc_events (child_ptid.pid ());
#ifndef PTRACE_VFORK
/* For vfork, the child process will have the P_PPWAIT
@@ -1452,16 +1519,16 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
#ifdef USE_SIGTRAP_SIGINFO
/* Implement the "stopped_by_sw_breakpoint" target_ops method. */
-int
+bool
fbsd_nat_target::stopped_by_sw_breakpoint ()
{
struct ptrace_lwpinfo pl;
if (ptrace (PT_LWPINFO, get_ptrace_pid (inferior_ptid), (caddr_t) &pl,
sizeof pl) == -1)
- return 0;
+ return false;
- return ((pl.pl_flags & PL_FLAG_SI)
+ return (pl.pl_flags == PL_FLAG_SI
&& pl.pl_siginfo.si_signo == SIGTRAP
&& pl.pl_siginfo.si_code == TRAP_BRKPT);
}
@@ -1469,10 +1536,10 @@ fbsd_nat_target::stopped_by_sw_breakpoint ()
/* Implement the "supports_stopped_by_sw_breakpoint" target_ops
method. */
-int
+bool
fbsd_nat_target::supports_stopped_by_sw_breakpoint ()
{
- return 1;
+ return true;
}
#endif
@@ -1486,7 +1553,7 @@ fbsd_nat_target::follow_fork (int follow_child, int detach_fork)
if (!follow_child && detach_fork)
{
struct thread_info *tp = inferior_thread ();
- pid_t child_pid = ptid_get_pid (tp->pending_follow.value.related_pid);
+ pid_t child_pid = tp->pending_follow.value.related_pid.pid ();
/* Breakpoints have already been detached from the child by
infrun.c. */
@@ -1557,7 +1624,7 @@ fbsd_nat_target::remove_vfork_catchpoint (int pid)
void
fbsd_nat_target::post_startup_inferior (ptid_t pid)
{
- fbsd_enable_proc_events (ptid_get_pid (pid));
+ fbsd_enable_proc_events (pid.pid ());
}
/* Implement the "post_attach" target_ops method. */