OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [lynx-nat.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* Native-dependent code for LynxOS.
2
   Copyright 1993, 1994, 1995, 1996, 1999, 2000, 2001
3
   Free Software Foundation, Inc.
4
 
5
   This file is part of GDB.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 2 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 59 Temple Place - Suite 330,
20
   Boston, MA 02111-1307, USA.  */
21
 
22
#include "defs.h"
23
#include "frame.h"
24
#include "inferior.h"
25
#include "target.h"
26
#include "gdbcore.h"
27
#include "regcache.h"
28
 
29
#include <sys/ptrace.h>
30
#include <sys/wait.h>
31
#include <sys/fpp.h>
32
 
33
static unsigned long registers_addr (int pid);
34
static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
35
 
36
#define X(ENTRY)(offsetof(struct econtext, ENTRY))
37
 
38
#ifdef I386
39
/* Mappings from tm-i386v.h */
40
 
41
static int regmap[] =
42
{
43
  X (eax),
44
  X (ecx),
45
  X (edx),
46
  X (ebx),
47
  X (esp),                      /* sp */
48
  X (ebp),                      /* fp */
49
  X (esi),
50
  X (edi),
51
  X (eip),                      /* pc */
52
  X (flags),                    /* ps */
53
  X (cs),
54
  X (ss),
55
  X (ds),
56
  X (es),
57
  X (ecode),                    /* Lynx doesn't give us either fs or gs, so */
58
  X (fault),                    /* we just substitute these two in the hopes
59
                                   that they are useful. */
60
};
61
#endif /* I386 */
62
 
63
#ifdef M68K
64
/* Mappings from tm-m68k.h */
65
 
66
static int regmap[] =
67
{
68
  X (regs[0]),                   /* d0 */
69
  X (regs[1]),                  /* d1 */
70
  X (regs[2]),                  /* d2 */
71
  X (regs[3]),                  /* d3 */
72
  X (regs[4]),                  /* d4 */
73
  X (regs[5]),                  /* d5 */
74
  X (regs[6]),                  /* d6 */
75
  X (regs[7]),                  /* d7 */
76
  X (regs[8]),                  /* a0 */
77
  X (regs[9]),                  /* a1 */
78
  X (regs[10]),                 /* a2 */
79
  X (regs[11]),                 /* a3 */
80
  X (regs[12]),                 /* a4 */
81
  X (regs[13]),                 /* a5 */
82
  X (regs[14]),                 /* fp */
83
  offsetof (st_t, usp) - offsetof (st_t, ec),   /* sp */
84
  X (status),                   /* ps */
85
  X (pc),
86
 
87
  X (fregs[0 * 3]),              /* fp0 */
88
  X (fregs[1 * 3]),             /* fp1 */
89
  X (fregs[2 * 3]),             /* fp2 */
90
  X (fregs[3 * 3]),             /* fp3 */
91
  X (fregs[4 * 3]),             /* fp4 */
92
  X (fregs[5 * 3]),             /* fp5 */
93
  X (fregs[6 * 3]),             /* fp6 */
94
  X (fregs[7 * 3]),             /* fp7 */
95
 
96
  X (fcregs[0]),         /* fpcontrol */
97
  X (fcregs[1]),                /* fpstatus */
98
  X (fcregs[2]),                /* fpiaddr */
99
  X (ssw),                      /* fpcode */
100
  X (fault),                    /* fpflags */
101
};
102
#endif /* M68K */
103
 
104
#ifdef SPARC
105
/* Mappings from tm-sparc.h */
106
 
107
#define FX(ENTRY)(offsetof(struct fcontext, ENTRY))
108
 
109
static int regmap[] =
110
{
111
  -1,                           /* g0 */
112
  X (g1),
113
  X (g2),
114
  X (g3),
115
  X (g4),
116
  -1,                           /* g5->g7 aren't saved by Lynx */
117
  -1,
118
  -1,
119
 
120
  X (o[0]),
121
  X (o[1]),
122
  X (o[2]),
123
  X (o[3]),
124
  X (o[4]),
125
  X (o[5]),
126
  X (o[6]),                     /* sp */
127
  X (o[7]),                     /* ra */
128
 
129
  -1, -1, -1, -1, -1, -1, -1, -1,       /* l0 -> l7 */
130
 
131
  -1, -1, -1, -1, -1, -1, -1, -1,       /* i0 -> i7 */
132
 
133
  FX (f.fregs[0]),               /* f0 */
134
  FX (f.fregs[1]),
135
  FX (f.fregs[2]),
136
  FX (f.fregs[3]),
137
  FX (f.fregs[4]),
138
  FX (f.fregs[5]),
139
  FX (f.fregs[6]),
140
  FX (f.fregs[7]),
141
  FX (f.fregs[8]),
142
  FX (f.fregs[9]),
143
  FX (f.fregs[10]),
144
  FX (f.fregs[11]),
145
  FX (f.fregs[12]),
146
  FX (f.fregs[13]),
147
  FX (f.fregs[14]),
148
  FX (f.fregs[15]),
149
  FX (f.fregs[16]),
150
  FX (f.fregs[17]),
151
  FX (f.fregs[18]),
152
  FX (f.fregs[19]),
153
  FX (f.fregs[20]),
154
  FX (f.fregs[21]),
155
  FX (f.fregs[22]),
156
  FX (f.fregs[23]),
157
  FX (f.fregs[24]),
158
  FX (f.fregs[25]),
159
  FX (f.fregs[26]),
160
  FX (f.fregs[27]),
161
  FX (f.fregs[28]),
162
  FX (f.fregs[29]),
163
  FX (f.fregs[30]),
164
  FX (f.fregs[31]),
165
 
166
  X (y),
167
  X (psr),
168
  X (wim),
169
  X (tbr),
170
  X (pc),
171
  X (npc),
172
  FX (fsr),                     /* fpsr */
173
  -1,                           /* cpsr */
174
};
175
#endif /* SPARC */
176
 
177
#ifdef rs6000
178
 
179
static int regmap[] =
180
{
181
  X (iregs[0]),                  /* r0 */
182
  X (iregs[1]),
183
  X (iregs[2]),
184
  X (iregs[3]),
185
  X (iregs[4]),
186
  X (iregs[5]),
187
  X (iregs[6]),
188
  X (iregs[7]),
189
  X (iregs[8]),
190
  X (iregs[9]),
191
  X (iregs[10]),
192
  X (iregs[11]),
193
  X (iregs[12]),
194
  X (iregs[13]),
195
  X (iregs[14]),
196
  X (iregs[15]),
197
  X (iregs[16]),
198
  X (iregs[17]),
199
  X (iregs[18]),
200
  X (iregs[19]),
201
  X (iregs[20]),
202
  X (iregs[21]),
203
  X (iregs[22]),
204
  X (iregs[23]),
205
  X (iregs[24]),
206
  X (iregs[25]),
207
  X (iregs[26]),
208
  X (iregs[27]),
209
  X (iregs[28]),
210
  X (iregs[29]),
211
  X (iregs[30]),
212
  X (iregs[31]),
213
 
214
  X (fregs[0]),                  /* f0 */
215
  X (fregs[1]),
216
  X (fregs[2]),
217
  X (fregs[3]),
218
  X (fregs[4]),
219
  X (fregs[5]),
220
  X (fregs[6]),
221
  X (fregs[7]),
222
  X (fregs[8]),
223
  X (fregs[9]),
224
  X (fregs[10]),
225
  X (fregs[11]),
226
  X (fregs[12]),
227
  X (fregs[13]),
228
  X (fregs[14]),
229
  X (fregs[15]),
230
  X (fregs[16]),
231
  X (fregs[17]),
232
  X (fregs[18]),
233
  X (fregs[19]),
234
  X (fregs[20]),
235
  X (fregs[21]),
236
  X (fregs[22]),
237
  X (fregs[23]),
238
  X (fregs[24]),
239
  X (fregs[25]),
240
  X (fregs[26]),
241
  X (fregs[27]),
242
  X (fregs[28]),
243
  X (fregs[29]),
244
  X (fregs[30]),
245
  X (fregs[31]),
246
 
247
  X (srr0),                     /* IAR (PC) */
248
  X (srr1),                     /* MSR (PS) */
249
  X (cr),                       /* CR */
250
  X (lr),                       /* LR */
251
  X (ctr),                      /* CTR */
252
  X (xer),                      /* XER */
253
  X (mq)                        /* MQ */
254
};
255
 
256
#endif /* rs6000 */
257
 
258
#ifdef SPARC
259
 
260
/* This routine handles some oddball cases for Sparc registers and LynxOS.
261
   In partucular, it causes refs to G0, g5->7, and all fp regs to return zero.
262
   It also handles knows where to find the I & L regs on the stack.  */
263
 
264
void
265
fetch_inferior_registers (int regno)
266
{
267
  int whatregs = 0;
268
 
269
#define WHATREGS_FLOAT 1
270
#define WHATREGS_GEN 2
271
#define WHATREGS_STACK 4
272
 
273
  if (regno == -1)
274
    whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK;
275
  else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
276
    whatregs = WHATREGS_STACK;
277
  else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
278
    whatregs = WHATREGS_FLOAT;
279
  else
280
    whatregs = WHATREGS_GEN;
281
 
282
  if (whatregs & WHATREGS_GEN)
283
    {
284
      struct econtext ec;       /* general regs */
285
      char buf[MAX_REGISTER_RAW_SIZE];
286
      int retval;
287
      int i;
288
 
289
      errno = 0;
290
      retval = ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
291
                       (PTRACE_ARG3_TYPE) & ec, 0);
292
      if (errno)
293
        perror_with_name ("ptrace(PTRACE_GETREGS)");
294
 
295
      memset (buf, 0, REGISTER_RAW_SIZE (G0_REGNUM));
296
      supply_register (G0_REGNUM, buf);
297
      supply_register (TBR_REGNUM, (char *) &ec.tbr);
298
 
299
      memcpy (&registers[REGISTER_BYTE (G1_REGNUM)], &ec.g1,
300
              4 * REGISTER_RAW_SIZE (G1_REGNUM));
301
      for (i = G1_REGNUM; i <= G1_REGNUM + 3; i++)
302
        register_valid[i] = 1;
303
 
304
      supply_register (PS_REGNUM, (char *) &ec.psr);
305
      supply_register (Y_REGNUM, (char *) &ec.y);
306
      supply_register (PC_REGNUM, (char *) &ec.pc);
307
      supply_register (NPC_REGNUM, (char *) &ec.npc);
308
      supply_register (WIM_REGNUM, (char *) &ec.wim);
309
 
310
      memcpy (&registers[REGISTER_BYTE (O0_REGNUM)], ec.o,
311
              8 * REGISTER_RAW_SIZE (O0_REGNUM));
312
      for (i = O0_REGNUM; i <= O0_REGNUM + 7; i++)
313
        register_valid[i] = 1;
314
    }
315
 
316
  if (whatregs & WHATREGS_STACK)
317
    {
318
      CORE_ADDR sp;
319
      int i;
320
 
321
      sp = read_register (SP_REGNUM);
322
 
323
      target_read_memory (sp + FRAME_SAVED_I0,
324
                          &registers[REGISTER_BYTE (I0_REGNUM)],
325
                          8 * REGISTER_RAW_SIZE (I0_REGNUM));
326
      for (i = I0_REGNUM; i <= I7_REGNUM; i++)
327
        register_valid[i] = 1;
328
 
329
      target_read_memory (sp + FRAME_SAVED_L0,
330
                          &registers[REGISTER_BYTE (L0_REGNUM)],
331
                          8 * REGISTER_RAW_SIZE (L0_REGNUM));
332
      for (i = L0_REGNUM; i <= L0_REGNUM + 7; i++)
333
        register_valid[i] = 1;
334
    }
335
 
336
  if (whatregs & WHATREGS_FLOAT)
337
    {
338
      struct fcontext fc;       /* fp regs */
339
      int retval;
340
      int i;
341
 
342
      errno = 0;
343
      retval = ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
344
                       (PTRACE_ARG3_TYPE) & fc, 0);
345
      if (errno)
346
        perror_with_name ("ptrace(PTRACE_GETFPREGS)");
347
 
348
      memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], fc.f.fregs,
