1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-10-19 19:59:43 +00:00

Upgrade to 8.2.

- Remove patches for upstream commits in 8.2.
- Add an upstream patch to include NT_PROCSTAT_AUXV, NT_PROCSTAT_PS_STRINGS,
  and NT_PROCSTAT_VMMAP notes in core dumps generated by 'gcore'.
- Update kgdb for changes in 8.2.
- Add 'USES=gettext-runtime'

Reviewed by:	pizzamig (maintainer)
Differential Revision:	https://reviews.freebsd.org/D17085
This commit is contained in:
John Baldwin 2018-09-24 17:23:35 +00:00
parent 98cebee2f0
commit 05bc472d2d
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=480613
25 changed files with 395 additions and 2265 deletions

View File

@ -2,7 +2,7 @@
# $FreeBSD$
PORTNAME= gdb
PORTVERSION= 8.1.1
PORTVERSION= 8.2
CATEGORIES= devel
MASTER_SITES= GNU
@ -23,7 +23,7 @@ TEST_TARGET= check
# C++14. However, clang in 10.3 crashes while building this port.
# Requiring C++14 forces 10.3 to use an external version of clang while
# still using the base system clang on 11.0 and later.
USES= compiler:c++14-lang cpe gmake libtool tar:xz
USES= compiler:c++14-lang cpe gettext-runtime gmake libtool tar:xz
USE_CSTD= gnu89
CPE_VENDOR= gnu
GNU_CONFIGURE= yes
@ -40,16 +40,7 @@ CFLAGS+= -DRL_NO_COMPAT -Wno-unused-function -Wno-unused-variable
CFLAGS+= -Wno-unknown-warning-option
EXCLUDE= dejagnu expect sim texinfo intl
EXTRACT_AFTER_ARGS= ${EXCLUDE:S/^/--exclude /}
EXTRA_PATCHES= ${FILESDIR}/commit-d2176225dc \
${FILESDIR}/commit-b999e2038d \
${FILESDIR}/commit-262f62f57d \
${FILESDIR}/commit-92fce24de2 \
${FILESDIR}/commit-2d97a5d9d3 \
${FILESDIR}/commit-906b4aac4c \
${FILESDIR}/commit-f169cfdc08 \
${FILESDIR}/commit-12279366d7 \
${FILESDIR}/commit-386a867618 \
${FILESDIR}/commit-7efba073e2
EXTRA_PATCHES= ${FILESDIR}/commit-8aa0243d54
LIB_DEPENDS+= libexpat.so:textproc/expat2
VER= ${PORTVERSION:S/.//g}

View File

@ -1,3 +1,3 @@
TIMESTAMP = 1533926440
SHA256 (gdb-8.1.1.tar.xz) = 97dcc3169bd430270fc29adb65145846a58c1b55cdbb73382a4a89307bdad03c
SIZE (gdb-8.1.1.tar.xz) = 20064728
TIMESTAMP = 1536418789
SHA256 (gdb-8.2.tar.xz) = c3a441a29c7c89720b734e5a9c6289c0a06be7e0c76ef538f7bbcef389347c39
SIZE (gdb-8.2.tar.xz) = 20173112

View File

@ -1,121 +0,0 @@
commit 12279366d71627bfbdd74d1a6675dca825d8feca
Author: John Baldwin <jhb@FreeBSD.org>
Date: Sat Mar 3 21:25:33 2018 -0800
Implement "to_stopped_by_hw_breakpoint" for x86 debug registers.
Report that a thread is stopped by a hardware breakpoint if a non-data
watchpoint is set in DR6. This change should be a no-op since a target
still needs to implement the "to_supports_stopped_by_hw_breakpoint"
method before this function is used.
gdb/ChangeLog:
* nat/x86-dregs.c (x86_dr_stopped_by_hw_breakpoint): New function.
* nat/x86-dregs.h (x86_dr_stopped_by_hw_breakpoint): New
prototype.
* x86-nat.c (x86_stopped_by_hw_breakpoint): New function.
(x86_use_watchpoints): Set "stopped_by_hw_breakpoint" target
method.
diff --git gdb/nat/x86-dregs.c gdb/nat/x86-dregs.c
index c816473628..f11a708e27 100644
--- gdb/nat/x86-dregs.c
+++ gdb/nat/x86-dregs.c
@@ -649,3 +649,48 @@ x86_dr_stopped_by_watchpoint (struct x86_debug_reg_state *state)
CORE_ADDR addr = 0;
return x86_dr_stopped_data_address (state, &addr);
}
+
+/* Return non-zero if the inferior has some hardware breakpoint that
+ triggered. Otherwise return zero. */
+
+int
+x86_dr_stopped_by_hw_breakpoint (struct x86_debug_reg_state *state)
+{
+ CORE_ADDR addr = 0;
+ int i;
+ int rc = 0;
+ /* The current thread's DR_STATUS. We always need to read this to
+ check whether some watchpoint caused the trap. */
+ unsigned status;
+ /* We need DR_CONTROL as well, but only iff DR_STATUS indicates a
+ breakpoint trap. Only fetch it when necessary, to avoid an
+ unnecessary extra syscall when no watchpoint triggered. */
+ int control_p = 0;
+ unsigned control = 0;
+
+ /* As above, always read the current thread's debug registers rather
+ than trusting dr_mirror. */
+ status = x86_dr_low_get_status ();
+
+ ALL_DEBUG_ADDRESS_REGISTERS (i)
+ {
+ if (!X86_DR_WATCH_HIT (status, i))
+ continue;
+
+ if (!control_p)
+ {
+ control = x86_dr_low_get_control ();
+ control_p = 1;
+ }
+
+ if (X86_DR_GET_RW_LEN (control, i) == 0)
+ {
+ addr = x86_dr_low_get_addr (i);
+ rc = 1;
+ if (show_debug_regs)
+ x86_show_dr (state, "watchpoint_hit", addr, -1, hw_execute);
+ }
+ }
+
+ return rc;
+}
diff --git gdb/nat/x86-dregs.h gdb/nat/x86-dregs.h
index dd6242eda9..e86e83aea0 100644
--- gdb/nat/x86-dregs.h
+++ gdb/nat/x86-dregs.h
@@ -128,4 +128,8 @@ extern int x86_dr_stopped_data_address (struct x86_debug_reg_state *state,
Otherwise return false. */
extern int x86_dr_stopped_by_watchpoint (struct x86_debug_reg_state *state);
+/* Return true if the inferior has some hardware breakpoint that
+ triggered. Otherwise return false. */
+extern int x86_dr_stopped_by_hw_breakpoint (struct x86_debug_reg_state *state);
+
#endif /* X86_DREGS_H */
diff --git gdb/x86-nat.c gdb/x86-nat.c
index b126c47c94..bec51373a6 100644
--- gdb/x86-nat.c
+++ gdb/x86-nat.c
@@ -260,6 +260,18 @@ x86_can_use_hw_breakpoint (struct target_ops *self,
return 1;
}
+/* Return non-zero if the inferior has some breakpoint that triggered.
+ Otherwise return zero. */
+
+static int
+x86_stopped_by_hw_breakpoint (struct target_ops *ops)
+{
+ struct x86_debug_reg_state *state
+ = x86_debug_reg_state (ptid_get_pid (inferior_ptid));
+
+ return x86_dr_stopped_by_hw_breakpoint (state);
+}
+
static void
add_show_debug_regs_command (void)
{
@@ -297,6 +309,11 @@ x86_use_watchpoints (struct target_ops *t)
t->to_remove_watchpoint = x86_remove_watchpoint;
t->to_insert_hw_breakpoint = x86_insert_hw_breakpoint;
t->to_remove_hw_breakpoint = x86_remove_hw_breakpoint;
+
+ /* A target must provide an implementation of the
+ "to_supports_stopped_by_hw_breakpoint" target method before this
+ callback will be used. */
+ t->to_stopped_by_hw_breakpoint = x86_stopped_by_hw_breakpoint;
}
void

View File

@ -1,43 +0,0 @@
commit 262f62f57d987269152412a55c458a03adc6ddd6
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue Jan 9 13:35:17 2018 -0800
Use gdb::unique_xmalloc_ptr<> instead of a deleter that invokes free().
Since xfree() always wraps free(), it is safe to use the xfree deleter
for buffers allocated by library routines such as kinfo_getvmmap() that
must be released via free().
gdb/ChangeLog:
* fbsd-nat.c (struct free_deleter): Remove.
(fbsd_find_memory_regions): Use gdb::unique_xmalloc_ptr<>.
diff --git gdb/fbsd-nat.c gdb/fbsd-nat.c
index d0aaf89145..81f8e27a2d 100644
--- gdb/fbsd-nat.c
+++ gdb/fbsd-nat.c
@@ -81,14 +81,6 @@ fbsd_pid_to_exec_file (struct target_ops *self, int pid)
}
#ifdef HAVE_KINFO_GETVMMAP
-/* Deleter for std::unique_ptr that invokes free. */
-
-template <typename T>
-struct free_deleter
-{
- void operator() (T *ptr) const { free (ptr); }
-};
-
/* 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. */
@@ -102,7 +94,7 @@ fbsd_find_memory_regions (struct target_ops *self,
uint64_t size;
int i, nitems;
- std::unique_ptr<struct kinfo_vmentry, free_deleter<struct kinfo_vmentry>>
+ gdb::unique_xmalloc_ptr<struct kinfo_vmentry>
vmentl (kinfo_getvmmap (pid, &nitems));
if (vmentl == NULL)
perror_with_name (_("Couldn't fetch VM map entries."));

View File

@ -1,169 +0,0 @@
commit 2d97a5d9d33aea87c3bd02fd1fa417f5d4e1fa05
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue Jan 9 13:35:17 2018 -0800
Document support for 'info proc' on FreeBSD.
Since the 'info proc' support on FreeBSD does not use /proc, reword
the documentation for 'info proc' to not assume /proc. This includes
renaming the node to 'Process Information' and suggesting that
additional process information can be queried via different
OS-specific interfaces. This is also cleans up the description of
'info proc' support for core files a bit as /proc is not used for core
file support on any current platform.
gdb/ChangeLog:
* NEWS: Document that 'info proc' now works on FreeBSD.
gdb/doc/ChangeLog:
* gdb.texinfo (pwd): Update cross-reference for Process Information
node and remove explicit /proc reference.
(Native): Rename subsection from SVR4 Process Information to
Process Information.
(Process Information): Reword introduction to be less /proc
centric. Document support for "info proc" on FreeBSD.
diff --git gdb/NEWS gdb/NEWS
index 2f834c6ff4..f69173a245 100644
--- gdb/NEWS
+++ gdb/NEWS
@@ -3,6 +3,9 @@
*** Changes since GDB 8.1
+* 'info proc' now works on running processes on FreeBSD systems and core
+ files created on FreeBSD systems.
+
*** Changes in GDB 8.1
* GDB now supports dynamically creating arbitrary register groups specified
diff --git gdb/doc/gdb.texinfo gdb/doc/gdb.texinfo
index 8bdafb0ba4..096c82cc82 100644
--- gdb/doc/gdb.texinfo
+++ gdb/doc/gdb.texinfo
@@ -2523,9 +2523,9 @@ Print the @value{GDBN} working directory.
It is generally impossible to find the current working directory of
the process being debugged (since a program can change its directory
-during its run). If you work on a system where @value{GDBN} is
-configured with the @file{/proc} support, you can use the @code{info
-proc} command (@pxref{SVR4 Process Information}) to find out the
+during its run). If you work on a system where @value{GDBN} supports
+the @code {info proc} command (@pxref{Process Information}), you can
+use the @code{info proc} command to find out the
current working directory of the debuggee.
@node Input/Output
@@ -21712,7 +21712,7 @@ configurations.
@menu
* BSD libkvm Interface:: Debugging BSD kernel memory images
-* SVR4 Process Information:: SVR4 process information
+* Process Information:: Process information
* DJGPP Native:: Features specific to the DJGPP port
* Cygwin Native:: Features specific to the Cygwin port
* Hurd Native:: Features specific to @sc{gnu} Hurd
@@ -21759,24 +21759,32 @@ Set current context from proc address. This command isn't available on
modern FreeBSD systems.
@end table
-@node SVR4 Process Information
-@subsection SVR4 Process Information
+@node Process Information
+@subsection Process Information
@cindex /proc
@cindex examine process image
@cindex process info via @file{/proc}
-Many versions of SVR4 and compatible systems provide a facility called
-@samp{/proc} that can be used to examine the image of a running
-process using file-system subroutines.
+Some operating systems provide interfaces to fetch additional
+information about running processes beyond memory and per-thread
+register state. If @value{GDBN} is configured for an operating system
+with a supported interface, the command @code{info proc} is available
+to report information about the process running your program, or about
+any process running on your system.
-If @value{GDBN} is configured for an operating system with this
-facility, the command @code{info proc} is available to report
-information about the process running your program, or about any
-process running on your system. This includes, as of this writing,
-@sc{gnu}/Linux and Solaris, for example.
+One supported interface is a facility called @samp{/proc} that can be
+used to examine the image of a running process using file-system
+subroutines. This facility is supported on @sc{gnu}/Linux and Solaris
+systems.
-This command may also work on core files that were created on a system
-that has the @samp{/proc} facility.
+On FreeBSD systems, system control nodes are used to query process
+information.
+
+In addition, some systems may provide additional process information
+in core files. Note that a core file may include a subset of the
+information available from a live process. Process information is
+currently avaiable from cores created on @sc{gnu}/Linux and FreeBSD
+systems.
@table @code
@kindex info proc
@@ -21800,36 +21808,40 @@ a process ID rather than a thread ID).
@item info proc cmdline
@cindex info proc cmdline
Show the original command line of the process. This command is
-specific to @sc{gnu}/Linux.
+supported on @sc{gnu}/Linux and FreeBSD.
@item info proc cwd
@cindex info proc cwd
Show the current working directory of the process. This command is
-specific to @sc{gnu}/Linux.
+supported on @sc{gnu}/Linux and FreeBSD.
@item info proc exe
@cindex info proc exe
-Show the name of executable of the process. This command is specific
-to @sc{gnu}/Linux.
+Show the name of executable of the process. This command is supported
+on @sc{gnu}/Linux and FreeBSD.
@item info proc mappings
@cindex memory address space mappings
-Report the memory address space ranges accessible in the program, with
-information on whether the process has read, write, or execute access
-rights to each range. On @sc{gnu}/Linux systems, each memory range
-includes the object file which is mapped to that range, instead of the
-memory access rights to that range.
+Report the memory address space ranges accessible in the program. On
+Solaris and FreeBSD systems, each memory range includes information on
+whether the process has read, write, or execute access rights to each
+range. On @sc{gnu}/Linux and FreeBSD systems, each memory range
+includes the object file which is mapped to that range.
@item info proc stat
@itemx info proc status
@cindex process detailed status information
-These subcommands are specific to @sc{gnu}/Linux systems. They show
-the process-related information, including the user ID and group ID;
-how many threads are there in the process; its virtual memory usage;
-the signals that are pending, blocked, and ignored; its TTY; its
-consumption of system and user time; its stack size; its @samp{nice}
-value; etc. For more information, see the @samp{proc} man page
-(type @kbd{man 5 proc} from your shell prompt).
+Show additional process-related information, including the user ID and
+group ID; virtual memory usage; the signals that are pending, blocked,
+and ignored; its TTY; its consumption of system and user time; its
+stack size; its @samp{nice} value; etc. These commands are supported
+on @sc{gnu}/Linux and FreeBSD.
+
+For @sc{gnu}/Linux systems, see the @samp{proc} man page for more
+information (type @kbd{man 5 proc} from your shell prompt).
+
+For FreeBSD systems, @code{info proc stat} is an alias for @code{info
+proc status}.
@item info proc all
Show all the information about the process described under all of the

