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 <connection.h>
31 #include <genericreq.h>
32 #include <debuggerreq.h>
33 #include <debuggerconn.h>
41 #include <sys/filio.h>
44 #include <sys/errno.h>
48 /* Non-zero means that we're doing the cadillac 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 char **pprompt; /* Pointer to pointer to prompt */
74 /* Tell cadillac_command_line_input() where to get its text from */
75 static int doing_breakcommands_message = 0;
77 /* Stash command text here */
78 static char *command_line_text = 0;
79 static int command_line_length = 0;
81 /* Flags returned by wait_for_events() */
82 #define KERNEL_EVENT 1
86 /* This routine redirects the output of fputs_filtered to the kernel so that
87 the user can see what's going on in his debugger window. */
94 CVWriteTranscriptInfo (conn, instance_id, (char *)ptr);
100 cadillac_query(query, args)
106 vsprintf(buf, query, args);
108 CVWriteQueryInfo(conn,
113 ""); /* transcript */
117 cadillac_acknowledge_query(ack)
120 CVWriteQueryInfo(conn,
125 ""); /* transcript */
128 /* Copy all data from the pty to the kernel. */
139 cc = read(inferior_pty, buf, sizeof(buf));
143 && errno == EWOULDBLOCK))
150 perror("pty read error");
154 req = CWriteTtyRequest(conn, TextIORType);
155 CWriteVstringLen(conn, buf, cc);
158 CWriteRequestBuffer(conn);
161 /* Copy data from the kernel to the pty. */
164 kernel_to_pty(data, len)
170 cc = write(inferior_pty, data, len);
178 perror("pty write error");
181 printf("Couldn't write all the data to the pty, wanted %d, got %d\n",
187 full_filename(symtab)
188 struct symtab *symtab;
196 if (symtab->fullname)
197 return savestring(symtab->fullname, strlen(symtab->fullname));
200 pathlen = strlen(symtab->dirname);
203 if (symtab->filename)
204 pathlen += strlen(symtab->filename);
206 filename = xmalloc(pathlen+1);
209 strcpy(filename, symtab->dirname);
212 if (symtab->filename)
213 strcat(filename, symtab->filename);
218 /* Tell the cadillac kernel how high the stack is so that frame numbers (which
219 are relative to the current stack height make sense.
221 Calculate the number of frames on the stack, and the number of subroutine
222 invocations that haven't changed since the last call to this routine. The
223 second number is calculated by comparing the PCs of the current stack frames
224 to the PCs of the previous set of stack frames. The screw here is that a
225 subroutine may call several different procedures, which means that the PC
226 in its frame changes, even though you are still in the same subroutine. We
227 resolve this by converting the frames PC into the PC at the start of the
228 function (for efficiency, this is done only if the simple comparison test
237 /* Non-zero means that Cadillac kernel already knows how high the stack is. */
238 static int stack_info_valid = 0;
243 struct pclist *pclist = 0, *pli, *opli;
244 static struct pclist *old_pclist;
248 if (stack_info_valid)
254 /* First, calculate the stack height, and build the new pclist */
256 for (frame = get_current_frame();
258 frame = get_prev_frame(frame))
261 pli = (struct pclist *)xmalloc(sizeof(struct pclist));
268 /* Now, figure out how much of the stack hasn't changed */
270 for (pli = pclist, opli = old_pclist;
271 pli != 0 && opli != 0;
272 pli = pli->next, opli = opli->next, (similar)++)
274 if ((pli->pc != opli->pc)
275 && (get_pc_function_start(pli->pc)
276 != get_pc_function_start(opli->pc)))
280 /* Free up all elements of the old pclist */
291 old_pclist = pclist; /* Install the new pclist */
293 CVWriteStackSizeInfo(conn,
295 height, /* Frame depth */
297 similar, /* Frame diff */
301 stack_info_valid = 1;
304 /* Tell the kernel where we are in the program, and what the stack looks like.
310 static int linecount = 48;
311 struct symtab_and_line sal;
312 struct symbol *symbol;
313 char *funcname, *filename;
314 static int sent_prog_inst = 0;
319 if (inferior_pid == 0) /* target has died */
321 CVWriteProgramTerminatedInfo(conn,
328 sal = find_pc_line(stop_pc, 0);
329 symbol = find_pc_function(stop_pc);
331 funcname = symbol ? symbol->name : "";
332 filename = full_filename(sal.symtab);
337 CVWriteProgramInstanceInfo(conn,
348 CVWriteStackFrameInfo(conn,
352 0, /* XXX - frame # */
355 "" /* XXX ? transcript */
358 CVWriteProgramStoppedInfo(conn,
360 0, /* XXX - breakpoint # or signal # */
363 "" /* XXX ? transcript */
370 /* Call this to output annotated function names. Names will be demangled if
371 necessary. arg_mode contains flags that are passed on to cplus_demangle. */
374 cadillac_annotate_function(funcname, arg_mode, level)
380 char *demangled_name = NULL;
383 if (funcname == NULL)
388 demangled_name = cplus_demangle(funcname, arg_mode);
391 funcname = demangled_name;
396 if (level < 0) level = 0;
398 CVWriteBackTraceEntryInfo(conn,
404 free(demangled_name);
407 /* Call this just prior to printing out the name & value of a variable. This
408 tells the kernel where to annotate the output. */
411 expression - A text handle on what GDB can use to reference this value.
412 This can be a symbol name, or a convenience var, etc...
413 symbol - Used to determine the scope of the data. May be NULL.
414 type - Determines if we have a pointer ref, and the print name of the type.
415 Used in ShowValue message.
416 valaddr - The address in target memory of the data.
417 field - The field name of the struct or union element being referenced.
420 static char cum_expr[200]; /* Cumulative expression */
421 static char *expr_stack[100] = {cum_expr}; /* Pointers to end of expressions */
422 static char **last_expr = expr_stack; /* Current expr stack pointer */
425 cadillac_start_variable_annotation(expression, symbol, type, valaddr, field)
427 struct symbol *symbol;
434 enum type_code type_code;
435 enum address_class sym_class;
440 strcpy(*last_expr++, expression);
441 *last_expr = *(last_expr-1) + strlen(expression);
443 switch (TYPE_CODE(type))
445 case TYPE_CODE_ARRAY:
446 case TYPE_CODE_STRUCT:
447 case TYPE_CODE_UNION:
451 ref_type = CValueValueRef;
454 ref_type = CValuePointerRef;
457 ref_type = CValueUndefRef;
461 /* Make sure that pointer points at something we understand */
463 if (ref_type == CValuePointerRef)
464 switch (TYPE_CODE(TYPE_TARGET_TYPE(type)))
467 case TYPE_CODE_ARRAY:
468 case TYPE_CODE_STRUCT:
469 case TYPE_CODE_UNION:
475 ref_type = CValueUndefRef;
481 sym_class = SYMBOL_CLASS(symbol);
486 case LOC_CONST_BYTES:
487 stor_cl = CValueStorStaticConst;
490 stor_cl = CValueStorStaticVar;
494 stor_cl = CValueStorRegister;
500 stor_cl = CValueStorLocalVar;
503 stor_cl = CValueStorUndef;
508 stor_cl = CValueStorUndef;
510 type_cast = TYPE_NAME(type);
512 CVWriteValueBeginInfo(conn,
517 0, /* XXX - frameno */
521 ""); /* transcript */
525 cadillac_end_variable_annotation()
527 last_expr--; /* Pop the expr stack */
528 **last_expr = '\000'; /* Cut off the last part of the expr */
530 CVWriteValueEndInfo(conn,
532 ""); /* transcript */
535 /* Tell the kernel that the target is now running. */
540 CVWriteProgramBusyInfo(conn,
542 ""); /* XXX ? transcript */
543 CWriteRequestBuffer(conn); /* Must take place synchronusly! */
544 stack_info_valid = 0;
549 cadillac_symbol_file(objfile)
550 struct objfile *objfile;
552 CVWriteSymbolTableInfo(conn,
554 ""); /* Transcript */
557 /* execute_command_1(echo, queue, cmd, args) - echo - non-zero means echo the
558 command. queue - non-zero means don't execute it now, just save it away for
559 later. cmd - string containing printf control sequences. args - list of
560 arguments needed by those control sequences.
563 /* Linked list of queued up commands */
564 static struct command_line *queued_commands = 0;
565 static struct command_line *last_queued_command = 0;
567 /* Call this routine to save a command for later. The command string is
568 copied into freshly malloc'ed memory. */
575 struct command_line *cl;
578 s = (strlen(cmd) + 1) + 7 & ~(unsigned long)7;
580 buf = (char *)xmalloc(s + sizeof(struct command_line));
581 cl = (struct command_line *)(buf + s);
585 strncpy(cl->line, cmd, s);
588 last_queued_command->next = cl;
590 queued_commands = cl;
592 last_queued_command = cl;
595 /* Call this procedure to take a command off of the command queue. It returns
596 a pointer to a buf which the caller is responsible for freeing. NULL is
597 returned if there are no commands queued. */
602 struct command_line *cl;
605 cl = queued_commands;
610 queued_commands = cl->next;
616 execute_command_1(va_alist)
619 char buf[100]; /* XXX - make buf dynamic! */
628 echo = va_arg(args, int);
629 queue = va_arg(args, int);
630 cmd = va_arg(args, char *);
632 vsprintf(buf, cmd, args);
639 printf_filtered("%s\n", buf);
640 execute_command(buf, 1);
650 kernel_record(fd, ptr, num)
655 fwrite(ptr, num, 1, kerout);
657 return write(fd, ptr, num);
662 cadillac_condition_breakpoint(b)
663 struct breakpoint *b;
665 CVWriteBreakConditionInfo(conn,
668 b->cond_string ? b->cond_string : "",
674 cadillac_commands_breakpoint(b)
675 struct breakpoint *b;
677 struct command_line *l;
679 CVWriteBreakCommandBegInfo(conn,
682 ""); /* transcript */
684 for (l = b->commands; l; l = l->next)
685 CVWriteBreakCommandEntryInfo(conn,
688 ""); /* transcript */
690 CVWriteBreakCommandEndInfo(conn,
692 ""); /* transcript */
696 breakpoint_notify(b, action)
697 struct breakpoint *b;
703 char *included_in_filename = "";
705 if (b->type != bp_breakpoint)
708 filename = full_filename(b->symtab);
710 sym = find_pc_function(b->address);
712 funcname = SYMBOL_NAME(sym);
714 CVWriteBreakpointInfo (conn,
723 filename ? filename : "",
724 "", /* included_in_filename */
729 cadillac_commands_breakpoint(b);
731 cadillac_condition_breakpoint(b);
738 cadillac_create_breakpoint(b)
739 struct breakpoint *b;
741 breakpoint_notify(b, CEnableBreakpoint);
745 cadillac_delete_breakpoint(b)
746 struct breakpoint *b;
748 breakpoint_notify(b, CDeleteBreakpoint);
752 cadillac_enable_breakpoint(b)
753 struct breakpoint *b;
755 breakpoint_notify(b, CEnableBreakpoint);
759 cadillac_disable_breakpoint(b)
760 struct breakpoint *b;
762 breakpoint_notify(b, CDisableBreakpoint);
766 cadillac_ignore_breakpoint(b)
767 struct breakpoint *b;
769 breakpoint_notify(b, CBreakAttrUnchanged);
772 /* Open up a pty and its associated tty. Return the fd of the tty. */
780 struct termios termios;
782 #define HIGHPTY (('z' - 'p') * 16 - 1)
784 for (n = 0; n <= HIGHPTY; n++)
786 sprintf(dev, "/dev/pty%c%x", n/16 + 'p', n%16);
787 if (stat(dev, &statbuf))
789 ptyfd = open(dev, O_RDWR);
792 sprintf(dev, "/dev/tty%c%x", n/16 + 'p', n%16);
793 ttyfd = open(dev, O_RDWR);
794 if (ttyfd < 0) {close(ptyfd); continue;}
796 /* Setup pty for non-blocking I/O. Also make it give us a SIGIO when
797 there's data available. */
799 n = fcntl(ptyfd, F_GETFL, 0);
800 fcntl(ptyfd, F_SETFL, n|FNDELAY|FASYNC);
801 fcntl(ptyfd, F_SETOWN, getpid());
803 tcgetattr(ttyfd, &termios);
804 termios.c_oflag &= ~OPOST; /* No post-processing */
805 tcsetattr(ttyfd, TCSANOW, &termios);
807 inferior_pty = ptyfd;
808 inferior_tty = ttyfd;
812 error ("getpty: can't get a pty\n");
815 /* Examine a protocol packet from the driver. */
818 kernel_dispatch(queue)
819 int queue; /* Non-zero means we should just queue up
822 register CHeader *head;
824 head = (CHeader *)CPeekNextRequest (conn);
827 fprintf (stderr, "EOF on kernel read!\n");
831 if (head->reqType < LastTtyRequestRType)
833 CTtyRequest* req = CReadTtyRequest (conn);
834 switch (req->head.reqType)
836 case AcceptConnectionRType:
837 /* Tell the rest of the world that cadillac is now set up */
841 case RefuseConnectionRType:
842 fprintf (stderr, "Debugger connection refused\n");
845 case KillProgramRType:
853 p = CGetVstring(conn, &len);
854 kernel_to_pty(p, len);
858 fprintf(stderr, "Unknown request type = %d\n",
865 CVDebuggerRequest *req = CVReadDebuggerRequest (conn);
868 fprintf (stderr, "CVReadDebuggerRequest returned NULL, type = %d\n",
873 switch (req->head.request->reqType)
875 case OpenProgramInstanceRType:
877 char *arglist, buf[100]; /* XXX - Make buf dynamic! */
879 /* XXX - should notice when program_id changes */
880 arglist = req->openProgramInstance.progArglist.text;
881 arglen = req->openProgramInstance.progArglist.byteLen;
883 execute_command_1(1, queue, "break main");
884 execute_command_1(1, queue, "enable delete $bpnum");
887 execute_command_1(1, queue, "set args %.*s", arglen, arglist);
889 execute_command_1(1, queue, "run");
892 case SearchPathRType:
893 directory_command(req->searchPath.searchPath.text, 0);
895 case QuitDebuggerRType:
896 execute_command_1(1, queue, "quit");
899 if (req->run.request->useArglist == CNewArglist)
901 execute_command_1(1, queue, "set args %.*s",
902 req->run.progArglist.byteLen,
903 req->run.progArglist.text);
905 execute_command_1(1, queue, "run");
908 execute_command_1(1, queue, "continue");
911 execute_command_1(1, queue, "step %d", req->step.request->stepCount);
914 execute_command_1(1, queue, "next %d", req->next.request->nextCount);
916 case ChangeStackFrameRType:
917 switch (req->changeStackFrame.request->frameMovement)
919 case CToCurrentStackFrame:
920 execute_command_1(1, queue, "frame %d",
921 req->changeStackFrame.request->frameNo);
923 case CToInnerStackFrame:
924 execute_command_1(1, queue, "down %d",
925 req->changeStackFrame.request->frameNo);
927 case CToOuterStackFrame:
928 execute_command_1(1, queue, "up %d",
929 req->changeStackFrame.request->frameNo);
931 case CToAbsoluteStackFrame:
932 execute_command_1(1, queue, "frame %d",
933 req->changeStackFrame.request->frameNo);
938 /* XXX - deal with limit??? */
939 execute_command_1(1, queue, "backtrace");
942 execute_command_1(1, queue, "finish");
944 case TerminateProgramRType:
945 execute_command_1(1, queue, "kill");
947 case NewBreakpointRType:
952 tail = strrchr(req->newBreakpoint.fileName.text, '/');
954 tail = req->newBreakpoint.fileName.text;
957 skipped = tail - req->newBreakpoint.fileName.text;
958 execute_command_1(1, queue, "break %.*s:%d",
959 req->newBreakpoint.fileName.byteLen - skipped,
961 req->newBreakpoint.request->fileLinePos);
965 killpg(pgrp_inferior, SIGINT);
972 /* XXX - should really break command up into seperate lines
973 and spoon-feed it to execute_command */
975 text = req->userInput.userInput.text;
976 len = req->userInput.userInput.byteLen;
978 if (text[len-1] == '\n') text[len-1] = '\000';
980 while (*text == ' ' || *text == '\t') text++;
982 if (strcmp(text, "]*[") == 0) /* XXX - What does this mean??? */
986 execute_command_1(0, queue, "%s", text);
988 print_prompt(); /* User just typed a blank line */
991 case QueryResponseRType:
995 if (req->queryResponse.request->response)
999 execute_command_1(1, 1, resp);
1000 printf_filtered("%s\n", resp);
1003 case ChangeBreakpointRType:
1004 switch (req->changeBreakpoint.request->breakpointAttr)
1006 case CBreakAttrUnchanged:
1007 execute_command_1(1, queue, "ignore %d %d",
1008 req->changeBreakpoint.request->breakpointId,
1009 req->changeBreakpoint.request->ignoreCount);
1011 case CEnableBreakpoint:
1012 execute_command_1(1, queue, "enable %d",
1013 req->changeBreakpoint.request->breakpointId);
1015 case CDisableBreakpoint:
1016 execute_command_1(1, queue, "disable %d",
1017 req->changeBreakpoint.request->breakpointId);
1019 case CDeleteBreakpoint:
1020 execute_command_1(1, queue, "delete %d",
1021 req->changeBreakpoint.request->breakpointId);
1023 case CEnableDisableBreakpoint:
1024 execute_command_1(1, queue, "enable once %d",
1025 req->changeBreakpoint.request->breakpointId);
1027 case CEnableDeleteBreakpoint:
1028 execute_command_1(1, queue, "enable delete %d",
1029 req->changeBreakpoint.request->breakpointId);
1032 printf_filtered("ChangeBreakpointRType: unknown breakpointAttr\n");
1033 printf_filtered(" breakpointAttr = %d\n",
1034 req->changeBreakpoint.request->breakpointAttr);
1035 printf_filtered(" breakpointId = %d\n",
1036 req->changeBreakpoint.request->breakpointId);
1037 printf_filtered(" breakpointType = %d\n",
1038 req->changeBreakpoint.request->breakpointType);
1039 printf_filtered(" ignoreCount = %d\n",
1040 req->changeBreakpoint.request->ignoreCount);
1044 case BreakConditionRType:
1045 execute_command_1(1, queue, "condition %d %.*s",
1046 req->breakCondition.request->breakpointId,
1047 req->breakCondition.condition.byteLen,
1048 req->breakCondition.condition.text);
1050 case BreakCommandsRType:
1051 /* Put pointers to where cadillac_command_line_input() can find
1053 doing_breakcommands_message = 1;
1054 command_line_length = req->breakCommands.commands.byteLen;
1055 command_line_text = req->breakCommands.commands.text;
1056 execute_command_1(1, queue, "commands %d",
1057 req->breakCommands.request->breakpointId);
1058 command_line_text = (char *)NULL;
1059 command_line_length = 0;
1060 doing_breakcommands_message = 0;
1062 case ShowValueRType:
1064 char expr[100], *p = expr;
1068 if (req->showValue.request->ref_type == CValuePointerRef)
1071 if (req->showValue.type_cast.byteLen)
1074 strncat(expr, req->showValue.type_cast.text,
1075 req->showValue.type_cast.byteLen);
1079 if (req->showValue.field.byteLen)
1082 strncat(expr, req->showValue.expression.text,
1083 req->showValue.expression.byteLen);
1085 if (req->showValue.field.byteLen)
1089 strncat(expr, req->showValue.field.text,
1090 req->showValue.field.byteLen);
1093 execute_command_1(1, queue, "print %s", expr);
1098 char expr[100], *p = expr;
1102 if (req->setValue.request->ref_type == CValuePointerRef)
1106 if (req->setValue.type_cast.byteLen)
1109 strncat(expr, req->setValue.type_cast.text,
1110 req->setValue.type_cast.byteLen);
1114 if (req->setValue.field.byteLen)
1117 strncat(expr, req->setValue.expression.text,
1118 req->setValue.expression.byteLen);
1120 if (req->setValue.field.byteLen)
1124 strncat(expr, req->setValue.field.text,
1125 req->setValue.field.byteLen);
1128 execute_command_1(1, queue, "print %s = (%s) %s", expr,
1129 req->setValue.type_cast.text,
1130 req->setValue.value.text);
1134 fprintf(stderr, "Unknown request type = %d\n",
1135 req->head.request->reqType);
1138 free (req); /* Should probably call CVFreeDebuggerRequest() here, but
1139 can't do so if interrupt level has mucked with req->
1140 request. CVFreeDebuggerRequest() only ends up calling
1145 /* Return a bitmask indicating if the kernel or the pty did something
1146 interesting. Set poll to non-zero if you don't want to wait. */
1149 wait_for_events(poll)
1155 static struct timeval tv = {0};
1157 /* Output all pending requests. */
1158 CWriteRequestBuffer(conn);
1162 /* Wait till there's some activity from the kernel or the pty. */
1165 FD_SET(kerfd, &readfds);
1166 if (inferior_pty > 0)
1167 FD_SET(inferior_pty, &readfds);
1169 numfds = select(sizeof(readfds)*8, &readfds, 0, 0, &tv);
1171 numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0);
1173 while (numfds <= 0 && !poll);
1175 if (FD_ISSET(inferior_pty, &readfds))
1176 eventmask |= PTY_EVENT;
1178 if (FD_ISSET(kerfd, &readfds))
1179 eventmask |= KERNEL_EVENT;
1184 /* This is called from read_command_lines() to provide the text for breakpoint
1185 commands, which is supplied in a BreakCommands message. Each call to this
1186 routine supplies a single line of text, with the newline removed. */
1188 /* This routine may be invoked in two different contexts. In the first, it
1189 is being called as a result of the BreakCommands message. In this case,
1190 all of the command text is immediately available. In the second case, it is
1191 called as a result of the user typing the 'command' command. The command
1192 text then needs to be glommed out of UserInput messages (and possibly other
1193 messages as well). The most 'straighforward' way of doing this is to
1194 basically simulate the main loop, but just accumulate the command text
1195 instead of sending it to execute_command(). */
1198 cadillac_command_line_input()
1202 if (doing_breakcommands_message)
1204 if (command_line_length <= 0)
1205 return (char *)NULL;
1207 p = command_line_text;
1209 while (command_line_length-- > 0)
1211 if (*command_line_text == '\n')
1213 *command_line_text = '\000';
1214 command_line_text++;
1217 command_line_text++;
1220 printf_filtered("%s\n", p);
1225 /* We come here when the user has typed the 'command' or 'define' command
1226 to the GDB window. We are basically deep inside of the 'command'
1227 command processing routine right now, and will be called to get a new
1228 line of input. We expect that kernel_dispatch will queue up only one
1229 command at a time. */
1232 static char buf[100];
1234 eventmask = wait_for_events(0);
1236 if (eventmask & PTY_EVENT)
1239 if (eventmask & KERNEL_EVENT)
1240 kernel_dispatch(1); /* Queue up commands */
1242 /* Note that command has been echoed by the time we get here */
1244 p = dequeue_command();
1248 strncpy(buf, p, sizeof(buf));
1257 /* Establish contact with the kernel. */
1260 cadillac_initialize(cadillac_id, execarg)
1266 extern long strtol(char *str, char **ptr, int base);
1267 char pathname[MAXPATHLEN];
1270 if (!execarg) execarg = "";
1272 printf("gdb-debugger pid=%d\n", getpid()); /* XXX - debugging only */
1274 /* First establish the connection with the kernel. */
1276 kerfd = COpenClientSocket(NULL);
1278 printf("COpenClientSocket() failed\n");
1282 /* Setup for I/O interrupts when appropriate. */
1284 n = fcntl(kerfd, F_GETFL, 0);
1285 fcntl(kerfd, F_SETFL, n|FASYNC);
1286 fcntl(kerfd, F_SETOWN, getpid());
1288 /* Setup connection buffering. */
1290 CSetSocketBufferSize (kerfd, 12000);
1292 /* Generate a new connection control block. */
1294 conn = NewConnection (0, kerfd, kerfd);
1296 printf("NewConnection() failed\n");
1300 #ifdef KERNEL_RECORD
1301 kerout = fopen("kernel.output", "+w");
1303 CReadWriteHooks(conn, conn->previewMethod, conn->readMethod, kernel_record);
1306 /* Tell the kernel that we are the "debugger". */
1308 req = CWriteTtyRequest (conn, QueryConnectionRType);
1309 req->generic.queryconnection.major = 0;
1310 req->generic.queryconnection.minor = 0;
1311 req->generic.queryconnection.cadillacId1=strtol(cadillac_id, &ctmp, 16);
1312 req->generic.queryconnection.cadillacId2 = strtol(++ctmp, NULL, 16);
1313 req->generic.queryconnection.nProtocols = 1;
1314 CWriteProtocol (conn, 0, 0, "debugger");
1315 CWriteLength (conn);
1317 /* Tell the kernel that we are actually running. */
1319 /* KROCK ALERT!!! The kernel doesn't really care about the arguments to
1320 the program at all! It only cares that argument 7 be the name of the
1321 target program. So, we just fill in the rest of the slots with
1322 padding. I hope the kernel never cares about this! */
1324 req = CWriteTtyRequest (conn, RunningProgramRType);
1325 req->runningprogram.argc = 8;
1327 CWriteVstring0 (conn, pathname);
1329 CWriteVstring0 (conn, "0");
1330 CWriteVstring0 (conn, "1");
1331 CWriteVstring0 (conn, "2");
1332 CWriteVstring0 (conn, "3");
1333 CWriteVstring0 (conn, "4");
1334 CWriteVstring0 (conn, "5");
1335 CWriteVstring0 (conn, "6");
1336 CWriteVstring0 (conn, execarg);
1337 CWriteLength (conn);
1339 /* Tell the kernel our PID and all that */
1342 CVWriteDebugProgramInfo(conn,
1348 /* Tell the rest of the world that Cadillac is now set up. */
1351 setsid(); /* Drop controlling tty, become pgrp master */
1352 getpty(); /* Setup the pty */
1353 dup2(inferior_tty, 0); /* Attach all GDB I/O to the pty */
1354 dup2(inferior_tty, 1);
1355 dup2(inferior_tty, 2);
1358 /* This is called from execute_command, and provides a wrapper around
1359 various command routines in a place where both protocol messages and
1360 user input both flow through.
1364 cadillac_call_command(cmdblk, arg, from_tty)
1365 struct cmd_list_element *cmdblk;
1369 if (cmdblk->class == class_run)
1373 (*cmdblk->function.cfunc)(arg, from_tty);
1377 (*cmdblk->function.cfunc)(arg, from_tty);
1383 cadillac_new_process()
1385 instance_id = inferior_pid;
1396 eventmask = wait_for_events(1);
1401 if (eventmask & PTY_EVENT)
1404 if (eventmask & KERNEL_EVENT)
1410 cadillac_wait(status)
1415 signal(SIGIO, iosig);
1419 signal(SIGIO, SIG_DFL);
1429 /* All requests from the Cadillac kernel eventually end up here. */
1432 cadillac_main_loop()
1435 struct cleanup *old_chain;
1437 doing_breakcommands_message = 0;
1439 /* We will come thru here any time there is an error, so send status if
1446 /* The actual event loop! */
1453 old_chain = make_cleanup(null_routine, 0);
1455 /* First, empty out the command queue, then check for new requests. */
1457 while (cmd = dequeue_command())
1459 execute_command_1(1, 0, cmd);
1463 eventmask = wait_for_events(0);
1465 if (eventmask & PTY_EVENT)
1468 if (eventmask & KERNEL_EVENT)
1471 bpstat_do_actions(&stop_bpstat);
1472 do_cleanups(old_chain);