349
              32 * REGISTER_RAW_SIZE (FP0_REGNUM));
350
      for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++)
351
        register_valid[i] = 1;
352
 
353
      supply_register (FPS_REGNUM, (char *) &fc.fsr);
354
    }
355
}
356
 
357
/* This routine handles storing of the I & L regs for the Sparc.  The trick
358
   here is that they actually live on the stack.  The really tricky part is
359
   that when changing the stack pointer, the I & L regs must be written to
360
   where the new SP points, otherwise the regs will be incorrect when the
361
   process is started up again.   We assume that the I & L regs are valid at
362
   this point.  */
363
 
364
void
365
store_inferior_registers (int regno)
366
{
367
  int whatregs = 0;
368
 
369
  if (regno == -1)
370
    whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK;
371
  else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
372
    whatregs = WHATREGS_STACK;
373
  else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
374
    whatregs = WHATREGS_FLOAT;
375
  else if (regno == SP_REGNUM)
376
    whatregs = WHATREGS_STACK | WHATREGS_GEN;
377
  else
378
    whatregs = WHATREGS_GEN;
379
 
380
  if (whatregs & WHATREGS_GEN)
381
    {
382
      struct econtext ec;       /* general regs */
383
      int retval;
384
 
385
      ec.tbr = read_register (TBR_REGNUM);
386
      memcpy (&ec.g1, &registers[REGISTER_BYTE (G1_REGNUM)],
387
              4 * REGISTER_RAW_SIZE (G1_REGNUM));
388
 
389
      ec.psr = read_register (PS_REGNUM);
390
      ec.y = read_register (Y_REGNUM);
391
      ec.pc = read_register (PC_REGNUM);
392
      ec.npc = read_register (NPC_REGNUM);
393
      ec.wim = read_register (WIM_REGNUM);
394
 
395
      memcpy (ec.o, &registers[REGISTER_BYTE (O0_REGNUM)],
396
              8 * REGISTER_RAW_SIZE (O0_REGNUM));
397
 
398
      errno = 0;
399
      retval = ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
400
                       (PTRACE_ARG3_TYPE) & ec, 0);
401
      if (errno)
402
        perror_with_name ("ptrace(PTRACE_SETREGS)");
403
    }