View File

@ -1,115 +0,0 @@
commit 386a86761838df16c1459275d465ed21a1c35d9f
Author: John Baldwin <jhb@FreeBSD.org>
Date: Sat Mar 3 21:25:33 2018 -0800
Add a new debug knob for the FreeBSD native target.
For now this just logs information about the state of the current LWP
for each STOPPED event in fbsd_wait().
gdb/ChangeLog:
* NEWS (Changes since GDB 8.1): Add "set/show debug fbsd-nat".
* fbsd-nat.c (debug_fbsd_nat): New variable.
(show_fbsd_nat_debug): New function.
(fbsd_wait): Log LWP info if "debug_fbsd_nat" is enabled.
(_initialize_fbsd_nat): Add "fbsd-nat" debug boolean command.
gdb/doc/ChangeLog:
* gdb.texinfo (Debugging Output): Document "set/show debug
fbsd-nat".
diff --git gdb/NEWS gdb/NEWS
index 1767cef920..867e268a2a 100644
--- gdb/NEWS
+++ gdb/NEWS
@@ -6,6 +6,12 @@
* 'info proc' now works on running processes on FreeBSD systems and core
files created on FreeBSD systems.
+* New commands
+
+set debug fbsd-nat
+show debug fbsd-nat
+ Control display of debugging info regarding the FreeBSD native target.
+
*** Changes in GDB 8.1
* GDB now supports dynamically creating arbitrary register groups specified
diff --git gdb/doc/gdb.texinfo gdb/doc/gdb.texinfo
index ee7adc8df2..74e0fdb4a4 100644
--- gdb/doc/gdb.texinfo
+++ gdb/doc/gdb.texinfo
@@ -24554,6 +24554,11 @@ Displays the current state of displaying debugging info about
Turns on or off debugging messages from the FreeBSD LWP debug support.
@item show debug fbsd-lwp
Show the current state of FreeBSD LWP debugging messages.
+@item set debug fbsd-nat
+@cindex FreeBSD native target debug messages
+Turns on or off debugging messages from the FreeBSD native target.
+@item show debug fbsd-nat
+Show the current state of FreeBSD native target debugging messages.
@item set debug frame
@cindex frame debugging info
Turns on or off display of @value{GDBN} frame debugging info. The
diff --git gdb/fbsd-nat.c gdb/fbsd-nat.c
index 3a216abf18..2516ac5552 100644
--- gdb/fbsd-nat.c
+++ gdb/fbsd-nat.c
@@ -765,6 +765,7 @@ fbsd_xfer_partial (struct target_ops *ops, enum target_object object,
#ifdef PT_LWPINFO
static int debug_fbsd_lwp;
+static int debug_fbsd_nat;
static void (*super_resume) (struct target_ops *,
ptid_t,
@@ -782,6 +783,14 @@ show_fbsd_lwp_debug (struct ui_file *file, int from_tty,
fprintf_filtered (file, _("Debugging of FreeBSD lwp module is %s.\n"), value);
}
+static void
+show_fbsd_nat_debug (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Debugging of FreeBSD native target is %s.\n"),
+ value);
+}
+
/*
FreeBSD's first thread support was via a "reentrant" version of libc
(libc_r) that first shipped in 2.2.7. This library multiplexed all
@@ -1212,6 +1221,18 @@ fbsd_wait (struct target_ops *ops,
wptid = ptid_build (pid, pl.pl_lwpid, 0);
+ if (debug_fbsd_nat)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "FNAT: stop for LWP %u event %d flags %#x\n",
+ pl.pl_lwpid, pl.pl_event, pl.pl_flags);
+ if (pl.pl_flags & PL_FLAG_SI)
+ fprintf_unfiltered (gdb_stdlog,
+ "FNAT: si_signo %u si_code %u\n",
+ pl.pl_siginfo.si_signo,
+ pl.pl_siginfo.si_code);
+ }
+
#ifdef PT_LWP_EVENTS
if (pl.pl_flags & PL_FLAG_EXITED)
{
@@ -1569,5 +1590,13 @@ Enables printf debugging output."),
NULL,
&show_fbsd_lwp_debug,
&setdebuglist, &showdebuglist);
+ add_setshow_boolean_cmd ("fbsd-nat", class_maintenance,
+ &debug_fbsd_nat, _("\
+Set debugging of FreeBSD native target."), _("\
+Show debugging of FreeBSD native target."), _("\
+Enables printf debugging output."),
+ NULL,
+ &show_fbsd_nat_debug,
+ &setdebuglist, &showdebuglist);
#endif
}

View File

@ -1,184 +0,0 @@
commit 7efba073e2b83803a47fd89e701fe60b98f2debc
Author: John Baldwin <jhb@FreeBSD.org>
Date: Sat Mar 3 21:25:33 2018 -0800
Use signal information to determine SIGTRAP type for FreeBSD.
Use the signal code from siginfo_t to distinguish SIGTRAP events due
to trace traps (TRAP_TRACE) and software breakpoints (TRAP_BRKPT).
For software breakpoints, adjust the PC when the event is reported as
part of the API when supplying "stopped_by_sw_breakpoint". Currently
FreeBSD only supports hardware watchpoints and breakpoints on x86
which are reported as trace traps. Signal information is not used on
MIPS and sparc64 kernels which do not reliably report TRAP_BRKPT for
software breakpoints.
gdb/ChangeLog:
* fbsd-nat.c: Include "inf-ptrace.h".
(USE_SIGTRAP_SIGINFO): Conditionally define.
[USE_SIGTRAP_SIGINFO] (fbsd_handle_debug_trap): New function.
(fbsd_wait) [USE_SIGTRAP_SIGINFO]: Call "fbsd_handle_debug_trap".
[USE_SIGTRAP_SIGINFO] (fbsd_stopped_by_sw_breakpoint): New
function.
[USE_SIGTRAP_SIGINFO] (fbsd_supports_stopped_by_sw_breakpoint):
Likewise.
[USE_SIGTRAP_SIGINFO] (fbsd_supports_stopped_by_hw_breakpoint):
Likewise.
(fbsd_nat_add_target) [USE_SIGTRAP_SIGINFO]: Set
"stopped_by_sw_breakpoint", "supports_stopped_by_sw_breakpoint",
"supports_stopped_by_hw_breakpoint" target methods.
diff --git gdb/fbsd-nat.c gdb/fbsd-nat.c
index 2516ac5552..bea7f42c7e 100644
--- gdb/fbsd-nat.c
+++ gdb/fbsd-nat.c
@@ -26,6 +26,7 @@
#include "gdbcmd.h"
#include "gdbthread.h"
#include "gdb_wait.h"
+#include "inf-ptrace.h"
#include <sys/types.h>
#include <sys/procfs.h>
#include <sys/ptrace.h>
@@ -45,6 +46,14 @@
#include <list>
+#ifdef TRAP_BRKPT
+/* MIPS does not set si_code for SIGTRAP. sparc64 reports
+ non-standard values in si_code for SIGTRAP. */
+# if !defined(__mips__) && !defined(__sparc64__)
+# define USE_SIGTRAP_SIGINFO
+# endif
+#endif
+
/* Return the name of a file that can be opened to get the symbols for
the child process identified by PID. */
@@ -1187,6 +1196,56 @@ fbsd_resume (struct target_ops *ops,
super_resume (ops, ptid, step, signo);
}
+#ifdef USE_SIGTRAP_SIGINFO
+/* Handle breakpoint and trace traps reported via SIGTRAP. If the
+ trap was a breakpoint or trace trap that should be reported to the
+ core, return true. */
+
+static bool
+fbsd_handle_debug_trap (struct target_ops *ops, 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)
+ return false;
+
+ /* Trace traps are either a single step or a hardware watchpoint or
+ breakpoint. */
+ if (pl.pl_siginfo.si_code == TRAP_TRACE)
+ {
+ if (debug_fbsd_nat)
+ fprintf_unfiltered (gdb_stdlog,
+ "FNAT: trace trap for LWP %ld\n", ptid.lwp ());
+ return true;
+ }
+
+ if (pl.pl_siginfo.si_code == TRAP_BRKPT)
+ {
+ /* Fixup PC for the software breakpoint. */
+ struct regcache *regcache = get_thread_regcache (ptid);
+ struct gdbarch *gdbarch = regcache->arch ();
+ int decr_pc = gdbarch_decr_pc_after_break (gdbarch);
+
+ if (debug_fbsd_nat)
+ fprintf_unfiltered (gdb_stdlog,
+ "FNAT: sw breakpoint trap for LWP %ld\n",
+ ptid.lwp ());
+ if (decr_pc != 0)
+ {
+ CORE_ADDR pc;
+
+ pc = regcache_read_pc (regcache);
+ regcache_write_pc (regcache, pc - decr_pc);
+ }
+ return true;
+ }
+
+ return false;
+}
+#endif
+
/* Wait for the child specified by PTID to do something. Return the
process ID of the child, or MINUS_ONE_PTID in case of error; store
the status in *OURSTATUS. */
@@ -1372,6 +1431,11 @@ fbsd_wait (struct target_ops *ops,
}
#endif
+#ifdef USE_SIGTRAP_SIGINFO
+ if (fbsd_handle_debug_trap (ops, wptid, pl))
+ return wptid;
+#endif
+
/* Note that PL_FLAG_SCE is set for any event reported while
a thread is executing a system call in the kernel. In
particular, signals that interrupt a sleep in a system
@@ -1410,6 +1474,42 @@ fbsd_wait (struct target_ops *ops,
}
}
+#ifdef USE_SIGTRAP_SIGINFO
+/* Implement the "to_stopped_by_sw_breakpoint" target_ops method. */
+
+static int
+fbsd_stopped_by_sw_breakpoint (struct target_ops *ops)
+{
+ struct ptrace_lwpinfo pl;
+
+ if (ptrace (PT_LWPINFO, get_ptrace_pid (inferior_ptid), (caddr_t) &pl,
+ sizeof pl) == -1)
+ return 0;
+
+ return ((pl.pl_flags & PL_FLAG_SI)
+ && pl.pl_siginfo.si_signo == SIGTRAP
+ && pl.pl_siginfo.si_code == TRAP_BRKPT);
+}
+
+/* Implement the "to_supports_stopped_by_sw_breakpoint" target_ops
+ method. */
+
+static int
+fbsd_supports_stopped_by_sw_breakpoint (struct target_ops *ops)
+{
+ return 1;
+}
+
+/* Implement the "to_supports_stopped_by_hw_breakpoint" target_ops
+ method. */
+
+static int
+fbsd_supports_stopped_by_hw_breakpoint (struct target_ops *ops)
+{
+ return ops->to_stopped_by_hw_breakpoint != NULL;
+}
+#endif
+
#ifdef TDP_RFPPWAIT
/* Target hook for follow_fork. On entry and at return inferior_ptid is
the ptid of the followed inferior. */
@@ -1560,6 +1660,13 @@ fbsd_nat_add_target (struct target_ops *t)
t->to_wait = fbsd_wait;
t->to_post_startup_inferior = fbsd_post_startup_inferior;
t->to_post_attach = fbsd_post_attach;
+#ifdef USE_SIGTRAP_SIGINFO
+ t->to_stopped_by_sw_breakpoint = fbsd_stopped_by_sw_breakpoint;
+ t->to_supports_stopped_by_sw_breakpoint
+ = fbsd_supports_stopped_by_sw_breakpoint;
+ t->to_supports_stopped_by_hw_breakpoint
+ = fbsd_supports_stopped_by_hw_breakpoint;
+#endif
#ifdef TDP_RFPPWAIT
t->to_follow_fork = fbsd_follow_fork;
t->to_insert_fork_catchpoint = fbsd_insert_fork_catchpoint;

View File

@ -0,0 +1,197 @@
commit 739ab2e92e1840c9285f3cfce1f1236c0fa68730
Author: Simon Ser <contact@emersion.fr>
Date: Thu Sep 6 15:03:19 2018 -0700
Generate NT_PROCSTAT_{AUXV,VMMAP,PS_STRINGS} in FreeBSD coredumps
gcore generates NT_AUXV and NT_FILE notes for Linux targets. On
FreeBSD auxv is stored in a NT_PROCSTAT_AUXV section, virtual memory
mappings are stored in a NT_PROCSTAT_VMMAP, and both are prefixed with
the struct size. In addition, store a NT_PROCSTAT_PS_STRINGS note
saving the initial location of the argv[] and environment[] arrays.
gdb/ChangeLog:
PR gdb/23105
* fbsd-nat.c (fbsd_nat_target::xfer_partial): Add support for
TARGET_OBJECT_FREEBSD_VMMAP and TARGET_OBJECT_FREEBSD_PS_STRINGS.
* fbsd-tdep.c (fbsd_make_note_desc): New.
(fbsd_make_corefile_notes): Write NT_PROCSTAT_AUXV,
NT_PROCSTAT_VMMAP and NT_PROCSTAT_PS_STRINGS notes.
* target.h (enum target_object) Add FreeBSD-specific
TARGET_OBJECT_FREEBSD_VMMAP and TARGET_OBJECT_FREEBSD_PS_STRINGS.
diff --git gdb/ChangeLog gdb/ChangeLog
index 410fbef920..e6f44a3ac2 100644
--- gdb/ChangeLog
+++ gdb/ChangeLog
@@ -1,3 +1,14 @@
+2018-09-06 Simon Ser <contact@emersion.fr>
+
+ PR gdb/23105
+ * fbsd-nat.c (fbsd_nat_target::xfer_partial): Add support for
+ TARGET_OBJECT_FREEBSD_VMMAP and TARGET_OBJECT_FREEBSD_PS_STRINGS.
+ * fbsd-tdep.c (fbsd_make_note_desc): New.
+ (fbsd_make_corefile_notes): Write NT_PROCSTAT_AUXV,
+ NT_PROCSTAT_VMMAP and NT_PROCSTAT_PS_STRINGS notes.
+ * target.h (enum target_object) Add FreeBSD-specific
+ TARGET_OBJECT_FREEBSD_VMMAP and TARGET_OBJECT_FREEBSD_PS_STRINGS.
+
2018-09-06 Simon Marchi <simon.marchi@ericsson.com>
* compile/compile-c.h (generate_c_for_variable_locations):
diff --git gdb/fbsd-nat.c gdb/fbsd-nat.c
index 115deac070..a255318d14 100644
--- gdb/fbsd-nat.c
+++ gdb/fbsd-nat.c
@@ -751,6 +751,61 @@ fbsd_nat_target::xfer_partial (enum target_object object,
}
return TARGET_XFER_E_IO;
}
+ 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;
+ }
default:
return inf_ptrace_target::xfer_partial (object, annex,
readbuf, writebuf, offset,
diff --git gdb/fbsd-tdep.c gdb/fbsd-tdep.c
index 78d0c3d830..ed43087169 100644
--- gdb/fbsd-tdep.c
+++ gdb/fbsd-tdep.c
@@ -512,6 +512,28 @@ fbsd_corefile_thread (struct thread_info *info,
args->note_size, args->stop_signal);
}
+/* Return a byte_vector containing the contents of a core dump note
+ for the target object of type OBJECT. If STRUCTSIZE is non-zero,
+ the data is prefixed with a 32-bit integer size to match the format
+ used in FreeBSD NT_PROCSTAT_* notes. */
+
+static gdb::optional<gdb::byte_vector>
+fbsd_make_note_desc (enum target_object object, uint32_t structsize)
+{
+ gdb::optional<gdb::byte_vector> buf =
+ target_read_alloc (current_top_target (), object, NULL);
+ if (!buf || buf->empty ())
+ return {};
+
+ if (structsize == 0)
+ return buf;
+
+ gdb::byte_vector desc (sizeof (structsize) + buf->size ());
+ memcpy (desc.data (), &structsize, sizeof (structsize));
+ memcpy (desc.data () + sizeof (structsize), buf->data (), buf->size ());
+ return desc;
+}
+
/* Create appropriate note sections for a corefile, returning them in
allocated memory. */
@@ -586,6 +608,40 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
note_data = thread_args.note_data;
+ /* Auxiliary vector. */
+ uint32_t structsize = gdbarch_ptr_bit (gdbarch) / 4; /* Elf_Auxinfo */
+ gdb::optional<gdb::byte_vector> note_desc =
+ fbsd_make_note_desc (TARGET_OBJECT_AUXV, structsize);
+ if (note_desc && !note_desc->empty ())
+ {
+ note_data = elfcore_write_note (obfd, note_data, note_size, "FreeBSD",
+ NT_FREEBSD_PROCSTAT_AUXV,
+ note_desc->data (), note_desc->size ());
+ if (!note_data)
+ return NULL;
+ }
+
+ /* Virtual memory mappings. */
+ note_desc = fbsd_make_note_desc (TARGET_OBJECT_FREEBSD_VMMAP, 0);
+ if (note_desc && !note_desc->empty ())
+ {
+ note_data = elfcore_write_note (obfd, note_data, note_size, "FreeBSD",
+ NT_FREEBSD_PROCSTAT_VMMAP,
+ note_desc->data (), note_desc->size ());
+ if (!note_data)
+ return NULL;
+ }
+
+ note_desc = fbsd_make_note_desc (TARGET_OBJECT_FREEBSD_PS_STRINGS, 0);
+ if (note_desc && !note_desc->empty ())
+ {
+ note_data = elfcore_write_note (obfd, note_data, note_size, "FreeBSD",
+ NT_FREEBSD_PROCSTAT_PSSTRINGS,
+ note_desc->data (), note_desc->size ());
+ if (!note_data)
+ return NULL;
+ }
+
return note_data;
}
diff --git gdb/target.h gdb/target.h
index 229b5d0551..a3000c80c6 100644
--- gdb/target.h
+++ gdb/target.h
@@ -202,6 +202,10 @@ enum target_object
of the process ID of the process in question, in hexadecimal
format. */
TARGET_OBJECT_EXEC_FILE,
+ /* FreeBSD virtual memory mappings. */
+ TARGET_OBJECT_FREEBSD_VMMAP,
+ /* FreeBSD process strings. */
+ TARGET_OBJECT_FREEBSD_PS_STRINGS,
/* Possible future objects: TARGET_OBJECT_FILE, ... */
};

