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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* Low level Unix child interface to ptrace, for GDB when running under Unix.
2
   Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
3
   1999, 2000, 2001
4
   Free 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 "gdb_string.h"
28
#include "regcache.h"
29
 
30
#include "gdb_wait.h"
31
 
32
#include "command.h"
33
 
34
#ifdef USG
35
#include <sys/types.h>
36
#endif
37
 
38
#include <sys/param.h>
39
#include "gdb_dirent.h"
40
#include <signal.h>
41
#include <sys/ioctl.h>
42
 
43
#ifdef HAVE_PTRACE_H
44
#include <ptrace.h>
45
#else
46
#ifdef HAVE_SYS_PTRACE_H
47
#include <sys/ptrace.h>
48
#endif
49
#endif
50
 
51
#if !defined (PT_READ_I)
52
#define PT_READ_I       1       /* Read word from text space */
53
#endif
54
#if !defined (PT_READ_D)
55
#define PT_READ_D       2       /* Read word from data space */
56
#endif
57
#if !defined (PT_READ_U)
58
#define PT_READ_U       3       /* Read word from kernel user struct */
59
#endif
60
#if !defined (PT_WRITE_I)
61
#define PT_WRITE_I      4       /* Write word to text space */
62
#endif
63
#if !defined (PT_WRITE_D)
64
#define PT_WRITE_D      5       /* Write word to data space */
65
#endif
66
#if !defined (PT_WRITE_U)
67
#define PT_WRITE_U      6       /* Write word to kernel user struct */
68
#endif
69
#if !defined (PT_CONTINUE)
70
#define PT_CONTINUE     7       /* Continue after signal */
71
#endif
72
#if !defined (PT_STEP)
73
#define PT_STEP         9       /* Set flag for single stepping */
74
#endif
75
#if !defined (PT_KILL)
76
#define PT_KILL         8       /* Send child a SIGKILL signal */
77
#endif
78
 
79
#ifndef PT_ATTACH
80
#define PT_ATTACH PTRACE_ATTACH
81
#endif
82
#ifndef PT_DETACH
83
#define PT_DETACH PTRACE_DETACH
84
#endif
85
 
86
#include "gdbcore.h"
87
#ifndef NO_SYS_FILE
88
#include <sys/file.h>
89
#endif
90
#if 0
91
/* Don't think this is used anymore.  On the sequent (not sure whether it's
92
   dynix or ptx or both), it is included unconditionally by sys/user.h and
93
   not protected against multiple inclusion.  */
94
#include "gdb_stat.h"
95
#endif
96
 
97
#if !defined (FETCH_INFERIOR_REGISTERS)
98
#include <sys/user.h>           /* Probably need to poke the user structure */
99
#if defined (KERNEL_U_ADDR_BSD)
100
#include <a.out.h>              /* For struct nlist */
101
#endif /* KERNEL_U_ADDR_BSD.  */
102
#endif /* !FETCH_INFERIOR_REGISTERS */
103
 
104
#if !defined (CHILD_XFER_MEMORY)
105
static void udot_info (char *, int);
106
#endif
107
 
108
#if !defined (FETCH_INFERIOR_REGISTERS)
109
static void fetch_register (int);
110
static void store_register (int);
111
#endif
112
 
113
void _initialize_kernel_u_addr (void);
114
void _initialize_infptrace (void);
115
 
116
 
117
/* This function simply calls ptrace with the given arguments.
118
   It exists so that all calls to ptrace are isolated in this
119
   machine-dependent file. */
