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