Fri Sep 18 14:07:44 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
[deliverable/binutils-gdb.git] / gdb / convex-xdep.c
CommitLineData
b28d3617
JG
1/* Convex host-dependent code for GDB.
2 Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
dd3b648e
RP
3
4This file is part of GDB.
5
99a7de40 6This program is free software; you can redistribute it and/or modify
dd3b648e 7it under the terms of the GNU General Public License as published by
99a7de40
JG
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
dd3b648e 10
99a7de40 11This program is distributed in the hope that it will be useful,
dd3b648e
RP
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
99a7de40 17along with this program; if not, write to the Free Software
6c9638b4 18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
dd3b648e 19
dd3b648e 20#include "defs.h"
dd3b648e
RP
21#include "command.h"
22#include "symtab.h"
23#include "value.h"
24#include "frame.h"
25#include "inferior.h"
26#include "wait.h"
27
28#include <signal.h>
29#include <fcntl.h>
30#include "gdbcore.h"
31
32#include <sys/param.h>
33#include <sys/dir.h>
34#include <sys/user.h>
35#include <sys/ioctl.h>
36#include <sys/pcntl.h>
37#include <sys/thread.h>
38#include <sys/proc.h>
39#include <sys/file.h>
2b576293 40#include "gdb_stat.h"
dd3b648e
RP
41#include <sys/mman.h>
42
43#include <convex/vmparam.h>
44#include <convex/filehdr.h>
45#include <convex/opthdr.h>
46#include <convex/scnhdr.h>
47#include <convex/core.h>
48
49/* Per-thread data, read from the inferior at each stop and written
50 back at each resume. */
51
52/* Number of active threads.
53 Tables are valid for thread numbers less than this. */
54
55static int n_threads;
56
57#define MAXTHREADS 8
58
59/* Thread state. The remaining data is valid only if this is PI_TALIVE. */
60
61static int thread_state[MAXTHREADS];
62
63/* Stop pc, signal, signal subcode */
64
65static int thread_pc[MAXTHREADS];
66static int thread_signal[MAXTHREADS];
67static int thread_sigcode[MAXTHREADS];
68
69/* Thread registers.
70 If thread is selected, the regs are in registers[] instead. */
71
72static char thread_regs[MAXTHREADS][REGISTER_BYTES];
73
74/* 1 if the top frame on the thread's stack was a context frame,
75 meaning that the kernel is up to something and we should not
76 touch the thread at all except to resume it. */
77
78static char thread_is_in_kernel[MAXTHREADS];
79
80/* The currently selected thread's number. */
81
82static int inferior_thread;
83
84/* Inferior process's file handle and a process control block
85 to feed args to ioctl with. */
86
87static int inferior_fd;
88static struct pcntl ps;
89
90/* SOFF file headers for exec or core file. */
91
92static FILEHDR filehdr;
93static OPTHDR opthdr;
94static SCNHDR scnhdr;
95
96/* Address maps constructed from section headers of exec and core files.
97 Defines process address -> file address translation. */
98
99struct pmap
100{
101 long mem_addr; /* process start address */
102 long mem_end; /* process end+1 address */
103 long file_addr; /* file start address */
104 long thread; /* -1 shared; 0,1,... thread-local */
105 long type; /* S_TEXT S_DATA S_BSS S_TBSS etc */
106 long which; /* used to sort map for info files */
107};
108
109static int n_exec, n_core;
110static struct pmap exec_map[100];
111static struct pmap core_map[100];
112
113/* Offsets in the core file of core_context and core_tcontext blocks. */
114
115static int context_offset;
116static int tcontext_offset[MAXTHREADS];
117
118/* Core file control blocks. */
119
120static struct core_context_v70 c;
121static struct core_tcontext_v70 tc;
122static struct user u;
123static thread_t th;
124static proc_t pr;
125
126/* The registers of the currently selected thread. */
127
128extern char registers[REGISTER_BYTES];
129
130/* Vector and communication registers from core dump or from inferior.
131 These are read on demand, ie, not normally valid. */
132
133static struct vecst vector_registers;
134static struct creg_ctx comm_registers;
135
136/* Flag, set on a vanilla CONT command and cleared when the inferior
137 is continued. */
138
139static int all_continue;
140
141/* Flag, set when the inferior is continued by a vanilla CONT command,
142 cleared if it is continued for any other purpose. */
143
144static int thread_switch_ok;
145
146/* Stack of signals recieved from threads but not yet delivered to gdb. */
147
148struct threadpid
149{
150 int pid;
151 int thread;
152 int signo;
153 int subsig;
154 int pc;
155};
156
157static struct threadpid signal_stack_bot[100];
158static struct threadpid *signal_stack = signal_stack_bot;
159
160/* How to detect empty stack -- bottom frame is all zero. */
161
162#define signal_stack_is_empty() (signal_stack->pid == 0)
163
164/* Mode controlled by SET PIPE command, controls the psw SEQ bit
165 which forces each instruction to complete before the next one starts. */
166
167static int sequential = 0;
168
169/* Mode controlled by the SET PARALLEL command. Values are:
170 0 concurrency limit 1 thread, dynamic scheduling
171 1 no concurrency limit, dynamic scheduling
172 2 no concurrency limit, fixed scheduling */
173
174static int parallel = 1;
175
176/* Mode controlled by SET BASE command, output radix for unformatted
177 integer typeout, as in argument lists, aggregates, and so on.
178 Zero means guess whether it's an address (hex) or not (decimal). */
179
180static int output_radix = 0;
181
182/* Signal subcode at last thread stop. */
183
184static int stop_sigcode;
185
186/* Hack, see wait() below. */
187
188static int exec_trap_timer;
189
190#include "gdbcmd.h"
191
dd3b648e
RP
192static struct type *vector_type ();
193static long *read_vector_register ();
194static long *read_vector_register_1 ();
195static void write_vector_register ();
119dfbb7 196static ULONGEST read_comm_register ();
dd3b648e
RP
197static void write_comm_register ();
198static void convex_cont_command ();
199static void thread_continue ();
200static void select_thread ();
201static void scan_stack ();
202static void set_fixed_scheduling ();
203static char *subsig_name ();
204static void psw_info ();
205static sig_noop ();
206static ptr_cmp ();
207
dd3b648e
RP
208\f
209/* Execute ptrace. Convex V7 replaced ptrace with pattach.
210 Allow ptrace (0) as a no-op. */
211
212int
213call_ptrace (request, pid, procaddr, buf)
e676a15f
FF
214 int request, pid;
215 PTRACE_ARG3_TYPE procaddr;
216 int buf;
dd3b648e
RP
217{
218 if (request == 0)
219 return;
220 error ("no ptrace");
221}
222
223/* Replacement for system execle routine.
224 Convert it to an equivalent exect, which pattach insists on. */
225
226execle (name, argv)
227 char *name, *argv;
228{
229 char ***envp = (char ***) &argv;
230 while (*envp++) ;
231
232 signal (SIGTRAP, sig_noop);
233 exect (name, &argv, *envp);
234}
235
236/* Stupid handler for stupid trace trap that otherwise causes
237 startup to stupidly hang. */
238
239static sig_noop ()
240{}
241
242/* Read registers from inferior into registers[] array.
243 For convex, they are already there, read in when the inferior stops. */
244
245void
246fetch_inferior_registers (regno)
247 int regno;
248{
249}
250
251/* Store our register values back into the inferior.
252 For Convex, do this only once, right before resuming inferior. */
253
1ab3bf1b 254void
dd3b648e
RP
255store_inferior_registers (regno)
256 int regno;
257{
258}
259
260/* Copy LEN bytes from inferior's memory starting at MEMADDR
261 to debugger memory starting at MYADDR.
262 On failure (cannot read from inferior, usually because address is out
263 of bounds) returns the value of errno. */
264
265int
266read_inferior_memory (memaddr, myaddr, len)
267 CORE_ADDR memaddr;
268 char *myaddr;
269 int len;
270{
271 errno = 0;
272 while (len > 0)
273 {
274 /* little-known undocumented max request size */
275 int i = (len < 12288) ? len : 12288;
276
277 lseek (inferior_fd, memaddr, 0);
278 read (inferior_fd, myaddr, i);
279
280 memaddr += i;
281 myaddr += i;
282 len -= i;
283 }
284 if (errno)
4ed97c9a 285 memset (myaddr, '\0', len);
dd3b648e
RP
286 return errno;
287}
288
289/* Copy LEN bytes of data from debugger memory at MYADDR
290 to inferior's memory at MEMADDR.
291 Returns errno on failure (cannot write the inferior) */
292
293int
294write_inferior_memory (memaddr, myaddr, len)
295 CORE_ADDR memaddr;
296 char *myaddr;
297 int len;
298{
299 errno = 0;
300 lseek (inferior_fd, memaddr, 0);
301 write (inferior_fd, myaddr, len);
302 return errno;
303}
304
305/* Here from create_inferior when the inferior process has been created
306 and started up. We must do a pattach to grab it for debugging.
307
308 Also, intercept the CONT command by altering its dispatch address. */
5d76c8e6
JK
309/* FIXME: This used to be called from a macro CREATE_INFERIOR_HOOK.
310 But now init_trace_fun is in the same place. So re-write this to
311 use the init_trace_fun (making convex a debugging target). */
dd3b648e
RP
312
313create_inferior_hook (pid)
314 int pid;
315{
316 static char cont[] = "cont";
317 static char cont1[] = "c";
318 char *linep = cont;
319 char *linep1 = cont1;
320 char **line = &linep;
321 char **line1 = &linep1;
322 struct cmd_list_element *c;
323
324 c = lookup_cmd (line, cmdlist, "", 0);
325 c->function = convex_cont_command;
326 c = lookup_cmd (line1, cmdlist, "", 0);
327 c->function = convex_cont_command;
328
329 inferior_fd = pattach (pid, O_EXCL);
330 if (inferior_fd < 0)
331 perror_with_name ("pattach");
332 inferior_thread = 0;
333 set_fixed_scheduling (pid, parallel == 2);
334}
335
336/* Attach process PID for debugging. */
337
338attach (pid)
339 int pid;
340{
341 int fd = pattach (pid, O_EXCL);
342 if (fd < 0)
343 perror_with_name ("pattach");
344 attach_flag = 1;
345 /* wait for strange kernel reverberations to go away */
346 sleep (1);
347
348 setpgrp (pid, pid);
349
350 inferior_fd = fd;
351 inferior_thread = 0;
352 return pid;
353}
354
355/* Stop debugging the process whose number is PID
356 and continue it with signal number SIGNAL.
357 SIGNAL = 0 means just continue it. */
358
359void
360detach (signal)
361 int signal;
362{
363 signal_stack = signal_stack_bot;
364 thread_continue (-1, 0, signal);
365 ioctl (inferior_fd, PIXDETACH, &ps);
366 close (inferior_fd);
367 inferior_fd = 0;
368 attach_flag = 0;
369}
370
371/* Kill off the inferior process. */
372
373kill_inferior ()
374{
375 if (inferior_pid == 0)
376 return;
377 ioctl (inferior_fd, PIXTERMINATE, 0);
378 wait (0);
379 target_mourn_inferior ();
380}
381
dd3b648e
RP
382/* Read vector register REG, and return a pointer to the value. */
383
384static long *
385read_vector_register (reg)
386 int reg;
387{
388 if (have_inferior_p ())
389 {
390 errno = 0;
391 ps.pi_buffer = (char *) &vector_registers;
392 ps.pi_nbytes = sizeof vector_registers;
393 ps.pi_offset = 0;
394 ps.pi_thread = inferior_thread;
395 ioctl (inferior_fd, PIXRDVREGS, &ps);
396 if (errno)
4ed97c9a 397 memset (&vector_registers, '\0', sizeof vector_registers);
dd3b648e
RP
398 }
399 else if (corechan >= 0)
400 {
401 lseek (corechan, tcontext_offset[inferior_thread], 0);
402 if (myread (corechan, &tc, sizeof tc) < 0)
403 perror_with_name (corefile);
404 lseek (corechan, tc.core_thread_p, 0);
405 if (myread (corechan, &th, sizeof th) < 0)
406 perror_with_name (corefile);
407 lseek (corechan, tc.core_vregs_p, 0);
408 if (myread (corechan, &vector_registers, 16*128) < 0)
409 perror_with_name (corefile);
410 vector_registers.vm[0] = th.t_vect_ctx.vc_vm[0];
411 vector_registers.vm[1] = th.t_vect_ctx.vc_vm[1];
412 vector_registers.vls = th.t_vect_ctx.vc_vls;
413 }
414
415 return read_vector_register_1 (reg);
416}
417
418/* Return a pointer to vector register REG, which must already have been
419 fetched from the inferior or core file. */
420
421static long *
422read_vector_register_1 (reg)
423 int reg;
424{
425 switch (reg)
426 {
427 case VM_REGNUM:
428 return (long *) vector_registers.vm;
429 case VS_REGNUM:
430 return (long *) &vector_registers.vls;
431 case VL_REGNUM:
432 return 1 + (long *) &vector_registers.vls;
433 default:
434 return (long *) &vector_registers.vr[reg];
435 }
436}
437
438/* Write vector register REG, element ELEMENT, new value VAL.
439 NB: must use read-modify-write on the entire vector state,
440 since pattach does not do offsetted writes correctly. */
441
442static void
443write_vector_register (reg, element, val)
444 int reg, element;
119dfbb7 445 ULONGEST val;
dd3b648e
RP
446{
447 if (have_inferior_p ())
448 {
449 errno = 0;
450 ps.pi_thread = inferior_thread;
451 ps.pi_offset = 0;
452 ps.pi_buffer = (char *) &vector_registers;
453 ps.pi_nbytes = sizeof vector_registers;
454
455 ioctl (inferior_fd, PIXRDVREGS, &ps);
456
457 switch (reg)
458 {
459 case VL_REGNUM:
460 vector_registers.vls =
461 (vector_registers.vls & 0xffffffff00000000LL)
462 + (unsigned long) val;
463 break;
464
465 case VS_REGNUM:
466 vector_registers.vls =
467 (val << 32) + (unsigned long) vector_registers.vls;
468 break;
469
470 default:
471 vector_registers.vr[reg].el[element] = val;
472 break;
473 }
474
475 ioctl (inferior_fd, PIXWRVREGS, &ps);
476
477 if (errno)
478 perror_with_name ("writing vector register");
479 }
480}
481
482/* Return the contents of communication register NUM. */
483
119dfbb7 484static ULONGEST
dd3b648e
RP
485read_comm_register (num)
486 int num;
487{
488 if (have_inferior_p ())
489 {
490 ps.pi_buffer = (char *) &comm_registers;
491 ps.pi_nbytes = sizeof comm_registers;
492 ps.pi_offset = 0;
493 ps.pi_thread = inferior_thread;
494 ioctl (inferior_fd, PIXRDCREGS, &ps);
495 }
496 return comm_registers.crreg.r4[num];
497}
498
499/* Store a new value VAL into communication register NUM.
500 NB: Must use read-modify-write on the whole comm register set
501 since pattach does not do offsetted writes correctly. */
502
503static void
504write_comm_register (num, val)
505 int num;
119dfbb7 506 ULONGEST val;
dd3b648e
RP
507{
508 if (have_inferior_p ())
509 {
510 ps.pi_buffer = (char *) &comm_registers;
511 ps.pi_nbytes = sizeof comm_registers;
512 ps.pi_offset = 0;
513 ps.pi_thread = inferior_thread;
514 ioctl (inferior_fd, PIXRDCREGS, &ps);
515 comm_registers.crreg.r4[num] = val;
516 ioctl (inferior_fd, PIXWRCREGS, &ps);
517 }
518}
519
520/* Resume execution of the inferior process.
521 If STEP is nonzero, single-step it.
522 If SIGNAL is nonzero, give it that signal. */
523
524void
525resume (step, signal)
526 int step;
527 int signal;
528{
529 errno = 0;
530 if (step || signal)
531 thread_continue (inferior_thread, step, signal);
532 else
533 thread_continue (-1, 0, 0);
534}
535
536/* Maybe resume some threads.
537 THREAD is which thread to resume, or -1 to resume them all.
538 STEP and SIGNAL are as in resume.
539
540 Global variable ALL_CONTINUE is set when we are here to do a
541 `cont' command; otherwise we may be doing `finish' or a call or
542 something else that will not tolerate an automatic thread switch.
543
544 If there are stopped threads waiting to deliver signals, and
545 ALL_CONTINUE, do not actually resume anything. gdb will do a wait
546 and see one of the stopped threads in the queue. */
547
548static void
549thread_continue (thread, step, signal)
550 int thread, step, signal;
551{
552 int n;
553
554 /* If we are to continue all threads, but not for the CONTINUE command,
555 pay no attention and continue only the selected thread. */
556
557 if (thread < 0 && ! all_continue)
558 thread = inferior_thread;
559
560 /* If we are not stepping, we have now executed the continue part
561 of a CONTINUE command. */
562
563 if (! step)
564 all_continue = 0;
565
566 /* Allow wait() to switch threads if this is an all-out continue. */
567
568 thread_switch_ok = thread < 0;
569
570 /* If there are threads queued up, don't resume. */
571
572 if (thread_switch_ok && ! signal_stack_is_empty ())
573 return;
574
575 /* OK, do it. */
576
577 for (n = 0; n < n_threads; n++)
578 if (thread_state[n] == PI_TALIVE)
579 {
580 select_thread (n);
581
582 if ((thread < 0 || n == thread) && ! thread_is_in_kernel[n])
583 {
584 /* Blam the trace bits in the stack's saved psws to match
585 the desired step mode. This is required so that
586 single-stepping a return doesn't restore a psw with a
587 clear trace bit and fly away, and conversely,
588 proceeding through a return in a routine that was
589 stepped into doesn't cause a phantom break by restoring
590 a psw with the trace bit set. */
591 scan_stack (PSW_T_BIT, step);
592 scan_stack (PSW_S_BIT, sequential);
593 }
594
595 ps.pi_buffer = registers;
596 ps.pi_nbytes = REGISTER_BYTES;
597 ps.pi_offset = 0;
598 ps.pi_thread = n;
599 if (! thread_is_in_kernel[n])
600 if (ioctl (inferior_fd, PIXWRREGS, &ps))
601 perror_with_name ("PIXWRREGS");
602
603 if (thread < 0 || n == thread)
604 {
605 ps.pi_pc = 1;
606 ps.pi_signo = signal;
607 if (ioctl (inferior_fd, step ? PIXSTEP : PIXCONTINUE, &ps) < 0)
608 perror_with_name ("PIXCONTINUE");
609 }
610 }
611
612 if (ioctl (inferior_fd, PIXRUN, &ps) < 0)
613 perror_with_name ("PIXRUN");
614}
615
616/* Replacement for system wait routine.
617
618 The system wait returns with one or more threads stopped by
619 signals. Put stopped threads on a stack and return them one by
620 one, so that it appears that wait returns one thread at a time.
621
622 Global variable THREAD_SWITCH_OK is set when gdb can tolerate wait
623 returning a new thread. If it is false, then only one thread is
624 running; we will do a real wait, the thread will do something, and
625 we will return that. */
626
627pid_t
628wait (w)
629 union wait *w;
630{
631 int pid;
632
633 if (!w)
634 return wait3 (0, 0, 0);
635
636 /* Do a real wait if we were told to, or if there are no queued threads. */
637
638 if (! thread_switch_ok || signal_stack_is_empty ())
639 {
640 int thread;
641
642 pid = wait3 (w, 0, 0);
643
644 if (!WIFSTOPPED (*w) || pid != inferior_pid)
645 return pid;
646
647 /* The inferior has done something and stopped. Read in all the
648 threads' registers, and queue up any signals that happened. */
649
650 if (ioctl (inferior_fd, PIXGETTHCOUNT, &ps) < 0)
651 perror_with_name ("PIXGETTHCOUNT");
652
653 n_threads = ps.pi_othdcnt;
654 for (thread = 0; thread < n_threads; thread++)
655 {
656 ps.pi_thread = thread;
657 if (ioctl (inferior_fd, PIXGETSUBCODE, &ps) < 0)
658 perror_with_name ("PIXGETSUBCODE");
659 thread_state[thread] = ps.pi_otstate;
660
661 if (ps.pi_otstate == PI_TALIVE)
662 {
663 select_thread (thread);
664 ps.pi_buffer = registers;
665 ps.pi_nbytes = REGISTER_BYTES;
666 ps.pi_offset = 0;
667 ps.pi_thread = thread;
668 if (ioctl (inferior_fd, PIXRDREGS, &ps) < 0)
669 perror_with_name ("PIXRDREGS");
670
671 registers_fetched ();
672
673 thread_pc[thread] = read_pc ();
674 thread_signal[thread] = ps.pi_osigno;
675 thread_sigcode[thread] = ps.pi_osigcode;
676
677 /* If the thread's stack has a context frame
678 on top, something fucked is going on. I do not
679 know what, but do I know this: the only thing you
680 can do with such a thread is continue it. */
681
682 thread_is_in_kernel[thread] =
683 ((read_register (PS_REGNUM) >> 25) & 3) == 0;
684
685 /* Signals push an extended frame and then fault
686 with a ridiculous pc. Pop the frame. */
687
688 if (thread_pc[thread] > STACK_END_ADDR)
689 {
690 POP_FRAME;
691 if (is_break_pc (thread_pc[thread]))
692 thread_pc[thread] = read_pc () - 2;
693 else
694 thread_pc[thread] = read_pc ();
695 write_register (PC_REGNUM, thread_pc[thread]);
696 }
697
698 if (ps.pi_osigno || ps.pi_osigcode)
699 {
700 signal_stack++;
701 signal_stack->pid = pid;
702 signal_stack->thread = thread;
703 signal_stack->signo = thread_signal[thread];
704 signal_stack->subsig = thread_sigcode[thread];
705 signal_stack->pc = thread_pc[thread];
706 }
707
708 /* The following hackery is caused by a unix 7.1 feature:
709 the inferior's fixed scheduling mode is cleared when
710 it execs the shell (since the shell is not a parallel
711 program). So, note the 5.4 trap we get when
712 the shell does its exec, then catch the 5.0 trap
713 that occurs when the debuggee starts, and set fixed
714 scheduling mode properly. */
715
716 if (ps.pi_osigno == 5 && ps.pi_osigcode == 4)
717 exec_trap_timer = 1;
718 else
719 exec_trap_timer--;
720
721 if (ps.pi_osigno == 5 && exec_trap_timer == 0)
722 set_fixed_scheduling (pid, parallel == 2);
723 }
724 }
725
726 if (signal_stack_is_empty ())
727 error ("no active threads?!");
728 }
729
730 /* Select the thread that stopped, and return *w saying why. */
731
732 select_thread (signal_stack->thread);
733
67ac9759 734 FIXME: need to convert from host sig.
dd3b648e
RP
735 stop_signal = signal_stack->signo;
736 stop_sigcode = signal_stack->subsig;
737
738 WSETSTOP (*w, signal_stack->signo);
739 w->w_thread = signal_stack->thread;
740 return (signal_stack--)->pid;
741}
742
743/* Select thread THREAD -- its registers, stack, per-thread memory.
744 This is the only routine that may assign to inferior_thread
745 or thread_regs[]. */
746
747static void
748select_thread (thread)
749 int thread;
750{
751 if (thread == inferior_thread)
752 return;
753
ade40d31 754 memcpy (thread_regs[inferior_thread], registers, REGISTER_BYTES);
dd3b648e
RP
755 ps.pi_thread = inferior_thread = thread;
756 if (have_inferior_p ())
757 ioctl (inferior_fd, PISETRWTID, &ps);
ade40d31 758 memcpy (registers, thread_regs[thread], REGISTER_BYTES);
dd3b648e
RP
759}
760
761/* Routine to set or clear a psw bit in the psw and also all psws
762 saved on the stack. Quits when we get to a frame in which the
763 saved psw is correct. */
764
765static void
766scan_stack (bit, val)
767 long bit, val;
768{
769 long ps = read_register (PS_REGNUM);
770 long fp;
771 if (val ? !(ps & bit) : (ps & bit))
772 {
773 ps ^= bit;
774 write_register (PS_REGNUM, ps);
775
776 fp = read_register (FP_REGNUM);
777 while (fp & 0x80000000)
778 {
779 ps = read_memory_integer (fp + 4, 4);
780 if (val ? (ps & bit) : !(ps & bit))
781 break;
782 ps ^= bit;
783 write_memory (fp + 4, &ps, 4);
784 fp = read_memory_integer (fp + 8, 4);
785 }
786 }
787}
788
789/* Set fixed scheduling (alliant mode) of process PID to ARG (0 or 1). */
790
791static void
792set_fixed_scheduling (pid, arg)
793 int arg;
794{
795 struct pattributes pattr;
796 getpattr (pid, &pattr);
797 pattr.pattr_pfixed = arg;
798 setpattr (pid, &pattr);
799}
800\f
801void
802core_file_command (filename, from_tty)
803 char *filename;
804 int from_tty;
805{
806 int n;
807
808 /* Discard all vestiges of any previous core file
809 and mark data and stack spaces as empty. */
810
811 if (corefile)
812 free (corefile);
813 corefile = 0;
814
815 if (corechan >= 0)
816 close (corechan);
817 corechan = -1;
818
819 data_start = 0;
820 data_end = 0;
821 stack_start = STACK_END_ADDR;
822 stack_end = STACK_END_ADDR;
823 n_core = 0;
824
825 /* Now, if a new core file was specified, open it and digest it. */
826
827 if (filename)
828 {
829 filename = tilde_expand (filename);
830 make_cleanup (free, filename);
831
832 if (have_inferior_p ())
6fe90fc8 833 error ("To look at a core file, you must kill the program with \"kill\".");
dd3b648e
RP
834 corechan = open (filename, O_RDONLY, 0);
835 if (corechan < 0)
836 perror_with_name (filename);
837
838 if (myread (corechan, &filehdr, sizeof filehdr) < 0)
839 perror_with_name (filename);
840
841 if (!IS_CORE_SOFF_MAGIC (filehdr.h_magic))
842 error ("%s: not a core file.\n", filename);
843
844 if (myread (corechan, &opthdr, filehdr.h_opthdr) < 0)
845 perror_with_name (filename);
846
847 /* Read through the section headers.
848 For text, data, etc, record an entry in the core file map.
849 For context and tcontext, record the file address of
850 the context blocks. */
851
852 lseek (corechan, (long) filehdr.h_scnptr, 0);
853
854 n_threads = 0;
855 for (n = 0; n < filehdr.h_nscns; n++)
856 {
857 if (myread (corechan, &scnhdr, sizeof scnhdr) < 0)
858 perror_with_name (filename);
859 if ((scnhdr.s_flags & S_TYPMASK) >= S_TEXT
860 && (scnhdr.s_flags & S_TYPMASK) <= S_COMON)
861 {
862 core_map[n_core].mem_addr = scnhdr.s_vaddr;
863 core_map[n_core].mem_end = scnhdr.s_vaddr + scnhdr.s_size;
864 core_map[n_core].file_addr = scnhdr.s_scnptr;
865 core_map[n_core].type = scnhdr.s_flags & S_TYPMASK;
866 if (core_map[n_core].type != S_TBSS
867 && core_map[n_core].type != S_TDATA
868 && core_map[n_core].type != S_TTEXT)
869 core_map[n_core].thread = -1;
870 else if (n_core == 0
871 || core_map[n_core-1].mem_addr != scnhdr.s_vaddr)
872 core_map[n_core].thread = 0;
873 else
874 core_map[n_core].thread = core_map[n_core-1].thread + 1;
875 n_core++;
876 }
877 else if ((scnhdr.s_flags & S_TYPMASK) == S_CONTEXT)
878 context_offset = scnhdr.s_scnptr;
879 else if ((scnhdr.s_flags & S_TYPMASK) == S_TCONTEXT)
880 tcontext_offset[n_threads++] = scnhdr.s_scnptr;
881 }
882
883 /* Read the context block, struct user, struct proc,
884 and the comm regs. */
885
886 lseek (corechan, context_offset, 0);
887 if (myread (corechan, &c, sizeof c) < 0)
888 perror_with_name (filename);
889 lseek (corechan, c.core_user_p, 0);
890 if (myread (corechan, &u, sizeof u) < 0)
891 perror_with_name (filename);
892 lseek (corechan, c.core_proc_p, 0);
893 if (myread (corechan, &pr, sizeof pr) < 0)
894 perror_with_name (filename);
895 comm_registers = pr.p_creg;
896
897 /* Core file apparently is really there. Make it really exist
898 for xfer_core_file so we can do read_memory on it. */
899
900 if (filename[0] == '/')
901 corefile = savestring (filename, strlen (filename));
902 else
58ae87f6 903 corefile = concat (current_directory, "/", filename, NULL);
dd3b648e
RP
904
905 printf_filtered ("Program %s ", u.u_comm);
906
907 /* Read the thread registers and fill in the thread_xxx[] data. */
908
909 for (n = 0; n < n_threads; n++)
910 {
911 select_thread (n);
912
913 lseek (corechan, tcontext_offset[n], 0);
914 if (myread (corechan, &tc, sizeof tc) < 0)
915 perror_with_name (corefile);
916 lseek (corechan, tc.core_thread_p, 0);
917 if (myread (corechan, &th, sizeof th) < 0)
918 perror_with_name (corefile);
919
920 lseek (corechan, tc.core_syscall_context_p, 0);
921 if (myread (corechan, registers, REGISTER_BYTES) < 0)
922 perror_with_name (corefile);
923
924 thread_signal[n] = th.t_cursig;
925 thread_sigcode[n] = th.t_code;
926 thread_state[n] = th.t_state;
927 thread_pc[n] = read_pc ();
928
929 if (thread_pc[n] > STACK_END_ADDR)
930 {
931 POP_FRAME;
932 if (is_break_pc (thread_pc[n]))
933 thread_pc[n] = read_pc () - 2;
934 else
935 thread_pc[n] = read_pc ();
936 write_register (PC_REGNUM, thread_pc[n]);
937 }
938
939 printf_filtered ("thread %d received signal %d, %s\n",
940 n, thread_signal[n],
4ace50a5 941 safe_strsignal (thread_signal[n]));
dd3b648e
RP
942 }
943
944 /* Select an interesting thread -- also-rans died with SIGKILL,
945 so find one that didn't. */
946
947 for (n = 0; n < n_threads; n++)
948 if (thread_signal[n] != 0 && thread_signal[n] != SIGKILL)
949 {
950 select_thread (n);
951 stop_signal = thread_signal[n];
952 stop_sigcode = thread_sigcode[n];
953 break;
954 }
955
956 core_aouthdr.a_magic = 0;
957
958 flush_cached_frames ();
dd3b648e
RP
959 select_frame (get_current_frame (), 0);
960 validate_files ();
961
cadbb07a 962 print_stack_frame (selected_frame, selected_frame_level, -1);
dd3b648e
RP
963 }
964 else if (from_tty)
965 printf_filtered ("No core file now.\n");
966}
This page took 0.327247 seconds and 4 git commands to generate.