This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[eliz@is.elta.co.il: Patches to gdb/go32-nat.c]


------- Start of forwarded message -------
Date: Sun, 27 Jun 1999 18:46:05 +0300 (IDT)
From: Eli Zaretskii <eliz@is.elta.co.il>
X-Sender: eliz@is
To: gdb-patches@sourceware.cygnus.com
cc: DJ Delorie <dj@delorie.com>
Subject: Patches to gdb/go32-nat.c
Content-Type: TEXT/PLAIN; charset=US-ASCII

The following patches to go32-nat.c correct quite a few problems in
the DJGPP version.

1999-06-26  Eli Zaretskii  <eliz@is.elta.co.il>

	* go32-nat.c (redir_cmdline_parse, redir_cmdline_delete,
	redir_to_child, redir_to_debugger, redir_debug_init)
	[__DJGPP_MINOR__ < 3]: Dummy stubs for redirecting debuggee's
	standard handles.
	(print_387_status): Print "last FP instruction", not "last
	exception".  Restore the upper 5 bits of the opcode that aren't
	stored in the FPU state.  Print the FPU stack in its physical
	order, not relative to ST(0).  Print "special", not "trap" for
	unnormals and infinities.  Print all 10 bytes of each FP register,
	and print them with 19 significant digits.
	(regno_mapping): Make the mapping consistent with tm-go32.h.
	(sig_map): Add mappings for SIGQUIT, SIGFPE, SIGALRM.  Map NMI to
	SIGBUS.
	(excep_map): New variable, maps GDB signals to DJGPP exceptions.
	(go32_attach): Signal an error: we cannot attach to other
	processes.
	(go32_resume): Record the signal with which the inferior should be
	resumed, mapped to the DJGPP exception number.
	(go32_wait): Pass the signal recorded in go32_resume to the
	debuggee.  Save and restore debugger's and debuggee's current
	working directory.
	[__DJGPP_MINOR__ < 3]: Save and restore inferior's FPU state.
	(store_register): FPU regsiters have numbers less than 31.
	(go32_kill_inferior): Delete the parsed command-line storage.
	(go32_create_inferior): Initialize the parsed command-line
	storage.  Parse the command line and create the redirections for
	inferior's standard handles.
	[__DJGPP_MINOR__ < 3]: Init the inferior's FPU state.
	(ignore2): Function deleted.
	(device_mode): New function, switches a character device between
	raw and cooked mode.
	(go32_terminal_init): Invalidate the raw/cooked mode information.
	(go32_terminal_info): Print whether the inferior's terminal is in
	raw or cooked mode.
	[__DJGPP_MINOR__ > 2]: Say if standard handles are redirected or
	closed by the inferior.
	(go32_terminal_inferior): Switch standard handles to the
	inferior's files/devices.  Put the inferior's input device to
	raw/cooked mode, exactly like we found it last time.
	(go32_terminal_ours): Restore debugger's standard handles and put
	the terminal into cooked mode.  Save the mode of inferior's input
	device.
	(init_go32_ops): Assign go32_ops.to_attach,
	go32_ops.to_terminal_info, go32_ops.to_terminal_ours_for_output.
	Initialize inferior's cwd and the command-line storage.

*** cvs/gdb/go32-nat.c	Mon Jun  7 22:17:28 1999
- --- ./gdb/go32-nat.c	Sat Jun 26 19:27:58 1999
*************** Foundation, Inc., 59 Temple Place - Suit
*** 32,40 ****
- --- 32,46 ----
  #include <stdio.h>     /* required for __DJGPP_MINOR__ */
  #include <stdlib.h>
  #include <string.h>
+ #include <errno.h>
  #include <unistd.h>
+ #include <io.h>
+ #include <dpmi.h>
  #include <debug/v2load.h>
  #include <debug/dbgcom.h>
+ #if __DJGPP_MINOR__ > 2
+ #include <debug/redir.h>
+ #endif
  
  #if __DJGPP_MINOR__ < 3
  /* This code will be provided from DJGPP 2.03 on. Until then I code it
*************** load_npx (void)
*** 93,98 ****
- --- 99,125 ----
  {
    asm ("frstor %0" : "=m" (npx));
  }
+ /* ------------------------------------------------------------------------- */
+ /* Stubs for the missing redirection functions.  */
+ typedef struct {
+   char *command;
+   int redirected;
+ } cmdline_t;
+ 
+ void redir_cmdline_delete (cmdline_t *ptr) {ptr->redirected = 0;}
+ int  redir_cmdline_parse (const char *args, cmdline_t *ptr)
+ {
+   return -1;
+ }
+ int redir_to_child (cmdline_t *ptr)
+ {
+   return 1;
+ }
+ int redir_to_debugger (cmdline_t *ptr)
+ {
+   return 1;
+ }
+ int redir_debug_init (cmdline_t *ptr) { return 0; }
  #endif /* __DJGPP_MINOR < 3 */
  
  extern void _initialize_go32_nat (void);
