1 /* Energize (formerly known as Cadillac) interface routines.
2 Copyright 1991, 1992 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
28 #include <sys/types.h>
30 #include <sys/param.h>
31 #include "energize/connection.h"
32 #include "energize/genericreq.h"
33 #include "energize/debuggerreq.h"
34 #include "energize/debuggerconn.h"
35 #include "energize/ttyconn.h"
42 #include <sys/filio.h>
45 #include <sys/errno.h>
49 #include <sys/stropts.h>
52 /* Non-zero means that we're doing the energize interface. */
55 /* Non-zero means we are reloading breakpoints, etc from the
56 Energize kernel, and we should suppress various messages */
57 static int energize_reloading = 0;
59 /* Connection block for debugger<=>kernel communications. */
60 static Connection *conn = 0;
62 /* fd for our socket to the kernel. */
65 /* The kernel's ID for this instance of the program. */
66 static int program_id;
68 static int instance_id;
70 /* The fd for the pty associated with the inferior. */
71 static int inferior_pty = -1;
72 static int inferior_tty = -1;
74 static int has_run = 0;
76 extern int pgrp_inferior;
78 extern char *source_path;
80 /* The name of the executable file */
81 static char *exec_file;
83 /* Tell energize_command_line_input() where to get its text from */
84 static int doing_breakcommands_message = 0;
86 /* Stash command text here */
87 static char *command_line_text = 0;
88 static int command_line_length = 0;
90 /* Flags returned by wait_for_events() */
91 #define KERNEL_EVENT 1
94 static void execute_command_1();
97 /* This routine redirects the output of fputs_filtered to the kernel so that
98 the user can see what's going on in his debugger window. */
105 CVWriteTranscriptInfo (conn, instance_id, (char *)ptr);
111 energize_query(query, args)
120 vsprintf(buf, query, args);
122 CVWriteQueryInfo(conn,
127 ""); /* transcript */
131 energize_acknowledge_query(ack)
134 CVWriteQueryInfo(conn,
139 ""); /* transcript */
142 /* Copy all data from the pty to the kernel. */
153 cc = read(inferior_pty, buf, sizeof(buf));
157 && (errno == EWOULDBLOCK
158 || errno == EAGAIN)))
165 perror("pty_to_kernel: pty read error");
169 req = CWriteTtyRequest(conn, TextIORType);
170 CWriteVstringLen(conn, buf, cc);
173 CWriteRequestBuffer(conn);
176 /* Copy data from the kernel to the pty. */
179 kernel_to_pty(data, len)
185 cc = write(inferior_pty, data, len);
193 perror("kernel_to_pty: pty write error");
196 printf("Couldn't write all the data to the pty, wanted %d, got %d\n",
202 full_filename(symtab)
203 struct symtab *symtab;
211 if (symtab->fullname)
212 return savestring(symtab->fullname, strlen(symtab->fullname));
214 if (symtab->filename[0] == '/')
215 return savestring(symtab->filename, strlen(symtab->filename));
218 pathlen = strlen(symtab->dirname);
221 if (symtab->filename)
222 pathlen += strlen(symtab->filename);
224 filename = xmalloc(pathlen+1);
227 strcpy(filename, symtab->dirname);
230 if (symtab->filename)
231 strcat(filename, symtab->filename);
236 /* Tell the energize kernel how high the stack is so that frame numbers (which
237 are relative to the current stack height make sense.
239 Calculate the number of frames on the stack, and the number of subroutine
240 invocations that haven't changed since the last call to this routine. The
241 second number is calculated by comparing the PCs of the current stack frames
242 to the PCs of the previous set of stack frames. The screw here is that a
243 subroutine may call several different procedures, which means that the PC
244 in its frame changes, even though you are still in the same subroutine. We
245 resolve this by converting the frames PC into the PC at the start of the
246 function (for efficiency, this is done only if the simple comparison test
255 /* Non-zero means that Energize kernel already knows how high the stack is. */
256 static int stack_info_valid = 0;
261 struct pclist *pclist = 0, *pli, *opli;
262 static struct pclist *old_pclist;
266 if (stack_info_valid)
272 /* First, calculate the stack height, and build the new pclist */
274 for (frame = get_current_frame();
276 frame = get_prev_frame(frame))
279 pli = (struct pclist *)xmalloc(sizeof(struct pclist));
286 /* Now, figure out how much of the stack hasn't changed */
288 for (pli = pclist, opli = old_pclist;
289 pli != 0 && opli != 0;
290 pli = pli->next, opli = opli->next, (similar)++)
292 if ((pli->pc != opli->pc)
293 && (get_pc_function_start(pli->pc)
294 != get_pc_function_start(opli->pc)))
298 /* Free up all elements of the old pclist */
309 old_pclist = pclist; /* Install the new pclist */
311 CVWriteStackSizeInfo(conn,
313 height, /* Frame depth */
315 similar, /* Frame diff */
319 stack_info_valid = 1;
322 /* Tell the Energize server about the file and line # that corresponds to pc,
323 and which stack frame level that pc corresponds to. */
326 send_location(pc, frame_level)
330 char *funcname, *filename;
331 struct symtab_and_line sal;
332 struct symbol *symbol;
334 sal = find_pc_line(pc, 0);
335 symbol = find_pc_function(pc);
337 funcname = symbol ? symbol->name : "";
338 filename = full_filename(sal.symtab);
342 CVWriteStackFrameInfo(conn,
349 "" /* XXX ? transcript */
355 /* Tell the kernel where we are in the program, and what the stack looks like.
362 struct symbol *symbol;
363 static int sent_prog_inst = 0;
365 symbol = find_pc_function(stop_pc);
366 funcname = symbol ? symbol->name : "";
371 if (inferior_pid == 0) /* target has died */
373 CVWriteProgramTerminatedInfo(conn,
383 CVWriteProgramInstanceInfo(conn,
392 send_location(stop_pc,
393 selected_frame_level); /* Had better be 0! */
395 CVWriteProgramStoppedInfo(conn,
397 0, /* XXX - breakpoint # or signal # */
400 "" /* XXX ? transcript */
405 /* Call this to output annotated function names. Names will be demangled if
406 necessary. arg_mode contains flags that are passed on to cplus_demangle. */
409 energize_annotate_function(funcname, arg_mode, level)
414 char *demangled_name = NULL;
416 if (funcname == NULL)
421 demangled_name = cplus_demangle(funcname, arg_mode);
425 funcname = demangled_name;
426 printf_filtered("'");
432 if (level < 0) level = 0;
434 CVWriteBackTraceEntryInfo(conn,
441 free(demangled_name);
442 printf_filtered("'");
446 /* Call this just prior to printing out the name & value of a variable. This
447 tells the kernel where to annotate the output. */
450 expression - A text handle on what GDB can use to reference this value.
451 This can be a symbol name, or a convenience var, etc...
452 symbol - Used to determine the scope of the data. May be NULL.
453 type - Determines if we have a pointer ref, and the print name of the type.
454 Used in ShowValue message.
455 valaddr - The address in target memory of the data.
456 field - The field name of the struct or union element being referenced.
459 static char cum_expr[200]; /* Cumulative expression */
460 static char *expr_stack[100] = {cum_expr}; /* Pointers to end of expressions */
461 static char **last_expr = expr_stack; /* Current expr stack pointer */
464 energize_start_variable_annotation(expression, symbol, type, valaddr, field)
466 struct symbol *symbol;
473 enum type_code type_code;
474 enum address_class sym_class;
482 strcpy(*last_expr++, expression);
483 *last_expr = *(last_expr-1) + strlen(expression);
485 switch (TYPE_CODE(type))
487 case TYPE_CODE_ARRAY:
488 case TYPE_CODE_STRUCT:
489 case TYPE_CODE_UNION:
493 ref_type = CValueValueRef;
496 ref_type = CValuePointerRef;
499 ref_type = CValueUndefRef;
503 /* Make sure that pointer points at something we understand */
505 if (ref_type == CValuePointerRef)
506 switch (TYPE_CODE(TYPE_TARGET_TYPE(type)))
509 case TYPE_CODE_ARRAY:
510 case TYPE_CODE_STRUCT:
511 case TYPE_CODE_UNION:
517 ref_type = CValueUndefRef;
523 sym_class = SYMBOL_CLASS(symbol);
528 case LOC_CONST_BYTES:
529 stor_cl = CValueStorStaticConst;
532 stor_cl = CValueStorStaticVar;
536 stor_cl = CValueStorRegister;
542 stor_cl = CValueStorLocalVar;
545 stor_cl = CValueStorUndef;
550 stor_cl = CValueStorUndef;
552 type_cast = TYPE_NAME(type);
554 CVWriteValueBeginInfo(conn,
559 0, /* XXX - frameno */
563 ""); /* transcript */
567 energize_end_variable_annotation()
572 last_expr--; /* Pop the expr stack */
573 **last_expr = '\000'; /* Cut off the last part of the expr */
575 CVWriteValueEndInfo(conn,
577 ""); /* transcript */
580 /* Tell the kernel that the target is now running. */
585 CVWriteProgramBusyInfo(conn,
587 ""); /* XXX ? transcript */
588 CWriteRequestBuffer(conn); /* Must take place synchronusly! */
589 stack_info_valid = 0;
594 energize_symbol_file(objfile)
595 struct objfile *objfile;
600 CVWriteSymbolTableInfo(conn,
602 ""); /* Transcript */
605 /* execute_command_1(echo, queue, cmd, args) - echo - non-zero means echo the
606 command. queue - non-zero means don't execute it now, just save it away for
607 later. cmd - string containing printf control sequences. args - list of
608 arguments needed by those control sequences.
611 /* Linked list of queued up commands */
612 static struct command_line *queued_commands = 0;
613 static struct command_line *last_queued_command = 0;
615 /* Call this routine to save a command for later. The command string is
616 copied into freshly malloc'ed memory. */
623 struct command_line *cl;
626 s = (strlen(cmd) + 1) + 7 & ~(unsigned long)7;
628 buf = (char *)xmalloc(s + sizeof(struct command_line));
629 cl = (struct command_line *)(buf + s);
633 strncpy(cl->line, cmd, s);
636 last_queued_command->next = cl;
638 queued_commands = cl;
640 last_queued_command = cl;
643 /* Call this procedure to take a command off of the command queue. It returns
644 a pointer to a buf which the caller is responsible for freeing. NULL is
645 returned if there are no commands queued. */
650 struct command_line *cl;
653 cl = queued_commands;
658 queued_commands = cl->next;
664 execute_command_1(va_alist)
667 char buf[100]; /* XXX - make buf dynamic! */
675 echo = va_arg(args, int);
677 queue = va_arg(args, int);
678 cmd = va_arg(args, char *);
680 vsprintf(buf, cmd, args);
687 printf_filtered("%s\n", buf);
688 execute_command(buf, 1);
698 kernel_record(fd, ptr, num)
703 fwrite(ptr, num, 1, kerout);
705 return write(fd, ptr, num);
710 energize_condition_breakpoint(b)
711 struct breakpoint *b;
714 CVWriteBreakConditionInfo(conn,
717 b->cond_string ? b->cond_string : "",
723 energize_commands_breakpoint(b)
724 struct breakpoint *b;
726 struct command_line *l;
731 CVWriteBreakCommandBegInfo(conn,
734 ""); /* transcript */
736 for (l = b->commands; l; l = l->next)
737 CVWriteBreakCommandEntryInfo(conn,
740 ""); /* transcript */
742 CVWriteBreakCommandEndInfo(conn,
744 ""); /* transcript */
748 breakpoint_notify(b, action)
749 struct breakpoint *b;
755 char *included_in_filename = "";
758 || energize_reloading) /* Don't notify energize about breakpoint changes, as it's about to send us
762 if (b->type != bp_breakpoint)
765 filename = full_filename(b->symtab);
767 sym = find_pc_function(b->address);
769 funcname = SYMBOL_NAME(sym);
771 CVWriteBreakpointInfo (conn,
780 filename ? filename : "",
781 "", /* included_in_filename */
786 energize_commands_breakpoint(b);
788 energize_condition_breakpoint(b);
795 energize_create_breakpoint(b)
796 struct breakpoint *b;
798 breakpoint_notify(b, CEnableBreakpoint);
802 energize_delete_breakpoint(b)
803 struct breakpoint *b;
805 breakpoint_notify(b, CDeleteBreakpoint);
809 energize_enable_breakpoint(b)
810 struct breakpoint *b;
812 breakpoint_notify(b, CEnableBreakpoint);
816 energize_disable_breakpoint(b)
817 struct breakpoint *b;
819 breakpoint_notify(b, CDisableBreakpoint);
823 energize_ignore_breakpoint(b)
824 struct breakpoint *b;
826 breakpoint_notify(b, CBreakAttrUnchanged);
829 /* Open up a pty and its associated tty. Return the fd of the tty. */
838 struct termios termios;
840 #define HIGHPTY (('z' - 'p') * 16 - 1)
842 for (n = 0; n <= HIGHPTY; n++)
844 sprintf(dev, "/dev/pty%c%x", n/16 + 'p', n%16);
845 if (stat(dev, &statbuf))
847 ptyfd = open(dev, O_RDWR);
850 sprintf(dev, "/dev/tty%c%x", n/16 + 'p', n%16);
851 ttyfd = open(dev, O_RDWR);
858 /* Setup pty for non-blocking I/O. Also make it give us a SIGIO when
859 there's data available. */
861 n = fcntl(ptyfd, F_GETFL, 0);
862 fcntl(ptyfd, F_SETFL, n|FNDELAY|FASYNC);
863 fcntl(ptyfd, F_SETOWN, getpid());
865 tcgetattr(ttyfd, &termios);
866 termios.c_oflag &= ~OPOST; /* No post-processing */
867 tcsetattr(ttyfd, TCSANOW, &termios);
869 inferior_pty = ptyfd;
870 inferior_tty = ttyfd;
874 error ("getpty: can't get a pty\n");
877 /* Alternate getpty for NCRs */
879 #ifdef NCR486 /* LTL */
880 #define MAX_PTM_TRY 16
881 #define MAX_GRANTPT_TRY 4
886 extern char *ptsname();
890 struct termios termios;
892 mfd = open("/dev/ptmx", O_RDWR); /* get the master */
894 error ("getpty: can't locate master\n");
896 if (grantpt(mfd) < 0) /* get a slave */
897 error ("getpty: can't acquire slave");
901 slavename = ptsname(mfd); /* get the slave device name */
903 error ("getpty: can't get a pts\n");
905 /* Drop controlling tty, become pgrp master */
907 if (setpgid(0, getppid()) == -1)
908 perror("setpgid() failed: ");
911 perror("setsid() failed: ");
913 sfd = open(slavename, O_RDWR);
917 error ("getpty: can't open slave\n");
921 if (ioctl(sfd, I_PUSH, "ptem")) perror ("getpty: ioctl I_PUSH fails");
922 if (ioctl(sfd, I_PUSH, "ldterm")) perror ("getpty: ioctl I_PUSH fails");
924 /* setup mty for non-blocking I/O. */
926 n = fcntl(mfd, F_GETFL);
928 perror ("getpty: fcntl F_GETFL failed");
930 if (fcntl(mfd, F_SETFL, n|O_NDELAY) <0)
931 perror("getpty: fcntl F_SETFL failed");
933 /* set up for async i/o - V.4 will send SIGPOLL when data available */
935 if (ioctl (mfd, I_SETSIG, S_INPUT|S_RDNORM) < 0)
936 perror ("getpty: ioctl I_SETSIG failed");
938 if (tcgetattr(sfd, &termios))
939 perror("getpty: tcgetattr fails");
940 termios.c_oflag &= ~OPOST; /* no post-processing */
941 if (tcsetattr(sfd, TCSANOW, &termios))
942 perror("getpty: tcsetattr fails");
952 /* Examine a protocol packet from the driver. */
955 kernel_dispatch(queue)
956 int queue; /* Non-zero means we should just queue up
959 register CHeader *head;
961 head = (CHeader *)CPeekNextRequest (conn);
964 fprintf (stderr, "EOF on kernel read!\n");
968 if (head->reqType < LastTtyRequestRType)
970 CTtyRequest* req = CReadTtyRequest (conn);
971 switch (req->head.reqType)
973 case AcceptConnectionRType:
974 /* Tell the rest of the world that energize is now set up */
978 case RefuseConnectionRType:
979 fprintf (stderr, "Debugger connection refused\n");
982 case KillProgramRType:
990 p = CGetVstring(conn, &len);
991 kernel_to_pty(p, len);
995 fprintf(stderr, "Unknown Tty request type = %d\n",
1002 CVDebuggerRequest *req = CVReadDebuggerRequest (conn);
1005 fprintf (stderr, "CVReadDebuggerRequest returned NULL, type = %d\n",
1010 switch (req->head.request->reqType)
1012 case OpenProgramInstanceRType:
1014 char *arglist, buf[100]; /* XXX - Make buf dynamic! */
1016 /* XXX - should notice when program_id changes */
1017 arglist = req->openProgramInstance.progArglist.text;
1018 arglen = req->openProgramInstance.progArglist.byteLen;
1020 execute_command_1(1, queue, "break main");
1021 execute_command_1(1, queue, "enable delete $bpnum");
1024 execute_command_1(1, queue, "set args %.*s", arglen, arglist);
1026 execute_command_1(1, queue, "run");
1029 case SearchPathRType:
1030 directory_command(req->searchPath.searchPath.text, 0);
1032 case QuitDebuggerRType:
1033 execute_command_1(1, queue, "quit");
1036 if (req->run.request->useArglist == CNewArglist)
1038 execute_command_1(1, queue, "set args %.*s",
1039 req->run.progArglist.byteLen,
1040 req->run.progArglist.text);
1042 execute_command_1(1, queue, "run");
1045 execute_command_1(1, queue, "continue");
1048 execute_command_1(1, queue, "step %d", req->step.request->stepCount);
1051 execute_command_1(1, queue, "next %d", req->next.request->nextCount);
1053 case ChangeStackFrameRType:
1054 switch (req->changeStackFrame.request->frameMovement)
1056 case CToCurrentStackFrame:
1057 execute_command_1(1, queue, "frame %d",
1058 req->changeStackFrame.request->frameNo);
1060 case CToInnerStackFrame:
1061 execute_command_1(1, queue, "down %d",
1062 req->changeStackFrame.request->frameNo);
1064 case CToOuterStackFrame:
1065 execute_command_1(1, queue, "up %d",
1066 req->changeStackFrame.request->frameNo);
1068 case CToAbsoluteStackFrame:
1069 execute_command_1(1, queue, "frame %d",
1070 req->changeStackFrame.request->frameNo);
1074 case BackTraceRType:
1075 /* XXX - deal with limit??? */
1076 execute_command_1(1, queue, "backtrace");
1079 execute_command_1(1, queue, "finish");
1081 case TerminateProgramRType:
1082 execute_command_1(1, queue, "kill");
1084 case NewBreakpointRType:
1089 tail = strrchr(req->newBreakpoint.fileName.text, '/');
1091 tail = req->newBreakpoint.fileName.text;
1094 skipped = tail - req->newBreakpoint.fileName.text;
1095 execute_command_1(1, queue, "break %.*s:%d",
1096 req->newBreakpoint.fileName.byteLen - skipped,
1098 req->newBreakpoint.request->fileLinePos);
1102 kill(-pgrp_inferior, SIGINT);
1104 case UserInputRType:
1109 /* XXX - should really break command up into seperate lines
1110 and spoon-feed it to execute_command */
1112 text = req->userInput.userInput.text;
1113 len = req->userInput.userInput.byteLen;
1115 if (text[len-1] == '\n') text[len-1] = '\000';
1117 while (*text == ' ' || *text == '\t') text++;
1119 if (STREQ(text, "]*[")) /* XXX - What does this mean??? */
1122 if (*text != '\000')
1123 execute_command_1(0, queue, "%s", text);
1125 print_prompt(); /* User just typed a blank line */
1128 case QueryResponseRType:
1132 if (req->queryResponse.request->response)
1136 execute_command_1(1, 1, resp);
1137 printf_filtered("%s\n", resp);
1140 case ChangeBreakpointRType:
1141 switch (req->changeBreakpoint.request->breakpointAttr)
1143 case CBreakAttrUnchanged:
1144 execute_command_1(1, queue, "ignore %d %d",
1145 req->changeBreakpoint.request->breakpointId,
1146 req->changeBreakpoint.request->ignoreCount);
1148 case CEnableBreakpoint:
1149 execute_command_1(1, queue, "enable %d",
1150 req->changeBreakpoint.request->breakpointId);
1152 case CDisableBreakpoint:
1153 execute_command_1(1, queue, "disable %d",
1154 req->changeBreakpoint.request->breakpointId);
1156 case CDeleteBreakpoint:
1157 execute_command_1(1, queue, "delete %d",
1158 req->changeBreakpoint.request->breakpointId);
1160 case CEnableDisableBreakpoint:
1161 execute_command_1(1, queue, "enable once %d",
1162 req->changeBreakpoint.request->breakpointId);
1164 case CEnableDeleteBreakpoint:
1165 execute_command_1(1, queue, "enable delete %d",
1166 req->changeBreakpoint.request->breakpointId);
1169 printf_filtered("ChangeBreakpointRType: unknown breakpointAttr\n");
1170 printf_filtered(" breakpointAttr = %d\n",
1171 req->changeBreakpoint.request->breakpointAttr);
1172 printf_filtered(" breakpointId = %d\n",
1173 req->changeBreakpoint.request->breakpointId);
1174 printf_filtered(" breakpointType = %d\n",
1175 req->changeBreakpoint.request->breakpointType);
1176 printf_filtered(" ignoreCount = %d\n",
1177 req->changeBreakpoint.request->ignoreCount);
1181 case BreakConditionRType:
1182 execute_command_1(1, queue, "condition %d %.*s",
1183 req->breakCondition.request->breakpointId,
1184 req->breakCondition.condition.byteLen,
1185 req->breakCondition.condition.text);
1187 case BreakCommandsRType:
1188 /* Put pointers to where energize_command_line_input() can find
1190 doing_breakcommands_message = 1;
1191 command_line_length = req->breakCommands.commands.byteLen;
1192 command_line_text = req->breakCommands.commands.text;
1193 execute_command_1(1, queue, "commands %d",
1194 req->breakCommands.request->breakpointId);
1195 command_line_text = (char *)NULL;
1196 command_line_length = 0;
1197 doing_breakcommands_message = 0;
1199 case ShowValueRType:
1201 char expr[100], *p = expr;
1205 if (req->showValue.request->ref_type == CValuePointerRef)
1208 if (req->showValue.type_cast.byteLen)
1211 strncat(expr, req->showValue.type_cast.text,
1212 req->showValue.type_cast.byteLen);
1216 if (req->showValue.field.byteLen)
1219 strncat(expr, req->showValue.expression.text,
1220 req->showValue.expression.byteLen);
1222 if (req->showValue.field.byteLen)
1226 strncat(expr, req->showValue.field.text,
1227 req->showValue.field.byteLen);
1230 execute_command_1(1, queue, "print %s", expr);
1235 char expr[100], *p = expr;
1239 if (req->setValue.request->ref_type == CValuePointerRef)
1243 if (req->setValue.type_cast.byteLen)
1246 strncat(expr, req->setValue.type_cast.text,
1247 req->setValue.type_cast.byteLen);
1251 if (req->setValue.field.byteLen)
1254 strncat(expr, req->setValue.expression.text,
1255 req->setValue.expression.byteLen);
1257 if (req->setValue.field.byteLen)
1261 strncat(expr, req->setValue.field.text,
1262 req->setValue.field.byteLen);
1265 execute_command_1(1, queue, "print %s = (%s) %s", expr,
1266 req->setValue.type_cast.text,
1267 req->setValue.value.text);
1270 case DynamicLoadRType:
1274 filename = req->dynamicLoad.filenames.byteLen ?
1275 req->dynamicLoad.filenames.text : exec_file;
1277 switch (req->dynamicLoad.request->action)
1279 case CDynamicLoadUpdateSymtab:
1280 energize_reloading = 1;
1281 execute_command_1(1, queue, "set confirm no");
1282 execute_command_1(1, queue, "delete");
1283 /* execute_command_1(1, queue, "set $bpnum=1");*/ /* Use this to reset breakpoint #s */
1284 execute_command_1(1, queue, "exec-file %s", filename);
1285 execute_command_1(1, queue, "symbol-file %s", filename);
1286 execute_command_1(1, queue, "set confirm yes");
1287 energize_reloading = 0;
1289 case CDynamicLoadRestoreStart:
1291 case CDynamicLoadRestoreEnd: /* Not used anymore??? */
1292 printf_filtered("\n[Target has changed, automatic restoration of state has been done.]\n");
1296 printf_filtered("DynamicLoadRType: unknown action=%d, filename=%s\n",
1297 req->dynamicLoad.request->action,
1298 req->dynamicLoad.filenames.text);
1304 fprintf(stderr, "Unknown Debugger request type = %d\n",
1305 req->head.request->reqType);
1308 free (req); /* Should probably call CVFreeDebuggerRequest() here, but
1309 can't do so if interrupt level has mucked with req->
1310 request. CVFreeDebuggerRequest() only ends up calling
1315 /* Return a bitmask indicating if the kernel or the pty did something
1316 interesting. Set poll to non-zero if you don't want to wait. */
1319 wait_for_events(poll)
1325 static struct timeval tv = {0};
1327 /* Output all pending requests. */
1328 CWriteRequestBuffer(conn);
1332 /* Wait till there's some activity from the kernel or the pty. */
1335 FD_SET(kerfd, &readfds);
1337 FD_SET(inferior_pty, &readfds);
1340 numfds = select(sizeof(readfds)*8, &readfds, 0, 0, &tv);
1342 numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0);
1344 while (numfds <= 0 && !poll);
1349 if (FD_ISSET(inferior_pty, &readfds))
1350 eventmask |= PTY_EVENT;
1352 if (FD_ISSET(kerfd, &readfds))
1353 eventmask |= KERNEL_EVENT;
1358 /* This is called from read_command_lines() to provide the text for breakpoint
1359 commands, which is supplied in a BreakCommands message. Each call to this
1360 routine supplies a single line of text, with the newline removed. */
1362 /* This routine may be invoked in two different contexts. In the first, it
1363 is being called as a result of the BreakCommands message. In this case,
1364 all of the command text is immediately available. In the second case, it is
1365 called as a result of the user typing the 'command' command. The command
1366 text then needs to be glommed out of UserInput messages (and possibly other
1367 messages as well). The most 'straighforward' way of doing this is to
1368 basically simulate the main loop, but just accumulate the command text
1369 instead of sending it to execute_command(). */
1372 energize_command_line_input(prompt, repeat)
1379 return command_line_input(prompt, repeat);
1381 if (doing_breakcommands_message)
1383 if (command_line_length <= 0)
1384 return (char *)NULL;
1386 p = command_line_text;
1388 while (command_line_length-- > 0)
1390 if (*command_line_text == '\n')
1392 *command_line_text = '\000';
1393 command_line_text++;
1396 command_line_text++;
1399 printf_filtered("%s\n", p);
1404 /* We come here when the user has typed the 'command' or 'define' command
1405 to the GDB window. We are basically deep inside of the 'command'
1406 command processing routine right now, and will be called to get a new
1407 line of input. We expect that kernel_dispatch will queue up only one
1408 command at a time. */
1411 static char buf[100];
1413 eventmask = wait_for_events(0);
1415 if (eventmask & PTY_EVENT)
1418 if (eventmask & KERNEL_EVENT)
1419 kernel_dispatch(1); /* Queue up commands */
1421 /* Note that command has been echoed by the time we get here */
1423 p = dequeue_command();
1427 strncpy(buf, p, sizeof(buf));
1436 /* Establish contact with the kernel. */
1439 energize_initialize(energize_id, execarg)
1445 extern long strtol(char *str, char **ptr, int base);
1446 char pathname[MAXPATHLEN];
1452 if (!execarg) execarg = "";
1454 exec_file = strdup(execarg); /* Save for later */
1456 printf("\ngdb-debugger pid=%d\n", getpid()); /* XXX - debugging only */
1458 /* First establish the connection with the kernel. */
1460 kerfd = COpenClientSocket(NULL);
1462 printf("COpenClientSocket() failed\n");
1466 /* Setup for I/O interrupts when appropriate. */
1468 signal(SIGIO, SIG_IGN);
1471 if (ioctl (kerfd, I_SETSIG, S_INPUT|S_RDNORM) < 0)
1472 perror ("getpty: ioctl I_SETSIG failed");
1474 n = fcntl(kerfd, F_GETFL, 0);
1475 fcntl(kerfd, F_SETFL, n|FASYNC);
1476 fcntl(kerfd, F_SETOWN, getpid());
1479 /* Setup connection buffering. */
1481 CSetSocketBufferSize (kerfd, 12000);
1483 /* Generate a new connection control block. */
1485 conn = NewConnection (0, kerfd, kerfd);
1487 printf("NewConnection() failed\n");
1491 #ifdef KERNEL_RECORD
1492 kerout = fopen("kernel.output", "+w");
1494 CReadWriteHooks(conn, conn->previewMethod, conn->readMethod, kernel_record);
1497 /* Tell the kernel that we are the "debugger". */
1499 req = CWriteTtyRequest (conn, QueryConnectionRType);
1500 req->generic.queryconnection.major = 0;
1501 req->generic.queryconnection.minor = 0;
1502 req->generic.queryconnection.cadillacId1=strtol(energize_id, &ctmp, 16);
1503 req->generic.queryconnection.cadillacId2 = strtol(++ctmp, NULL, 16);
1504 req->generic.queryconnection.nProtocols = 1;
1505 CWriteProtocol (conn, 0, 0, "debugger");
1506 CWriteLength (conn);
1508 /* Tell the kernel that we are actually running. */
1510 /* KROCK ALERT!!! The kernel doesn't really care about the arguments to
1511 the program at all! It only cares that argument 7 be the name of the
1512 target program. So, we just fill in the rest of the slots with
1513 padding. I hope the kernel never cares about this! */
1515 req = CWriteTtyRequest (conn, RunningProgramRType);
1516 req->runningprogram.argc = 8;
1517 getcwd (pathname, MAXPATHLEN);
1518 CWriteVstring0 (conn, pathname);
1520 CWriteVstring0 (conn, "0");
1521 CWriteVstring0 (conn, "1");
1522 CWriteVstring0 (conn, "2");
1523 CWriteVstring0 (conn, "3");
1524 CWriteVstring0 (conn, "4");
1525 CWriteVstring0 (conn, "5");
1526 CWriteVstring0 (conn, "6");
1527 CWriteVstring0 (conn, execarg);
1528 CWriteLength (conn);
1530 /* Tell the kernel our PID and all that */
1533 CVWriteDebugProgramInfo(conn,
1539 /* Tell the rest of the world that Energize is now set up. */
1542 getpty(); /* Setup the pty */
1544 /* Attach all GDB I/O to the pty */
1546 dup2(inferior_tty, 0);
1547 dup2(inferior_tty, 1);
1548 dup2(inferior_tty, 2);
1551 /* This is called from execute_command, and provides a wrapper around
1552 various command routines in a place where both protocol messages and
1553 user input both flow through.
1557 energize_call_command(cmdblk, arg, from_tty)
1558 struct cmd_list_element *cmdblk;
1564 (*cmdblk->function.cfunc) (arg, from_tty);
1568 if (cmdblk->class == class_run)
1572 (*cmdblk->function.cfunc)(arg, from_tty);
1576 (*cmdblk->function.cfunc)(arg, from_tty);
1578 if (STREQ(cmdblk->name, "up")
1579 || STREQ(cmdblk->name, "down")
1580 || STREQ(cmdblk->name, "frame"))
1581 send_location(get_frame_info(selected_frame)->pc,
1582 selected_frame_level);
1587 energize_new_process()
1589 instance_id = inferior_pid;
1600 eventmask = wait_for_events(1);
1605 if (eventmask & PTY_EVENT)
1608 if (eventmask & KERNEL_EVENT)
1614 energize_wait(status)
1618 struct sigaction action;
1619 static sigset_t nullsigmask = {0};
1622 return target_wait(status);
1625 action.sa_handler = iosig;
1626 action.sa_mask = nullsigmask;
1627 action.sa_flags = SA_RESTART;
1628 sigaction(SIGIO, &action, NULL);
1630 signal(SIGIO, iosig);
1633 pid = target_wait(status);
1635 signal(SIGIO, SIG_IGN);
1640 energize_shell_wait(status)
1644 struct sigaction action;
1645 static sigset_t nullsigmask = {0};
1648 return wait(status);
1651 action.sa_handler = iosig;
1652 action.sa_mask = nullsigmask;
1653 action.sa_flags = SA_RESTART;
1654 sigaction(SIGIO, &action, NULL);
1656 signal(SIGIO, iosig);
1661 signal(SIGIO, SIG_IGN);
1671 /* All requests from the Energize kernel eventually end up here. */
1674 energize_main_loop()
1677 struct cleanup *old_chain;
1679 doing_breakcommands_message = 0;
1681 /* We will come thru here any time there is an error, so send status if
1688 /* The actual event loop! */
1695 old_chain = make_cleanup(null_routine, 0);
1697 /* First, empty out the command queue, then check for new requests. */
1699 while (cmd = dequeue_command())
1701 execute_command_1(1, 0, cmd);
1705 eventmask = wait_for_events(0);
1707 if (eventmask & PTY_EVENT)
1710 if (eventmask & KERNEL_EVENT)
1713 bpstat_do_actions(&stop_bpstat);
1714 do_cleanups(old_chain);