9 date 89.03.27.20.08.50; author gnu; state Exp;
14 date 89.03.27.20.07.47; author gnu; state Exp;
19 date 89.03.27.18.49.06; author gnu; state Exp;
24 date 89.03.20.19.47.11; author gnu; state Exp;
35 @Restore A/UX-specific changes.
38 @/* Low level interface to ptrace, for GDB when running under Unix.
39 Copyright (C) 1988 Free Software Foundation, Inc.
41 GDB is distributed in the hope that it will be useful, but WITHOUT ANY
42 WARRANTY. No author or distributor accepts responsibility to anyone
43 for the consequences of using it or for whether it serves any
44 particular purpose or works at all, unless he says so in writing.
45 Refer to the GDB General Public License for full details.
47 Everyone is granted permission to copy, modify and redistribute GDB,
48 but only under the conditions described in the GDB General Public
49 License. A copy of this license is supposed to have been given to you
50 along with GDB so you can know your rights and responsibilities. It
51 should be in a file named COPYING. Among other things, the copyright
52 notice and this notice must be preserved on all copies.
54 In other words, go ahead and share GDB, but don't try to stop
55 anyone else from sharing it farther. Help stamp out software hoarding!
64 #include <sys/types.h>
67 #ifdef UNISOFT_ASSHOLES
70 #define mc68881 /* Needed to get float in user.h!!! */
71 #include <sys/seg.h> /* For user.h */
74 /* Things Unisoft defined differently from every other Unix system */
77 #define KERNEL_U_ADDR UDOT
81 #include <sys/param.h>
84 #include <sys/ioctl.h>
87 #ifdef COFF_ENCAPSULATE
88 #include "a.out.encap.h"
93 #define N_SET_MAGIC(exec, val) ((exec).a_magic = (val))
96 #include <sys/user.h> /* After a.out.h */
102 /* This function simply calls ptrace with the given arguments.
103 It exists so that all calls to ptrace are isolated in this
104 machine-dependent file.
106 If you are having trouble debugging ptrace calls, turn on DEBUG
107 and every call to ptrace, in this module or elsewhere, will be
110 call_ptrace (request, pid, arg3, arg4)
111 int request, pid, arg3, arg4;
116 fprintf(stderr, "ptrace(%x,,%x, %x) = ", request, arg3, arg4);
117 result=ptrace (request, pid, arg3, arg4);
118 fprintf(stderr, "%x\n", result);
121 #define ptrace call_ptrace
124 return ptrace (request, pid, arg3, arg4);
130 if (remote_debugging)
132 if (inferior_pid == 0)
134 ptrace (8, inferior_pid, 0, 0);
139 /* This is used when GDB is exiting. It gives less chance of error.*/
141 kill_inferior_fast ()
143 if (remote_debugging)
145 if (inferior_pid == 0)
147 ptrace (8, inferior_pid, 0, 0);
151 /* Resume execution of the inferior process.
152 If STEP is nonzero, single-step it.
153 If SIGNAL is nonzero, give it that signal. */
156 resume (step, signal)
161 if (remote_debugging)
162 remote_resume (step, signal);
165 ptrace (step ? 9 : 7, inferior_pid, 1, signal);
167 perror_with_name ("ptrace");
172 fetch_inferior_registers ()
175 register unsigned int regaddr;
176 char buf[MAX_REGISTER_RAW_SIZE];
180 unsigned int offset = (char *) &u.u_ar0 - (char *) &u;
181 offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR;
183 for (regno = 0; regno < NUM_REGS; regno++)
185 regaddr = register_addr (regno, offset);
186 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
188 *(int *) &buf[i] = ptrace (3, inferior_pid, regaddr, 0);
189 regaddr += sizeof (int);
191 supply_register (regno, buf);
195 /* Store our register values back into the inferior.
196 If REGNO is -1, do this for all registers.
197 Otherwise, REGNO specifies which register (so we can save time). */
199 store_inferior_registers (regno)
202 register unsigned int regaddr;
206 unsigned int offset = (char *) &u.u_ar0 - (char *) &u;
207 offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR;
211 regaddr = register_addr (regno, offset);
213 #ifdef UNISOFT_ASSHOLES
214 /* You can't write the PC with ptrace 6, only with ptrace 11! */
215 if (regno == PC_REGNUM)
216 ptrace(11, inferior_pid, 16, read_register(regno));
219 ptrace (6, inferior_pid, regaddr, read_register (regno));
222 sprintf (buf, "writing register number %d", regno);
223 perror_with_name (buf);
226 else for (regno = 0; regno < NUM_REGS; regno++)
228 regaddr = register_addr (regno, offset);
230 #ifdef UNISOFT_ASSHOLES
231 if (regno == PC_REGNUM)
232 ptrace(11, inferior_pid, 16, read_register(regno));
235 ptrace (6, inferior_pid, regaddr, read_register (regno));
238 sprintf (buf, "writing all regs, number %d", regno);
239 perror_with_name (buf);
244 /* Copy LEN bytes from inferior's memory starting at MEMADDR
245 to debugger memory starting at MYADDR.
246 On failure (cannot read from inferior, usually because address is out
247 of bounds) returns the value of errno. */
250 read_inferior_memory (memaddr, myaddr, len)
256 /* Round starting address down to longword boundary. */
257 register CORE_ADDR addr = memaddr & - sizeof (int);
258 /* Round ending address up; get number of longwords that makes. */
260 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
261 /* Allocate buffer of that many longwords. */
262 register int *buffer = (int *) alloca (count * sizeof (int));
265 /* Read all the longwords */
266 for (i = 0; i < count; i++, addr += sizeof (int))
269 if (remote_debugging)
270 buffer[i] = remote_fetch_word (addr);
272 buffer[i] = ptrace (1, inferior_pid, addr, 0);
277 /* Copy appropriate bytes out of the buffer. */
278 bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
282 /* Copy LEN bytes of data from debugger memory at MYADDR
283 to inferior's memory at MEMADDR.
284 On failure (cannot write the inferior)
285 returns the value of errno. */
288 write_inferior_memory (memaddr, myaddr, len)
294 /* Round starting address down to longword boundary. */
295 register CORE_ADDR addr = memaddr & - sizeof (int);
296 /* Round ending address up; get number of longwords that makes. */
298 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
299 /* Allocate buffer of that many longwords. */
300 register int *buffer = (int *) alloca (count * sizeof (int));
303 /* Fill start and end extra bytes of buffer with existing memory data. */
305 if (remote_debugging)
306 buffer[0] = remote_fetch_word (addr);
308 buffer[0] = ptrace (1, inferior_pid, addr, 0);
312 if (remote_debugging)
314 = remote_fetch_word (addr + (count - 1) * sizeof (int));
317 = ptrace (1, inferior_pid,
318 addr + (count - 1) * sizeof (int), 0);
321 /* Copy data to be written over corresponding part of buffer */
323 bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
325 /* Write the entire buffer. */
327 for (i = 0; i < count; i++, addr += sizeof (int))
330 if (remote_debugging)
331 remote_store_word (addr, buffer[i]);
333 ptrace (4, inferior_pid, addr, buffer[i]);
341 /* Work with core dump and executable files, for GDB.
342 This code would be in core.c if it weren't machine-dependent. */
344 /* Recognize COFF format systems because a.out.h defines AOUTHDR. */
350 #define N_TXTADDR(hdr) 0
351 #endif /* no N_TXTADDR */
354 #define N_DATADDR(hdr) hdr.a_text
355 #endif /* no N_DATADDR */
357 /* Make COFF and non-COFF names for things a little more compatible
358 to reduce conditionals later. */
361 #define a_magic magic
365 #define AOUTHDR struct exec
368 extern char *sys_siglist[];
371 /* Hook for `exec_file_command' command to call. */
373 extern void (*exec_file_display_hook) ();
375 /* File names of core file and executable file. */
377 extern char *corefile;
378 extern char *execfile;
380 /* Descriptors on which core file and executable file are open.
381 Note that the execchan is closed when an inferior is created
382 and reopened if the inferior dies or is killed. */
387 /* Last modification time of executable file.
388 Also used in source.c to compare against mtime of a source file. */
390 extern int exec_mtime;
392 /* Virtual addresses of bounds of the two areas of memory in the core file. */
394 extern CORE_ADDR data_start;
395 extern CORE_ADDR data_end;
396 extern CORE_ADDR stack_start;
397 extern CORE_ADDR stack_end;
399 /* Virtual addresses of bounds of two areas of memory in the exec file.
400 Note that the data area in the exec file is used only when there is no core file. */
402 extern CORE_ADDR text_start;
403 extern CORE_ADDR text_end;
405 extern CORE_ADDR exec_data_start;
406 extern CORE_ADDR exec_data_end;
408 /* Address in executable file of start of text area data. */
410 extern int text_offset;
412 /* Address in executable file of start of data area data. */
414 extern int exec_data_offset;
416 /* Address in core file of start of data area data. */
418 extern int data_offset;
420 /* Address in core file of start of stack area data. */
422 extern int stack_offset;
425 /* various coff data structures */
427 extern FILHDR file_hdr;
428 extern SCNHDR text_hdr;
429 extern SCNHDR data_hdr;
431 #endif /* not COFF_FORMAT */
433 /* a.out header saved in core file. */
435 extern AOUTHDR core_aouthdr;
437 /* a.out header of exec file. */
439 extern AOUTHDR exec_aouthdr;
441 extern void validate_files ();
443 core_file_command (filename, from_tty)
448 extern char registers[];
450 /* Discard all vestiges of any previous core file
451 and mark data and stack spaces as empty. */
463 stack_start = STACK_END_ADDR;
464 stack_end = STACK_END_ADDR;
466 /* Now, if a new core file was specified, open it and digest it. */
470 if (have_inferior_p ())
471 error ("To look at a core file, you must kill the inferior with \"kill\".");
472 corechan = open (filename, O_RDONLY, 0);
474 perror_with_name (filename);
475 /* 4.2-style (and perhaps also sysV-style) core dump file. */
481 val = myread (corechan, &u, sizeof u);
483 perror_with_name ("Not a core file: reading upage");
485 error ("Not a core file: could only read %d bytes", val);
486 data_start = exec_data_start;
488 data_end = data_start + NBPG * u.u_dsize;
489 stack_start = stack_end - NBPG * u.u_ssize;
490 data_offset = NBPG * UPAGES;
491 stack_offset = NBPG * (UPAGES + u.u_dsize);
493 /* Some machines put an absolute address in here; Unisoft
494 seems to put the offset in the upage of the regs. Sigh. */
495 reg_offset = (int) u.u_ar0;
496 if (reg_offset > NBPG * UPAGES)
497 reg_offset -= KERNEL_U_ADDR;
499 /* I don't know where to find this info.
500 So, for now, mark it as not available. */
501 N_SET_MAGIC (core_aouthdr, 0);
503 /* Read the register values out of the core file and store
504 them where `read_register' will find them. */
509 for (regno = 0; regno < NUM_REGS; regno++)
511 char buf[MAX_REGISTER_RAW_SIZE];
513 val = lseek (corechan, register_addr (regno, reg_offset), 0);
515 perror_with_name (reg_names[regno]);
517 val = myread (corechan, buf, sizeof buf);
519 perror_with_name (reg_names[regno]);
520 supply_register (regno, buf);
524 if (filename[0] == '/')
525 corefile = savestring (filename, strlen (filename));
528 corefile = concat (current_directory, "/", filename);
531 set_current_frame ( create_new_frame (read_register (FP_REGNUM),
533 select_frame (get_current_frame (), 0);
537 printf ("No core file now.\n");
540 exec_file_command (filename, from_tty)
546 /* Eliminate all traces of old exec file.
547 Mark text segment as empty. */
553 data_end -= exec_data_start;
562 /* Now open and digest the file the user requested, if any. */
566 execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
569 perror_with_name (filename);
576 if (read_file_hdr (execchan, &file_hdr) < 0)
577 error ("\"%s\": not in executable format.", execfile);
579 aout_hdrsize = file_hdr.f_opthdr;
580 num_sections = file_hdr.f_nscns;
582 if (read_aout_hdr (execchan, &exec_aouthdr, aout_hdrsize) < 0)
583 error ("\"%s\": can't read optional aouthdr", execfile);
585 if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections) < 0)
586 error ("\"%s\": can't read text section header", execfile);
588 if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0)
589 error ("\"%s\": can't read data section header", execfile);
591 text_start = exec_aouthdr.text_start;
592 text_end = text_start + exec_aouthdr.tsize;
593 text_offset = text_hdr.s_scnptr;
594 exec_data_start = exec_aouthdr.data_start;
595 exec_data_end = exec_data_start + exec_aouthdr.dsize;
596 exec_data_offset = data_hdr.s_scnptr;
597 data_start = exec_data_start;
598 data_end += exec_data_start;
599 exec_mtime = file_hdr.f_timdat;
601 #else /* not COFF_FORMAT */
605 #ifdef HEADER_SEEK_FD
606 HEADER_SEEK_FD (execchan);
609 val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR));
612 perror_with_name (filename);
614 text_start = N_TXTADDR (exec_aouthdr);
615 exec_data_start = N_DATADDR (exec_aouthdr);
617 text_offset = N_TXTOFF (exec_aouthdr);
618 exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
620 text_end = text_start + exec_aouthdr.a_text;
621 exec_data_end = exec_data_start + exec_aouthdr.a_data;
622 data_start = exec_data_start;
623 data_end += exec_data_start;
625 fstat (execchan, &st_exec);
626 exec_mtime = st_exec.st_mtime;
628 #endif /* not COFF_FORMAT */
633 printf ("No exec file now.\n");
635 /* Tell display code (if any) about the changed file name. */
636 if (exec_file_display_hook)
637 (*exec_file_display_hook) (filename);
644 @Remove A/UX-specific changes for shipping to FSF.
650 ptrace (6, inferior_pid, regaddr, read_register (regno));
653 ptrace (6, inferior_pid, regaddr, read_register (regno));
659 @A/UX and USG changes, and a little better error reporting.
663 #ifdef UNISOFT_ASSHOLES
666 #define mc68881 /* Needed to get float in user.h!!! */
667 #include <sys/seg.h> /* For user.h */
669 #include <sys/time.h>
670 /* Things Unisoft defined differently from every other Unix system */
671 #define NBPG PAGESIZE
673 #define KERNEL_U_ADDR UDOT
678 #ifdef UNISOFT_ASSHOLES
679 /* You can't write the PC with ptrace 6, only with ptrace 11! */
680 if (regno == PC_REGNUM)
681 ptrace(11, inferior_pid, 16, read_register(regno));
684 ptrace (6, inferior_pid, regaddr, read_register (regno));
687 #ifdef UNISOFT_ASSHOLES
688 if (regno == PC_REGNUM)
689 ptrace(11, inferior_pid, 16, read_register(regno));
692 ptrace (6, inferior_pid, regaddr, read_register (regno));
703 #include <sys/user.h>
707 machine-dependent file. */
712 ptrace (6, inferior_pid, regaddr, read_register (regno));
715 ptrace (6, inferior_pid, regaddr, read_register (regno));
718 sprintf (buf, "writing register number %d", regno);
721 perror_with_name (filename);
724 reg_offset = (int) u.u_ar0 - KERNEL_U_ADDR;
727 perror_with_name (filename);
730 perror_with_name (filename);