120
int
121
call_ptrace (int request, int pid, PTRACE_ARG3_TYPE addr, int data)
122
{
123
  int pt_status = 0;
124
 
125
#if 0
126
  int saved_errno;
127
 
128
  printf ("call_ptrace(request=%d, pid=%d, addr=0x%x, data=0x%x)",
129
          request, pid, addr, data);
130
#endif
131
#if defined(PT_SETTRC)
132
  /* If the parent can be told to attach to us, try to do it.  */
133
  if (request == PT_SETTRC)
134
    {
135
      errno = 0;
136
#if !defined (FIVE_ARG_PTRACE)
137
      pt_status = ptrace (PT_SETTRC, pid, addr, data);
138
#else
139
      /* Deal with HPUX 8.0 braindamage.  We never use the
140
         calls which require the fifth argument.  */
141
      pt_status = ptrace (PT_SETTRC, pid, addr, data, 0);
142
#endif
143
      if (errno)
144
        perror_with_name ("ptrace");
145
#if 0
146
      printf (" = %d\n", pt_status);
147
#endif
148
      if (pt_status < 0)
149
        return pt_status;
150
      else
151
        return parent_attach_all (pid, addr, data);
152
    }
153
#endif
154
 
155
#if defined(PT_CONTIN1)
156
  /* On HPUX, PT_CONTIN1 is a form of continue that preserves pending
157
     signals.  If it's available, use it.  */
158
  if (request == PT_CONTINUE)
159
    request = PT_CONTIN1;
160
#endif
161
 
162
#if defined(PT_SINGLE1)
163
  /* On HPUX, PT_SINGLE1 is a form of step that preserves pending
164
     signals.  If it's available, use it.  */
165
  if (request == PT_STEP)
166
    request = PT_SINGLE1;
167
#endif
168
 
169
#if 0
170
  saved_errno = errno;
171
  errno = 0;
172
#endif
173
#if !defined (FIVE_ARG_PTRACE)
174
  pt_status = ptrace (request, pid, addr, data);
175
#else
176
  /* Deal with HPUX 8.0 braindamage.  We never use the
177
     calls which require the fifth argument.  */
178
  pt_status = ptrace (request, pid, addr, data, 0);
179
#endif
180
 
181
#if 0
182
  if (errno)
183
    printf (" [errno = %d]", errno);
184
 
185
  errno = saved_errno;
186
  printf (" = 0x%x\n", pt_status);
187
#endif
188
  return pt_status;
189
}
190
 
191
 
192
#if defined (DEBUG_PTRACE) || defined (FIVE_ARG_PTRACE)
193
/* For the rest of the file, use an extra level of indirection */
194
/* This lets us breakpoint usefully on call_ptrace. */
195
#define ptrace call_ptrace
196
#endif
197
 
198
/* Wait for a process to finish, possibly running a target-specific
199
   hook before returning.  */
200
 
201
int
202
ptrace_wait (ptid_t ptid, int *status)
203
{
204
  int wstate;
205
 
206
  wstate = wait (status);
207
  target_post_wait (pid_to_ptid (wstate), *status);
208
  return wstate;
209
}
210
 
211
void
212
kill_inferior (void)
213
{
214
  int status;
215
  int pid =  PIDGET (inferior_ptid);
216
 
217
  if (pid == 0)
218
    return;
219
 
220
  /* This once used to call "kill" to kill the inferior just in case
221
     the inferior was still running.  As others have noted in the past
222
     (kingdon) there shouldn't be any way to get here if the inferior
223
     is still running -- else there's a major problem elsewere in gdb
224
     and it needs to be fixed.
225
 
226
     The kill call causes problems under hpux10, so it's been removed;
227
     if this causes problems we'll deal with them as they arise.  */
228
  ptrace (PT_KILL, pid, (PTRACE_ARG3_TYPE) 0, 0);
229
  ptrace_wait (null_ptid, &status);
230
  target_mourn_inferior ();
231
}
232
 
233
#ifndef CHILD_RESUME
234
 
235
/* Resume execution of the inferior process.
236
   If STEP is nonzero, single-step it.
237
   If SIGNAL is nonzero, give it that signal.  */
238
 
239
void
240
child_resume (ptid_t ptid, int step, enum target_signal signal)
241
{
242
  int pid = PIDGET (ptid);
243
 
244
  errno = 0;
245
 
246
  if (pid == -1)
247
    /* Resume all threads.  */
248
    /* I think this only gets used in the non-threaded case, where "resume
249
       all threads" and "resume inferior_ptid" are the same.  */
250
    pid = PIDGET (inferior_ptid);
251
 
252
  /* An address of (PTRACE_ARG3_TYPE)1 tells ptrace to continue from where
253
     it was.  (If GDB wanted it to start some other way, we have already
254
     written a new PC value to the child.)
255
 
256
     If this system does not support PT_STEP, a higher level function will
257
     have called single_step() to transmute the step request into a
258
     continue request (by setting breakpoints on all possible successor
259
     instructions), so we don't have to worry about that here.  */
260
 
261
  if (step)
262
    {
263
      if (SOFTWARE_SINGLE_STEP_P ())
264
        internal_error (__FILE__, __LINE__, "failed internal consistency check");               /* Make sure this doesn't happen. */
265
      else
266
        ptrace (PT_STEP, pid, (PTRACE_ARG3_TYPE) 1,
267
                target_signal_to_host (signal));
268
    }
269
  else
270
    ptrace (PT_CONTINUE, pid, (PTRACE_ARG3_TYPE) 1,
271
            target_signal_to_host (signal));
272
 
273
  if (errno)
274
    {
275
      perror_with_name ("ptrace");
276
    }
277
}
278
#endif /* CHILD_RESUME */
279
 
