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
34static unsigned long registers_addr (int pid);
35static 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
42static 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
67static 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
110static 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
180static 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#if defined (I386) || defined (M68K) || defined (rs6000)
260
261/* Return the offset relative to the start of the per-thread data to the
262   saved context block.  */
263
264static unsigned long
265registers_addr (int pid)
266{
267  CORE_ADDR stblock;
268  int ecpoff = offsetof (st_t, ecp);
269  CORE_ADDR ecp;
270
271  errno = 0;
272  stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, pid, (PTRACE_ARG3_TYPE) 0,
273				0);
274  if (errno)
275    perror_with_name ("ptrace(PTRACE_THREADUSER)");
276
277  ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE) ecpoff,
278			    0);
279  if (errno)
280    perror_with_name ("ptrace(PTRACE_PEEKTHREAD)");
281
282  return ecp - stblock;
283}
284
285/* Fetch one or more registers from the inferior.  REGNO == -1 to get
286   them all.  We actually fetch more than requested, when convenient,
287   marking them as valid so we won't fetch them again.  */
288
289void
290fetch_inferior_registers (int regno)
291{
292  int reglo, reghi;
293  int i;
294  unsigned long ecp;
295
296  if (regno == -1)
297    {
298      reglo = 0;
299      reghi = NUM_REGS - 1;
300    }
301  else
302    reglo = reghi = regno;
303
304  ecp = registers_addr (PIDGET (inferior_ptid));
305
306  {
307    char buf[MAX_REGISTER_SIZE];
308    for (regno = reglo; regno <= reghi; regno++)
309      {
310	int ptrace_fun = PTRACE_PEEKTHREAD;
311
312#ifdef M68K
313	ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD;
314#endif
315
316	for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (int))
317	  {
318	    unsigned int reg;
319
320	    errno = 0;
321	    reg = ptrace (ptrace_fun, PIDGET (inferior_ptid),
322			  (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), 0);
323	    if (errno)
324	      perror_with_name ("ptrace(PTRACE_PEEKUSP)");
325
326	    *(int *) &buf[i] = reg;
327	  }
328	supply_register (regno, buf);
329      }
330  }
331}
332
333/* Store our register values back into the inferior.
334   If REGNO is -1, do this for all registers.
335   Otherwise, REGNO specifies which register (so we can save time).  */
336
337void
338store_inferior_registers (int regno)
339{
340  int reglo, reghi;
341  int i;
342  unsigned long ecp;
343
344  if (regno == -1)
345    {
346      reglo = 0;
347      reghi = NUM_REGS - 1;
348    }
349  else
350    reglo = reghi = regno;
351
352  ecp = registers_addr (PIDGET (inferior_ptid));
353
354  for (regno = reglo; regno <= reghi; regno++)
355    {
356      int ptrace_fun = PTRACE_POKEUSER;
357
358      if (CANNOT_STORE_REGISTER (regno))
359	continue;
360
361#ifdef M68K
362      ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER;
363#endif
364
365      for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (int))
366	{
367	  unsigned int reg;
368
369	  reg = *(unsigned int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno) + i];
370
371	  errno = 0;
372	  ptrace (ptrace_fun, PIDGET (inferior_ptid),
373		  (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), reg);
374	  if (errno)
375	    perror_with_name ("ptrace(PTRACE_POKEUSP)");
376	}
377    }
378}
379#endif /* defined (I386) || defined (M68K) || defined (rs6000) */
380
381/* Wait for child to do something.  Return pid of child, or -1 in case
382   of error; store status through argument pointer OURSTATUS.  */
383
384ptid_t
385child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
386{
387  int save_errno;
388  int thread;
389  union wait status;
390  int pid;
391
392  while (1)
393    {
394      int sig;
395
396      set_sigint_trap ();	/* Causes SIGINT to be passed on to the
397				   attached process. */
398      pid = wait (&status);
399
400      save_errno = errno;
401
402      clear_sigint_trap ();
403
404      if (pid == -1)
405	{
406	  if (save_errno == EINTR)
407	    continue;
408	  fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
409			      safe_strerror (save_errno));
410	  /* Claim it exited with unknown signal.  */
411	  ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
412	  ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
413	  return -1;
414	}
415
416      if (pid != PIDGET (inferior_ptid))	/* Some other process?!? */
417	continue;
418
419      thread = status.w_tid;	/* Get thread id from status */
420
421      /* Initial thread value can only be acquired via wait, so we have to
422         resort to this hack.  */
423
424      if (TIDGET (inferior_ptid) == 0 && thread != 0)
425	{
426	  inferior_ptid = MERGEPID (PIDGET (inferior_ptid), thread);
427	  add_thread (inferior_ptid);
428	}
429
430      ptid = BUILDPID (pid, thread);
431
432      /* We've become a single threaded process again.  */
433      if (thread == 0)
434	inferior_ptid = ptid;
435
436      /* Check for thread creation.  */
437      if (WIFSTOPPED (status)
438	  && WSTOPSIG (status) == SIGTRAP
439	  && !in_thread_list (ptid))
440	{
441	  int realsig;
442
443	  realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid),
444	                    (PTRACE_ARG3_TYPE) 0, 0);
445
446	  if (realsig == SIGNEWTHREAD)
447	    {
448	      /* It's a new thread notification.  We don't want to much with
449	         realsig -- the code in wait_for_inferior expects SIGTRAP. */
450	      ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
451	      ourstatus->value.sig = TARGET_SIGNAL_0;
452	      return ptid;
453	    }
454	  else
455	    error ("Signal for unknown thread was not SIGNEWTHREAD");
456	}
457
458      /* Check for thread termination.  */
459      else if (WIFSTOPPED (status)
460	       && WSTOPSIG (status) == SIGTRAP
461	       && in_thread_list (ptid))
462	{
463	  int realsig;
464
465	  realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid),
466	                    (PTRACE_ARG3_TYPE) 0, 0);
467
468	  if (realsig == SIGTHREADEXIT)
469	    {
470	      ptrace (PTRACE_CONT, PIDGET (ptid), (PTRACE_ARG3_TYPE) 0, 0);
471	      continue;
472	    }
473	}
474
475#ifdef SPARC
476      /* SPARC Lynx uses an byte reversed wait status; we must use the
477         host macros to access it.  These lines just a copy of
478         store_waitstatus.  We can't use CHILD_SPECIAL_WAITSTATUS
479         because target.c can't include the Lynx <sys/wait.h>.  */
480      if (WIFEXITED (status))
481	{
482	  ourstatus->kind = TARGET_WAITKIND_EXITED;
483	  ourstatus->value.integer = WEXITSTATUS (status);
484	}
485      else if (!WIFSTOPPED (status))
486	{
487	  ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
488	  ourstatus->value.sig =
489	    target_signal_from_host (WTERMSIG (status));
490	}
491      else
492	{
493	  ourstatus->kind = TARGET_WAITKIND_STOPPED;
494	  ourstatus->value.sig =
495	    target_signal_from_host (WSTOPSIG (status));
496	}
497#else
498      store_waitstatus (ourstatus, status.w_status);
499#endif
500
501      return ptid;
502    }
503}
504
505/* Return nonzero if the given thread is still alive.  */
506int
507child_thread_alive (ptid_t ptid)
508{
509  int pid = PIDGET (ptid);
510
511  /* Arggh.  Apparently pthread_kill only works for threads within
512     the process that calls pthread_kill.
513
514     We want to avoid the lynx signal extensions as they simply don't
515     map well to the generic gdb interface we want to keep.
516
517     All we want to do is determine if a particular thread is alive;
518     it appears as if we can just make a harmless thread specific
519     ptrace call to do that.  */
520  return (ptrace (PTRACE_THREADUSER, pid, 0, 0) != -1);
521}
522
523/* Resume execution of the inferior process.
524   If STEP is nonzero, single-step it.
525   If SIGNAL is nonzero, give it that signal.  */
526
527void
528child_resume (ptid_t ptid, int step, enum target_signal signal)
529{
530  int func;
531  int pid = PIDGET (ptid);
532
533  errno = 0;
534
535  /* If pid == -1, then we want to step/continue all threads, else
536     we only want to step/continue a single thread.  */
537  if (pid == -1)
538    {
539      pid = PIDGET (inferior_ptid);
540      func = step ? PTRACE_SINGLESTEP : PTRACE_CONT;
541    }
542  else
543    func = step ? PTRACE_SINGLESTEP_ONE : PTRACE_CONT_ONE;
544
545
546  /* An address of (PTRACE_ARG3_TYPE)1 tells ptrace to continue from where
547     it was.  (If GDB wanted it to start some other way, we have already
548     written a new PC value to the child.)
549
550     If this system does not support PT_STEP, a higher level function will
551     have called single_step() to transmute the step request into a
552     continue request (by setting breakpoints on all possible successor
553     instructions), so we don't have to worry about that here.  */
554
555  ptrace (func, pid, (PTRACE_ARG3_TYPE) 1, target_signal_to_host (signal));
556
557  if (errno)
558    perror_with_name ("ptrace");
559}
560
561/* Convert a Lynx process ID to a string.  Returns the string in a static
562   buffer.  */
563
564char *
565child_pid_to_str (ptid_t ptid)
566{
567  static char buf[40];
568
569  sprintf (buf, "process %d thread %d", PIDGET (ptid), TIDGET (ptid));
570
571  return buf;
572}
573
574/* Extract the register values out of the core file and store
575   them where `read_register' will find them.
576
577   CORE_REG_SECT points to the register values themselves, read into memory.
578   CORE_REG_SIZE is the size of that area.
579   WHICH says which set of registers we are handling (0 = int, 2 = float
580   on machines where they are discontiguous).
581   REG_ADDR is the offset from u.u_ar0 to the register values relative to
582   core_reg_sect.  This is used with old-fashioned core files to
583   locate the registers in a large upage-plus-stack ".reg" section.
584   Original upage address X is at location core_reg_sect+x+reg_addr.
585 */
586
587static void
588fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
589		      CORE_ADDR reg_addr)
590{
591  struct st_entry s;
592  unsigned int regno;
593
594  for (regno = 0; regno < NUM_REGS; regno++)
595    if (regmap[regno] != -1)
596      supply_register (regno, core_reg_sect + offsetof (st_t, ec)
597		       + regmap[regno]);
598
599#ifdef SPARC
600/* Fetching this register causes all of the I & L regs to be read from the
601   stack and validated.  */
602
603  fetch_inferior_registers (I0_REGNUM);
604#endif
605}
606
607
608/* Register that we are able to handle lynx core file formats.
609   FIXME: is this really bfd_target_unknown_flavour? */
610
611static struct core_fns lynx_core_fns =
612{
613  bfd_target_unknown_flavour,		/* core_flavour */
614  default_check_format,			/* check_format */
615  default_core_sniffer,			/* core_sniffer */
616  fetch_core_registers,			/* core_read_registers */
617  NULL					/* next */
618};
619
620void
621_initialize_core_lynx (void)
622{
623  add_core_fns (&lynx_core_fns);
624}
625