]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/gdb/gdb/lynx-nat.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / gdb / 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 #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
264 static unsigned long
265 registers_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
289 void
290 fetch_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
337 void
338 store_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
384 ptid_t
385 child_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.  */
506 int
507 child_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
527 void
528 child_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
564 char *
565 child_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
587 static void
588 fetch_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 \f
607
608 /* Register that we are able to handle lynx core file formats.
609    FIXME: is this really bfd_target_unknown_flavour? */
610
611 static 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
620 void
621 _initialize_core_lynx (void)
622 {
623   add_core_fns (&lynx_core_fns);
624 }