404
 
405
  if (whatregs & WHATREGS_STACK)
406
    {
407
      int regoffset;
408
      CORE_ADDR sp;
409
 
410
      sp = read_register (SP_REGNUM);
411
 
412
      if (regno == -1 || regno == SP_REGNUM)
413
        {
414
          if (!register_valid[L0_REGNUM + 5])
415
            internal_error (__FILE__, __LINE__, "failed internal consistency check");
416
          target_write_memory (sp + FRAME_SAVED_I0,
417
                              &registers[REGISTER_BYTE (I0_REGNUM)],
418
                              8 * REGISTER_RAW_SIZE (I0_REGNUM));
419
 
420
          target_write_memory (sp + FRAME_SAVED_L0,
421
                              &registers[REGISTER_BYTE (L0_REGNUM)],
422
                              8 * REGISTER_RAW_SIZE (L0_REGNUM));
423
        }
424
      else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
425
        {
426
          if (!register_valid[regno])
427
            internal_error (__FILE__, __LINE__, "failed internal consistency check");
428
          if (regno >= L0_REGNUM && regno <= L0_REGNUM + 7)
429
            regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM)
430
              + FRAME_SAVED_L0;
431
          else
432
            regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (I0_REGNUM)
433
              + FRAME_SAVED_I0;
434
          target_write_memory (sp + regoffset,
435
                              &registers[REGISTER_BYTE (regno)],
436
                              REGISTER_RAW_SIZE (regno));
437
        }
