* hppa-tdep.c: Remove all uses of use_unwind and `set use_unwind'
[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 FRAME 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 extern int demangle;
415 char *demangled_name = NULL;
416
417 if (funcname == NULL)
418 return;
419
420 if (demangle)
421 {
422 demangled_name = cplus_demangle(funcname, arg_mode);
423
424 if (demangled_name)
425 {
426 funcname = demangled_name;
427 printf_filtered("'");
428 }
429 }
430
431 send_stack_info();
432
433 if (level < 0) level = 0;
434
435 CVWriteBackTraceEntryInfo(conn,
436 instance_id,
437 level, /* frameNo */
438 funcname);
439
440 if (demangled_name)
441 {
442 free(demangled_name);
443 printf_filtered("'");
444 }
445 }
446
447 /* Call this just prior to printing out the name & value of a variable. This
448 tells the kernel where to annotate the output. */
449
450 /* The args are:
451 expression - A text handle on what GDB can use to reference this value.
452 This can be a symbol name, or a convenience var, etc...
453 symbol - Used to determine the scope of the data. May be NULL.
454 type - Determines if we have a pointer ref, and the print name of the type.
455 Used in ShowValue message.
456 valaddr - The address in target memory of the data.
457 field - The field name of the struct or union element being referenced.
458 */
459
460 static char cum_expr[200]; /* Cumulative expression */
461 static char *expr_stack[100] = {cum_expr}; /* Pointers to end of expressions */
462 static char **last_expr = expr_stack; /* Current expr stack pointer */
463
464 void
465 energize_start_variable_annotation(expression, symbol, type, valaddr, field)
466 char *expression;
467 struct symbol *symbol;
468 struct type *type;
469 CORE_ADDR valaddr;
470 char *field;
471 {
472 int ref_type;
473 int stor_cl;
474 enum type_code type_code;
475 enum address_class sym_class;
476 char *type_cast;
477
478 if (!energize)
479 return;
480
481 send_stack_info();
482
483 strcpy(*last_expr++, expression);
484 *last_expr = *(last_expr-1) + strlen(expression);
485
486 switch (TYPE_CODE(type))
487 {
488 case TYPE_CODE_ARRAY:
489 case TYPE_CODE_STRUCT:
490 case TYPE_CODE_UNION:
491 case TYPE_CODE_ENUM:
492 case TYPE_CODE_INT:
493 case TYPE_CODE_FLT:
494 ref_type = CValueValueRef;
495 break;
496 case TYPE_CODE_PTR:
497 ref_type = CValuePointerRef;
498 break;
499 default:
500 ref_type = CValueUndefRef;
501 break;
502 }
503
504 /* Make sure that pointer points at something we understand */
505
506 if (ref_type == CValuePointerRef)
507 switch (TYPE_CODE(TYPE_TARGET_TYPE(type)))
508 {
509 case TYPE_CODE_PTR:
510 case TYPE_CODE_ARRAY:
511 case TYPE_CODE_STRUCT:
512 case TYPE_CODE_UNION:
513 case TYPE_CODE_ENUM:
514 case TYPE_CODE_INT:
515 case TYPE_CODE_FLT:
516 break;
517 default:
518 ref_type = CValueUndefRef;
519 break;
520 }
521
522 if (symbol)
523 {
524 sym_class = SYMBOL_CLASS(symbol);
525
526 switch (sym_class)
527 {
528 case LOC_CONST:
529 case LOC_CONST_BYTES:
530 stor_cl = CValueStorStaticConst;
531 break;
532 case LOC_STATIC:
533 stor_cl = CValueStorStaticVar;
534 break;
535 case LOC_REGISTER:
536 case LOC_REGPARM:
537 stor_cl = CValueStorRegister;
538 break;
539 case LOC_ARG:
540 case LOC_REF_ARG:
541 case LOC_LOCAL:
542 case LOC_LOCAL_ARG:
543 stor_cl = CValueStorLocalVar;
544 break;
545 default:
546 stor_cl = CValueStorUndef;
547 break;
548 }
549 }
550 else
551 stor_cl = CValueStorUndef;
552
553 type_cast = TYPE_NAME(type);
554
555 CVWriteValueBeginInfo(conn,
556 instance_id,
557 valaddr,
558 ref_type,
559 stor_cl,
560 0, /* XXX - frameno */
561 cum_expr,
562 field,
563 type_cast,
564 ""); /* transcript */
565 }
566
567 void
568 energize_end_variable_annotation()
569 {
570 if (!energize)
571 return;
572
573 last_expr--; /* Pop the expr stack */
574 **last_expr = '\000'; /* Cut off the last part of the expr */
575
576 CVWriteValueEndInfo(conn,
577 instance_id,
578 ""); /* transcript */
579 }
580 \f
581 /* Tell the kernel that the target is now running. */
582
583 static void
584 go_busy()
585 {
586 CVWriteProgramBusyInfo(conn,
587 instance_id,
588 ""); /* XXX ? transcript */
589 CWriteRequestBuffer(conn); /* Must take place synchronusly! */
590 stack_info_valid = 0;
591 }
592
593 \f
594 void
595 energize_symbol_file(objfile)
596 struct objfile *objfile;
597 {
598 if (!energize)
599 return;
600
601 CVWriteSymbolTableInfo(conn,
602 objfile->name,
603 ""); /* Transcript */
604 }
605
606 /* execute_command_1(echo, queue, cmd, args) - echo - non-zero means echo the
607 command. queue - non-zero means don't execute it now, just save it away for
608 later. cmd - string containing printf control sequences. args - list of
609 arguments needed by those control sequences.
610 */
611
612 /* Linked list of queued up commands */
613 static struct command_line *queued_commands = 0;
614 static struct command_line *last_queued_command = 0;
615
616 /* Call this routine to save a command for later. The command string is
617 copied into freshly malloc'ed memory. */
618
619 static void
620 queue_command(cmd)
621 char *cmd;
622 {
623 char *buf;
624 struct command_line *cl;
625 unsigned long s;
626
627 s = (strlen(cmd) + 1) + 7 & ~(unsigned long)7;
628
629 buf = (char *)xmalloc(s + sizeof(struct command_line));
630 cl = (struct command_line *)(buf + s);
631 cl->next = 0;
632 cl->line = buf;
633
634 strncpy(cl->line, cmd, s);
635
636 if (queued_commands)
637 last_queued_command->next = cl;
638 else
639 queued_commands = cl;
640
641 last_queued_command = cl;
642 }
643
644 /* Call this procedure to take a command off of the command queue. It returns
645 a pointer to a buf which the caller is responsible for freeing. NULL is
646 returned if there are no commands queued. */
647
648 static char *
649 dequeue_command()
650 {
651 struct command_line *cl;
652 char *cmd;
653
654 cl = queued_commands;
655
656 if (!cl)
657 return NULL;
658
659 queued_commands = cl->next;
660
661 return cl->line;
662 }
663
664 static void
665 execute_command_1(va_alist)
666 va_dcl
667 {
668 char buf[100]; /* XXX - make buf dynamic! */
669
670 int echo;
671 int queue;
672 char *cmd;
673 va_list args;
674
675 va_start(args);
676 echo = va_arg(args, int);
677
678 queue = va_arg(args, int);
679 cmd = va_arg(args, char *);
680
681 vsprintf(buf, cmd, args);
682
683 if (queue)
684 queue_command(buf);
685 else
686 {
687 if (echo)
688 printf_filtered("%s\n", buf);
689 execute_command(buf, 1);
690 }
691
692 va_end(args);
693 }
694
695 #ifdef KERNEL_RECORD
696 FILE *kerout;
697
698 static int
699 kernel_record(fd, ptr, num)
700 int fd, num;
701 char *ptr;
702
703 {
704 fwrite(ptr, num, 1, kerout);
705 fflush(kerout);
706 return write(fd, ptr, num);
707 }
708 #endif
709
710 void
711 energize_condition_breakpoint(b)
712 struct breakpoint *b;
713 {
714 if (energize)
715 CVWriteBreakConditionInfo(conn,
716 instance_id,
717 b->number,
718 b->cond_string ? b->cond_string : "",
719 "" /* transcript */
720 );
721 }
722
723 void
724 energize_commands_breakpoint(b)
725 struct breakpoint *b;
726 {
727 struct command_line *l;
728
729 if (!energize)
730 return;
731
732 CVWriteBreakCommandBegInfo(conn,
733 instance_id,
734 b->number,
735 ""); /* transcript */
736
737 for (l = b->commands; l; l = l->next)
738 CVWriteBreakCommandEntryInfo(conn,
739 instance_id,
740 l->line,
741 ""); /* transcript */
742
743 CVWriteBreakCommandEndInfo(conn,
744 instance_id,
745 ""); /* transcript */
746 }
747
748 static void
749 breakpoint_notify(b, action)
750 struct breakpoint *b;
751 int action;
752 {
753 struct symbol *sym;
754 char *funcname = "";
755 char *filename;
756 char *included_in_filename = "";
757
758 if (!energize
759 || energize_reloading) /* Don't notify energize about breakpoint changes, as it's about to send us
760 a new bunch. */
761 return;
762
763 if (b->type != bp_breakpoint)
764 return;
765
766 filename = full_filename(b->symtab);
767
768 sym = find_pc_function(b->address);
769 if (sym)
770 funcname = SYMBOL_NAME(sym);
771
772 CVWriteBreakpointInfo (conn,
773 instance_id,
774 b->number,
775 b->line_number,
776 CFileLinePos,
777 CBreakOnInstrAccess,
778 action,
779 b->ignore_count,
780 funcname,
781 filename ? filename : "",
782 "", /* included_in_filename */
783 "" /* transcript */
784 );
785
786 if (b->commands)
787 energize_commands_breakpoint(b);
788
789 energize_condition_breakpoint(b);
790
791 if (filename)
792 free(filename);
793 }
794
795 void
796 energize_create_breakpoint(b)
797 struct breakpoint *b;
798 {
799 breakpoint_notify(b, CEnableBreakpoint);
800 }
801
802 void
803 energize_delete_breakpoint(b)
804 struct breakpoint *b;
805 {
806 breakpoint_notify(b, CDeleteBreakpoint);
807 }
808
809 void
810 energize_enable_breakpoint(b)
811 struct breakpoint *b;
812 {
813 breakpoint_notify(b, CEnableBreakpoint);
814 }
815
816 void
817 energize_disable_breakpoint(b)
818 struct breakpoint *b;
819 {
820 breakpoint_notify(b, CDisableBreakpoint);
821 }
822
823 void
824 energize_ignore_breakpoint(b)
825 struct breakpoint *b;
826 {
827 breakpoint_notify(b, CBreakAttrUnchanged);
828 }
829 \f
830 /* Open up a pty and its associated tty. Return the fd of the tty. */
831
832 #ifndef NCR486
833 static void
834 getpty()
835 {
836 int n, ptyfd, ttyfd;
837 static char dev[30];
838 struct stat statbuf;
839 struct termios termios;
840
841 #define HIGHPTY (('z' - 'p') * 16 - 1)
842
843 for (n = 0; n <= HIGHPTY; n++)
844 {
845 sprintf(dev, "/dev/pty%c%x", n/16 + 'p', n%16);
846 if (stat(dev, &statbuf))
847 break;
848 ptyfd = open(dev, O_RDWR);
849 if (ptyfd < 0)
850 continue;
851 sprintf(dev, "/dev/tty%c%x", n/16 + 'p', n%16);
852 ttyfd = open(dev, O_RDWR);
853 if (ttyfd < 0)
854 {
855 close(ptyfd);
856 continue;
857 }
858
859 /* Setup pty for non-blocking I/O. Also make it give us a SIGIO when
860 there's data available. */
861
862 n = fcntl(ptyfd, F_GETFL, 0);
863 fcntl(ptyfd, F_SETFL, n|FNDELAY|FASYNC);
864 fcntl(ptyfd, F_SETOWN, getpid());
865
866 tcgetattr(ttyfd, &termios);
867 termios.c_oflag &= ~OPOST; /* No post-processing */
868 tcsetattr(ttyfd, TCSANOW, &termios);
869
870 inferior_pty = ptyfd;
871 inferior_tty = ttyfd;
872 return;
873 }
874
875 error ("getpty: can't get a pty\n");
876 }
877 #endif
878 /* Alternate getpty for NCRs */
879
880 #ifdef NCR486 /* LTL */
881 #define MAX_PTM_TRY 16
882 #define MAX_GRANTPT_TRY 4
883 static void
884 getpty()
885 {
886 char *slavename;
887 extern char *ptsname();
888 int j, i;
889 int n, mfd, sfd;
890 struct stat statbuf;
891 struct termios termios;
892
893 mfd = open("/dev/ptmx", O_RDWR); /* get the master */
894 if (mfd < 0)
895 error ("getpty: can't locate master\n");
896
897 if (grantpt(mfd) < 0) /* get a slave */
898 error ("getpty: can't acquire slave");
899
900 unlockpt(mfd);
901
902 slavename = ptsname(mfd); /* get the slave device name */
903 if (!slavename)
904 error ("getpty: can't get a pts\n");
905
906 /* Drop controlling tty, become pgrp master */
907
908 if (setpgid(0, getppid()) == -1)
909 perror("setpgid() failed: ");
910
911 if (setsid() == -1)
912 perror("setsid() failed: ");
913
914 sfd = open(slavename, O_RDWR);
915 if (sfd < 0)
916 {
917 close(mfd);
918 error ("getpty: can't open slave\n");
919 }
920
921
922 if (ioctl(sfd, I_PUSH, "ptem")) perror ("getpty: ioctl I_PUSH fails");
923 if (ioctl(sfd, I_PUSH, "ldterm")) perror ("getpty: ioctl I_PUSH fails");
924
925 /* setup mty for non-blocking I/O. */
926
927 n = fcntl(mfd, F_GETFL);
928 if (n < 0)
929 perror ("getpty: fcntl F_GETFL failed");
930
931 if (fcntl(mfd, F_SETFL, n|O_NDELAY) <0)
932 perror("getpty: fcntl F_SETFL failed");
933
934 /* set up for async i/o - V.4 will send SIGPOLL when data available */
935
936 if (ioctl (mfd, I_SETSIG, S_INPUT|S_RDNORM) < 0)
937 perror ("getpty: ioctl I_SETSIG failed");
938
939 if (tcgetattr(sfd, &termios))
940 perror("getpty: tcgetattr fails");
941 termios.c_oflag &= ~OPOST; /* no post-processing */
942 if (tcsetattr(sfd, TCSANOW, &termios))
943 perror("getpty: tcsetattr fails");
944
945 inferior_pty=mfd;
946 inferior_tty=sfd;
947
948 return;
949 }
950
951 #endif /* NCR486 */
952 \f
953 /* Examine a protocol packet from the driver. */
954
955 static void
956 kernel_dispatch(queue)
957 int queue; /* Non-zero means we should just queue up
958 commands. */
959 {
960 register CHeader *head;
961
962 head = (CHeader *)CPeekNextRequest (conn);
963 if (head == NULL)
964 {
965 fprintf (stderr, "EOF on kernel read!\n");
966 exit (1);
967 }
968
969 if (head->reqType < LastTtyRequestRType)
970 {
971 CTtyRequest* req = CReadTtyRequest (conn);
972 switch (req->head.reqType)
973 {
974 case AcceptConnectionRType:
975 /* Tell the rest of the world that energize is now set up */
976 CSkipRequest (conn);
977 break;
978
979 case RefuseConnectionRType:
980 fprintf (stderr, "Debugger connection refused\n");
981 exit (1);
982
983 case KillProgramRType:
984 exit (0);
985
986 case TextIORType:
987 {
988 char *p;
989 ReqLen len;
990
991 p = CGetVstring(conn, &len);
992 kernel_to_pty(p, len);
993 }
994 break;
995 default:
996 fprintf(stderr, "Unknown Tty request type = %d\n",
997 req->head.reqType);
998 break;
999 }
1000 }
1001 else
1002 {
1003 CVDebuggerRequest *req = CVReadDebuggerRequest (conn);
1004 if (!req)
1005 {
1006 fprintf (stderr, "CVReadDebuggerRequest returned NULL, type = %d\n",
1007 head->reqType);
1008 exit(1);
1009 }
1010
1011 switch (req->head.request->reqType)
1012 {
1013 case OpenProgramInstanceRType:
1014 {
1015 char *arglist, buf[100]; /* XXX - Make buf dynamic! */
1016 int arglen;
1017 /* XXX - should notice when program_id changes */
1018 arglist = req->openProgramInstance.progArglist.text;
1019 arglen = req->openProgramInstance.progArglist.byteLen;
1020
1021 execute_command_1(1, queue, "break main");
1022 execute_command_1(1, queue, "enable delete $bpnum");
1023 if (arglist)
1024 {
1025 execute_command_1(1, queue, "set args %.*s", arglen, arglist);
1026 }
1027 execute_command_1(1, queue, "run");
1028 }
1029 break;
1030 case SearchPathRType:
1031 directory_command(req->searchPath.searchPath.text, 0);
1032 break;
1033 case QuitDebuggerRType:
1034 execute_command_1(1, queue, "quit");
1035 break;
1036 case RunRType:
1037 if (req->run.request->useArglist == CNewArglist)
1038 {
1039 execute_command_1(1, queue, "set args %.*s",
1040 req->run.progArglist.byteLen,
1041 req->run.progArglist.text);
1042 }
1043 execute_command_1(1, queue, "run");
1044 break;
1045 case ContinueRType:
1046 execute_command_1(1, queue, "continue");
1047 break;
1048 case StepRType:
1049 execute_command_1(1, queue, "step %d", req->step.request->stepCount);
1050 break;
1051 case NextRType:
1052 execute_command_1(1, queue, "next %d", req->next.request->nextCount);
1053 break;
1054 case ChangeStackFrameRType:
1055 switch (req->changeStackFrame.request->frameMovement)
1056 {
1057 case CToCurrentStackFrame:
1058 execute_command_1(1, queue, "frame %d",
1059 req->changeStackFrame.request->frameNo);
1060 break;
1061 case CToInnerStackFrame:
1062 execute_command_1(1, queue, "down %d",
1063 req->changeStackFrame.request->frameNo);
1064 break;
1065 case CToOuterStackFrame:
1066 execute_command_1(1, queue, "up %d",
1067 req->changeStackFrame.request->frameNo);
1068 break;
1069 case CToAbsoluteStackFrame:
1070 execute_command_1(1, queue, "frame %d",
1071 req->changeStackFrame.request->frameNo);
1072 break;
1073 }
1074 break;
1075 case BackTraceRType:
1076 /* XXX - deal with limit??? */
1077 execute_command_1(1, queue, "backtrace");
1078 break;
1079 case FinishRType:
1080 execute_command_1(1, queue, "finish");
1081 break;
1082 case TerminateProgramRType:
1083 execute_command_1(1, queue, "kill");
1084 break;
1085 case NewBreakpointRType:
1086 {
1087 char *tail;
1088 int skipped;
1089
1090 tail = strrchr(req->newBreakpoint.fileName.text, '/');
1091 if (!tail)
1092 tail = req->newBreakpoint.fileName.text;
1093 else
1094 tail++;
1095 skipped = tail - req->newBreakpoint.fileName.text;
1096 execute_command_1(1, queue, "break %.*s:%d",
1097 req->newBreakpoint.fileName.byteLen - skipped,
1098 tail,
1099 req->newBreakpoint.request->fileLinePos);
1100 }
1101 break;
1102 case StopRType:
1103 kill(-pgrp_inferior, SIGINT);
1104 break;
1105 case UserInputRType:
1106 {
1107 char *text;
1108 long len;
1109
1110 /* XXX - should really break command up into seperate lines
1111 and spoon-feed it to execute_command */
1112
1113 text = req->userInput.userInput.text;
1114 len = req->userInput.userInput.byteLen;
1115
1116 if (text[len-1] == '\n') text[len-1] = '\000';
1117
1118 while (*text == ' ' || *text == '\t') text++;
1119
1120 if (STREQ(text, "]*[")) /* XXX - What does this mean??? */
1121 break;
1122
1123 if (*text != '\000')
1124 execute_command_1(0, queue, "%s", text);
1125 else
1126 print_prompt(); /* User just typed a blank line */
1127 }
1128 break;
1129 case QueryResponseRType:
1130 {
1131 char *resp;
1132
1133 if (req->queryResponse.request->response)
1134 resp = "y";
1135 else
1136 resp = "n";
1137 execute_command_1(1, 1, resp);
1138 printf_filtered("%s\n", resp);
1139 }
1140 break;
1141 case ChangeBreakpointRType:
1142 switch (req->changeBreakpoint.request->breakpointAttr)
1143 {
1144 case CBreakAttrUnchanged:
1145 execute_command_1(1, queue, "ignore %d %d",
1146 req->changeBreakpoint.request->breakpointId,
1147 req->changeBreakpoint.request->ignoreCount);
1148 break;
1149 case CEnableBreakpoint:
1150 execute_command_1(1, queue, "enable %d",
1151 req->changeBreakpoint.request->breakpointId);
1152 break;
1153 case CDisableBreakpoint:
1154 execute_command_1(1, queue, "disable %d",
1155 req->changeBreakpoint.request->breakpointId);
1156 break;
1157 case CDeleteBreakpoint:
1158 execute_command_1(1, queue, "delete %d",
1159 req->changeBreakpoint.request->breakpointId);
1160 break;
1161 case CEnableDisableBreakpoint:
1162 execute_command_1(1, queue, "enable once %d",
1163 req->changeBreakpoint.request->breakpointId);
1164 break;
1165 case CEnableDeleteBreakpoint:
1166 execute_command_1(1, queue, "enable delete %d",
1167 req->changeBreakpoint.request->breakpointId);
1168 break;
1169 default:
1170 printf_filtered("ChangeBreakpointRType: unknown breakpointAttr\n");
1171 printf_filtered(" breakpointAttr = %d\n",
1172 req->changeBreakpoint.request->breakpointAttr);
1173 printf_filtered(" breakpointId = %d\n",
1174 req->changeBreakpoint.request->breakpointId);
1175 printf_filtered(" breakpointType = %d\n",
1176 req->changeBreakpoint.request->breakpointType);
1177 printf_filtered(" ignoreCount = %d\n",
1178 req->changeBreakpoint.request->ignoreCount);
1179 break;
1180 }
1181 break;
1182 case BreakConditionRType:
1183 execute_command_1(1, queue, "condition %d %.*s",
1184 req->breakCondition.request->breakpointId,
1185 req->breakCondition.condition.byteLen,
1186 req->breakCondition.condition.text);
1187 break;
1188 case BreakCommandsRType:
1189 /* Put pointers to where energize_command_line_input() can find
1190 them. */
1191 doing_breakcommands_message = 1;
1192 command_line_length = req->breakCommands.commands.byteLen;
1193 command_line_text = req->breakCommands.commands.text;
1194 execute_command_1(1, queue, "commands %d",
1195 req->breakCommands.request->breakpointId);
1196 command_line_text = (char *)NULL;
1197 command_line_length = 0;
1198 doing_breakcommands_message = 0;
1199 break;
1200 case ShowValueRType:
1201 {
1202 char expr[100], *p = expr;
1203
1204 expr[0] = 0;
1205
1206 if (req->showValue.request->ref_type == CValuePointerRef)
1207 strcat(expr, "* ");
1208
1209 if (req->showValue.type_cast.byteLen)
1210 {
1211 strcat(expr, "(");
1212 strncat(expr, req->showValue.type_cast.text,
1213 req->showValue.type_cast.byteLen);
1214 strcat(expr, ") ");
1215 }
1216
1217 if (req->showValue.field.byteLen)
1218 strcat(expr, "(");
1219
1220 strncat(expr, req->showValue.expression.text,
1221 req->showValue.expression.byteLen);
1222
1223 if (req->showValue.field.byteLen)
1224 {
1225 strcat(expr, ")");
1226
1227 strncat(expr, req->showValue.field.text,
1228 req->showValue.field.byteLen);
1229 }
1230
1231 execute_command_1(1, queue, "print %s", expr);
1232 }
1233 break;
1234 case SetValueRType:
1235 {
1236 char expr[100], *p = expr;
1237
1238 expr[0] = 0;
1239
1240 if (req->setValue.request->ref_type == CValuePointerRef)
1241 strcat(expr, "* ");
1242
1243 #if 0
1244 if (req->setValue.type_cast.byteLen)
1245 {
1246 strcat(expr, "(");
1247 strncat(expr, req->setValue.type_cast.text,
1248 req->setValue.type_cast.byteLen);
1249 strcat(expr, ") ");
1250 }
1251 #endif
1252 if (req->setValue.field.byteLen)
1253 strcat(expr, "(");
1254
1255 strncat(expr, req->setValue.expression.text,
1256 req->setValue.expression.byteLen);
1257
1258 if (req->setValue.field.byteLen)
1259 {
1260 strcat(expr, ")");
1261
1262 strncat(expr, req->setValue.field.text,
1263 req->setValue.field.byteLen);
1264 }
1265
1266 execute_command_1(1, queue, "print %s = (%s) %s", expr,
1267 req->setValue.type_cast.text,
1268 req->setValue.value.text);
1269 }
1270 break;
1271 case DynamicLoadRType:
1272 {
1273 char *filename;
1274
1275 filename = req->dynamicLoad.filenames.byteLen ?
1276 req->dynamicLoad.filenames.text : exec_file;
1277
1278 switch (req->dynamicLoad.request->action)
1279 {
1280 case CDynamicLoadUpdateSymtab:
1281 energize_reloading = 1;
1282 execute_command_1(1, queue, "set confirm no");
1283 execute_command_1(1, queue, "delete");
1284 /* execute_command_1(1, queue, "set $bpnum=1");*/ /* Use this to reset breakpoint #s */
1285 execute_command_1(1, queue, "exec-file %s", filename);
1286 execute_command_1(1, queue, "symbol-file %s", filename);
1287 execute_command_1(1, queue, "set confirm yes");
1288 energize_reloading = 0;
1289 break;
1290 case CDynamicLoadRestoreStart:
1291 break;
1292 case CDynamicLoadRestoreEnd: /* Not used anymore??? */
1293 printf_filtered("\n[Target has changed, automatic restoration of state has been done.]\n");
1294 print_prompt();
1295 break;
1296 default:
1297 printf_filtered("DynamicLoadRType: unknown action=%d, filename=%s\n",
1298 req->dynamicLoad.request->action,
1299 req->dynamicLoad.filenames.text);
1300 break;
1301 }
1302 }
1303 break;
1304 default:
1305 fprintf(stderr, "Unknown Debugger request type = %d\n",
1306 req->head.request->reqType);
1307 break;
1308 }
1309 free (req); /* Should probably call CVFreeDebuggerRequest() here, but
1310 can't do so if interrupt level has mucked with req->
1311 request. CVFreeDebuggerRequest() only ends up calling
1312 free() anyway! */
1313 }
1314 }
1315 \f
1316 /* Return a bitmask indicating if the kernel or the pty did something
1317 interesting. Set poll to non-zero if you don't want to wait. */
1318
1319 static int
1320 wait_for_events(poll)
1321 int poll;
1322 {
1323 fd_set readfds;
1324 int numfds;
1325 int eventmask = 0;
1326 static struct timeval tv = {0};
1327
1328 /* Output all pending requests. */
1329 CWriteRequestBuffer(conn);
1330
1331 FD_ZERO(&readfds);
1332
1333 /* Wait till there's some activity from the kernel or the pty. */
1334 do
1335 {
1336 FD_SET(kerfd, &readfds);
1337
1338 FD_SET(inferior_pty, &readfds);
1339
1340 if (poll)
1341 numfds = select(sizeof(readfds)*8, &readfds, 0, 0, &tv);
1342 else
1343 numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0);
1344 }
1345 while (numfds <= 0 && !poll);
1346
1347 if (numfds == 0)
1348 return 0;
1349
1350 if (FD_ISSET(inferior_pty, &readfds))
1351 eventmask |= PTY_EVENT;
1352
1353 if (FD_ISSET(kerfd, &readfds))
1354 eventmask |= KERNEL_EVENT;
1355
1356 return eventmask;
1357 }
1358 \f
1359 /* This is called from read_command_lines() to provide the text for breakpoint
1360 commands, which is supplied in a BreakCommands message. Each call to this
1361 routine supplies a single line of text, with the newline removed. */
1362
1363 /* This routine may be invoked in two different contexts. In the first, it
1364 is being called as a result of the BreakCommands message. In this case,
1365 all of the command text is immediately available. In the second case, it is
1366 called as a result of the user typing the 'command' command. The command
1367 text then needs to be glommed out of UserInput messages (and possibly other
1368 messages as well). The most 'straighforward' way of doing this is to
1369 basically simulate the main loop, but just accumulate the command text
1370 instead of sending it to execute_command(). */
1371
1372 char *
1373 energize_command_line_input(prompt, repeat)
1374 char *prompt;
1375 int repeat;
1376 {
1377 char *p;
1378
1379 if (!energize)
1380 return command_line_input(prompt, repeat);
1381
1382 if (doing_breakcommands_message)
1383 {
1384 if (command_line_length <= 0)
1385 return (char *)NULL;
1386
1387 p = command_line_text;
1388
1389 while (command_line_length-- > 0)
1390 {
1391 if (*command_line_text == '\n')
1392 {
1393 *command_line_text = '\000';
1394 command_line_text++;
1395 break;
1396 }
1397 command_line_text++;
1398 }
1399
1400 printf_filtered("%s\n", p);
1401 return p;
1402 }
1403 else
1404 {
1405 /* We come here when the user has typed the 'command' or 'define' command
1406 to the GDB window. We are basically deep inside of the 'command'
1407 command processing routine right now, and will be called to get a new
1408 line of input. We expect that kernel_dispatch will queue up only one
1409 command at a time. */
1410
1411 int eventmask;
1412 static char buf[100];
1413
1414 eventmask = wait_for_events(0);
1415
1416 if (eventmask & PTY_EVENT)
1417 pty_to_kernel();
1418
1419 if (eventmask & KERNEL_EVENT)
1420 kernel_dispatch(1); /* Queue up commands */
1421
1422 /* Note that command has been echoed by the time we get here */
1423
1424 p = dequeue_command();
1425
1426 if (p)
1427 {
1428 strncpy(buf, p, sizeof(buf));
1429 free(p);
1430 return buf;
1431 }
1432 else
1433 return NULL;
1434 }
1435 }
1436 \f
1437 /* Establish contact with the kernel. */
1438
1439 void
1440 energize_initialize(energize_id, execarg)
1441 char *energize_id;
1442 char *execarg;
1443 {
1444 CTtyRequest *req;
1445 char *ctmp;
1446 extern long strtol(char *str, char **ptr, int base);
1447 char pathname[MAXPATHLEN];
1448 int n;
1449
1450 if (!energize_id)
1451 return;
1452
1453 if (!execarg) execarg = "";
1454
1455 exec_file = strdup(execarg); /* Save for later */
1456
1457 printf("\ngdb-debugger pid=%d\n", getpid()); /* XXX - debugging only */
1458
1459 /* First establish the connection with the kernel. */
1460
1461 kerfd = COpenClientSocket(NULL);
1462 if (kerfd < 0) {
1463 printf("COpenClientSocket() failed\n");
1464 exit(1);
1465 }
1466
1467 /* Setup for I/O interrupts when appropriate. */
1468
1469 signal(SIGIO, SIG_IGN);
1470
1471 #ifdef NCR486
1472 if (ioctl (kerfd, I_SETSIG, S_INPUT|S_RDNORM) < 0)
1473 perror ("getpty: ioctl I_SETSIG failed");
1474 #else
1475 n = fcntl(kerfd, F_GETFL, 0);
1476 fcntl(kerfd, F_SETFL, n|FASYNC);
1477 fcntl(kerfd, F_SETOWN, getpid());
1478 #endif
1479
1480 /* Setup connection buffering. */
1481
1482 CSetSocketBufferSize (kerfd, 12000);
1483
1484 /* Generate a new connection control block. */
1485
1486 conn = NewConnection (0, kerfd, kerfd);
1487 if (!conn) {
1488 printf("NewConnection() failed\n");
1489 exit(1);
1490 }
1491
1492 #ifdef KERNEL_RECORD
1493 kerout = fopen("kernel.output", "+w");
1494
1495 CReadWriteHooks(conn, conn->previewMethod, conn->readMethod, kernel_record);
1496 #endif
1497
1498 /* Tell the kernel that we are the "debugger". */
1499
1500 req = CWriteTtyRequest (conn, QueryConnectionRType);
1501 req->generic.queryconnection.major = 0;
1502 req->generic.queryconnection.minor = 0;
1503 req->generic.queryconnection.cadillacId1=strtol(energize_id, &ctmp, 16);
1504 req->generic.queryconnection.cadillacId2 = strtol(++ctmp, NULL, 16);
1505 req->generic.queryconnection.nProtocols = 1;
1506 CWriteProtocol (conn, 0, 0, "debugger");
1507 CWriteLength (conn);
1508
1509 /* Tell the kernel that we are actually running. */
1510
1511 /* KROCK ALERT!!! The kernel doesn't really care about the arguments to
1512 the program at all! It only cares that argument 7 be the name of the
1513 target program. So, we just fill in the rest of the slots with
1514 padding. I hope the kernel never cares about this! */
1515
1516 req = CWriteTtyRequest (conn, RunningProgramRType);
1517 req->runningprogram.argc = 8;
1518 getcwd (pathname, MAXPATHLEN);
1519 CWriteVstring0 (conn, pathname);
1520
1521 CWriteVstring0 (conn, "0");
1522 CWriteVstring0 (conn, "1");
1523 CWriteVstring0 (conn, "2");
1524 CWriteVstring0 (conn, "3");
1525 CWriteVstring0 (conn, "4");
1526 CWriteVstring0 (conn, "5");
1527 CWriteVstring0 (conn, "6");
1528 CWriteVstring0 (conn, execarg);
1529 CWriteLength (conn);
1530
1531 /* Tell the kernel our PID and all that */
1532
1533 program_id = 1;
1534 CVWriteDebugProgramInfo(conn,
1535 getpid(),
1536 program_id,
1537 execarg,
1538 "");
1539
1540 /* Tell the rest of the world that Energize is now set up. */
1541 energize = 1;
1542
1543 getpty(); /* Setup the pty */
1544
1545 /* Attach all GDB I/O to the pty */
1546
1547 dup2(inferior_tty, 0);
1548 dup2(inferior_tty, 1);
1549 dup2(inferior_tty, 2);
1550 }
1551
1552 /* This is called from execute_command, and provides a wrapper around
1553 various command routines in a place where both protocol messages and
1554 user input both flow through.
1555 */
1556
1557 void
1558 energize_call_command(cmdblk, arg, from_tty)
1559 struct cmd_list_element *cmdblk;
1560 char *arg;
1561 int from_tty;
1562 {
1563 if (!energize)
1564 {
1565 (*cmdblk->function.cfunc) (arg, from_tty);
1566 return;
1567 }
1568
1569 if (cmdblk->class == class_run)
1570 {
1571 go_busy();
1572 has_run = 1;
1573 (*cmdblk->function.cfunc)(arg, from_tty);
1574 send_status();
1575 }
1576 else
1577 (*cmdblk->function.cfunc)(arg, from_tty);
1578
1579 if (STREQ(cmdblk->name, "up")
1580 || STREQ(cmdblk->name, "down")
1581 || STREQ(cmdblk->name, "frame"))
1582 send_location(get_frame_info(selected_frame)->pc,
1583 selected_frame_level);
1584 print_prompt();
1585 }
1586
1587 void
1588 energize_new_process()
1589 {
1590 instance_id = inferior_pid;
1591 }
1592
1593 static void
1594 iosig(signo)
1595 int signo;
1596 {
1597 while (1)
1598 {
1599 int eventmask;
1600
1601 eventmask = wait_for_events(1);
1602
1603 if (eventmask == 0)
1604 return;
1605
1606 if (eventmask & PTY_EVENT)
1607 pty_to_kernel();
1608
1609 if (eventmask & KERNEL_EVENT)
1610 kernel_dispatch(1);
1611 }
1612 }
1613
1614 int
1615 energize_wait(status)
1616 int *status;
1617 {
1618 int pid;
1619 struct sigaction action;
1620 static sigset_t nullsigmask = {0};
1621
1622 if (!energize)
1623 return target_wait(status);
1624
1625 #ifdef NCR486
1626 action.sa_handler = iosig;
1627 action.sa_mask = nullsigmask;
1628 action.sa_flags = SA_RESTART;
1629 sigaction(SIGIO, &action, NULL);
1630 #else
1631 signal(SIGIO, iosig);
1632 #endif
1633
1634 pid = target_wait(status);
1635
1636 signal(SIGIO, SIG_IGN);
1637 return pid;
1638 }
1639
1640 int
1641 energize_shell_wait(status)
1642 int *status;
1643 {
1644 int pid;
1645 struct sigaction action;
1646 static sigset_t nullsigmask = {0};
1647
1648 if (!energize)
1649 return wait(status);
1650
1651 #ifdef NCR486
1652 action.sa_handler = iosig;
1653 action.sa_mask = nullsigmask;
1654 action.sa_flags = SA_RESTART;
1655 sigaction(SIGIO, &action, NULL);
1656 #else
1657 signal(SIGIO, iosig);
1658 #endif
1659
1660 pid = wait(status);
1661
1662 signal(SIGIO, SIG_IGN);
1663 return pid;
1664 }
1665
1666 static void
1667 null_routine(arg)
1668 int arg;
1669 {
1670 }
1671
1672 /* All requests from the Energize kernel eventually end up here. */
1673
1674 void
1675 energize_main_loop()
1676 {
1677 CTtyRequest *req;
1678 struct cleanup *old_chain;
1679
1680 doing_breakcommands_message = 0;
1681
1682 /* We will come thru here any time there is an error, so send status if
1683 necessary. */
1684
1685 send_status();
1686
1687 print_prompt();
1688
1689 /* The actual event loop! */
1690
1691 while (1)
1692 {
1693 int eventmask;
1694 char *cmd;
1695
1696 old_chain = make_cleanup(null_routine, 0);
1697
1698 /* First, empty out the command queue, then check for new requests. */
1699
1700 while (cmd = dequeue_command())
1701 {
1702 execute_command_1(1, 0, cmd);
1703 free(cmd);
1704 }
1705
1706 eventmask = wait_for_events(0);
1707
1708 if (eventmask & PTY_EVENT)
1709 pty_to_kernel();
1710
1711 if (eventmask & KERNEL_EVENT)
1712 kernel_dispatch(0);
1713
1714 bpstat_do_actions(&stop_bpstat);
1715 do_cleanups(old_chain);
1716 }
1717 }
This page took 0.063721 seconds and 4 git commands to generate.