This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Patches for FreeBSD 4.2
- To: gdb-patches at sources dot redhat dot com
- Subject: Patches for FreeBSD 4.2
- From: Stu Grossman <grossman at juniper dot net>
- Date: Tue, 10 Jul 2001 23:39:04 -0700 (PDT)
Here is a set of patches that fixes a bunch of problems (and some testsuite
failures) for FreeBSD 4.2.
Stu
Index: gdb/ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/ChangeLog,v
retrieving revision 1.1410
diff -c -p -r1.1410 ChangeLog
*** ChangeLog 2001/07/04 21:14:05 1.1410
--- ChangeLog 2001/07/11 00:06:34
***************
*** 1,3 ****
--- 1,29 ----
+ 2001-07-10 Stu Grossman <grossman@juniper.net>
+
+ * Makefile.in (SUBDIR_MI_INITS): Add $(srcdir) to source file names for
+ old makes.
+ * i386-tdep.c (i386_store_return_value): Make sure that floats get
+ stored at the top of the FP stack.
+ * infrun.c (handle_inferior_event): Change the way stepping over
+ signals works. It's much more general, and works for systems that
+ don't use signal trampolines on entry.
+ * i386-freebsd-nat.c: New file to support FreeBSD specific stuff.
+ * config/i386/fbsd.mh (NATDEPFILES): Add i386-freebsd-nat.o.
+ * config/i386/nm-fbsd.h: Define CHILD_RESUME 'cuz FreeBSD can't use
+ the stock one.
+ * config/i386/tm-fbsd.h: Define FRAME_SAVED_PC to use FreeBSD specific
+ code to extract return PC from signal frames.
+ * Define FRAME_CHAIN_VALID to use func_frame_chain_valid, since ELF
+ doesn't generate N_TEXT object file markers.
+ * Remove SIGTRAMP_START and SIGTRAMP_END. Move all of that logic into
+ a FreeBSD specific function invoke via IN_SIGTRAMP.
+ * testsuite/gdb.base/completion.exp: Fix completion test of things
+ beginning with "a". FreeBSD's libc includes many things beginning with
+ "a", which confused the test. Fix various other completion tests as
+ well.
+ * testsuite/gdb.base/selftest.exp(backtrace through signal handler):
+ Update expected string to match current reality.
+
2001-07-04 Mark Kettenis <kettenis@gnu.org>
* i387-tdep.c (print_i387_value): Add extra space after final full
Index: gdb/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.91
diff -c -p -r1.91 Makefile.in
*** Makefile.in 2001/06/28 03:33:26 1.91
--- Makefile.in 2001/07/11 00:06:36
*************** SUBDIR_MI_SRCS = \
*** 170,176 ****
mi/mi-main.c mi/mi-parse.c mi/mi-getopt.c
SUBDIR_MI_DEPS =
SUBDIR_MI_INITS = \
! mi/mi-cmds.c mi/mi-parse.c mi/mi-main.c mi/mi-out.c
SUBDIR_MI_LDFLAGS=
SUBDIR_MI_CFLAGS= \
-DMI_OUT=1
--- 170,176 ----
mi/mi-main.c mi/mi-parse.c mi/mi-getopt.c
SUBDIR_MI_DEPS =
SUBDIR_MI_INITS = \
! $(srcdir)/mi/mi-cmds.c $(srcdir)/mi/mi-parse.c $(srcdir)/mi/mi-main.c $(srcdir)/mi/mi-out.c
SUBDIR_MI_LDFLAGS=
SUBDIR_MI_CFLAGS= \
-DMI_OUT=1
Index: gdb/i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.31
diff -c -p -r1.31 i386-tdep.c
*** i386-tdep.c 2001/05/09 16:16:33 1.31
--- i386-tdep.c 2001/07/11 00:06:36
*************** i386_store_return_value (struct type *ty
*** 861,871 ****
--- 861,885 ----
if (TYPE_CODE (type) == TYPE_CODE_FLT)
{
+ ULONGEST fstat;
+
if (NUM_FREGS == 0)
{
warning ("Cannot set floating-point return value.");
return;
}
+
+ /* According to the SVR4 x86 ABI, a returned FP value must be at the top
+ of the FP stack. So we force the FP stack pointer to make it look
+ like there is one item on the FP stack (at st(0)) which is where we
+ will store the return value. Failure to do this will result in great
+ weirdness due to uncaught FP stack overflows. */
+
+ fstat = read_register (FSTAT_REGNUM);
+ fstat |= 0x3800;
+ write_register (FSTAT_REGNUM, fstat);
+
+ write_register (FTAG_REGNUM, 0x3fff);
/* Floating-point return values can be found in %st(0). */
if (len == TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT
Index: gdb/infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.41
diff -c -p -r1.41 infrun.c
*** infrun.c 2001/06/28 21:48:41 1.41
--- infrun.c 2001/07/11 00:06:39
*************** handle_inferior_event (struct execution_
*** 2265,2304 ****
/* Clear the signal if it should not be passed. */
if (signal_program[stop_signal] == 0)
stop_signal = TARGET_SIGNAL_0;
!
! /* I'm not sure whether this needs to be check_sigtramp2 or
! whether it could/should be keep_going.
!
! This used to jump to step_over_function if we are stepping,
! which is wrong.
!
! Suppose the user does a `next' over a function call, and while
! that call is in progress, the inferior receives a signal for
! which GDB does not stop (i.e., signal_stop[SIG] is false). In
! that case, when we reach this point, there is already a
! step-resume breakpoint established, right where it should be:
! immediately after the function call the user is "next"-ing
! over. If we call step_over_function now, two bad things
! happen:
!
! - we'll create a new breakpoint, at wherever the current
! frame's return address happens to be. That could be
! anywhere, depending on what function call happens to be on
! the top of the stack at that point. Point is, it's probably
! not where we need it.
!
! - the existing step-resume breakpoint (which is at the correct
! address) will get orphaned: step_resume_breakpoint will point
! to the new breakpoint, and the old step-resume breakpoint
! will never be cleaned up.
!
! The old behavior was meant to help HP-UX single-step out of
! sigtramps. It would place the new breakpoint at prev_pc, which
! was certainly wrong. I don't know the details there, so fixing
! this probably breaks that. As with anything else, it's up to
! the HP-UX maintainer to furnish a fix that doesn't break other
! platforms. --JimB, 20 May 1999 */
! check_sigtramp2 (ecs);
keep_going (ecs);
return;
}
--- 2265,2294 ----
/* Clear the signal if it should not be passed. */
if (signal_program[stop_signal] == 0)
stop_signal = TARGET_SIGNAL_0;
! else
! {
! /* What is happening here is that the inferior is about to have a
! signal delivered. What we will do now is set a step_resume
! breakpoint at the current PC to allow the signal handler to run,
! and then keep on chugging along. */
!
! if (currently_stepping (ecs))
! {
! struct symtab_and_line sr_sal;
!
! INIT_SAL (&sr_sal); /* initialize to zeroes */
! sr_sal.pc = stop_pc;
! sr_sal.section = find_pc_overlay (sr_sal.pc);
! /* We perhaps could set the frame if we kept track of what the
! frame corresponding to prev_pc was. But we don't, so don't. */
! through_sigtramp_breakpoint =
! set_momentary_breakpoint (sr_sal, NULL, bp_through_sigtramp);
! insert_breakpoints ();
!
! ecs->remove_breakpoints_on_following_step = 1;
! ecs->another_trap = 1;
! }
! }
keep_going (ecs);
return;
}
Index: gdb/config/i386/fbsd.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/fbsd.mh,v
retrieving revision 1.7
diff -c -p -r1.7 fbsd.mh
*** fbsd.mh 2001/04/12 18:44:40 1.7
--- fbsd.mh 2001/07/11 00:06:41
***************
*** 1,6 ****
# Host: Intel 386 running FreeBSD
XDEPFILES=
# NOTE: Do not spread NATDEPFILES over several lines - it hurts BSD make.
! NATDEPFILES= fork-child.o infptrace.o inftarg.o solib.o solib-svr4.o solib-legacy.o corelow.o core-aout.o core-regset.o i387-nat.o i386bsd-nat.o i386-nat.o
XM_FILE= xm-fbsd.h
NAT_FILE= nm-fbsd.h
--- 1,6 ----
# Host: Intel 386 running FreeBSD
XDEPFILES=
# NOTE: Do not spread NATDEPFILES over several lines - it hurts BSD make.
! NATDEPFILES= fork-child.o infptrace.o inftarg.o solib.o solib-svr4.o solib-legacy.o corelow.o core-aout.o core-regset.o i387-nat.o i386bsd-nat.o i386-nat.o i386-freebsd-nat.o
XM_FILE= xm-fbsd.h
NAT_FILE= nm-fbsd.h
Index: gdb/config/i386/nm-fbsd.h
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/nm-fbsd.h,v
retrieving revision 1.4
diff -c -p -r1.4 nm-fbsd.h
*** nm-fbsd.h 2001/03/31 18:09:03 1.4
--- nm-fbsd.h 2001/07/11 00:06:42
***************
*** 28,33 ****
--- 28,36 ----
#include "i386/nm-i386.h"
+ /* Must use child_resume in i386-freebsd-nat.c to work around OS bug */
+ #define CHILD_RESUME
+
/* Provide access to the i386 hardware debugging registers. */
#define I386_DR_LOW_SET_CONTROL(control) \
Index: gdb/config/i386/tm-fbsd.h
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/tm-fbsd.h,v
retrieving revision 1.3
diff -c -p -r1.3 tm-fbsd.h
*** tm-fbsd.h 2001/03/06 08:21:28 1.3
--- tm-fbsd.h 2001/07/11 00:06:42
***************
*** 24,33 ****
--- 24,43 ----
#define HAVE_I387_REGS
#include "i386/tm-i386.h"
+ #undef FRAME_SAVED_PC
+ #define FRAME_SAVED_PC(FRAME) i386_freebsd_frame_saved_pc(FRAME)
+ CORE_ADDR i386_freebsd_frame_saved_pc(struct frame_info *frame);
+
+ /* Use the alternate method of determining valid frame chains. */
+
+ #define FRAME_CHAIN_VALID(fp,fi) func_frame_chain_valid (fp, fi)
+
/* FreeBSD uses the old gcc convention for struct returns. */
+ #if 0
#define USE_STRUCT_CONVENTION(gcc_p, type) \
generic_use_struct_convention (1, type)
+ #endif
/* Support for longjmp. */
*************** extern int get_longjmp_target (CORE_ADDR
*** 45,57 ****
/* Support for signal handlers. */
-
- /* The sigtramp is above the user stack and immediately below
- the user area. Using constants here allows for cross debugging.
- These are tested for FreeBSD 3.4. */
! #define SIGTRAMP_START(pc) 0xbfbfdf20
! #define SIGTRAMP_END(pc) 0xbfbfdff0
/* Offset to saved PC in sigcontext, from <sys/signal.h>. */
#define SIGCONTEXT_PC_OFFSET 20
--- 55,63 ----
/* Support for signal handlers. */
! extern int i386_freebsd_in_sigtramp (CORE_ADDR pc, char *name);
! #define IN_SIGTRAMP(PC, NAME) i386_freebsd_in_sigtramp (PC, NAME)
/* Offset to saved PC in sigcontext, from <sys/signal.h>. */
#define SIGCONTEXT_PC_OFFSET 20
Index: gdb/testsuite/gdb.base/completion.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/completion.exp,v
retrieving revision 1.4
diff -c -p -r1.4 completion.exp
*** completion.exp 2001/05/30 02:54:41 1.4
--- completion.exp 2001/07/11 00:06:46
*************** gdb_expect {
*** 349,368 ****
}
! send_gdb "p \"a\t"
sleep 1
gdb_expect {
! -re "^p \"a\\\x07$"\
{ send_gdb "\n"
gdb_expect {
-re "Unterminated string in expression\\..*$gdb_prompt $"\
! { pass "complete 'p a'"}
! -re ".*$gdb_prompt $" { fail "complete 'p a'"}
! timeout {fail "(timeout) complete 'p a'"}
}
}
! -re ".*$gdb_prompt $" { fail "complete 'p \"a'" }
! timeout { fail "(timeout) complete 'p \"a'" }
}
send_gdb "p 'a\t"
--- 349,370 ----
}
! set unlikely_word abracadubious
!
! send_gdb "p \"$unlikely_word\t"
sleep 1
gdb_expect {
! -re "^p \"$unlikely_word\\\x07$"\
{ send_gdb "\n"
gdb_expect {
-re "Unterminated string in expression\\..*$gdb_prompt $"\
! { pass "complete 'p $unlikely_word'"}
! -re ".*$gdb_prompt $" { fail "complete 'p $unlikely_word'"}
! timeout {fail "(timeout) complete 'p $unlikely_word'"}
}
}
! -re ".*$gdb_prompt $" { fail "complete 'p \"$unlikely_word'" }
! timeout { fail "(timeout) complete 'p \"$unlikely_word'" }
}
send_gdb "p 'a\t"
*************** gdb_expect {
*** 387,393 ****
-re "^p 'a\\\x07$" {
send_gdb "\t"
gdb_expect {
! -re "a64l.*argv.*$gdb_prompt p .a$" {
send_gdb "\n"
gdb_expect {
-re "Invalid character constant\\..*$gdb_prompt $" {
--- 389,395 ----
-re "^p 'a\\\x07$" {
send_gdb "\t"
gdb_expect {
! -re ".*argv.*$gdb_prompt p .a$" {
send_gdb "\n"
gdb_expect {
-re "Invalid character constant\\..*$gdb_prompt $" {
*************** gdb_expect {
*** 425,487 ****
}
! send_gdb "p b-a\t"
sleep 1
gdb_expect {
! -re "^p b-a\\\x07$"\
{ send_gdb "\n"
gdb_expect {
-re "No symbol \"b\" in current context\\..*$gdb_prompt $"\
! { pass "complete 'p b-a'"}
! -re ".*$gdb_prompt $" { fail "complete 'p b-a'"}
! timeout {fail "(timeout) complete 'p b-a'"}
}
}
! -re ".*$gdb_prompt $" { fail "complete 'p b-a'" }
! timeout { fail "(timeout) complete 'p b-a'" }
}
! send_gdb "p b-a\t"
sleep 1
gdb_expect {
! -re "^p b-a\\\x07$" {
send_gdb "\t"
gdb_expect {
! -re "a64l.*argv.*$gdb_prompt p b-a$" {
send_gdb "\n"
gdb_expect {
-re "No symbol \"b\" in current context\\..*$gdb_prompt $" {
! pass "complete (2) 'p b-a'"
}
! -re ".*$gdb_prompt $" { fail "complete (2) 'p b-a'" }
! timeout { fail "(timeout) complete (2) 'p b-a'" }
}
}
-re "(There are $decimal possibilities\\. Do you really\r\nwish to see them all.|Display all $decimal possibilities.) \\(y or n\\)$" {
send_gdb "n"
gdb_expect {
! -re "\\(gdb\\) p b-a$" {
send_gdb "\n"
gdb_expect {
-re "No symbol \"b\" in current context\\..*$gdb_prompt $" {
! pass "complete (2) 'p b-a'"
}
-re ".*$gdb_prompt $" {
! fail "complete (2) 'p b-a'"
}
! timeout { fail "(timeout) complete (2) 'p b-a'" }
}
}
! -re ".*$gdb_prompt $" { fail "complete (2) 'p b-a'" }
! timeout { fail "(timeout) complete (2) 'p b-a'" }
}
}
! -re ".*$gdb_prompt $" { fail "complete (2) 'p b-a'" }
! timeout { fail "(timeout) complete (2) 'p b-a'" }
}
}
! -re ".*$gdb_prompt $" { fail "complete (2) 'p b-a'" }
! timeout { fail "(timeout) complete (2) 'p b-a'" }
}
send_gdb "p b-\t"
--- 427,489 ----
}
! send_gdb "p b-marker\t"
sleep 1
gdb_expect {
! -re "^p b-marker\\\x07$"\
{ send_gdb "\n"
gdb_expect {
-re "No symbol \"b\" in current context\\..*$gdb_prompt $"\
! { pass "complete 'p b-marker'"}
! -re ".*$gdb_prompt $" { fail "complete 'p b-marker'"}
! timeout {fail "(timeout) complete 'p b-marker'"}
}
}
! -re ".*$gdb_prompt $" { fail "complete 'p b-marker'" }
! timeout { fail "(timeout) complete 'p b-marker'" }
}
! send_gdb "p b-marker\t"
sleep 1
gdb_expect {
! -re "^p b-marker\\\x07$" {
send_gdb "\t"
gdb_expect {
! -re "marker1 *marker2 *marker3 *marker4 *.*$gdb_prompt p b-marker$" {
send_gdb "\n"
gdb_expect {
-re "No symbol \"b\" in current context\\..*$gdb_prompt $" {
! pass "complete (2) 'p b-marker'"
}
! -re ".*$gdb_prompt $" { fail "complete (2) 'p b-marker'" }
! timeout { fail "(timeout) complete (2) 'p b-marker'" }
}
}
-re "(There are $decimal possibilities\\. Do you really\r\nwish to see them all.|Display all $decimal possibilities.) \\(y or n\\)$" {
send_gdb "n"
gdb_expect {
! -re "\\(gdb\\) p b-marker$" {
send_gdb "\n"
gdb_expect {
-re "No symbol \"b\" in current context\\..*$gdb_prompt $" {
! pass "complete (2) 'p b-marker'"
}
-re ".*$gdb_prompt $" {
! fail "complete (2) 'p b-marker'"
}
! timeout { fail "(timeout) complete (2) 'p b-marker'" }
}
}
! -re ".*$gdb_prompt $" { fail "complete (2) 'p b-marker'" }
! timeout { fail "(timeout) complete (2) 'p b-marker'" }
}
}
! -re ".*$gdb_prompt $" { fail "complete (2) 'p b-marker'" }
! timeout { fail "(timeout) complete (2) 'p b-marker'" }
}
}
! -re ".*$gdb_prompt $" { fail "complete (2) 'p b-marker'" }
! timeout { fail "(timeout) complete (2) 'p b-marker'" }
}
send_gdb "p b-\t"
Index: gdb/testsuite/gdb.base/selftest.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/selftest.exp,v
retrieving revision 1.2
diff -c -p -r1.2 selftest.exp
*** selftest.exp 2001/03/06 08:21:51 1.2
--- selftest.exp 2001/07/11 00:06:46
*************** GDB.*Copyright \[0-9\]+ Free Software Fo
*** 376,382 ****
set description "backtrace through signal handler"
send_gdb "backtrace\n"
gdb_expect {
! -re "#0.*read.*in main \\(.*\\) at .*main\\.c.*$gdb_prompt $" {
pass "$description"
}
-re ".*$gdb_prompt $" {
--- 376,382 ----
set description "backtrace through signal handler"
send_gdb "backtrace\n"
gdb_expect {
! -re "#0.*cli_command_loop.*in main \\(.*\\) at .*main\\.c.*$gdb_prompt $" {
pass "$description"
}
-re ".*$gdb_prompt $" {
Index: gdb/i386-freebsd-nat.c
===================================================================
diff -c -p empty i386-freebsd-nat.c
*** Tue Jul 10 17:24:02 2001
--- i386-freebsd-nat.c Tue Jul 10 13:40:10 2001
***************
*** 0 ****
--- 1,115 ----
+ /* Native-dependent code for FreeBSD Unix running on i386's, for GDB.
+ Copyright 2000 Free Software Foundation, Inc.
+
+ (This file is derived from i386b-nat.c.)
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+ #include "defs.h"
+ #include "gdbcore.h"
+ #include "frame.h"
+ #include "inferior.h"
+ #include <sys/param.h>
+ #include <sys/user.h>
+ #include <sys/exec.h>
+ #include <machine/sigframe.h>
+ #include <sys/ptrace.h>
+
+ /* Return the saved program counter for FRAME. */
+
+ CORE_ADDR
+ i386_freebsd_frame_saved_pc (struct frame_info *frame)
+ {
+ CORE_ADDR pc;
+
+ if (!frame->signal_handler_caller)
+ return read_memory_unsigned_integer (frame->frame + 4, 4);
+
+ if (frame->next)
+ return read_memory_unsigned_integer ((CORE_ADDR)&((struct sigframe *)(frame->next->frame + 8))->sf_uc.uc_mcontext.mc_eip, 4);
+ else
+ return 0;
+ }
+
+ int
+ i386_freebsd_in_sigtramp (CORE_ADDR pc, char *name)
+ {
+ return ((pc >= (CORE_ADDR)PS_STRINGS - 100)
+ && ((pc) < (CORE_ADDR)PS_STRINGS));
+ }
+
+ /* Resume execution of the inferior process.
+ If STEP is nonzero, single-step it.
+ If SIGNAL is nonzero, give it that signal. */
+
+ void
+ child_resume (ptid_t ptid, int step, enum target_signal signal)
+ {
+ int pid = PIDGET (ptid);
+
+ errno = 0;
+
+ if (pid == -1)
+ /* Resume all threads. */
+ /* I think this only gets used in the non-threaded case, where "resume
+ all threads" and "resume inferior_ptid" are the same. */
+ pid = PIDGET (inferior_ptid);
+
+ /* An address of (PTRACE_ARG3_TYPE)1 tells ptrace to continue from where
+ it was. (If GDB wanted it to start some other way, we have already
+ written a new PC value to the child.)
+
+ If this system does not support PT_STEP, a higher level function will
+ have called single_step() to transmute the step request into a
+ continue request (by setting breakpoints on all possible successor
+ instructions), so we don't have to worry about that here. */
+
+ if (step)
+ {
+ if (SOFTWARE_SINGLE_STEP_P ())
+ internal_error (__FILE__, __LINE__, "failed internal consistency check"); /* Make sure this doesn't happen. */
+ else
+ ptrace (PT_STEP, pid, (PTRACE_ARG3_TYPE) 1,
+ target_signal_to_host (signal));
+ }
+ else
+ {
+ unsigned int eflags;
+
+ /* Workaround for a bug in FreeBSD. Make sure that the trace flag is off
+ when doing a continue. There is a code path through the kernel which
+ can leaves the flag on by the time we get here. If a process has a
+ signal pending (such as SIGALRM) and we do a PT_STEP, the process
+ never really has a chance to run because the kernel needs to notify
+ the debugger that a signal is being sent. Therefore, the process
+ never goes through the kernel's trap() function which would normally
+ clear it. */
+
+ eflags = read_register (PS_REGNUM);
+ if (eflags & 0x100)
+ write_register (PS_REGNUM, eflags & ~0x100);
+
+ ptrace (PT_CONTINUE, pid, (PTRACE_ARG3_TYPE) 1,
+ target_signal_to_host (signal));
+ }
+
+ if (errno)
+ {
+ perror_with_name ("ptrace");
+ }
+ }