438
    }
439
 
440
  if (whatregs & WHATREGS_FLOAT)
441
    {
442
      struct fcontext fc;       /* fp regs */
443
      int retval;
444
 
445
/* We read fcontext first so that we can get good values for fq_t... */
446
      errno = 0;
447
      retval = ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
448
                       (PTRACE_ARG3_TYPE) & fc, 0);
449
      if (errno)
450
        perror_with_name ("ptrace(PTRACE_GETFPREGS)");
451
 
452
      memcpy (fc.f.fregs, &registers[REGISTER_BYTE (FP0_REGNUM)],
453
              32 * REGISTER_RAW_SIZE (FP0_REGNUM));
454
 
455
      fc.fsr = read_register (FPS_REGNUM);
456
 
457
      errno = 0;
458
      retval = ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid),
459
                       (PTRACE_ARG3_TYPE) & fc, 0);
460
      if (errno)
461
        perror_with_name ("ptrace(PTRACE_SETFPREGS)");
462
    }
463
}
464
#endif /* SPARC */
465
 
466
#if defined (I386) || defined (M68K) || defined (rs6000)
467
 
468
/* Return the offset relative to the start of the per-thread data to the
469
   saved context block.  */
470
 
471
static unsigned long
472
registers_addr (int pid)
473
{
474
  CORE_ADDR stblock;
475
  int ecpoff = offsetof (st_t, ecp);
476
  CORE_ADDR ecp;
477
 
478
  errno = 0;
479
  stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, pid, (PTRACE_ARG3_TYPE) 0,
480
                                0);
