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