*************** print_387_status (unsigned short status,
*** 197,204 ****
      }
  
    print_387_control_word (ep->control & 0xffff);
!   printf_unfiltered ("last exception: ");
!   printf_unfiltered ("opcode %s; ", local_hex_string (ep->opcode));
    printf_unfiltered ("pc %s:", local_hex_string (ep->code_seg));
    printf_unfiltered ("%s; ", local_hex_string (ep->eip));
    printf_unfiltered ("operand %s", local_hex_string (ep->operand_seg));
- --- 224,237 ----
      }
  
    print_387_control_word (ep->control & 0xffff);
!   /* Other platforms say "last exception", but that's not true: the
!      FPU stores the last non-control instruction there.  */
!   printf_unfiltered ("last FP instruction: ");
!   /* The ORing with D800h restores the upper 5 bits of the opcode that
!      are not stored by the FPU (since these bits are the same for all
!      floating-point instructions).  */
!   printf_unfiltered ("opcode %s; ",
! 		     local_hex_string (ep->opcode ? (ep->opcode|0xd800) : 0));
    printf_unfiltered ("pc %s:", local_hex_string (ep->code_seg));
    printf_unfiltered ("%s; ", local_hex_string (ep->eip));
    printf_unfiltered ("operand %s", local_hex_string (ep->operand_seg));
*************** print_387_status (unsigned short status,
*** 206,240 ****
  
    top = (ep->status >> 11) & 7;
  
!   printf_unfiltered ("regno tag   msb          lsb  value\n");
!   for (fpreg = 0; fpreg < 8; fpreg++)
      {
        long double val;
  
        printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : "  ", fpreg);
  
        switch ((ep->tag >> (fpreg * 2)) & 3)
  	{
  	case 0:
! 	  printf_unfiltered ("valid ");
  	  break;
  	case 1:
! 	  printf_unfiltered ("zero  ");
  	  break;
  	case 2:
! 	  printf_unfiltered ("trap  ");
  	  break;
  	case 3:
! 	  printf_unfiltered ("empty ");
  	  break;
  	}
!       for (i = 0; i < 8; i++)
! 	printf_unfiltered ("%02x", ep->regs[fpreg][i]);
  
!       REGISTER_CONVERT_TO_VIRTUAL (FP0_REGNUM + fpreg, builtin_type_long_double,
! 				   &ep->regs[fpreg], &val);
  
!       printf_unfiltered ("  %LG\n", val);
      }
  }
  
- --- 239,282 ----
  
    top = (ep->status >> 11) & 7;
  
!   printf_unfiltered ("regno tag     msb              lsb  value\n");
!   for (fpreg = 7; fpreg >= 0; fpreg--)
      {
+       /* FNSAVE saves the FP registers in their logical TOP-relative
+ 	 order, beginning with ST(0).  Since we need to print them in
+ 	 their physical order, we have to remap them.  */
+       int  regno = fpreg - top;
        long double val;
  
+       if (regno < 0)
+ 	regno += 8;
+ 
        printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : "  ", fpreg);
  
        switch ((ep->tag >> (fpreg * 2)) & 3)
  	{
  	case 0:
! 	  printf_unfiltered ("valid   ");
  	  break;
  	case 1:
! 	  printf_unfiltered ("zero    ");
  	  break;
  	case 2:
! 	  /* All other versions of print_387_status use TRAP here, but I
! 	     think this is misleading, since Intel manuals say SPECIAL.  */
! 	  printf_unfiltered ("special ");
  	  break;
  	case 3:
! 	  printf_unfiltered ("empty   ");
  	  break;
  	}
!       for (i = 9; i >= 0; i--)
! 	printf_unfiltered ("%02x", ep->regs[regno][i]);
  
!       REGISTER_CONVERT_TO_VIRTUAL (FP0_REGNUM+regno, builtin_type_long_double,
! 				   &ep->regs[regno], &val);
  