481
  if (errno)
482
    perror_with_name ("ptrace(PTRACE_THREADUSER)");
483
 
484
  ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE) ecpoff,
485
                            0);
486
  if (errno)
487
    perror_with_name ("ptrace(PTRACE_PEEKTHREAD)");
488
 
489
  return ecp - stblock;
490
}
491
 
492
/* Fetch one or more registers from the inferior.  REGNO == -1 to get
493
   them all.  We actually fetch more than requested, when convenient,
494
   marking them as valid so we won't fetch them again.  */
495
 
496
void
497
fetch_inferior_registers (int regno)
498
{
499
  int reglo, reghi;
500
  int i;
501
  unsigned long ecp;
502
 
503
  if (regno == -1)
504
    {
505
      reglo = 0;
506
      reghi = NUM_REGS - 1;
507
    }
508
  else
509
    reglo = reghi = regno;
510
 
511
  ecp = registers_addr (PIDGET (inferior_ptid));
512
 
513
  for (regno = reglo; regno <= reghi; regno++)
514
    {
515
      char buf[MAX_REGISTER_RAW_SIZE];
516
      int ptrace_fun = PTRACE_PEEKTHREAD;
517
 
518
#ifdef M68K
519
      ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD;
520
#endif
521
 
522
      for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
523
        {
524
          unsigned int reg;
525
 
526
          errno = 0;
527
          reg = ptrace (ptrace_fun, PIDGET (inferior_ptid),
528
                        (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), 0);
529
          if (errno)
530
            perror_with_name ("ptrace(PTRACE_PEEKUSP)");
531
 
532
          *(int *) &buf[i] = reg;
533
        }
534
      supply_register (regno, buf);
535
    }
536
}
537
 
538
/* Store our register values back into the inferior.
539
   If REGNO is -1, do this for all registers.
540
   Otherwise, REGNO specifies which register (so we can save time).  */
541
 
542
void
543
store_inferior_registers (int regno)
544
{
545
  int reglo, reghi;
546
  int i;
547
  unsigned long ecp;
548
 
549
  if (regno == -1)
550
    {
551
      reglo = 0;
552
      reghi = NUM_REGS - 1;
553
    }
554
  else
555
    reglo = reghi = regno;
556
 
557
  ecp = registers_addr (PIDGET (inferior_ptid));
558
 
559
  for (regno = reglo; regno <= reghi; regno++)
560
    {
561
      int ptrace_fun = PTRACE_POKEUSER;
562
 
563
      if (CANNOT_STORE_REGISTER (regno))
564
        continue;
565
 
566
#ifdef M68K
567
      ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER;
568
#endif
569
 
570
      for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
571
        {
572
          unsigned int reg;
573
 
574
          reg = *(unsigned int *) &registers[REGISTER_BYTE (regno) + i];
575
 
576
          errno = 0;
577
          ptrace (ptrace_fun, PIDGET (inferior_ptid),
578
                  (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), reg);
579
          if (errno)
580
            perror_with_name ("ptrace(PTRACE_POKEUSP)");
581
        }
582
    }
583
}
584
#endif /* defined (I386) || defined (M68K) || defined (rs6000) */
585
 
