2003-09-17 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / lynx-nat.c
CommitLineData
c906108c 1/* Native-dependent code for LynxOS.
2555fe1a
AC
2
3 Copyright 1993, 1994, 1995, 1996, 1999, 2000, 2001, 2003 Free
4 Software Foundation, Inc.
c906108c 5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
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.
c906108c 12
c5aa993b
JM
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.
c906108c 17
c5aa993b
JM
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. */
c906108c
SS
22
23#include "defs.h"
24#include "frame.h"
25#include "inferior.h"
26#include "target.h"
27#include "gdbcore.h"
4e052eda 28#include "regcache.h"
c906108c
SS
29
30#include <sys/ptrace.h>
2555fe1a 31#Include "gdb_wait.h"
c906108c
SS
32#include <sys/fpp.h>
33
a14ed312
KB
34static unsigned long registers_addr (int pid);
35static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
c906108c
SS
36
37#define X(ENTRY)(offsetof(struct econtext, ENTRY))
38
39#ifdef I386
40/* Mappings from tm-i386v.h */
41
42static int regmap[] =
43{
c5aa993b
JM
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
c906108c
SS
60 that they are useful. */
61};
62#endif /* I386 */
63
64#ifdef M68K
65/* Mappings from tm-m68k.h */
66
67static int regmap[] =
68{
c5aa993b
JM
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 */
c906108c
SS
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 */
c5aa993b
JM
113 X (g1),
114 X (g2),
115 X (g3),
116 X (g4),
c906108c
SS
117 -1, /* g5->g7 aren't saved by Lynx */
118 -1,
119 -1,
120
c5aa993b
JM
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 */
c906108c
SS
174 -1, /* cpsr */
175};
176#endif /* SPARC */
177
178#ifdef rs6000
179
180static int regmap[] =
181{
c5aa993b
JM
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 */
c906108c
SS
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
265void
fba45db2 266fetch_inferior_registers (int regno)
c906108c
SS
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 {
c5aa993b 285 struct econtext ec; /* general regs */
123a958e 286 char buf[MAX_REGISTER_SIZE];
c906108c
SS
287 int retval;
288 int i;
289
290 errno = 0;
39f77062
KB
291 retval = ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
292 (PTRACE_ARG3_TYPE) & ec, 0);
c906108c
SS
293 if (errno)
294 perror_with_name ("ptrace(PTRACE_GETREGS)");
c5aa993b 295
c906108c
SS
296 memset (buf, 0, REGISTER_RAW_SIZE (G0_REGNUM));
297 supply_register (G0_REGNUM, buf);
c5aa993b 298 supply_register (TBR_REGNUM, (char *) &ec.tbr);
c906108c 299
62700349 300 memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (G1_REGNUM)], &ec.g1,
c906108c
SS
301 4 * REGISTER_RAW_SIZE (G1_REGNUM));
302 for (i = G1_REGNUM; i <= G1_REGNUM + 3; i++)
8262ee23 303 deprecated_register_valid[i] = 1;
c906108c 304
c5aa993b
JM
305 supply_register (PS_REGNUM, (char *) &ec.psr);
306 supply_register (Y_REGNUM, (char *) &ec.y);
307 supply_register (PC_REGNUM, (char *) &ec.pc);
efe59759 308 supply_register (DEPRECATED_NPC_REGNUM, (char *) &ec.npc);
c5aa993b 309 supply_register (WIM_REGNUM, (char *) &ec.wim);
c906108c 310
62700349 311 memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (O0_REGNUM)], ec.o,
c906108c
SS
312 8 * REGISTER_RAW_SIZE (O0_REGNUM));
313 for (i = O0_REGNUM; i <= O0_REGNUM + 7; i++)
8262ee23 314 deprecated_register_valid[i] = 1;
c906108c
SS
315 }
316
317 if (whatregs & WHATREGS_STACK)
318 {
319 CORE_ADDR sp;
320 int i;
321
322 sp = read_register (SP_REGNUM);
323
f7384f0f 324 target_read_memory (sp + FRAME_SAVED_I0,
62700349 325 &deprecated_registers[DEPRECATED_REGISTER_BYTE (I0_REGNUM)],
f7384f0f 326 8 * REGISTER_RAW_SIZE (I0_REGNUM));
c906108c 327 for (i = I0_REGNUM; i <= I7_REGNUM; i++)
8262ee23 328 deprecated_register_valid[i] = 1;
c906108c 329
f7384f0f 330 target_read_memory (sp + FRAME_SAVED_L0,
62700349 331 &deprecated_registers[DEPRECATED_REGISTER_BYTE (L0_REGNUM)],
f7384f0f 332 8 * REGISTER_RAW_SIZE (L0_REGNUM));
c906108c 333 for (i = L0_REGNUM; i <= L0_REGNUM + 7; i++)
8262ee23 334 deprecated_register_valid[i] = 1;
c906108c
SS
335 }
336
337 if (whatregs & WHATREGS_FLOAT)
338 {
c5aa993b 339 struct fcontext fc; /* fp regs */
c906108c
SS
340 int retval;
341 int i;
342
343 errno = 0;
39f77062
KB
344 retval = ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
345 (PTRACE_ARG3_TYPE) & fc, 0);
c906108c
SS
346 if (errno)
347 perror_with_name ("ptrace(PTRACE_GETFPREGS)");
c5aa993b 348
62700349 349 memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)], fc.f.fregs,
c906108c
SS
350 32 * REGISTER_RAW_SIZE (FP0_REGNUM));
351 for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++)
8262ee23 352 deprecated_register_valid[i] = 1;
c906108c 353
c5aa993b 354 supply_register (FPS_REGNUM, (char *) &fc.fsr);
c906108c
SS
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
365void
fba45db2 366store_inferior_registers (int regno)
c906108c
SS
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 {
c5aa993b 383 struct econtext ec; /* general regs */
c906108c
SS
384 int retval;
385
386 ec.tbr = read_register (TBR_REGNUM);
62700349 387 memcpy (&ec.g1, &deprecated_registers[DEPRECATED_REGISTER_BYTE (G1_REGNUM)],
c906108c
SS
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);
efe59759 393 ec.npc = read_register (DEPRECATED_NPC_REGNUM);
c906108c
SS
394 ec.wim = read_register (WIM_REGNUM);
395
62700349 396 memcpy (ec.o, &deprecated_registers[DEPRECATED_REGISTER_BYTE (O0_REGNUM)],
c906108c
SS
397 8 * REGISTER_RAW_SIZE (O0_REGNUM));
398
399 errno = 0;
39f77062
KB
400 retval = ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
401 (PTRACE_ARG3_TYPE) & ec, 0);
c906108c
SS
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 {
8262ee23 415 if (!deprecated_register_valid[L0_REGNUM + 5])
e1e9e218 416 internal_error (__FILE__, __LINE__, "failed internal consistency check");
f7384f0f 417 target_write_memory (sp + FRAME_SAVED_I0,
62700349 418 &deprecated_registers[DEPRECATED_REGISTER_BYTE (I0_REGNUM)],
f7384f0f 419 8 * REGISTER_RAW_SIZE (I0_REGNUM));
c906108c 420
f7384f0f 421 target_write_memory (sp + FRAME_SAVED_L0,
62700349 422 &deprecated_registers[DEPRECATED_REGISTER_BYTE (L0_REGNUM)],
f7384f0f 423 8 * REGISTER_RAW_SIZE (L0_REGNUM));
c906108c
SS
424 }
425 else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
426 {
8262ee23 427 if (!deprecated_register_valid[regno])
e1e9e218 428 internal_error (__FILE__, __LINE__, "failed internal consistency check");
c906108c 429 if (regno >= L0_REGNUM && regno <= L0_REGNUM + 7)
62700349 430 regoffset = DEPRECATED_REGISTER_BYTE (regno) - DEPRECATED_REGISTER_BYTE (L0_REGNUM)
c906108c
SS
431 + FRAME_SAVED_L0;
432 else
62700349 433 regoffset = DEPRECATED_REGISTER_BYTE (regno) - DEPRECATED_REGISTER_BYTE (I0_REGNUM)
c906108c 434 + FRAME_SAVED_I0;
f7384f0f 435 target_write_memory (sp + regoffset,
62700349 436 &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)],
f7384f0f 437 REGISTER_RAW_SIZE (regno));
c906108c
SS
438 }
439 }
440
441 if (whatregs & WHATREGS_FLOAT)
442 {
c5aa993b 443 struct fcontext fc; /* fp regs */
c906108c
SS
444 int retval;
445
446/* We read fcontext first so that we can get good values for fq_t... */
447 errno = 0;
39f77062
KB
448 retval = ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
449 (PTRACE_ARG3_TYPE) & fc, 0);
c906108c
SS
450 if (errno)
451 perror_with_name ("ptrace(PTRACE_GETFPREGS)");
c5aa993b 452
62700349 453 memcpy (fc.f.fregs, &deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM)],
c906108c
SS
454 32 * REGISTER_RAW_SIZE (FP0_REGNUM));
455
456 fc.fsr = read_register (FPS_REGNUM);
457
458 errno = 0;
39f77062
KB
459 retval = ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid),
460 (PTRACE_ARG3_TYPE) & fc, 0);
c906108c
SS
461 if (errno)
462 perror_with_name ("ptrace(PTRACE_SETFPREGS)");
c5aa993b 463 }
c906108c
SS
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
472static unsigned long
fba45db2 473registers_addr (int pid)
c906108c
SS
474{
475 CORE_ADDR stblock;
c5aa993b 476 int ecpoff = offsetof (st_t, ecp);
c906108c
SS
477 CORE_ADDR ecp;
478
479 errno = 0;
c5aa993b 480 stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, pid, (PTRACE_ARG3_TYPE) 0,
c906108c
SS
481 0);
482 if (errno)
483 perror_with_name ("ptrace(PTRACE_THREADUSER)");
484
c5aa993b 485 ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE) ecpoff,
c906108c
SS
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
497void
fba45db2 498fetch_inferior_registers (int regno)
c906108c
SS
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
39f77062 512 ecp = registers_addr (PIDGET (inferior_ptid));
c906108c 513
6789195b 514 {
123a958e 515 char buf[MAX_REGISTER_SIZE];
6789195b
AC
516 for (regno = reglo; regno <= reghi; regno++)
517 {
518 int ptrace_fun = PTRACE_PEEKTHREAD;
519
c906108c 520#ifdef M68K
6789195b 521 ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD;
c906108c 522#endif
6789195b
AC
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 }
c906108c
SS
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
c906108c 545void
fba45db2 546store_inferior_registers (int regno)
c906108c
SS
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
39f77062 560 ecp = registers_addr (PIDGET (inferior_ptid));
c906108c
SS
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
62700349 577 reg = *(unsigned int *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno) + i];
c906108c
SS
578
579 errno = 0;
39f77062 580 ptrace (ptrace_fun, PIDGET (inferior_ptid),
c906108c
SS
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
39f77062
KB
592ptid_t
593child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
c906108c
SS
594{
595 int save_errno;
596 int thread;
597 union wait status;
39f77062 598 int pid;
c906108c
SS
599
600 while (1)
601 {
602 int sig;
603
c5aa993b 604 set_sigint_trap (); /* Causes SIGINT to be passed on to the
c906108c
SS
605 attached process. */
606 pid = wait (&status);
607
608 save_errno = errno;
609
c5aa993b 610 clear_sigint_trap ();
c906108c
SS
611
612 if (pid == -1)
613 {
614 if (save_errno == EINTR)
615 continue;
616 fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
c5aa993b 617 safe_strerror (save_errno));
c906108c
SS
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
39f77062 624 if (pid != PIDGET (inferior_ptid)) /* Some other process?!? */
c906108c
SS
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
c5aa993b 630 resort to this hack. */
c906108c 631
39f77062 632 if (TIDGET (inferior_ptid) == 0 && thread != 0)
c906108c 633 {
39f77062
KB
634 inferior_ptid = MERGEPID (PIDGET (inferior_ptid), thread);
635 add_thread (inferior_ptid);
c906108c
SS
636 }
637
39f77062 638 ptid = BUILDPID (pid, thread);
c906108c
SS
639
640 /* We've become a single threaded process again. */
641 if (thread == 0)
39f77062 642 inferior_ptid = ptid;
c906108c
SS
643
644 /* Check for thread creation. */
c5aa993b
JM
645 if (WIFSTOPPED (status)
646 && WSTOPSIG (status) == SIGTRAP
39f77062 647 && !in_thread_list (ptid))
c906108c
SS
648 {
649 int realsig;
650
39f77062
KB
651 realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid),
652 (PTRACE_ARG3_TYPE) 0, 0);
c906108c
SS
653
654 if (realsig == SIGNEWTHREAD)
655 {
656 /* It's a new thread notification. We don't want to much with
c5aa993b 657 realsig -- the code in wait_for_inferior expects SIGTRAP. */
c906108c
SS
658 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
659 ourstatus->value.sig = TARGET_SIGNAL_0;
39f77062 660 return ptid;
c906108c
SS
661 }
662 else
663 error ("Signal for unknown thread was not SIGNEWTHREAD");
664 }
665
666 /* Check for thread termination. */
c5aa993b
JM
667 else if (WIFSTOPPED (status)
668 && WSTOPSIG (status) == SIGTRAP
39f77062 669 && in_thread_list (ptid))
c906108c
SS
670 {
671 int realsig;
672
39f77062
KB
673 realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid),
674 (PTRACE_ARG3_TYPE) 0, 0);
c906108c
SS
675
676 if (realsig == SIGTHREADEXIT)
677 {
39f77062 678 ptrace (PTRACE_CONT, PIDGET (ptid), (PTRACE_ARG3_TYPE) 0, 0);
c906108c
SS
679 continue;
680 }
681 }
682
683#ifdef SPARC
684 /* SPARC Lynx uses an byte reversed wait status; we must use the
c5aa993b
JM
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>. */
c906108c
SS
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
39f77062 709 return ptid;
c906108c
SS
710 }
711}
712
713/* Return nonzero if the given thread is still alive. */
714int
39f77062 715child_thread_alive (ptid_t ptid)
c906108c 716{
39f77062
KB
717 int pid = PIDGET (ptid);
718
c906108c
SS
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
735void
39f77062 736child_resume (ptid_t ptid, int step, enum target_signal signal)
c906108c
SS
737{
738 int func;
39f77062 739 int pid = PIDGET (ptid);
c906108c
SS
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 {
39f77062 747 pid = PIDGET (inferior_ptid);
c906108c
SS
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
772char *
39f77062 773child_pid_to_str (ptid_t ptid)
c906108c
SS
774{
775 static char buf[40];
776
39f77062 777 sprintf (buf, "process %d thread %d", PIDGET (ptid), TIDGET (ptid));
c906108c
SS
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
c5aa993b 788 on machines where they are discontiguous).
c906108c 789 REG_ADDR is the offset from u.u_ar0 to the register values relative to
c5aa993b
JM
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.
c906108c
SS
793 */
794
795static void
fba45db2
KB
796fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
797 CORE_ADDR reg_addr)
c906108c
SS
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}
c906108c 814\f
c5aa993b 815
c906108c
SS
816/* Register that we are able to handle lynx core file formats.
817 FIXME: is this really bfd_target_unknown_flavour? */
818
819static struct core_fns lynx_core_fns =
820{
2acceee2
JM
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 */
c906108c
SS
826};
827
828void
fba45db2 829_initialize_core_lynx (void)
c906108c
SS
830{
831 add_core_fns (&lynx_core_fns);
832}
This page took 0.401046 seconds and 4 git commands to generate.