!       printf_unfiltered ("  %.19LG\n", val);
      }
  }
  
*************** i386_go32_float_info (void)
*** 244,259 ****
    print_387_status (0, (struct env387 *) &npx);
  }
  
! #define r_ofs(x) ((int)(&(((TSS *)0)->x)))
  
  static struct
  {
!   int tss_ofs;
!   int size;
  }
  regno_mapping[] =
  {
!   r_ofs (tss_eax), 4,
    r_ofs (tss_ecx), 4,
    r_ofs (tss_edx), 4,
    r_ofs (tss_ebx), 4,
- --- 286,301 ----
    print_387_status (0, (struct env387 *) &npx);
  }
  
! #define r_ofs(x) (offsetof(TSS,x))
  
  static struct
  {
!   size_t tss_ofs;
!   size_t size;
  }
  regno_mapping[] =
  {
!   r_ofs (tss_eax), 4,	/* normal registers, from a_tss */
    r_ofs (tss_ecx), 4,
    r_ofs (tss_edx), 4,
    r_ofs (tss_ebx), 4,
*************** regno_mapping[] =
*** 269,275 ****
    r_ofs (tss_es), 2,
    r_ofs (tss_fs), 2,
    r_ofs (tss_gs), 2,
!   0, 10,
    1, 10,
    2, 10,
    3, 10,
- --- 311,317 ----
    r_ofs (tss_es), 2,
    r_ofs (tss_fs), 2,
    r_ofs (tss_gs), 2,
!   0, 10,		/* 8 FP registers, from npx.reg[] */
    1, 10,
    2, 10,
    3, 10,
*************** regno_mapping[] =
*** 277,289 ****
    5, 10,
    6, 10,
    7, 10,
!   0, 2,
!   4, 2,
!   8, 2,
!   12, 4,
!   16, 2,
!   20, 4,
!   24, 2
  };
  
  static struct
- --- 319,333 ----
    5, 10,
    6, 10,
    7, 10,
! 	/* The order of the next 7 registers must be consistent
! 	   with their numbering in config/i386/tm-go32.h, which see.  */
!   0, 2,			/* control word, from npx */
!   4, 2,			/* status word, from npx */
!   8, 2,			/* tag word, from npx */
!   16, 2,		/* last FP exception CS from npx */
!   24, 2,		/* last FP exception operand selector from npx */
!   12, 4,		/* last FP exception EIP from npx */
!   20, 4			/* last FP exception operand offset from npx */
  };
  
  static struct
*************** sig_map[] =
*** 295,301 ****
  {
    0, TARGET_SIGNAL_FPE,
    1, TARGET_SIGNAL_TRAP,
!   2, TARGET_SIGNAL_UNKNOWN,
    3, TARGET_SIGNAL_TRAP,
    4, TARGET_SIGNAL_FPE,
    5, TARGET_SIGNAL_SEGV,
- --- 339,348 ----
  {
    0, TARGET_SIGNAL_FPE,
    1, TARGET_SIGNAL_TRAP,
!   /* Exception 2 is triggered by the NMI.  DJGPP handles it as SIGILL,
!      but I think SIGBUS is better, since the NMI is usually activated
!      as a result of a memory parity check failure.  */
!   2, TARGET_SIGNAL_BUS,
    3, TARGET_SIGNAL_TRAP,
    4, TARGET_SIGNAL_FPE,
    5, TARGET_SIGNAL_SEGV,
*************** sig_map[] =
*** 306,325 ****
    10, TARGET_SIGNAL_BUS,
    11, TARGET_SIGNAL_SEGV,
    12, TARGET_SIGNAL_SEGV,
!   13, TARGET_SIGNAL_ABRT,
    14, TARGET_SIGNAL_SEGV,
    16, TARGET_SIGNAL_FPE,
    31, TARGET_SIGNAL_ILL,
    0x75, TARGET_SIGNAL_FPE,
    0x79, TARGET_SIGNAL_INT,
!   0x1b, TARGET_SIGNAL_INT,
    -1, -1
  };
  
  static void
  go32_open (char *name, int from_tty)
  {
!   printf_unfiltered ("Use the `run' command to run go32 programs\n");
  }
  
  static void
- --- 353,392 ----
    10, TARGET_SIGNAL_BUS,
    11, TARGET_SIGNAL_SEGV,
    12, TARGET_SIGNAL_SEGV,
!   13, TARGET_SIGNAL_SEGV,
    14, TARGET_SIGNAL_SEGV,
    16, TARGET_SIGNAL_FPE,
+   17, TARGET_SIGNAL_BUS,
    31, TARGET_SIGNAL_ILL,
+   0x1b, TARGET_SIGNAL_INT,
    0x75, TARGET_SIGNAL_FPE,
+   0x78, TARGET_SIGNAL_ALRM,
    0x79, TARGET_SIGNAL_INT,
!   0x7a, TARGET_SIGNAL_QUIT,
    -1, -1
  };
  