586
/* Wait for child to do something.  Return pid of child, or -1 in case
587
   of error; store status through argument pointer OURSTATUS.  */
588
 
589
ptid_t
590
child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
591
{
592
  int save_errno;
593
  int thread;
594
  union wait status;
595
  int pid;
596
 
597
  while (1)
598
    {
599
      int sig;
600
 
601
      set_sigint_trap ();       /* Causes SIGINT to be passed on to the
602
                                   attached process. */
603
      pid = wait (&status);
604
 
605
      save_errno = errno;
606
 
607
      clear_sigint_trap ();
608
 
609
      if (pid == -1)
610
        {
611
          if (save_errno == EINTR)
612
            continue;
613
          fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
614
                              safe_strerror (save_errno));
615
          /* Claim it exited with unknown signal.  */
616
          ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
617
          ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
618
          return -1;
619
        }
620
 
621
      if (pid != PIDGET (inferior_ptid))        /* Some other process?!? */
622
        continue;
623
 
624
      thread = status.w_tid;    /* Get thread id from status */
625
 
626
      /* Initial thread value can only be acquired via wait, so we have to
627
         resort to this hack.  */
628
 
629
      if (TIDGET (inferior_ptid) == 0 && thread != 0)
630
        {
631
          inferior_ptid = MERGEPID (PIDGET (inferior_ptid), thread);
632
          add_thread (inferior_ptid);
633
        }
634
 
635
      ptid = BUILDPID (pid, thread);
636
 
637
      /* We've become a single threaded process again.  */
638
      if (thread == 0)
639
        inferior_ptid = ptid;
640
 
641
      /* Check for thread creation.  */
642
      if (WIFSTOPPED (status)
643
          && WSTOPSIG (status) == SIGTRAP
644
          && !in_thread_list (ptid))
645
        {
646
          int realsig;
647
 
648
          realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid),
649
                            (PTRACE_ARG3_TYPE) 0, 0);
650
 
651
          if (realsig == SIGNEWTHREAD)
652
            {
653
              /* It's a new thread notification.  We don't want to much with
654
                 realsig -- the code in wait_for_inferior expects SIGTRAP. */
655
              ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
656
              ourstatus->value.sig = TARGET_SIGNAL_0;
657
              return ptid;
658
            }
659
          else
660
            error ("Signal for unknown thread was not SIGNEWTHREAD");
661
        }
662
 
663
      /* Check for thread termination.  */
664
      else if (WIFSTOPPED (status)
665
               && WSTOPSIG (status) == SIGTRAP
666
               && in_thread_list (ptid))
667
        {
668
          int realsig;
669
 
670
          realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid),
671
                            (PTRACE_ARG3_TYPE) 0, 0);
672
 
673
          if (realsig == SIGTHREADEXIT)
674
            {
675
              ptrace (PTRACE_CONT, PIDGET (ptid), (PTRACE_ARG3_TYPE) 0, 0);
676
              continue;
677
            }
678
        }
679
 
680
#ifdef SPARC
681
      /* SPARC Lynx uses an byte reversed wait status; we must use the
682
         host macros to access it.  These lines just a copy of
683
         store_waitstatus.  We can't use CHILD_SPECIAL_WAITSTATUS
684
         because target.c can't include the Lynx <sys/wait.h>.  */
685
      if (WIFEXITED (status))
686
        {
687
          ourstatus->kind = TARGET_WAITKIND_EXITED;
688
          ourstatus->value.integer = WEXITSTATUS (status);
689
        }
690
      else if (!WIFSTOPPED (status))
691
        {
692
          ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
693
          ourstatus->value.sig =
694
            target_signal_from_host (WTERMSIG (status));
695
        }
696
      else
697
        {
698
          ourstatus->kind = TARGET_WAITKIND_STOPPED;
699
          ourstatus->value.sig =
700
            target_signal_from_host (WSTOPSIG (status));
701
        }
702
#else
703
      store_waitstatus (ourstatus, status.w_status);
704
#endif
705
 
706
      return ptid;
707
    }
708
}
709
 
