Update FSF address.
[external/binutils.git] / gdb / convex-xdep.c
1 /* Convex host-dependent code for GDB.
2    Copyright 1990, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 #include "defs.h"
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>
40 #include "gdb_stat.h"
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
55 static int n_threads;
56
57 #define MAXTHREADS 8
58                 
59 /* Thread state.  The remaining data is valid only if this is PI_TALIVE.  */
60
61 static int thread_state[MAXTHREADS];
62
63 /* Stop pc, signal, signal subcode */
64
65 static int thread_pc[MAXTHREADS];
66 static int thread_signal[MAXTHREADS];
67 static int thread_sigcode[MAXTHREADS];  
68
69 /* Thread registers.
70    If thread is selected, the regs are in registers[] instead.  */
71
72 static 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
78 static char thread_is_in_kernel[MAXTHREADS];
79
80 /* The currently selected thread's number.  */
81
82 static int inferior_thread;
83
84 /* Inferior process's file handle and a process control block
85    to feed args to ioctl with.  */
86
87 static int inferior_fd;
88 static struct pcntl ps;
89
90 /* SOFF file headers for exec or core file.  */
91
92 static FILEHDR filehdr;
93 static OPTHDR opthdr;
94 static SCNHDR scnhdr;
95
96 /* Address maps constructed from section headers of exec and core files.
97    Defines process address -> file address translation.  */
98
99 struct 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
109 static int n_exec, n_core;
110 static struct pmap exec_map[100];
111 static struct pmap core_map[100];
112
113 /* Offsets in the core file of core_context and core_tcontext blocks.  */
114
115 static int context_offset;
116 static int tcontext_offset[MAXTHREADS];
117
118 /* Core file control blocks.  */
119
120 static struct core_context_v70 c;
121 static struct core_tcontext_v70 tc;
122 static struct user u;
123 static thread_t th;
124 static proc_t pr;
125
126 /* The registers of the currently selected thread.  */
127
128 extern 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
133 static struct vecst vector_registers;
134 static struct creg_ctx comm_registers;
135
136 /* Flag, set on a vanilla CONT command and cleared when the inferior
137    is continued.  */
138
139 static 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
144 static int thread_switch_ok;
145
146 /* Stack of signals recieved from threads but not yet delivered to gdb.  */
147
148 struct threadpid 
149 {
150     int pid;
151     int thread;
152     int signo;
153     int subsig;
154     int pc;
155 };
156
157 static struct threadpid signal_stack_bot[100];
158 static 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
167 static 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
174 static 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
180 static int output_radix = 0;
181
182 /* Signal subcode at last thread stop.  */
183
184 static int stop_sigcode;
185
186 /* Hack, see wait() below.  */
187
188 static int exec_trap_timer;
189
190 #include "gdbcmd.h"
191
192 static struct type *vector_type ();
193 static long *read_vector_register ();
194 static long *read_vector_register_1 ();
195 static void write_vector_register ();
196 static unsigned LONGEST read_comm_register ();
197 static void write_comm_register ();
198 static void convex_cont_command ();
199 static void thread_continue ();
200 static void select_thread ();
201 static void scan_stack ();
202 static void set_fixed_scheduling ();
203 static char *subsig_name ();
204 static void psw_info ();
205 static sig_noop ();
206 static ptr_cmp ();
207
208 \f
209 /* Execute ptrace.  Convex V7 replaced ptrace with pattach.
210    Allow ptrace (0) as a no-op.  */
211
212 int
213 call_ptrace (request, pid, procaddr, buf)
214      int request, pid;
215      PTRACE_ARG3_TYPE procaddr;
216      int buf;
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
226 execle (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
239 static 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
245 void
246 fetch_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
254 void
255 store_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
265 int
266 read_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) 
285     memset (myaddr, '\0', len);
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
293 int
294 write_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.  */
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).  */
312
313 create_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
338 attach (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
359 void
360 detach (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
373 kill_inferior ()
374 {
375   if (inferior_pid == 0)
376     return;
377   ioctl (inferior_fd, PIXTERMINATE, 0);
378   wait (0);
379   target_mourn_inferior ();
380 }
381
382 /* Read vector register REG, and return a pointer to the value.  */
383
384 static long *
385 read_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)
397         memset (&vector_registers, '\0', sizeof vector_registers);
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
421 static long *
422 read_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
442 static void
443 write_vector_register (reg, element, val)
444     int reg, element;
445     unsigned LONGEST val;
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
484 static unsigned LONGEST 
485 read_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
503 static void
504 write_comm_register (num, val)
505      int num;
506      unsigned LONGEST val;
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
524 void
525 resume (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
548 static void
549 thread_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
627 pid_t
628 wait (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
734  FIXME: need to convert from host sig.
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
747 static void
748 select_thread (thread)
749      int thread;
750 {
751   if (thread == inferior_thread)
752     return;
753
754   memcpy (thread_regs[inferior_thread], registers, REGISTER_BYTES);
755   ps.pi_thread = inferior_thread = thread;
756   if (have_inferior_p ())
757     ioctl (inferior_fd, PISETRWTID, &ps);
758   memcpy (registers, thread_regs[thread], REGISTER_BYTES);
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
765 static void
766 scan_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
791 static void
792 set_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
801 void
802 core_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 ())
833         error ("To look at a core file, you must kill the program with \"kill\".");
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
903         corefile = concat (current_directory, "/", filename, NULL);
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],
941                            safe_strsignal (thread_signal[n]));
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 ();
959       select_frame (get_current_frame (), 0);
960       validate_files ();
961
962       print_stack_frame (selected_frame, selected_frame_level, -1);
963     }
964   else if (from_tty)
965     printf_filtered ("No core file now.\n");
966 }