+ static struct {
+   enum target_signal gdb_sig;
+   int djgpp_excepno;
+ } excepn_map[] = {
+   TARGET_SIGNAL_0, -1,
+   TARGET_SIGNAL_ILL, 6,		/* Invalid Opcode */
+   TARGET_SIGNAL_TRAP, 1,	/* Debug */
+   TARGET_SIGNAL_BUS, 17,	/* Alignment Check */
+   TARGET_SIGNAL_SEGV, 13,	/* GPF */
+   TARGET_SIGNAL_FPE, 0x75,	/* this and the rest are fake exceptions */
+   TARGET_SIGNAL_INT, 0x79,	/* see dpmiexcp.c in djlsr*.zip for details */
+   TARGET_SIGNAL_QUIT, 0x7a,
+   TARGET_SIGNAL_ALRM, 0x78,
+   TARGET_SIGNAL_PROF, 0x78,
+   0, 0
+ };
+ 
  static void
  go32_open (char *name, int from_tty)
  {
!   printf_unfiltered ("Done.  Use the \"run\" command to run the program.\n");
  }
  
  static void
*************** go32_close (int quitting)
*** 330,336 ****
  static void
  go32_attach (char *args, int from_tty)
  {
!   printf_unfiltered ("Use the `run' command to run go32 programs\n");
  }
  
  static void
- --- 397,405 ----
  static void
  go32_attach (char *args, int from_tty)
  {
!   error ("\
! You cannot attach to a running program on this platform.\n\
! Use the `run' command to run DJGPP programs.");
  }
  
  static void
*************** go32_detach (char *args, int from_tty)
*** 339,350 ****
  }
  
  static int resume_is_step;
  
  static void
  go32_resume (int pid, int step, enum target_signal siggnal)
!   {
!     resume_is_step = step;
!   }
  
  static int
  go32_wait (int pid, struct target_waitstatus *status)
- --- 408,431 ----
  }
  
  static int resume_is_step;
+ static int resume_signal = -1;
  
  static void
  go32_resume (int pid, int step, enum target_signal siggnal)
! {
!   int i;
! 
!   resume_is_step = step;
! 
!   for (i = 0, resume_signal = -1; excepn_map[i].gdb_sig != 0; i++)
!     if (excepn_map[i].gdb_sig == siggnal)
!       {
! 	resume_signal = excepn_map[i].djgpp_excepno;
! 	break;
!       }
! }
! 
! static char child_cwd[FILENAME_MAX];
  
  static int
  go32_wait (int pid, struct target_waitstatus *status)
