1 /* 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, 2004
4 Free Software Foundation, Inc.
6 This file is part of GDB.
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.
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.
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. */
31 #include "gdb_assert.h"
33 #include "gdb_string.h"
35 #include <sys/param.h>
36 #include "gdb_dirent.h"
38 #include <sys/ioctl.h>
40 #include "gdb_ptrace.h"
42 #ifdef HAVE_SYS_FILE_H
46 #if !defined (FETCH_INFERIOR_REGISTERS)
47 #include <sys/user.h> /* Probably need to poke the user structure */
48 #endif /* !FETCH_INFERIOR_REGISTERS */
50 #if !defined (CHILD_XFER_MEMORY)
51 static void udot_info (char *, int);
54 void _initialize_infptrace (void);
57 /* This function simply calls ptrace with the given arguments.
58 It exists so that all calls to ptrace are isolated in this
59 machine-dependent file. */
61 call_ptrace (int request
, int pid
, PTRACE_ARG3_TYPE addr
, int data
)
68 printf ("call_ptrace(request=%d, pid=%d, addr=0x%x, data=0x%x)",
69 request
, pid
, addr
, data
);
71 #if defined(PT_SETTRC)
72 /* If the parent can be told to attach to us, try to do it. */
73 if (request
== PT_SETTRC
)
76 #ifndef PTRACE_TYPE_ARG5
77 pt_status
= ptrace (PT_SETTRC
, pid
, addr
, data
);
79 /* Deal with HPUX 8.0 braindamage. We never use the
80 calls which require the fifth argument. */
81 pt_status
= ptrace (PT_SETTRC
, pid
, addr
, data
, 0);
84 perror_with_name ("ptrace");
86 printf (" = %d\n", pt_status
);
91 return parent_attach_all (pid
, addr
, data
);
95 #if defined(PT_CONTIN1)
96 /* On HPUX, PT_CONTIN1 is a form of continue that preserves pending
97 signals. If it's available, use it. */
98 if (request
== PT_CONTINUE
)
102 #if defined(PT_SINGLE1)
103 /* On HPUX, PT_SINGLE1 is a form of step that preserves pending
104 signals. If it's available, use it. */
105 if (request
== PT_STEP
)
106 request
= PT_SINGLE1
;
113 #ifndef PTRACE_TYPE_ARG5
114 pt_status
= ptrace (request
, pid
, addr
, data
);
116 /* Deal with HPUX 8.0 braindamage. We never use the
117 calls which require the fifth argument. */
118 pt_status
= ptrace (request
, pid
, addr
, data
, 0);
123 printf (" [errno = %d]", errno
);
126 printf (" = 0x%x\n", pt_status
);
132 #if defined (DEBUG_PTRACE) || defined (PTRACE_TYPE_ARG5)
133 /* For the rest of the file, use an extra level of indirection */
134 /* This lets us breakpoint usefully on call_ptrace. */
135 #define ptrace call_ptrace
138 /* Wait for a process to finish, possibly running a target-specific
139 hook before returning. */
142 ptrace_wait (ptid_t ptid
, int *status
)
146 wstate
= wait (status
);
147 target_post_wait (pid_to_ptid (wstate
), *status
);
151 #ifndef DEPRECATED_KILL_INFERIOR
152 /* NOTE: cagney/2004-09-12: Instead of definining this macro, code
153 should call inf_ptrace_target to get a basic ptrace target and then
154 locally update any necessary methods. See ppcnbsd-nat.c. */
160 int pid
= PIDGET (inferior_ptid
);
165 /* This once used to call "kill" to kill the inferior just in case
166 the inferior was still running. As others have noted in the past
167 (kingdon) there shouldn't be any way to get here if the inferior
168 is still running -- else there's a major problem elsewere in gdb
169 and it needs to be fixed.
171 The kill call causes problems under hpux10, so it's been removed;
172 if this causes problems we'll deal with them as they arise. */
173 ptrace (PT_KILL
, pid
, (PTRACE_TYPE_ARG3
) 0, 0);
174 ptrace_wait (null_ptid
, &status
);
175 target_mourn_inferior ();
177 #endif /* DEPRECATED_KILL_INFERIOR */
179 #ifndef DEPRECATED_CHILD_RESUME
180 /* NOTE: cagney/2004-09-12: Instead of definining this macro, code
181 should call inf_ptrace_target to get a basic ptrace target and then
182 locally update any necessary methods. See ppcnbsd-nat.c. */
184 /* Resume execution of the inferior process.
185 If STEP is nonzero, single-step it.
186 If SIGNAL is nonzero, give it that signal. */
189 child_resume (ptid_t ptid
, int step
, enum target_signal signal
)
191 int request
= PT_CONTINUE
;
192 int pid
= PIDGET (ptid
);
195 /* Resume all threads. */
196 /* I think this only gets used in the non-threaded case, where "resume
197 all threads" and "resume inferior_ptid" are the same. */
198 pid
= PIDGET (inferior_ptid
);
202 /* If this system does not support PT_STEP, a higher level
203 function will have called single_step() to transmute the step
204 request into a continue request (by setting breakpoints on
205 all possible successor instructions), so we don't have to
206 worry about that here. */
208 gdb_assert (!SOFTWARE_SINGLE_STEP_P ());
212 /* An address of (PTRACE_TYPE_ARG3)1 tells ptrace to continue from
213 where it was. If GDB wanted it to start some other way, we have
214 already written a new PC value to the child. */
217 ptrace (request
, pid
, (PTRACE_TYPE_ARG3
)1, target_signal_to_host (signal
));
219 perror_with_name ("ptrace");
221 #endif /* DEPRECATED_CHILD_RESUME */
224 /* Start debugging the process whose number is PID. */
231 ptrace (PT_ATTACH
, pid
, (PTRACE_TYPE_ARG3
) 0, 0);
233 perror_with_name ("ptrace");
237 error ("This system does not support attaching to a process");
241 /* Stop debugging the process whose number is PID and continue it with
242 signal number SIGNAL. SIGNAL = 0 means just continue it. */
248 int pid
= PIDGET (inferior_ptid
);
251 ptrace (PT_DETACH
, pid
, (PTRACE_TYPE_ARG3
) 1, signal
);
253 perror_with_name ("ptrace");
256 error ("This system does not support detaching from a process");
261 #ifndef FETCH_INFERIOR_REGISTERS
263 /* U_REGS_OFFSET is the offset of the registers within the u area. */
264 #ifndef U_REGS_OFFSET
267 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
270 #define U_REGS_OFFSET \
271 ptrace (PT_READ_U, PIDGET (inferior_ptid), \
272 (PTRACE_TYPE_ARG3) (offsetof (struct user, u_ar0)), 0) \
276 /* Fetch register REGNUM from the inferior. */
279 fetch_register (int regnum
)
283 PTRACE_TYPE_RET
*buf
;
286 if (CANNOT_FETCH_REGISTER (regnum
))
288 regcache_raw_supply (current_regcache
, regnum
, NULL
);
292 /* GNU/Linux LWP ID's are process ID's. */
293 tid
= TIDGET (inferior_ptid
);
295 tid
= PIDGET (inferior_ptid
); /* Not a threaded program. */
297 /* This isn't really an address. But ptrace thinks of it as one. */
298 addr
= register_addr (regnum
, U_REGS_OFFSET
);
299 size
= register_size (current_gdbarch
, regnum
);
301 gdb_assert ((size
% sizeof (PTRACE_TYPE_RET
)) == 0);
304 /* Read the register contents from the inferior a chuck at the time. */
305 for (i
= 0; i
< size
/ sizeof (PTRACE_TYPE_RET
); i
++)
308 buf
[i
] = ptrace (PT_READ_U
, tid
, (PTRACE_TYPE_ARG3
) addr
, 0);
310 error ("Couldn't read register %s (#%d): %s.", REGISTER_NAME (regnum
),
311 regnum
, safe_strerror (errno
));
313 addr
+= sizeof (PTRACE_TYPE_RET
);
315 regcache_raw_supply (current_regcache
, regnum
, buf
);
318 /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
319 for all registers. */
322 fetch_inferior_registers (int regnum
)
325 for (regnum
= 0; regnum
< NUM_REGS
; regnum
++)
326 fetch_register (regnum
);
328 fetch_register (regnum
);
331 /* Store register REGNUM into the inferior. */
334 store_register (int regnum
)
338 PTRACE_TYPE_RET
*buf
;
341 if (CANNOT_STORE_REGISTER (regnum
))
344 /* GNU/Linux LWP ID's are process ID's. */
345 tid
= TIDGET (inferior_ptid
);
347 tid
= PIDGET (inferior_ptid
); /* Not a threaded program. */
349 /* This isn't really an address. But ptrace thinks of it as one. */
350 addr
= register_addr (regnum
, U_REGS_OFFSET
);
351 size
= register_size (current_gdbarch
, regnum
);
353 gdb_assert ((size
% sizeof (PTRACE_TYPE_RET
)) == 0);
356 /* Write the register contents into the inferior a chunk at the time. */
357 regcache_raw_collect (current_regcache
, regnum
, buf
);
358 for (i
= 0; i
< size
/ sizeof (PTRACE_TYPE_RET
); i
++)
361 ptrace (PT_WRITE_U
, tid
, (PTRACE_TYPE_ARG3
) addr
, buf
[i
]);
363 error ("Couldn't write register %s (#%d): %s.", REGISTER_NAME (regnum
),
364 regnum
, safe_strerror (errno
));
366 addr
+= sizeof (PTRACE_TYPE_RET
);
370 /* Store register REGNUM back into the inferior. If REGNUM is -1, do
371 this for all registers (including the floating point registers). */
374 store_inferior_registers (int regnum
)
377 for (regnum
= 0; regnum
< NUM_REGS
; regnum
++)
378 store_register (regnum
);
380 store_register (regnum
);
383 #endif /* not FETCH_INFERIOR_REGISTERS. */
386 /* Set an upper limit on alloca. */
387 #ifndef GDB_MAX_ALLOCA
388 #define GDB_MAX_ALLOCA 0x1000
391 #if !defined (CHILD_XFER_MEMORY)
392 /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
393 in the NEW_SUN_PTRACE case. It ought to be straightforward. But
394 it appears that writing did not write the data that I specified. I
395 cannot understand where it got the data that it actually did write. */
397 /* Copy LEN bytes to or from inferior's memory starting at MEMADDR to
398 debugger memory starting at MYADDR. Copy to inferior if WRITE is
399 nonzero. TARGET is ignored.
401 Returns the length copied, which is either the LEN argument or
402 zero. This xfer function does not do partial moves, since
403 child_ops doesn't allow memory operations to cross below us in the
404 target stack anyway. */
407 child_xfer_memory (CORE_ADDR memaddr
, char *myaddr
, int len
, int write
,
408 struct mem_attrib
*attrib
, struct target_ops
*target
)
411 /* Round starting address down to longword boundary. */
412 CORE_ADDR addr
= memaddr
& -(CORE_ADDR
) sizeof (PTRACE_TYPE_RET
);
413 /* Round ending address up; get number of longwords that makes. */
414 int count
= ((((memaddr
+ len
) - addr
) + sizeof (PTRACE_TYPE_RET
) - 1)
415 / sizeof (PTRACE_TYPE_RET
));
416 int alloc
= count
* sizeof (PTRACE_TYPE_RET
);
417 PTRACE_TYPE_RET
*buffer
;
418 struct cleanup
*old_chain
= NULL
;
421 /* OpenBSD 3.1, NetBSD 1.6 and FreeBSD 5.0 have a new PT_IO request
422 that promises to be much more efficient in reading and writing
423 data in the traced process's address space. */
426 struct ptrace_io_desc piod
;
428 /* NOTE: We assume that there are no distinct address spaces for
429 instruction and data. */
430 piod
.piod_op
= write
? PIOD_WRITE_D
: PIOD_READ_D
;
431 piod
.piod_offs
= (void *) memaddr
;
432 piod
.piod_addr
= myaddr
;
435 if (ptrace (PT_IO
, PIDGET (inferior_ptid
), (caddr_t
) &piod
, 0) == -1)
437 /* If the PT_IO request is somehow not supported, fallback on
438 using PT_WRITE_D/PT_READ_D. Otherwise we will return zero
439 to indicate failure. */
445 /* Return the actual number of bytes read or written. */
446 return piod
.piod_len
;
451 /* Allocate buffer of that many longwords. */
452 if (len
< GDB_MAX_ALLOCA
)
454 buffer
= (PTRACE_TYPE_RET
*) alloca (alloc
);
458 buffer
= (PTRACE_TYPE_RET
*) xmalloc (alloc
);
459 old_chain
= make_cleanup (xfree
, buffer
);
464 /* Fill start and end extra bytes of buffer with existing memory
466 if (addr
!= memaddr
|| len
< (int) sizeof (PTRACE_TYPE_RET
))
468 /* Need part of initial word -- fetch it. */
469 buffer
[0] = ptrace (PT_READ_I
, PIDGET (inferior_ptid
),
470 (PTRACE_TYPE_ARG3
) addr
, 0);
473 if (count
> 1) /* FIXME, avoid if even boundary. */
476 ptrace (PT_READ_I
, PIDGET (inferior_ptid
),
478 (addr
+ (count
- 1) * sizeof (PTRACE_TYPE_RET
))), 0);
481 /* Copy data to be written over corresponding part of buffer. */
482 memcpy ((char *) buffer
+ (memaddr
& (sizeof (PTRACE_TYPE_RET
) - 1)),
485 /* Write the entire buffer. */
486 for (i
= 0; i
< count
; i
++, addr
+= sizeof (PTRACE_TYPE_RET
))
489 ptrace (PT_WRITE_D
, PIDGET (inferior_ptid
),
490 (PTRACE_TYPE_ARG3
) addr
, buffer
[i
]);
493 /* Using the appropriate one (I or D) is necessary for
494 Gould NP1, at least. */
496 ptrace (PT_WRITE_I
, PIDGET (inferior_ptid
),
497 (PTRACE_TYPE_ARG3
) addr
, buffer
[i
]);
505 /* Read all the longwords. */
506 for (i
= 0; i
< count
; i
++, addr
+= sizeof (PTRACE_TYPE_RET
))
509 buffer
[i
] = ptrace (PT_READ_I
, PIDGET (inferior_ptid
),
510 (PTRACE_TYPE_ARG3
) addr
, 0);
516 /* Copy appropriate bytes out of the buffer. */
518 (char *) buffer
+ (memaddr
& (sizeof (PTRACE_TYPE_RET
) - 1)),
522 if (old_chain
!= NULL
)
523 do_cleanups (old_chain
);
529 udot_info (char *dummy1
, int dummy2
)
531 #if defined (KERNEL_U_SIZE)
532 long udot_off
; /* Offset into user struct */
533 int udot_val
; /* Value from user struct at udot_off */
534 char mess
[128]; /* For messages */
537 if (!target_has_execution
)
539 error ("The program is not being run.");
542 #if !defined (KERNEL_U_SIZE)
544 /* Adding support for this command is easy. Typically you just add a
545 routine, called "kernel_u_size" that returns the size of the user
546 struct, to the appropriate *-nat.c file and then add to the native
547 config file "#define KERNEL_U_SIZE kernel_u_size()" */
548 error ("Don't know how large ``struct user'' is in this version of gdb.");
552 for (udot_off
= 0; udot_off
< KERNEL_U_SIZE
; udot_off
+= sizeof (udot_val
))
554 if ((udot_off
% 24) == 0)
558 printf_filtered ("\n");
560 printf_filtered ("%s:", paddr (udot_off
));
562 udot_val
= ptrace (PT_READ_U
, PIDGET (inferior_ptid
), (PTRACE_TYPE_ARG3
) udot_off
, 0);
565 sprintf (mess
, "\nreading user struct at offset 0x%s",
566 paddr_nz (udot_off
));
567 perror_with_name (mess
);
569 /* Avoid using nonportable (?) "*" in print specs */
570 printf_filtered (sizeof (int) == 4 ? " 0x%08x" : " 0x%16x", udot_val
);
572 printf_filtered ("\n");
576 #endif /* !defined (CHILD_XFER_MEMORY). */
580 _initialize_infptrace (void)
582 #if !defined (CHILD_XFER_MEMORY)
583 add_info ("udot", udot_info
,
584 "Print contents of kernel ``struct user'' for current child.");
This page took 0.040622 seconds and 4 git commands to generate.