gdb-2.8
[external/binutils.git] / gdb / inflow.c
1 /* Low level interface to ptrace, for GDB when running under Unix.
2    Copyright (C) 1986, 1987 Free Software Foundation, Inc.
3
4 GDB is distributed in the hope that it will be useful, but WITHOUT ANY
5 WARRANTY.  No author or distributor accepts responsibility to anyone
6 for the consequences of using it or for whether it serves any
7 particular purpose or works at all, unless he says so in writing.
8 Refer to the GDB General Public License for full details.
9
10 Everyone is granted permission to copy, modify and redistribute GDB,
11 but only under the conditions described in the GDB General Public
12 License.  A copy of this license is supposed to have been given to you
13 along with GDB so you can know your rights and responsibilities.  It
14 should be in a file named COPYING.  Among other things, the copyright
15 notice and this notice must be preserved on all copies.
16
17 In other words, go ahead and share GDB, but don't try to stop
18 anyone else from sharing it farther.  Help stamp out software hoarding!
19 */
20
21 #include "defs.h"
22 #include "initialize.h"
23 #include "param.h"
24 #include "frame.h"
25 #include "inferior.h"
26
27 #include <stdio.h>
28 #include <sys/param.h>
29 #include <sys/dir.h>
30 #ifndef UMAX_PTRACE
31 #include <sys/user.h>
32 #endif
33 #include <signal.h>
34 #include <sys/ioctl.h>
35 #include <fcntl.h>
36
37 #ifdef UMAX_PTRACE
38 #include <a.out.h>
39 #include <sys/ptrace.h>
40 #define PTRACE_ATTACH PT_ATTACH
41 #define PTRACE_DETACH PT_FREEPROC
42 #endif
43
44 #ifdef NEW_SUN_PTRACE
45 #include <sys/ptrace.h>
46 #include <machine/reg.h>
47 #endif
48
49 #ifdef HP9K320
50 #include <sys/ptrace.h>
51 #include <sys/reg.h>
52 #include <sys/trap.h>
53 #endif
54
55 #ifdef HAVE_TERMIO
56 #include <termio.h>
57 #undef TIOCGETP
58 #define TIOCGETP TCGETA
59 #undef TIOCSETN
60 #define TIOCSETN TCSETA
61 #undef TIOCSETP
62 #define TIOCSETP TCSETAF
63 #define TERMINAL struct termio
64 #else
65 #include <sgtty.h>
66 #define TERMINAL struct sgttyb
67 #endif
68
69 extern int errno;
70
71 /* Nonzero if we are debugging an attached outside process
72    rather than an inferior.  */
73
74 static int attach_flag;
75
76 START_FILE
77 \f
78 /* Record terminal status separately for debugger and inferior.  */
79
80 static TERMINAL sg_inferior;
81 static TERMINAL sg_ours;
82 static int tflags_inferior;
83 static int tflags_ours;
84
85 #ifdef TIOCGLTC
86 static struct tchars tc_inferior;
87 static struct tchars tc_ours;
88 static struct ltchars ltc_inferior;
89 static struct ltchars ltc_ours;
90 static int lmode_inferior;
91 static int lmode_ours;
92 #endif /* TIOCGLTC */
93
94 #ifdef TIOCGPGRP
95 static int pgrp_inferior;
96 static int pgrp_ours;
97 #else
98 static int (*sigint_ours) ();
99 static int (*sigquit_ours) ();
100 #endif /* TIOCGPGRP */
101
102 /* Copy of inferior_io_terminal when inferior was last started.  */
103 static char *inferior_thisrun_terminal;
104
105 static void terminal_ours_1 ();
106
107 /* Nonzero if our terminal settings are in effect.
108    Zero if the inferior's settings are in effect.  */
109 static int terminal_is_ours;
110
111 /* Initialize the terminal settings we record for the inferior,
112    before we actually run the inferior.  */
113
114 void
115 terminal_init_inferior ()
116 {
117   if (remote_debugging)
118     return;
119
120   sg_inferior = sg_ours;
121   tflags_inferior = tflags_ours;
122
123 #ifdef TIOCGLTC
124   tc_inferior = tc_ours;
125   ltc_inferior = ltc_ours;
126   lmode_inferior = lmode_ours;
127 #endif /* TIOCGLTC */
128
129 #ifdef TIOCGPGRP
130   pgrp_inferior = inferior_pid;
131 #endif /* TIOCGPGRP */
132
133   terminal_is_ours = 1;
134 }
135
136 /* Put the inferior's terminal settings into effect.
137    This is preparation for starting or resuming the inferior.  */
138
139 void
140 terminal_inferior ()
141 {
142   if (remote_debugging)
143     return;
144
145   if (terminal_is_ours)   /*  && inferior_thisrun_terminal == 0) */
146     {
147       fcntl (0, F_SETFL, tflags_inferior);
148       fcntl (0, F_SETFL, tflags_inferior);
149       ioctl (0, TIOCSETN, &sg_inferior);
150
151 #ifdef TIOCGLTC
152       ioctl (0, TIOCSETC, &tc_inferior);
153       ioctl (0, TIOCSLTC, &ltc_inferior);
154       ioctl (0, TIOCLSET, &lmode_inferior);
155 #endif /* TIOCGLTC */
156
157 #ifdef TIOCGPGRP
158       ioctl (0, TIOCSPGRP, &pgrp_inferior);
159 #else
160       sigint_ours = (signal (SIGINT, SIG_IGN));
161       sigquit_ours = (signal (SIGQUIT, SIG_IGN));
162 #endif /* TIOCGPGRP */
163     }
164   terminal_is_ours = 0;
165 }
166
167 /* Put some of our terminal settings into effect,
168    enough to get proper results from our output,
169    but do not change into or out of RAW mode
170    so that no input is discarded.
171
172    After doing this, either terminal_ours or terminal_inferior
173    should be called to get back to a normal state of affairs.  */
174
175 void
176 terminal_ours_for_output ()
177 {
178   if (remote_debugging)
179     return;
180
181   terminal_ours_1 (1);
182 }
183
184 /* Put our terminal settings into effect.
185    First record the inferior's terminal settings
186    so they can be restored properly later.  */
187
188 void
189 terminal_ours ()
190 {
191   if (remote_debugging)
192     return;
193
194   terminal_ours_1 (0);
195 }
196
197 static void
198 terminal_ours_1 (output_only)
199      int output_only;
200 {
201 #ifdef TIOCGPGRP
202   /* Ignore this signal since it will happen when we try to set the pgrp.  */
203   int (*osigttou) ();
204 #endif /* TIOCGPGRP */
205
206   if (!terminal_is_ours)  /*   && inferior_thisrun_terminal == 0)  */
207     {
208       terminal_is_ours = 1;
209
210 #ifdef TIOCGPGRP
211       osigttou = signal (SIGTTOU, SIG_IGN);
212
213       ioctl (0, TIOCGPGRP, &pgrp_inferior);
214       ioctl (0, TIOCSPGRP, &pgrp_ours);
215
216       signal (SIGTTOU, osigttou);
217 #else
218       signal (SIGINT, sigint_ours);
219       signal (SIGQUIT, sigquit_ours);
220 #endif /* TIOCGPGRP */
221
222       tflags_inferior = fcntl (0, F_GETFL, 0);
223       ioctl (0, TIOCGETP, &sg_inferior);
224
225 #ifdef TIOCGLTC
226       ioctl (0, TIOCGETC, &tc_inferior);
227       ioctl (0, TIOCGLTC, &ltc_inferior);
228       ioctl (0, TIOCLGET, &lmode_inferior);
229 #endif /* TIOCGLTC */
230     }
231
232 #ifdef HAVE_TERMIO
233   sg_ours.c_lflag |= ICANON;
234   if (output_only && !(sg_inferior.c_lflag & ICANON))
235     sg_ours.c_lflag &= ~ICANON;
236 #else /* not HAVE_TERMIO */
237   sg_ours.sg_flags &= ~RAW & ~CBREAK;
238   if (output_only)
239     sg_ours.sg_flags |= (RAW | CBREAK) & sg_inferior.sg_flags;
240 #endif /* not HAVE_TERMIO */
241
242   fcntl (0, F_SETFL, tflags_ours);
243   fcntl (0, F_SETFL, tflags_ours);
244   ioctl (0, TIOCSETN, &sg_ours);
245
246 #ifdef TIOCGLTC
247   ioctl (0, TIOCSETC, &tc_ours);
248   ioctl (0, TIOCSLTC, &ltc_ours);
249   ioctl (0, TIOCLSET, &lmode_ours);
250 #endif /* TIOCGLTC */
251
252
253 #ifdef HAVE_TERMIO
254   sg_ours.c_lflag |= ICANON;
255 #else /* not HAVE_TERMIO */
256   sg_ours.sg_flags &= ~RAW & ~CBREAK;
257 #endif /* not HAVE_TERMIO */
258 }
259
260 static void
261 term_status_command ()
262 {
263   register int i;
264
265   if (remote_debugging)
266     {
267       printf ("No terminal status when remote debugging.\n");
268       return;
269     }
270
271   printf ("Inferior's terminal status (currently saved by GDB):\n");
272
273 #ifdef HAVE_TERMIO
274
275   printf ("fcntl flags = 0x%x, c_iflag = 0x%x, c_oflag = 0x%x,\n",
276           tflags_inferior, sg_inferior.c_iflag, sg_inferior.c_oflag);
277   printf ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
278           sg_inferior.c_cflag, sg_inferior.c_lflag, sg_inferior.c_line);
279   printf ("c_cc: ");
280   for (i = 0; (i < NCC); i += 1)
281     printf ("0x%x ", sg_inferior.c_cc[i]);
282   printf ("\n");
283
284 #else /* not HAVE_TERMIO */
285
286   printf ("fcntl flags = 0x%x, lmode = 0x%x,\nsgttyb.sg_flags = 0x%x, owner pid = %d.\n",
287           tflags_inferior, lmode_inferior,
288           sg_inferior.sg_flags, pgrp_inferior);
289   printf ("tchars: ");
290   for (i = 0; i < sizeof (struct tchars); i++)
291     printf ("0x%x ", ((char *)&tc_inferior)[i]);
292   printf ("\n");
293   printf ("ltchars: ");
294   for (i = 0; i < sizeof (struct ltchars); i++)
295     printf ("0x%x ", ((char *)&ltc_inferior)[i]);
296
297 #endif /* not HAVE_TERMIO */
298 }
299 \f
300 static void
301 new_tty (ttyname)
302      char *ttyname;
303 {
304   register int tty;
305   register int fd;
306
307 #if 0
308   /* I think it is better not to do this.  Then C-z on the GDB terminal
309      will still stop the program, while C-z on the data terminal
310      will be input.  */
311
312   /* Disconnect the child process from our controlling terminal.  */
313   tty = open("/dev/tty", O_RDWR);
314   if (tty > 0)
315     {
316       ioctl(tty, TIOCNOTTY, 0);
317       close(tty);
318     }
319 #endif
320   /* Now open the specified new terminal.  */
321
322   tty = open(ttyname, O_RDWR);
323   if (tty == -1)
324     _exit(1);
325
326   dup2(tty, 0);
327   dup2(tty, 1);
328   dup2(tty, 2);
329   close(tty);
330 }
331 \f
332 /* Start an inferior process and returns its pid.
333    ALLARGS is a string containing shell command to run the program.
334    ENV is the environment vector to pass.  */
335
336 #ifndef SHELL_FILE
337 #define SHELL_FILE "/bin/sh"
338 #endif
339
340 int
341 create_inferior (allargs, env)
342      char *allargs;
343      char **env;
344 {
345   int pid;
346   char *shell_command;
347   extern int sys_nerr;
348   extern char *sys_errlist[];
349   extern int errno;
350
351   /* If desired, concat something onto the front of ALLARGS.
352      SHELL_COMMAND is the result.  */
353 #ifdef SHELL_COMMAND_CONCAT
354   shell_command = (char *) alloca (strlen (SHELL_COMMAND_CONCAT) + strlen (allargs) + 1);
355   strcpy (shell_command, SHELL_COMMAND_CONCAT);
356   strcat (shell_command, allargs);
357 #else
358   shell_command = allargs;
359 #endif
360
361   /* exec is said to fail if the executable is open.  */
362   close_exec_file ();
363
364   pid = vfork ();
365   if (pid < 0)
366     perror_with_name ("vfork");
367
368   if (pid == 0)
369     {
370       char *args[4];
371
372 #ifdef TIOCGPGRP
373       /* Run inferior in a separate process group.  */
374       setpgrp (getpid (), getpid ());
375 #endif /* TIOCGPGRP */
376
377       inferior_thisrun_terminal = inferior_io_terminal;
378       if (inferior_io_terminal != 0)
379         new_tty (inferior_io_terminal);
380
381 /* Not needed on Sun, at least, and loses there
382    because it clobbers the superior.  */
383 /*???      signal (SIGQUIT, SIG_DFL);
384       signal (SIGINT, SIG_DFL);  */
385
386       ptrace (0);
387
388       args[0] = "sh";
389       args[1] = "-c";
390       args[2] = shell_command;
391       args[3] = 0;
392
393       execve (SHELL_FILE, args, env);
394
395       fprintf (stderr, "Cannot exec %s: %s.\n", SHELL_FILE,
396                errno < sys_nerr ? sys_errlist[errno] : "unknown error");
397       fflush (stderr);
398       _exit (0177);
399     }
400   return pid;
401 }
402
403 /* Kill the inferior process.  Make us have no inferior.  */
404
405 static void
406 kill_command ()
407 {
408   if (remote_debugging)
409     return;
410   if (inferior_pid == 0)
411     error ("The program is not being run.");
412   if (!query ("Kill the inferior process? "))
413     error ("Not confirmed.");
414   kill_inferior ();
415 }
416
417 kill_inferior ()
418 {
419   if (remote_debugging)
420     return;
421   if (inferior_pid == 0)
422     return;
423   ptrace (8, inferior_pid, 0, 0);
424   wait (0);
425   inferior_died ();
426 }
427
428 /* This is used when GDB is exiting.  It gives less chance of error.*/
429
430 kill_inferior_fast ()
431 {
432   if (remote_debugging)
433     return;
434   if (inferior_pid == 0)
435     return;
436   ptrace (8, inferior_pid, 0, 0);
437   wait (0);
438 }
439
440 inferior_died ()
441 {
442   inferior_pid = 0;
443   attach_flag = 0;
444   mark_breakpoints_out ();
445   reopen_exec_file ();
446   if (have_core_file_p ())
447     set_current_frame (read_register (FP_REGNUM));
448 }
449
450 /* Resume execution of the inferior process.
451    If STEP is nonzero, single-step it.
452    If SIGNAL is nonzero, give it that signal.  */
453
454 void
455 resume (step, signal)
456      int step;
457      int signal;
458 {
459   errno = 0;
460   if (remote_debugging)
461     remote_resume (step, signal);
462   else
463     {
464       ptrace (step ? 9 : 7, inferior_pid, 1, signal);
465       if (errno)
466         perror_with_name ("ptrace");
467     }
468 }
469 \f
470 #ifdef ATTACH_DETACH
471
472 /* Start debugging the process whose number is PID.  */
473
474 attach (pid)
475      int pid;
476 {
477   errno = 0;
478   ptrace (PTRACE_ATTACH, pid, 0, 0);
479   if (errno)
480     perror_with_name ("ptrace");
481   attach_flag = 1;
482   return pid;
483 }
484
485 /* Stop debugging the process whose number is PID
486    and continue it with signal number SIGNAL.
487    SIGNAL = 0 means just continue it.  */
488
489 void
490 detach (signal)
491      int signal;
492 {
493   errno = 0;
494   ptrace (PTRACE_DETACH, inferior_pid, 1, signal);
495   if (errno)
496     perror_with_name ("ptrace");
497   attach_flag = 0;
498 }
499 #endif /* ATTACH_DETACH */
500 \f
501 #ifdef NEW_SUN_PTRACE
502
503 void
504 fetch_inferior_registers ()
505 {
506   struct regs inferior_registers;
507   struct fp_status inferior_fp_registers;
508   extern char registers[];
509
510   if (remote_debugging)
511     remote_fetch_registers (registers);
512   else
513     {
514       ptrace (PTRACE_GETREGS, inferior_pid, &inferior_registers);
515       ptrace (PTRACE_GETFPREGS, inferior_pid, &inferior_fp_registers);
516
517       bcopy (&inferior_registers, registers, 16 * 4);
518       bcopy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
519              sizeof inferior_fp_registers.fps_regs);
520       *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
521       *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
522       bcopy (&inferior_fp_registers.fps_control,
523              &registers[REGISTER_BYTE (FPC_REGNUM)],
524              sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
525     }
526 }
527
528 /* Store our register values back into the inferior.
529    If REGNO is -1, do this for all registers.
530    Otherwise, REGNO specifies which register (so we can save time).  */
531
532 store_inferior_registers (regno)
533      int regno;
534 {
535   struct regs inferior_registers;
536   struct fp_status inferior_fp_registers;
537   extern char registers[];
538
539   if (remote_debugging)
540     remote_store_registers (registers);
541   else
542     {
543       bcopy (registers, &inferior_registers, 16 * 4);
544       bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
545              sizeof inferior_fp_registers.fps_regs);
546       inferior_registers.r_ps = *(int *)&registers[REGISTER_BYTE (PS_REGNUM)];
547       inferior_registers.r_pc = *(int *)&registers[REGISTER_BYTE (PC_REGNUM)];
548       bcopy (&registers[REGISTER_BYTE (FPC_REGNUM)],
549              &inferior_fp_registers.fps_control,
550              sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
551
552       ptrace (PTRACE_SETREGS, inferior_pid, &inferior_registers);
553       ptrace (PTRACE_SETFPREGS, inferior_pid, &inferior_fp_registers);
554     }
555 }
556
557 #else
558 #ifdef HP9K320
559
560 #define FP_REGISTER_ADDR_DIFF(u, regno)                                 \
561   (((char *) (FP_REGISTER_ADDR (u, regno))) - ((char *) &(u)))
562
563 #define INFERIOR_AR0(u)                                                 \
564   ((ptrace                                                              \
565     (PT_RUAREA, inferior_pid, ((char *) &u.u_ar0 - (char *) &u), 0))    \
566    - KERNEL_U_ADDR)
567
568 static void
569 fetch_inferior_register (regno, regaddr)
570      register int regno;
571      register unsigned int regaddr;
572 {
573 #ifndef HPUX_VERSION_5
574   if (regno == PS_REGNUM)
575     {
576       union { int i; short s[2]; } ps_val;
577       int regval;
578
579       ps_val.i = (ptrace (PT_RUAREA, inferior_pid, regaddr, 0));
580       regval = ps_val.s[0];
581       supply_register (regno, &regval);
582     }
583   else
584 #endif /* not HPUX_VERSION_5 */
585     {
586       char buf[MAX_REGISTER_RAW_SIZE];
587       register int i;
588
589       for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
590         {
591           *(int *) &buf[i] = ptrace (PT_RUAREA, inferior_pid, regaddr, 0);
592           regaddr += sizeof (int);
593         }
594       supply_register (regno, buf);
595     }
596   return;
597 }
598
599 static void
600 store_inferior_register_1 (regno, regaddr, value)
601      int regno;
602      unsigned int regaddr;
603      int value;
604 {
605   errno = 0;
606   ptrace (PT_WUAREA, inferior_pid, regaddr, value);
607 #if 0
608   /* HP-UX randomly sets errno to non-zero for regno == 25.
609      However, the value is correctly written, so ignore errno. */
610   if (errno != 0)
611     {
612       char string_buf[64];
613
614       sprintf (string_buf, "writing register number %d", regno);
615       perror_with_name (string_buf);
616     }
617 #endif
618   return;
619 }
620
621 static void
622 store_inferior_register (regno, regaddr)
623      register int regno;
624      register unsigned int regaddr;
625 {
626 #ifndef HPUX_VERSION_5
627   if (regno == PS_REGNUM)
628     {
629       union { int i; short s[2]; } ps_val;
630
631       ps_val.i = (ptrace (PT_RUAREA, inferior_pid, regaddr, 0));
632       ps_val.s[0] = (read_register (regno));
633       store_inferior_register_1 (regno, regaddr, ps_val.i);
634     }
635   else
636 #endif /* not HPUX_VERSION_5 */
637     {
638       char buf[MAX_REGISTER_RAW_SIZE];
639       register int i;
640       extern char registers[];
641
642       for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
643         {
644           store_inferior_register_1
645             (regno, regaddr,
646              (*(int *) &registers[(REGISTER_BYTE (regno)) + i]));
647           regaddr += sizeof (int);
648         }
649     }
650   return;
651 }
652
653 void
654 fetch_inferior_registers ()
655 {
656   struct user u;
657   register int regno;
658   register unsigned int ar0_offset;
659
660   ar0_offset = (INFERIOR_AR0 (u));
661   for (regno = 0; (regno < FP0_REGNUM); regno++)
662     fetch_inferior_register (regno, (REGISTER_ADDR (ar0_offset, regno)));
663   for (; (regno < NUM_REGS); regno++)
664     fetch_inferior_register (regno, (FP_REGISTER_ADDR_DIFF (u, regno)));
665 }
666
667 /* Store our register values back into the inferior.
668    If REGNO is -1, do this for all registers.
669    Otherwise, REGNO specifies which register (so we can save time).  */
670
671 store_inferior_registers (regno)
672      register int regno;
673 {
674   struct user u;
675   register unsigned int ar0_offset;
676
677   if (regno >= FP0_REGNUM)
678     {
679       store_inferior_register (regno, (FP_REGISTER_ADDR_DIFF (u, regno)));
680       return;
681     }
682
683   ar0_offset = (INFERIOR_AR0 (u));
684   if (regno >= 0)
685     {
686       store_inferior_register (regno, (REGISTER_ADDR (ar0_offset, regno)));
687       return;
688     }
689
690   for (regno = 0; (regno < FP0_REGNUM); regno++)
691     store_inferior_register (regno, (REGISTER_ADDR (ar0_offset, regno)));
692   for (; (regno < NUM_REGS); regno++)
693     store_inferior_register (regno, (FP_REGISTER_ADDR_DIFF (u, regno)));
694   return;
695 }
696
697 #else /* not HP9K320 */
698
699 void
700 fetch_inferior_registers ()
701 {
702   register int regno;
703   register unsigned int regaddr;
704   char buf[MAX_REGISTER_RAW_SIZE];
705   register int i;
706
707 #ifdef UMAX_PTRACE
708   unsigned int offset = 0;
709 #else
710   struct user u;
711   unsigned int offset = (char *) &u.u_ar0 - (char *) &u;
712   offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR;
713 #endif
714
715   for (regno = 0; regno < NUM_REGS; regno++)
716     {
717       regaddr = register_addr (regno, offset);
718       for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
719         {
720           *(int *) &buf[i] = ptrace (3, inferior_pid, regaddr, 0);
721           regaddr += sizeof (int);
722         }
723       supply_register (regno, buf);
724     }
725 }
726
727 /* Store our register values back into the inferior.
728    If REGNO is -1, do this for all registers.
729    Otherwise, REGNO specifies which register (so we can save time).  */
730
731 store_inferior_registers (regno)
732      int regno;
733 {
734   register unsigned int regaddr;
735   char buf[80];
736   extern char registers[];
737   int i;
738
739 #ifdef UMAX_PTRACE
740   unsigned int offset = 0;
741 #else
742   struct user u;
743   unsigned int offset = (char *) &u.u_ar0 - (char *) &u;
744   offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR;
745 #endif
746
747   if (regno >= 0)
748     {
749       regaddr = register_addr (regno, offset);
750       for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int))
751         {
752           errno = 0;
753           ptrace (6, inferior_pid, regaddr,
754                   *(int *) &registers[REGISTER_BYTE (regno) + i]);
755           if (errno != 0)
756             {
757               sprintf (buf, "writing register number %d(%d)", regno, i);
758               perror_with_name (buf);
759             }
760           regaddr += sizeof(int);
761         }
762     }
763   else for (regno = 0; regno < NUM_REGS; regno++)
764     {
765       regaddr = register_addr (regno, offset);
766       for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int))
767         {
768           errno = 0;
769           ptrace (6, inferior_pid, regaddr,
770                   *(int *) &registers[REGISTER_BYTE (regno) + i]);
771           if (errno != 0)
772             {
773               sprintf (buf, "writing register number %d(%d)", regno, i);
774               perror_with_name (buf);
775             }
776           regaddr += sizeof(int);
777         }
778     }
779 }
780
781 #endif /* not HP9K320 */
782 #endif /* not NEW_SUN_PTRACE */
783 \f
784 /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
785    in the NEW_SUN_PTRACE case.
786    It ought to be straightforward.  But it appears that writing did
787    not write the data that I specified.  I cannot understand where
788    it got the data that it actually did write.  */
789
790 /* Copy LEN bytes from inferior's memory starting at MEMADDR
791    to debugger memory starting at MYADDR.  */
792
793 read_inferior_memory (memaddr, myaddr, len)
794      CORE_ADDR memaddr;
795      char *myaddr;
796      int len;
797 {
798   register int i;
799   /* Round starting address down to longword boundary.  */
800   register CORE_ADDR addr = memaddr & - sizeof (int);
801   /* Round ending address up; get number of longwords that makes.  */
802   register int count
803     = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
804   /* Allocate buffer of that many longwords.  */
805   register int *buffer = (int *) alloca (count * sizeof (int));
806
807   /* Read all the longwords */
808   for (i = 0; i < count; i++, addr += sizeof (int))
809     {
810       if (remote_debugging)
811         buffer[i] = remote_fetch_word (addr);
812       else
813         buffer[i] = ptrace (1, inferior_pid, addr, 0);
814     }
815
816   /* Copy appropriate bytes out of the buffer.  */
817   bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
818 }
819
820 /* Copy LEN bytes of data from debugger memory at MYADDR
821    to inferior's memory at MEMADDR.
822    On failure (cannot write the inferior)
823    returns the value of errno.  */
824
825 int
826 write_inferior_memory (memaddr, myaddr, len)
827      CORE_ADDR memaddr;
828      char *myaddr;
829      int len;
830 {
831   register int i;
832   /* Round starting address down to longword boundary.  */
833   register CORE_ADDR addr = memaddr & - sizeof (int);
834   /* Round ending address up; get number of longwords that makes.  */
835   register int count
836     = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
837   /* Allocate buffer of that many longwords.  */
838   register int *buffer = (int *) alloca (count * sizeof (int));
839   extern int errno;
840
841   /* Fill start and end extra bytes of buffer with existing memory data.  */
842
843   if (remote_debugging)
844     buffer[0] = remote_fetch_word (addr);
845   else
846     buffer[0] = ptrace (1, inferior_pid, addr, 0);
847
848   if (count > 1)
849     {
850       if (remote_debugging)
851         buffer[count - 1]
852           = remote_fetch_word (addr + (count - 1) * sizeof (int));
853       else
854         buffer[count - 1]
855           = ptrace (1, inferior_pid,
856                     addr + (count - 1) * sizeof (int), 0);
857     }
858
859   /* Copy data to be written over corresponding part of buffer */
860
861   bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
862
863   /* Write the entire buffer.  */
864
865   for (i = 0; i < count; i++, addr += sizeof (int))
866     {
867       errno = 0;
868       if (remote_debugging)
869         remote_store_word (addr, buffer[i]);
870       else
871         ptrace (4, inferior_pid, addr, buffer[i]);
872       if (errno)
873         return errno;
874     }
875
876   return 0;
877 }
878 \f
879 static void
880 try_writing_regs_command ()
881 {
882   register int i;
883   register int value;
884   extern int errno;
885
886   if (inferior_pid == 0)
887     error ("There is no inferior process now.");
888
889   for (i = 0; ; i += 2)
890     {
891       QUIT;
892       errno = 0;
893       value = ptrace (3, inferior_pid, i, 0);
894       ptrace (6, inferior_pid, i, value);
895       if (errno == 0)
896         {
897           printf (" Succeeded with address 0x%x; value 0x%x (%d).\n",
898                   i, value, value);
899         }
900       else if ((i & 0377) == 0)
901         printf (" Failed at 0x%x.\n", i);
902     }
903 }
904 \f
905 static
906 initialize ()
907 {
908   add_com ("term-status", class_obscure, term_status_command,
909            "Print info on inferior's saved terminal status.");
910
911   add_com ("try-writing-regs", class_obscure, try_writing_regs_command,
912            "Try writing all locations in inferior's system block.\n\
913 Report which ones can be written.");
914
915   add_com ("kill", class_run, kill_command,
916            "Kill execution of program being debugged.");
917
918   inferior_pid = 0;
919
920   ioctl (0, TIOCGETP, &sg_ours);
921   fcntl (0, F_GETFL, tflags_ours);
922
923 #ifdef TIOCGLTC
924   ioctl (0, TIOCGETC, &tc_ours);
925   ioctl (0, TIOCGLTC, &ltc_ours);
926   ioctl (0, TIOCLGET, &lmode_ours);
927 #endif /* TIOCGLTC */
928
929 #ifdef TIOCGPGRP
930   ioctl (0, TIOCGPGRP, &pgrp_ours);
931 #endif /* TIOCGPGRP */
932
933   terminal_is_ours = 1;
934 }
935
936 END_FILE