View File

@ -1,29 +0,0 @@
commit 906b4aac4c1d3cdb2b1ea7105133cfbe25e04e14
Author: John Baldwin <jhb@FreeBSD.org>
Date: Fri Jan 12 12:05:50 2018 -0800
Use the correct value for the offset of 'kve_protection'.
I had forgotten to convert the decimal output of 'ptype /o' to hex
(but still used a 0x prefix) for the KVE_PROTECTION constant defining
the offset of the 'kve_protection' field in the 'kinfo_vmentry'
structure. This resulted in garbage permissions for entries in 'info
proc mappings' for FreeBSD core dumps.
gdb/ChangeLog:
* fbsd-tdep.c (KVE_PROTECTION): Correct value.
diff --git gdb/fbsd-tdep.c gdb/fbsd-tdep.c
index 8aa0243d54..e49a9aff09 100644
--- gdb/fbsd-tdep.c
+++ gdb/fbsd-tdep.c
@@ -62,7 +62,7 @@
#define KVE_END 0x10
#define KVE_OFFSET 0x18
#define KVE_FLAGS 0x2c
-#define KVE_PROTECTION 0x56
+#define KVE_PROTECTION 0x38
#define KVE_PATH 0x88
/* Flags in the 'kve_protection' field in struct kinfo_vmentry. These

View File

@ -1,548 +0,0 @@
commit 92fce24de299a8b9a9a1c0c6b98e0e9c1656f99c
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue Jan 9 13:35:17 2018 -0800
Support 'info proc' for native FreeBSD processes.
- Command line arguments are fetched via the kern.proc.args.<pid>
sysctl.
- The 'cwd' and 'exe' values are obtained from the per-process
file descriptor table returned by kinfo_getfile() from libutil.
- 'mappings' is implemented by walking the array of VM map entries
returned by kinfo_getvmmap() from libutil.
- 'status' output is generated by outputting fields from the structure
returned by the kern.proc.pid.<pid> sysctl.
- 'stat' is aliased to 'status'.
gdb/ChangeLog:
* configure.ac: Check for kinfo_getfile in libutil.
* configure: Regenerate.
* config.in: Regenerate.
* fbsd-nat.c: Include "fbsd-tdep.h".
(fbsd_fetch_cmdline): New.
(fbsd_fetch_kinfo_proc): Move earlier and change to return a bool
rather than calling error.
(fbsd_info_proc): New.
(fbsd_thread_name): Report error if fbsd_fetch_kinfo_proc fails.
(fbsd_wait): Report warning if fbsd_fetch_kinfo_proc fails.
(fbsd_nat_add_target): Set "to_info_proc" to "fbsd_info_proc".
diff --git gdb/config.in gdb/config.in
index 1d11a97080..ad2cc1754e 100644
--- gdb/config.in
+++ gdb/config.in
@@ -219,6 +219,9 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
+/* Define to 1 if your system has the kinfo_getfile function. */
+#undef HAVE_KINFO_GETFILE
+
/* Define to 1 if your system has the kinfo_getvmmap function. */
#undef HAVE_KINFO_GETVMMAP
diff --git gdb/configure gdb/configure
index db610f32fc..68b9aad02d 100755
--- gdb/configure
+++ gdb/configure
@@ -7927,6 +7927,66 @@ $as_echo "#define HAVE_KINFO_GETVMMAP 1" >>confdefs.h
fi
+# fbsd-nat.c can also use kinfo_getfile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing kinfo_getfile" >&5
+$as_echo_n "checking for library containing kinfo_getfile... " >&6; }
+if test "${ac_cv_search_kinfo_getfile+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char kinfo_getfile ();
+int
+main ()
+{
+return kinfo_getfile ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' util util-freebsd; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_kinfo_getfile=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_kinfo_getfile+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_kinfo_getfile+set}" = set; then :
+
+else
+ ac_cv_search_kinfo_getfile=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_kinfo_getfile" >&5
+$as_echo "$ac_cv_search_kinfo_getfile" >&6; }
+ac_res=$ac_cv_search_kinfo_getfile
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+$as_echo "#define HAVE_KINFO_GETFILE 1" >>confdefs.h
+
+fi
+
+
if test "X$prefix" = "XNONE"; then
acl_final_prefix="$ac_default_prefix"
diff --git gdb/configure.ac gdb/configure.ac
index 3db44ae758..551afc727e 100644
--- gdb/configure.ac
+++ gdb/configure.ac
@@ -523,6 +523,11 @@ AC_SEARCH_LIBS(kinfo_getvmmap, util util-freebsd,
[AC_DEFINE(HAVE_KINFO_GETVMMAP, 1,
[Define to 1 if your system has the kinfo_getvmmap function. ])])
+# fbsd-nat.c can also use kinfo_getfile.
+AC_SEARCH_LIBS(kinfo_getfile, util util-freebsd,
+ [AC_DEFINE(HAVE_KINFO_GETFILE, 1,
+ [Define to 1 if your system has the kinfo_getfile function. ])])
+
AM_ICONV
# GDB may fork/exec the iconv program to get the list of supported character
diff --git gdb/fbsd-nat.c gdb/fbsd-nat.c
index 81f8e27a2d..b352418813 100644
--- gdb/fbsd-nat.c
+++ gdb/fbsd-nat.c
@@ -32,14 +32,16 @@
#include <sys/signal.h>
#include <sys/sysctl.h>
#include <sys/user.h>
-#ifdef HAVE_KINFO_GETVMMAP
+#if defined(HAVE_KINFO_GETFILE) || defined(HAVE_KINFO_GETVMMAP)
#include <libutil.h>
-#else
+#endif
+#if !defined(HAVE_KINFO_GETVMMAP)
#include "filestuff.h"
#endif
#include "elf-bfd.h"
#include "fbsd-nat.h"
+#include "fbsd-tdep.h"
#include <list>
@@ -205,6 +207,331 @@ fbsd_find_memory_regions (struct target_ops *self,
}
#endif
+/* Fetch the command line for a running process. */
+
+static gdb::unique_xmalloc_ptr<char>
+fbsd_fetch_cmdline (pid_t pid)
+{
+ size_t len;
+ int mib[4];
+
+ len = 0;
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_ARGS;
+ mib[3] = pid;
+ if (sysctl (mib, 4, NULL, &len, NULL, 0) == -1)
+ return nullptr;
+
+ if (len == 0)
+ return nullptr;
+
+ gdb::unique_xmalloc_ptr<char> cmdline ((char *) xmalloc (len));
+ if (sysctl (mib, 4, cmdline.get (), &len, NULL, 0) == -1)
+ return nullptr;
+
+ return cmdline;
+}
+
+/* Fetch the external variant of the kernel's internal process
+ structure for the process PID into KP. */
+
+static bool
+fbsd_fetch_kinfo_proc (pid_t pid, struct kinfo_proc *kp)
+{
+ size_t len;
+ int mib[4];
+
+ len = sizeof *kp;
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PID;
+ mib[3] = pid;
+ return (sysctl (mib, 4, kp, &len, NULL, 0) == 0);
+}
+
+/* Implement the "to_info_proc target_ops" method. */
+
+static void
+fbsd_info_proc (struct target_ops *ops, const char *args,
+ enum info_proc_what what)
+{
+#ifdef HAVE_KINFO_GETFILE
+ gdb::unique_xmalloc_ptr<struct kinfo_file> fdtbl;
+ 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_GETVMMAP
+ bool do_mappings = false;
+#endif
+ bool do_status = false;
+
+ switch (what)
+ {
+ case IP_MINIMAL:
+ do_cmdline = true;
+ do_cwd = true;
+ do_exe = true;
+ break;
+#ifdef HAVE_KINFO_GETVMMAP
+ case IP_MAPPINGS:
+ do_mappings = true;
+ break;
+#endif
+ case IP_STATUS:
+ case IP_STAT:
+ do_status = true;
+ break;
+ case IP_CMDLINE:
+ do_cmdline = true;
+ break;
+ case IP_EXE:
+ do_exe = true;
+ break;
+ case IP_CWD:
+ do_cwd = true;
+ break;
+ case IP_ALL:
+ do_cmdline = true;
+ do_cwd = true;
+ do_exe = true;
+#ifdef HAVE_KINFO_GETVMMAP
+ do_mappings = true;
+#endif
+ do_status = true;
+ break;
+ default:
+ error (_("Not supported on this target."));
+ }
+
+ gdb_argv built_argv (args);
+ if (built_argv.count () == 0)
+ {
+ pid = ptid_get_pid (inferior_ptid);
+ 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);
+#ifdef HAVE_KINFO_GETFILE
+ if (do_cwd || do_exe)
+ fdtbl.reset (kinfo_getfile (pid, &nfd));
+#endif
+
+ if (do_cmdline)
+ {
+ gdb::unique_xmalloc_ptr<char> cmdline = fbsd_fetch_cmdline (pid);
+ if (cmdline != nullptr)
+ printf_filtered ("cmdline = '%s'\n", cmdline.get ());
+ else
+ warning (_("unable to fetch command line"));
+ }
+ if (do_cwd)
+ {
+ const char *cwd = NULL;
+#ifdef HAVE_KINFO_GETFILE
+ struct kinfo_file *kf = fdtbl.get ();
+ for (int i = 0; i < nfd; i++, kf++)
+ {
+ if (kf->kf_type == KF_TYPE_VNODE && kf->kf_fd == KF_FD_TYPE_CWD)
+ {
+ cwd = kf->kf_path;
+ break;
+ }
+ }
+#endif
+ if (cwd != NULL)
+ printf_filtered ("cwd = '%s'\n", cwd);
+ else
+ warning (_("unable to fetch current working directory"));
+ }
+ if (do_exe)
+ {
+ const char *exe = NULL;
+#ifdef HAVE_KINFO_GETFILE
+ struct kinfo_file *kf = fdtbl.get ();
+ for (int i = 0; i < nfd; i++, kf++)
+ {
+ if (kf->kf_type == KF_TYPE_VNODE && kf->kf_fd == KF_FD_TYPE_TEXT)
+ {
+ exe = kf->kf_path;
+ break;
+ }
+ }
+#endif
+ if (exe == NULL)
+ exe = fbsd_pid_to_exec_file (ops, pid);
+ if (exe != NULL)
+ printf_filtered ("exe = '%s'\n", exe);
+ else
+ warning (_("unable to fetch executable path name"));
+ }
+#ifdef HAVE_KINFO_GETVMMAP
+ if (do_mappings)
+ {
+ int nvment;
+ gdb::unique_xmalloc_ptr<struct kinfo_vmentry>
+ vmentl (kinfo_getvmmap (pid, &nvment));
+
+ 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
+
+ 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
+ }
+ }
+ else
+ warning (_("unable to fetch virtual memory map"));
+ }
+#endif
+ if (do_status)
+ {
+ if (!fbsd_fetch_kinfo_proc (pid, &kp))
+ warning (_("Failed to fetch process information"));
+ else
+ {
+ const char *state;
+ int pgtok;
+
+ printf_filtered ("Name: %s\n", kp.ki_comm);
+ switch (kp.ki_stat)
+ {
+ case SIDL:
+ state = "I (idle)";
+ break;
+ case SRUN:
+ state = "R (running)";
+ break;
+ case SSTOP:
+ state = "T (stopped)";
+ break;
+ case SZOMB:
+ state = "Z (zombie)";
+ break;
+ case SSLEEP:
+ state = "S (sleeping)";
+ break;
+ case SWAIT:
+ state = "W (interrupt wait)";
+ break;
+ case SLOCK:
+ state = "L (blocked on lock)";
+ break;
+ default:
+ state = "? (unknown)";
+ break;
+ }
+ printf_filtered ("State: %s\n", state);
+ printf_filtered ("Parent process: %d\n", kp.ki_ppid);
+ printf_filtered ("Process group: %d\n", kp.ki_pgid);
+ printf_filtered ("Session id: %d\n", kp.ki_sid);
+ printf_filtered ("TTY: %ju\n", (uintmax_t) kp.ki_tdev);
+ printf_filtered ("TTY owner process group: %d\n", kp.ki_tpgid);
+ printf_filtered ("User IDs (real, effective, saved): %d %d %d\n",
+ kp.ki_ruid, kp.ki_uid, kp.ki_svuid);
+ printf_filtered ("Group IDs (real, effective, saved): %d %d %d\n",
+ kp.ki_rgid, kp.ki_groups[0], kp.ki_svgid);
+ printf_filtered ("Groups: ");
+ for (int i = 0; i < kp.ki_ngroups; i++)
+ printf_filtered ("%d ", kp.ki_groups[i]);
+ printf_filtered ("\n");
+ printf_filtered ("Minor faults (no memory page): %ld\n",
+ kp.ki_rusage.ru_minflt);
+ printf_filtered ("Minor faults, children: %ld\n",
+ kp.ki_rusage_ch.ru_minflt);
+ printf_filtered ("Major faults (memory page faults): %ld\n",
+ kp.ki_rusage.ru_majflt);
+ printf_filtered ("Major faults, children: %ld\n",
+ kp.ki_rusage_ch.ru_majflt);
+ printf_filtered ("utime: %jd.%06ld\n",
+ (intmax_t) kp.ki_rusage.ru_utime.tv_sec,
+ kp.ki_rusage.ru_utime.tv_usec);
+ printf_filtered ("stime: %jd.%06ld\n",
+ (intmax_t) kp.ki_rusage.ru_stime.tv_sec,
+ kp.ki_rusage.ru_stime.tv_usec);
+ printf_filtered ("utime, children: %jd.%06ld\n",
+ (intmax_t) kp.ki_rusage_ch.ru_utime.tv_sec,
+ kp.ki_rusage_ch.ru_utime.tv_usec);
+ printf_filtered ("stime, children: %jd.%06ld\n",
+ (intmax_t) kp.ki_rusage_ch.ru_stime.tv_sec,
+ kp.ki_rusage_ch.ru_stime.tv_usec);
+ printf_filtered ("'nice' value: %d\n", kp.ki_nice);
+ printf_filtered ("Start time: %jd.%06ld\n", kp.ki_start.tv_sec,
+ kp.ki_start.tv_usec);
+ pgtok = getpagesize () / 1024;
+ printf_filtered ("Virtual memory size: %ju kB\n",
+ (uintmax_t) kp.ki_size / 1024);
+ printf_filtered ("Data size: %ju kB\n",
+ (uintmax_t) kp.ki_dsize * pgtok);
+ printf_filtered ("Stack size: %ju kB\n",
+ (uintmax_t) kp.ki_ssize * pgtok);
+ printf_filtered ("Text size: %ju kB\n",
+ (uintmax_t) kp.ki_tsize * pgtok);
+ printf_filtered ("Resident set size: %ju kB\n",
+ (uintmax_t) kp.ki_rssize * pgtok);
+ printf_filtered ("Maximum RSS: %ju kB\n",
+ (uintmax_t) kp.ki_rusage.ru_maxrss);
+ printf_filtered ("Pending Signals: ");
+ for (int i = 0; i < _SIG_WORDS; i++)
+ printf_filtered ("%08x ", kp.ki_siglist.__bits[i]);
+ printf_filtered ("\n");
+ printf_filtered ("Ignored Signals: ");
+ for (int i = 0; i < _SIG_WORDS; i++)
+ printf_filtered ("%08x ", kp.ki_sigignore.__bits[i]);
+ printf_filtered ("\n");
+ printf_filtered ("Caught Signals: ");
+ for (int i = 0; i < _SIG_WORDS; i++)
+ printf_filtered ("%08x ", kp.ki_sigcatch.__bits[i]);
+ printf_filtered ("\n");
+ }
+ }
+}
+
#ifdef KERN_PROC_AUXV
static enum target_xfer_status (*super_xfer_partial) (struct target_ops *ops,
enum target_object object,
@@ -455,26 +782,6 @@ show_fbsd_lwp_debug (struct ui_file *file, int from_tty,
fprintf_filtered (file, _("Debugging of FreeBSD lwp module is %s.\n"), value);
}
-#if defined(TDP_RFPPWAIT) || defined(HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME)
-/* Fetch the external variant of the kernel's internal process
- structure for the process PID into KP. */
-
-static void
-fbsd_fetch_kinfo_proc (pid_t pid, struct kinfo_proc *kp)
-{
- size_t len;
- int mib[4];
-
- len = sizeof *kp;
- mib[0] = CTL_KERN;
- mib[1] = KERN_PROC;
- mib[2] = KERN_PROC_PID;
- mib[3] = pid;
- if (sysctl (mib, 4, kp, &len, NULL, 0) == -1)
- perror_with_name (("sysctl"));
-}
-#endif
-
/*
FreeBSD's first thread support was via a "reentrant" version of libc
(libc_r) that first shipped in 2.2.7. This library multiplexed all
@@ -560,7 +867,8 @@ fbsd_thread_name (struct target_ops *self, struct thread_info *thr)
/* Note that ptrace_lwpinfo returns the process command in pl_tdname
if a name has not been set explicitly. Return a NULL name in
that case. */
- fbsd_fetch_kinfo_proc (pid, &kp);
+ if (!fbsd_fetch_kinfo_proc (pid, &kp))
+ perror_with_name (_("Failed to fetch process information"));
if (ptrace (PT_LWPINFO, lwp, (caddr_t) &pl, sizeof pl) == -1)
perror_with_name (("ptrace"));
if (strcmp (kp.ki_comm, pl.pl_tdname) == 0)
@@ -970,9 +1278,13 @@ fbsd_wait (struct target_ops *ops,
#ifndef PTRACE_VFORK
/* For vfork, the child process will have the P_PPWAIT
flag set. */
- fbsd_fetch_kinfo_proc (child, &kp);
- if (kp.ki_flag & P_PPWAIT)
- ourstatus->kind = TARGET_WAITKIND_VFORKED;
+ if (fbsd_fetch_kinfo_proc (child, &kp))
+ {
+ if (kp.ki_flag & P_PPWAIT)
+ ourstatus->kind = TARGET_WAITKIND_VFORKED;
+ }
+ else
+ warning (_("Failed to fetch process information"));
#endif
ourstatus->value.related_pid = child_ptid;
@@ -1176,6 +1488,7 @@ fbsd_nat_add_target (struct target_ops *t)
{
t->to_pid_to_exec_file = fbsd_pid_to_exec_file;
t->to_find_memory_regions = fbsd_find_memory_regions;
+ t->to_info_proc = fbsd_info_proc;
#ifdef KERN_PROC_AUXV
super_xfer_partial = t->to_xfer_partial;
t->to_xfer_partial = fbsd_xfer_partial;

View File

@ -1,32 +0,0 @@
commit b999e2038dbc54e2c8b1c390f8b8fe50d0f1d10a
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue Jan 9 13:35:17 2018 -0800
Don't return stale data from fbsd_pid_to_exec_file for kernel processes.
For processes without an associated executable (such as kernel processes),
the kern.proc.pathname.<pid> system control node returns a length of zero
without modifying the user's buffer. Detect this case and return NULL
rather than the previous contents of the static buffer 'buf'.
gdb/ChangeLog:
* fbsd-nat.c (fbsd_pid_to_exec_file) [KERN_PROC_PATHNAME]: Return
NULL for an empty pathname.
diff --git gdb/fbsd-nat.c gdb/fbsd-nat.c
index ec4eed9abe..d0aaf89145 100644
--- gdb/fbsd-nat.c
+++ gdb/fbsd-nat.c
@@ -63,7 +63,10 @@ fbsd_pid_to_exec_file (struct target_ops *self, int pid)
mib[3] = pid;
buflen = sizeof buf;
if (sysctl (mib, 4, buf, &buflen, NULL, 0) == 0)
- return buf;
+ /* The kern.proc.pathname.<pid> sysctl returns a length of zero
+ for processes without an associated executable such as kernel
+ processes. */
+ return buflen == 0 ? NULL : buf;
#endif
xsnprintf (name, PATH_MAX, "/proc/%d/exe", pid);

View File

@ -1,725 +0,0 @@
commit d2176225dc982c22640215a0e611e997e8eeb030
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue Jan 9 13:35:17 2018 -0800
Support 'info proc' for FreeBSD process core dumps.
- Command line arguments are obtained from the pr_psargs[] array
saved in the NT_PRPSINFO note.
- The 'cwd' and 'exe' values are obtained from the per-process file
descriptor table stored in the NT_PROCSTAT_FILES core note.
- 'mappings' is implemented by walking the array of VM map entries
stored in the NT_PROCSTAT_VMMAP core note.
- 'status' output is generated by outputting fields from
the first structure stored in the NT_PROCSTAT_PROC core note.
- 'stat' is aliased to 'status'.
gdb/ChangeLog:
* fbsd-tdep.c (KVE_STRUCTSIZE, KVE_START, KVE_END, KVE_OFFSET)
(KVE_FLAGS, KVE_PROTECTION, KVE_PATH, 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_SUPER, KINFO_VME_FLAG_GROWS_UP)
(KINFO_VME_FLAG_GROWS_DOWN, KF_STRUCTSIZE, KF_TYPE, KF_FD)
(KF_PATH, KINFO_FILE_TYPE_VNODE, KINFO_FILE_FD_TYPE_CWD)
(KINFO_FILE_FD_TYPE_TEXT, SIG_WORDS, struct kinfo_proc_layout)
(kinfo_proc_layout_32, kinfo_proc_layout_i386)
(kinfo_proc_layout_64, fbsd_vm_map_entry_flags)
(fbsd_core_info_proc_mappings, fbsd_core_vnode_path)
(fbsd_core_fetch_timeval, fbsd_print_sigset)
(fbsd_core_info_proc_status, fbsd_core_info_proc): New.
(fbsd_init_abi): Install gdbarch "core_info_proc" method.
* fbsd-tdep.h (fbsd_vm_map_entry_flags): New.
diff --git gdb/fbsd-tdep.c gdb/fbsd-tdep.c
index ce17c672d9..8aa0243d54 100644
--- gdb/fbsd-tdep.c
+++ gdb/fbsd-tdep.c
@@ -52,6 +52,228 @@
#define SIZE64_SIGINFO_T 80
#define SIZE32_SIGINFO_T 64
+/* Offsets in data structure used in NT_FREEBSD_PROCSTAT_VMMAP core
+ dump notes. See <sys/user.h> for the definition of struct
+ kinfo_vmentry. This data structure should have the same layout on
+ all architectures. */
+
+#define KVE_STRUCTSIZE 0x0
+#define KVE_START 0x8
+#define KVE_END 0x10
+#define KVE_OFFSET 0x18
+#define KVE_FLAGS 0x2c
+#define KVE_PROTECTION 0x56
+#define KVE_PATH 0x88
+
+/* Flags in the 'kve_protection' field in struct kinfo_vmentry. These
+ match the KVME_PROT_* constants in <sys/user.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/user.h>. */
+
+#define KINFO_VME_FLAG_COW 0x00000001
+#define KINFO_VME_FLAG_NEEDS_COPY 0x00000002
+#define KINFO_VME_FLAG_NOCOREDUMP 0x00000004
+#define KINFO_VME_FLAG_SUPER 0x00000008
+#define KINFO_VME_FLAG_GROWS_UP 0x00000010
+#define KINFO_VME_FLAG_GROWS_DOWN 0x00000020
+
+/* Offsets in data structure used in NT_FREEBSD_PROCSTAT_FILES core
+ dump notes. See <sys/user.h> for the definition of struct
+ kinfo_file. This data structure should have the same layout on all
+ architectures. */
+
+#define KF_STRUCTSIZE 0x0
+#define KF_TYPE 0x4
+#define KF_FD 0x8
+#define KF_PATH 0x170
+
+/* Constants for the 'kf_type' field in struct kinfo_file. These
+ match the KF_TYPE_* constants in <sys/user.h>. */
+
+#define KINFO_FILE_TYPE_VNODE 1
+
+/* Special values for the 'kf_fd' field in struct kinfo_file. These
+ match the KF_FD_TYPE_* constants in <sys/user.h>. */
+
+#define KINFO_FILE_FD_TYPE_CWD -1
+#define KINFO_FILE_FD_TYPE_TEXT -5
+
+/* Number of 32-bit words in a signal set. This matches _SIG_WORDS in
+ <sys/_sigset.h> and is the same value on all architectures. */
+
+#define SIG_WORDS 4
+
+/* Offsets in data structure used in NT_FREEBSD_PROCSTAT_PROC core
+ dump notes. See <sys/user.h> for the definition of struct
+ kinfo_proc. This data structure has different layouts on different
+ architectures mostly due to ILP32 vs LP64. However, FreeBSD/i386
+ uses a 32-bit time_t while all other architectures use a 64-bit
+ time_t.
+
+ The core dump note actually contains one kinfo_proc structure for
+ each thread, but all of the process-wide data can be obtained from
+ the first structure. One result of this note's format is that some
+ of the process-wide status available in the native target method
+ from the kern.proc.pid.<pid> sysctl such as ki_stat and ki_siglist
+ is not available from a core dump. Instead, the per-thread data
+ structures contain the value of these fields for individual
+ threads. */
+
+struct kinfo_proc_layout
+{
+ /* Offsets of struct kinfo_proc members. */
+ int ki_layout;
+ int ki_pid;
+ int ki_ppid;
+ int ki_pgid;
+ int ki_tpgid;
+ int ki_sid;
+ int ki_tdev_freebsd11;
+ int ki_sigignore;
+ int ki_sigcatch;
+ int ki_uid;
+ int ki_ruid;
+ int ki_svuid;
+ int ki_rgid;
+ int ki_svgid;
+ int ki_ngroups;
+ int ki_groups;
+ int ki_size;
+ int ki_rssize;
+ int ki_tsize;
+ int ki_dsize;
+ int ki_ssize;
+ int ki_start;
+ int ki_nice;
+ int ki_comm;
+ int ki_tdev;
+ int ki_rusage;
+ int ki_rusage_ch;
+
+ /* Offsets of struct rusage members. */
+ int ru_utime;
+ int ru_stime;
+ int ru_maxrss;
+ int ru_minflt;
+ int ru_majflt;
+};
+
+const struct kinfo_proc_layout kinfo_proc_layout_32 =
+ {
+ .ki_layout = 0x4,
+ .ki_pid = 0x28,
+ .ki_ppid = 0x2c,
+ .ki_pgid = 0x30,
+ .ki_tpgid = 0x34,
+ .ki_sid = 0x38,
+ .ki_tdev_freebsd11 = 0x44,
+ .ki_sigignore = 0x68,
+ .ki_sigcatch = 0x78,
+ .ki_uid = 0x88,
+ .ki_ruid = 0x8c,
+ .ki_svuid = 0x90,
+ .ki_rgid = 0x94,
+ .ki_svgid = 0x98,
+ .ki_ngroups = 0x9c,
+ .ki_groups = 0xa0,
+ .ki_size = 0xe0,
+ .ki_rssize = 0xe4,
+ .ki_tsize = 0xec,
+ .ki_dsize = 0xf0,
+ .ki_ssize = 0xf4,
+ .ki_start = 0x118,
+ .ki_nice = 0x145,
+ .ki_comm = 0x17f,
+ .ki_tdev = 0x1f0,
+ .ki_rusage = 0x220,
+ .ki_rusage_ch = 0x278,
+
+ .ru_utime = 0x0,
+ .ru_stime = 0x10,
+ .ru_maxrss = 0x20,
+ .ru_minflt = 0x30,
+ .ru_majflt = 0x34,
+ };
+
+const struct kinfo_proc_layout kinfo_proc_layout_i386 =
+ {
+ .ki_layout = 0x4,
+ .ki_pid = 0x28,
+ .ki_ppid = 0x2c,
+ .ki_pgid = 0x30,
+ .ki_tpgid = 0x34,
+ .ki_sid = 0x38,
+ .ki_tdev_freebsd11 = 0x44,
+ .ki_sigignore = 0x68,
+ .ki_sigcatch = 0x78,
+ .ki_uid = 0x88,
+ .ki_ruid = 0x8c,
+ .ki_svuid = 0x90,
+ .ki_rgid = 0x94,
+ .ki_svgid = 0x98,
+ .ki_ngroups = 0x9c,
+ .ki_groups = 0xa0,
+ .ki_size = 0xe0,
+ .ki_rssize = 0xe4,
+ .ki_tsize = 0xec,
+ .ki_dsize = 0xf0,
+ .ki_ssize = 0xf4,
+ .ki_start = 0x118,
+ .ki_nice = 0x135,
+ .ki_comm = 0x16f,
+ .ki_tdev = 0x1e0,
+ .ki_rusage = 0x210,
+ .ki_rusage_ch = 0x258,
+
+ .ru_utime = 0x0,
+ .ru_stime = 0x8,
+ .ru_maxrss = 0x10,
+ .ru_minflt = 0x20,
+ .ru_majflt = 0x24,
+ };
+
+const struct kinfo_proc_layout kinfo_proc_layout_64 =
+ {
+ .ki_layout = 0x4,
+ .ki_pid = 0x48,
+ .ki_ppid = 0x4c,
+ .ki_pgid = 0x50,
+ .ki_tpgid = 0x54,
+ .ki_sid = 0x58,
+ .ki_tdev_freebsd11 = 0x64,
+ .ki_sigignore = 0x88,
+ .ki_sigcatch = 0x98,
+ .ki_uid = 0xa8,
+ .ki_ruid = 0xac,
+ .ki_svuid = 0xb0,
+ .ki_rgid = 0xb4,
+ .ki_svgid = 0xb8,
+ .ki_ngroups = 0xbc,
+ .ki_groups = 0xc0,
+ .ki_size = 0x100,
+ .ki_rssize = 0x108,
+ .ki_tsize = 0x118,
+ .ki_dsize = 0x120,
+ .ki_ssize = 0x128,
+ .ki_start = 0x150,
+ .ki_nice = 0x185,
+ .ki_comm = 0x1bf,
+ .ki_tdev = 0x230,
+ .ki_rusage = 0x260,
+ .ki_rusage_ch = 0x2f0,
+
+ .ru_utime = 0x0,
+ .ru_stime = 0x10,
+ .ru_maxrss = 0x20,
+ .ru_minflt = 0x40,
+ .ru_majflt = 0x48,
+ };
+
static struct gdbarch_data *fbsd_gdbarch_data_handle;
struct fbsd_gdbarch_data
@@ -367,6 +589,433 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
return note_data;
}
+/* Helper function to generate mappings flags for a single VM map
+ entry in 'info proc mappings'. */
+
+const char *
+fbsd_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_SUPER) ? 'S' : '-';
+ 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;
+}
+
+/* Implement "info proc mappings" for a corefile. */
+
+static void
+fbsd_core_info_proc_mappings (struct gdbarch *gdbarch)
+{
+ asection *section;
+ unsigned char *descdata, *descend;
+ size_t note_size;
+
+ section = bfd_get_section_by_name (core_bfd, ".note.freebsdcore.vmmap");
+ if (section == NULL)
+ {
+ warning (_("unable to find mappings in core file"));
+ return;
+ }
+
+ note_size = bfd_get_section_size (section);
+ if (note_size < 4)
+ error (_("malformed core note - too short for header"));
+
+ gdb::def_vector<unsigned char> contents (note_size);
+ if (!bfd_get_section_contents (core_bfd, section, contents.data (),
+ 0, note_size))
+ error (_("could not get core note contents"));
+
+ descdata = contents.data ();
+ descend = descdata + note_size;
+
+ /* Skip over the structure size. */
+ descdata += 4;
+
+ printf_filtered (_("Mapped address spaces:\n\n"));
+ if (gdbarch_addr_bit (gdbarch) == 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");
+ }
+
+ while (descdata + KVE_PATH < descend)
+ {
+ ULONGEST start, end, offset, flags, prot, structsize;
+
+ structsize = bfd_get_32 (core_bfd, descdata + KVE_STRUCTSIZE);
+ if (structsize < KVE_PATH)
+ error (_("malformed core note - vmmap entry too small"));
+
+ start = bfd_get_64 (core_bfd, descdata + KVE_START);
+ end = bfd_get_64 (core_bfd, descdata + KVE_END);
+ offset = bfd_get_64 (core_bfd, descdata + KVE_OFFSET);
+ flags = bfd_get_32 (core_bfd, descdata + KVE_FLAGS);
+ prot = bfd_get_32 (core_bfd, descdata + KVE_PROTECTION);
+ if (gdbarch_addr_bit (gdbarch) == 64)
+ {
+ printf_filtered (" %18s %18s %10s %10s %9s %s\n",
+ paddress (gdbarch, start),
+ paddress (gdbarch, end),
+ hex_string (end - start),
+ hex_string (offset),
+ fbsd_vm_map_entry_flags (flags, prot),
+ descdata + KVE_PATH);
+ }
+ else
+ {
+ printf_filtered ("\t%10s %10s %10s %10s %9s %s\n",
+ paddress (gdbarch, start),
+ paddress (gdbarch, end),
+ hex_string (end - start),
+ hex_string (offset),
+ fbsd_vm_map_entry_flags (flags, prot),
+ descdata + KVE_PATH);
+ }
+
+ descdata += structsize;
+ }
+}
+
+/* Fetch the pathname of a vnode for a single file descriptor from the
+ file table core note. */
+
+static gdb::unique_xmalloc_ptr<char>
+fbsd_core_vnode_path (struct gdbarch *gdbarch, int fd)
+{
+ asection *section;
+ unsigned char *descdata, *descend;
+ size_t note_size;
+
+ section = bfd_get_section_by_name (core_bfd, ".note.freebsdcore.files");
+ if (section == NULL)
+ return nullptr;
+
+ note_size = bfd_get_section_size (section);
+ if (note_size < 4)
+ error (_("malformed core note - too short for header"));
+
+ gdb::def_vector<unsigned char> contents (note_size);
+ if (!bfd_get_section_contents (core_bfd, section, contents.data (),
+ 0, note_size))
+ error (_("could not get core note contents"));
+
+ descdata = contents.data ();
+ descend = descdata + note_size;
+
+ /* Skip over the structure size. */
+ descdata += 4;
+
+ while (descdata + KVE_PATH < descend)
+ {
+ ULONGEST structsize;
+
+ structsize = bfd_get_32 (core_bfd, descdata + KF_STRUCTSIZE);
+ if (structsize < KVE_PATH)
+ error (_("malformed core note - vmmap entry too small"));
+
+ if (bfd_get_32 (core_bfd, descdata + KF_TYPE) == KINFO_FILE_TYPE_VNODE
+ && bfd_get_signed_32 (core_bfd, descdata + KF_FD) == fd)
+ {
+ char *path = (char *) descdata + KF_PATH;
+ return gdb::unique_xmalloc_ptr<char> (xstrdup (path));
+ }
+
+ descdata += structsize;
+ }
+ return nullptr;
+}
+
+/* Helper function to read a struct timeval. */
+
+static void
+fbsd_core_fetch_timeval (struct gdbarch *gdbarch, unsigned char *data,
+ LONGEST &sec, ULONGEST &usec)
+{
+ if (gdbarch_addr_bit (gdbarch) == 64)
+ {
+ sec = bfd_get_signed_64 (core_bfd, data);
+ usec = bfd_get_64 (core_bfd, data + 8);
+ }
+ else if (bfd_get_arch (core_bfd) == bfd_arch_i386)
+ {
+ sec = bfd_get_signed_32 (core_bfd, data);
+ usec = bfd_get_32 (core_bfd, data + 4);
+ }
+ else
+ {
+ sec = bfd_get_signed_64 (core_bfd, data);
+ usec = bfd_get_32 (core_bfd, data + 8);
+ }
+}
+
+/* Print out the contents of a signal set. */
+
+static void
+fbsd_print_sigset (const char *descr, unsigned char *sigset)
+{
+ printf_filtered ("%s: ", descr);
+ for (int i = 0; i < SIG_WORDS; i++)
+ printf_filtered ("%08x ",
+ (unsigned int) bfd_get_32 (core_bfd, sigset + i * 4));
+ printf_filtered ("\n");
+}
+
+/* Implement "info proc status" for a corefile. */
+
+static void
+fbsd_core_info_proc_status (struct gdbarch *gdbarch)
+{
+ const struct kinfo_proc_layout *kp;
+ asection *section;
+ const char *state;
+ unsigned char *descdata;
+ int addr_bit, long_bit;
+ size_t note_size;
+ ULONGEST value;
+ LONGEST sec;
+
+ section = bfd_get_section_by_name (core_bfd, ".note.freebsdcore.proc");
+ if (section == NULL)
+ {
+ warning (_("unable to find process info in core file"));
+ return;
+ }
+
+ addr_bit = gdbarch_addr_bit (gdbarch);
+ if (addr_bit == 64)
+ kp = &kinfo_proc_layout_64;
+ else if (bfd_get_arch (core_bfd) == bfd_arch_i386)
+ kp = &kinfo_proc_layout_i386;
+ else
+ kp = &kinfo_proc_layout_32;
+ long_bit = gdbarch_long_bit (gdbarch);
+
+ /*
+ * Ensure that the note is large enough for all of the fields fetched
+ * by this function. In particular, the note must contain the 32-bit
+ * structure size, then it must be long enough to access the last
+ * field used (ki_rusage_ch.ru_majflt) which is the size of a long.
+ */
+ note_size = bfd_get_section_size (section);
+ if (note_size < (4 + kp->ki_rusage_ch + kp->ru_majflt
+ + long_bit / TARGET_CHAR_BIT))
+ error (_("malformed core note - too short"));
+
+ gdb::def_vector<unsigned char> contents (note_size);
+ if (!bfd_get_section_contents (core_bfd, section, contents.data (),
+ 0, note_size))
+ error (_("could not get core note contents"));
+
+ descdata = contents.data ();
+
+ /* Skip over the structure size. */
+ descdata += 4;
+
+ /* Verify 'ki_layout' is 0. */
+ if (bfd_get_32 (core_bfd, descdata + kp->ki_layout) != 0)
+ {
+ warning (_("unsupported process information in core file"));
+ return;
+ }
+
+ printf_filtered ("Name: %.19s\n", descdata + kp->ki_comm);
+ printf_filtered ("Process ID: %s\n",
+ pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_pid)));
+ printf_filtered ("Parent process: %s\n",
+ pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_ppid)));
+ printf_filtered ("Process group: %s\n",
+ pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_pgid)));
+ printf_filtered ("Session id: %s\n",
+ pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_sid)));
+
+ /* FreeBSD 12.0 and later store a 64-bit dev_t at 'ki_tdev'. Older
+ kernels store a 32-bit dev_t at 'ki_tdev_freebsd11'. In older
+ kernels the 64-bit 'ki_tdev' field is in a reserved section of
+ the structure that is cleared to zero. Assume that a zero value
+ in ki_tdev indicates a core dump from an older kernel and use the
+ value in 'ki_tdev_freebsd11' instead. */
+ value = bfd_get_64 (core_bfd, descdata + kp->ki_tdev);
+ if (value == 0)
+ value = bfd_get_32 (core_bfd, descdata + kp->ki_tdev_freebsd11);
+ printf_filtered ("TTY: %s\n", pulongest (value));
+ printf_filtered ("TTY owner process group: %s\n",
+ pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_tpgid)));
+ printf_filtered ("User IDs (real, effective, saved): %s %s %s\n",
+ pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_ruid)),
+ pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_uid)),
+ pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_svuid)));
+ printf_filtered ("Group IDs (real, effective, saved): %s %s %s\n",
+ pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_rgid)),
+ pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_groups)),
+ pulongest (bfd_get_32 (core_bfd, descdata + kp->ki_svgid)));
+ printf_filtered ("Groups: ");
+ uint16_t ngroups = bfd_get_16 (core_bfd, descdata + kp->ki_ngroups);
+ for (int i = 0; i < ngroups; i++)
+ printf_filtered ("%s ",
+ pulongest (bfd_get_32 (core_bfd,
+ descdata + kp->ki_groups + i * 4)));
+ printf_filtered ("\n");
+ value = bfd_get (long_bit, core_bfd,
+ descdata + kp->ki_rusage + kp->ru_minflt);
+ printf_filtered ("Minor faults (no memory page): %s\n", pulongest (value));
+ value = bfd_get (long_bit, core_bfd,
+ descdata + kp->ki_rusage_ch + kp->ru_minflt);
+ printf_filtered ("Minor faults, children: %s\n", pulongest (value));
+ value = bfd_get (long_bit, core_bfd,
+ descdata + kp->ki_rusage + kp->ru_majflt);
+ printf_filtered ("Major faults (memory page faults): %s\n",
+ pulongest (value));
+ value = bfd_get (long_bit, core_bfd,
+ descdata + kp->ki_rusage_ch + kp->ru_majflt);
+ printf_filtered ("Major faults, children: %s\n", pulongest (value));
+ fbsd_core_fetch_timeval (gdbarch,
+ descdata + kp->ki_rusage + kp->ru_utime,
+ sec, value);
+ printf_filtered ("utime: %s.%06d\n", plongest (sec), (int) value);
+ fbsd_core_fetch_timeval (gdbarch,
+ descdata + kp->ki_rusage + kp->ru_stime,
+ sec, value);
+ printf_filtered ("stime: %s.%06d\n", plongest (sec), (int) value);
+ fbsd_core_fetch_timeval (gdbarch,
+ descdata + kp->ki_rusage_ch + kp->ru_utime,
+ sec, value);
+ printf_filtered ("utime, children: %s.%06d\n", plongest (sec), (int) value);
+ fbsd_core_fetch_timeval (gdbarch,
+ descdata + kp->ki_rusage_ch + kp->ru_stime,
+ sec, value);
+ printf_filtered ("stime, children: %s.%06d\n", plongest (sec), (int) value);
+ printf_filtered ("'nice' value: %d\n",
+ bfd_get_signed_8 (core_bfd, descdata + kp->ki_nice));
+ fbsd_core_fetch_timeval (gdbarch, descdata + kp->ki_start, sec, value);
+ printf_filtered ("Start time: %s.%06d\n", plongest (sec), (int) value);
+ printf_filtered ("Virtual memory size: %s kB\n",
+ pulongest (bfd_get (addr_bit, core_bfd,
+ descdata + kp->ki_size) / 1024));
+ printf_filtered ("Data size: %s pages\n",
+ pulongest (bfd_get (addr_bit, core_bfd,
+ descdata + kp->ki_dsize)));
+ printf_filtered ("Stack size: %s pages\n",
+ pulongest (bfd_get (addr_bit, core_bfd,
+ descdata + kp->ki_ssize)));
+ printf_filtered ("Text size: %s pages\n",
+ pulongest (bfd_get (addr_bit, core_bfd,
+ descdata + kp->ki_tsize)));
+ printf_filtered ("Resident set size: %s pages\n",
+ pulongest (bfd_get (addr_bit, core_bfd,
+ descdata + kp->ki_rssize)));
+ printf_filtered ("Maximum RSS: %s pages\n",
+ pulongest (bfd_get (long_bit, core_bfd,
+ descdata + kp->ki_rusage
+ + kp->ru_maxrss)));
+ fbsd_print_sigset ("Ignored Signals", descdata + kp->ki_sigignore);
+ fbsd_print_sigset ("Caught Signals", descdata + kp->ki_sigcatch);
+}
+
+/* Implement the "core_info_proc" gdbarch method. */
+
+static void
+fbsd_core_info_proc (struct gdbarch *gdbarch, const char *args,
+ enum info_proc_what what)
+{
+ bool do_cmdline = false;
+ bool do_cwd = false;
+ bool do_exe = false;
+ bool do_mappings = false;
+ bool do_status = false;
+ int pid;
+
+ switch (what)
+ {
+ case IP_MINIMAL:
+ do_cmdline = true;
+ do_cwd = true;
+ do_exe = true;
+ break;
+ case IP_MAPPINGS:
+ do_mappings = true;
+ break;
+ case IP_STATUS:
+ case IP_STAT:
+ do_status = true;
+ break;
+ case IP_CMDLINE:
+ do_cmdline = true;
+ break;
+ case IP_EXE:
+ do_exe = true;
+ break;
+ case IP_CWD:
+ do_cwd = true;
+ break;
+ case IP_ALL:
+ do_cmdline = true;
+ do_cwd = true;
+ do_exe = true;
+ do_mappings = true;
+ do_status = true;
+ break;
+ default:
+ return;
+ }
+
+ pid = bfd_core_file_pid (core_bfd);
+ if (pid != 0)
+ printf_filtered (_("process %d\n"), pid);
+
+ if (do_cmdline)
+ {
+ const char *cmdline;
+
+ cmdline = bfd_core_file_failing_command (core_bfd);
+ if (cmdline)
+ printf_filtered ("cmdline = '%s'\n", cmdline);
+ else
+ warning (_("Command line unavailable"));
+ }
+ if (do_cwd)
+ {
+ gdb::unique_xmalloc_ptr<char> cwd =
+ fbsd_core_vnode_path (gdbarch, KINFO_FILE_FD_TYPE_CWD);
+ if (cwd)
+ printf_filtered ("cwd = '%s'\n", cwd.get ());
+ else
+ warning (_("unable to read current working directory"));
+ }
+ if (do_exe)
+ {
+ gdb::unique_xmalloc_ptr<char> exe =
+ fbsd_core_vnode_path (gdbarch, KINFO_FILE_FD_TYPE_TEXT);
+ if (exe)
+ printf_filtered ("exe = '%s'\n", exe.get ());
+ else
+ warning (_("unable to read executable path name"));
+ }
+ if (do_mappings)
+ fbsd_core_info_proc_mappings (gdbarch);
+ if (do_status)
+ fbsd_core_info_proc_status (gdbarch);
+}
+
/* Print descriptions of FreeBSD-specific AUXV entries to FILE. */
static void
@@ -519,6 +1168,7 @@ fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_core_thread_name (gdbarch, fbsd_core_thread_name);
set_gdbarch_core_xfer_siginfo (gdbarch, fbsd_core_xfer_siginfo);
set_gdbarch_make_corefile_notes (gdbarch, fbsd_make_corefile_notes);
+ set_gdbarch_core_info_proc (gdbarch, fbsd_core_info_proc);
set_gdbarch_print_auxv_entry (gdbarch, fbsd_print_auxv_entry);
set_gdbarch_get_siginfo_type (gdbarch, fbsd_get_siginfo_type);
diff --git gdb/fbsd-tdep.h gdb/fbsd-tdep.h
index 9769903dec..0b293e5a25 100644
--- gdb/fbsd-tdep.h
+++ gdb/fbsd-tdep.h
@@ -22,4 +22,11 @@
extern void fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch);
+/* Helper function to generate mappings flags for a single VM map
+ entry in 'info proc mappings'. The KVE_FLAGS and KVE_PROTECTION
+ parameters should contain the values of the corresponding fields in
+ a 'struct kinfo_vmentry'. */
+
+extern const char *fbsd_vm_map_entry_flags (int kve_flags, int kve_protection);
+
#endif /* fbsd-tdep.h */

