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. */
27 #include <sys/types.h>
29 #include <sys/param.h>
30 #include "energize/connection.h"
31 #include "energize/genericreq.h"
32 #include "energize/debuggerreq.h"
33 #include "energize/debuggerconn.h"
34 #include "energize/ttyconn.h"
41 #include <sys/filio.h>
44 #include <sys/errno.h>
48 /* Non-zero means that we're doing the energize interface. */
51 /* Connection block for debugger<=>kernel communications. */
52 static Connection *conn = 0;
54 /* fd for our socket to the kernel. */
57 /* The kernel's ID for this instance of the program. */
58 static int program_id;
60 static int instance_id;
62 /* The fd for the pty associated with the inferior. */
63 static int inferior_pty = -1;
64 static int inferior_tty = -1;
66 static int has_run = 0;
68 extern int pgrp_inferior;
70 extern char *source_path;
72 /* The name of the executable file */
73 static char *exec_file;
75 /* Tell energize_command_line_input() where to get its text from */
76 static int doing_breakcommands_message = 0;
78 /* Stash command text here */
79 static char *command_line_text = 0;
80 static int command_line_length = 0;
82 /* Flags returned by wait_for_events() */
83 #define KERNEL_EVENT 1
87 /* This routine redirects the output of fputs_filtered to the kernel so that
88 the user can see what's going on in his debugger window. */
95 CVWriteTranscriptInfo (conn, instance_id, (char *)ptr);
101 energize_query(query, args)
110 vsprintf(buf, query, args);
112 CVWriteQueryInfo(conn,
117 ""); /* transcript */
121 energize_acknowledge_query(ack)
124 CVWriteQueryInfo(conn,
129 ""); /* transcript */
132 /* Copy all data from the pty to the kernel. */
143 cc = read(inferior_pty, buf, sizeof(buf));
147 && errno == EWOULDBLOCK))
154 perror("pty read error");
158 req = CWriteTtyRequest(conn, TextIORType);
159 CWriteVstringLen(conn, buf, cc);
162 CWriteRequestBuffer(conn);
165 /* Copy data from the kernel to the pty. */
168 kernel_to_pty(data, len)
174 cc = write(inferior_pty, data, len);
182 perror("pty write error");
185 printf("Couldn't write all the data to the pty, wanted %d, got %d\n",
191 full_filename(symtab)
192 struct symtab *symtab;
200 if (symtab->fullname)
201 return savestring(symtab->fullname, strlen(symtab->fullname));
204 pathlen = strlen(symtab->dirname);
207 if (symtab->filename)
208 pathlen += strlen(symtab->filename);
210 filename = xmalloc(pathlen+1);
213 strcpy(filename, symtab->dirname);
216 if (symtab->filename)
217 strcat(filename, symtab->filename);
222 /* Tell the energize kernel how high the stack is so that frame numbers (which
223 are relative to the current stack height) make sense.
225 Calculate the number of frames on the stack, and the number of subroutine
226 invocations that haven't changed since the last call to this routine. The
227 second number is calculated by comparing the PCs of the current stack frames
228 to the PCs of the previous set of stack frames. The screw here is that a
229 subroutine may call several different procedures, which means that the PC
230 in its frame changes, even though you are still in the same subroutine. We
231 resolve this by converting the frames PC into the PC at the start of the
232 function (for efficiency, this is done only if the simple comparison test
241 /* Non-zero means that Energize kernel already knows how high the stack is. */
242 static int stack_info_valid = 0;
247 struct pclist *pclist = 0, *pli, *opli;
248 static struct pclist *old_pclist;
252 if (stack_info_valid)
258 /* First, calculate the stack height, and build the new pclist */
260 for (frame = get_current_frame();
262 frame = get_prev_frame(frame))
265 pli = (struct pclist *)xmalloc(sizeof(struct pclist));
272 /* Now, figure out how much of the stack hasn't changed */
274 for (pli = pclist, opli = old_pclist;
275 pli != 0 && opli != 0;
276 pli = pli->next, opli = opli->next, (similar)++)
278 if ((pli->pc != opli->pc)
279 && (get_pc_function_start(pli->pc)
280 != get_pc_function_start(opli->pc)))
284 /* Free up all elements of the old pclist */
295 old_pclist = pclist; /* Install the new pclist */
297 CVWriteStackSizeInfo(conn,
299 height, /* Frame depth */
301 similar, /* Frame diff */
305 stack_info_valid = 1;
308 /* Tell the Energize server about the file and line # that corresponds to pc,
309 and which stack frame level that pc corresponds to. */
312 send_location(pc, frame_level)
316 char *funcname, *filename;
317 struct symtab_and_line sal;
318 struct symbol *symbol;
320 sal = find_pc_line(pc, 0);
321 symbol = find_pc_function(pc);
323 funcname = symbol ? symbol->name : "";
324 filename = full_filename(sal.symtab);
328 CVWriteStackFrameInfo(conn,
335 "" /* XXX ? transcript */
341 /* Tell the kernel where we are in the program, and what the stack looks like.
348 struct symbol *symbol;
349 static int sent_prog_inst = 0;
351 symbol = find_pc_function(stop_pc);
352 funcname = symbol ? symbol->name : "";
357 if (inferior_pid == 0) /* target has died */
359 CVWriteProgramTerminatedInfo(conn,
369 CVWriteProgramInstanceInfo(conn,
378 send_location(stop_pc,
379 selected_frame_level); /* Had better be 0! */
381 CVWriteProgramStoppedInfo(conn,
383 0, /* XXX - breakpoint # or signal # */
386 "" /* XXX ? transcript */
391 /* Call this to output annotated function names. Names will be demangled if
392 necessary. arg_mode contains flags that are passed on to cplus_demangle. */
395 energize_annotate_function(funcname, arg_mode, level)
401 char *demangled_name = NULL;
403 if (funcname == NULL)
408 demangled_name = cplus_demangle(funcname, arg_mode);
412 funcname = demangled_name;
413 printf_filtered("'");
419 if (level < 0) level = 0;
421 CVWriteBackTraceEntryInfo(conn,
428 free(demangled_name);
429 printf_filtered("'");
433 /* Call this just prior to printing out the name & value of a variable. This
434 tells the kernel where to annotate the output. */
437 expression - A text handle on what GDB can use to reference this value.
438 This can be a symbol name, or a convenience var, etc...
439 symbol - Used to determine the scope of the data. May be NULL.
440 type - Determines if we have a pointer ref, and the print name of the type.
441 Used in ShowValue message.
442 valaddr - The address in target memory of the data.
443 field - The field name of the struct or union element being referenced.
446 static char cum_expr[200]; /* Cumulative expression */
447 static char *expr_stack[100] = {cum_expr}; /* Pointers to end of expressions */
448 static char **last_expr = expr_stack; /* Current expr stack pointer */
451 energize_start_variable_annotation(expression, symbol, type, valaddr, field)
453 struct symbol *symbol;
460 enum type_code type_code;
461 enum address_class sym_class;
469 strcpy(*last_expr++, expression);
470 *last_expr = *(last_expr-1) + strlen(expression);
472 switch (TYPE_CODE(type))
474 case TYPE_CODE_ARRAY:
475 case TYPE_CODE_STRUCT:
476 case TYPE_CODE_UNION:
480 ref_type = CValueValueRef;
483 ref_type = CValuePointerRef;
486 ref_type = CValueUndefRef;
490 /* Make sure that pointer points at something we understand */
492 if (ref_type == CValuePointerRef)
493 switch (TYPE_CODE(TYPE_TARGET_TYPE(type)))
496 case TYPE_CODE_ARRAY:
497 case TYPE_CODE_STRUCT:
498 case TYPE_CODE_UNION:
504 ref_type = CValueUndefRef;
510 sym_class = SYMBOL_CLASS(symbol);
515 case LOC_CONST_BYTES:
516 stor_cl = CValueStorStaticConst;
519 stor_cl = CValueStorStaticVar;
523 stor_cl = CValueStorRegister;
529 stor_cl = CValueStorLocalVar;
532 stor_cl = CValueStorUndef;
537 stor_cl = CValueStorUndef;
539 type_cast = TYPE_NAME(type);
541 CVWriteValueBeginInfo(conn,
546 0, /* XXX - frameno */
550 ""); /* transcript */
554 energize_end_variable_annotation()
559 last_expr--; /* Pop the expr stack */
560 **last_expr = '\000'; /* Cut off the last part of the expr */
562 CVWriteValueEndInfo(conn,
564 ""); /* transcript */
567 /* Tell the kernel that the target is now running. */
572 CVWriteProgramBusyInfo(conn,
574 ""); /* XXX ? transcript */
575 CWriteRequestBuffer(conn); /* Must take place synchronusly! */
576 stack_info_valid = 0;
581 energize_symbol_file(objfile)
582 struct objfile *objfile;
587 CVWriteSymbolTableInfo(conn,
589 ""); /* Transcript */
592 /* execute_command_1(echo, queue, cmd, args) - echo - non-zero means echo the
593 command. queue - non-zero means don't execute it now, just save it away for
594 later. cmd - string containing printf control sequences. args - list of
595 arguments needed by those control sequences.
598 /* Linked list of queued up commands */
599 static struct command_line *queued_commands = 0;
600 static struct command_line *last_queued_command = 0;
602 /* Call this routine to save a command for later. The command string is
603 copied into freshly malloc'ed memory. */
610 struct command_line *cl;
613 s = (strlen(cmd) + 1) + 7 & ~(unsigned long)7;
615 buf = (char *)xmalloc(s + sizeof(struct command_line));
616 cl = (struct command_line *)(buf + s);
620 strncpy(cl->line, cmd, s);
623 last_queued_command->next = cl;
625 queued_commands = cl;
627 last_queued_command = cl;
630 /* Call this procedure to take a command off of the command queue. It returns
631 a pointer to a buf which the caller is responsible for freeing. NULL is
632 returned if there are no commands queued. */
637 struct command_line *cl;
640 cl = queued_commands;
645 queued_commands = cl->next;
651 execute_command_1(va_alist)
654 char buf[100]; /* XXX - make buf dynamic! */
663 echo = va_arg(args, int);
664 queue = va_arg(args, int);
665 cmd = va_arg(args, char *);
667 vsprintf(buf, cmd, args);
674 printf_filtered("%s\n", buf);
675 execute_command(buf, 1);
685 kernel_record(fd, ptr, num)
690 fwrite(ptr, num, 1, kerout);
692 return write(fd, ptr, num);
697 energize_condition_breakpoint(b)
698 struct breakpoint *b;
701 CVWriteBreakConditionInfo(conn,
704 b->cond_string ? b->cond_string : "",
710 energize_commands_breakpoint(b)
711 struct breakpoint *b;
713 struct command_line *l;
718 CVWriteBreakCommandBegInfo(conn,
721 ""); /* transcript */
723 for (l = b->commands; l; l = l->next)
724 CVWriteBreakCommandEntryInfo(conn,
727 ""); /* transcript */
729 CVWriteBreakCommandEndInfo(conn,
731 ""); /* transcript */
735 breakpoint_notify(b, action)
736 struct breakpoint *b;
742 char *included_in_filename = "";
747 if (b->type != bp_breakpoint)
750 filename = full_filename(b->symtab);
752 sym = find_pc_function(b->address);
754 funcname = SYMBOL_NAME(sym);
756 CVWriteBreakpointInfo (conn,
765 filename ? filename : "",
766 "", /* included_in_filename */
771 energize_commands_breakpoint(b);
773 energize_condition_breakpoint(b);
780 energize_create_breakpoint(b)
781 struct breakpoint *b;
783 breakpoint_notify(b, CEnableBreakpoint);
787 energize_delete_breakpoint(b)
788 struct breakpoint *b;
790 breakpoint_notify(b, CDeleteBreakpoint);
794 energize_enable_breakpoint(b)
795 struct breakpoint *b;
797 breakpoint_notify(b, CEnableBreakpoint);
801 energize_disable_breakpoint(b)
802 struct breakpoint *b;
804 breakpoint_notify(b, CDisableBreakpoint);
808 energize_ignore_breakpoint(b)
809 struct breakpoint *b;
811 breakpoint_notify(b, CBreakAttrUnchanged);
814 /* Open up a pty and its associated tty. Return the fd of the tty. */
823 struct termios termios;
825 #define HIGHPTY (('z' - 'p') * 16 - 1)
827 for (n = 0; n <= HIGHPTY; n++)
829 sprintf(dev, "/dev/pty%c%x", n/16 + 'p', n%16);
830 if (stat(dev, &statbuf))
832 ptyfd = open(dev, O_RDWR);
835 sprintf(dev, "/dev/tty%c%x", n/16 + 'p', n%16);
836 ttyfd = open(dev, O_RDWR);
843 /* Setup pty for non-blocking I/O. Also make it give us a SIGIO when
844 there's data available. */
846 n = fcntl(ptyfd, F_GETFL, 0);
847 fcntl(ptyfd, F_SETFL, n|FNDELAY|FASYNC);
848 fcntl(ptyfd, F_SETOWN, getpid());
850 tcgetattr(ttyfd, &termios);
851 termios.c_oflag &= ~OPOST; /* No post-processing */
852 tcsetattr(ttyfd, TCSANOW, &termios);
854 inferior_pty = ptyfd;
855 inferior_tty = ttyfd;
859 error ("getpty: can't get a pty\n");
862 /* Alternate getpty for NCRs */
864 #ifdef NCR486 /* LTL */
865 #define MAX_PTM_TRY 16
866 #define MAX_GRANTPT_TRY 4
871 extern char *ptsname();
874 struct termios termios;
876 /* Number of pseudo-terms is tuneable(16 - 255). System default is 16. */
877 for (i = 0; i < MAX_PTM_TRY; i++)
879 mfd = open("/dev/ptmx", O_RDWR); /* get the master */
884 if (grantpt(mfd) < 0) /* get a slave */
885 for (j = 0; j < MAX_GRANTPT_TRY; j++)
886 if (grantpt(mfd) == 0 )
892 if (unlockpt(mfd) < 0)
893 { /* unlock the slave so he can be opened */
898 slavename = ptsname(mfd); /* get the slave device name */
905 sfd = open(slavename, O_RDWR);
913 /* setup mty for non-blocking I/O. Also make it give us a SIGIO
914 when there's data availabe. */
915 n = fcntl(mfd, F_GETFL, 0);
916 fcntl(mfd, F_SETFL, n | O_NDELAY | O_SYNC);
917 fcntl(mfd, F_SETOWN,getpid());
919 tcgetattr(sfd, &termios);
920 termios.c_oflag &= ~OPOST; /* no post-processing */
921 tcsetattr(sfd, TCSANOW, &termios);
927 error ("getpty: can't get a pts\n");
931 /* Examine a protocol packet from the driver. */
934 kernel_dispatch(queue)
935 int queue; /* Non-zero means we should just queue up
938 register CHeader *head;
940 head = (CHeader *)CPeekNextRequest (conn);
943 fprintf (stderr, "EOF on kernel read!\n");
947 if (head->reqType < LastTtyRequestRType)
949 CTtyRequest* req = CReadTtyRequest (conn);
950 switch (req->head.reqType)
952 case AcceptConnectionRType:
953 /* Tell the rest of the world that energize is now set up */
957 case RefuseConnectionRType:
958 fprintf (stderr, "Debugger connection refused\n");
961 case KillProgramRType:
969 p = CGetVstring(conn, &len);
970 kernel_to_pty(p, len);
974 fprintf(stderr, "Unknown Tty request type = %d\n",
981 CVDebuggerRequest *req = CVReadDebuggerRequest (conn);
984 fprintf (stderr, "CVReadDebuggerRequest returned NULL, type = %d\n",
989 switch (req->head.request->reqType)
991 case OpenProgramInstanceRType:
993 char *arglist, buf[100]; /* XXX - Make buf dynamic! */
995 /* XXX - should notice when program_id changes */
996 arglist = req->openProgramInstance.progArglist.text;
997 arglen = req->openProgramInstance.progArglist.byteLen;
999 execute_command_1(1, queue, "break main");
1000 execute_command_1(1, queue, "enable delete $bpnum");
1003 execute_command_1(1, queue, "set args %.*s", arglen, arglist);
1005 execute_command_1(1, queue, "run");
1008 case SearchPathRType:
1009 directory_command(req->searchPath.searchPath.text, 0);
1011 case QuitDebuggerRType:
1012 execute_command_1(1, queue, "quit");
1015 if (req->run.request->useArglist == CNewArglist)
1017 execute_command_1(1, queue, "set args %.*s",
1018 req->run.progArglist.byteLen,
1019 req->run.progArglist.text);
1021 execute_command_1(1, queue, "run");
1024 execute_command_1(1, queue, "continue");
1027 execute_command_1(1, queue, "step %d", req->step.request->stepCount);
1030 execute_command_1(1, queue, "next %d", req->next.request->nextCount);
1032 case ChangeStackFrameRType:
1033 switch (req->changeStackFrame.request->frameMovement)
1035 case CToCurrentStackFrame:
1036 execute_command_1(1, queue, "frame %d",
1037 req->changeStackFrame.request->frameNo);
1039 case CToInnerStackFrame:
1040 execute_command_1(1, queue, "down %d",
1041 req->changeStackFrame.request->frameNo);
1043 case CToOuterStackFrame:
1044 execute_command_1(1, queue, "up %d",
1045 req->changeStackFrame.request->frameNo);
1047 case CToAbsoluteStackFrame:
1048 execute_command_1(1, queue, "frame %d",
1049 req->changeStackFrame.request->frameNo);
1053 case BackTraceRType:
1054 /* XXX - deal with limit??? */
1055 execute_command_1(1, queue, "backtrace");
1058 execute_command_1(1, queue, "finish");
1060 case TerminateProgramRType:
1061 execute_command_1(1, queue, "kill");
1063 case NewBreakpointRType:
1068 tail = strrchr(req->newBreakpoint.fileName.text, '/');
1070 tail = req->newBreakpoint.fileName.text;
1073 skipped = tail - req->newBreakpoint.fileName.text;
1074 execute_command_1(1, queue, "break %.*s:%d",
1075 req->newBreakpoint.fileName.byteLen - skipped,
1077 req->newBreakpoint.request->fileLinePos);
1081 killpg(pgrp_inferior, SIGINT);
1083 case UserInputRType:
1088 /* XXX - should really break command up into seperate lines
1089 and spoon-feed it to execute_command */
1091 text = req->userInput.userInput.text;
1092 len = req->userInput.userInput.byteLen;
1094 if (text[len-1] == '\n') text[len-1] = '\000';
1096 while (*text == ' ' || *text == '\t') text++;
1098 if (strcmp(text, "]*[") == 0) /* XXX - What does this mean??? */
1101 if (*text != '\000')
1102 execute_command_1(0, queue, "%s", text);
1104 print_prompt(); /* User just typed a blank line */
1107 case QueryResponseRType:
1111 if (req->queryResponse.request->response)
1115 execute_command_1(1, 1, resp);
1116 printf_filtered("%s\n", resp);
1119 case ChangeBreakpointRType:
1120 switch (req->changeBreakpoint.request->breakpointAttr)
1122 case CBreakAttrUnchanged:
1123 execute_command_1(1, queue, "ignore %d %d",
1124 req->changeBreakpoint.request->breakpointId,
1125 req->changeBreakpoint.request->ignoreCount);
1127 case CEnableBreakpoint:
1128 execute_command_1(1, queue, "enable %d",
1129 req->changeBreakpoint.request->breakpointId);
1131 case CDisableBreakpoint:
1132 execute_command_1(1, queue, "disable %d",
1133 req->changeBreakpoint.request->breakpointId);
1135 case CDeleteBreakpoint:
1136 execute_command_1(1, queue, "delete %d",
1137 req->changeBreakpoint.request->breakpointId);
1139 case CEnableDisableBreakpoint:
1140 execute_command_1(1, queue, "enable once %d",
1141 req->changeBreakpoint.request->breakpointId);
1143 case CEnableDeleteBreakpoint:
1144 execute_command_1(1, queue, "enable delete %d",
1145 req->changeBreakpoint.request->breakpointId);
1148 printf_filtered("ChangeBreakpointRType: unknown breakpointAttr\n");
1149 printf_filtered(" breakpointAttr = %d\n",
1150 req->changeBreakpoint.request->breakpointAttr);
1151 printf_filtered(" breakpointId = %d\n",
1152 req->changeBreakpoint.request->breakpointId);
1153 printf_filtered(" breakpointType = %d\n",
1154 req->changeBreakpoint.request->breakpointType);
1155 printf_filtered(" ignoreCount = %d\n",
1156 req->changeBreakpoint.request->ignoreCount);
1160 case BreakConditionRType:
1161 execute_command_1(1, queue, "condition %d %.*s",
1162 req->breakCondition.request->breakpointId,
1163 req->breakCondition.condition.byteLen,
1164 req->breakCondition.condition.text);
1166 case BreakCommandsRType:
1167 /* Put pointers to where energize_command_line_input() can find
1169 doing_breakcommands_message = 1;
1170 command_line_length = req->breakCommands.commands.byteLen;
1171 command_line_text = req->breakCommands.commands.text;
1172 execute_command_1(1, queue, "commands %d",
1173 req->breakCommands.request->breakpointId);
1174 command_line_text = (char *)NULL;
1175 command_line_length = 0;
1176 doing_breakcommands_message = 0;
1178 case ShowValueRType:
1180 char expr[100], *p = expr;
1184 if (req->showValue.request->ref_type == CValuePointerRef)
1187 if (req->showValue.type_cast.byteLen)
1190 strncat(expr, req->showValue.type_cast.text,
1191 req->showValue.type_cast.byteLen);
1195 if (req->showValue.field.byteLen)
1198 strncat(expr, req->showValue.expression.text,
1199 req->showValue.expression.byteLen);
1201 if (req->showValue.field.byteLen)
1205 strncat(expr, req->showValue.field.text,
1206 req->showValue.field.byteLen);
1209 execute_command_1(1, queue, "print %s", expr);
1214 char expr[100], *p = expr;
1218 if (req->setValue.request->ref_type == CValuePointerRef)
1222 if (req->setValue.type_cast.byteLen)
1225 strncat(expr, req->setValue.type_cast.text,
1226 req->setValue.type_cast.byteLen);
1230 if (req->setValue.field.byteLen)
1233 strncat(expr, req->setValue.expression.text,
1234 req->setValue.expression.byteLen);
1236 if (req->setValue.field.byteLen)
1240 strncat(expr, req->setValue.field.text,
1241 req->setValue.field.byteLen);
1244 execute_command_1(1, queue, "print %s = (%s) %s", expr,
1245 req->setValue.type_cast.text,
1246 req->setValue.value.text);
1249 case DynamicLoadRType:
1253 filename = req->dynamicLoad.filenames.byteLen ?
1254 req->dynamicLoad.filenames.text : exec_file;
1256 switch (req->dynamicLoad.request->action)
1258 case CDynamicLoadUpdateSymtab:
1259 execute_command_1(1, queue, "exec-file %s", filename);
1260 execute_command_1(1, queue, "symbol-file %s", filename);
1263 printf_filtered("DynamicLoadRType: unknown action=%d, filename=%s\n",
1264 req->dynamicLoad.request->action,
1265 req->dynamicLoad.filenames.text);
1271 fprintf(stderr, "Unknown Debugger request type = %d\n",
1272 req->head.request->reqType);
1275 free (req); /* Should probably call CVFreeDebuggerRequest() here, but
1276 can't do so if interrupt level has mucked with req->
1277 request. CVFreeDebuggerRequest() only ends up calling
1282 /* Return a bitmask indicating if the kernel or the pty did something
1283 interesting. Set poll to non-zero if you don't want to wait. */
1286 wait_for_events(poll)
1292 static struct timeval tv = {0};
1294 /* Output all pending requests. */
1295 CWriteRequestBuffer(conn);
1299 /* Wait till there's some activity from the kernel or the pty. */
1302 FD_SET(kerfd, &readfds);
1303 if (inferior_pty > 0)
1304 FD_SET(inferior_pty, &readfds);
1306 numfds = select(sizeof(readfds)*8, &readfds, 0, 0, &tv);
1308 numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0);
1310 while (numfds <= 0 && !poll);
1312 if (FD_ISSET(inferior_pty, &readfds))
1313 eventmask |= PTY_EVENT;
1315 if (FD_ISSET(kerfd, &readfds))
1316 eventmask |= KERNEL_EVENT;
1321 /* This is called from read_command_lines() to provide the text for breakpoint
1322 commands, which is supplied in a BreakCommands message. Each call to this
1323 routine supplies a single line of text, with the newline removed. */
1325 /* This routine may be invoked in two different contexts. In the first, it
1326 is being called as a result of the BreakCommands message. In this case,
1327 all of the command text is immediately available. In the second case, it is
1328 called as a result of the user typing the 'command' command. The command
1329 text then needs to be glommed out of UserInput messages (and possibly other
1330 messages as well). The most 'straighforward' way of doing this is to
1331 basically simulate the main loop, but just accumulate the command text
1332 instead of sending it to execute_command(). */
1335 energize_command_line_input(prompt, repeat)
1342 return command_line_input(prompt, repeat);
1344 if (doing_breakcommands_message)
1346 if (command_line_length <= 0)
1347 return (char *)NULL;
1349 p = command_line_text;
1351 while (command_line_length-- > 0)
1353 if (*command_line_text == '\n')
1355 *command_line_text = '\000';
1356 command_line_text++;
1359 command_line_text++;
1362 printf_filtered("%s\n", p);
1367 /* We come here when the user has typed the 'command' or 'define' command
1368 to the GDB window. We are basically deep inside of the 'command'
1369 command processing routine right now, and will be called to get a new
1370 line of input. We expect that kernel_dispatch will queue up only one
1371 command at a time. */
1374 static char buf[100];
1376 eventmask = wait_for_events(0);
1378 if (eventmask & PTY_EVENT)
1381 if (eventmask & KERNEL_EVENT)
1382 kernel_dispatch(1); /* Queue up commands */
1384 /* Note that command has been echoed by the time we get here */
1386 p = dequeue_command();
1390 strncpy(buf, p, sizeof(buf));
1399 /* Establish contact with the kernel. */
1402 energize_initialize(energize_id, execarg)
1408 extern long strtol(char *str, char **ptr, int base);
1409 char pathname[MAXPATHLEN];
1415 if (!execarg) execarg = "";
1417 exec_file = strdup(execarg); /* Save for later */
1419 printf("\ngdb-debugger pid=%d\n", getpid()); /* XXX - debugging only */
1421 /* First establish the connection with the kernel. */
1423 kerfd = COpenClientSocket(NULL);
1425 printf("COpenClientSocket() failed\n");
1429 /* Setup for I/O interrupts when appropriate. */
1431 n = fcntl(kerfd, F_GETFL, 0);
1435 fcntl(kerfd, F_SETFL, n|FASYNC);
1436 fcntl(kerfd, F_SETOWN, getpid());
1438 /* Setup connection buffering. */
1440 CSetSocketBufferSize (kerfd, 12000);
1442 /* Generate a new connection control block. */
1444 conn = NewConnection (0, kerfd, kerfd);
1446 printf("NewConnection() failed\n");
1450 #ifdef KERNEL_RECORD
1451 kerout = fopen("kernel.output", "+w");
1453 CReadWriteHooks(conn, conn->previewMethod, conn->readMethod, kernel_record);
1456 /* Tell the kernel that we are the "debugger". */
1458 req = CWriteTtyRequest (conn, QueryConnectionRType);
1459 req->generic.queryconnection.major = 0;
1460 req->generic.queryconnection.minor = 0;
1461 req->generic.queryconnection.cadillacId1=strtol(energize_id, &ctmp, 16);
1462 req->generic.queryconnection.cadillacId2 = strtol(++ctmp, NULL, 16);
1463 req->generic.queryconnection.nProtocols = 1;
1464 CWriteProtocol (conn, 0, 0, "debugger");
1465 CWriteLength (conn);
1467 /* Tell the kernel that we are actually running. */
1469 /* KROCK ALERT!!! The kernel doesn't really care about the arguments to
1470 the program at all! It only cares that argument 7 be the name of the
1471 target program. So, we just fill in the rest of the slots with
1472 padding. I hope the kernel never cares about this! */
1474 req = CWriteTtyRequest (conn, RunningProgramRType);
1475 req->runningprogram.argc = 8;
1477 CWriteVstring0 (conn, pathname);
1479 CWriteVstring0 (conn, "0");
1480 CWriteVstring0 (conn, "1");
1481 CWriteVstring0 (conn, "2");
1482 CWriteVstring0 (conn, "3");
1483 CWriteVstring0 (conn, "4");
1484 CWriteVstring0 (conn, "5");
1485 CWriteVstring0 (conn, "6");
1486 CWriteVstring0 (conn, execarg);
1487 CWriteLength (conn);
1489 /* Tell the kernel our PID and all that */
1492 CVWriteDebugProgramInfo(conn,
1498 /* Tell the rest of the world that Energize is now set up. */
1501 setsid(); /* Drop controlling tty, become pgrp master */
1502 getpty(); /* Setup the pty */
1503 dup2(inferior_tty, 0); /* Attach all GDB I/O to the pty */
1504 dup2(inferior_tty, 1);
1505 dup2(inferior_tty, 2);
1508 /* This is called from execute_command, and provides a wrapper around
1509 various command routines in a place where both protocol messages and
1510 user input both flow through.
1514 energize_call_command(cmdblk, arg, from_tty)
1515 struct cmd_list_element *cmdblk;
1521 (*cmdblk->function.cfunc) (arg, from_tty);
1525 if (cmdblk->class == class_run)
1529 (*cmdblk->function.cfunc)(arg, from_tty);
1533 (*cmdblk->function.cfunc)(arg, from_tty);
1535 if (strcmp(cmdblk->name, "up") == 0
1536 || strcmp(cmdblk->name, "down") == 0
1537 || strcmp(cmdblk->name, "frame") == 0)
1538 send_location(get_frame_info(selected_frame)->pc,
1539 selected_frame_level);
1544 energize_new_process()
1546 instance_id = inferior_pid;
1557 eventmask = wait_for_events(1);
1562 if (eventmask & PTY_EVENT)
1565 if (eventmask & KERNEL_EVENT)
1571 energize_wait(status)
1577 return wait(status);
1579 signal(SIGIO, iosig);
1583 signal(SIGIO, SIG_DFL);
1593 /* All requests from the Energize kernel eventually end up here. */
1596 energize_main_loop()
1599 struct cleanup *old_chain;
1601 doing_breakcommands_message = 0;
1603 /* We will come thru here any time there is an error, so send status if
1610 /* The actual event loop! */
1617 old_chain = make_cleanup(null_routine, 0);
1619 /* First, empty out the command queue, then check for new requests. */
1621 while (cmd = dequeue_command())
1623 execute_command_1(1, 0, cmd);
1627 eventmask = wait_for_events(0);
1629 if (eventmask & PTY_EVENT)
1632 if (eventmask & KERNEL_EVENT)
1635 bpstat_do_actions(&stop_bpstat);
1636 do_cleanups(old_chain);