*************** go32_wait (int pid, struct target_waitst
*** 355,369 ****
      a_tss.tss_eflags |= 0x0100;
    else
      a_tss.tss_eflags &= 0xfeff;
  
  #if __DJGPP_MINOR__ < 3
!   save_npx ();
  #endif
    run_child ();
  #if __DJGPP_MINOR__ < 3
!   load_npx ();
  #endif
  
    if (a_tss.tss_irqn == 0x21)
      {
        status->kind = TARGET_WAITKIND_EXITED;
- --- 436,471 ----
      a_tss.tss_eflags |= 0x0100;
    else
      a_tss.tss_eflags &= 0xfeff;
+   if (resume_signal <= -1)
+     a_tss.tss_trap = 0;
+   else
+     {
+       /* FIXME: this doesn't seem to work for all signals.  SIGSEGV
+          and SIGTRAP do work, but SIGFPE and SIGBUS don't.  Why?  */
+       a_tss.tss_trap = 0xffff;	/* run_child looks for this */
+       a_tss.tss_irqn = resume_signal;
+     }
+ 
+   /* The child might change working directory behind our back.  The
+      GDB users won't like the side effects of that when they work with
+      relative file names, and GDB might be confused by its current
+      directory not being in sync with the truth.  So we always make a
+      point of changing back to where GDB thinks is its cwd, when we
+      return control to the debugger, but restore child's cwd before we
+      run it.  */
+   chdir (child_cwd);
  
  #if __DJGPP_MINOR__ < 3
!   load_npx ();
  #endif
    run_child ();
  #if __DJGPP_MINOR__ < 3
!   save_npx ();
  #endif
  
+   getcwd (child_cwd, sizeof (child_cwd)); /* in case it has changed */
+   chdir (current_directory);
+ 
    if (a_tss.tss_irqn == 0x21)
      {
        status->kind = TARGET_WAITKIND_EXITED;
*************** go32_wait (int pid, struct target_waitst
*** 377,385 ****
- --- 479,491 ----
  	{
  	  if (a_tss.tss_irqn == sig_map[i].go32_sig)
  	    {
+ #if __DJGPP_MINOR__ < 3
  	      if ((status->value.sig = sig_map[i].gdb_sig) !=
  		  TARGET_SIGNAL_TRAP)
  		status->kind = TARGET_WAITKIND_SIGNALLED;
+ #else
+ 	      status->value.sig = sig_map[i].gdb_sig;
+ #endif
  	      break;
  	    }
  	}
*************** go32_fetch_registers (int regno)
*** 410,422 ****
  			 (char *) &npx.reg[regno_mapping[regno].tss_ofs]);
        else if (regno < 31)
  	supply_register (regno,
! 			 (char *) &npx.reg + regno_mapping[regno].tss_ofs);
        else
! 	{
! 	  printf_unfiltered ("Invalid register in go32_fetch_register(%d)",
! 			     regno);
! 	  exit (1);
! 	}
      }
  }
  
- --- 516,524 ----
  			 (char *) &npx.reg[regno_mapping[regno].tss_ofs]);
        else if (regno < 31)
  	supply_register (regno,
! 			 (char *) &npx + regno_mapping[regno].tss_ofs);
        else
! 	fatal ("Invalid register no. %d in go32_fetch_register.", regno);
      }
  }
  
*************** store_register (int regno)
*** 430,442 ****
      rp = (char *) &a_tss + regno_mapping[regno].tss_ofs;
    else if (regno < 24)
      rp = (char *) &npx.reg[regno_mapping[regno].tss_ofs];
!   else if (regno > 31)
      rp = (char *) &npx + regno_mapping[regno].tss_ofs;
    else
!     {
!       printf_unfiltered ("Invalid register in store_register(%d)", regno);
!       exit (1);
!     }
    memcpy (rp, v, regno_mapping[regno].size);
  }
  
- --- 532,541 ----
      rp = (char *) &a_tss + regno_mapping[regno].tss_ofs;
    else if (regno < 24)
      rp = (char *) &npx.reg[regno_mapping[regno].tss_ofs];
!   else if (regno < 31)
      rp = (char *) &npx + regno_mapping[regno].tss_ofs;
    else
!     fatal ("Invalid register no. %d in store_register.", regno);
    memcpy (rp, v, regno_mapping[regno].size);
  }
  
*************** go32_xfer_memory (CORE_ADDR memaddr, cha
*** 487,496 ****
      }
  }
  
  static void
  go32_files_info (struct target_ops *target)
  {
!   printf_unfiltered ("You are running a DJGPP V2 program\n");
  }
  
  static void
- --- 586,597 ----
      }
  }
  
+ static cmdline_t child_cmd;	/* parsed child's command line kept here */
+ 
  static void
  go32_files_info (struct target_ops *target)
  {
!   printf_unfiltered ("You are running a DJGPP V2 program.\n");
  }
  
  static void
*************** go32_stop (void)
*** 505,510 ****
- --- 606,614 ----
  static void
  go32_kill_inferior (void)
  {
+   redir_cmdline_delete (&child_cmd);
+   resume_signal = -1;
+   resume_is_step = 0;
    unpush_target (&go32_ops);
  }
  
*************** go32_create_inferior (char *exec_file, c
*** 520,525 ****
- --- 624,645 ----
        go32_stop ();
        go32_kill_inferior ();
      }
