|
|
1.1 root 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:
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, <c_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, <c_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, <c_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 *)<c_inferior)[i]);
296:
297: #endif /* not HAVE_TERMIO */
298: }
299:
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:
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:
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:
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, ®isters[REGISTER_BYTE (FP0_REGNUM)],
519: sizeof inferior_fp_registers.fps_regs);
520: *(int *)®isters[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
521: *(int *)®isters[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
522: bcopy (&inferior_fp_registers.fps_control,
523: ®isters[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 (®isters[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
545: sizeof inferior_fp_registers.fps_regs);
546: inferior_registers.r_ps = *(int *)®isters[REGISTER_BYTE (PS_REGNUM)];
547: inferior_registers.r_pc = *(int *)®isters[REGISTER_BYTE (PC_REGNUM)];
548: bcopy (®isters[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, ®val);
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 *) ®isters[(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 *) ®isters[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 *) ®isters[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:
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:
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:
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, <c_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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.