710
/* Return nonzero if the given thread is still alive.  */
711
int
712
child_thread_alive (ptid_t ptid)
713
{
714
  int pid = PIDGET (ptid);
715
 
716
  /* Arggh.  Apparently pthread_kill only works for threads within
717
     the process that calls pthread_kill.
718
 
719
     We want to avoid the lynx signal extensions as they simply don't
720
     map well to the generic gdb interface we want to keep.
721
 
722
     All we want to do is determine if a particular thread is alive;
723
     it appears as if we can just make a harmless thread specific
724
     ptrace call to do that.  */
725
  return (ptrace (PTRACE_THREADUSER, pid, 0, 0) != -1);
726
}
727
 
728
/* Resume execution of the inferior process.
729
   If STEP is nonzero, single-step it.
730
   If SIGNAL is nonzero, give it that signal.  */
731
 
732
void
733
child_resume (ptid_t ptid, int step, enum target_signal signal)
734
{
735
  int func;
736
  int pid = PIDGET (ptid);
737
 
738
  errno = 0;
739
 
740
  /* If pid == -1, then we want to step/continue all threads, else
741
     we only want to step/continue a single thread.  */
742
  if (pid == -1)
743
    {
744
      pid = PIDGET (inferior_ptid);
745
      func = step ? PTRACE_SINGLESTEP : PTRACE_CONT;
746
    }
747
  else
748
    func = step ? PTRACE_SINGLESTEP_ONE : PTRACE_CONT_ONE;
749
 
750
 
751
  /* An address of (PTRACE_ARG3_TYPE)1 tells ptrace to continue from where
752
     it was.  (If GDB wanted it to start some other way, we have already
753
     written a new PC value to the child.)
754
 
755
     If this system does not support PT_STEP, a higher level function will
756
     have called single_step() to transmute the step request into a
757
     continue request (by setting breakpoints on all possible successor
758
     instructions), so we don't have to worry about that here.  */
759
 
760
  ptrace (func, pid, (PTRACE_ARG3_TYPE) 1, target_signal_to_host (signal));
761
 
762
  if (errno)
763
    perror_with_name ("ptrace");
764
}
765
 
766
/* Convert a Lynx process ID to a string.  Returns the string in a static
767
   buffer.  */
768
 
769
char *
770
child_pid_to_str (ptid_t ptid)
771
{
772
  static char buf[40];
773
 
774
  sprintf (buf, "process %d thread %d", PIDGET (ptid), TIDGET (ptid));
775
 
776
  return buf;
777
}
778
 
779
/* Extract the register values out of the core file and store
780
   them where `read_register' will find them.
781
 
782
   CORE_REG_SECT points to the register values themselves, read into memory.
783
   CORE_REG_SIZE is the size of that area.
784
   WHICH says which set of registers we are handling (0 = int, 2 = float
785
   on machines where they are discontiguous).
786
   REG_ADDR is the offset from u.u_ar0 to the register values relative to
787
   core_reg_sect.  This is used with old-fashioned core files to
788
   locate the registers in a large upage-plus-stack ".reg" section.
789
   Original upage address X is at location core_reg_sect+x+reg_addr.
790
 */
791
 
792
static void
793
fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
794
                      CORE_ADDR reg_addr)
795
{
796
  struct st_entry s;
797
  unsigned int regno;
798
 
799
  for (regno = 0; regno < NUM_REGS; regno++)
800
    if (regmap[regno] != -1)
801
      supply_register (regno, core_reg_sect + offsetof (st_t, ec)
802
                       + regmap[regno]);
803
 
804
#ifdef SPARC
805
/* Fetching this register causes all of the I & L regs to be read from the
806
   stack and validated.  */
807
 
808
  fetch_inferior_registers (I0_REGNUM);
809
#endif
810
}
811
 
812
 
813
/* Register that we are able to handle lynx core file formats.
814
   FIXME: is this really bfd_target_unknown_flavour? */
815
 
816
static struct core_fns lynx_core_fns =
817
{
818
  bfd_target_unknown_flavour,           /* core_flavour */
819
  default_check_format,                 /* check_format */
820
  default_core_sniffer,                 /* core_sniffer */
821
  fetch_core_registers,                 /* core_read_registers */
822
  NULL                                  /* next */
823
};
824
 
825
void
826
_initialize_core_lynx (void)
827
{
828
  add_core_fns (&lynx_core_fns);
829
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.