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