* energize.c (send_location): New routine to consolidate all
[external/binutils.git] / gdb / energize.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 "energize/connection.h"
31 #include "energize/genericreq.h"
32 #include "energize/debuggerreq.h"
33 #include "energize/debuggerconn.h"
34 #include "energize/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 energize interface. */
49 int energize = 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 /* The name of the executable file */
73 static char *exec_file;
74
75 /* Tell energize_command_line_input() where to get its text from */
76 static int doing_breakcommands_message = 0;
77
78 /* Stash command text here */
79 static char *command_line_text = 0;
80 static int command_line_length = 0;
81
82 /* Flags returned by wait_for_events() */
83 #define KERNEL_EVENT 1
84 #define PTY_EVENT 2
85
86 \f
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. */
89
90 void
91 energize_fputs(ptr)
92      const char *ptr;
93 {
94   if (conn)
95     CVWriteTranscriptInfo (conn, instance_id, (char *)ptr);
96   else
97     fputs (ptr, stdout);
98 }
99
100 void
101 energize_query(query, args)
102      char *query;
103      va_list args;
104 {
105   char buf[100];
106
107   if (!energize)
108     return;
109
110   vsprintf(buf, query, args);
111
112   CVWriteQueryInfo(conn,
113                    instance_id,
114                    CQueryConfirm,
115                    qno_unknown,
116                    buf,
117                    "");         /* transcript */
118 }
119
120 void
121 energize_acknowledge_query(ack)
122      char *ack;
123 {
124   CVWriteQueryInfo(conn,
125                    instance_id,
126                    CQueryAcknowleged,
127                    0,
128                    ack,
129                    "");         /* transcript */
130 }
131
132 /* Copy all data from the pty to the kernel. */
133
134 static void
135 pty_to_kernel()
136 {
137   CTtyRequest *req;
138   char buf[1024];
139   int cc;
140
141   while (1)
142     {
143       cc = read(inferior_pty, buf, sizeof(buf));
144
145       if (cc == 0
146           || (cc < 0
147               && errno == EWOULDBLOCK))
148         break;
149
150       if (cc < 0)
151         {
152           close(inferior_pty);
153           inferior_pty = -1;
154           perror("pty read error");
155           break;
156         }
157
158       req = CWriteTtyRequest(conn, TextIORType);
159       CWriteVstringLen(conn, buf, cc);
160       CWriteLength(conn);
161     }
162   CWriteRequestBuffer(conn);
163 }
164
165 /* Copy data from the kernel to the pty. */
166
167 static void
168 kernel_to_pty(data, len)
169      char *data;
170      int len;
171 {
172   int cc;
173
174   cc = write(inferior_pty, data, len);
175
176   if (cc != len)
177     {
178       if (cc < 0)
179         {
180           close(inferior_pty);
181           inferior_pty = -1;
182           perror("pty write error");
183           return;
184         }
185       printf("Couldn't write all the data to the pty, wanted %d, got %d\n",
186              len, cc);
187     }
188 }
189 \f
190 static char *
191 full_filename(symtab)
192      struct symtab *symtab;
193 {
194   int pathlen;
195   char *filename;
196
197   if (!symtab)
198     return NULL;
199
200   if (symtab->fullname)
201     return savestring(symtab->fullname, strlen(symtab->fullname));
202
203   if (symtab->dirname)
204     pathlen = strlen(symtab->dirname);
205   else
206     pathlen = 0;
207   if (symtab->filename)
208     pathlen += strlen(symtab->filename);
209
210   filename = xmalloc(pathlen+1);
211
212   if (symtab->dirname)
213     strcpy(filename, symtab->dirname);
214   else
215     *filename = '\000';
216   if (symtab->filename)
217     strcat(filename, symtab->filename);
218
219   return filename;
220 }
221
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.
224
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
233    fails). */
234
235 struct pclist
236 {
237   CORE_ADDR pc;
238   struct pclist *next;
239 };
240
241 /* Non-zero means that Energize kernel already knows how high the stack is. */
242 static int stack_info_valid = 0;
243
244 static void
245 send_stack_info()
246 {
247   struct pclist *pclist = 0, *pli, *opli;
248   static struct pclist *old_pclist;
249   FRAME frame;
250   int height, similar;
251
252   if (stack_info_valid)
253     return;
254
255   height = 0;
256   similar = 0;
257
258 /* First, calculate the stack height, and build the new pclist */
259
260   for (frame = get_current_frame();
261        frame != 0;
262        frame = get_prev_frame(frame))
263     {
264       (height)++;
265       pli = (struct pclist *)xmalloc(sizeof(struct pclist));
266
267       pli->pc = frame->pc;
268       pli->next = pclist;
269       pclist = pli;
270     }
271
272 /* Now, figure out how much of the stack hasn't changed */
273
274   for (pli = pclist, opli = old_pclist;
275        pli != 0 && opli != 0;
276        pli = pli->next, opli = opli->next, (similar)++)
277     {
278       if ((pli->pc != opli->pc)
279           && (get_pc_function_start(pli->pc)
280               != get_pc_function_start(opli->pc)))
281         break;
282     }
283
284 /* Free up all elements of the old pclist */
285
286   opli = old_pclist;
287
288   while (opli)
289     {
290       pli = opli->next;
291       free (opli);
292       opli = pli;
293     }
294
295   old_pclist = pclist;          /* Install the new pclist */
296
297   CVWriteStackSizeInfo(conn,
298                        instance_id,
299                        height,  /* Frame depth */
300                        CInnerFrameIs0,
301                        similar, /* Frame diff */
302                        ""       /* Transcript */
303                        );
304
305   stack_info_valid = 1;
306 }
307
308 /* Tell the Energize server about the file and line # that corresponds to pc,
309    and which stack frame level that pc corresponds to. */
310
311 static void
312 send_location(pc, frame_level)
313      CORE_ADDR pc;
314      int frame_level;
315 {
316   char *funcname, *filename;
317   struct symtab_and_line sal;
318   struct symbol *symbol;
319
320   sal = find_pc_line(pc, 0);
321   symbol = find_pc_function(pc);
322
323   funcname = symbol ? symbol->name : "";
324   filename = full_filename(sal.symtab);
325
326   send_stack_info();
327
328   CVWriteStackFrameInfo(conn,
329                         instance_id,
330                         sal.line,
331                         CFileLinePos,
332                         frame_level,
333                         funcname,
334                         filename,
335                         ""      /* XXX ? transcript */
336                         );
337   if (filename)
338     free(filename);
339 }
340
341 /* Tell the kernel where we are in the program, and what the stack looks like.
342    */
343
344 static void
345 send_status()
346
347   char *funcname;
348   struct symbol *symbol;
349   static int sent_prog_inst = 0;
350
351   symbol = find_pc_function(stop_pc);
352   funcname = symbol ? symbol->name : "";
353
354   if (!has_run)
355     return;
356
357   if (inferior_pid == 0)        /* target has died */
358     {
359       CVWriteProgramTerminatedInfo(conn,
360                                    instance_id,
361                                    ""
362                                    );
363       return;
364     }
365
366   if (!sent_prog_inst)
367     {
368       sent_prog_inst = 1;
369       CVWriteProgramInstanceInfo(conn,
370                                  program_id,
371                                  instance_id,
372                                  "", /* hostname */
373                                  "", /* arglist */
374                                  ""
375                                  );
376     }
377
378   send_location(stop_pc,
379                 selected_frame_level); /* Had better be 0! */
380
381   CVWriteProgramStoppedInfo(conn,
382                             instance_id,
383                             0,  /* XXX - breakpoint # or signal # */
384                             CDebuggerCommand,
385                             funcname,
386                             ""  /* XXX ? transcript */
387                             );
388
389 }
390
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. */
393
394 void
395 energize_annotate_function(funcname, arg_mode, level)
396      char *funcname;
397      int arg_mode;
398      int level;
399 {
400   extern int demangle;
401   char *demangled_name = NULL;
402
403   if (funcname == NULL)
404     return;
405
406   if (demangle)
407     {
408       demangled_name = cplus_demangle(funcname, arg_mode);
409
410       if (demangled_name)
411         {
412           funcname = demangled_name;
413           printf_filtered("'");
414         }
415     }
416
417   send_stack_info();
418
419   if (level < 0) level = 0;
420
421   CVWriteBackTraceEntryInfo(conn,
422                             instance_id,
423                             level, /* frameNo */
424                             funcname);
425
426   if (demangled_name)
427     {
428       free(demangled_name);
429       printf_filtered("'");
430     }
431 }
432
433 /* Call this just prior to printing out the name & value of a variable.  This
434    tells the kernel where to annotate the output. */
435
436 /* The args are:
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.
444 */
445
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 */
449
450 void
451 energize_start_variable_annotation(expression, symbol, type, valaddr, field)
452      char *expression;
453      struct symbol *symbol;
454      struct type *type;
455      CORE_ADDR valaddr;
456      char *field;
457 {
458   int ref_type;
459   int stor_cl;
460   enum type_code type_code;
461   enum address_class sym_class;
462   char *type_cast;
463
464   if (!energize)
465     return;
466
467   send_stack_info();
468
469   strcpy(*last_expr++, expression);
470   *last_expr = *(last_expr-1) + strlen(expression);
471
472   switch (TYPE_CODE(type))
473     {
474     case TYPE_CODE_ARRAY:
475     case TYPE_CODE_STRUCT:
476     case TYPE_CODE_UNION:
477     case TYPE_CODE_ENUM:
478     case TYPE_CODE_INT:
479     case TYPE_CODE_FLT:
480       ref_type = CValueValueRef;
481       break;
482     case TYPE_CODE_PTR:
483       ref_type = CValuePointerRef;
484       break;
485     default:
486       ref_type = CValueUndefRef;
487       break;
488     }
489
490 /* Make sure that pointer points at something we understand */
491
492   if (ref_type == CValuePointerRef)
493     switch (TYPE_CODE(TYPE_TARGET_TYPE(type)))
494       {
495       case TYPE_CODE_PTR:
496       case TYPE_CODE_ARRAY:
497       case TYPE_CODE_STRUCT:
498       case TYPE_CODE_UNION:
499       case TYPE_CODE_ENUM:
500       case TYPE_CODE_INT:
501       case TYPE_CODE_FLT:
502         break;
503       default:
504         ref_type = CValueUndefRef;
505         break;
506       }
507
508   if (symbol)
509     {
510       sym_class = SYMBOL_CLASS(symbol);
511
512       switch (sym_class)
513         {
514         case LOC_CONST:
515         case LOC_CONST_BYTES:
516           stor_cl = CValueStorStaticConst;
517           break;
518         case LOC_STATIC:
519           stor_cl = CValueStorStaticVar;
520           break;
521         case LOC_REGISTER:
522         case LOC_REGPARM:
523           stor_cl = CValueStorRegister;
524           break;
525         case LOC_ARG:
526         case LOC_REF_ARG:
527         case LOC_LOCAL:
528         case LOC_LOCAL_ARG:
529           stor_cl = CValueStorLocalVar;
530           break;
531         default:
532           stor_cl = CValueStorUndef;
533           break;
534         }
535     }
536   else
537     stor_cl = CValueStorUndef;
538
539   type_cast = TYPE_NAME(type);
540
541   CVWriteValueBeginInfo(conn,
542                         instance_id,
543                         valaddr,
544                         ref_type,
545                         stor_cl,
546                         0,      /* XXX - frameno */
547                         cum_expr,
548                         field,
549                         type_cast,
550                         "");    /* transcript */
551 }
552
553 void
554 energize_end_variable_annotation()
555 {
556   if (!energize)
557     return;
558
559   last_expr--;                  /* Pop the expr stack */
560   **last_expr = '\000';         /* Cut off the last part of the expr */
561
562   CVWriteValueEndInfo(conn,
563                       instance_id,
564                       "");      /* transcript */
565 }
566 \f
567 /* Tell the kernel that the target is now running. */
568
569 static void
570 go_busy()
571 {
572   CVWriteProgramBusyInfo(conn,
573                          instance_id,
574                          "");   /* XXX ? transcript */
575   CWriteRequestBuffer(conn);    /* Must take place synchronusly! */
576   stack_info_valid = 0;
577 }
578
579 \f
580 void
581 energize_symbol_file(objfile)
582      struct objfile *objfile;
583 {
584   if (!energize)
585     return;
586
587   CVWriteSymbolTableInfo(conn,
588                          objfile->name,
589                          "");   /* Transcript */
590 }
591
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.
596  */
597
598 /* Linked list of queued up commands */
599 static struct command_line *queued_commands = 0;
600 static struct command_line *last_queued_command = 0;
601
602 /* Call this routine to save a command for later.  The command string is
603    copied into freshly malloc'ed memory. */
604
605 static void
606 queue_command(cmd)
607      char *cmd;
608 {
609   char *buf;
610   struct command_line *cl;
611   unsigned long s;
612
613   s = (strlen(cmd) + 1) + 7 & ~(unsigned long)7;
614
615   buf = (char *)xmalloc(s + sizeof(struct command_line));
616   cl = (struct command_line *)(buf + s);
617   cl->next = 0;
618   cl->line = buf;
619
620   strncpy(cl->line, cmd, s);
621
622   if (queued_commands)
623     last_queued_command->next = cl;
624   else
625     queued_commands = cl;
626
627   last_queued_command = cl;
628 }
629
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. */
633
634 static char *
635 dequeue_command()
636 {
637   struct command_line *cl;
638   char *cmd;
639
640   cl = queued_commands;
641
642   if (!cl)
643     return NULL;
644
645   queued_commands = cl->next;
646
647   return cl->line;
648 }
649
650 static void
651 execute_command_1(va_alist)
652      va_dcl
653 {
654   char buf[100];                /* XXX - make buf dynamic! */
655   
656   int echo;
657   int queue;
658   char *cmd;
659   va_list args;
660
661   va_start(args);
662
663   echo = va_arg(args, int);
664   queue = va_arg(args, int);
665   cmd = va_arg(args, char *);
666
667   vsprintf(buf, cmd, args);
668
669   if (queue)
670     queue_command(buf);
671   else
672     {
673       if (echo)
674         printf_filtered("%s\n", buf);
675       execute_command(buf, 1);
676     }
677
678   va_end(args);
679 }
680
681 #ifdef KERNEL_RECORD
682 FILE *kerout;
683
684 static int
685 kernel_record(fd, ptr, num)
686      int fd, num;
687      char *ptr;
688
689 {
690   fwrite(ptr, num, 1, kerout);
691   fflush(kerout);
692   return write(fd, ptr, num);
693 }
694 #endif
695
696 void
697 energize_condition_breakpoint(b)
698      struct breakpoint *b;
699 {
700   if (energize)
701     CVWriteBreakConditionInfo(conn,
702                               instance_id,
703                               b->number,
704                               b->cond_string ? b->cond_string : "",
705                               "" /* transcript */
706                               );
707 }
708
709 void
710 energize_commands_breakpoint(b)
711      struct breakpoint *b;
712 {
713   struct command_line *l;
714
715   if (!energize)
716     return;
717
718   CVWriteBreakCommandBegInfo(conn,
719                              instance_id,
720                              b->number,
721                              ""); /* transcript */
722
723   for (l = b->commands; l; l = l->next)
724     CVWriteBreakCommandEntryInfo(conn,
725                                  instance_id,
726                                  l->line,
727                                  ""); /* transcript */
728
729   CVWriteBreakCommandEndInfo(conn,
730                              instance_id,
731                              ""); /* transcript */
732 }
733
734 static void
735 breakpoint_notify(b, action)
736      struct breakpoint *b;
737      int action;
738 {
739   struct symbol *sym;
740   char *funcname = "";
741   char *filename;
742   char *included_in_filename = "";
743
744   if (!energize)
745     return;
746
747   if (b->type != bp_breakpoint)
748     return;
749
750   filename = full_filename(b->symtab);
751
752   sym = find_pc_function(b->address);
753   if (sym)
754     funcname = SYMBOL_NAME(sym);
755
756   CVWriteBreakpointInfo (conn,
757                          instance_id,
758                          b->number,
759                          b->line_number,
760                          CFileLinePos,
761                          CBreakOnInstrAccess,
762                          action,
763                          b->ignore_count,
764                          funcname,
765                          filename ? filename : "",
766                          "",    /* included_in_filename */
767                          ""     /* transcript */
768                          );
769
770   if (b->commands)
771     energize_commands_breakpoint(b);
772
773   energize_condition_breakpoint(b);
774
775   if (filename)
776     free(filename);
777 }
778
779 void
780 energize_create_breakpoint(b)
781      struct breakpoint *b;
782 {
783   breakpoint_notify(b, CEnableBreakpoint);
784 }
785
786 void
787 energize_delete_breakpoint(b)
788      struct breakpoint *b;
789 {
790   breakpoint_notify(b, CDeleteBreakpoint);
791 }
792
793 void
794 energize_enable_breakpoint(b)
795      struct breakpoint *b;
796 {
797   breakpoint_notify(b, CEnableBreakpoint);
798 }
799
800 void
801 energize_disable_breakpoint(b)
802      struct breakpoint *b;
803 {
804   breakpoint_notify(b, CDisableBreakpoint);
805 }
806
807 void
808 energize_ignore_breakpoint(b)
809      struct breakpoint *b;
810 {
811   breakpoint_notify(b, CBreakAttrUnchanged);
812 }
813 \f
814 /* Open up a pty and its associated tty.  Return the fd of the tty. */
815
816 #ifndef NCR486
817 static void
818 getpty()
819 {
820   int n, ptyfd, ttyfd;
821   static char dev[30];
822   struct stat statbuf;
823   struct termios termios;
824
825 #define HIGHPTY (('z' - 'p') * 16 - 1)
826
827   for (n = 0; n <= HIGHPTY; n++)
828     {
829       sprintf(dev, "/dev/pty%c%x", n/16 + 'p', n%16);
830       if (stat(dev, &statbuf))
831         break;
832       ptyfd = open(dev, O_RDWR);
833       if (ptyfd < 0)
834         continue;
835       sprintf(dev, "/dev/tty%c%x", n/16 + 'p', n%16);
836       ttyfd = open(dev, O_RDWR);
837       if (ttyfd < 0)
838         {
839           close(ptyfd);
840           continue;
841         }
842
843       /* Setup pty for non-blocking I/O.  Also make it give us a SIGIO when
844          there's data available.  */
845
846       n = fcntl(ptyfd, F_GETFL, 0);
847       fcntl(ptyfd, F_SETFL, n|FNDELAY|FASYNC);
848       fcntl(ptyfd, F_SETOWN, getpid());
849
850       tcgetattr(ttyfd, &termios);
851       termios.c_oflag &= ~OPOST; /* No post-processing */
852       tcsetattr(ttyfd, TCSANOW, &termios);
853
854       inferior_pty = ptyfd;
855       inferior_tty = ttyfd;
856       return;
857     }
858
859   error ("getpty: can't get a pty\n");
860 }
861 #endif
862 /* Alternate getpty for NCRs */
863
864 #ifdef NCR486 /* LTL */
865 #define MAX_PTM_TRY 16
866 #define MAX_GRANTPT_TRY 4
867 static void
868 getpty()
869 {
870   char *slavename;
871   extern char *ptsname();
872   int j, i;
873   int n, mfd, sfd;
874   struct termios termios;
875
876   /* Number of pseudo-terms is tuneable(16 - 255). System default is 16. */
877   for (i = 0; i < MAX_PTM_TRY; i++)
878     {
879       mfd = open("/dev/ptmx", O_RDWR); /* get the master */
880
881       if (mfd < 0)
882         continue;
883
884       if (grantpt(mfd) < 0)     /* get a slave */
885         for (j = 0; j < MAX_GRANTPT_TRY; j++)
886           if (grantpt(mfd) == 0 )
887             {
888               close(mfd);
889               continue;
890             }
891
892       if (unlockpt(mfd) < 0)
893         {                       /* unlock the slave so he can be opened */
894           close(mfd);
895           continue;
896         }
897
898       slavename = ptsname(mfd); /* get the slave device name */
899       if (!slavename)
900         {
901           close(mfd);
902           continue;
903         }
904
905       sfd = open(slavename, O_RDWR);
906
907       if (sfd < 0)
908         {
909           close(mfd);
910           continue;
911         }
912
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());
918   
919       tcgetattr(sfd, &termios);
920       termios.c_oflag &= ~OPOST;        /* no post-processing */
921       tcsetattr(sfd, TCSANOW, &termios);
922
923       inferior_pty=mfd;
924       inferior_tty=sfd;
925       return;
926     }
927   error ("getpty: can't get a pts\n");
928
929 #endif
930 \f
931 /* Examine a protocol packet from the driver. */
932
933 static void
934 kernel_dispatch(queue)
935      int queue;                 /* Non-zero means we should just queue up
936                                    commands. */
937 {
938   register CHeader *head;
939
940   head = (CHeader *)CPeekNextRequest (conn);
941   if (head == NULL)
942     {
943       fprintf (stderr, "EOF on kernel read!\n");
944       exit (1);
945     }
946
947   if (head->reqType < LastTtyRequestRType)
948     {
949       CTtyRequest* req = CReadTtyRequest (conn);
950       switch (req->head.reqType)
951         {
952         case AcceptConnectionRType:
953           /* Tell the rest of the world that energize is now set up */
954           CSkipRequest (conn);
955           break;
956
957         case RefuseConnectionRType:
958           fprintf (stderr, "Debugger connection refused\n");
959           exit (1);
960
961         case KillProgramRType:
962           exit (0);
963
964         case TextIORType:
965           {
966             char *p;
967             ReqLen len;
968
969             p = CGetVstring(conn, &len);
970             kernel_to_pty(p, len);
971           }
972           break;
973         default:
974           fprintf(stderr, "Unknown Tty request type = %d\n",
975                   req->head.reqType);
976           break;
977         }
978     }
979   else
980     {
981       CVDebuggerRequest *req = CVReadDebuggerRequest (conn);
982       if (!req)
983         {
984           fprintf (stderr, "CVReadDebuggerRequest returned NULL, type = %d\n",
985                    head->reqType);
986           exit(1);
987         }
988
989       switch (req->head.request->reqType)
990         {
991         case OpenProgramInstanceRType:
992           {
993             char *arglist, buf[100]; /* XXX - Make buf dynamic! */
994             int arglen;
995             /* XXX - should notice when program_id changes */
996             arglist = req->openProgramInstance.progArglist.text;
997             arglen = req->openProgramInstance.progArglist.byteLen;
998
999             execute_command_1(1, queue, "break main");
1000             execute_command_1(1, queue, "enable delete $bpnum");
1001             if (arglist)
1002               {
1003                 execute_command_1(1, queue, "set args %.*s", arglen, arglist);
1004               }
1005             execute_command_1(1, queue, "run");
1006           }
1007           break;
1008         case SearchPathRType:
1009           directory_command(req->searchPath.searchPath.text, 0);
1010           break;
1011         case QuitDebuggerRType:
1012           execute_command_1(1, queue, "quit");
1013           break;
1014         case RunRType:
1015           if (req->run.request->useArglist == CNewArglist)
1016             {
1017               execute_command_1(1, queue, "set args %.*s",
1018                                 req->run.progArglist.byteLen,
1019                                 req->run.progArglist.text);
1020             }
1021           execute_command_1(1, queue, "run");
1022           break;
1023         case ContinueRType:
1024           execute_command_1(1, queue, "continue");
1025           break;
1026         case StepRType:
1027           execute_command_1(1, queue, "step %d", req->step.request->stepCount);
1028           break;
1029         case NextRType:
1030           execute_command_1(1, queue, "next %d", req->next.request->nextCount);
1031           break;
1032         case ChangeStackFrameRType:
1033           switch (req->changeStackFrame.request->frameMovement)
1034             {
1035             case CToCurrentStackFrame:
1036               execute_command_1(1, queue, "frame %d",
1037                                 req->changeStackFrame.request->frameNo);
1038               break;
1039             case CToInnerStackFrame:
1040               execute_command_1(1, queue, "down %d",
1041                                 req->changeStackFrame.request->frameNo);
1042               break;
1043             case CToOuterStackFrame:
1044               execute_command_1(1, queue, "up %d",
1045                                 req->changeStackFrame.request->frameNo);
1046               break;
1047             case CToAbsoluteStackFrame:
1048               execute_command_1(1, queue, "frame %d",
1049                                 req->changeStackFrame.request->frameNo);
1050               break;
1051             }
1052           break;
1053         case BackTraceRType:
1054           /* XXX - deal with limit??? */
1055           execute_command_1(1, queue, "backtrace");
1056           break;
1057         case FinishRType:
1058           execute_command_1(1, queue, "finish");
1059           break;
1060         case TerminateProgramRType:
1061           execute_command_1(1, queue, "kill");
1062           break;
1063         case NewBreakpointRType:
1064           {
1065             char *tail;
1066             int skipped;
1067
1068             tail = strrchr(req->newBreakpoint.fileName.text, '/');
1069             if (!tail)
1070               tail = req->newBreakpoint.fileName.text;
1071             else
1072               tail++;
1073             skipped = tail - req->newBreakpoint.fileName.text;
1074             execute_command_1(1, queue, "break %.*s:%d",
1075                               req->newBreakpoint.fileName.byteLen - skipped,
1076                               tail,
1077                               req->newBreakpoint.request->fileLinePos);
1078           }
1079           break;
1080         case StopRType:
1081           killpg(pgrp_inferior, SIGINT);
1082           break;
1083         case UserInputRType:
1084           {
1085             char *text;
1086             long len;
1087
1088             /* XXX - should really break command up into seperate lines
1089                and spoon-feed it to execute_command */
1090
1091             text = req->userInput.userInput.text;
1092             len = req->userInput.userInput.byteLen;
1093
1094             if (text[len-1] == '\n') text[len-1] = '\000';
1095
1096             while (*text == ' ' || *text == '\t') text++;
1097
1098             if (strcmp(text, "]*[") == 0) /* XXX - What does this mean??? */
1099               break;
1100
1101             if (*text != '\000')
1102               execute_command_1(0, queue, "%s", text);
1103             else
1104               print_prompt();   /* User just typed a blank line */
1105           }
1106           break;
1107         case QueryResponseRType:
1108           {
1109             char *resp;
1110
1111             if (req->queryResponse.request->response)
1112               resp = "y";
1113             else
1114               resp = "n";
1115             execute_command_1(1, 1, resp);
1116             printf_filtered("%s\n", resp);
1117           }
1118           break;
1119         case ChangeBreakpointRType:
1120           switch (req->changeBreakpoint.request->breakpointAttr)
1121             {
1122             case CBreakAttrUnchanged:
1123               execute_command_1(1, queue, "ignore %d %d",
1124                                 req->changeBreakpoint.request->breakpointId,
1125                                 req->changeBreakpoint.request->ignoreCount);
1126               break;
1127             case CEnableBreakpoint:
1128               execute_command_1(1, queue, "enable %d",
1129                                 req->changeBreakpoint.request->breakpointId);
1130               break;
1131             case CDisableBreakpoint:
1132               execute_command_1(1, queue, "disable %d",
1133                                 req->changeBreakpoint.request->breakpointId);
1134               break;
1135             case CDeleteBreakpoint:
1136               execute_command_1(1, queue, "delete %d",
1137                                 req->changeBreakpoint.request->breakpointId);
1138               break;
1139             case CEnableDisableBreakpoint:
1140               execute_command_1(1, queue, "enable once %d",
1141                                 req->changeBreakpoint.request->breakpointId);
1142               break;
1143             case CEnableDeleteBreakpoint:
1144               execute_command_1(1, queue, "enable delete %d",
1145                                 req->changeBreakpoint.request->breakpointId);
1146               break;
1147             default:
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);
1157               break;
1158             }
1159           break;
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);
1165           break;
1166         case BreakCommandsRType:
1167           /* Put pointers to where energize_command_line_input() can find
1168              them. */
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;
1177           break;
1178         case ShowValueRType:
1179           {
1180             char expr[100], *p = expr;
1181
1182             expr[0] = 0;
1183
1184             if (req->showValue.request->ref_type == CValuePointerRef)
1185               strcat(expr, "* ");
1186
1187             if (req->showValue.type_cast.byteLen)
1188               {
1189                 strcat(expr, "(");
1190                 strncat(expr, req->showValue.type_cast.text,
1191                         req->showValue.type_cast.byteLen);
1192                 strcat(expr, ") ");
1193               }
1194
1195             if (req->showValue.field.byteLen)
1196               strcat(expr, "(");
1197
1198             strncat(expr, req->showValue.expression.text,
1199                     req->showValue.expression.byteLen);
1200
1201             if (req->showValue.field.byteLen)
1202               {
1203                 strcat(expr, ")");
1204
1205                 strncat(expr, req->showValue.field.text,
1206                         req->showValue.field.byteLen);
1207               }
1208
1209             execute_command_1(1, queue, "print %s", expr);
1210           }
1211           break;
1212         case SetValueRType:
1213           {
1214             char expr[100], *p = expr;
1215
1216             expr[0] = 0;
1217
1218             if (req->setValue.request->ref_type == CValuePointerRef)
1219               strcat(expr, "* ");
1220
1221 #if 0
1222             if (req->setValue.type_cast.byteLen)
1223               {
1224                 strcat(expr, "(");
1225                 strncat(expr, req->setValue.type_cast.text,
1226                         req->setValue.type_cast.byteLen);
1227                 strcat(expr, ") ");
1228               }
1229 #endif
1230             if (req->setValue.field.byteLen)
1231               strcat(expr, "(");
1232
1233             strncat(expr, req->setValue.expression.text,
1234                     req->setValue.expression.byteLen);
1235
1236             if (req->setValue.field.byteLen)
1237               {
1238                 strcat(expr, ")");
1239
1240                 strncat(expr, req->setValue.field.text,
1241                         req->setValue.field.byteLen);
1242               }
1243
1244             execute_command_1(1, queue, "print %s = (%s) %s", expr,
1245                               req->setValue.type_cast.text,
1246                               req->setValue.value.text);
1247           }
1248           break;
1249         case DynamicLoadRType:
1250           {
1251             char *filename;
1252
1253             filename = req->dynamicLoad.filenames.byteLen ?
1254               req->dynamicLoad.filenames.text : exec_file;
1255
1256             switch (req->dynamicLoad.request->action)
1257               {
1258               case CDynamicLoadUpdateSymtab:
1259                 execute_command_1(1, queue, "exec-file %s", filename);
1260                 execute_command_1(1, queue, "symbol-file %s", filename);
1261                 break;
1262               default:
1263                 printf_filtered("DynamicLoadRType: unknown action=%d, filename=%s\n",
1264                                 req->dynamicLoad.request->action,
1265                                 req->dynamicLoad.filenames.text);
1266                 break;
1267               }
1268           }
1269           break;
1270         default:
1271           fprintf(stderr, "Unknown Debugger request type = %d\n",
1272                   req->head.request->reqType);
1273           break;
1274         }
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
1278                      free() anyway! */
1279     }
1280 }
1281 \f
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.  */
1284
1285 static int
1286 wait_for_events(poll)
1287      int poll;
1288 {
1289   fd_set readfds;
1290   int numfds;
1291   int eventmask = 0;
1292   static struct timeval tv = {0};
1293
1294   /* Output all pending requests. */
1295   CWriteRequestBuffer(conn);
1296
1297   FD_ZERO(&readfds);
1298
1299   /* Wait till there's some activity from the kernel or the pty. */
1300   do
1301     {
1302       FD_SET(kerfd, &readfds);
1303       if (inferior_pty > 0)
1304         FD_SET(inferior_pty, &readfds);
1305       if (poll)
1306         numfds = select(sizeof(readfds)*8, &readfds, 0, 0, &tv);
1307       else
1308         numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0);
1309     }
1310   while (numfds <= 0 && !poll);
1311
1312   if (FD_ISSET(inferior_pty, &readfds))
1313     eventmask |= PTY_EVENT;
1314
1315   if (FD_ISSET(kerfd, &readfds))
1316     eventmask |= KERNEL_EVENT;
1317
1318   return eventmask;
1319 }
1320 \f
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. */
1324
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().  */
1333
1334 char *
1335 energize_command_line_input(prompt, repeat)
1336      char *prompt;
1337      int repeat;
1338 {
1339   char *p;
1340
1341   if (!energize)
1342     return command_line_input(prompt, repeat);
1343
1344   if (doing_breakcommands_message)
1345     {
1346       if (command_line_length <= 0)
1347         return (char *)NULL;
1348
1349       p = command_line_text;
1350
1351       while (command_line_length-- > 0)
1352         {
1353           if (*command_line_text == '\n')
1354             {
1355               *command_line_text = '\000';
1356               command_line_text++;
1357               break;
1358             }
1359           command_line_text++;
1360         }
1361
1362       printf_filtered("%s\n", p);
1363       return p;
1364     }
1365   else
1366     {
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. */
1372
1373       int eventmask;
1374       static char buf[100];
1375       
1376       eventmask = wait_for_events(0);
1377
1378       if (eventmask & PTY_EVENT)
1379         pty_to_kernel();
1380
1381       if (eventmask & KERNEL_EVENT)
1382         kernel_dispatch(1);     /* Queue up commands */
1383
1384 /* Note that command has been echoed by the time we get here */
1385
1386       p = dequeue_command();
1387
1388       if (p)
1389         {
1390           strncpy(buf, p, sizeof(buf));
1391           free(p);
1392           return buf;
1393         }
1394       else
1395         return NULL;
1396     }
1397 }
1398 \f
1399 /* Establish contact with the kernel. */
1400
1401 void
1402 energize_initialize(energize_id, execarg)
1403      char *energize_id;
1404      char *execarg;
1405 {
1406   CTtyRequest *req;
1407   char *ctmp;
1408   extern long strtol(char *str, char **ptr, int base);
1409   char pathname[MAXPATHLEN];
1410   int n;
1411
1412   if (!energize_id)
1413     return;
1414
1415   if (!execarg) execarg = "";
1416
1417   exec_file = strdup(execarg);  /* Save for later */
1418
1419   printf("\ngdb-debugger pid=%d\n", getpid()); /* XXX - debugging only */
1420   
1421   /* First establish the connection with the kernel. */
1422
1423   kerfd = COpenClientSocket(NULL);
1424   if (kerfd < 0) {
1425     printf("COpenClientSocket() failed\n");
1426     exit(1);
1427   }
1428
1429   /* Setup for I/O interrupts when appropriate. */
1430
1431   n = fcntl(kerfd, F_GETFL, 0);
1432 #ifdef NCR486...
1433   O_SYNC
1434 #endif
1435   fcntl(kerfd, F_SETFL, n|FASYNC);
1436   fcntl(kerfd, F_SETOWN, getpid());
1437
1438   /* Setup connection buffering. */
1439
1440   CSetSocketBufferSize (kerfd, 12000);
1441
1442   /* Generate a new connection control block. */
1443
1444   conn = NewConnection (0, kerfd, kerfd);
1445   if (!conn) {
1446     printf("NewConnection() failed\n");
1447     exit(1);
1448   }
1449
1450 #ifdef KERNEL_RECORD
1451   kerout = fopen("kernel.output", "+w");
1452
1453   CReadWriteHooks(conn, conn->previewMethod, conn->readMethod, kernel_record);
1454 #endif
1455
1456   /* Tell the kernel that we are the "debugger". */
1457
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);
1466
1467   /* Tell the kernel that we are actually running. */
1468
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! */
1473
1474   req = CWriteTtyRequest (conn, RunningProgramRType);
1475   req->runningprogram.argc = 8;
1476   getwd (pathname);
1477   CWriteVstring0 (conn, pathname);
1478
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);
1488
1489   /* Tell the kernel our PID and all that */
1490
1491   program_id = 1;
1492   CVWriteDebugProgramInfo(conn,
1493                           getpid(),
1494                           program_id,
1495                           execarg,
1496                           "");
1497
1498   /* Tell the rest of the world that Energize is now set up. */
1499   energize = 1;
1500
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);
1506 }
1507
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.
1511 */
1512
1513 void
1514 energize_call_command(cmdblk, arg, from_tty)
1515      struct cmd_list_element *cmdblk;
1516      char *arg;
1517      int from_tty;
1518 {
1519   if (!energize)
1520     {
1521       (*cmdblk->function.cfunc) (arg, from_tty);
1522       return;
1523     }
1524
1525   if (cmdblk->class == class_run)
1526     {
1527       go_busy();
1528       has_run = 1;
1529       (*cmdblk->function.cfunc)(arg, from_tty);
1530       send_status();
1531     }
1532   else
1533     (*cmdblk->function.cfunc)(arg, from_tty);
1534
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);
1540   print_prompt();
1541 }
1542
1543 void
1544 energize_new_process()
1545 {
1546   instance_id = inferior_pid;
1547 }
1548
1549 static void
1550 iosig(signo)
1551      int signo;
1552 {
1553   while (1)
1554     {
1555       int eventmask;
1556
1557       eventmask = wait_for_events(1);
1558
1559       if (eventmask == 0)
1560         return;
1561
1562       if (eventmask & PTY_EVENT)
1563         pty_to_kernel();
1564
1565       if (eventmask & KERNEL_EVENT)
1566         kernel_dispatch(1);
1567     }
1568 }
1569
1570 int
1571 energize_wait(status)
1572      int *status;
1573 {
1574   int pid;
1575
1576   if (!energize)
1577     return wait(status);
1578
1579   signal(SIGIO, iosig);
1580
1581   pid = wait(status);
1582
1583   signal(SIGIO, SIG_DFL);
1584   return pid;
1585 }
1586
1587 static void
1588 null_routine(arg)
1589      int arg;
1590 {
1591 }
1592
1593 /* All requests from the Energize kernel eventually end up here. */
1594
1595 void
1596 energize_main_loop()
1597 {
1598   CTtyRequest *req;
1599   struct cleanup *old_chain;
1600
1601   doing_breakcommands_message = 0;
1602
1603 /* We will come thru here any time there is an error, so send status if
1604    necessary. */
1605
1606   send_status();
1607
1608   print_prompt();
1609
1610   /* The actual event loop! */
1611
1612   while (1)
1613     {
1614       int eventmask;
1615       char *cmd;
1616
1617       old_chain = make_cleanup(null_routine, 0);
1618
1619 /* First, empty out the command queue, then check for new requests. */
1620
1621       while (cmd = dequeue_command())
1622         {
1623           execute_command_1(1, 0, cmd);
1624           free(cmd);
1625         }
1626
1627       eventmask = wait_for_events(0);
1628
1629       if (eventmask & PTY_EVENT)
1630         pty_to_kernel();
1631
1632       if (eventmask & KERNEL_EVENT)
1633         kernel_dispatch(0);
1634
1635       bpstat_do_actions(&stop_bpstat);
1636       do_cleanups(old_chain);
1637     }
1638 }