View File

@ -1,84 +0,0 @@
commit f169cfdc08761a3d9fcd587ad8661102672403ec
Author: John Baldwin <jhb@FreeBSD.org>
Date: Tue Oct 24 21:06:00 2017 -0700
Workaround a FreeBSD ptrace() bug with clearing thread events.
When multiple threads within a process wish to report STOPPED events
from wait(), the kernel picks one thread event as the thread event to
report. The chosen thread event is retrieved via PT_LWPINFO by
passing the process ID as the request pid. If multiple events are
pending, then the subsequent wait() after resuming a process will
report another STOPPED event after resuming the process to handle the
next thread event and so on.
A single thread event is cleared as a side effect of resuming the
process with PT_CONTINUE, PT_STEP, etc. In older kernels, however,
the request pid was used to select which thread's event was cleared
rather than always clearing the event that was just reported. To
avoid clearing the event of the wrong LWP, always pass the process ID
instead of an LWP ID to PT_CONTINUE or PT_SYSCALL.
In the case of stepping, the process ID cannot be used with PT_STEP
since it would step the thread that reported an event which may not be
the thread indicated by PTID. For stepping, use PT_SETSTEP to enable
stepping on the desired thread before resuming the process via
PT_CONTINUE instead of using PT_STEP.
This manifested as a failure in the
gdb.threads/continue-pending-status.exp test. Specifically, if thread
2 reported a breakpoint and the test thus switched to thread 3 before
continuing, thread 3's event (if any) was discarded and thread 2's
breakpoint remained pending and was reported a second time as a
duplicate event. As a result, the PC was decremented twice for the
same breakpoint resulting in an illegal instruction fault on x86.
gdb/ChangeLog:
* fbsd-nat.c (fbsd_resume): Use PT_SETSTEP for stepping and a
wildcard process pid for super_resume for kernels with a
specific bug.
diff --git gdb/fbsd-nat.c gdb/fbsd-nat.c
index b352418813..3a216abf18 100644
--- gdb/fbsd-nat.c
+++ gdb/fbsd-nat.c
@@ -1143,6 +1143,38 @@ fbsd_resume (struct target_ops *ops,
}
ptid = inferior_ptid;
}
+
+#if __FreeBSD_version < 1200052
+ /* When multiple threads within a process wish to report STOPPED
+ events from wait(), the kernel picks one thread event as the
+ thread event to report. The chosen thread event is retrieved via
+ PT_LWPINFO by passing the process ID as the request pid. If
+ multiple events are pending, then the subsequent wait() after
+ resuming a process will report another STOPPED event after
+ resuming the process to handle the next thread event and so on.
+
+ A single thread event is cleared as a side effect of resuming the
+ process with PT_CONTINUE, PT_STEP, etc. In older kernels,
+ however, the request pid was used to select which thread's event
+ was cleared rather than always clearing the event that was just
+ reported. To avoid clearing the event of the wrong LWP, always
+ pass the process ID instead of an LWP ID to PT_CONTINUE or
+ PT_SYSCALL.
+
+ In the case of stepping, the process ID cannot be used with
+ PT_STEP since it would step the thread that reported an event
+ which may not be the thread indicated by PTID. For stepping, use
+ PT_SETSTEP to enable stepping on the desired thread before
+ resuming the process via PT_CONTINUE instead of using
+ PT_STEP. */
+ if (step)
+ {
+ if (ptrace (PT_SETSTEP, get_ptrace_pid (ptid), NULL, 0) == -1)
+ perror_with_name (("ptrace"));
+ step = 0;
+ }
+ ptid = ptid_t (ptid.pid ());
+#endif
super_resume (ops, ptid, step, signo);
}

