Fix up mix of man(7)/mdoc(7).
[netbsd-mini2440.git] / gnu / dist / gdb6 / gdb / lynx-nat.c
blobd66e5bd47c5005be920f213e189c609b84f86cc2
1 /* Native-dependent code for LynxOS.
3 Copyright (C) 1993, 1994, 1995, 1996, 1999, 2000, 2001, 2003 Free
4 Software Foundation, Inc.
6 This file is part of GDB.
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.
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.
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., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
23 #include "defs.h"
24 #include "frame.h"
25 #include "inferior.h"
26 #include "target.h"
27 #include "gdbcore.h"
28 #include "regcache.h"
30 #include <sys/ptrace.h>
31 #Include "gdb_wait.h"
32 #include <sys/fpp.h>
34 static unsigned long registers_addr (int pid);
35 static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
37 #define X(ENTRY)(offsetof(struct econtext, ENTRY))
39 #ifdef I386
40 /* Mappings from tm-i386v.h */
42 static int regmap[] =
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. */
62 #endif /* I386 */
64 #ifdef M68K
65 /* Mappings from tm-m68k.h */
67 static int regmap[] =
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),
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 */
97 X (fcregs[0]), /* fpcontrol */
98 X (fcregs[1]), /* fpstatus */
99 X (fcregs[2]), /* fpiaddr */
100 X (ssw), /* fpcode */
101 X (fault), /* fpflags */
103 #endif /* M68K */
105 #ifdef SPARC
106 /* Mappings from tm-sparc.h */
108 #define FX(ENTRY)(offsetof(struct fcontext, ENTRY))
110 static int regmap[] =
112 -1, /* g0 */
113 X (g1),
114 X (g2),
115 X (g3),
116 X (g4),
117 -1, /* g5->g7 aren't saved by Lynx */
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 */
130 -1, -1, -1, -1, -1, -1, -1, -1, /* l0 -> l7 */
132 -1, -1, -1, -1, -1, -1, -1, -1, /* i0 -> i7 */
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]),
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 */
176 #endif /* SPARC */
178 #ifdef rs6000
180 static int regmap[] =
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]),
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]),
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 */
257 #endif /* rs6000 */
259 #if defined (I386) || defined (M68K) || defined (rs6000)
261 /* Return the offset relative to the start of the per-thread data to the
262 saved context block. */
264 static unsigned long
265 registers_addr (int pid)
267 CORE_ADDR stblock;
268 int ecpoff = offsetof (st_t, ecp);
269 CORE_ADDR ecp;
271 errno = 0;
272 stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, pid, (PTRACE_ARG3_TYPE) 0,
274 if (errno)
275 perror_with_name ("ptrace(PTRACE_THREADUSER)");
277 ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE) ecpoff,
279 if (errno)
280 perror_with_name ("ptrace(PTRACE_PEEKTHREAD)");
282 return ecp - stblock;
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. */
289 void
290 fetch_inferior_registers (int regno)
292 int reglo, reghi;
293 int i;
294 unsigned long ecp;
296 if (regno == -1)
298 reglo = 0;
299 reghi = NUM_REGS - 1;
301 else
302 reglo = reghi = regno;
304 ecp = registers_addr (PIDGET (inferior_ptid));
307 char buf[MAX_REGISTER_SIZE];
308 for (regno = reglo; regno <= reghi; regno++)
310 int ptrace_fun = PTRACE_PEEKTHREAD;
312 #ifdef M68K
313 ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD;
314 #endif
316 for (i = 0; i < register_size (current_gdbarch, regno); i += sizeof (int))
318 unsigned int reg;
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)");
326 *(int *) &buf[i] = reg;
328 regcache_raw_supply (current_regcache, regno, buf);
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). */
337 void
338 store_inferior_registers (int regno)
340 int reglo, reghi;
341 int i;
342 unsigned long ecp;
344 if (regno == -1)
346 reglo = 0;
347 reghi = NUM_REGS - 1;
349 else
350 reglo = reghi = regno;
352 ecp = registers_addr (PIDGET (inferior_ptid));
354 for (regno = reglo; regno <= reghi; regno++)
356 int ptrace_fun = PTRACE_POKEUSER;
358 if (CANNOT_STORE_REGISTER (regno))
359 continue;
361 #ifdef M68K
362 ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER;
363 #endif
365 for (i = 0; i < register_size (current_gdbarch, regno); i += sizeof (int))
367 unsigned int reg;
369 reg = *(unsigned int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno) + i];
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)");
379 #endif /* defined (I386) || defined (M68K) || defined (rs6000) */
381 /* Wait for child to do something. Return pid of child, or -1 in case
382 of error; store status through argument pointer OURSTATUS. */
384 ptid_t
385 child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
387 int save_errno;
388 int thread;
389 union wait status;
390 int pid;
392 while (1)
394 int sig;
396 set_sigint_trap (); /* Causes SIGINT to be passed on to the
397 attached process. */
398 pid = wait (&status);
400 save_errno = errno;
402 clear_sigint_trap ();
404 if (pid == -1)
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;
416 if (pid != PIDGET (inferior_ptid)) /* Some other process?!? */
417 continue;
419 thread = status.w_tid; /* Get thread id from status */
421 /* Initial thread value can only be acquired via wait, so we have to
422 resort to this hack. */
424 if (TIDGET (inferior_ptid) == 0 && thread != 0)
426 inferior_ptid = MERGEPID (PIDGET (inferior_ptid), thread);
427 add_thread (inferior_ptid);
430 ptid = BUILDPID (pid, thread);
432 /* We've become a single threaded process again. */
433 if (thread == 0)
434 inferior_ptid = ptid;
436 /* Check for thread creation. */
437 if (WIFSTOPPED (status)
438 && WSTOPSIG (status) == SIGTRAP
439 && !in_thread_list (ptid))
441 int realsig;
443 realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid),
444 (PTRACE_ARG3_TYPE) 0, 0);
446 if (realsig == SIGNEWTHREAD)
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;
454 else
455 error ("Signal for unknown thread was not SIGNEWTHREAD");
458 /* Check for thread termination. */
459 else if (WIFSTOPPED (status)
460 && WSTOPSIG (status) == SIGTRAP
461 && in_thread_list (ptid))
463 int realsig;
465 realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid),
466 (PTRACE_ARG3_TYPE) 0, 0);
468 if (realsig == SIGTHREADEXIT)
470 ptrace (PTRACE_CONT, PIDGET (ptid), (PTRACE_ARG3_TYPE) 0, 0);
471 continue;
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))
482 ourstatus->kind = TARGET_WAITKIND_EXITED;
483 ourstatus->value.integer = WEXITSTATUS (status);
485 else if (!WIFSTOPPED (status))
487 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
488 ourstatus->value.sig =
489 target_signal_from_host (WTERMSIG (status));
491 else
493 ourstatus->kind = TARGET_WAITKIND_STOPPED;
494 ourstatus->value.sig =
495 target_signal_from_host (WSTOPSIG (status));
497 #else
498 store_waitstatus (ourstatus, status.w_status);
499 #endif
501 return ptid;
505 /* Return nonzero if the given thread is still alive. */
507 child_thread_alive (ptid_t ptid)
509 int pid = PIDGET (ptid);
511 /* Arggh. Apparently pthread_kill only works for threads within
512 the process that calls pthread_kill.
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.
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);
523 /* Resume execution of the inferior process.
524 If STEP is nonzero, single-step it.
525 If SIGNAL is nonzero, give it that signal. */
527 void
528 child_resume (ptid_t ptid, int step, enum target_signal signal)
530 int func;
531 int pid = PIDGET (ptid);
533 errno = 0;
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)
539 pid = PIDGET (inferior_ptid);
540 func = step ? PTRACE_SINGLESTEP : PTRACE_CONT;
542 else
543 func = step ? PTRACE_SINGLESTEP_ONE : PTRACE_CONT_ONE;
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.)
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. */
555 ptrace (func, pid, (PTRACE_ARG3_TYPE) 1, target_signal_to_host (signal));
557 if (errno)
558 perror_with_name ("ptrace");
561 /* Convert a Lynx process ID to a string. Returns the string in a static
562 buffer. */
564 char *
565 child_pid_to_str (ptid_t ptid)
567 static char buf[40];
569 sprintf (buf, "process %d thread %d", PIDGET (ptid), TIDGET (ptid));
571 return buf;
574 /* Extract the register values out of the core file and store
575 them where `read_register' will find them.
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.
587 static void
588 fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
589 CORE_ADDR reg_addr)
591 struct st_entry s;
592 unsigned int regno;
594 for (regno = 0; regno < NUM_REGS; regno++)
595 if (regmap[regno] != -1)
596 regcache_raw_supply (current_regcache, regno,
597 core_reg_sect + offsetof (st_t, ec) + regmap[regno]);
599 #ifdef SPARC
600 /* Fetching this register causes all of the I & L regs to be read from the
601 stack and validated. */
603 fetch_inferior_registers (I0_REGNUM);
604 #endif
608 /* Register that we are able to handle lynx core file formats.
609 FIXME: is this really bfd_target_unknown_flavour? */
611 static struct core_fns lynx_core_fns =
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 */
620 void
621 _initialize_core_lynx (void)
623 deprecated_add_core_fns (&lynx_core_fns);