Annotation of 43BSDReno/contrib/emacs-18.55/gdb/inflow.c, revision 1.1.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.