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