Annotation of 43BSDReno/contrib/emacs-18.55/gdb/inflow.c, revision 1.1

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, &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: 
        !           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, &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: 
        !           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, &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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.