]> Git Repo - binutils.git/blob - gdb/cadillac.c
* mips-xdep.c (REGISTER_PTRACE_ADDR, fetch_inferior_registers,
[binutils.git] / gdb / cadillac.c
1 /* Energize (formerly known as Cadillac) interface routines.
2    Copyright 1991, 1992 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
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.
10
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.
15
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.  */
19
20 #include "defs.h"
21 #include "symtab.h"
22 #include "inferior.h"
23 #include "command.h"
24 #include "bfd.h"
25 #include "symfile.h"
26 #include "objfiles.h"
27 #include <sys/types.h>
28 #include <sys/time.h>
29 #include <sys/param.h>
30 #include <connection.h>
31 #include <genericreq.h>
32 #include <debuggerreq.h>
33 #include <debuggerconn.h>
34 #include <ttyconn.h>
35 #include <varargs.h>
36 #include <sys/stat.h>
37 #ifdef USG
38 #include <sys/file.h>
39 #endif
40 #include <fcntl.h>
41 #include <sys/filio.h>
42 #include <setjmp.h>
43 #include <signal.h>
44 #include <sys/errno.h>
45 #include <termios.h>
46 #include <string.h>
47
48 /* Non-zero means that we're doing the cadillac interface. */
49 int cadillac = 0;
50
51 /* Connection block for debugger<=>kernel communications. */
52 static Connection *conn = 0;
53
54 /* fd for our socket to the kernel. */
55 static int kerfd;
56
57 /* The kernel's ID for this instance of the program. */
58 static int program_id;
59
60 static int instance_id;
61
62 /* The fd for the pty associated with the inferior. */
63 static int inferior_pty = -1;
64 static int inferior_tty = -1;
65
66 static int has_run = 0;
67
68 extern int pgrp_inferior;
69
70 extern char *source_path;
71
72 char **pprompt;                 /* Pointer to pointer to prompt */
73
74 /* Tell cadillac_command_line_input() where to get its text from */
75 static int doing_breakcommands_message = 0;
76
77 /* Stash command text here */
78 static char *command_line_text = 0;
79 static int command_line_length = 0;
80
81 /* Flags returned by wait_for_events() */
82 #define KERNEL_EVENT 1
83 #define PTY_EVENT 2
84
85 \f
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. */
88
89 void
90 cadillac_fputs(ptr)
91      const char *ptr;
92 {
93   if (conn)
94     CVWriteTranscriptInfo (conn, instance_id, (char *)ptr);
95   else
96     fputs (ptr, stdout);
97 }
98
99 void
100 cadillac_query(query, args)
101      char *query;
102      va_list args;
103 {
104   char buf[100];
105
106   vsprintf(buf, query, args);
107
108   CVWriteQueryInfo(conn,
109                    instance_id,
110                    CQueryConfirm,
111                    qno_unknown,
112                    buf,
113                    "");         /* transcript */
114 }
115
116 void
117 cadillac_acknowledge_query(ack)
118      char *ack;
119 {
120   CVWriteQueryInfo(conn,
121                    instance_id,
122                    CQueryAcknowleged,
123                    0,
124                    ack,
125                    "");         /* transcript */
126 }
127
128 /* Copy all data from the pty to the kernel. */
129
130 static void
131 pty_to_kernel()
132 {
133   CTtyRequest *req;
134   char buf[1024];
135   int cc;
136
137   while (1)
138     {
139       cc = read(inferior_pty, buf, sizeof(buf));
140
141       if (cc == 0
142           || (cc < 0
143               && errno == EWOULDBLOCK))
144         break;
145
146       if (cc < 0)
147         {
148           close(inferior_pty);
149           inferior_pty = -1;
150           perror("pty read error");
151           break;
152         }
153
154       req = CWriteTtyRequest(conn, TextIORType);
155       CWriteVstringLen(conn, buf, cc);
156       CWriteLength(conn);
157     }
158   CWriteRequestBuffer(conn);
159 }
160
161 /* Copy data from the kernel to the pty. */
162
163 static void
164 kernel_to_pty(data, len)
165      char *data;
166      int len;
167 {
168   int cc;
169
170   cc = write(inferior_pty, data, len);
171
172   if (cc != len)
173     {
174       if (cc < 0)
175         {
176           close(inferior_pty);
177           inferior_pty = -1;
178           perror("pty write error");
179           return;
180         }
181       printf("Couldn't write all the data to the pty, wanted %d, got %d\n",
182              len, cc);
183     }
184 }
185 \f
186 static char *
187 full_filename(symtab)
188      struct symtab *symtab;
189 {
190   int pathlen;
191   char *filename;
192
193   if (!symtab)
194     return NULL;
195
196   if (symtab->fullname)
197     return savestring(symtab->fullname, strlen(symtab->fullname));
198
199   if (symtab->dirname)
200     pathlen = strlen(symtab->dirname);
201   else
202     pathlen = 0;
203   if (symtab->filename)
204     pathlen += strlen(symtab->filename);
205
206   filename = xmalloc(pathlen+1);
207
208   if (symtab->dirname)
209     strcpy(filename, symtab->dirname);
210   else
211     *filename = '\000';
212   if (symtab->filename)
213     strcat(filename, symtab->filename);
214
215   return filename;
216 }
217
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.
220
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
229    fails). */
230
231 struct pclist
232 {
233   CORE_ADDR pc;
234   struct pclist *next;
235 };
236
237 /* Non-zero means that Cadillac kernel already knows how high the stack is. */
238 static int stack_info_valid = 0;
239
240 static void
241 send_stack_info()
242 {
243   struct pclist *pclist = 0, *pli, *opli;
244   static struct pclist *old_pclist;
245   FRAME frame;
246   int height, similar;
247
248   if (stack_info_valid)
249     return;
250
251   height = 0;
252   similar = 0;
253
254 /* First, calculate the stack height, and build the new pclist */
255
256   for (frame = get_current_frame();
257        frame != 0;
258        frame = get_prev_frame(frame))
259     {
260       (height)++;
261       pli = (struct pclist *)xmalloc(sizeof(struct pclist));
262
263       pli->pc = frame->pc;
264       pli->next = pclist;
265       pclist = pli;
266     }
267
268 /* Now, figure out how much of the stack hasn't changed */
269
270   for (pli = pclist, opli = old_pclist;
271        pli != 0 && opli != 0;
272        pli = pli->next, opli = opli->next, (similar)++)
273     {
274       if ((pli->pc != opli->pc)
275           && (get_pc_function_start(pli->pc)
276               != get_pc_function_start(opli->pc)))
277         break;
278     }
279
280 /* Free up all elements of the old pclist */
281
282   opli = old_pclist;
283
284   while (opli)
285     {
286       pli = opli->next;
287       free (opli);
288       opli = pli;
289     }
290
291   old_pclist = pclist;          /* Install the new pclist */
292
293   CVWriteStackSizeInfo(conn,
294                        instance_id,
295                        height,  /* Frame depth */
296                        CInnerFrameIs0,
297                        similar, /* Frame diff */
298                        ""       /* Transcript */
299                        );
300
301   stack_info_valid = 1;
302 }
303
304 /* Tell the kernel where we are in the program, and what the stack looks like.
305    */
306
307 static void
308 send_status()
309 {
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;
315
316   if (!has_run)
317     return;
318
319   if (inferior_pid == 0)        /* target has died */
320     {
321       CVWriteProgramTerminatedInfo(conn,
322                                    instance_id,
323                                    ""
324                                    );
325       return;
326     }
327
328   sal = find_pc_line(stop_pc, 0);
329   symbol = find_pc_function(stop_pc);
330
331   funcname = symbol ? symbol->name : "";
332   filename = full_filename(sal.symtab);
333
334   if (!sent_prog_inst)
335     {
336       sent_prog_inst = 1;
337       CVWriteProgramInstanceInfo(conn,
338                                  program_id,
339                                  instance_id,
340                                  "", /* hostname */
341                                  "", /* arglist */
342                                  ""
343                                  );
344     }
345
346   send_stack_info();
347
348   CVWriteStackFrameInfo(conn,
349                         instance_id,
350                         sal.line,
351                         CFileLinePos,
352                         0,      /* XXX - frame # */
353                         funcname,
354                         filename,
355                         ""      /* XXX ? transcript */
356                         );
357
358   CVWriteProgramStoppedInfo(conn,
359                             instance_id,
360                             0,  /* XXX - breakpoint # or signal # */
361                             CDebuggerCommand,
362                             funcname,
363                             ""  /* XXX ? transcript */
364                             );
365
366   if (filename)
367     free(filename);
368 }
369
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. */
372
373 void
374 cadillac_annotate_function(funcname, arg_mode, level)
375      char *funcname;
376      int arg_mode;
377      int level;
378 {
379   extern int demangle;
380   char *demangled_name = NULL;
381
382
383   if (funcname == NULL)
384     return;
385
386   if (demangle)
387     {
388       demangled_name = cplus_demangle(funcname, arg_mode);
389
390       if (demangled_name)
391         funcname = demangled_name;
392     }
393
394   send_stack_info();
395
396   if (level < 0) level = 0;
397
398   CVWriteBackTraceEntryInfo(conn,
399                             instance_id,
400                             level, /* frameNo */
401                             funcname);
402
403   if (demangled_name)
404     free(demangled_name);
405 }
406
407 /* Call this just prior to printing out the name & value of a variable.  This
408    tells the kernel where to annotate the output. */
409
410 /* The args are:
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.
418 */
419
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 */
423
424 void
425 cadillac_start_variable_annotation(expression, symbol, type, valaddr, field)
426      char *expression;
427      struct symbol *symbol;
428      struct type *type;
429      CORE_ADDR valaddr;
430      char *field;
431 {
432   int ref_type;
433   int stor_cl;
434   enum type_code type_code;
435   enum address_class sym_class;
436   char *type_cast;
437
438   send_stack_info();
439
440   strcpy(*last_expr++, expression);
441   *last_expr = *(last_expr-1) + strlen(expression);
442
443   switch (TYPE_CODE(type))
444     {
445     case TYPE_CODE_ARRAY:
446     case TYPE_CODE_STRUCT:
447     case TYPE_CODE_UNION:
448     case TYPE_CODE_ENUM:
449     case TYPE_CODE_INT:
450     case TYPE_CODE_FLT:
451       ref_type = CValueValueRef;
452       break;
453     case TYPE_CODE_PTR:
454       ref_type = CValuePointerRef;
455       break;
456     default:
457       ref_type = CValueUndefRef;
458       break;
459     }
460
461 /* Make sure that pointer points at something we understand */
462
463   if (ref_type == CValuePointerRef)
464     switch (TYPE_CODE(TYPE_TARGET_TYPE(type)))
465       {
466       case TYPE_CODE_PTR:
467       case TYPE_CODE_ARRAY:
468       case TYPE_CODE_STRUCT:
469       case TYPE_CODE_UNION:
470       case TYPE_CODE_ENUM:
471       case TYPE_CODE_INT:
472       case TYPE_CODE_FLT:
473         break;
474       default:
475         ref_type = CValueUndefRef;
476         break;
477       }
478
479   if (symbol)
480     {
481       sym_class = SYMBOL_CLASS(symbol);
482
483       switch (sym_class)
484         {
485         case LOC_CONST:
486         case LOC_CONST_BYTES:
487           stor_cl = CValueStorStaticConst;
488           break;
489         case LOC_STATIC:
490           stor_cl = CValueStorStaticVar;
491           break;
492         case LOC_REGISTER:
493         case LOC_REGPARM:
494           stor_cl = CValueStorRegister;
495           break;
496         case LOC_ARG:
497         case LOC_REF_ARG:
498         case LOC_LOCAL:
499         case LOC_LOCAL_ARG:
500           stor_cl = CValueStorLocalVar;
501           break;
502         default:
503           stor_cl = CValueStorUndef;
504           break;
505         }
506     }
507   else
508     stor_cl = CValueStorUndef;
509
510   type_cast = TYPE_NAME(type);
511
512   CVWriteValueBeginInfo(conn,
513                         instance_id,
514                         valaddr,
515                         ref_type,
516                         stor_cl,
517                         0,      /* XXX - frameno */
518                         cum_expr,
519                         field,
520                         type_cast,
521                         "");    /* transcript */
522 }
523
524 void
525 cadillac_end_variable_annotation()
526 {
527   last_expr--;                  /* Pop the expr stack */
528   **last_expr = '\000';         /* Cut off the last part of the expr */
529
530   CVWriteValueEndInfo(conn,
531                       instance_id,
532                       "");      /* transcript */
533 }
534 \f
535 /* Tell the kernel that the target is now running. */
536
537 static void
538 go_busy()
539 {
540   CVWriteProgramBusyInfo(conn,
541                          instance_id,
542                          "");   /* XXX ? transcript */
543   CWriteRequestBuffer(conn);    /* Must take place synchronusly! */
544   stack_info_valid = 0;
545 }
546
547 \f
548 void
549 cadillac_symbol_file(objfile)
550      struct objfile *objfile;
551 {
552   CVWriteSymbolTableInfo(conn,
553                          objfile->name,
554                          "");   /* Transcript */
555 }
556
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.
561  */
562
563 /* Linked list of queued up commands */
564 static struct command_line *queued_commands = 0;
565 static struct command_line *last_queued_command = 0;
566
567 /* Call this routine to save a command for later.  The command string is
568    copied into freshly malloc'ed memory. */
569
570 static void
571 queue_command(cmd)
572      char *cmd;
573 {
574   char *buf;
575   struct command_line *cl;
576   unsigned long s;
577
578   s = (strlen(cmd) + 1) + 7 & ~(unsigned long)7;
579
580   buf = (char *)xmalloc(s + sizeof(struct command_line));
581   cl = (struct command_line *)(buf + s);
582   cl->next = 0;
583   cl->line = buf;
584
585   strncpy(cl->line, cmd, s);
586
587   if (queued_commands)
588     last_queued_command->next = cl;
589   else
590     queued_commands = cl;
591
592   last_queued_command = cl;
593 }
594
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. */
598
599 static char *
600 dequeue_command()
601 {
602   struct command_line *cl;
603   char *cmd;
604
605   cl = queued_commands;
606
607   if (!cl)
608     return NULL;
609
610   queued_commands = cl->next;
611
612   return cl->line;
613 }
614
615 static void
616 execute_command_1(va_alist)
617      va_dcl
618 {
619   char buf[100];                /* XXX - make buf dynamic! */
620   
621   int echo;
622   int queue;
623   char *cmd;
624   va_list args;
625
626   va_start(args);
627
628   echo = va_arg(args, int);
629   queue = va_arg(args, int);
630   cmd = va_arg(args, char *);
631
632   vsprintf(buf, cmd, args);
633
634   if (queue)
635     queue_command(buf);
636   else
637     {
638       if (echo)
639         printf_filtered("%s\n", buf);
640       execute_command(buf, 1);
641     }
642
643   va_end(args);
644 }
645
646 #ifdef KERNEL_RECORD
647 FILE *kerout;
648
649 static int
650 kernel_record(fd, ptr, num)
651      int fd, num;
652      char *ptr;
653
654 {
655   fwrite(ptr, num, 1, kerout);
656   fflush(kerout);
657   return write(fd, ptr, num);
658 }
659 #endif
660
661 void
662 cadillac_condition_breakpoint(b)
663      struct breakpoint *b;
664 {
665   CVWriteBreakConditionInfo(conn,
666                             instance_id,
667                             b->number,
668                             b->cond_string ? b->cond_string : "",
669                             ""  /* transcript */
670                             );
671 }
672
673 void
674 cadillac_commands_breakpoint(b)
675      struct breakpoint *b;
676 {
677   struct command_line *l;
678
679   CVWriteBreakCommandBegInfo(conn,
680                              instance_id,
681                              b->number,
682                              ""); /* transcript */
683
684   for (l = b->commands; l; l = l->next)
685     CVWriteBreakCommandEntryInfo(conn,
686                                  instance_id,
687                                  l->line,
688                                  ""); /* transcript */
689
690   CVWriteBreakCommandEndInfo(conn,
691                              instance_id,
692                              ""); /* transcript */
693 }
694
695 static void
696 breakpoint_notify(b, action)
697      struct breakpoint *b;
698      int action;
699 {
700   struct symbol *sym;
701   char *funcname = "";
702   char *filename;
703   char *included_in_filename = "";
704
705   if (b->type != bp_breakpoint)
706     return;
707
708   filename = full_filename(b->symtab);
709
710   sym = find_pc_function(b->address);
711   if (sym)
712     funcname = SYMBOL_NAME(sym);
713
714   CVWriteBreakpointInfo (conn,
715                          instance_id,
716                          b->number,
717                          b->line_number,
718                          CFileLinePos,
719                          CBreakOnInstrAccess,
720                          action,
721                          b->ignore_count,
722                          funcname,
723                          filename ? filename : "",
724                          "",    /* included_in_filename */
725                          ""     /* transcript */
726                          );
727
728   if (b->commands)
729     cadillac_commands_breakpoint(b);
730
731   cadillac_condition_breakpoint(b);
732
733   if (filename)
734     free(filename);
735 }
736
737 void
738 cadillac_create_breakpoint(b)
739      struct breakpoint *b;
740 {
741   breakpoint_notify(b, CEnableBreakpoint);
742 }
743
744 void
745 cadillac_delete_breakpoint(b)
746      struct breakpoint *b;
747 {
748   breakpoint_notify(b, CDeleteBreakpoint);
749 }
750
751 void
752 cadillac_enable_breakpoint(b)
753      struct breakpoint *b;
754 {
755   breakpoint_notify(b, CEnableBreakpoint);
756 }
757
758 void
759 cadillac_disable_breakpoint(b)
760      struct breakpoint *b;
761 {
762   breakpoint_notify(b, CDisableBreakpoint);
763 }
764
765 void
766 cadillac_ignore_breakpoint(b)
767      struct breakpoint *b;
768 {
769   breakpoint_notify(b, CBreakAttrUnchanged);
770 }
771 \f
772 /* Open up a pty and its associated tty.  Return the fd of the tty. */
773
774 static void
775 getpty()
776 {
777   int n, ptyfd, ttyfd;
778   static char dev[30];
779   struct stat statbuf;
780   struct termios termios;
781
782 #define HIGHPTY (('z' - 'p') * 16 - 1)
783
784   for (n = 0; n <= HIGHPTY; n++)
785     {
786       sprintf(dev, "/dev/pty%c%x", n/16 + 'p', n%16);
787       if (stat(dev, &statbuf))
788         break;
789       ptyfd = open(dev, O_RDWR);
790       if (ptyfd < 0)
791         continue;
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;}
795
796       /* Setup pty for non-blocking I/O.  Also make it give us a SIGIO when
797          there's data available.  */
798
799       n = fcntl(ptyfd, F_GETFL, 0);
800       fcntl(ptyfd, F_SETFL, n|FNDELAY|FASYNC);
801       fcntl(ptyfd, F_SETOWN, getpid());
802
803       tcgetattr(ttyfd, &termios);
804       termios.c_oflag &= ~OPOST; /* No post-processing */
805       tcsetattr(ttyfd, TCSANOW, &termios);
806
807       inferior_pty = ptyfd;
808       inferior_tty = ttyfd;
809       return;
810     }
811
812   error ("getpty: can't get a pty\n");
813 }
814 \f
815 /* Examine a protocol packet from the driver. */
816
817 static void
818 kernel_dispatch(queue)
819      int queue;                 /* Non-zero means we should just queue up
820                                    commands. */
821 {
822   register CHeader *head;
823
824   head = (CHeader *)CPeekNextRequest (conn);
825   if (head == NULL)
826     {
827       fprintf (stderr, "EOF on kernel read!\n");
828       exit (1);
829     }
830
831   if (head->reqType < LastTtyRequestRType)
832     {
833       CTtyRequest* req = CReadTtyRequest (conn);
834       switch (req->head.reqType)
835         {
836         case AcceptConnectionRType:
837           /* Tell the rest of the world that cadillac is now set up */
838           CSkipRequest (conn);
839           break;
840
841         case RefuseConnectionRType:
842           fprintf (stderr, "Debugger connection refused\n");
843           exit (1);
844
845         case KillProgramRType:
846           exit (0);
847
848         case TextIORType:
849           {
850             char *p;
851             ReqLen len;
852
853             p = CGetVstring(conn, &len);
854             kernel_to_pty(p, len);
855           }
856           break;
857         default:
858           fprintf(stderr, "Unknown request type = %d\n",
859                   req->head.reqType);
860           break;
861         }
862     }
863   else
864     {
865       CVDebuggerRequest *req = CVReadDebuggerRequest (conn);
866       if (!req)
867         {
868           fprintf (stderr, "CVReadDebuggerRequest returned NULL, type = %d\n",
869                    head->reqType);
870           exit(1);
871         }
872
873       switch (req->head.request->reqType)
874         {
875         case OpenProgramInstanceRType:
876           {
877             char *arglist, buf[100]; /* XXX - Make buf dynamic! */
878             int arglen;
879             /* XXX - should notice when program_id changes */
880             arglist = req->openProgramInstance.progArglist.text;
881             arglen = req->openProgramInstance.progArglist.byteLen;
882
883             execute_command_1(1, queue, "break main");
884             execute_command_1(1, queue, "enable delete $bpnum");
885             if (arglist)
886               {
887                 execute_command_1(1, queue, "set args %.*s", arglen, arglist);
888               }
889             execute_command_1(1, queue, "run");
890           }
891           break;
892         case SearchPathRType:
893           directory_command(req->searchPath.searchPath.text, 0);
894           break;
895         case QuitDebuggerRType:
896           execute_command_1(1, queue, "quit");
897           break;
898         case RunRType:
899           if (req->run.request->useArglist == CNewArglist)
900             {
901               execute_command_1(1, queue, "set args %.*s",
902                                 req->run.progArglist.byteLen,
903                                 req->run.progArglist.text);
904             }
905           execute_command_1(1, queue, "run");
906           break;
907         case ContinueRType:
908           execute_command_1(1, queue, "continue");
909           break;
910         case StepRType:
911           execute_command_1(1, queue, "step %d", req->step.request->stepCount);
912           break;
913         case NextRType:
914           execute_command_1(1, queue, "next %d", req->next.request->nextCount);
915           break;
916         case ChangeStackFrameRType:
917           switch (req->changeStackFrame.request->frameMovement)
918             {
919             case CToCurrentStackFrame:
920               execute_command_1(1, queue, "frame %d",
921                                 req->changeStackFrame.request->frameNo);
922               break;
923             case CToInnerStackFrame:
924               execute_command_1(1, queue, "down %d",
925                                 req->changeStackFrame.request->frameNo);
926               break;
927             case CToOuterStackFrame:
928               execute_command_1(1, queue, "up %d",
929                                 req->changeStackFrame.request->frameNo);
930               break;
931             case CToAbsoluteStackFrame:
932               execute_command_1(1, queue, "frame %d",
933                                 req->changeStackFrame.request->frameNo);
934               break;
935             }
936           break;
937         case BackTraceRType:
938           /* XXX - deal with limit??? */
939           execute_command_1(1, queue, "backtrace");
940           break;
941         case FinishRType:
942           execute_command_1(1, queue, "finish");
943           break;
944         case TerminateProgramRType:
945           execute_command_1(1, queue, "kill");
946           break;
947         case NewBreakpointRType:
948           {
949             char *tail;
950             int skipped;
951
952             tail = strrchr(req->newBreakpoint.fileName.text, '/');
953             if (!tail)
954               tail = req->newBreakpoint.fileName.text;
955             else
956               tail++;
957             skipped = tail - req->newBreakpoint.fileName.text;
958             execute_command_1(1, queue, "break %.*s:%d",
959                               req->newBreakpoint.fileName.byteLen - skipped,
960                               tail,
961                               req->newBreakpoint.request->fileLinePos);
962           }
963           break;
964         case StopRType:
965           killpg(pgrp_inferior, SIGINT);
966           break;
967         case UserInputRType:
968           {
969             char *text;
970             long len;
971
972             /* XXX - should really break command up into seperate lines
973                and spoon-feed it to execute_command */
974
975             text = req->userInput.userInput.text;
976             len = req->userInput.userInput.byteLen;
977
978             if (text[len-1] == '\n') text[len-1] = '\000';
979
980             while (*text == ' ' || *text == '\t') text++;
981
982             if (strcmp(text, "]*[") == 0) /* XXX - What does this mean??? */
983               break;
984
985             if (*text != '\000')
986               execute_command_1(0, queue, "%s", text);
987             else
988               print_prompt();   /* User just typed a blank line */
989           }
990           break;
991         case QueryResponseRType:
992           {
993             char *resp;
994
995             if (req->queryResponse.request->response)
996               resp = "y";
997             else
998               resp = "n";
999             execute_command_1(1, 1, resp);
1000             printf_filtered("%s\n", resp);
1001           }
1002           break;
1003         case ChangeBreakpointRType:
1004           switch (req->changeBreakpoint.request->breakpointAttr)
1005             {
1006             case CBreakAttrUnchanged:
1007               execute_command_1(1, queue, "ignore %d %d",
1008                                 req->changeBreakpoint.request->breakpointId,
1009                                 req->changeBreakpoint.request->ignoreCount);
1010               break;
1011             case CEnableBreakpoint:
1012               execute_command_1(1, queue, "enable %d",
1013                                 req->changeBreakpoint.request->breakpointId);
1014               break;
1015             case CDisableBreakpoint:
1016               execute_command_1(1, queue, "disable %d",
1017                                 req->changeBreakpoint.request->breakpointId);
1018               break;
1019             case CDeleteBreakpoint:
1020               execute_command_1(1, queue, "delete %d",
1021                                 req->changeBreakpoint.request->breakpointId);
1022               break;
1023             case CEnableDisableBreakpoint:
1024               execute_command_1(1, queue, "enable once %d",
1025                                 req->changeBreakpoint.request->breakpointId);
1026               break;
1027             case CEnableDeleteBreakpoint:
1028               execute_command_1(1, queue, "enable delete %d",
1029                                 req->changeBreakpoint.request->breakpointId);
1030               break;
1031             default:
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);
1041               break;
1042             }
1043           break;
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);
1049           break;
1050         case BreakCommandsRType:
1051           /* Put pointers to where cadillac_command_line_input() can find
1052              them. */
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;
1061           break;
1062         case ShowValueRType:
1063           {
1064             char expr[100], *p = expr;
1065
1066             expr[0] = 0;
1067
1068             if (req->showValue.request->ref_type == CValuePointerRef)
1069               strcat(expr, "* ");
1070
1071             if (req->showValue.type_cast.byteLen)
1072               {
1073                 strcat(expr, "(");
1074                 strncat(expr, req->showValue.type_cast.text,
1075                         req->showValue.type_cast.byteLen);
1076                 strcat(expr, ") ");
1077               }
1078
1079             if (req->showValue.field.byteLen)
1080               strcat(expr, "(");
1081
1082             strncat(expr, req->showValue.expression.text,
1083                     req->showValue.expression.byteLen);
1084
1085             if (req->showValue.field.byteLen)
1086               {
1087                 strcat(expr, ")");
1088
1089                 strncat(expr, req->showValue.field.text,
1090                         req->showValue.field.byteLen);
1091               }
1092
1093             execute_command_1(1, queue, "print %s", expr);
1094           }
1095           break;
1096         case SetValueRType:
1097           {
1098             char expr[100], *p = expr;
1099
1100             expr[0] = 0;
1101
1102             if (req->setValue.request->ref_type == CValuePointerRef)
1103               strcat(expr, "* ");
1104
1105 #if 0
1106             if (req->setValue.type_cast.byteLen)
1107               {
1108                 strcat(expr, "(");
1109                 strncat(expr, req->setValue.type_cast.text,
1110                         req->setValue.type_cast.byteLen);
1111                 strcat(expr, ") ");
1112               }
1113 #endif
1114             if (req->setValue.field.byteLen)
1115               strcat(expr, "(");
1116
1117             strncat(expr, req->setValue.expression.text,
1118                     req->setValue.expression.byteLen);
1119
1120             if (req->setValue.field.byteLen)
1121               {
1122                 strcat(expr, ")");
1123
1124                 strncat(expr, req->setValue.field.text,
1125                         req->setValue.field.byteLen);
1126               }
1127
1128             execute_command_1(1, queue, "print %s = (%s) %s", expr,
1129                               req->setValue.type_cast.text,
1130                               req->setValue.value.text);
1131           }
1132           break;
1133         default:
1134           fprintf(stderr, "Unknown request type = %d\n",
1135                   req->head.request->reqType);
1136           break;
1137         }
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
1141                      free() anyway! */
1142     }
1143 }
1144 \f
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.  */
1147
1148 static int
1149 wait_for_events(poll)
1150      int poll;
1151 {
1152   fd_set readfds;
1153   int numfds;
1154   int eventmask = 0;
1155   static struct timeval tv = {0};
1156
1157   /* Output all pending requests. */
1158   CWriteRequestBuffer(conn);
1159
1160   FD_ZERO(&readfds);
1161
1162   /* Wait till there's some activity from the kernel or the pty. */
1163   do
1164     {
1165       FD_SET(kerfd, &readfds);
1166       if (inferior_pty > 0)
1167         FD_SET(inferior_pty, &readfds);
1168       if (poll)
1169         numfds = select(sizeof(readfds)*8, &readfds, 0, 0, &tv);
1170       else
1171         numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0);
1172     }
1173   while (numfds <= 0 && !poll);
1174
1175   if (FD_ISSET(inferior_pty, &readfds))
1176     eventmask |= PTY_EVENT;
1177
1178   if (FD_ISSET(kerfd, &readfds))
1179     eventmask |= KERNEL_EVENT;
1180
1181   return eventmask;
1182 }
1183 \f
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. */
1187
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().  */
1196
1197 char *
1198 cadillac_command_line_input()
1199 {
1200   char *p;
1201
1202   if (doing_breakcommands_message)
1203     {
1204       if (command_line_length <= 0)
1205         return (char *)NULL;
1206
1207       p = command_line_text;
1208
1209       while (command_line_length-- > 0)
1210         {
1211           if (*command_line_text == '\n')
1212             {
1213               *command_line_text = '\000';
1214               command_line_text++;
1215               break;
1216             }
1217           command_line_text++;
1218         }
1219
1220       printf_filtered("%s\n", p);
1221       return p;
1222     }
1223   else
1224     {
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. */
1230
1231       int eventmask;
1232       static char buf[100];
1233       
1234       eventmask = wait_for_events(0);
1235
1236       if (eventmask & PTY_EVENT)
1237         pty_to_kernel();
1238
1239       if (eventmask & KERNEL_EVENT)
1240         kernel_dispatch(1);     /* Queue up commands */
1241
1242 /* Note that command has been echoed by the time we get here */
1243
1244       p = dequeue_command();
1245
1246       if (p)
1247         {
1248           strncpy(buf, p, sizeof(buf));
1249           free(p);
1250           return buf;
1251         }
1252       else
1253         return NULL;
1254     }
1255 }
1256 \f
1257 /* Establish contact with the kernel. */
1258
1259 void
1260 cadillac_initialize(cadillac_id, execarg)
1261      char *cadillac_id;
1262      char *execarg;
1263 {
1264   CTtyRequest *req;
1265   char *ctmp;
1266   extern long strtol(char *str, char **ptr, int base);
1267   char pathname[MAXPATHLEN];
1268   int n;
1269
1270   if (!execarg) execarg = "";
1271
1272   printf("gdb-debugger pid=%d\n", getpid()); /* XXX - debugging only */
1273   
1274   /* First establish the connection with the kernel. */
1275
1276   kerfd = COpenClientSocket(NULL);
1277   if (kerfd < 0) {
1278     printf("COpenClientSocket() failed\n");
1279     exit(1);
1280   }
1281
1282   /* Setup for I/O interrupts when appropriate. */
1283
1284   n = fcntl(kerfd, F_GETFL, 0);
1285   fcntl(kerfd, F_SETFL, n|FASYNC);
1286   fcntl(kerfd, F_SETOWN, getpid());
1287
1288   /* Setup connection buffering. */
1289
1290   CSetSocketBufferSize (kerfd, 12000);
1291
1292   /* Generate a new connection control block. */
1293
1294   conn = NewConnection (0, kerfd, kerfd);
1295   if (!conn) {
1296     printf("NewConnection() failed\n");
1297     exit(1);
1298   }
1299
1300 #ifdef KERNEL_RECORD
1301   kerout = fopen("kernel.output", "+w");
1302
1303   CReadWriteHooks(conn, conn->previewMethod, conn->readMethod, kernel_record);
1304 #endif
1305
1306   /* Tell the kernel that we are the "debugger". */
1307
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);
1316
1317   /* Tell the kernel that we are actually running. */
1318
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! */
1323
1324   req = CWriteTtyRequest (conn, RunningProgramRType);
1325   req->runningprogram.argc = 8;
1326   getwd (pathname);
1327   CWriteVstring0 (conn, pathname);
1328
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);
1338
1339   /* Tell the kernel our PID and all that */
1340
1341   program_id = 1;
1342   CVWriteDebugProgramInfo(conn,
1343                           getpid(),
1344                           program_id,
1345                           execarg,
1346                           "");
1347
1348   /* Tell the rest of the world that Cadillac is now set up. */
1349   cadillac = 1;
1350
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);
1356 }
1357
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.
1361 */
1362
1363 void
1364 cadillac_call_command(cmdblk, arg, from_tty)
1365      struct cmd_list_element *cmdblk;
1366      char *arg;
1367      int from_tty;
1368 {
1369   if (cmdblk->class == class_run)
1370     {
1371       go_busy();
1372       has_run = 1;
1373       (*cmdblk->function.cfunc)(arg, from_tty);
1374       send_status();
1375     }
1376   else
1377     (*cmdblk->function.cfunc)(arg, from_tty);
1378
1379   print_prompt();
1380 }
1381
1382 void
1383 cadillac_new_process()
1384 {
1385   instance_id = inferior_pid;
1386 }
1387
1388 static void
1389 iosig(signo)
1390      int signo;
1391 {
1392   while (1)
1393     {
1394       int eventmask;
1395
1396       eventmask = wait_for_events(1);
1397
1398       if (eventmask == 0)
1399         return;
1400
1401       if (eventmask & PTY_EVENT)
1402         pty_to_kernel();
1403
1404       if (eventmask & KERNEL_EVENT)
1405         kernel_dispatch(1);
1406     }
1407 }
1408
1409 int
1410 cadillac_wait(status)
1411      int *status;
1412 {
1413   int pid;
1414
1415   signal(SIGIO, iosig);
1416
1417   pid = wait(status);
1418
1419   signal(SIGIO, SIG_DFL);
1420   return pid;
1421 }
1422
1423 static void
1424 null_routine(arg)
1425      int arg;
1426 {
1427 }
1428
1429 /* All requests from the Cadillac kernel eventually end up here. */
1430
1431 void
1432 cadillac_main_loop()
1433 {
1434   CTtyRequest *req;
1435   struct cleanup *old_chain;
1436
1437   doing_breakcommands_message = 0;
1438
1439 /* We will come thru here any time there is an error, so send status if
1440    necessary. */
1441
1442   send_status();
1443
1444   print_prompt();
1445
1446   /* The actual event loop! */
1447
1448   while (1)
1449     {
1450       int eventmask;
1451       char *cmd;
1452
1453       old_chain = make_cleanup(null_routine, 0);
1454
1455 /* First, empty out the command queue, then check for new requests. */
1456
1457       while (cmd = dequeue_command())
1458         {
1459           execute_command_1(1, 0, cmd);
1460           free(cmd);
1461         }
1462
1463       eventmask = wait_for_events(0);
1464
1465       if (eventmask & PTY_EVENT)
1466         pty_to_kernel();
1467
1468       if (eventmask & KERNEL_EVENT)
1469         kernel_dispatch(0);
1470
1471       bpstat_do_actions(&stop_bpstat);
1472       do_cleanups(old_chain);
1473     }
1474 }
This page took 0.103276 seconds and 4 git commands to generate.