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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* Low level Unix child interface to ptrace, for GDB when running under Unix.
2
   Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
3
   1998, 1999, 2000, 2001, 2002
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 = alloca (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
  char *buf = alloca (MAX_REGISTER_RAW_SIZE);
428
 
429
  if (CANNOT_STORE_REGISTER (regno))
430
    {
431
      return;
432
    }
433
 
434
  /* Overload thread id onto process id */
435
  if ((tid = TIDGET (inferior_ptid)) == 0)
436
    tid = PIDGET (inferior_ptid);       /* no thread id, just use process id */
437
 
438
  offset = U_REGS_OFFSET;
439
 
440
  regaddr = register_addr (regno, offset);
441
 
442
  /* Put the contents of regno into a local buffer */
443
  regcache_collect (regno, buf);
444
 
445
  /* Store the local buffer into the inferior a chunk at the time. */
446
  for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
447
    {
448
      errno = 0;
449
      ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr,
450
              *(PTRACE_XFER_TYPE *) (buf + i));
451
      regaddr += sizeof (PTRACE_XFER_TYPE);
452
      if (errno != 0)
453
        {
454
          sprintf (mess, "writing register %s (#%d)",
455
                   REGISTER_NAME (regno), regno);
456
          perror_with_name (mess);
457
        }
458
    }
459
}
460
 
461
/* Store our register values back into the inferior.
462
   If REGNO is negative, do this for all registers.
463
   Otherwise, REGNO specifies which register (so we can save time).  */
464
 
465
void
466
store_inferior_registers (int regno)
467
{
468
  if (regno >= 0)
469
    {
470
      store_register (regno);
471
    }
472
  else
473
    {
474
      for (regno = 0; regno < NUM_REGS; regno++)
475
        {
476
          store_register (regno);
477
        }
478
    }
479
}
480
#endif /* !defined (FETCH_INFERIOR_REGISTERS).  */
481
 
482
 
483
/* Set an upper limit on alloca.  */
484
#ifndef GDB_MAX_ALLOCA
485
#define GDB_MAX_ALLOCA 0x1000
486
#endif
487
 
488
#if !defined (CHILD_XFER_MEMORY)
489
/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
490
   in the NEW_SUN_PTRACE case.  It ought to be straightforward.  But
491
   it appears that writing did not write the data that I specified.  I
492
   cannot understand where it got the data that it actually did write.  */
493
 
494
/* Copy LEN bytes to or from inferior's memory starting at MEMADDR to
495
   debugger memory starting at MYADDR.  Copy to inferior if WRITE is
496
   nonzero.  TARGET is ignored.
497
 
498
   Returns the length copied, which is either the LEN argument or
499
   zero.  This xfer function does not do partial moves, since
500
   child_ops doesn't allow memory operations to cross below us in the
501
   target stack anyway.  */
502
 
503
int
504
child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
505
                   struct mem_attrib *attrib, struct target_ops *target)
506
{
507
  int i;
508
  /* Round starting address down to longword boundary.  */
509
  CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE);
510
  /* Round ending address up; get number of longwords that makes.  */