+   resume_signal = -1;
+   resume_is_step = 0;
+   /* Init command line storage.  */
+   if (redir_debug_init (&child_cmd) == -1)
+     fatal ("Cannot allocate redirection storage: not enough memory.\n");
+ 
+   /* Parse the command line and create redirections.  */
+   if (strpbrk (args, "<>"))
+     {
+       if (redir_cmdline_parse (args, &child_cmd) == 0)
+ 	args = child_cmd.command;
+       else
+ 	error ("Syntax error in command line.");
+     }
+   else
+     child_cmd.command = strdup (args);
  
    cmdline = (char *) alloca (strlen (args) + 4);
    cmdline[0] = strlen (args);
*************** go32_create_inferior (char *exec_file, c
*** 537,542 ****
- --- 657,665 ----
    environ = env_save;
  
    edi_init (start_state);
+ #if __DJGPP_MINOR__ < 3
+   save_npx ();
+ #endif
  
    inferior_pid = SOME_PID;
    push_target (&go32_ops);
*************** ignore (void)
*** 564,574 ****
  {
  }
  
- - static void
- - ignore2 (char *a, int b)
- - {
- - }
- - 
  /* Hardware watchpoint support.  */
  
  #define DR_STATUS 6
- --- 687,692 ----
*************** go32_insert_hw_breakpoint (CORE_ADDR add
*** 818,856 ****
    return 0;
  }
  
! static int inf_flags_valid = 0;
! static int inf_in_flag;
! static int inf_out_flag;
  
  static void
  go32_terminal_init (void)
  {
!   /* Save the filemodes for stdin/stout */
!   inf_in_flag = setmode(0, 0);
!   setmode(0, inf_in_flag);
!   inf_out_flag = setmode(1, 0);
!   setmode(1, inf_out_flag);
!   inf_flags_valid = 1;
  }
  
  static void
  go32_terminal_inferior (void)
  {
!   /* set the filemodes for stdin/stdout of the inferior */
!   if (inf_flags_valid)
!   {
!     setmode(0, inf_in_flag);
!     setmode(1, inf_out_flag);
!   }
  }
  
  static void
  go32_terminal_ours (void)
  {
!   /* Switch to text mode on stdin/stdout always on the gdb terminal and
!      save the inferior modes to be restored later */
!   inf_in_flag = setmode(0, O_TEXT);
!   inf_out_flag = setmode(1, O_TEXT);
  }
  
  static void
- --- 936,1067 ----
    return 0;
  }
  
! /* Put the device open on handle FD into either raw or cooked
!    mode, return 1 if it was in raw mode, zero otherwise.  */
! 
! static int
! device_mode (int fd, int raw_p)
! {
!   int oldmode, newmode;
!   __dpmi_regs regs;
! 
!   regs.x.ax = 0x4400;
!   regs.x.bx = fd;
!   __dpmi_int(0x21, &regs);
!   if (regs.x.flags & 1)
!     return -1;
!   newmode = oldmode = regs.x.dx;
! 
!   if (raw_p)
!     newmode |= 0x20;
!   else
!     newmode &= ~0x20;
! 
!   if (oldmode & 0x80)	/* Only for character dev */
!   {
!     regs.x.ax = 0x4401;
!     regs.x.bx = fd;
!     regs.x.dx = newmode & 0xff;   /* Force upper byte zero, else it fails */
!     __dpmi_int(0x21, &regs);
!     if (regs.x.flags & 1)
!       return -1;
!   }
!   return (oldmode & 0x20) == 0x20;
! }
! 
! 
! static int inf_mode_valid = 0;
! static int inf_terminal_mode;
! 
! /* This semaphore is needed because, amazingly enough, GDB calls
!    target.to_terminal_ours more than once after the inferior stops.
!    But we need the information from the first call only, since the
!    second call will always see GDB's own cooked terminal.  */
! static int terminal_is_ours = 1;
  
  static void
  go32_terminal_init (void)
  {
!   inf_mode_valid = 0;	/* reinitialize, in case they are restarting child */
!   terminal_is_ours = 1;
! }
! 
! static void
! go32_terminal_info (char *args, int from_tty)
! {
!   printf_unfiltered ("Inferior's terminal is in %s mode.\n",
! 		     !inf_mode_valid
! 		     ? "default" : inf_terminal_mode ? "raw" : "cooked");
! 
! #if __DJGPP_MINOR__ > 2
!   if (child_cmd.redirection)
!     {
!       int i;
! 
!       for (i = 0; i < DBG_HANDLES; i++)
! 	{
! 	  if (child_cmd.redirection[i]->file_name)
! 	    printf_unfiltered ("\tFile handle %d is redirected to `%s'.\n",
! 			       i, child_cmd.redirection[i]->file_name);
! 	  else if (_get_dev_info(child_cmd.redirection[i]->inf_handle) == -1)
! 	    printf_unfiltered
! 	      ("\tFile handle %d appears to be closed by inferior.\n", i);
! 	  /* Mask off the raw/cooked bit when comparing device info words.  */
! 	  else if ((_get_dev_info(child_cmd.redirection[i]->inf_handle) & 0xdf)
! 		   != (_get_dev_info(i) & 0xdf))
! 	    printf_unfiltered
! 	      ("\tFile handle %d appears to be redirected by inferior.\n", i);
! 	}
!     }
! #endif
  }
  
  static void
  go32_terminal_inferior (void)
  {
!   /* Redirect standard handles as child wants them.  */
!   errno = 0;
!   if (redir_to_child (&child_cmd) == -1)
!     {
!       redir_to_debugger (&child_cmd);
!       error ("Cannot redirect standard handles for program: %s.",
! 	     strerror (errno));
!     }
!   /* set the console device of the inferior to whatever mode
!      (raw or cooked) we found it last time */
!   if (terminal_is_ours)
!     {
!       if (inf_mode_valid)
! 	device_mode (0, inf_terminal_mode);
!       terminal_is_ours = 0;
!     }
  }
  
  static void
  go32_terminal_ours (void)
  {
!   /* Switch to cooked mode on the gdb terminal and save the inferior
!      terminal mode to be restored when it is resumed */
!   if (!terminal_is_ours)
!     {
!       inf_terminal_mode = device_mode (0, 0);
!       if (inf_terminal_mode != -1)
! 	inf_mode_valid = 1;
!       else
! 	/* If device_mode returned -1, we don't know what happens with
! 	   handle 0 anymore, so make the info invalid.  */
! 	inf_mode_valid = 0;
!       terminal_is_ours = 1;
! 
!       /* Restore debugger's standard handles.  */
!       errno = 0;
!       if (redir_to_debugger (&child_cmd) == -1)
! 	{
! 	  redir_to_child (&child_cmd);
! 	  error ("Cannot redirect standard handles for debugger: %s.",
! 		 strerror (errno));
! 	}
!     }
  }
  
  static void
