*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / lynx-nat.c
1 /* Native-dependent code for LynxOS.
2
3 Copyright (C) 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., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, 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 < register_size (current_gdbarch, 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 regcache_raw_supply (current_regcache, 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 < register_size (current_gdbarch, 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 regcache_raw_supply (current_regcache, regno,
597 core_reg_sect + offsetof (st_t, ec) + 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 deprecated_add_core_fns (&lynx_core_fns);
624 }
This page took 0.043339 seconds and 4 git commands to generate.