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)
415 char *demangled_name = NULL;
417 if (funcname == NULL)
422 demangled_name = cplus_demangle(funcname, arg_mode);
426 funcname = demangled_name;
427 printf_filtered("'");
433 if (level < 0) level = 0;
435 CVWriteBackTraceEntryInfo(conn,
442 free(demangled_name);
443 printf_filtered("'");
447 /* Call this just prior to printing out the name & value of a variable. This
448 tells the kernel where to annotate the output. */
451 expression - A text handle on what GDB can use to reference this value.
452 This can be a symbol name, or a convenience var, etc...
453 symbol - Used to determine the scope of the data. May be NULL.
454 type - Determines if we have a pointer ref, and the print name of the type.
455 Used in ShowValue message.
456 valaddr - The address in target memory of the data.
457 field - The field name of the struct or union element being referenced.
460 static char cum_expr[200]; /* Cumulative expression */
461 static char *expr_stack[100] = {cum_expr}; /* Pointers to end of expressions */
462 static char **last_expr = expr_stack; /* Current expr stack pointer */
465 energize_start_variable_annotation(expression, symbol, type, valaddr, field)
467 struct symbol *symbol;
474 enum type_code type_code;
475 enum address_class sym_class;
483 strcpy(*last_expr++, expression);
484 *last_expr = *(last_expr-1) + strlen(expression);
486 switch (TYPE_CODE(type))
488 case TYPE_CODE_ARRAY:
489 case TYPE_CODE_STRUCT:
490 case TYPE_CODE_UNION:
494 ref_type = CValueValueRef;
497 ref_type = CValuePointerRef;
500 ref_type = CValueUndefRef;
504 /* Make sure that pointer points at something we understand */
506 if (ref_type == CValuePointerRef)
507 switch (TYPE_CODE(TYPE_TARGET_TYPE(type)))
510 case TYPE_CODE_ARRAY:
511 case TYPE_CODE_STRUCT:
512 case TYPE_CODE_UNION:
518 ref_type = CValueUndefRef;
524 sym_class = SYMBOL_CLASS(symbol);
529 case LOC_CONST_BYTES:
530 stor_cl = CValueStorStaticConst;
533 stor_cl = CValueStorStaticVar;
537 stor_cl = CValueStorRegister;
543 stor_cl = CValueStorLocalVar;
546 stor_cl = CValueStorUndef;
551 stor_cl = CValueStorUndef;
553 type_cast = TYPE_NAME(type);
555 CVWriteValueBeginInfo(conn,
560 0, /* XXX - frameno */
564 ""); /* transcript */
568 energize_end_variable_annotation()
573 last_expr--; /* Pop the expr stack */
574 **last_expr = '\000'; /* Cut off the last part of the expr */
576 CVWriteValueEndInfo(conn,
578 ""); /* transcript */
581 /* Tell the kernel that the target is now running. */
586 CVWriteProgramBusyInfo(conn,
588 ""); /* XXX ? transcript */
589 CWriteRequestBuffer(conn); /* Must take place synchronusly! */
590 stack_info_valid = 0;
595 energize_symbol_file(objfile)
596 struct objfile *objfile;
601 CVWriteSymbolTableInfo(conn,
603 ""); /* Transcript */
606 /* execute_command_1(echo, queue, cmd, args) - echo - non-zero means echo the
607 command. queue - non-zero means don't execute it now, just save it away for
608 later. cmd - string containing printf control sequences. args - list of
609 arguments needed by those control sequences.
612 /* Linked list of queued up commands */
613 static struct command_line *queued_commands = 0;
614 static struct command_line *last_queued_command = 0;
616 /* Call this routine to save a command for later. The command string is
617 copied into freshly malloc'ed memory. */
624 struct command_line *cl;
627 s = (strlen(cmd) + 1) + 7 & ~(unsigned long)7;
629 buf = (char *)xmalloc(s + sizeof(struct command_line));
630 cl = (struct command_line *)(buf + s);
634 strncpy(cl->line, cmd, s);
637 last_queued_command->next = cl;
639 queued_commands = cl;
641 last_queued_command = cl;
644 /* Call this procedure to take a command off of the command queue. It returns
645 a pointer to a buf which the caller is responsible for freeing. NULL is
646 returned if there are no commands queued. */
651 struct command_line *cl;
654 cl = queued_commands;
659 queued_commands = cl->next;
665 execute_command_1(va_alist)
668 char buf[100]; /* XXX - make buf dynamic! */
676 echo = va_arg(args, int);
678 queue = va_arg(args, int);
679 cmd = va_arg(args, char *);
681 vsprintf(buf, cmd, args);
688 printf_filtered("%s\n", buf);
689 execute_command(buf, 1);
699 kernel_record(fd, ptr, num)
704 fwrite(ptr, num, 1, kerout);
706 return write(fd, ptr, num);
711 energize_condition_breakpoint(b)
712 struct breakpoint *b;
715 CVWriteBreakConditionInfo(conn,
718 b->cond_string ? b->cond_string : "",
724 energize_commands_breakpoint(b)
725 struct breakpoint *b;
727 struct command_line *l;
732 CVWriteBreakCommandBegInfo(conn,
735 ""); /* transcript */
737 for (l = b->commands; l; l = l->next)
738 CVWriteBreakCommandEntryInfo(conn,
741 ""); /* transcript */
743 CVWriteBreakCommandEndInfo(conn,
745 ""); /* transcript */
749 breakpoint_notify(b, action)
750 struct breakpoint *b;
756 char *included_in_filename = "";
759 || energize_reloading) /* Don't notify energize about breakpoint changes, as it's about to send us
763 if (b->type != bp_breakpoint)
766 filename = full_filename(b->symtab);
768 sym = find_pc_function(b->address);
770 funcname = SYMBOL_NAME(sym);
772 CVWriteBreakpointInfo (conn,
781 filename ? filename : "",
782 "", /* included_in_filename */
787 energize_commands_breakpoint(b);
789 energize_condition_breakpoint(b);
796 energize_create_breakpoint(b)
797 struct breakpoint *b;
799 breakpoint_notify(b, CEnableBreakpoint);
803 energize_delete_breakpoint(b)
804 struct breakpoint *b;
806 breakpoint_notify(b, CDeleteBreakpoint);
810 energize_enable_breakpoint(b)
811 struct breakpoint *b;
813 breakpoint_notify(b, CEnableBreakpoint);
817 energize_disable_breakpoint(b)
818 struct breakpoint *b;
820 breakpoint_notify(b, CDisableBreakpoint);
824 energize_ignore_breakpoint(b)
825 struct breakpoint *b;
827 breakpoint_notify(b, CBreakAttrUnchanged);
830 /* Open up a pty and its associated tty. Return the fd of the tty. */
839 struct termios termios;
841 #define HIGHPTY (('z' - 'p') * 16 - 1)
843 for (n = 0; n <= HIGHPTY; n++)
845 sprintf(dev, "/dev/pty%c%x", n/16 + 'p', n%16);
846 if (stat(dev, &statbuf))
848 ptyfd = open(dev, O_RDWR);
851 sprintf(dev, "/dev/tty%c%x", n/16 + 'p', n%16);
852 ttyfd = open(dev, O_RDWR);
859 /* Setup pty for non-blocking I/O. Also make it give us a SIGIO when
860 there's data available. */
862 n = fcntl(ptyfd, F_GETFL, 0);
863 fcntl(ptyfd, F_SETFL, n|FNDELAY|FASYNC);
864 fcntl(ptyfd, F_SETOWN, getpid());
866 tcgetattr(ttyfd, &termios);
867 termios.c_oflag &= ~OPOST; /* No post-processing */
868 tcsetattr(ttyfd, TCSANOW, &termios);
870 inferior_pty = ptyfd;
871 inferior_tty = ttyfd;
875 error ("getpty: can't get a pty\n");
878 /* Alternate getpty for NCRs */
880 #ifdef NCR486 /* LTL */
881 #define MAX_PTM_TRY 16
882 #define MAX_GRANTPT_TRY 4
887 extern char *ptsname();
891 struct termios termios;
893 mfd = open("/dev/ptmx", O_RDWR); /* get the master */
895 error ("getpty: can't locate master\n");
897 if (grantpt(mfd) < 0) /* get a slave */
898 error ("getpty: can't acquire slave");
902 slavename = ptsname(mfd); /* get the slave device name */
904 error ("getpty: can't get a pts\n");
906 /* Drop controlling tty, become pgrp master */
908 if (setpgid(0, getppid()) == -1)
909 perror("setpgid() failed: ");
912 perror("setsid() failed: ");
914 sfd = open(slavename, O_RDWR);
918 error ("getpty: can't open slave\n");
922 if (ioctl(sfd, I_PUSH, "ptem")) perror ("getpty: ioctl I_PUSH fails");
923 if (ioctl(sfd, I_PUSH, "ldterm")) perror ("getpty: ioctl I_PUSH fails");
925 /* setup mty for non-blocking I/O. */
927 n = fcntl(mfd, F_GETFL);
929 perror ("getpty: fcntl F_GETFL failed");
931 if (fcntl(mfd, F_SETFL, n|O_NDELAY) <0)
932 perror("getpty: fcntl F_SETFL failed");
934 /* set up for async i/o - V.4 will send SIGPOLL when data available */
936 if (ioctl (mfd, I_SETSIG, S_INPUT|S_RDNORM) < 0)
937 perror ("getpty: ioctl I_SETSIG failed");
939 if (tcgetattr(sfd, &termios))
940 perror("getpty: tcgetattr fails");
941 termios.c_oflag &= ~OPOST; /* no post-processing */
942 if (tcsetattr(sfd, TCSANOW, &termios))
943 perror("getpty: tcsetattr fails");
953 /* Examine a protocol packet from the driver. */
956 kernel_dispatch(queue)
957 int queue; /* Non-zero means we should just queue up
960 register CHeader *head;
962 head = (CHeader *)CPeekNextRequest (conn);
965 fprintf (stderr, "EOF on kernel read!\n");
969 if (head->reqType < LastTtyRequestRType)
971 CTtyRequest* req = CReadTtyRequest (conn);
972 switch (req->head.reqType)
974 case AcceptConnectionRType:
975 /* Tell the rest of the world that energize is now set up */
979 case RefuseConnectionRType:
980 fprintf (stderr, "Debugger connection refused\n");
983 case KillProgramRType:
991 p = CGetVstring(conn, &len);
992 kernel_to_pty(p, len);
996 fprintf(stderr, "Unknown Tty request type = %d\n",
1003 CVDebuggerRequest *req = CVReadDebuggerRequest (conn);
1006 fprintf (stderr, "CVReadDebuggerRequest returned NULL, type = %d\n",
1011 switch (req->head.request->reqType)
1013 case OpenProgramInstanceRType:
1015 char *arglist, buf[100]; /* XXX - Make buf dynamic! */
1017 /* XXX - should notice when program_id changes */
1018 arglist = req->openProgramInstance.progArglist.text;
1019 arglen = req->openProgramInstance.progArglist.byteLen;
1021 execute_command_1(1, queue, "break main");
1022 execute_command_1(1, queue, "enable delete $bpnum");
1025 execute_command_1(1, queue, "set args %.*s", arglen, arglist);
1027 execute_command_1(1, queue, "run");
1030 case SearchPathRType:
1031 directory_command(req->searchPath.searchPath.text, 0);
1033 case QuitDebuggerRType:
1034 execute_command_1(1, queue, "quit");
1037 if (req->run.request->useArglist == CNewArglist)
1039 execute_command_1(1, queue, "set args %.*s",
1040 req->run.progArglist.byteLen,
1041 req->run.progArglist.text);
1043 execute_command_1(1, queue, "run");
1046 execute_command_1(1, queue, "continue");
1049 execute_command_1(1, queue, "step %d", req->step.request->stepCount);
1052 execute_command_1(1, queue, "next %d", req->next.request->nextCount);
1054 case ChangeStackFrameRType:
1055 switch (req->changeStackFrame.request->frameMovement)
1057 case CToCurrentStackFrame:
1058 execute_command_1(1, queue, "frame %d",
1059 req->changeStackFrame.request->frameNo);
1061 case CToInnerStackFrame:
1062 execute_command_1(1, queue, "down %d",
1063 req->changeStackFrame.request->frameNo);
1065 case CToOuterStackFrame:
1066 execute_command_1(1, queue, "up %d",
1067 req->changeStackFrame.request->frameNo);
1069 case CToAbsoluteStackFrame:
1070 execute_command_1(1, queue, "frame %d",
1071 req->changeStackFrame.request->frameNo);
1075 case BackTraceRType:
1076 /* XXX - deal with limit??? */
1077 execute_command_1(1, queue, "backtrace");
1080 execute_command_1(1, queue, "finish");
1082 case TerminateProgramRType:
1083 execute_command_1(1, queue, "kill");
1085 case NewBreakpointRType:
1090 tail = strrchr(req->newBreakpoint.fileName.text, '/');
1092 tail = req->newBreakpoint.fileName.text;
1095 skipped = tail - req->newBreakpoint.fileName.text;
1096 execute_command_1(1, queue, "break %.*s:%d",
1097 req->newBreakpoint.fileName.byteLen - skipped,
1099 req->newBreakpoint.request->fileLinePos);
1103 kill(-pgrp_inferior, SIGINT);
1105 case UserInputRType:
1110 /* XXX - should really break command up into seperate lines
1111 and spoon-feed it to execute_command */
1113 text = req->userInput.userInput.text;
1114 len = req->userInput.userInput.byteLen;
1116 if (text[len-1] == '\n') text[len-1] = '\000';
1118 while (*text == ' ' || *text == '\t') text++;
1120 if (STREQ(text, "]*[")) /* XXX - What does this mean??? */
1123 if (*text != '\000')
1124 execute_command_1(0, queue, "%s", text);
1126 print_prompt(); /* User just typed a blank line */
1129 case QueryResponseRType:
1133 if (req->queryResponse.request->response)
1137 execute_command_1(1, 1, resp);
1138 printf_filtered("%s\n", resp);
1141 case ChangeBreakpointRType:
1142 switch (req->changeBreakpoint.request->breakpointAttr)
1144 case CBreakAttrUnchanged:
1145 execute_command_1(1, queue, "ignore %d %d",
1146 req->changeBreakpoint.request->breakpointId,
1147 req->changeBreakpoint.request->ignoreCount);
1149 case CEnableBreakpoint:
1150 execute_command_1(1, queue, "enable %d",
1151 req->changeBreakpoint.request->breakpointId);
1153 case CDisableBreakpoint:
1154 execute_command_1(1, queue, "disable %d",
1155 req->changeBreakpoint.request->breakpointId);
1157 case CDeleteBreakpoint:
1158 execute_command_1(1, queue, "delete %d",
1159 req->changeBreakpoint.request->breakpointId);
1161 case CEnableDisableBreakpoint:
1162 execute_command_1(1, queue, "enable once %d",
1163 req->changeBreakpoint.request->breakpointId);
1165 case CEnableDeleteBreakpoint:
1166 execute_command_1(1, queue, "enable delete %d",
1167 req->changeBreakpoint.request->breakpointId);
1170 printf_filtered("ChangeBreakpointRType: unknown breakpointAttr\n");
1171 printf_filtered(" breakpointAttr = %d\n",
1172 req->changeBreakpoint.request->breakpointAttr);
1173 printf_filtered(" breakpointId = %d\n",
1174 req->changeBreakpoint.request->breakpointId);
1175 printf_filtered(" breakpointType = %d\n",
1176 req->changeBreakpoint.request->breakpointType);
1177 printf_filtered(" ignoreCount = %d\n",
1178 req->changeBreakpoint.request->ignoreCount);
1182 case BreakConditionRType:
1183 execute_command_1(1, queue, "condition %d %.*s",
1184 req->breakCondition.request->breakpointId,
1185 req->breakCondition.condition.byteLen,
1186 req->breakCondition.condition.text);
1188 case BreakCommandsRType:
1189 /* Put pointers to where energize_command_line_input() can find
1191 doing_breakcommands_message = 1;
1192 command_line_length = req->breakCommands.commands.byteLen;
1193 command_line_text = req->breakCommands.commands.text;
1194 execute_command_1(1, queue, "commands %d",
1195 req->breakCommands.request->breakpointId);
1196 command_line_text = (char *)NULL;
1197 command_line_length = 0;
1198 doing_breakcommands_message = 0;
1200 case ShowValueRType:
1202 char expr[100], *p = expr;
1206 if (req->showValue.request->ref_type == CValuePointerRef)
1209 if (req->showValue.type_cast.byteLen)
1212 strncat(expr, req->showValue.type_cast.text,
1213 req->showValue.type_cast.byteLen);
1217 if (req->showValue.field.byteLen)
1220 strncat(expr, req->showValue.expression.text,
1221 req->showValue.expression.byteLen);
1223 if (req->showValue.field.byteLen)
1227 strncat(expr, req->showValue.field.text,
1228 req->showValue.field.byteLen);
1231 execute_command_1(1, queue, "print %s", expr);
1236 char expr[100], *p = expr;
1240 if (req->setValue.request->ref_type == CValuePointerRef)
1244 if (req->setValue.type_cast.byteLen)
1247 strncat(expr, req->setValue.type_cast.text,
1248 req->setValue.type_cast.byteLen);
1252 if (req->setValue.field.byteLen)
1255 strncat(expr, req->setValue.expression.text,
1256 req->setValue.expression.byteLen);
1258 if (req->setValue.field.byteLen)
1262 strncat(expr, req->setValue.field.text,
1263 req->setValue.field.byteLen);
1266 execute_command_1(1, queue, "print %s = (%s) %s", expr,
1267 req->setValue.type_cast.text,
1268 req->setValue.value.text);
1271 case DynamicLoadRType:
1275 filename = req->dynamicLoad.filenames.byteLen ?
1276 req->dynamicLoad.filenames.text : exec_file;
1278 switch (req->dynamicLoad.request->action)
1280 case CDynamicLoadUpdateSymtab:
1281 energize_reloading = 1;
1282 execute_command_1(1, queue, "set confirm no");
1283 execute_command_1(1, queue, "delete");
1284 /* execute_command_1(1, queue, "set $bpnum=1");*/ /* Use this to reset breakpoint #s */
1285 execute_command_1(1, queue, "exec-file %s", filename);
1286 execute_command_1(1, queue, "symbol-file %s", filename);
1287 execute_command_1(1, queue, "set confirm yes");
1288 energize_reloading = 0;
1290 case CDynamicLoadRestoreStart:
1292 case CDynamicLoadRestoreEnd: /* Not used anymore??? */
1293 printf_filtered("\n[Target has changed, automatic restoration of state has been done.]\n");
1297 printf_filtered("DynamicLoadRType: unknown action=%d, filename=%s\n",
1298 req->dynamicLoad.request->action,
1299 req->dynamicLoad.filenames.text);
1305 fprintf(stderr, "Unknown Debugger request type = %d\n",
1306 req->head.request->reqType);
1309 free (req); /* Should probably call CVFreeDebuggerRequest() here, but
1310 can't do so if interrupt level has mucked with req->
1311 request. CVFreeDebuggerRequest() only ends up calling
1316 /* Return a bitmask indicating if the kernel or the pty did something
1317 interesting. Set poll to non-zero if you don't want to wait. */
1320 wait_for_events(poll)
1326 static struct timeval tv = {0};
1328 /* Output all pending requests. */
1329 CWriteRequestBuffer(conn);
1333 /* Wait till there's some activity from the kernel or the pty. */
1336 FD_SET(kerfd, &readfds);
1338 FD_SET(inferior_pty, &readfds);
1341 numfds = select(sizeof(readfds)*8, &readfds, 0, 0, &tv);
1343 numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0);
1345 while (numfds <= 0 && !poll);
1350 if (FD_ISSET(inferior_pty, &readfds))
1351 eventmask |= PTY_EVENT;
1353 if (FD_ISSET(kerfd, &readfds))
1354 eventmask |= KERNEL_EVENT;
1359 /* This is called from read_command_lines() to provide the text for breakpoint
1360 commands, which is supplied in a BreakCommands message. Each call to this
1361 routine supplies a single line of text, with the newline removed. */
1363 /* This routine may be invoked in two different contexts. In the first, it
1364 is being called as a result of the BreakCommands message. In this case,
1365 all of the command text is immediately available. In the second case, it is
1366 called as a result of the user typing the 'command' command. The command
1367 text then needs to be glommed out of UserInput messages (and possibly other
1368 messages as well). The most 'straighforward' way of doing this is to
1369 basically simulate the main loop, but just accumulate the command text
1370 instead of sending it to execute_command(). */
1373 energize_command_line_input(prompt, repeat)
1380 return command_line_input(prompt, repeat);
1382 if (doing_breakcommands_message)
1384 if (command_line_length <= 0)
1385 return (char *)NULL;
1387 p = command_line_text;
1389 while (command_line_length-- > 0)
1391 if (*command_line_text == '\n')
1393 *command_line_text = '\000';
1394 command_line_text++;
1397 command_line_text++;
1400 printf_filtered("%s\n", p);
1405 /* We come here when the user has typed the 'command' or 'define' command
1406 to the GDB window. We are basically deep inside of the 'command'
1407 command processing routine right now, and will be called to get a new
1408 line of input. We expect that kernel_dispatch will queue up only one
1409 command at a time. */
1412 static char buf[100];
1414 eventmask = wait_for_events(0);
1416 if (eventmask & PTY_EVENT)
1419 if (eventmask & KERNEL_EVENT)
1420 kernel_dispatch(1); /* Queue up commands */
1422 /* Note that command has been echoed by the time we get here */
1424 p = dequeue_command();
1428 strncpy(buf, p, sizeof(buf));
1437 /* Establish contact with the kernel. */
1440 energize_initialize(energize_id, execarg)
1446 extern long strtol(char *str, char **ptr, int base);
1447 char pathname[MAXPATHLEN];
1453 if (!execarg) execarg = "";
1455 exec_file = strdup(execarg); /* Save for later */
1457 printf("\ngdb-debugger pid=%d\n", getpid()); /* XXX - debugging only */
1459 /* First establish the connection with the kernel. */
1461 kerfd = COpenClientSocket(NULL);
1463 printf("COpenClientSocket() failed\n");
1467 /* Setup for I/O interrupts when appropriate. */
1469 signal(SIGIO, SIG_IGN);
1472 if (ioctl (kerfd, I_SETSIG, S_INPUT|S_RDNORM) < 0)
1473 perror ("getpty: ioctl I_SETSIG failed");
1475 n = fcntl(kerfd, F_GETFL, 0);
1476 fcntl(kerfd, F_SETFL, n|FASYNC);
1477 fcntl(kerfd, F_SETOWN, getpid());
1480 /* Setup connection buffering. */
1482 CSetSocketBufferSize (kerfd, 12000);
1484 /* Generate a new connection control block. */
1486 conn = NewConnection (0, kerfd, kerfd);
1488 printf("NewConnection() failed\n");
1492 #ifdef KERNEL_RECORD
1493 kerout = fopen("kernel.output", "+w");
1495 CReadWriteHooks(conn, conn->previewMethod, conn->readMethod, kernel_record);
1498 /* Tell the kernel that we are the "debugger". */
1500 req = CWriteTtyRequest (conn, QueryConnectionRType);
1501 req->generic.queryconnection.major = 0;
1502 req->generic.queryconnection.minor = 0;
1503 req->generic.queryconnection.cadillacId1=strtol(energize_id, &ctmp, 16);
1504 req->generic.queryconnection.cadillacId2 = strtol(++ctmp, NULL, 16);
1505 req->generic.queryconnection.nProtocols = 1;
1506 CWriteProtocol (conn, 0, 0, "debugger");
1507 CWriteLength (conn);
1509 /* Tell the kernel that we are actually running. */
1511 /* KROCK ALERT!!! The kernel doesn't really care about the arguments to
1512 the program at all! It only cares that argument 7 be the name of the
1513 target program. So, we just fill in the rest of the slots with
1514 padding. I hope the kernel never cares about this! */
1516 req = CWriteTtyRequest (conn, RunningProgramRType);
1517 req->runningprogram.argc = 8;
1518 getcwd (pathname, MAXPATHLEN);
1519 CWriteVstring0 (conn, pathname);
1521 CWriteVstring0 (conn, "0");
1522 CWriteVstring0 (conn, "1");
1523 CWriteVstring0 (conn, "2");
1524 CWriteVstring0 (conn, "3");
1525 CWriteVstring0 (conn, "4");
1526 CWriteVstring0 (conn, "5");
1527 CWriteVstring0 (conn, "6");
1528 CWriteVstring0 (conn, execarg);
1529 CWriteLength (conn);
1531 /* Tell the kernel our PID and all that */
1534 CVWriteDebugProgramInfo(conn,
1540 /* Tell the rest of the world that Energize is now set up. */
1543 getpty(); /* Setup the pty */
1545 /* Attach all GDB I/O to the pty */
1547 dup2(inferior_tty, 0);
1548 dup2(inferior_tty, 1);
1549 dup2(inferior_tty, 2);
1552 /* This is called from execute_command, and provides a wrapper around
1553 various command routines in a place where both protocol messages and
1554 user input both flow through.
1558 energize_call_command(cmdblk, arg, from_tty)
1559 struct cmd_list_element *cmdblk;
1565 (*cmdblk->function.cfunc) (arg, from_tty);
1569 if (cmdblk->class == class_run)
1573 (*cmdblk->function.cfunc)(arg, from_tty);
1577 (*cmdblk->function.cfunc)(arg, from_tty);
1579 if (STREQ(cmdblk->name, "up")
1580 || STREQ(cmdblk->name, "down")
1581 || STREQ(cmdblk->name, "frame"))
1582 send_location(get_frame_info(selected_frame)->pc,
1583 selected_frame_level);
1588 energize_new_process()
1590 instance_id = inferior_pid;
1601 eventmask = wait_for_events(1);
1606 if (eventmask & PTY_EVENT)
1609 if (eventmask & KERNEL_EVENT)
1615 energize_wait(status)
1619 struct sigaction action;
1620 static sigset_t nullsigmask = {0};
1623 return target_wait(status);
1626 action.sa_handler = iosig;
1627 action.sa_mask = nullsigmask;
1628 action.sa_flags = SA_RESTART;
1629 sigaction(SIGIO, &action, NULL);
1631 signal(SIGIO, iosig);
1634 pid = target_wait(status);
1636 signal(SIGIO, SIG_IGN);
1641 energize_shell_wait(status)
1645 struct sigaction action;
1646 static sigset_t nullsigmask = {0};
1649 return wait(status);
1652 action.sa_handler = iosig;
1653 action.sa_mask = nullsigmask;
1654 action.sa_flags = SA_RESTART;
1655 sigaction(SIGIO, &action, NULL);
1657 signal(SIGIO, iosig);
1662 signal(SIGIO, SIG_IGN);
1672 /* All requests from the Energize kernel eventually end up here. */
1675 energize_main_loop()
1678 struct cleanup *old_chain;
1680 doing_breakcommands_message = 0;
1682 /* We will come thru here any time there is an error, so send status if
1689 /* The actual event loop! */
1696 old_chain = make_cleanup(null_routine, 0);
1698 /* First, empty out the command queue, then check for new requests. */
1700 while (cmd = dequeue_command())
1702 execute_command_1(1, 0, cmd);
1706 eventmask = wait_for_events(0);
1708 if (eventmask & PTY_EVENT)
1711 if (eventmask & KERNEL_EVENT)
1714 bpstat_do_actions(&stop_bpstat);
1715 do_cleanups(old_chain);