*************** init_go32_ops (void)
*** 862,867 ****
- --- 1073,1079 ----
      "Program loaded by djgpp, when gdb is used as an external debugger";
    go32_ops.to_open = go32_open;
    go32_ops.to_close = go32_close;
+   go32_ops.to_attach = go32_attach;
    go32_ops.to_detach = go32_detach;
    go32_ops.to_resume = go32_resume;
    go32_ops.to_wait = go32_wait;
*************** init_go32_ops (void)
*** 874,882 ****
    go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
    go32_ops.to_terminal_init = go32_terminal_init;
    go32_ops.to_terminal_inferior = go32_terminal_inferior;
!   go32_ops.to_terminal_ours_for_output = ignore;
    go32_ops.to_terminal_ours = go32_terminal_ours;
!   go32_ops.to_terminal_info = ignore2;
    go32_ops.to_kill = go32_kill_inferior;
    go32_ops.to_create_inferior = go32_create_inferior;
    go32_ops.to_mourn_inferior = go32_mourn_inferior;
- --- 1086,1094 ----
    go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
    go32_ops.to_terminal_init = go32_terminal_init;
    go32_ops.to_terminal_inferior = go32_terminal_inferior;
!   go32_ops.to_terminal_ours_for_output = go32_terminal_ours;
    go32_ops.to_terminal_ours = go32_terminal_ours;
!   go32_ops.to_terminal_info = go32_terminal_info;
    go32_ops.to_kill = go32_kill_inferior;
    go32_ops.to_create_inferior = go32_create_inferior;
    go32_ops.to_mourn_inferior = go32_mourn_inferior;
*************** init_go32_ops (void)
*** 889,894 ****
- --- 1101,1113 ----
    go32_ops.to_has_registers = 1;
    go32_ops.to_has_execution = 1;
    go32_ops.to_magic = OPS_MAGIC;
+ 
+   /* Initialize child's cwd with the current one.  */
+   getcwd (child_cwd, sizeof (child_cwd));
+ 
+   /* Initialize child's command line storage.  */
+   if (redir_debug_init (&child_cmd) == -1)
+     fatal ("Cannot allocate redirection storage: not enough memory.\n");
  }
  
  void
------- End of forwarded message -------

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]