280
 
281
#ifdef ATTACH_DETACH
282
/* Start debugging the process whose number is PID.  */
283
int
284
attach (int pid)
285
{
286
  errno = 0;
287
  ptrace (PT_ATTACH, pid, (PTRACE_ARG3_TYPE) 0, 0);
288
  if (errno)
289
    perror_with_name ("ptrace");
290
  attach_flag = 1;
291
  return pid;
292
}
293
 
294
/* Stop debugging the process whose number is PID
295
   and continue it with signal number SIGNAL.
296
   SIGNAL = 0 means just continue it.  */
297
 
298
void
299
detach (int signal)
300
{
301
  errno = 0;
302
  ptrace (PT_DETACH, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) 1,
303
          signal);
304
  if (errno)
305
    perror_with_name ("ptrace");
306
  attach_flag = 0;
307
}
308
#endif /* ATTACH_DETACH */
309
 
310
/* Default the type of the ptrace transfer to int.  */
311
#ifndef PTRACE_XFER_TYPE
312
#define PTRACE_XFER_TYPE int
313
#endif
314
 
315
/* KERNEL_U_ADDR is the amount to subtract from u.u_ar0
316
   to get the offset in the core file of the register values.  */
317
#if defined (KERNEL_U_ADDR_BSD) && !defined (FETCH_INFERIOR_REGISTERS)
318
/* Get kernel_u_addr using BSD-style nlist().  */
319
CORE_ADDR kernel_u_addr;
320
#endif /* KERNEL_U_ADDR_BSD.  */
321
 
322
void
323
_initialize_kernel_u_addr (void)
324
{
325
#if defined (KERNEL_U_ADDR_BSD) && !defined (FETCH_INFERIOR_REGISTERS)
326
  struct nlist names[2];
327
 
328
  names[0].n_un.n_name = "_u";
329
  names[1].n_un.n_name = NULL;
330
  if (nlist ("/vmunix", names) == 0)
331
    kernel_u_addr = names[0].n_value;
332
  else
333
    internal_error (__FILE__, __LINE__,
334
                    "Unable to get kernel u area address.");
335
#endif /* KERNEL_U_ADDR_BSD.  */
336
}
337
 
338
#if !defined (FETCH_INFERIOR_REGISTERS)
339
 
340
#if !defined (offsetof)
341
#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
342
#endif
343
 
