1 /* Low level interface to ptrace, for GDB when running under Unix.
2 Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
4 This file is part of GDB.
6 GDB is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
11 GDB is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GDB; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
26 #include <sys/param.h>
29 #include <sys/ioctl.h>
33 #include <sys/ptrace.h>
34 #define PTRACE_ATTACH PT_ATTACH
35 #define PTRACE_DETACH PT_FREEPROC
41 extern int attach_flag
;
43 /* This function simply calls ptrace with the given arguments.
44 It exists so that all calls to ptrace are isolated in this
45 machine-dependent file. */
47 call_ptrace (request
, pid
, arg3
, arg4
)
48 int request
, pid
, arg3
, arg4
;
50 return ptrace (request
, pid
, arg3
, arg4
);
57 if (inferior_pid
== 0)
59 ptrace (8, inferior_pid
, 0, 0);
64 /* This is used when GDB is exiting. It gives less chance of error.*/
70 if (inferior_pid
== 0)
72 ptrace (8, inferior_pid
, 0, 0);
76 /* Resume execution of the inferior process.
77 If STEP is nonzero, single-step it.
78 If SIGNAL is nonzero, give it that signal. */
87 remote_resume (step
, signal
);
90 ptrace (step
? 9 : 7, inferior_pid
, 1, signal
);
92 perror_with_name ("ptrace");
98 /* Start debugging the process whose number is PID. */
104 ptrace (PTRACE_ATTACH
, pid
, 0, 0);
106 perror_with_name ("ptrace");
111 /* Stop debugging the process whose number is PID
112 and continue it with signal number SIGNAL.
113 SIGNAL = 0 means just continue it. */
120 ptrace (PTRACE_DETACH
, inferior_pid
, 1, signal
);
122 perror_with_name ("ptrace");
125 #endif /* ATTACH_DETACH */
128 fetch_inferior_registers ()
131 register unsigned int regaddr
;
132 char buf
[MAX_REGISTER_RAW_SIZE
];
135 unsigned int offset
= 0;
137 for (regno
= 0; regno
< NUM_REGS
; regno
++)
139 regaddr
= register_addr (regno
, offset
);
140 for (i
= 0; i
< REGISTER_RAW_SIZE (regno
); i
+= sizeof (int))
142 *(int *) &buf
[i
] = ptrace (3, inferior_pid
, regaddr
, 0);
143 regaddr
+= sizeof (int);
145 supply_register (regno
, buf
);
149 /* Store our register values back into the inferior.
150 If REGNO is -1, do this for all registers.
151 Otherwise, REGNO specifies which register (so we can save time). */
153 store_inferior_registers (regno
)
156 register unsigned int regaddr
;
159 unsigned int offset
= 0;
163 regaddr
= register_addr (regno
, offset
);
165 ptrace (6, inferior_pid
, regaddr
, read_register (regno
));
168 sprintf (buf
, "writing register number %d", regno
);
169 perror_with_name (buf
);
172 else for (regno
= 0; regno
< NUM_REGS
; regno
++)
174 regaddr
= register_addr (regno
, offset
);
176 ptrace (6, inferior_pid
, regaddr
, read_register (regno
));
179 sprintf (buf
, "writing register number %d", regno
);
180 perror_with_name (buf
);
185 /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
186 in the NEW_SUN_PTRACE case.
187 It ought to be straightforward. But it appears that writing did
188 not write the data that I specified. I cannot understand where
189 it got the data that it actually did write. */
191 /* Copy LEN bytes from inferior's memory starting at MEMADDR
192 to debugger memory starting at MYADDR.
193 On failure (cannot read from inferior, usually because address is out
194 of bounds) returns the value of errno. */
197 read_inferior_memory (memaddr
, myaddr
, len
)
203 /* Round starting address down to longword boundary. */
204 register CORE_ADDR addr
= memaddr
& - sizeof (int);
205 /* Round ending address up; get number of longwords that makes. */
207 = (((memaddr
+ len
) - addr
) + sizeof (int) - 1) / sizeof (int);
208 /* Allocate buffer of that many longwords. */
209 register int *buffer
= (int *) alloca (count
* sizeof (int));
212 /* Read all the longwords */
213 for (i
= 0; i
< count
; i
++, addr
+= sizeof (int))
216 if (remote_debugging
)
217 buffer
[i
] = remote_fetch_word (addr
);
219 buffer
[i
] = ptrace (1, inferior_pid
, addr
, 0);
224 /* Copy appropriate bytes out of the buffer. */
225 bcopy ((char *) buffer
+ (memaddr
& (sizeof (int) - 1)), myaddr
, len
);
229 /* Copy LEN bytes of data from debugger memory at MYADDR
230 to inferior's memory at MEMADDR.
231 On failure (cannot write the inferior)
232 returns the value of errno. */
235 write_inferior_memory (memaddr
, myaddr
, len
)
241 /* Round starting address down to longword boundary. */
242 register CORE_ADDR addr
= memaddr
& - sizeof (int);
243 /* Round ending address up; get number of longwords that makes. */
245 = (((memaddr
+ len
) - addr
) + sizeof (int) - 1) / sizeof (int);
246 /* Allocate buffer of that many longwords. */
247 register int *buffer
= (int *) alloca (count
* sizeof (int));
250 /* Fill start and end extra bytes of buffer with existing memory data. */
252 if (remote_debugging
)
253 buffer
[0] = remote_fetch_word (addr
);
255 buffer
[0] = ptrace (1, inferior_pid
, addr
, 0);
259 if (remote_debugging
)
261 = remote_fetch_word (addr
+ (count
- 1) * sizeof (int));
264 = ptrace (1, inferior_pid
,
265 addr
+ (count
- 1) * sizeof (int), 0);
268 /* Copy data to be written over corresponding part of buffer */
270 bcopy (myaddr
, (char *) buffer
+ (memaddr
& (sizeof (int) - 1)), len
);
272 /* Write the entire buffer. */
274 for (i
= 0; i
< count
; i
++, addr
+= sizeof (int))
277 if (remote_debugging
)
278 remote_store_word (addr
, buffer
[i
]);
280 ptrace (4, inferior_pid
, addr
, buffer
[i
]);
288 /* Work with core dump and executable files, for GDB.
289 This code would be in core.c if it weren't machine-dependent. */
291 /* Recognize COFF format systems because a.out.h defines AOUTHDR. */
297 #define N_TXTADDR(hdr) 0
298 #endif /* no N_TXTADDR */
301 #define N_DATADDR(hdr) hdr.a_text
302 #endif /* no N_DATADDR */
304 /* Make COFF and non-COFF names for things a little more compatible
305 to reduce conditionals later. */
308 #define a_magic magic
313 #define AOUTHDR struct exec
317 extern char *sys_siglist
[];
320 /* Hook for `exec_file_command' command to call. */
322 extern void (*exec_file_display_hook
) ();
324 /* File names of core file and executable file. */
326 extern char *corefile
;
327 extern char *execfile
;
329 /* Descriptors on which core file and executable file are open.
330 Note that the execchan is closed when an inferior is created
331 and reopened if the inferior dies or is killed. */
336 /* Last modification time of executable file.
337 Also used in source.c to compare against mtime of a source file. */
339 extern int exec_mtime
;
341 /* Virtual addresses of bounds of the two areas of memory in the core file. */
343 extern CORE_ADDR data_start
;
344 extern CORE_ADDR data_end
;
345 extern CORE_ADDR stack_start
;
346 extern CORE_ADDR stack_end
;
348 /* Virtual addresses of bounds of two areas of memory in the exec file.
349 Note that the data area in the exec file is used only when there is no core file. */
351 extern CORE_ADDR text_start
;
352 extern CORE_ADDR text_end
;
354 extern CORE_ADDR exec_data_start
;
355 extern CORE_ADDR exec_data_end
;
357 /* Address in executable file of start of text area data. */
359 extern int text_offset
;
361 /* Address in executable file of start of data area data. */
363 extern int exec_data_offset
;
365 /* Address in core file of start of data area data. */
367 extern int data_offset
;
369 /* Address in core file of start of stack area data. */
371 extern int stack_offset
;
374 /* various coff data structures */
376 extern FILHDR file_hdr
;
377 extern SCNHDR text_hdr
;
378 extern SCNHDR data_hdr
;
380 #endif /* not COFF_FORMAT */
382 /* a.out header saved in core file. */
384 extern AOUTHDR core_aouthdr
;
386 /* a.out header of exec file. */
388 extern AOUTHDR exec_aouthdr
;
390 extern void validate_files ();
392 core_file_command (filename
, from_tty
)
397 extern char registers
[];
399 /* Discard all vestiges of any previous core file
400 and mark data and stack spaces as empty. */
412 stack_start
= STACK_END_ADDR
;
413 stack_end
= STACK_END_ADDR
;
415 /* Now, if a new core file was specified, open it and digest it. */
419 filename
= tilde_expand (filename
);
420 make_cleanup (free
, filename
);
422 if (have_inferior_p ())
423 error ("To look at a core file, you must kill the inferior with \"kill\".");
424 corechan
= open (filename
, O_RDONLY
, 0);
426 perror_with_name (filename
);
427 /* 4.2-style (and perhaps also sysV-style) core dump file. */
429 struct ptrace_user u
;
432 val
= myread (corechan
, &u
, sizeof u
);
434 perror_with_name (filename
);
435 data_start
= exec_data_start
;
437 data_end
= data_start
+ u
.pt_dsize
;
438 stack_start
= stack_end
- u
.pt_ssize
;
439 data_offset
= sizeof u
;
440 stack_offset
= data_offset
+ u
.pt_dsize
;
443 bcopy (&u
.pt_aouthdr
, &core_aouthdr
, sizeof (AOUTHDR
));
444 printf ("Core file is from \"%s\".\n", u
.pt_comm
);
446 printf ("Program terminated with signal %d, %s.\n",
449 ? sys_siglist
[u
.pt_signal
]
452 /* Read the register values out of the core file and store
453 them where `read_register' will find them. */
458 for (regno
= 0; regno
< NUM_REGS
; regno
++)
460 char buf
[MAX_REGISTER_RAW_SIZE
];
462 val
= lseek (corechan
, register_addr (regno
, reg_offset
), 0);
464 perror_with_name (filename
);
466 val
= myread (corechan
, buf
, sizeof buf
);
468 perror_with_name (filename
);
469 supply_register (regno
, buf
);
473 if (filename
[0] == '/')
474 corefile
= savestring (filename
, strlen (filename
));
477 corefile
= concat (current_directory
, "/", filename
);
480 set_current_frame ( create_new_frame (read_register (FP_REGNUM
),
482 select_frame (get_current_frame (), 0);
486 printf ("No core file now.\n");
489 exec_file_command (filename
, from_tty
)
495 /* Eliminate all traces of old exec file.
496 Mark text segment as empty. */
502 data_end
-= exec_data_start
;
511 /* Now open and digest the file the user requested, if any. */
515 filename
= tilde_expand (filename
);
516 make_cleanup (free
, filename
);
518 execchan
= openp (getenv ("PATH"), 1, filename
, O_RDONLY
, 0,
521 perror_with_name (filename
);
528 if (read_file_hdr (execchan
, &file_hdr
) < 0)
529 error ("\"%s\": not in executable format.", execfile
);
531 aout_hdrsize
= file_hdr
.f_opthdr
;
532 num_sections
= file_hdr
.f_nscns
;
534 if (read_aout_hdr (execchan
, &exec_aouthdr
, aout_hdrsize
) < 0)
535 error ("\"%s\": can't read optional aouthdr", execfile
);
537 if (read_section_hdr (execchan
, _TEXT
, &text_hdr
, num_sections
,
539 error ("\"%s\": can't read text section header", execfile
);
541 if (read_section_hdr (execchan
, _DATA
, &data_hdr
, num_sections
,
543 error ("\"%s\": can't read data section header", execfile
);
545 text_start
= exec_aouthdr
.text_start
;
546 text_end
= text_start
+ exec_aouthdr
.tsize
;
547 text_offset
= text_hdr
.s_scnptr
;
548 exec_data_start
= exec_aouthdr
.data_start
;
549 exec_data_end
= exec_data_start
+ exec_aouthdr
.dsize
;
550 exec_data_offset
= data_hdr
.s_scnptr
;
551 data_start
= exec_data_start
;
552 data_end
+= exec_data_start
;
553 exec_mtime
= file_hdr
.f_timdat
;
555 #else /* not COFF_FORMAT */
559 val
= myread (execchan
, &exec_aouthdr
, sizeof (AOUTHDR
));
562 perror_with_name (filename
);
564 text_start
= N_TXTADDR (exec_aouthdr
);
565 exec_data_start
= N_DATADDR (exec_aouthdr
);
567 text_offset
= N_TXTOFF (exec_aouthdr
);
568 exec_data_offset
= N_TXTOFF (exec_aouthdr
) + exec_aouthdr
.a_text
;
570 text_end
= text_start
+ exec_aouthdr
.a_text
;
571 exec_data_end
= exec_data_start
+ exec_aouthdr
.a_data
;
572 data_start
= exec_data_start
;
573 data_end
+= exec_data_start
;
575 fstat (execchan
, &st_exec
);
576 exec_mtime
= st_exec
.st_mtime
;
578 #endif /* not COFF_FORMAT */
583 printf ("No exec file now.\n");
585 /* Tell display code (if any) about the changed file name. */
586 if (exec_file_display_hook
)
587 (*exec_file_display_hook
) (filename
);