511
  int count = ((((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1)
512
               / sizeof (PTRACE_XFER_TYPE));
513
  int alloc = count * sizeof (PTRACE_XFER_TYPE);
514
  PTRACE_XFER_TYPE *buffer;
515
  struct cleanup *old_chain = NULL;
516
 
517
  /* Allocate buffer of that many longwords.  */
518
  if (len < GDB_MAX_ALLOCA)
519
    {
520
      buffer = (PTRACE_XFER_TYPE *) alloca (alloc);
521
    }
522
  else
523
    {
524
      buffer = (PTRACE_XFER_TYPE *) xmalloc (alloc);
525
      old_chain = make_cleanup (xfree, buffer);
526
    }
527
 
528
  if (write)
529
    {
530
      /* Fill start and end extra bytes of buffer with existing memory
531
         data.  */
532
      if (addr != memaddr || len < (int) sizeof (PTRACE_XFER_TYPE))
533
        {
534
          /* Need part of initial word -- fetch it.  */
535
          buffer[0] = ptrace (PT_READ_I, PIDGET (inferior_ptid),
536
                              (PTRACE_ARG3_TYPE) addr, 0);
537
        }
538
 
539
      if (count > 1)            /* FIXME, avoid if even boundary.  */
540
        {
541
          buffer[count - 1] =
542
            ptrace (PT_READ_I, PIDGET (inferior_ptid),
543
                    ((PTRACE_ARG3_TYPE)
544
                     (addr + (count - 1) * sizeof (PTRACE_XFER_TYPE))), 0);
545
        }
546
 
547
      /* Copy data to be written over corresponding part of buffer.  */
548
      memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
549
              myaddr, len);
550
 
551
      /* Write the entire buffer.  */
552
      for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
553
        {
554
          errno = 0;
555
          ptrace (PT_WRITE_D, PIDGET (inferior_ptid),
556
                  (PTRACE_ARG3_TYPE) addr, buffer[i]);
557
          if (errno)
558
            {
559
              /* Using the appropriate one (I or D) is necessary for
560
                 Gould NP1, at least.  */
561
              errno = 0;
562
              ptrace (PT_WRITE_I, PIDGET (inferior_ptid),
563
                      (PTRACE_ARG3_TYPE) addr, buffer[i]);
564
            }
565
          if (errno)
566
            return 0;
567
        }
568
#ifdef CLEAR_INSN_CACHE
569
      CLEAR_INSN_CACHE ();
570
#endif
571
    }
572
  else
573
    {
574
      /* Read all the longwords.  */
575
      for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
576
        {
577
          errno = 0;
578
          buffer[i] = ptrace (PT_READ_I, PIDGET (inferior_ptid),
579
                              (PTRACE_ARG3_TYPE) addr, 0);
580
          if (errno)
581
            return 0;
582
          QUIT;
583
        }
584
 
585
      /* Copy appropriate bytes out of the buffer.  */
586
      memcpy (myaddr,
587
              (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)),
588
              len);
589
    }
590
 
591
  if (old_chain != NULL)
592
    do_cleanups (old_chain);
593
  return len;
594
}
595
 
596
 
597
static void
598
udot_info (char *dummy1, int dummy2)
599
{
600
#if defined (KERNEL_U_SIZE)
601
  int udot_off;                 /* Offset into user struct */
602
  int udot_val;                 /* Value from user struct at udot_off */
603
  char mess[128];               /* For messages */
604
#endif
605
 
606
  if (!target_has_execution)
607
    {
608
      error ("The program is not being run.");
609
    }
610
 
611
#if !defined (KERNEL_U_SIZE)
612
 
613
  /* Adding support for this command is easy.  Typically you just add a
614
     routine, called "kernel_u_size" that returns the size of the user
615
     struct, to the appropriate *-nat.c file and then add to the native
616
     config file "#define KERNEL_U_SIZE kernel_u_size()" */
617
  error ("Don't know how large ``struct user'' is in this version of gdb.");
618
 
619
#else
620
 
621
  for (udot_off = 0; udot_off < KERNEL_U_SIZE; udot_off += sizeof (udot_val))
622
    {
623
      if ((udot_off % 24) == 0)
624
        {
625
          if (udot_off > 0)
626
            {
627
              printf_filtered ("\n");
628
            }
629
          printf_filtered ("%04x:", udot_off);
630
        }
631
      udot_val = ptrace (PT_READ_U, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) udot_off, 0);
632
      if (errno != 0)
633
        {
634
          sprintf (mess, "\nreading user struct at offset 0x%x", udot_off);
635
          perror_with_name (mess);
636
        }
637
      /* Avoid using nonportable (?) "*" in print specs */
638
      printf_filtered (sizeof (int) == 4 ? " 0x%08x" : " 0x%16x", udot_val);
639
    }
640
  printf_filtered ("\n");
641
 
642
#endif
643
}
644
#endif /* !defined (CHILD_XFER_MEMORY).  */
645
 
646
 
647
void
648
_initialize_infptrace (void)
649
{
650
#if !defined (CHILD_XFER_MEMORY)
651
  add_info ("udot", udot_info,
652
            "Print contents of kernel ``struct user'' for current child.");
653
#endif
654
}

powered by: WebSVN 2.1.0

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