344
/* U_REGS_OFFSET is the offset of the registers within the u area.  */
345
#if !defined (U_REGS_OFFSET)
346
#define U_REGS_OFFSET \
347
  ptrace (PT_READ_U, PIDGET (inferior_ptid), \
348
          (PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \
349
    - KERNEL_U_ADDR
350
#endif
351
 
352
/* Fetch one register.  */
353
 
354
static void
355
fetch_register (int regno)
356
{
357
  /* This isn't really an address.  But ptrace thinks of it as one.  */
358
  CORE_ADDR regaddr;
359
  char mess[128];               /* For messages */
360
  register int i;
361
  unsigned int offset;          /* Offset of registers within the u area.  */
362
  char buf[MAX_REGISTER_RAW_SIZE];
363
  int tid;
364
 
365
  if (CANNOT_FETCH_REGISTER (regno))
366
    {
367
      memset (buf, '\0', REGISTER_RAW_SIZE (regno));    /* Supply zeroes */
368
      supply_register (regno, buf);
369
      return;
370
    }
371
 
372
  /* Overload thread id onto process id */
373
  if ((tid = TIDGET (inferior_ptid)) == 0)
374
    tid = PIDGET (inferior_ptid);       /* no thread id, just use process id */
375
 
376
  offset = U_REGS_OFFSET;
377
 
378
  regaddr = register_addr (regno, offset);
379
  for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
380
    {
381
      errno = 0;
382
      *(PTRACE_XFER_TYPE *) & buf[i] = ptrace (PT_READ_U, tid,
383
                                               (PTRACE_ARG3_TYPE) regaddr, 0);
384
      regaddr += sizeof (PTRACE_XFER_TYPE);
385
      if (errno != 0)
386
        {
387
          sprintf (mess, "reading register %s (#%d)",
388
                   REGISTER_NAME (regno), regno);
389
          perror_with_name (mess);
390
        }
391
    }
392
  supply_register (regno, buf);
393
}
394
 
395
 
396
/* Fetch register values from the inferior.
397
   If REGNO is negative, do this for all registers.
398
   Otherwise, REGNO specifies which register (so we can save time). */
399
 
400
void
401
fetch_inferior_registers (int regno)
402
{
403
  if (regno >= 0)
404
    {
405
      fetch_register (regno);
406
    }
407
  else
408
    {
409
      for (regno = 0; regno < NUM_REGS; regno++)
410
        {
411
          fetch_register (regno);
412
        }
413
    }
414
}
415
 
416
/* Store one register. */
417
 
418
static void
419
store_register (int regno)
420
{
421
  /* This isn't really an address.  But ptrace thinks of it as one.  */
422
  CORE_ADDR regaddr;
423
  char mess[128];               /* For messages */
424
  register int i;
425
  unsigned int offset;          /* Offset of registers within the u area.  */
426
  int tid;
427
 
428
  if (CANNOT_STORE_REGISTER (regno))
429
    {
430
      return;
431
    }
432
 
433
  /* Overload thread id onto process id */
434
  if ((tid = TIDGET (inferior_ptid)) == 0)
435
    tid = PIDGET (inferior_ptid);       /* no thread id, just use process id */
436
 
437
  offset = U_REGS_OFFSET;
438
 
439
  regaddr = register_addr (regno, offset);
440
  for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
441
    {
442
      errno = 0;
443
      ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr,
444
              *(PTRACE_XFER_TYPE *) & registers[REGISTER_BYTE (regno) + i]);
445
      regaddr += sizeof (PTRACE_XFER_TYPE);
446
      if (errno != 0)
447
        {
448
          sprintf (mess, "writing register %s (#%d)",
449
                   REGISTER_NAME (regno), regno);
450
          perror_with_name (mess);
451
        }
452
    }
453
}
454
 
455
/* Store our register values back into the inferior.
456
   If REGNO is negative, do this for all registers.
457
   Otherwise, REGNO specifies which register (so we can save time).  */
458
 
459
void
460
store_inferior_registers (int regno)
461
{
462
  if (regno >= 0)
463
    {
464
      store_register (regno);
465
    }
466
  else
467
    {
468
      for (regno = 0; regno < NUM_REGS; regno++)
469
        {
470
          store_register (regno);
471
        }
472
    }
473
}
474
#endif /* !defined (FETCH_INFERIOR_REGISTERS).  */
475
 
476
 
477
#if !defined (CHILD_XFER_MEMORY)
478
/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
479
   in the NEW_SUN_PTRACE case.
480
   It ought to be straightforward.  But it appears that writing did
481
   not write the data that I specified.  I cannot understand where
482
   it got the data that it actually did write.  */
483
 
484
/* Copy LEN bytes to or from inferior's memory starting at MEMADDR
485
   to debugger memory starting at MYADDR.   Copy to inferior if
486
   WRITE is nonzero.  TARGET is ignored.
487
 
488
   Returns the length copied, which is either the LEN argument or zero.
489
   This xfer function does not do partial moves, since child_ops
490
   doesn't allow memory operations to cross below us in the target stack
491
   anyway.  */
492
 
493
int
494
child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
495
                   struct mem_attrib *attrib ATTRIBUTE_UNUSED,
496
                   struct target_ops *target)
497
{
498
  register int i;
499
  /* Round starting address down to longword boundary.  */
500
  register CORE_ADDR addr = memaddr & -sizeof (PTRACE_XFER_TYPE);
501
  /* Round ending address up; get number of longwords that makes.  */
502
  register int count
503
  = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
504
  / sizeof (PTRACE_XFER_TYPE);
505
  /* Allocate buffer of that many longwords.  */
506
  register PTRACE_XFER_TYPE *buffer
507
  = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE));
508
 
509
  if (write)
