#include "bfd.h"
#include "symfile.h"
#include "objfiles.h"
+#include "target.h"
#include <sys/types.h>
#include <sys/time.h>
#include <sys/param.h>
-#include <connection.h>
-#include <genericreq.h>
-#include <debuggerreq.h>
-#include <debuggerconn.h>
-#include <ttyconn.h>
+#include "energize/connection.h"
+#include "energize/genericreq.h"
+#include "energize/debuggerreq.h"
+#include "energize/debuggerconn.h"
+#include "energize/ttyconn.h"
#include <varargs.h>
#include <sys/stat.h>
#ifdef USG
#include <sys/errno.h>
#include <termios.h>
#include <string.h>
+#ifdef NCR486
+#include <sys/stropts.h>
+#endif
/* Non-zero means that we're doing the energize interface. */
int energize = 0;
+/* Non-zero means we are reloading breakpoints, etc from the
+ Energize kernel, and we should suppress various messages */
+static int energize_reloading = 0;
+
/* Connection block for debugger<=>kernel communications. */
static Connection *conn = 0;
extern char *source_path;
-char **pprompt; /* Pointer to pointer to prompt */
+/* The name of the executable file */
+static char *exec_file;
/* Tell energize_command_line_input() where to get its text from */
static int doing_breakcommands_message = 0;
#define KERNEL_EVENT 1
#define PTY_EVENT 2
+static void execute_command_1();
+
\f
/* This routine redirects the output of fputs_filtered to the kernel so that
the user can see what's going on in his debugger window. */
if (cc == 0
|| (cc < 0
- && errno == EWOULDBLOCK))
+ && (errno == EWOULDBLOCK
+ || errno == EAGAIN)))
break;
if (cc < 0)
{
close(inferior_pty);
inferior_pty = -1;
- perror("pty read error");
+ perror("pty_to_kernel: pty read error");
break;
}
{
close(inferior_pty);
inferior_pty = -1;
- perror("pty write error");
+ perror("kernel_to_pty: pty write error");
return;
}
printf("Couldn't write all the data to the pty, wanted %d, got %d\n",
if (symtab->fullname)
return savestring(symtab->fullname, strlen(symtab->fullname));
+ if (symtab->filename[0] == '/')
+ return savestring(symtab->filename, strlen(symtab->filename));
+
if (symtab->dirname)
pathlen = strlen(symtab->dirname);
else
stack_info_valid = 1;
}
+/* Tell the Energize server about the file and line # that corresponds to pc,
+ and which stack frame level that pc corresponds to. */
+
+static void
+send_location(pc, frame_level)
+ CORE_ADDR pc;
+ int frame_level;
+{
+ char *funcname, *filename;
+ struct symtab_and_line sal;
+ struct symbol *symbol;
+
+ sal = find_pc_line(pc, 0);
+ symbol = find_pc_function(pc);
+
+ funcname = symbol ? symbol->name : "";
+ filename = full_filename(sal.symtab);
+
+ send_stack_info();
+
+ CVWriteStackFrameInfo(conn,
+ instance_id,
+ sal.line,
+ CFileLinePos,
+ frame_level,
+ funcname,
+ filename,
+ "" /* XXX ? transcript */
+ );
+ if (filename)
+ free(filename);
+}
+
/* Tell the kernel where we are in the program, and what the stack looks like.
*/
static void
send_status()
-{
- static int linecount = 48;
- struct symtab_and_line sal;
+{
+ char *funcname;
struct symbol *symbol;
- char *funcname, *filename;
static int sent_prog_inst = 0;
+ symbol = find_pc_function(stop_pc);
+ funcname = symbol ? symbol->name : "";
+
if (!has_run)
return;
return;
}
- sal = find_pc_line(stop_pc, 0);
- symbol = find_pc_function(stop_pc);
-
- funcname = symbol ? symbol->name : "";
- filename = full_filename(sal.symtab);
-
if (!sent_prog_inst)
{
sent_prog_inst = 1;
);
}
- send_stack_info();
-
- CVWriteStackFrameInfo(conn,
- instance_id,
- sal.line,
- CFileLinePos,
- 0, /* XXX - frame # */
- funcname,
- filename,
- "" /* XXX ? transcript */
- );
+ send_location(stop_pc,
+ selected_frame_level); /* Had better be 0! */
CVWriteProgramStoppedInfo(conn,
instance_id,
"" /* XXX ? transcript */
);
- if (filename)
- free(filename);
}
/* Call this to output annotated function names. Names will be demangled if
int arg_mode;
int level;
{
- extern int demangle;
char *demangled_name = NULL;
if (funcname == NULL)
demangled_name = cplus_demangle(funcname, arg_mode);
if (demangled_name)
- funcname = demangled_name;
+ {
+ funcname = demangled_name;
+ printf_filtered("'");
+ }
}
send_stack_info();
funcname);
if (demangled_name)
- free(demangled_name);
+ {
+ free(demangled_name);
+ printf_filtered("'");
+ }
}
/* Call this just prior to printing out the name & value of a variable. This
va_list args;
va_start(args);
-
echo = va_arg(args, int);
+
queue = va_arg(args, int);
cmd = va_arg(args, char *);
}
#ifdef KERNEL_RECORD
-FILE *kerout;
+GDB_FILE *kerout;
static int
kernel_record(fd, ptr, num)
char *filename;
char *included_in_filename = "";
- if (!energize)
+ if (!energize
+ || energize_reloading) /* Don't notify energize about breakpoint changes, as it's about to send us
+ a new bunch. */
return;
if (b->type != bp_breakpoint)
\f
/* Open up a pty and its associated tty. Return the fd of the tty. */
+#ifndef NCR486
static void
getpty()
{
continue;
sprintf(dev, "/dev/tty%c%x", n/16 + 'p', n%16);
ttyfd = open(dev, O_RDWR);
- if (ttyfd < 0) {close(ptyfd); continue;}
+ if (ttyfd < 0)
+ {
+ close(ptyfd);
+ continue;
+ }
/* Setup pty for non-blocking I/O. Also make it give us a SIGIO when
there's data available. */
error ("getpty: can't get a pty\n");
}
+#endif
+/* Alternate getpty for NCRs */
+
+#ifdef NCR486 /* LTL */
+#define MAX_PTM_TRY 16
+#define MAX_GRANTPT_TRY 4
+static void
+getpty()
+{
+ char *slavename;
+ extern char *ptsname();
+ int j, i;
+ int n, mfd, sfd;
+ struct stat statbuf;
+ struct termios termios;
+
+ mfd = open("/dev/ptmx", O_RDWR); /* get the master */
+ if (mfd < 0)
+ error ("getpty: can't locate master\n");
+
+ if (grantpt(mfd) < 0) /* get a slave */
+ error ("getpty: can't acquire slave");
+
+ unlockpt(mfd);
+
+ slavename = ptsname(mfd); /* get the slave device name */
+ if (!slavename)
+ error ("getpty: can't get a pts\n");
+
+ /* Drop controlling tty, become pgrp master */
+
+ if (setpgid(0, getppid()) == -1)
+ perror("setpgid() failed: ");
+
+ if (setsid() == -1)
+ perror("setsid() failed: ");
+
+ sfd = open(slavename, O_RDWR);
+ if (sfd < 0)
+ {
+ close(mfd);
+ error ("getpty: can't open slave\n");
+ }
+
+
+ if (ioctl(sfd, I_PUSH, "ptem")) perror ("getpty: ioctl I_PUSH fails");
+ if (ioctl(sfd, I_PUSH, "ldterm")) perror ("getpty: ioctl I_PUSH fails");
+
+ /* setup mty for non-blocking I/O. */
+
+ n = fcntl(mfd, F_GETFL);
+ if (n < 0)
+ perror ("getpty: fcntl F_GETFL failed");
+
+ if (fcntl(mfd, F_SETFL, n|O_NDELAY) <0)
+ perror("getpty: fcntl F_SETFL failed");
+
+ /* set up for async i/o - V.4 will send SIGPOLL when data available */
+
+ if (ioctl (mfd, I_SETSIG, S_INPUT|S_RDNORM) < 0)
+ perror ("getpty: ioctl I_SETSIG failed");
+
+ if (tcgetattr(sfd, &termios))
+ perror("getpty: tcgetattr fails");
+ termios.c_oflag &= ~OPOST; /* no post-processing */
+ if (tcsetattr(sfd, TCSANOW, &termios))
+ perror("getpty: tcsetattr fails");
+
+ inferior_pty=mfd;
+ inferior_tty=sfd;
+
+ return;
+}
+
+#endif /* NCR486 */
\f
/* Examine a protocol packet from the driver. */
}
break;
default:
- fprintf(stderr, "Unknown request type = %d\n",
+ fprintf(stderr, "Unknown Tty request type = %d\n",
req->head.reqType);
break;
}
}
break;
case StopRType:
- killpg(pgrp_inferior, SIGINT);
+ kill(-pgrp_inferior, SIGINT);
break;
case UserInputRType:
{
while (*text == ' ' || *text == '\t') text++;
- if (strcmp(text, "]*[") == 0) /* XXX - What does this mean??? */
+ if (STREQ(text, "]*[")) /* XXX - What does this mean??? */
break;
if (*text != '\000')
req->setValue.value.text);
}
break;
+ case DynamicLoadRType:
+ {
+ char *filename;
+
+ filename = req->dynamicLoad.filenames.byteLen ?
+ req->dynamicLoad.filenames.text : exec_file;
+
+ switch (req->dynamicLoad.request->action)
+ {
+ case CDynamicLoadUpdateSymtab:
+ energize_reloading = 1;
+ execute_command_1(1, queue, "set confirm no");
+ execute_command_1(1, queue, "delete");
+/* execute_command_1(1, queue, "set $bpnum=1");*/ /* Use this to reset breakpoint #s */
+ execute_command_1(1, queue, "exec-file %s", filename);
+ execute_command_1(1, queue, "symbol-file %s", filename);
+ execute_command_1(1, queue, "set confirm yes");
+ energize_reloading = 0;
+ break;
+ case CDynamicLoadRestoreStart:
+ break;
+ case CDynamicLoadRestoreEnd: /* Not used anymore??? */
+ printf_filtered("\n[Target has changed, automatic restoration of state has been done.]\n");
+ print_prompt();
+ break;
+ default:
+ printf_filtered("DynamicLoadRType: unknown action=%d, filename=%s\n",
+ req->dynamicLoad.request->action,
+ req->dynamicLoad.filenames.text);
+ break;
+ }
+ }
+ break;
default:
- fprintf(stderr, "Unknown request type = %d\n",
+ fprintf(stderr, "Unknown Debugger request type = %d\n",
req->head.request->reqType);
break;
}
do
{
FD_SET(kerfd, &readfds);
- if (inferior_pty > 0)
- FD_SET(inferior_pty, &readfds);
+
+ FD_SET(inferior_pty, &readfds);
+
if (poll)
numfds = select(sizeof(readfds)*8, &readfds, 0, 0, &tv);
else
}
while (numfds <= 0 && !poll);
+ if (numfds == 0)
+ return 0;
+
if (FD_ISSET(inferior_pty, &readfds))
eventmask |= PTY_EVENT;
if (!execarg) execarg = "";
+ exec_file = strdup(execarg); /* Save for later */
+
printf("\ngdb-debugger pid=%d\n", getpid()); /* XXX - debugging only */
/* First establish the connection with the kernel. */
/* Setup for I/O interrupts when appropriate. */
+ signal(SIGIO, SIG_IGN);
+
+#ifdef NCR486
+ if (ioctl (kerfd, I_SETSIG, S_INPUT|S_RDNORM) < 0)
+ perror ("getpty: ioctl I_SETSIG failed");
+#else
n = fcntl(kerfd, F_GETFL, 0);
fcntl(kerfd, F_SETFL, n|FASYNC);
- fcntl(kerfd, F_SETOWN, getpid());
+ fcntl(kerfd, F_SETOWN, getpid());
+#endif
/* Setup connection buffering. */
req = CWriteTtyRequest (conn, RunningProgramRType);
req->runningprogram.argc = 8;
- getwd (pathname);
+ getcwd (pathname, MAXPATHLEN);
CWriteVstring0 (conn, pathname);
CWriteVstring0 (conn, "0");
/* Tell the rest of the world that Energize is now set up. */
energize = 1;
- setsid(); /* Drop controlling tty, become pgrp master */
getpty(); /* Setup the pty */
- dup2(inferior_tty, 0); /* Attach all GDB I/O to the pty */
+
+ /* Attach all GDB I/O to the pty */
+
+ dup2(inferior_tty, 0);
dup2(inferior_tty, 1);
dup2(inferior_tty, 2);
}
else
(*cmdblk->function.cfunc)(arg, from_tty);
+ if (STREQ(cmdblk->name, "up")
+ || STREQ(cmdblk->name, "down")
+ || STREQ(cmdblk->name, "frame"))
+ send_location(get_frame_info(selected_frame)->pc,
+ selected_frame_level);
print_prompt();
}
int *status;
{
int pid;
+ struct sigaction action;
+ static sigset_t nullsigmask = {0};
+
+ if (!energize)
+ return target_wait(status);
+
+#ifdef NCR486
+ action.sa_handler = iosig;
+ action.sa_mask = nullsigmask;
+ action.sa_flags = SA_RESTART;
+ sigaction(SIGIO, &action, NULL);
+#else
+ signal(SIGIO, iosig);
+#endif
+
+ pid = target_wait(status);
+
+ signal(SIGIO, SIG_IGN);
+ return pid;
+}
+
+int
+energize_shell_wait(status)
+ int *status;
+{
+ int pid;
+ struct sigaction action;
+ static sigset_t nullsigmask = {0};
if (!energize)
return wait(status);
+#ifdef NCR486
+ action.sa_handler = iosig;
+ action.sa_mask = nullsigmask;
+ action.sa_flags = SA_RESTART;
+ sigaction(SIGIO, &action, NULL);
+#else
signal(SIGIO, iosig);
+#endif
pid = wait(status);
- signal(SIGIO, SIG_DFL);
+ signal(SIGIO, SIG_IGN);
return pid;
}