aboutsummaryrefslogtreecommitdiff
path: root/contrib/gdb
diff options
context:
space:
mode:
authorGary Jennejohn <gj@FreeBSD.org>1997-01-15 21:49:58 +0000
committerGary Jennejohn <gj@FreeBSD.org>1997-01-15 21:49:58 +0000
commit8a9a74a8875a7ed6853b3520da8d63112a2b0867 (patch)
tree57757f955f8a686cb09fffd0f1490a562483ed15 /contrib/gdb
parent649c409d03464841e3076cb812c938ce94d11cb8 (diff)
downloadsrc-8a9a74a8875a7ed6853b3520da8d63112a2b0867.tar.gz
src-8a9a74a8875a7ed6853b3520da8d63112a2b0867.zip
FreeBSD specific modifications.
Obtained from /usr/ports/devel/gdb. 2.2. candidate ? Should I put $FreeBSD$ into these files ?
Notes
Notes: svn path=/head/; revision=21738
Diffstat (limited to 'contrib/gdb')
-rw-r--r--contrib/gdb/gdb/core-aout.c16
-rw-r--r--contrib/gdb/gdb/i386b-nat.c50
-rw-r--r--contrib/gdb/gdb/remote.c205
-rw-r--r--contrib/gdb/gdb/target.c2
-rw-r--r--contrib/gdb/gdb/target.h1
5 files changed, 260 insertions, 14 deletions
diff --git a/contrib/gdb/gdb/core-aout.c b/contrib/gdb/gdb/core-aout.c
index 7103a9c8e135..3e834058c892 100644
--- a/contrib/gdb/gdb/core-aout.c
+++ b/contrib/gdb/gdb/core-aout.c
@@ -67,15 +67,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
static void
fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
- char *core_reg_sect;
- unsigned core_reg_size;
- int which;
- unsigned reg_addr;
+ char *core_reg_sect;
+ unsigned core_reg_size;
+ int which;
+ CORE_ADDR reg_addr;
{
register int regno;
- register unsigned int addr;
+ register CORE_ADDR addr;
int bad_reg = -1;
- register reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */
+ register CORE_ADDR reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */
int numregs = ARCH_NUM_REGS;
/* If u.u_ar0 was an absolute address in the core file, relativize it now,
@@ -84,7 +84,7 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
CORE_REGISTER_ADDR to offset to the other registers. If this is a modern
core file without a upage, reg_ptr will be zero and this is all a big
NOP. */
- if (reg_ptr > (int) core_reg_size)
+ if (reg_ptr > core_reg_size)
reg_ptr -= KERNEL_U_ADDR;
for (regno = 0; regno < numregs; regno++)
@@ -114,7 +114,7 @@ register_addr (regno, blockend)
int regno;
int blockend;
{
- int addr;
+ CORE_ADDR addr;
if (regno < 0 || regno >= ARCH_NUM_REGS)
error ("Invalid register number %d.", regno);
diff --git a/contrib/gdb/gdb/i386b-nat.c b/contrib/gdb/gdb/i386b-nat.c
index d273cabeeb3b..cefb99ffcb03 100644
--- a/contrib/gdb/gdb/i386b-nat.c
+++ b/contrib/gdb/gdb/i386b-nat.c
@@ -72,13 +72,32 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, ignore)
#include <machine/reg.h>
+/* Some systems don't provide all the registers on a trap. Use SS as a
+ default if so. */
+
+#ifndef tDS
+#define tDS tSS
+#endif
+#ifndef tES
+#define tES tSS
+#endif
+#ifndef tFS
+#define tFS tSS
+#endif
+#ifndef tGS
+#define tGS tSS
+#endif
+
+/* These tables map between the registers on a trap frame, and the register
+ order used by the rest of GDB. */
/* this table must line up with REGISTER_NAMES in tm-i386.h */
/* symbols like 'tEAX' come from <machine/reg.h> */
static int tregmap[] =
{
tEAX, tECX, tEDX, tEBX,
tESP, tEBP, tESI, tEDI,
- tEIP, tEFLAGS, tCS, tSS
+ tEIP, tEFLAGS, tCS, tSS,
+ tDS, tES, tFS, tGS
};
#ifdef sEAX
@@ -97,7 +116,8 @@ static int sregmap[] =
{
tEAX, tECX, tEDX, tEBX,
tESP, tEBP, tESI, tEDI,
- tEIP, tEFLAGS, tCS, tSS
+ tEIP, tEFLAGS, tCS, tSS,
+ tDS, tES, tFS, tGS
};
#endif /* No sEAX */
@@ -125,6 +145,7 @@ i386_register_u_addr (blockend, regnum)
#endif /* !FETCH_INFERIOR_REGISTERS */
#ifdef FLOAT_INFO
+#include "expression.h"
#include "language.h" /* for local_hex_string */
#include "floatformat.h"
@@ -195,7 +216,7 @@ print_387_status (status, ep)
}
print_387_control_word ((unsigned int)ep->control);
- printf_unfiltered ("last exception: ");
+ printf_unfiltered ("last instruction: ");
printf_unfiltered ("opcode %s; ", local_hex_string(ep->opcode));
printf_unfiltered ("pc %s:", local_hex_string(ep->code_seg));
printf_unfiltered ("%s; ", local_hex_string(ep->eip));
@@ -227,6 +248,7 @@ print_387_status (status, ep)
}
}
+void
i386_float_info ()
{
struct user u; /* just for address computations */
@@ -271,9 +293,15 @@ i386_float_info ()
skip = 0;
#endif
}
-
+
+#ifdef __FreeBSD__
+ fpstatep = (struct fpstate *)(buf + skip);
+ print_387_status (fpstatep->sv_ex_sw, (struct env387 *)fpstatep);
+#else
print_387_status (0, (struct env387 *)buf);
+#endif
}
+#endif /* FLOAT_INFO */
int
kernel_u_size ()
@@ -281,4 +309,16 @@ kernel_u_size ()
return (sizeof (struct user));
}
-#endif
+#ifdef SETUP_ARBITRARY_FRAME
+#include "frame.h"
+struct frame_info *
+setup_arbitrary_frame (argc, argv)
+ int argc;
+ CORE_ADDR *argv;
+{
+ if (argc != 2)
+ error ("i386 frame specifications require two arguments: sp and pc");
+
+ return create_new_frame (argv[0], argv[1]);
+}
+#endif /* SETUP_ARBITRARY_FRAME */
diff --git a/contrib/gdb/gdb/remote.c b/contrib/gdb/gdb/remote.c
index 5356e5e459b6..ab4ccf292c3c 100644
--- a/contrib/gdb/gdb/remote.c
+++ b/contrib/gdb/gdb/remote.c
@@ -313,6 +313,183 @@ serial_t remote_desc = NULL;
static int stub_supports_P = 1;
+/*
+ * Support for quasi-interactive control of device through GDB port.
+ * While we're waiting for an event to occur, chat with the running device.
+ */
+#define REMOTE_CHAT
+#ifdef REMOTE_CHAT
+
+extern int quit_flag;
+
+static char tty_input[256];
+static int escape_count;
+static int echo_check;
+static int remote_chat = 0;
+
+enum read_stat {
+ READ_MORE,
+ FATAL_ERROR,
+ ENTER_DEBUG
+};
+
+static enum read_stat
+readtarget()
+{
+ int j;
+ int data;
+
+ /* Loop until the socket doesn't have any more data */
+ while ((data = readchar(0)) >= 0) {
+
+ /* Check for the escape sequence */
+ if (data == '|') {
+ /* If this is the fourth escape, get out */
+ if (++escape_count == 4)
+ return (ENTER_DEBUG);
+ continue; /* Not the fourth, continue */
+
+ } else {
+ /*
+ * Not an escape any more, Ensure any pending ones are flushed
+ */
+ for (j = 1; j <= escape_count; j++)
+ putchar('|');
+ escape_count = 0;
+ }
+
+ if (data == '\r') /* If this is a return character */
+ continue; /* just supress it */
+
+ if (echo_check != -1) { /* If we are checking for an echo */
+ /* If this might be an echo */
+ if (tty_input[echo_check] == data) {
+ echo_check++; /* Note one more character match */
+ continue; /* Go and loop */
+ } else {
+
+ if ((data == '\n') && (tty_input[echo_check] == '\r')) {
+ /* If this is the end of the line */
+ echo_check = -1; /* No more echo supression */
+ continue; /* Go and loop */
+ }
+
+ /* Not an echo, print out the data */
+ for (j = 0; j < echo_check; j++)
+ putchar(tty_input[j]);
+
+ echo_check = -1;/* No more echo checking */
+ }
+ }
+ putchar(data); /* Output the character */
+ }
+ return (READ_MORE); /* Indicate to read some more */
+}
+
+static enum read_stat
+readtty()
+{
+ enum read_stat status;
+ int tty_bc;
+
+ /* First, read a buffer full from the terminal */
+ if ((tty_bc = read(fileno(stdin), tty_input, sizeof(tty_input) - 1)) < 0) {
+ perror_with_name("readtty: read failed");
+ return (FATAL_ERROR);
+ }
+
+ /* Turn trailing newlines into returns */
+ if (tty_input[tty_bc - 1] == '\n')
+ tty_input[tty_bc - 1] = '\r';
+
+ if ((tty_input[0] == '~') && (tty_bc == 3))
+ switch (tty_input[1]) {
+ case 'b': /* ~b\n = send break & gdb */
+ SERIAL_SEND_BREAK (remote_desc);
+ /* fall through */
+
+ case 'c': /* ~c\n = return to gdb */
+ return (ENTER_DEBUG);
+ }
+
+ /* Make this a zero terminated string and write it out */
+ tty_input[tty_bc] = '\0';
+
+ if (SERIAL_WRITE(remote_desc, tty_input, tty_bc)) {
+ perror_with_name("readtty: write failed");
+ return (FATAL_ERROR);
+ }
+
+ return (READ_MORE);
+}
+
+static int
+remote_talk()
+{
+ fd_set input;
+ int tablesize;
+ enum read_stat status;
+ int panic_flag = 0;
+ char buf[4];
+
+ escape_count = 0;
+ echo_check = -1;
+
+ tablesize = getdtablesize();
+
+ for (;;) {
+
+ /*
+ * Check for anything from our socket - doesn't block. Note that this
+ * must be done *before* the select as there may be buffered I/O
+ * waiting to be processed.
+ */
+ if ((status = readtarget()) != READ_MORE)
+ return (status);
+
+ fflush(stdout); /* Flush output before blocking */
+
+ /* Now block on more socket input or TTY input */
+ FD_ZERO(&input);
+ FD_SET(fileno(stdin), &input);
+ FD_SET(remote_desc->fd, &input);
+
+ status = select(tablesize, &input, 0, 0, 0);
+ if ((status < 0) && (errno != EINTR)) {
+ perror_with_name("remote_talk: select");
+ return (FATAL_ERROR);
+ }
+
+ /* Handle Control-C typed */
+ if (quit_flag) {
+ if ((++panic_flag) == 3) {
+ printf("\nAre you repeating Control-C to terminate "
+ "the session? (y/n) [n] ");
+ fgets(buf, 3, stdin);
+ if (buf[0] == 'y') {
+ pop_target(); /* Clean up */
+ error("Debugging terminated by user interrupt");
+ }
+ panic_flag = 0;
+ }
+ quit_flag = 0;
+ SERIAL_WRITE(remote_desc, "\003", 1);
+ continue;
+ }
+
+ /* Handle terminal input */
+ if (FD_ISSET(fileno(stdin), &input)) {
+ panic_flag = 0;
+ status = readtty();
+ if (status != READ_MORE)
+ return (status);
+ echo_check = 0;
+ }
+ }
+}
+
+#endif /* REMOTE_CHAT */
+
/* These are the threads which we last sent to the remote system. -1 for all
or -2 for not sent yet. */
int general_thread;
@@ -405,6 +582,11 @@ get_offsets ()
CORE_ADDR text_addr, data_addr, bss_addr;
struct section_offsets *offs;
+#ifdef REMOTE_CHAT
+ if (remote_chat)
+ (void) remote_talk();
+#endif /* REMOTE_CHAT */
+
putpkt ("qOffsets");
getpkt (buf, 0);
@@ -729,6 +911,11 @@ remote_wait (pid, status)
{
unsigned char *p;
+#ifdef REMOTE_CHAT
+ if (remote_chat)
+ (void) remote_talk();
+#endif /* REMOTE_CHAT */
+
ofunc = (void (*)()) signal (SIGINT, remote_interrupt);
getpkt ((char *) buf, 1);
signal (SIGINT, ofunc);
@@ -1401,6 +1588,16 @@ putpkt (buf)
getpkt (junkbuf, 0);
continue; /* Now, go look for + */
}
+
+#ifdef REMOTE_CHAT
+ case '|':
+ {
+ if (!started_error_output)
+ continue;
+ /* else fall through */
+ }
+#endif /* REMOTE_CHAT */
+
default:
if (remote_debug)
{
@@ -1836,4 +2033,12 @@ _initialize_remote ()
var_integer, (char *)&remote_break,
"Set whether to send break if interrupted.\n", &setlist),
&showlist);
+
+#ifdef REMOTE_CHAT
+ add_show_from_set (add_set_cmd ("remotechat", no_class,
+ var_zinteger, (char *)&remote_chat,
+ "Set remote port interacts with target.\n", &setlist),
+ &showlist);
+#endif /* REMOTE_CHAT */
}
+
diff --git a/contrib/gdb/gdb/target.c b/contrib/gdb/gdb/target.c
index fc0dfd9b22cc..fa7c167a6185 100644
--- a/contrib/gdb/gdb/target.c
+++ b/contrib/gdb/gdb/target.c
@@ -905,7 +905,7 @@ find_core_target ()
for (t = target_structs; t < target_structs + target_struct_size;
++t)
{
- if ((*t)->to_stratum == core_stratum)
+ if ((*t)->to_stratum == (kernel_debugging ? kcore_stratum : core_stratum))
{
runable = *t;
++count;
diff --git a/contrib/gdb/gdb/target.h b/contrib/gdb/gdb/target.h
index fa2291da9b71..209faebc5b8c 100644
--- a/contrib/gdb/gdb/target.h
+++ b/contrib/gdb/gdb/target.h
@@ -46,6 +46,7 @@ enum strata {
dummy_stratum, /* The lowest of the low */
file_stratum, /* Executable files, etc */
core_stratum, /* Core dump files */
+ kcore_stratum, /* Kernel core files */
download_stratum, /* Downloading of remote targets */
process_stratum /* Executing processes */
};