510
    {
511
      /* Fill start and end extra bytes of buffer with existing memory data.  */
512
 
513
      if (addr != memaddr || len < (int) sizeof (PTRACE_XFER_TYPE))
514
        {
515
          /* Need part of initial word -- fetch it.  */
516
          buffer[0] = ptrace (PT_READ_I, PIDGET (inferior_ptid),
517
                              (PTRACE_ARG3_TYPE) addr, 0);
518
        }
519
 
520
      if (count > 1)            /* FIXME, avoid if even boundary */
521
        {
522
          buffer[count - 1]
523
            = ptrace (PT_READ_I, PIDGET (inferior_ptid),
524
                      ((PTRACE_ARG3_TYPE)
525
                       (addr + (count - 1) * sizeof (PTRACE_XFER_TYPE))),
526
                      0);
527
        }
528
 
529
      /* Copy data to be written over corresponding part of buffer */
530
 
531
      memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
532
              myaddr,
533
              len);
534
 
535
      /* Write the entire buffer.  */
536
 
537
      for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
538
        {
539
          errno = 0;
540
          ptrace (PT_WRITE_D, PIDGET (inferior_ptid),
541
                  (PTRACE_ARG3_TYPE) addr, buffer[i]);
542
          if (errno)
543
            {
544
              /* Using the appropriate one (I or D) is necessary for
545
                 Gould NP1, at least.  */
546
              errno = 0;
547
              ptrace (PT_WRITE_I, PIDGET (inferior_ptid),
548
                      (PTRACE_ARG3_TYPE) addr, buffer[i]);
549
            }
550
          if (errno)
551
            return 0;
552
        }
553
#ifdef CLEAR_INSN_CACHE
554
      CLEAR_INSN_CACHE ();
555
#endif
556
    }
557
  else
558
    {
559
      /* Read all the longwords */
560
      for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
561
        {
562
          errno = 0;
563
          buffer[i] = ptrace (PT_READ_I, PIDGET (inferior_ptid),
564
                              (PTRACE_ARG3_TYPE) addr, 0);
565
          if (errno)
566
            return 0;
567
          QUIT;
568
        }
569
 
570
      /* Copy appropriate bytes out of the buffer.  */
571
      memcpy (myaddr,
572
              (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
573
              len);
574
    }
575
  return len;
576
}
577
 
578
 
579
static void
580
udot_info (char *dummy1, int dummy2)
581
{
582
#if defined (KERNEL_U_SIZE)
583
  int udot_off;                 /* Offset into user struct */
584
  int udot_val;                 /* Value from user struct at udot_off */
585
  char mess[128];               /* For messages */
586
#endif
587
 
588
  if (!target_has_execution)
589
    {
590
      error ("The program is not being run.");
591
    }
592
 
593
#if !defined (KERNEL_U_SIZE)
594
 
595
  /* Adding support for this command is easy.  Typically you just add a
596
     routine, called "kernel_u_size" that returns the size of the user
597
     struct, to the appropriate *-nat.c file and then add to the native
598
     config file "#define KERNEL_U_SIZE kernel_u_size()" */
599
  error ("Don't know how large ``struct user'' is in this version of gdb.");
600
 
601
#else
602
 
603
  for (udot_off = 0; udot_off < KERNEL_U_SIZE; udot_off += sizeof (udot_val))
604
    {
605
      if ((udot_off % 24) == 0)
606
        {
607
          if (udot_off > 0)
608
            {
609
              printf_filtered ("\n");
610
            }
611
          printf_filtered ("%04x:", udot_off);
612
        }
613
      udot_val = ptrace (PT_READ_U, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) udot_off, 0);
614
      if (errno != 0)
615
        {
616
          sprintf (mess, "\nreading user struct at offset 0x%x", udot_off);
617
          perror_with_name (mess);
618
        }
619
      /* Avoid using nonportable (?) "*" in print specs */
620
      printf_filtered (sizeof (int) == 4 ? " 0x%08x" : " 0x%16x", udot_val);
621
    }
622
  printf_filtered ("\n");
623
 
624
#endif
625
}
626
#endif /* !defined (CHILD_XFER_MEMORY).  */
627
 
628
 
629
void
630
_initialize_infptrace (void)
631
{
632
#if !defined (CHILD_XFER_MEMORY)
633
  add_info ("udot", udot_info,
634
            "Print contents of kernel ``struct user'' for current child.");
635
#endif
636
}

powered by: WebSVN 2.1.0

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