OSDN Git Service

* linux-low.c (linux_create_inferior): Call setpgid. Return
[pf3gnuchains/pf3gnuchains3x.git] / gdb / lynx-nat.c
1 /* Native-dependent code for LynxOS.
2    Copyright 1993, 1994, 1995, 1996, 1999, 2000, 2001
3    Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.  */
21
22 #include "defs.h"
23 #include "frame.h"
24 #include "inferior.h"
25 #include "target.h"
26 #include "gdbcore.h"
27 #include "regcache.h"
28
29 #include <sys/ptrace.h>
30 #include <sys/wait.h>
31 #include <sys/fpp.h>
32
33 static unsigned long registers_addr (int pid);
34 static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
35
36 #define X(ENTRY)(offsetof(struct econtext, ENTRY))
37
38 #ifdef I386
39 /* Mappings from tm-i386v.h */
40
41 static int regmap[] =
42 {
43   X (eax),
44   X (ecx),
45   X (edx),
46   X (ebx),
47   X (esp),                      /* sp */
48   X (ebp),                      /* fp */
49   X (esi),
50   X (edi),
51   X (eip),                      /* pc */
52   X (flags),                    /* ps */
53   X (cs),
54   X (ss),
55   X (ds),
56   X (es),
57   X (ecode),                    /* Lynx doesn't give us either fs or gs, so */
58   X (fault),                    /* we just substitute these two in the hopes
59                                    that they are useful. */
60 };
61 #endif /* I386 */
62
63 #ifdef M68K
64 /* Mappings from tm-m68k.h */
65
66 static int regmap[] =
67 {
68   X (regs[0]),                  /* d0 */
69   X (regs[1]),                  /* d1 */
70   X (regs[2]),                  /* d2 */
71   X (regs[3]),                  /* d3 */
72   X (regs[4]),                  /* d4 */
73   X (regs[5]),                  /* d5 */
74   X (regs[6]),                  /* d6 */
75   X (regs[7]),                  /* d7 */
76   X (regs[8]),                  /* a0 */
77   X (regs[9]),                  /* a1 */
78   X (regs[10]),                 /* a2 */
79   X (regs[11]),                 /* a3 */
80   X (regs[12]),                 /* a4 */
81   X (regs[13]),                 /* a5 */
82   X (regs[14]),                 /* fp */
83   offsetof (st_t, usp) - offsetof (st_t, ec),   /* sp */
84   X (status),                   /* ps */
85   X (pc),
86
87   X (fregs[0 * 3]),             /* fp0 */
88   X (fregs[1 * 3]),             /* fp1 */
89   X (fregs[2 * 3]),             /* fp2 */
90   X (fregs[3 * 3]),             /* fp3 */
91   X (fregs[4 * 3]),             /* fp4 */
92   X (fregs[5 * 3]),             /* fp5 */
93   X (fregs[6 * 3]),             /* fp6 */
94   X (fregs[7 * 3]),             /* fp7 */
95
96   X (fcregs[0]),                /* fpcontrol */
97   X (fcregs[1]),                /* fpstatus */
98   X (fcregs[2]),                /* fpiaddr */
99   X (ssw),                      /* fpcode */
100   X (fault),                    /* fpflags */
101 };
102 #endif /* M68K */
103
104 #ifdef SPARC
105 /* Mappings from tm-sparc.h */
106
107 #define FX(ENTRY)(offsetof(struct fcontext, ENTRY))
108
109 static int regmap[] =
110 {
111   -1,                           /* g0 */
112   X (g1),
113   X (g2),
114   X (g3),
115   X (g4),
116   -1,                           /* g5->g7 aren't saved by Lynx */
117   -1,
118   -1,
119
120   X (o[0]),
121   X (o[1]),
122   X (o[2]),
123   X (o[3]),
124   X (o[4]),
125   X (o[5]),
126   X (o[6]),                     /* sp */
127   X (o[7]),                     /* ra */
128
129   -1, -1, -1, -1, -1, -1, -1, -1,       /* l0 -> l7 */
130
131   -1, -1, -1, -1, -1, -1, -1, -1,       /* i0 -> i7 */
132
133   FX (f.fregs[0]),              /* f0 */
134   FX (f.fregs[1]),
135   FX (f.fregs[2]),
136   FX (f.fregs[3]),
137   FX (f.fregs[4]),
138   FX (f.fregs[5]),
139   FX (f.fregs[6]),
140   FX (f.fregs[7]),
141   FX (f.fregs[8]),
142   FX (f.fregs[9]),
143   FX (f.fregs[10]),
144   FX (f.fregs[11]),
145   FX (f.fregs[12]),
146   FX (f.fregs[13]),
147   FX (f.fregs[14]),
148   FX (f.fregs[15]),
149   FX (f.fregs[16]),
150   FX (f.fregs[17]),
151   FX (f.fregs[18]),
152   FX (f.fregs[19]),
153   FX (f.fregs[20]),
154   FX (f.fregs[21]),
155   FX (f.fregs[22]),
156   FX (f.fregs[23]),
157   FX (f.fregs[24]),
158   FX (f.fregs[25]),
159   FX (f.fregs[26]),
160   FX (f.fregs[27]),
161   FX (f.fregs[28]),
162   FX (f.fregs[29]),
163   FX (f.fregs[30]),
164   FX (f.fregs[31]),
165
166   X (y),
167   X (psr),
168   X (wim),
169   X (tbr),
170   X (pc),
171   X (npc),
172   FX (fsr),                     /* fpsr */
173   -1,                           /* cpsr */
174 };
175 #endif /* SPARC */
176
177 #ifdef rs6000
178
179 static int regmap[] =
180 {
181   X (iregs[0]),                 /* r0 */
182   X (iregs[1]),
183   X (iregs[2]),
184   X (iregs[3]),
185   X (iregs[4]),
186   X (iregs[5]),
187   X (iregs[6]),
188   X (iregs[7]),
189   X (iregs[8]),
190   X (iregs[9]),
191   X (iregs[10]),
192   X (iregs[11]),
193   X (iregs[12]),
194   X (iregs[13]),
195   X (iregs[14]),
196   X (iregs[15]),
197   X (iregs[16]),
198   X (iregs[17]),
199   X (iregs[18]),
200   X (iregs[19]),
201   X (iregs[20]),
202   X (iregs[21]),
203   X (iregs[22]),
204   X (iregs[23]),
205   X (iregs[24]),
206   X (iregs[25]),
207   X (iregs[26]),
208   X (iregs[27]),
209   X (iregs[28]),
210   X (iregs[29]),
211   X (iregs[30]),
212   X (iregs[31]),
213
214   X (fregs[0]),                 /* f0 */
215   X (fregs[1]),
216   X (fregs[2]),
217   X (fregs[3]),
218   X (fregs[4]),
219   X (fregs[5]),
220   X (fregs[6]),
221   X (fregs[7]),
222   X (fregs[8]),
223   X (fregs[9]),
224   X (fregs[10]),
225   X (fregs[11]),
226   X (fregs[12]),
227   X (fregs[13]),
228   X (fregs[14]),
229   X (fregs[15]),
230   X (fregs[16]),
231   X (fregs[17]),
232   X (fregs[18]),
233   X (fregs[19]),
234   X (fregs[20]),
235   X (fregs[21]),
236   X (fregs[22]),
237   X (fregs[23]),
238   X (fregs[24]),
239   X (fregs[25]),
240   X (fregs[26]),
241   X (fregs[27]),
242   X (fregs[28]),
243   X (fregs[29]),
244   X (fregs[30]),
245   X (fregs[31]),
246
247   X (srr0),                     /* IAR (PC) */
248   X (srr1),                     /* MSR (PS) */
249   X (cr),                       /* CR */
250   X (lr),                       /* LR */
251   X (ctr),                      /* CTR */
252   X (xer),                      /* XER */
253   X (mq)                        /* MQ */
254 };
255
256 #endif /* rs6000 */
257
258 #ifdef SPARC
259
260 /* This routine handles some oddball cases for Sparc registers and LynxOS.
261    In partucular, it causes refs to G0, g5->7, and all fp regs to return zero.
262    It also handles knows where to find the I & L regs on the stack.  */
263
264 void
265 fetch_inferior_registers (int regno)
266 {
267   int whatregs = 0;
268
269 #define WHATREGS_FLOAT 1
270 #define WHATREGS_GEN 2
271 #define WHATREGS_STACK 4
272
273   if (regno == -1)
274     whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK;
275   else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
276     whatregs = WHATREGS_STACK;
277   else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
278     whatregs = WHATREGS_FLOAT;
279   else
280     whatregs = WHATREGS_GEN;
281
282   if (whatregs & WHATREGS_GEN)
283     {
284       struct econtext ec;       /* general regs */
285       char buf[MAX_REGISTER_RAW_SIZE];
286       int retval;
287       int i;
288
289       errno = 0;
290       retval = ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
291                        (PTRACE_ARG3_TYPE) & ec, 0);
292       if (errno)
293         perror_with_name ("ptrace(PTRACE_GETREGS)");
294
295       memset (buf, 0, REGISTER_RAW_SIZE (G0_REGNUM));
296       supply_register (G0_REGNUM, buf);
297       supply_register (TBR_REGNUM, (char *) &ec.tbr);
298
299       memcpy (&registers[REGISTER_BYTE (G1_REGNUM)], &ec.g1,
300               4 * REGISTER_RAW_SIZE (G1_REGNUM));
301       for (i = G1_REGNUM; i <= G1_REGNUM + 3; i++)
302         register_valid[i] = 1;
303
304       supply_register (PS_REGNUM, (char *) &ec.psr);
305       supply_register (Y_REGNUM, (char *) &ec.y);
306       supply_register (PC_REGNUM, (char *) &ec.pc);
307       supply_register (NPC_REGNUM, (char *) &ec.npc);
308       supply_register (WIM_REGNUM, (char *) &ec.wim);
309
310       memcpy (&registers[REGISTER_BYTE (O0_REGNUM)], ec.o,
311               8 * REGISTER_RAW_SIZE (O0_REGNUM));
312       for (i = O0_REGNUM; i <= O0_REGNUM + 7; i++)
313         register_valid[i] = 1;
314     }
315
316   if (whatregs & WHATREGS_STACK)
317     {
318       CORE_ADDR sp;
319       int i;
320
321       sp = read_register (SP_REGNUM);
322
323       target_read_memory (sp + FRAME_SAVED_I0,
324                           &registers[REGISTER_BYTE (I0_REGNUM)],
325                           8 * REGISTER_RAW_SIZE (I0_REGNUM));
326       for (i = I0_REGNUM; i <= I7_REGNUM; i++)
327         register_valid[i] = 1;
328
329       target_read_memory (sp + FRAME_SAVED_L0,
330                           &registers[REGISTER_BYTE (L0_REGNUM)],
331                           8 * REGISTER_RAW_SIZE (L0_REGNUM));
332       for (i = L0_REGNUM; i <= L0_REGNUM + 7; i++)
333         register_valid[i] = 1;
334     }
335
336   if (whatregs & WHATREGS_FLOAT)
337     {
338       struct fcontext fc;       /* fp regs */
339       int retval;
340       int i;
341
342       errno = 0;
343       retval = ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
344                        (PTRACE_ARG3_TYPE) & fc, 0);
345       if (errno)
346         perror_with_name ("ptrace(PTRACE_GETFPREGS)");
347
348       memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], fc.f.fregs,
349               32 * REGISTER_RAW_SIZE (FP0_REGNUM));
350       for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++)
351         register_valid[i] = 1;
352
353       supply_register (FPS_REGNUM, (char *) &fc.fsr);
354     }
355 }
356
357 /* This routine handles storing of the I & L regs for the Sparc.  The trick
358    here is that they actually live on the stack.  The really tricky part is
359    that when changing the stack pointer, the I & L regs must be written to
360    where the new SP points, otherwise the regs will be incorrect when the
361    process is started up again.   We assume that the I & L regs are valid at
362    this point.  */
363
364 void
365 store_inferior_registers (int regno)
366 {
367   int whatregs = 0;
368
369   if (regno == -1)
370     whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK;
371   else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
372     whatregs = WHATREGS_STACK;
373   else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
374     whatregs = WHATREGS_FLOAT;
375   else if (regno == SP_REGNUM)
376     whatregs = WHATREGS_STACK | WHATREGS_GEN;
377   else
378     whatregs = WHATREGS_GEN;
379
380   if (whatregs & WHATREGS_GEN)
381     {
382       struct econtext ec;       /* general regs */
383       int retval;
384
385       ec.tbr = read_register (TBR_REGNUM);
386       memcpy (&ec.g1, &registers[REGISTER_BYTE (G1_REGNUM)],
387               4 * REGISTER_RAW_SIZE (G1_REGNUM));
388
389       ec.psr = read_register (PS_REGNUM);
390       ec.y = read_register (Y_REGNUM);
391       ec.pc = read_register (PC_REGNUM);
392       ec.npc = read_register (NPC_REGNUM);
393       ec.wim = read_register (WIM_REGNUM);
394
395       memcpy (ec.o, &registers[REGISTER_BYTE (O0_REGNUM)],
396               8 * REGISTER_RAW_SIZE (O0_REGNUM));
397
398       errno = 0;
399       retval = ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
400                        (PTRACE_ARG3_TYPE) & ec, 0);
401       if (errno)
402         perror_with_name ("ptrace(PTRACE_SETREGS)");
403     }
404
405   if (whatregs & WHATREGS_STACK)
406     {
407       int regoffset;
408       CORE_ADDR sp;
409
410       sp = read_register (SP_REGNUM);
411
412       if (regno == -1 || regno == SP_REGNUM)
413         {
414           if (!register_valid[L0_REGNUM + 5])
415             internal_error (__FILE__, __LINE__, "failed internal consistency check");
416           target_write_memory (sp + FRAME_SAVED_I0,
417                               &registers[REGISTER_BYTE (I0_REGNUM)],
418                               8 * REGISTER_RAW_SIZE (I0_REGNUM));
419
420           target_write_memory (sp + FRAME_SAVED_L0,
421                               &registers[REGISTER_BYTE (L0_REGNUM)],
422                               8 * REGISTER_RAW_SIZE (L0_REGNUM));
423         }
424       else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
425         {
426           if (!register_valid[regno])
427             internal_error (__FILE__, __LINE__, "failed internal consistency check");
428           if (regno >= L0_REGNUM && regno <= L0_REGNUM + 7)
429             regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM)
430               + FRAME_SAVED_L0;
431           else
432             regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (I0_REGNUM)
433               + FRAME_SAVED_I0;
434           target_write_memory (sp + regoffset, 
435                               &registers[REGISTER_BYTE (regno)],
436                               REGISTER_RAW_SIZE (regno));
437         }
438     }
439
440   if (whatregs & WHATREGS_FLOAT)
441     {
442       struct fcontext fc;       /* fp regs */
443       int retval;
444
445 /* We read fcontext first so that we can get good values for fq_t... */
446       errno = 0;
447       retval = ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
448                        (PTRACE_ARG3_TYPE) & fc, 0);
449       if (errno)
450         perror_with_name ("ptrace(PTRACE_GETFPREGS)");
451
452       memcpy (fc.f.fregs, &registers[REGISTER_BYTE (FP0_REGNUM)],
453               32 * REGISTER_RAW_SIZE (FP0_REGNUM));
454
455       fc.fsr = read_register (FPS_REGNUM);
456
457       errno = 0;
458       retval = ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid),
459                        (PTRACE_ARG3_TYPE) & fc, 0);
460       if (errno)
461         perror_with_name ("ptrace(PTRACE_SETFPREGS)");
462     }
463 }
464 #endif /* SPARC */
465
466 #if defined (I386) || defined (M68K) || defined (rs6000)
467
468 /* Return the offset relative to the start of the per-thread data to the
469    saved context block.  */
470
471 static unsigned long
472 registers_addr (int pid)
473 {
474   CORE_ADDR stblock;
475   int ecpoff = offsetof (st_t, ecp);
476   CORE_ADDR ecp;
477
478   errno = 0;
479   stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, pid, (PTRACE_ARG3_TYPE) 0,
480                                 0);
481   if (errno)
482     perror_with_name ("ptrace(PTRACE_THREADUSER)");
483
484   ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE) ecpoff,
485                             0);
486   if (errno)
487     perror_with_name ("ptrace(PTRACE_PEEKTHREAD)");
488
489   return ecp - stblock;
490 }
491
492 /* Fetch one or more registers from the inferior.  REGNO == -1 to get
493    them all.  We actually fetch more than requested, when convenient,
494    marking them as valid so we won't fetch them again.  */
495
496 void
497 fetch_inferior_registers (int regno)
498 {
499   int reglo, reghi;
500   int i;
501   unsigned long ecp;
502
503   if (regno == -1)
504     {
505       reglo = 0;
506       reghi = NUM_REGS - 1;
507     }
508   else
509     reglo = reghi = regno;
510
511   ecp = registers_addr (PIDGET (inferior_ptid));
512
513   for (regno = reglo; regno <= reghi; regno++)
514     {
515       char buf[MAX_REGISTER_RAW_SIZE];
516       int ptrace_fun = PTRACE_PEEKTHREAD;
517
518 #ifdef M68K
519       ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD;
520 #endif
521
522       for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
523         {
524           unsigned int reg;
525
526           errno = 0;
527           reg = ptrace (ptrace_fun, PIDGET (inferior_ptid),
528                         (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), 0);
529           if (errno)
530             perror_with_name ("ptrace(PTRACE_PEEKUSP)");
531
532           *(int *) &buf[i] = reg;
533         }
534       supply_register (regno, buf);
535     }
536 }
537
538 /* Store our register values back into the inferior.
539    If REGNO is -1, do this for all registers.
540    Otherwise, REGNO specifies which register (so we can save time).  */
541
542 void
543 store_inferior_registers (int regno)
544 {
545   int reglo, reghi;
546   int i;
547   unsigned long ecp;
548
549   if (regno == -1)
550     {
551       reglo = 0;
552       reghi = NUM_REGS - 1;
553     }
554   else
555     reglo = reghi = regno;
556
557   ecp = registers_addr (PIDGET (inferior_ptid));
558
559   for (regno = reglo; regno <= reghi; regno++)
560     {
561       int ptrace_fun = PTRACE_POKEUSER;
562
563       if (CANNOT_STORE_REGISTER (regno))
564         continue;
565
566 #ifdef M68K
567       ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER;
568 #endif
569
570       for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
571         {
572           unsigned int reg;
573
574           reg = *(unsigned int *) &registers[REGISTER_BYTE (regno) + i];
575
576           errno = 0;
577           ptrace (ptrace_fun, PIDGET (inferior_ptid),
578                   (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), reg);
579           if (errno)
580             perror_with_name ("ptrace(PTRACE_POKEUSP)");
581         }
582     }
583 }
584 #endif /* defined (I386) || defined (M68K) || defined (rs6000) */
585
586 /* Wait for child to do something.  Return pid of child, or -1 in case
587    of error; store status through argument pointer OURSTATUS.  */
588
589 ptid_t
590 child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
591 {
592   int save_errno;
593   int thread;
594   union wait status;
595   int pid;
596
597   while (1)
598     {
599       int sig;
600
601       set_sigint_trap ();       /* Causes SIGINT to be passed on to the
602                                    attached process. */
603       pid = wait (&status);
604
605       save_errno = errno;
606
607       clear_sigint_trap ();
608
609       if (pid == -1)
610         {
611           if (save_errno == EINTR)
612             continue;
613           fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
614                               safe_strerror (save_errno));
615           /* Claim it exited with unknown signal.  */
616           ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
617           ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
618           return -1;
619         }
620
621       if (pid != PIDGET (inferior_ptid))        /* Some other process?!? */
622         continue;
623
624       thread = status.w_tid;    /* Get thread id from status */
625
626       /* Initial thread value can only be acquired via wait, so we have to
627          resort to this hack.  */
628
629       if (TIDGET (inferior_ptid) == 0 && thread != 0)
630         {
631           inferior_ptid = MERGEPID (PIDGET (inferior_ptid), thread);
632           add_thread (inferior_ptid);
633         }
634
635       ptid = BUILDPID (pid, thread);
636
637       /* We've become a single threaded process again.  */
638       if (thread == 0)
639         inferior_ptid = ptid;
640
641       /* Check for thread creation.  */
642       if (WIFSTOPPED (status)
643           && WSTOPSIG (status) == SIGTRAP
644           && !in_thread_list (ptid))
645         {
646           int realsig;
647
648           realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid),
649                             (PTRACE_ARG3_TYPE) 0, 0);
650
651           if (realsig == SIGNEWTHREAD)
652             {
653               /* It's a new thread notification.  We don't want to much with
654                  realsig -- the code in wait_for_inferior expects SIGTRAP. */
655               ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
656               ourstatus->value.sig = TARGET_SIGNAL_0;
657               return ptid;
658             }
659           else
660             error ("Signal for unknown thread was not SIGNEWTHREAD");
661         }
662
663       /* Check for thread termination.  */
664       else if (WIFSTOPPED (status)
665                && WSTOPSIG (status) == SIGTRAP
666                && in_thread_list (ptid))
667         {
668           int realsig;
669
670           realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid),
671                             (PTRACE_ARG3_TYPE) 0, 0);
672
673           if (realsig == SIGTHREADEXIT)
674             {
675               ptrace (PTRACE_CONT, PIDGET (ptid), (PTRACE_ARG3_TYPE) 0, 0);
676               continue;
677             }
678         }
679
680 #ifdef SPARC
681       /* SPARC Lynx uses an byte reversed wait status; we must use the
682          host macros to access it.  These lines just a copy of
683          store_waitstatus.  We can't use CHILD_SPECIAL_WAITSTATUS
684          because target.c can't include the Lynx <sys/wait.h>.  */
685       if (WIFEXITED (status))
686         {
687           ourstatus->kind = TARGET_WAITKIND_EXITED;
688           ourstatus->value.integer = WEXITSTATUS (status);
689         }
690       else if (!WIFSTOPPED (status))
691         {
692           ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
693           ourstatus->value.sig =
694             target_signal_from_host (WTERMSIG (status));
695         }
696       else
697         {
698           ourstatus->kind = TARGET_WAITKIND_STOPPED;
699           ourstatus->value.sig =
700             target_signal_from_host (WSTOPSIG (status));
701         }
702 #else
703       store_waitstatus (ourstatus, status.w_status);
704 #endif
705
706       return ptid;
707     }
708 }
709
710 /* Return nonzero if the given thread is still alive.  */
711 int
712 child_thread_alive (ptid_t ptid)
713 {
714   int pid = PIDGET (ptid);
715
716   /* Arggh.  Apparently pthread_kill only works for threads within
717      the process that calls pthread_kill.
718
719      We want to avoid the lynx signal extensions as they simply don't
720      map well to the generic gdb interface we want to keep.
721
722      All we want to do is determine if a particular thread is alive;
723      it appears as if we can just make a harmless thread specific
724      ptrace call to do that.  */
725   return (ptrace (PTRACE_THREADUSER, pid, 0, 0) != -1);
726 }
727
728 /* Resume execution of the inferior process.
729    If STEP is nonzero, single-step it.
730    If SIGNAL is nonzero, give it that signal.  */
731
732 void
733 child_resume (ptid_t ptid, int step, enum target_signal signal)
734 {
735   int func;
736   int pid = PIDGET (ptid);
737
738   errno = 0;
739
740   /* If pid == -1, then we want to step/continue all threads, else
741      we only want to step/continue a single thread.  */
742   if (pid == -1)
743     {
744       pid = PIDGET (inferior_ptid);
745       func = step ? PTRACE_SINGLESTEP : PTRACE_CONT;
746     }
747   else
748     func = step ? PTRACE_SINGLESTEP_ONE : PTRACE_CONT_ONE;
749
750
751   /* An address of (PTRACE_ARG3_TYPE)1 tells ptrace to continue from where
752      it was.  (If GDB wanted it to start some other way, we have already
753      written a new PC value to the child.)
754
755      If this system does not support PT_STEP, a higher level function will
756      have called single_step() to transmute the step request into a
757      continue request (by setting breakpoints on all possible successor
758      instructions), so we don't have to worry about that here.  */
759
760   ptrace (func, pid, (PTRACE_ARG3_TYPE) 1, target_signal_to_host (signal));
761
762   if (errno)
763     perror_with_name ("ptrace");
764 }
765
766 /* Convert a Lynx process ID to a string.  Returns the string in a static
767    buffer.  */
768
769 char *
770 child_pid_to_str (ptid_t ptid)
771 {
772   static char buf[40];
773
774   sprintf (buf, "process %d thread %d", PIDGET (ptid), TIDGET (ptid));
775
776   return buf;
777 }
778
779 /* Extract the register values out of the core file and store
780    them where `read_register' will find them.
781
782    CORE_REG_SECT points to the register values themselves, read into memory.
783    CORE_REG_SIZE is the size of that area.
784    WHICH says which set of registers we are handling (0 = int, 2 = float
785    on machines where they are discontiguous).
786    REG_ADDR is the offset from u.u_ar0 to the register values relative to
787    core_reg_sect.  This is used with old-fashioned core files to
788    locate the registers in a large upage-plus-stack ".reg" section.
789    Original upage address X is at location core_reg_sect+x+reg_addr.
790  */
791
792 static void
793 fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
794                       CORE_ADDR reg_addr)
795 {
796   struct st_entry s;
797   unsigned int regno;
798
799   for (regno = 0; regno < NUM_REGS; regno++)
800     if (regmap[regno] != -1)
801       supply_register (regno, core_reg_sect + offsetof (st_t, ec)
802                        + regmap[regno]);
803
804 #ifdef SPARC
805 /* Fetching this register causes all of the I & L regs to be read from the
806    stack and validated.  */
807
808   fetch_inferior_registers (I0_REGNUM);
809 #endif
810 }
811 \f
812
813 /* Register that we are able to handle lynx core file formats.
814    FIXME: is this really bfd_target_unknown_flavour? */
815
816 static struct core_fns lynx_core_fns =
817 {
818   bfd_target_unknown_flavour,           /* core_flavour */
819   default_check_format,                 /* check_format */
820   default_core_sniffer,                 /* core_sniffer */
821   fetch_core_registers,                 /* core_read_registers */
822   NULL                                  /* next */
823 };
824
825 void
826 _initialize_core_lynx (void)
827 {
828   add_core_fns (&lynx_core_fns);
829 }