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