View File

@ -1,8 +1,8 @@
diff --git gdb/Makefile.in gdb/Makefile.in
index 17b71c6e7c..95e92d08b4 100644
index 13627e07e0..a72fd8fe0f 100644
--- gdb/Makefile.in
+++ gdb/Makefile.in
@@ -230,7 +230,8 @@ INCGNU = -I$(srcdir)/gnulib/import -I$(GNULIB_BUILDDIR)/import
@@ -236,7 +236,8 @@ INCGNU = -I$(srcdir)/gnulib/import -I$(GNULIB_BUILDDIR)/import
# Generated headers in the gnulib directory. These must be listed
# so that they are generated before other files are compiled.
@ -12,7 +12,7 @@ index 17b71c6e7c..95e92d08b4 100644
#
# CLI sub directory definitons
@@ -629,6 +630,7 @@ TARGET_OBS = @TARGET_OBS@
@@ -643,6 +644,7 @@ TARGET_OBS = @TARGET_OBS@
# All target-dependent objects files that require 64-bit CORE_ADDR
# (used with --enable-targets=all --enable-64-bit-bfd).
ALL_64_TARGET_OBS = \
@ -20,7 +20,7 @@ index 17b71c6e7c..95e92d08b4 100644
aarch64-fbsd-tdep.o \
aarch64-linux-tdep.o \
aarch64-newlib-tdep.o \
@@ -642,6 +644,7 @@ ALL_64_TARGET_OBS = \
@@ -656,6 +658,7 @@ ALL_64_TARGET_OBS = \
amd64-darwin-tdep.o \
amd64-dicos-tdep.o \
amd64-fbsd-tdep.o \
@ -28,7 +28,7 @@ index 17b71c6e7c..95e92d08b4 100644
amd64-linux-tdep.o \
amd64-nbsd-tdep.o \
amd64-obsd-tdep.o \
@@ -656,6 +659,7 @@ ALL_64_TARGET_OBS = \
@@ -670,6 +673,7 @@ ALL_64_TARGET_OBS = \
ia64-vms-tdep.o \
mips64-obsd-tdep.o \
sparc64-fbsd-tdep.o \
@ -36,15 +36,15 @@ index 17b71c6e7c..95e92d08b4 100644
sparc64-linux-tdep.o \
sparc64-nbsd-tdep.o \
sparc64-obsd-tdep.o \
@@ -670,6 +674,7 @@ ALL_TARGET_OBS = \
arch/arm-linux.o \
@@ -685,6 +689,7 @@ ALL_TARGET_OBS = \
arch/i386.o \
arch/ppc-linux-common.o \
arm-bsd-tdep.o \
+ arm-fbsd-kern.o \
arm-fbsd-tdep.o \
arm-linux-tdep.o \
arm-nbsd-tdep.o \
@@ -684,6 +689,8 @@ ALL_TARGET_OBS = \
@@ -699,6 +704,8 @@ ALL_TARGET_OBS = \
cris-linux-tdep.o \
cris-tdep.o \
dicos-tdep.o \
@ -53,7 +53,7 @@ index 17b71c6e7c..95e92d08b4 100644
fbsd-tdep.o \
frv-linux-tdep.o \
frv-tdep.o \
@@ -700,6 +707,7 @@ ALL_TARGET_OBS = \
@@ -715,6 +722,7 @@ ALL_TARGET_OBS = \
i386-darwin-tdep.o \
i386-dicos-tdep.o \
i386-fbsd-tdep.o \
@ -61,7 +61,7 @@ index 17b71c6e7c..95e92d08b4 100644
i386-gnu-tdep.o \
i386-go32-tdep.o \
i386-linux-tdep.o \
@@ -724,6 +732,7 @@ ALL_TARGET_OBS = \
@@ -738,6 +746,7 @@ ALL_TARGET_OBS = \
mep-tdep.o \
microblaze-linux-tdep.o \
microblaze-tdep.o \
@ -69,26 +69,26 @@ index 17b71c6e7c..95e92d08b4 100644
mips-fbsd-tdep.o \
mips-linux-tdep.o \
mips-nbsd-tdep.o \
@@ -741,6 +750,7 @@ ALL_TARGET_OBS = \
nto-tdep.o \
@@ -755,6 +764,7 @@ ALL_TARGET_OBS = \
obsd-tdep.o \
or1k-tdep.o \
ppc-fbsd-tdep.o \
+ ppcfbsd-kern.o \
ppc-linux-tdep.o \
ppc-nbsd-tdep.o \
ppc-obsd-tdep.o \
@@ -1610,7 +1620,7 @@ generated_files = \
@@ -1611,7 +1621,7 @@ generated_files = \
# Flags needed to compile Python code
PYTHON_CFLAGS = @PYTHON_CFLAGS@
-all: gdb$(EXEEXT) $(CONFIG_ALL)
+all: gdb$(EXEEXT) kgdb$(EXEEXT) $(CONFIG_ALL)
-all: gdb$(EXEEXT) $(CONFIG_ALL) gdb-gdb.py gdb-gdb.gdb
+all: gdb$(EXEEXT) kgdb$(EXEEXT) $(CONFIG_ALL) gdb-gdb.py gdb-gdb.gdb
@$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed 's/testsuite//'`" subdir_do
# Rule for compiling .c files in the top-level gdb directory.
@@ -1920,6 +1930,12 @@ gdb$(EXEEXT): gdb.o $(LIBGDB_OBS) $(ADD_DEPS) $(CDEPS) $(TDEPLIBS)
-o gdb$(EXEEXT) gdb.o $(LIBGDB_OBS) \
$(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES)
@@ -1924,6 +1934,12 @@ ifneq ($(CODESIGN_CERT),)
$(ECHO_SIGN) $(CODESIGN) -s $(CODESIGN_CERT) gdb$(EXEEXT)
endif
+kgdb$(EXEEXT): kgdb-main.o $(LIBGDB_OBS) $(ADD_DEPS) $(CDEPS) $(TDEPLIBS)
+ rm -f kgdb$(EXEEXT)
@ -99,16 +99,16 @@ index 17b71c6e7c..95e92d08b4 100644
# Convenience rule to handle recursion.
$(LIBGNU) $(GNULIB_H): all-lib
all-lib: $(GNULIB_BUILDDIR)/Makefile
@@ -1964,7 +1980,7 @@ clean mostlyclean: $(CONFIG_CLEAN)
@@ -1968,7 +1984,7 @@ clean mostlyclean: $(CONFIG_CLEAN)
@$(MAKE) $(FLAGS_TO_PASS) DO=clean "DODIRS=$(CLEANDIRS)" subdir_do
rm -f *.o *.a $(ADD_FILES) *~ init.c-tmp init.l-tmp version.c-tmp
rm -f init.c version.c observer.h observer.inc
rm -f init.c version.c
- rm -f gdb$(EXEEXT) core make.log
+ rm -f gdb$(EXEEXT) core make.log kgdb$(EXEEXT)
rm -f gdb[0-9]$(EXEEXT)
rm -f test-cp-name-parser$(EXEEXT)
rm -f xml-builtin.c stamp-xml
@@ -2178,6 +2194,7 @@ MAKEOVERRIDES =
@@ -2183,6 +2199,7 @@ MAKEOVERRIDES =
ALLDEPFILES = \
aarch64-fbsd-nat.c \
@ -116,7 +116,7 @@ index 17b71c6e7c..95e92d08b4 100644
aarch64-fbsd-tdep.c \
aarch64-linux-nat.c \
aarch64-linux-tdep.c \
@@ -2195,6 +2212,7 @@ ALLDEPFILES = \
@@ -2200,6 +2217,7 @@ ALLDEPFILES = \
amd64-bsd-nat.c \
amd64-darwin-tdep.c \
amd64-dicos-tdep.c \
@ -124,7 +124,7 @@ index 17b71c6e7c..95e92d08b4 100644
amd64-fbsd-nat.c \
amd64-fbsd-tdep.c \
amd64-linux-nat.c \
@@ -2209,6 +2227,7 @@ ALLDEPFILES = \
@@ -2214,6 +2232,7 @@ ALLDEPFILES = \
arc-tdep.c \
arm.c \
arm-bsd-tdep.c \
@ -132,7 +132,7 @@ index 17b71c6e7c..95e92d08b4 100644
arm-fbsd-nat.c \
arm-fbsd-tdep.c \
arm-get-next-pcs.c \
@@ -2228,6 +2247,9 @@ ALLDEPFILES = \
@@ -2233,6 +2252,9 @@ ALLDEPFILES = \
darwin-nat.c \
dicos-tdep.c \
exec.c \
@ -142,7 +142,7 @@ index 17b71c6e7c..95e92d08b4 100644
fbsd-nat.c \
fbsd-tdep.c \
fork-child.c \
@@ -2249,6 +2271,7 @@ ALLDEPFILES = \
@@ -2254,6 +2276,7 @@ ALLDEPFILES = \
i386-darwin-nat.c \
i386-darwin-tdep.c \
i386-dicos-tdep.c \
@ -150,7 +150,7 @@ index 17b71c6e7c..95e92d08b4 100644
i386-fbsd-nat.c \
i386-fbsd-tdep.c \
i386-gnu-nat.c \
@@ -2290,6 +2313,7 @@ ALLDEPFILES = \
@@ -2293,6 +2316,7 @@ ALLDEPFILES = \
mingw-hdep.c \
mips-fbsd-nat.c \
mips-fbsd-tdep.c \
@ -158,7 +158,7 @@ index 17b71c6e7c..95e92d08b4 100644
mips-linux-nat.c \
mips-linux-tdep.c \
mips-nbsd-nat.c \
@@ -2307,6 +2331,7 @@ ALLDEPFILES = \
@@ -2310,6 +2334,7 @@ ALLDEPFILES = \
obsd-nat.c \
obsd-tdep.c \
posix-hdep.c \
@ -166,7 +166,7 @@ index 17b71c6e7c..95e92d08b4 100644
ppc-fbsd-nat.c \
ppc-fbsd-tdep.c \
ppc-linux-nat.c \
@@ -2351,6 +2376,7 @@ ALLDEPFILES = \
@@ -2355,6 +2380,7 @@ ALLDEPFILES = \
sparc-sol2-nat.c \
sparc-sol2-tdep.c \
sparc-tdep.c \
@ -174,7 +174,7 @@ index 17b71c6e7c..95e92d08b4 100644
sparc64-fbsd-nat.c \
sparc64-fbsd-tdep.c \
sparc64-linux-nat.c \
@@ -2638,7 +2664,7 @@ endif
@@ -2643,7 +2669,7 @@ endif
# A list of all the objects we might care about in this build, for
# dependency tracking.
@ -184,10 +184,10 @@ index 17b71c6e7c..95e92d08b4 100644
# All the .deps files to include.
diff --git gdb/config.in gdb/config.in
index 1d11a97080..50a5a5b322 100644
index 527290296e..8e0e90fd67 100644
--- gdb/config.in
+++ gdb/config.in
@@ -222,6 +222,9 @@
@@ -228,6 +228,9 @@
/* Define to 1 if your system has the kinfo_getvmmap function. */
#undef HAVE_KINFO_GETVMMAP
@ -198,10 +198,10 @@ index 1d11a97080..50a5a5b322 100644
#undef HAVE_LANGINFO_CODESET
diff --git gdb/configure gdb/configure
index 84a0790c0d..f4c323d4ab 100755
index 3849b9494f..18d2e363dc 100755
--- gdb/configure
+++ gdb/configure
@@ -7927,6 +7927,66 @@ $as_echo "#define HAVE_KINFO_GETVMMAP 1" >>confdefs.h
@@ -8082,6 +8082,66 @@ $as_echo "#define HAVE_KINFO_GETFILE 1" >>confdefs.h
fi
@ -269,12 +269,12 @@ index 84a0790c0d..f4c323d4ab 100755
if test "X$prefix" = "XNONE"; then
acl_final_prefix="$ac_default_prefix"
diff --git gdb/configure.ac gdb/configure.ac
index d4133ea71e..bac85c53e0 100644
index 4c20ea5178..df156b484f 100644
--- gdb/configure.ac
+++ gdb/configure.ac
@@ -523,6 +523,11 @@ AC_SEARCH_LIBS(kinfo_getvmmap, util util-freebsd,
[AC_DEFINE(HAVE_KINFO_GETVMMAP, 1,
[Define to 1 if your system has the kinfo_getvmmap function. ])])
@@ -534,6 +534,11 @@ AC_SEARCH_LIBS(kinfo_getfile, util util-freebsd,
[AC_DEFINE(HAVE_KINFO_GETFILE, 1,
[Define to 1 if your system has the kinfo_getfile function. ])])
+# kgdb needs kvm_open2 for cross-debugging
+AC_SEARCH_LIBS(kvm_open2, kvm,
@ -285,7 +285,7 @@ index d4133ea71e..bac85c53e0 100644
# GDB may fork/exec the iconv program to get the list of supported character
diff --git gdb/configure.nat gdb/configure.nat
index 8e14892722..ada205f34d 100644
index 7611266d86..8656015365 100644
--- gdb/configure.nat
+++ gdb/configure.nat
@@ -62,7 +62,8 @@ case ${gdb_host} in
@ -299,10 +299,10 @@ index 8e14892722..ada205f34d 100644
LOADLIBES='-lkvm'
;;
diff --git gdb/configure.tgt gdb/configure.tgt
index fb8014a8e8..4bb43e366c 100644
index f197160896..ced1140328 100644
--- gdb/configure.tgt
+++ gdb/configure.tgt
@@ -92,7 +92,7 @@ esac
@@ -94,7 +94,7 @@ esac
case "${targ}" in
*-*-freebsd* | *-*-kfreebsd*-gnu)
@ -311,7 +311,7 @@ index fb8014a8e8..4bb43e366c 100644
*-*-netbsd* | *-*-knetbsd*-gnu)
os_obs="nbsd-tdep.o solib-svr4.o";;
*-*-openbsd*)
@@ -109,7 +109,7 @@ aarch64*-*-elf | aarch64*-*-rtems*)
@@ -111,7 +111,7 @@ aarch64*-*-elf | aarch64*-*-rtems*)
aarch64*-*-freebsd*)
# Target: FreeBSD/aarch64
@ -320,7 +320,7 @@ index fb8014a8e8..4bb43e366c 100644
;;
aarch64*-*-linux*)
@@ -162,7 +162,7 @@ arm*-*-linux*)
@@ -164,7 +164,7 @@ arm*-*-linux*)
;;
arm*-*-freebsd*)
# Target: FreeBSD/arm
@ -329,7 +329,7 @@ index fb8014a8e8..4bb43e366c 100644
;;
arm*-*-netbsd* | arm*-*-knetbsd*-gnu)
# Target: NetBSD/arm
@@ -249,7 +249,11 @@ i[34567]86-*-dicos*)
@@ -251,7 +251,11 @@ i[34567]86-*-dicos*)
;;
i[34567]86-*-freebsd* | i[34567]86-*-kfreebsd*-gnu)
# Target: FreeBSD/i386
@ -342,7 +342,7 @@ index fb8014a8e8..4bb43e366c 100644
;;
i[34567]86-*-netbsd* | i[34567]86-*-knetbsd*-gnu)
# Target: NetBSD/i386
@@ -408,7 +412,7 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu)
@@ -405,7 +409,7 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu)
;;
mips*-*-freebsd*)
# Target: MIPS running FreeBSD
@ -351,7 +351,7 @@ index fb8014a8e8..4bb43e366c 100644
gdb_sim=../sim/mips/libsim.a
;;
mips64*-*-openbsd*)
@@ -472,7 +476,7 @@ or1k-*-* | or1knd-*-*)
@@ -464,7 +468,7 @@ or1k-*-* | or1knd-*-*)
powerpc*-*-freebsd*)
# Target: FreeBSD/powerpc
gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc64-tdep.o \
@ -360,7 +360,7 @@ index fb8014a8e8..4bb43e366c 100644
ravenscar-thread.o ppc-ravenscar-thread.o"
;;
@@ -594,6 +598,7 @@ sparc64-*-linux*)
@@ -587,6 +591,7 @@ sparc64-*-linux*)
sparc*-*-freebsd* | sparc*-*-kfreebsd*-gnu)
# Target: FreeBSD/sparc64
gdb_target_obs="sparc-tdep.o sparc64-tdep.o sparc64-fbsd-tdep.o \
@ -368,7 +368,7 @@ index fb8014a8e8..4bb43e366c 100644
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc-*-netbsd* | sparc-*-knetbsd*-gnu)
@@ -716,8 +721,8 @@ x86_64-*-linux*)
@@ -709,8 +714,8 @@ x86_64-*-linux*)
;;
x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu)
# Target: FreeBSD/amd64
@ -380,10 +380,10 @@ index fb8014a8e8..4bb43e366c 100644
x86_64-*-mingw* | x86_64-*-cygwin*)
# Target: MingW/amd64
diff --git gdb/defs.h gdb/defs.h
index 4fb2129b30..0cb0bad5c5 100644
index fc4217005a..3d2eb6b1e9 100644
--- gdb/defs.h
+++ gdb/defs.h
@@ -516,6 +516,7 @@ enum gdb_osabi
@@ -481,6 +481,7 @@ enum gdb_osabi
GDB_OSABI_SOLARIS,
GDB_OSABI_LINUX,
GDB_OSABI_FREEBSD,
@ -392,10 +392,10 @@ index 4fb2129b30..0cb0bad5c5 100644
GDB_OSABI_OPENBSD,
GDB_OSABI_WINCE,
diff --git gdb/gnulib/configure gdb/gnulib/configure
index 37efd06b67..a23fc0a81c 100644
index a152abcb76..140c4ad6a8 100644
--- gdb/gnulib/configure
+++ gdb/gnulib/configure
@@ -16790,6 +16790,7 @@ else
@@ -17214,6 +17214,7 @@ else
case "$host_os" in
# Guess all is fine on glibc systems.
*-gnu*) gl_cv_func_gettimeofday_clobber="guessing no" ;;
@ -404,34 +404,33 @@ index 37efd06b67..a23fc0a81c 100644
*) gl_cv_func_gettimeofday_clobber="guessing yes" ;;
esac
diff --git gdb/osabi.c gdb/osabi.c
index 129164f51e..4eacc074a3 100644
index 7d0540b181..c61c518652 100644
--- gdb/osabi.c
+++ gdb/osabi.c
@@ -65,6 +65,7 @@ static const struct osabi_names gdb_osabi_names[] =
@@ -66,6 +66,7 @@ static const struct osabi_names gdb_osabi_names[] =
{ "Solaris", NULL },
{ "GNU/Linux", "linux(-gnu)?" },
{ "GNU/Linux", "linux(-gnu[^-]*)?" },
{ "FreeBSD", NULL },
+ { "FreeBSD/kernel", NULL },
{ "NetBSD", NULL },
{ "OpenBSD", NULL },
{ "WindowsCE", NULL },
diff --git gdb/regcache.c gdb/regcache.c
index fb6a904dec..f9b7105b8f 100644
index f3f845aad6..7ca007a422 100644
--- gdb/regcache.c
+++ gdb/regcache.c
@@ -1079,6 +1079,23 @@ regcache::raw_supply_zeroed (int regnum)
@@ -1035,6 +1035,22 @@ reg_buffer::raw_supply_zeroed (int regnum)
m_register_status[regnum] = REG_VALID;
}
+void
+regcache::raw_supply_unsigned (int regnum, ULONGEST val)
+reg_buffer::raw_supply_unsigned (int regnum, ULONGEST val)
+{
+ enum bfd_endian byte_order = gdbarch_byte_order (m_descr->gdbarch);
+ gdb_byte *regbuf;
+ size_t regsize;
+
+ assert_regnum (regnum);
+ gdb_assert (!m_readonly_p);
+
+ regbuf = register_buffer (regnum);
+ regsize = m_descr->sizeof_register[regnum];
@ -440,19 +439,19 @@ index fb6a904dec..f9b7105b8f 100644
+ m_register_status[regnum] = REG_VALID;
+}
+
/* Collect register REGNUM from REGCACHE and store its contents in BUF. */
/* See common/common-regcache.h. */
void
diff --git gdb/regcache.h gdb/regcache.h
index 9e3da8c3fc..5c65a9be1e 100644
index 4a45f33871..94f542c087 100644
--- gdb/regcache.h
+++ gdb/regcache.h
@@ -294,6 +294,8 @@ public:
void raw_supply_integer (int regnum, const gdb_byte *addr, int addr_len,
bool is_signed);
@@ -207,6 +207,8 @@ public:
only LEN, without editing the rest of the register. */
void raw_supply_part (int regnum, int offset, int len, const gdb_byte *in);
+ void raw_supply_unsigned (int regnum, ULONGEST val);
+
void raw_supply_zeroed (int regnum);
void invalidate (int regnum);
enum register_status get_register_status (int regnum) const;
virtual ~reg_buffer () = default;

View File

@ -231,7 +231,7 @@ amd64fbsd_kernel_init_abi(struct gdbarch_info info, struct gdbarch *gdbarch)
{
amd64_init_abi(info, gdbarch,
amd64_target_description (X86_XSTATE_SSE_MASK));
amd64_target_description (X86_XSTATE_SSE_MASK, true));
frame_unwind_prepend_unwinder(gdbarch, &amd64fbsd_trapframe_unwind);

View File

@ -139,7 +139,7 @@ find_kld_path (const char *filename, char *path, size_t path_size)
{
struct kld_info *info;
struct cleanup *cleanup;
char *module_path;
gdb::unique_xmalloc_ptr<char> module_path;
char *module_dir, *cp;
int error;
@ -157,17 +157,13 @@ find_kld_path (const char *filename, char *path, size_t path_size)
target_read_string(info->module_path_addr, &module_path,
PATH_MAX, &error);
if (error == 0) {
cleanup = make_cleanup(xfree, module_path);
cp = module_path;
cp = module_path.get();
while ((module_dir = strsep(&cp, ";")) != NULL) {
snprintf(path, path_size, "%s/%s", module_dir,
filename);
if (check_kld_path(path, path_size)) {
do_cleanups(cleanup);
if (check_kld_path(path, path_size))
return (1);
}
}
do_cleanups(cleanup);
}
}
return (0);
@ -200,7 +196,7 @@ find_kld_address (const char *arg, CORE_ADDR *address)
{
struct kld_info *info;
CORE_ADDR kld;
char *kld_filename;
gdb::unique_xmalloc_ptr<char> kld_filename;
const char *filename;
int error;
@ -219,11 +215,8 @@ find_kld_address (const char *arg, CORE_ADDR *address)
continue;
/* Compare this kld's filename against our passed in name. */
if (strcmp(kld_filename, filename) != 0) {
xfree(kld_filename);
if (strcmp(kld_filename.get(), filename) != 0)
continue;
}
xfree(kld_filename);
/*
* We found a match, use its address as the base
@ -259,7 +252,6 @@ adjust_section_address (struct target_section *sec, CORE_ADDR *curr_base)
static void
load_kld (char *path, CORE_ADDR base_addr, int from_tty)
{
struct section_addr_info *sap;
struct target_section *sections = NULL, *sections_end = NULL, *s;
struct cleanup *cleanup;
gdb_bfd_ref_ptr bfd;
@ -289,14 +281,14 @@ load_kld (char *path, CORE_ADDR base_addr, int from_tty)
adjust_section_address(s, &curr_addr);
/* Build a section addr info to pass to symbol_file_add(). */
sap = build_section_addr_info_from_section_table (sections,
sections_end);
make_cleanup((make_cleanup_ftype *)free_section_addr_info, sap);
section_addr_info sap
= build_section_addr_info_from_section_table (sections,
sections_end);
printf_unfiltered("add symbol table from file \"%s\" at\n", path);
for (i = 0; i < sap->num_sections; i++)
printf_unfiltered("\t%s_addr = %s\n", sap->other[i].name,
paddress(target_gdbarch(), sap->other[i].addr));
for (i = 0; i < sap.size(); i++)
printf_unfiltered("\t%s_addr = %s\n", sap[i].name.c_str(),
paddress(target_gdbarch(), sap[i].addr));
if (from_tty && (!query("%s", "")))
error("Not confirmed.");
@ -304,7 +296,7 @@ load_kld (char *path, CORE_ADDR base_addr, int from_tty)
add_flags = 0;
if (from_tty)
add_flags |= SYMFILE_VERBOSE;
symbol_file_add_from_bfd(bfd.get(), path, add_flags, sap,
symbol_file_add_from_bfd(bfd.get(), path, add_flags, &sap,
OBJF_USERLOADED, NULL);
do_cleanups(cleanup);
@ -436,7 +428,7 @@ kld_current_sos (void)
struct so_list *head, **prev, *newobj;
struct kld_info *info;
CORE_ADDR kld, kernel;
char *path;
gdb::unique_xmalloc_ptr<char> path;
int error;
info = get_kld_info();
@ -475,9 +467,8 @@ kld_current_sos (void)
free_so(newobj);
continue;
}
strlcpy(newobj->so_original_name, path,
strlcpy(newobj->so_original_name, path.get(),
sizeof(newobj->so_original_name));
xfree(path);
/*
* Try to read the pathname (if it exists) and store
@ -498,9 +489,8 @@ kld_current_sos (void)
strlcpy(newobj->so_name, newobj->so_original_name,
sizeof(newobj->so_name));
} else {
strlcpy(newobj->so_name, path,
strlcpy(newobj->so_name, path.get(),
sizeof(newobj->so_name));
xfree(path);
}
} else
strlcpy(newobj->so_name, newobj->so_original_name,
@ -540,19 +530,19 @@ kld_in_dynsym_resolve_code (CORE_ADDR pc)
static int
kld_find_and_open_solib (const char *solib, unsigned o_flags,
char **temp_pathname)
gdb::unique_xmalloc_ptr<char> *temp_pathname)
{
char path[PATH_MAX];
int fd;
*temp_pathname = NULL;
temp_pathname->reset (NULL);
if (!find_kld_path(solib, path, sizeof(path))) {
errno = ENOENT;
return (-1);
}
fd = open(path, o_flags, 0);
if (fd >= 0)
*temp_pathname = xstrdup(path);
temp_pathname->reset(xstrdup(path));
return (fd);
}

View File

@ -51,10 +51,7 @@ __FBSDID("$FreeBSD$");
static CORE_ADDR stoppcbs;
static LONGEST pcb_size;
static void kgdb_core_cleanup(void *);
static char *vmcore;
struct target_ops kgdb_trgt_ops;
/* Per-architecture data key. */
static struct gdbarch_data *fbsd_vmcore_data;
@ -105,7 +102,6 @@ fbsd_vmcore_set_cpu_pcb_addr (struct gdbarch *gdbarch,
static CORE_ADDR kernstart;
static kvm_t *kvm;
static char kvm_err[_POSIX2_LINE_MAX];
int kgdb_quiet;
static ptid_t
@ -116,14 +112,14 @@ fbsd_vmcore_ptid(int tid)
* The remote target stores the 'tid' in the lwp
* field.
*/
return ptid_build(ptid_get_pid(inferior_ptid), tid, 0);
return ptid_t(inferior_ptid.pid(), tid, 0);
/*
* This follows the model described in bsd-kvm.c except that
* in kernel tids are used as the tid of the ptid instead of a
* process ID.
*/
return ptid_build(1, 1, tid);
return ptid_t(1, 1, tid);
}
#define MSGBUF_SEQ_TO_POS(size, seq) ((seq) % (size))
@ -212,6 +208,49 @@ fbsd_kernel_osabi_sniffer(bfd *abfd)
return (GDB_OSABI_UNKNOWN);
}
/* The FreeBSD libkvm target. */
static const target_info fbsd_kvm_target_info = {
"vmcore",
N_("Kernel core dump file"),
N_("Use a vmcore file as a target.\n\
If no filename is specified, /dev/mem is used to examine the running kernel.\n\
target vmcore [-w] [filename]")
};
class fbsd_kvm_target final : public target_ops
{
public:
fbsd_kvm_target ()
{ this->to_stratum = process_stratum; }
const target_info &info () const override
{ return fbsd_kvm_target_info; }
void close () override;
void fetch_registers (struct regcache *, int) override;
enum target_xfer_status xfer_partial (enum target_object object,
const char *annex,
gdb_byte *readbuf,
const gdb_byte *writebuf,
ULONGEST offset, ULONGEST len,
ULONGEST *xfered_len) override;
void files_info () override;
bool thread_alive (ptid_t ptid) override;
void update_thread_list () override;
const char *pid_to_str (ptid_t) override;
const char *extra_thread_info (thread_info *) override;
bool has_memory () override { return true; }
bool has_stack () override { return true; }
bool has_registers () override { return true; }
};
/* Target ops for libkvm interface. */
static fbsd_kvm_target fbsd_kvm_ops;
#ifdef HAVE_KVM_OPEN2
static int
kgdb_resolve_symbol(const char *name, kvaddr_t *kva)
@ -227,10 +266,11 @@ kgdb_resolve_symbol(const char *name, kvaddr_t *kva)
#endif
static void
kgdb_trgt_open(const char *args, int from_tty)
fbsd_kvm_target_open (const char *args, int from_tty)
{
struct fbsd_vmcore_ops *ops = (struct fbsd_vmcore_ops *)
gdbarch_data (target_gdbarch(), fbsd_vmcore_data);
char kvm_err[_POSIX2_LINE_MAX];
struct inferior *inf;
struct cleanup *old_chain;
struct thread_info *ti;
@ -288,7 +328,7 @@ kgdb_trgt_open(const char *args, int from_tty)
/* Don't free the filename now and close any previous vmcore. */
discard_cleanups(old_chain);
unpush_target(&kgdb_trgt_ops);
unpush_target(&fbsd_kvm_ops);
/*
* Determine the first address in KVA. Newer kernels export
@ -331,10 +371,7 @@ kgdb_trgt_open(const char *args, int from_tty)
kvm = nkvm;
vmcore = filename;
old_chain = make_cleanup(kgdb_core_cleanup, NULL);
push_target (&kgdb_trgt_ops);
discard_cleanups (old_chain);
push_target (&fbsd_kvm_ops);
kgdb_dmesg();
@ -359,8 +396,8 @@ kgdb_trgt_open(const char *args, int from_tty)
print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
}
static void
kgdb_trgt_close(struct target_ops *self)
void
fbsd_kvm_target::close()
{
if (kvm != NULL) {
@ -376,13 +413,7 @@ kgdb_trgt_close(struct target_ops *self)
inferior_ptid = null_ptid;
}
static void
kgdb_core_cleanup(void *arg)
{
kgdb_trgt_close(0);
}
#if 0
static void
kgdb_trgt_detach(struct target_ops *ops, const char *args, int from_tty)
{
@ -394,16 +425,17 @@ kgdb_trgt_detach(struct target_ops *ops, const char *args, int from_tty)
if (from_tty)
printf_filtered("No vmcore file now.\n");
}
#endif
static const char *
kgdb_trgt_extra_thread_info(struct target_ops *ops, struct thread_info *ti)
const char *
fbsd_kvm_target::extra_thread_info(thread_info *ti)
{
return (kgdb_thr_extra_thread_info(ptid_get_tid(ti->ptid)));
return (kgdb_thr_extra_thread_info(ti->ptid.tid()));
}
static void
kgdb_trgt_files_info(struct target_ops *target)
void
fbsd_kvm_target::files_info()
{
printf_filtered ("\t`%s', ", vmcore);
@ -411,8 +443,8 @@ kgdb_trgt_files_info(struct target_ops *target)
printf_filtered ("file type %s.\n", "FreeBSD kernel vmcore");
}
static void
kgdb_trgt_update_thread_list(struct target_ops *ops)
void
fbsd_kvm_target::update_thread_list()
{
/*
* XXX: We should probably rescan the thread list here and update
@ -435,24 +467,23 @@ kgdb_trgt_update_thread_list(struct target_ops *ops)
#endif
}
static const char *
kgdb_trgt_pid_to_str(struct target_ops *ops, ptid_t ptid)
const char *
fbsd_kvm_target::pid_to_str(ptid_t ptid)
{
static char buf[33];
snprintf(buf, sizeof(buf), "Thread %ld", ptid_get_tid(ptid));
snprintf(buf, sizeof(buf), "Thread %ld", ptid.tid());
return (buf);
}
static int
kgdb_trgt_thread_alive(struct target_ops *ops, ptid_t ptid)
bool
fbsd_kvm_target::thread_alive(ptid_t ptid)
{
return (kgdb_thr_lookup_tid(ptid_get_tid(ptid)) != NULL);
return (kgdb_thr_lookup_tid(ptid.tid()) != NULL);
}
static void
kgdb_trgt_fetch_registers(struct target_ops *tops,
struct regcache *regcache, int regnum)
void
fbsd_kvm_target::fetch_registers(struct regcache *regcache, int regnum)
{
struct fbsd_vmcore_ops *ops = (struct fbsd_vmcore_ops *)
gdbarch_data (target_gdbarch(), fbsd_vmcore_data);
@ -460,14 +491,14 @@ kgdb_trgt_fetch_registers(struct target_ops *tops,
if (ops->supply_pcb == NULL)
return;
kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid));
kt = kgdb_thr_lookup_tid(inferior_ptid.tid());
if (kt == NULL)
return;
ops->supply_pcb(regcache, kt->pcb);
}
static enum target_xfer_status
kgdb_trgt_xfer_partial(struct target_ops *ops, enum target_object object,
enum target_xfer_status
fbsd_kvm_target::xfer_partial(enum target_object object,
const char *annex, gdb_byte *readbuf,
const gdb_byte *writebuf,
ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
@ -497,6 +528,7 @@ kgdb_trgt_xfer_partial(struct target_ops *ops, enum target_object object,
}
}
#if 0
static int
kgdb_trgt_insert_breakpoint(struct target_ops *ops, struct gdbarch *gdbarch,
struct bp_target_info *bp_tgt)
@ -512,6 +544,7 @@ kgdb_trgt_remove_breakpoint(struct target_ops *ops, struct gdbarch *gdbarch,
return 0;
}
#endif
static void
kgdb_switch_to_thread(const char *arg, int tid)
@ -570,42 +603,11 @@ kgdb_set_tid_cmd (const char *arg, int from_tty)
kgdb_switch_to_thread(arg, addr);
}
static int
kgdb_trgt_return_one(struct target_ops *ops)
{
return 1;
}
void
_initialize_kgdb_target(void)
{
kgdb_trgt_ops.to_magic = OPS_MAGIC;
kgdb_trgt_ops.to_shortname = "vmcore";
kgdb_trgt_ops.to_longname = "kernel core dump file";
kgdb_trgt_ops.to_doc = "Use a vmcore file as a target.\n\
If no filename is specified, /dev/mem is used to examine the running kernel.\n\
target vmcore [-w] [filename]";
kgdb_trgt_ops.to_stratum = process_stratum;
kgdb_trgt_ops.to_has_memory = kgdb_trgt_return_one;
kgdb_trgt_ops.to_has_registers = kgdb_trgt_return_one;
kgdb_trgt_ops.to_has_stack = kgdb_trgt_return_one;
kgdb_trgt_ops.to_open = kgdb_trgt_open;
kgdb_trgt_ops.to_close = kgdb_trgt_close;
kgdb_trgt_ops.to_detach = kgdb_trgt_detach;
kgdb_trgt_ops.to_extra_thread_info = kgdb_trgt_extra_thread_info;
kgdb_trgt_ops.to_fetch_registers = kgdb_trgt_fetch_registers;
kgdb_trgt_ops.to_files_info = kgdb_trgt_files_info;
kgdb_trgt_ops.to_update_thread_list = kgdb_trgt_update_thread_list;
kgdb_trgt_ops.to_pid_to_str = kgdb_trgt_pid_to_str;
kgdb_trgt_ops.to_thread_alive = kgdb_trgt_thread_alive;
kgdb_trgt_ops.to_xfer_partial = kgdb_trgt_xfer_partial;
kgdb_trgt_ops.to_insert_breakpoint = kgdb_trgt_insert_breakpoint;
kgdb_trgt_ops.to_remove_breakpoint = kgdb_trgt_remove_breakpoint;
add_target(&kgdb_trgt_ops);
add_target(fbsd_kvm_target_info, fbsd_kvm_target_open);
fbsd_vmcore_data = gdbarch_data_register_pre_init(fbsd_vmcore_init);

View File

@ -186,7 +186,7 @@ i386fbsd_fetch_tss(void)
struct segment_descriptor sd;
CORE_ADDR addr, cpu0prvpage, tss;
kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid));
kt = kgdb_thr_lookup_tid(inferior_ptid.tid());
if (kt == NULL || kt->cpu == NOCPU || kt->cpu < 0)
return (0);

View File

@ -50,7 +50,6 @@ __FBSDID("$FreeBSD$");
#include <cli-out.h>
#include <main.h>
#include <objfiles.h>
#include "observer.h"
#include <target.h>
#include <top.h>
#include <ui-file.h>

View File

@ -41,7 +41,6 @@ struct kthr {
extern struct kthr *curkthr;
extern struct target_so_ops kld_so_ops;
extern struct target_ops kgdb_trgt_ops;
extern int kgdb_quiet;
CORE_ADDR kgdb_trgt_stop_pcb(u_int);

View File

@ -1,19 +1,16 @@
--- gdb/configure.orig 2017-09-14 09:28:17 UTC
+++ gdb/configure
@@ -15292,13 +15292,10 @@ if test "${ERROR_ON_WARNING}" = yes ; then
WERROR_CFLAGS="-Werror"
fi
@@ -15467,10 +15467,10 @@ fi
-# The options we'll try to enable.
+# These options work in either C or C++ modes.
# The options we'll try to enable.
build_warnings="-Wall -Wpointer-arith \
--Wno-unused -Wunused-value -Wunused-function \
--Wno-switch -Wno-char-subscripts \
+-Wno-unused \
-Wno-switch -Wno-char-subscripts \
--Wempty-body -Wunused-but-set-parameter -Wunused-but-set-variable \
--Wno-sign-compare -Wno-narrowing -Wno-error=maybe-uninitialized \
--Wno-mismatched-tags"
+-Wno-unused -Wno-switch -Wno-char-subscripts \
+-Wempty-body -Wno-sign-compare -Wno-narrowing -Wno-mismatched-tags"
case "${host}" in
*-*-mingw32*)
+-Wempty-body \
+-Wno-sign-compare -Wno-narrowing \
-Wno-mismatched-tags \
-Wno-error=deprecated-register \
-Wsuggest-override \

View File

@ -1,11 +0,0 @@
--- gdb/corelow.c.orig 2017-07-29 11:06:52 UTC
+++ gdb/corelow.c
@@ -517,7 +517,7 @@ get_core_register_section (struct regcache *regcache,
bool variable_size_section = (regset != NULL
&& regset->flags & REGSET_VARIABLE_SIZE);
- thread_section_name section_name (name, regcache->ptid ());
+ thread_section_name section_name (name, regcache_get_ptid (regcache));
section = bfd_get_section_by_name (core_bfd, section_name.c_str ());
if (! section)

View File

@ -1,6 +1,6 @@
--- gdb/fbsd-nat.c.orig 2017-09-14 09:28:17 UTC
+++ gdb/fbsd-nat.c
@@ -682,6 +682,14 @@ fbsd_resume (struct target_ops *ops,
@@ -1108,6 +1108,14 @@ fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo)
struct thread_info *tp;
int request;
@ -14,4 +14,4 @@
+#endif
ALL_NON_EXITED_THREADS (tp)
{
if (ptid_get_pid (tp->ptid) != ptid_get_pid (ptid))
if (tp->ptid.pid () != ptid.pid ())

View File

@ -1,10 +1,27 @@
--- gdb/i386-fbsd-nat.c 2017-09-14 09:28:17 UTC
+++ gdb/i386-fbsd-nat.c
@@ -163,7 +163,6 @@ _initialize_i386fbsd_nat (void)
t->to_read_description = i386fbsd_read_description;
@@ -43,8 +43,6 @@ public:
const struct target_desc *read_description () override;
#endif
- t->to_resume = i386fbsd_resume;
fbsd_nat_add_target (t);
- void resume (ptid_t, int, enum gdb_signal) override;
-
#if defined(HAVE_PT_GETDBREGS) && defined(USE_SIGTRAP_SIGINFO)
bool supports_stopped_by_hw_breakpoint () override;
#endif
@@ -52,6 +50,7 @@ public:
/* Support debugging kernel virtual memory images. */
static i386_fbsd_nat_target the_i386_fbsd_nat_target;
+#if 0
/* Resume execution of the inferior process. If STEP is nonzero,
single-step it. If SIGNAL is nonzero, give it that signal. */
@@ -98,6 +97,7 @@ i386_fbsd_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signal)
gdb_signal_to_host (signal)) == -1)
perror_with_name (("ptrace"));
}
+#endif
/* Support for debugging kernel virtual memory images. */

View File

@ -3,7 +3,7 @@
@@ -59,6 +59,8 @@ for opt in opt_flags:
elif opt in ('--libs', '--ldflags'):
libs = []
libs = ['-lpython' + pyver + abiflags]
+ if getvar('LDFLAGS') is not None:
+ libs.extend(getvar('LDFLAGS').split())
if getvar('LIBS') is not None: