1 /* Native debugging support for Intel x86 running DJGPP.
2 Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
3 Written by Robert Hoehne.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
30 #include "floatformat.h"
35 #include "gdb_string.h"
37 #include <stdio.h> /* might be required for __DJGPP_MINOR__ */
42 #include <sys/utsname.h>
44 /* breakpoint.h defines `disable' which is an enum member. */
45 #define disable interrup_disable
50 #include <debug/v2load.h>
51 #include <debug/dbgcom.h>
52 #if __DJGPP_MINOR__ > 2
53 #include <debug/redir.h>
56 #if __DJGPP_MINOR__ < 3
57 /* This code will be provided from DJGPP 2.03 on. Until then I code it
65 unsigned short exponent
:15;
66 unsigned short sign
:1;
85 static void save_npx (void); /* Save the FPU of the debugged program */
86 static void load_npx (void); /* Restore the FPU of the debugged program */
88 /* ------------------------------------------------------------------------- */
89 /* Store the contents of the NPX in the global variable `npx'. */
117 /* ------------------------------------------------------------------------- */
118 /* Reload the contents of the NPX from the global variable `npx'. */
123 asm ("frstor %0":"=m" (npx
));
125 /* ------------------------------------------------------------------------- */
126 /* Stubs for the missing redirection functions. */
133 redir_cmdline_delete (cmdline_t
*ptr
)
139 redir_cmdline_parse (const char *args
, cmdline_t
*ptr
)
145 redir_to_child (cmdline_t
*ptr
)
151 redir_to_debugger (cmdline_t
*ptr
)
157 redir_debug_init (cmdline_t
*ptr
)
161 #endif /* __DJGPP_MINOR < 3 */
163 typedef enum { wp_insert
, wp_remove
, wp_count
} wp_op
;
165 /* This holds the current reference counts for each debug register. */
166 static int dr_ref_count
[4];
170 static int prog_has_started
= 0;
171 static void go32_open (char *name
, int from_tty
);
172 static void go32_close (int quitting
);
173 static void go32_attach (char *args
, int from_tty
);
174 static void go32_detach (char *args
, int from_tty
);
175 static void go32_resume (ptid_t ptid
, int step
,
176 enum target_signal siggnal
);
177 static ptid_t
go32_wait (ptid_t ptid
,
178 struct target_waitstatus
*status
);
179 static void go32_fetch_registers (int regno
);
180 static void store_register (int regno
);
181 static void go32_store_registers (int regno
);
182 static void go32_prepare_to_store (void);
183 static int go32_xfer_memory (CORE_ADDR memaddr
, char *myaddr
, int len
,
185 struct mem_attrib
*attrib
,
186 struct target_ops
*target
);
187 static void go32_files_info (struct target_ops
*target
);
188 static void go32_stop (void);
189 static void go32_kill_inferior (void);
190 static void go32_create_inferior (char *exec_file
, char *args
, char **env
);
191 static void go32_mourn_inferior (void);
192 static int go32_can_run (void);
194 static struct target_ops go32_ops
;
195 static void go32_terminal_init (void);
196 static void go32_terminal_inferior (void);
197 static void go32_terminal_ours (void);
199 #define r_ofs(x) (offsetof(TSS,x))
208 {r_ofs (tss_eax
), 4}, /* normal registers, from a_tss */
209 {r_ofs (tss_ecx
), 4},
210 {r_ofs (tss_edx
), 4},
211 {r_ofs (tss_ebx
), 4},
212 {r_ofs (tss_esp
), 4},
213 {r_ofs (tss_ebp
), 4},
214 {r_ofs (tss_esi
), 4},
215 {r_ofs (tss_edi
), 4},
216 {r_ofs (tss_eip
), 4},
217 {r_ofs (tss_eflags
), 4},
224 {0, 10}, /* 8 FP registers, from npx.reg[] */
232 /* The order of the next 7 registers must be consistent
233 with their numbering in config/i386/tm-i386.h, which see. */
234 {0, 2}, /* control word, from npx */
235 {4, 2}, /* status word, from npx */
236 {8, 2}, /* tag word, from npx */
237 {16, 2}, /* last FP exception CS from npx */
238 {12, 4}, /* last FP exception EIP from npx */
239 {24, 2}, /* last FP exception operand selector from npx */
240 {20, 4}, /* last FP exception operand offset from npx */
241 {18, 2} /* last FP opcode from npx */
247 enum target_signal gdb_sig
;
251 {0, TARGET_SIGNAL_FPE
},
252 {1, TARGET_SIGNAL_TRAP
},
253 /* Exception 2 is triggered by the NMI. DJGPP handles it as SIGILL,
254 but I think SIGBUS is better, since the NMI is usually activated
255 as a result of a memory parity check failure. */
256 {2, TARGET_SIGNAL_BUS
},
257 {3, TARGET_SIGNAL_TRAP
},
258 {4, TARGET_SIGNAL_FPE
},
259 {5, TARGET_SIGNAL_SEGV
},
260 {6, TARGET_SIGNAL_ILL
},
261 {7, TARGET_SIGNAL_EMT
}, /* no-coprocessor exception */
262 {8, TARGET_SIGNAL_SEGV
},
263 {9, TARGET_SIGNAL_SEGV
},
264 {10, TARGET_SIGNAL_BUS
},
265 {11, TARGET_SIGNAL_SEGV
},
266 {12, TARGET_SIGNAL_SEGV
},
267 {13, TARGET_SIGNAL_SEGV
},
268 {14, TARGET_SIGNAL_SEGV
},
269 {16, TARGET_SIGNAL_FPE
},
270 {17, TARGET_SIGNAL_BUS
},
271 {31, TARGET_SIGNAL_ILL
},
272 {0x1b, TARGET_SIGNAL_INT
},
273 {0x75, TARGET_SIGNAL_FPE
},
274 {0x78, TARGET_SIGNAL_ALRM
},
275 {0x79, TARGET_SIGNAL_INT
},
276 {0x7a, TARGET_SIGNAL_QUIT
},
277 {-1, TARGET_SIGNAL_LAST
}
281 enum target_signal gdb_sig
;
284 {TARGET_SIGNAL_0
, -1},
285 {TARGET_SIGNAL_ILL
, 6}, /* Invalid Opcode */
286 {TARGET_SIGNAL_EMT
, 7}, /* triggers SIGNOFP */
287 {TARGET_SIGNAL_SEGV
, 13}, /* GPF */
288 {TARGET_SIGNAL_BUS
, 17}, /* Alignment Check */
289 /* The rest are fake exceptions, see dpmiexcp.c in djlsr*.zip for
291 {TARGET_SIGNAL_TERM
, 0x1b}, /* triggers Ctrl-Break type of SIGINT */
292 {TARGET_SIGNAL_FPE
, 0x75},
293 {TARGET_SIGNAL_INT
, 0x79},
294 {TARGET_SIGNAL_QUIT
, 0x7a},
295 {TARGET_SIGNAL_ALRM
, 0x78}, /* triggers SIGTIMR */
296 {TARGET_SIGNAL_PROF
, 0x78},
297 {TARGET_SIGNAL_LAST
, -1}
301 go32_open (char *name
, int from_tty
)
303 printf_unfiltered ("Done. Use the \"run\" command to run the program.\n");
307 go32_close (int quitting
)
312 go32_attach (char *args
, int from_tty
)
315 You cannot attach to a running program on this platform.\n\
316 Use the `run' command to run DJGPP programs.");
320 go32_detach (char *args
, int from_tty
)
324 static int resume_is_step
;
325 static int resume_signal
= -1;
328 go32_resume (ptid_t ptid
, int step
, enum target_signal siggnal
)
332 resume_is_step
= step
;
334 if (siggnal
!= TARGET_SIGNAL_0
&& siggnal
!= TARGET_SIGNAL_TRAP
)
336 for (i
= 0, resume_signal
= -1;
337 excepn_map
[i
].gdb_sig
!= TARGET_SIGNAL_LAST
; i
++)
338 if (excepn_map
[i
].gdb_sig
== siggnal
)
340 resume_signal
= excepn_map
[i
].djgpp_excepno
;
343 if (resume_signal
== -1)
344 printf_unfiltered ("Cannot deliver signal %s on this platform.\n",
345 target_signal_to_name (siggnal
));
349 static char child_cwd
[FILENAME_MAX
];
352 go32_wait (ptid_t ptid
, struct target_waitstatus
*status
)
355 unsigned char saved_opcode
;
356 unsigned long INT3_addr
= 0;
357 int stepping_over_INT
= 0;
359 a_tss
.tss_eflags
&= 0xfeff; /* reset the single-step flag (TF) */
362 /* If the next instruction is INT xx or INTO, we need to handle
363 them specially. Intel manuals say that these instructions
364 reset the single-step flag (a.k.a. TF). However, it seems
365 that, at least in the DPMI environment, and at least when
366 stepping over the DPMI interrupt 31h, the problem is having
367 TF set at all when INT 31h is executed: the debuggee either
368 crashes (and takes the system with it) or is killed by a
371 So we need to emulate single-step mode: we put an INT3 opcode
372 right after the INT xx instruction, let the debuggee run
373 until it hits INT3 and stops, then restore the original
374 instruction which we overwrote with the INT3 opcode, and back
375 up the debuggee's EIP to that instruction. */
376 read_child (a_tss
.tss_eip
, &saved_opcode
, 1);
377 if (saved_opcode
== 0xCD || saved_opcode
== 0xCE)
379 unsigned char INT3_opcode
= 0xCC;
382 = saved_opcode
== 0xCD ? a_tss
.tss_eip
+ 2 : a_tss
.tss_eip
+ 1;
383 stepping_over_INT
= 1;
384 read_child (INT3_addr
, &saved_opcode
, 1);
385 write_child (INT3_addr
, &INT3_opcode
, 1);
388 a_tss
.tss_eflags
|= 0x0100; /* normal instruction: set TF */
391 /* The special value FFFFh in tss_trap indicates to run_child that
392 tss_irqn holds a signal to be delivered to the debuggee. */
393 if (resume_signal
<= -1)
396 a_tss
.tss_irqn
= 0xff;
400 a_tss
.tss_trap
= 0xffff; /* run_child looks for this */
401 a_tss
.tss_irqn
= resume_signal
;
404 /* The child might change working directory behind our back. The
405 GDB users won't like the side effects of that when they work with
406 relative file names, and GDB might be confused by its current
407 directory not being in sync with the truth. So we always make a
408 point of changing back to where GDB thinks is its cwd, when we
409 return control to the debugger, but restore child's cwd before we
411 /* Initialize child_cwd, before the first call to run_child and not
412 in the initialization, so the child get also the changed directory
413 set with the gdb-command "cd ..." */
415 /* Initialize child's cwd with the current one. */
416 getcwd (child_cwd
, sizeof (child_cwd
));
420 #if __DJGPP_MINOR__ < 3
424 #if __DJGPP_MINOR__ < 3
428 /* Did we step over an INT xx instruction? */
429 if (stepping_over_INT
&& a_tss
.tss_eip
== INT3_addr
+ 1)
431 /* Restore the original opcode. */
432 a_tss
.tss_eip
--; /* EIP points *after* the INT3 instruction */
433 write_child (a_tss
.tss_eip
, &saved_opcode
, 1);
434 /* Simulate a TRAP exception. */
436 a_tss
.tss_eflags
|= 0x0100;
439 getcwd (child_cwd
, sizeof (child_cwd
)); /* in case it has changed */
440 chdir (current_directory
);
442 if (a_tss
.tss_irqn
== 0x21)
444 status
->kind
= TARGET_WAITKIND_EXITED
;
445 status
->value
.integer
= a_tss
.tss_eax
& 0xff;
449 status
->value
.sig
= TARGET_SIGNAL_UNKNOWN
;
450 status
->kind
= TARGET_WAITKIND_STOPPED
;
451 for (i
= 0; sig_map
[i
].go32_sig
!= -1; i
++)
453 if (a_tss
.tss_irqn
== sig_map
[i
].go32_sig
)
455 #if __DJGPP_MINOR__ < 3
456 if ((status
->value
.sig
= sig_map
[i
].gdb_sig
) !=
458 status
->kind
= TARGET_WAITKIND_SIGNALLED
;
460 status
->value
.sig
= sig_map
[i
].gdb_sig
;
466 return pid_to_ptid (SOME_PID
);
470 fetch_register (int regno
)
472 if (regno
< FP0_REGNUM
)
473 supply_register (regno
, (char *) &a_tss
+ regno_mapping
[regno
].tss_ofs
);
474 else if (regno
<= LAST_FPU_CTRL_REGNUM
)
475 i387_supply_register (regno
, (char *) &npx
);
477 internal_error (__FILE__
, __LINE__
,
478 "Invalid register no. %d in fetch_register.", regno
);
482 go32_fetch_registers (int regno
)
485 fetch_register (regno
);
488 for (regno
= 0; regno
< FP0_REGNUM
; regno
++)
489 fetch_register (regno
);
490 i387_supply_fsave ((char *) &npx
);
495 store_register (int regno
)
498 void *v
= (void *) register_buffer (regno
);
500 if (regno
< FP0_REGNUM
)
501 memcpy ((char *) &a_tss
+ regno_mapping
[regno
].tss_ofs
,
502 v
, regno_mapping
[regno
].size
);
503 else if (regno
<= LAST_FPU_CTRL_REGNUM
)
504 i387_fill_fsave ((char *)&npx
, regno
);
506 internal_error (__FILE__
, __LINE__
,
507 "Invalid register no. %d in store_register.", regno
);
511 go32_store_registers (int regno
)
516 store_register (regno
);
519 for (r
= 0; r
< FP0_REGNUM
; r
++)
521 i387_fill_fsave ((char *) &npx
, -1);
526 go32_prepare_to_store (void)
531 go32_xfer_memory (CORE_ADDR memaddr
, char *myaddr
, int len
, int write
,
532 struct mem_attrib
*attrib
, struct target_ops
*target
)
536 if (write_child (memaddr
, myaddr
, len
))
547 if (read_child (memaddr
, myaddr
, len
))
558 static cmdline_t child_cmd
; /* parsed child's command line kept here */
561 go32_files_info (struct target_ops
*target
)
563 printf_unfiltered ("You are running a DJGPP V2 program.\n");
571 inferior_ptid
= null_ptid
;
572 prog_has_started
= 0;
576 go32_kill_inferior (void)
578 redir_cmdline_delete (&child_cmd
);
581 unpush_target (&go32_ops
);
585 go32_create_inferior (char *exec_file
, char *args
, char **env
)
587 extern char **environ
;
590 char **env_save
= environ
;
593 /* If no exec file handed to us, get it from the exec-file command -- with
594 a good, common error message if none is specified. */
596 exec_file
= get_exec_file (1);
598 if (prog_has_started
)
601 go32_kill_inferior ();
606 /* Initialize child's cwd as empty to be initialized when starting
610 /* Init command line storage. */
611 if (redir_debug_init (&child_cmd
) == -1)
612 internal_error (__FILE__
, __LINE__
,
613 "Cannot allocate redirection storage: not enough memory.\n");
615 /* Parse the command line and create redirections. */
616 if (strpbrk (args
, "<>"))
618 if (redir_cmdline_parse (args
, &child_cmd
) == 0)
619 args
= child_cmd
.command
;
621 error ("Syntax error in command line.");
624 child_cmd
.command
= xstrdup (args
);
626 cmdlen
= strlen (args
);
627 /* v2loadimage passes command lines via DOS memory, so it cannot
628 possibly handle commands longer than 1MB. */
629 if (cmdlen
> 1024*1024)
630 error ("Command line too long.");
632 cmdline
= xmalloc (cmdlen
+ 4);
633 strcpy (cmdline
+ 1, args
);
634 /* If the command-line length fits into DOS 126-char limits, use the
635 DOS command tail format; otherwise, tell v2loadimage to pass it
636 through a buffer in conventional memory. */
639 cmdline
[0] = strlen (args
);
640 cmdline
[cmdlen
+ 1] = 13;
643 cmdline
[0] = 0xff; /* signal v2loadimage it's a long command */
647 if (v2loadimage (exec_file
, cmdline
, start_state
))
650 printf_unfiltered ("Load failed for image %s\n", exec_file
);
656 edi_init (start_state
);
657 #if __DJGPP_MINOR__ < 3
661 inferior_ptid
= pid_to_ptid (SOME_PID
);
662 push_target (&go32_ops
);
663 clear_proceed_status ();
664 insert_breakpoints ();
665 proceed ((CORE_ADDR
) -1, TARGET_SIGNAL_0
, 0);
666 prog_has_started
= 1;
670 go32_mourn_inferior (void)
672 /* We need to make sure all the breakpoint enable bits in the DR7
673 register are reset when the inferior exits. Otherwise, if they
674 rerun the inferior, the uncleared bits may cause random SIGTRAPs,
675 failure to set more watchpoints, and other calamities. It would
676 be nice if GDB itself would take care to remove all breakpoints
677 at all times, but it doesn't, probably under an assumption that
678 the OS cleans up when the debuggee exits. */
679 i386_cleanup_dregs ();
680 go32_kill_inferior ();
681 generic_mourn_inferior ();
690 /* Hardware watchpoint support. */
692 #define D_REGS edi.dr
693 #define CONTROL D_REGS[7]
694 #define STATUS D_REGS[6]
696 /* Pass the address ADDR to the inferior in the I'th debug register.
697 Here we just store the address in D_REGS, the watchpoint will be
698 actually set up when go32_wait runs the debuggee. */
700 go32_set_dr (int i
, CORE_ADDR addr
)
703 internal_error (__FILE__
, __LINE__
,
704 "Invalid register %d in go32_set_dr.\n", i
);
708 /* Pass the value VAL to the inferior in the DR7 debug control
709 register. Here we just store the address in D_REGS, the watchpoint
710 will be actually set up when go32_wait runs the debuggee. */
712 go32_set_dr7 (unsigned val
)
717 /* Get the value of the DR6 debug status register from the inferior.
718 Here we just return the value stored in D_REGS, as we've got it
719 from the last go32_wait call. */
726 /* Put the device open on handle FD into either raw or cooked
727 mode, return 1 if it was in raw mode, zero otherwise. */
730 device_mode (int fd
, int raw_p
)
732 int oldmode
, newmode
;
737 __dpmi_int (0x21, ®s
);
738 if (regs
.x
.flags
& 1)
740 newmode
= oldmode
= regs
.x
.dx
;
747 if (oldmode
& 0x80) /* Only for character dev */
751 regs
.x
.dx
= newmode
& 0xff; /* Force upper byte zero, else it fails */
752 __dpmi_int (0x21, ®s
);
753 if (regs
.x
.flags
& 1)
756 return (oldmode
& 0x20) == 0x20;
760 static int inf_mode_valid
= 0;
761 static int inf_terminal_mode
;
763 /* This semaphore is needed because, amazingly enough, GDB calls
764 target.to_terminal_ours more than once after the inferior stops.
765 But we need the information from the first call only, since the
766 second call will always see GDB's own cooked terminal. */
767 static int terminal_is_ours
= 1;
770 go32_terminal_init (void)
772 inf_mode_valid
= 0; /* reinitialize, in case they are restarting child */
773 terminal_is_ours
= 1;
777 go32_terminal_info (char *args
, int from_tty
)
779 printf_unfiltered ("Inferior's terminal is in %s mode.\n",
781 ? "default" : inf_terminal_mode
? "raw" : "cooked");
783 #if __DJGPP_MINOR__ > 2
784 if (child_cmd
.redirection
)
788 for (i
= 0; i
< DBG_HANDLES
; i
++)
790 if (child_cmd
.redirection
[i
]->file_name
)
791 printf_unfiltered ("\tFile handle %d is redirected to `%s'.\n",
792 i
, child_cmd
.redirection
[i
]->file_name
);
793 else if (_get_dev_info (child_cmd
.redirection
[i
]->inf_handle
) == -1)
795 ("\tFile handle %d appears to be closed by inferior.\n", i
);
796 /* Mask off the raw/cooked bit when comparing device info words. */
797 else if ((_get_dev_info (child_cmd
.redirection
[i
]->inf_handle
) & 0xdf)
798 != (_get_dev_info (i
) & 0xdf))
800 ("\tFile handle %d appears to be redirected by inferior.\n", i
);
807 go32_terminal_inferior (void)
809 /* Redirect standard handles as child wants them. */
811 if (redir_to_child (&child_cmd
) == -1)
813 redir_to_debugger (&child_cmd
);
814 error ("Cannot redirect standard handles for program: %s.",
817 /* set the console device of the inferior to whatever mode
818 (raw or cooked) we found it last time */
819 if (terminal_is_ours
)
822 device_mode (0, inf_terminal_mode
);
823 terminal_is_ours
= 0;
828 go32_terminal_ours (void)
830 /* Switch to cooked mode on the gdb terminal and save the inferior
831 terminal mode to be restored when it is resumed */
832 if (!terminal_is_ours
)
834 inf_terminal_mode
= device_mode (0, 0);
835 if (inf_terminal_mode
!= -1)
838 /* If device_mode returned -1, we don't know what happens with
839 handle 0 anymore, so make the info invalid. */
841 terminal_is_ours
= 1;
843 /* Restore debugger's standard handles. */
845 if (redir_to_debugger (&child_cmd
) == -1)
847 redir_to_child (&child_cmd
);
848 error ("Cannot redirect standard handles for debugger: %s.",
857 go32_ops
.to_shortname
= "djgpp";
858 go32_ops
.to_longname
= "djgpp target process";
860 "Program loaded by djgpp, when gdb is used as an external debugger";
861 go32_ops
.to_open
= go32_open
;
862 go32_ops
.to_close
= go32_close
;
863 go32_ops
.to_attach
= go32_attach
;
864 go32_ops
.to_detach
= go32_detach
;
865 go32_ops
.to_resume
= go32_resume
;
866 go32_ops
.to_wait
= go32_wait
;
867 go32_ops
.to_fetch_registers
= go32_fetch_registers
;
868 go32_ops
.to_store_registers
= go32_store_registers
;
869 go32_ops
.to_prepare_to_store
= go32_prepare_to_store
;
870 go32_ops
.to_xfer_memory
= go32_xfer_memory
;
871 go32_ops
.to_files_info
= go32_files_info
;
872 go32_ops
.to_insert_breakpoint
= memory_insert_breakpoint
;
873 go32_ops
.to_remove_breakpoint
= memory_remove_breakpoint
;
874 go32_ops
.to_terminal_init
= go32_terminal_init
;
875 go32_ops
.to_terminal_inferior
= go32_terminal_inferior
;
876 go32_ops
.to_terminal_ours_for_output
= go32_terminal_ours
;
877 go32_ops
.to_terminal_ours
= go32_terminal_ours
;
878 go32_ops
.to_terminal_info
= go32_terminal_info
;
879 go32_ops
.to_kill
= go32_kill_inferior
;
880 go32_ops
.to_create_inferior
= go32_create_inferior
;
881 go32_ops
.to_mourn_inferior
= go32_mourn_inferior
;
882 go32_ops
.to_can_run
= go32_can_run
;
883 go32_ops
.to_stop
= go32_stop
;
884 go32_ops
.to_stratum
= process_stratum
;
885 go32_ops
.to_has_all_memory
= 1;
886 go32_ops
.to_has_memory
= 1;
887 go32_ops
.to_has_stack
= 1;
888 go32_ops
.to_has_registers
= 1;
889 go32_ops
.to_has_execution
= 1;
890 go32_ops
.to_magic
= OPS_MAGIC
;
892 /* Initialize child's cwd as empty to be initialized when starting
896 /* Initialize child's command line storage. */
897 if (redir_debug_init (&child_cmd
) == -1)
898 internal_error (__FILE__
, __LINE__
,
899 "Cannot allocate redirection storage: not enough memory.\n");
901 /* We are always processing GCC-compiled programs. */
902 processing_gcc_compilation
= 2;
905 unsigned short windows_major
, windows_minor
;
907 /* Compute the version Windows reports via Int 2Fh/AX=1600h. */
909 go32_get_windows_version(void)
914 __dpmi_int(0x2f, &r
);
915 if (r
.h
.al
> 2 && r
.h
.al
!= 0x80 && r
.h
.al
!= 0xff
916 && (r
.h
.al
> 3 || r
.h
.ah
> 0))
918 windows_major
= r
.h
.al
;
919 windows_minor
= r
.h
.ah
;
922 windows_major
= 0xff; /* meaning no Windows */
925 /* A subroutine of go32_sysinfo to display memory info. */
927 print_mem (unsigned long datum
, const char *header
, int in_pages_p
)
929 if (datum
!= 0xffffffffUL
)
933 puts_filtered (header
);
936 printf_filtered ("%lu KB", datum
>> 10);
937 if (datum
> 1024 * 1024)
938 printf_filtered (" (%lu MB)", datum
>> 20);
941 printf_filtered ("%lu Bytes", datum
);
942 puts_filtered ("\n");
946 /* Display assorted information about the underlying OS. */
948 go32_sysinfo (char *arg
, int from_tty
)
951 char cpuid_vendor
[13];
952 unsigned cpuid_max
= 0, cpuid_eax
, cpuid_ebx
, cpuid_ecx
, cpuid_edx
;
953 unsigned true_dos_version
= _get_dos_version (1);
954 unsigned advertized_dos_version
= ((unsigned int)_osmajor
<< 8) | _osminor
;
956 char dpmi_vendor_info
[129];
957 int dpmi_vendor_available
=
958 __dpmi_get_capabilities (&dpmi_flags
, dpmi_vendor_info
);
959 __dpmi_version_ret dpmi_version_data
;
961 __dpmi_free_mem_info mem_info
;
964 cpuid_vendor
[0] = '\0';
966 strcpy (u
.machine
, "Unknown x86");
967 else if (u
.machine
[0] == 'i' && u
.machine
[1] > 4)
969 /* CPUID with EAX = 0 returns the Vendor ID. */
970 __asm__
__volatile__ ("xorl %%ebx, %%ebx;"
979 : "=m" (cpuid_vendor
[0]),
980 "=m" (cpuid_vendor
[4]),
981 "=m" (cpuid_vendor
[8]),
984 : "%eax", "%ebx", "%ecx", "%edx");
985 cpuid_vendor
[12] = '\0';
988 printf_filtered ("CPU Type.......................%s", u
.machine
);
990 printf_filtered (" (%s)", cpuid_vendor
);
991 puts_filtered ("\n");
993 /* CPUID with EAX = 1 returns processor signature and features. */
996 static char *brand_name
[] = {
1004 char cpu_string
[80];
1007 int intel_p
= strcmp (cpuid_vendor
, "GenuineIntel") == 0;
1008 int amd_p
= strcmp (cpuid_vendor
, "AuthenticAMD") == 0;
1009 unsigned cpu_family
, cpu_model
;
1011 __asm__
__volatile__ ("movl $1, %%eax;"
1018 brand_idx
= cpuid_ebx
& 0xff;
1019 cpu_family
= (cpuid_eax
>> 8) & 0xf;
1020 cpu_model
= (cpuid_eax
>> 4) & 0xf;
1021 cpu_brand
[0] = '\0';
1025 && brand_idx
< sizeof(brand_name
)/sizeof(brand_name
[0])
1026 && *brand_name
[brand_idx
])
1027 strcpy (cpu_brand
, brand_name
[brand_idx
]);
1028 else if (cpu_family
== 5)
1030 if (((cpuid_eax
>> 12) & 3) == 0 && cpu_model
== 4)
1031 strcpy (cpu_brand
, " MMX");
1032 else if (cpu_model
> 1 && ((cpuid_eax
>> 12) & 3) == 1)
1033 strcpy (cpu_brand
, " OverDrive");
1034 else if (cpu_model
> 1 && ((cpuid_eax
>> 12) & 3) == 2)
1035 strcpy (cpu_brand
, " Dual");
1037 else if (cpu_family
== 6 && cpu_model
< 8)
1042 strcpy (cpu_brand
, " Pro");
1045 strcpy (cpu_brand
, " II");
1048 strcpy (cpu_brand
, " II Xeon");
1051 strcpy (cpu_brand
, " Celeron");
1054 strcpy (cpu_brand
, " III");
1064 strcpy (cpu_brand
, "486/5x86");
1073 strcpy (cpu_brand
, "-K5");
1077 strcpy (cpu_brand
, "-K6");
1080 strcpy (cpu_brand
, "-K6-2");
1083 strcpy (cpu_brand
, "-K6-III");
1093 strcpy (cpu_brand
, " Athlon");
1096 strcpy (cpu_brand
, " Duron");
1102 sprintf (cpu_string
, "%s%s Model %d Stepping %d",
1103 intel_p
? "Pentium" : (amd_p
? "AMD" : "ix86"),
1104 cpu_brand
, cpu_model
, cpuid_eax
& 0xf);
1105 printfi_filtered (31, "%s\n", cpu_string
);
1106 if (((cpuid_edx
& (6 | (0x0d << 23))) != 0)
1107 || ((cpuid_edx
& 1) == 0)
1108 || (amd_p
&& (cpuid_edx
& (3 << 30)) != 0))
1110 puts_filtered ("CPU Features...................");
1111 /* We only list features which might be useful in the DPMI
1113 if ((cpuid_edx
& 1) == 0)
1114 puts_filtered ("No FPU "); /* it's unusual to not have an FPU */
1115 if ((cpuid_edx
& (1 << 1)) != 0)
1116 puts_filtered ("VME ");
1117 if ((cpuid_edx
& (1 << 2)) != 0)
1118 puts_filtered ("DE ");
1119 if ((cpuid_edx
& (1 << 4)) != 0)
1120 puts_filtered ("TSC ");
1121 if ((cpuid_edx
& (1 << 23)) != 0)
1122 puts_filtered ("MMX ");
1123 if ((cpuid_edx
& (1 << 25)) != 0)
1124 puts_filtered ("SSE ");
1125 if ((cpuid_edx
& (1 << 26)) != 0)
1126 puts_filtered ("SSE2 ");
1129 if ((cpuid_edx
& (1 << 31)) != 0)
1130 puts_filtered ("3DNow! ");
1131 if ((cpuid_edx
& (1 << 30)) != 0)
1132 puts_filtered ("3DNow!Ext");
1134 puts_filtered ("\n");
1137 puts_filtered ("\n");
1138 printf_filtered ("DOS Version....................%s %s.%s",
1139 _os_flavor
, u
.release
, u
.version
);
1140 if (true_dos_version
!= advertized_dos_version
)
1141 printf_filtered (" (disguised as v%d.%d)", _osmajor
, _osminor
);
1142 puts_filtered ("\n");
1144 go32_get_windows_version ();
1145 if (windows_major
!= 0xff)
1147 const char *windows_flavor
;
1149 printf_filtered ("Windows Version................%d.%02d (Windows ",
1150 windows_major
, windows_minor
);
1151 switch (windows_major
)
1154 windows_flavor
= "3.X";
1157 switch (windows_minor
)
1160 windows_flavor
= "95, 95A, or 95B";
1163 windows_flavor
= "95B OSR2.1 or 95C OSR2.5";
1166 windows_flavor
= "98 or 98 SE";
1169 windows_flavor
= "ME";
1172 windows_flavor
= "9X";
1177 windows_flavor
= "??";
1180 printf_filtered ("%s)\n", windows_flavor
);
1182 else if (true_dos_version
== 0x532 && advertized_dos_version
== 0x500)
1183 printf_filtered ("Windows Version................Windows NT or Windows 2000\n");
1184 puts_filtered ("\n");
1185 if (dpmi_vendor_available
== 0)
1187 /* The DPMI spec says the vendor string should be ASCIIZ, but
1188 I don't trust the vendors to follow that... */
1189 if (!memchr (&dpmi_vendor_info
[2], 0, 126))
1190 dpmi_vendor_info
[128] = '\0';
1191 printf_filtered ("DPMI Host......................%s v%d.%d (capabilities: %#x)\n",
1192 &dpmi_vendor_info
[2],
1193 (unsigned)dpmi_vendor_info
[0],
1194 (unsigned)dpmi_vendor_info
[1],
1195 ((unsigned)dpmi_flags
& 0x7f));
1197 __dpmi_get_version (&dpmi_version_data
);
1198 printf_filtered ("DPMI Version...................%d.%02d\n",
1199 dpmi_version_data
.major
, dpmi_version_data
.minor
);
1200 printf_filtered ("DPMI Info......................%s-bit DPMI, with%s Virtual Memory support\n",
1201 (dpmi_version_data
.flags
& 1) ? "32" : "16",
1202 (dpmi_version_data
.flags
& 4) ? "" : "out");
1203 printfi_filtered (31, "Interrupts reflected to %s mode\n",
1204 (dpmi_version_data
.flags
& 2) ? "V86" : "Real");
1205 printfi_filtered (31, "Processor type: i%d86\n",
1206 dpmi_version_data
.cpu
);
1207 printfi_filtered (31, "PIC base interrupt: Master: %#x Slave: %#x\n",
1208 dpmi_version_data
.master_pic
, dpmi_version_data
.slave_pic
);
1210 /* a_tss is only initialized when the debuggee is first run. */
1211 if (prog_has_started
)
1213 __asm__
__volatile__ ("pushfl ; popl %0" : "=g" (eflags
));
1214 printf_filtered ("Protection.....................Ring %d (in %s), with%s I/O protection\n",
1215 a_tss
.tss_cs
& 3, (a_tss
.tss_cs
& 4) ? "LDT" : "GDT",
1216 (a_tss
.tss_cs
& 3) > ((eflags
>> 12) & 3) ? "" : "out");
1218 puts_filtered ("\n");
1219 __dpmi_get_free_memory_information (&mem_info
);
1220 print_mem (mem_info
.total_number_of_physical_pages
,
1221 "DPMI Total Physical Memory.....", 1);
1222 print_mem (mem_info
.total_number_of_free_pages
,
1223 "DPMI Free Physical Memory......", 1);
1224 print_mem (mem_info
.size_of_paging_file_partition_in_pages
,
1225 "DPMI Swap Space................", 1);
1226 print_mem (mem_info
.linear_address_space_size_in_pages
,
1227 "DPMI Total Linear Address Size.", 1);
1228 print_mem (mem_info
.free_linear_address_space_in_pages
,
1229 "DPMI Free Linear Address Size..", 1);
1230 print_mem (mem_info
.largest_available_free_block_in_bytes
,
1231 "DPMI Largest Free Memory Block.", 0);
1235 __dpmi_int (0x21, ®s
);
1236 print_mem (regs
.x
.bx
<< 4, "Free DOS Memory................", 0);
1238 __dpmi_int (0x21, ®s
);
1239 if ((regs
.x
.flags
& 1) == 0)
1241 static const char *dos_hilo
[] = {
1242 "Low", "", "", "", "High", "", "", "", "High, then Low"
1244 static const char *dos_fit
[] = {
1245 "First", "Best", "Last"
1247 int hilo_idx
= (regs
.x
.ax
>> 4) & 0x0f;
1248 int fit_idx
= regs
.x
.ax
& 0x0f;
1254 printf_filtered ("DOS Memory Allocation..........%s memory, %s fit\n",
1255 dos_hilo
[hilo_idx
], dos_fit
[fit_idx
]);
1257 __dpmi_int (0x21, ®s
);
1258 if ((regs
.x
.flags
& 1) != 0)
1260 printfi_filtered (31, "UMBs %sin DOS memory chain\n",
1261 regs
.h
.al
== 0 ? "not " : "");
1266 unsigned short limit0
__attribute__((packed
));
1267 unsigned short base0
__attribute__((packed
));
1268 unsigned char base1
__attribute__((packed
));
1269 unsigned stype
:5 __attribute__((packed
));
1270 unsigned dpl
:2 __attribute__((packed
));
1271 unsigned present
:1 __attribute__((packed
));
1272 unsigned limit1
:4 __attribute__((packed
));
1273 unsigned available
:1 __attribute__((packed
));
1274 unsigned dummy
:1 __attribute__((packed
));
1275 unsigned bit32
:1 __attribute__((packed
));
1276 unsigned page_granular
:1 __attribute__((packed
));
1277 unsigned char base2
__attribute__((packed
));
1281 unsigned short offset0
__attribute__((packed
));
1282 unsigned short selector
__attribute__((packed
));
1283 unsigned param_count
:5 __attribute__((packed
));
1284 unsigned dummy
:3 __attribute__((packed
));
1285 unsigned stype
:5 __attribute__((packed
));
1286 unsigned dpl
:2 __attribute__((packed
));
1287 unsigned present
:1 __attribute__((packed
));
1288 unsigned short offset1
__attribute__((packed
));
1291 /* Read LEN bytes starting at logical address ADDR, and put the result
1292 into DEST. Return 1 if success, zero if not. */
1294 read_memory_region (unsigned long addr
, void *dest
, size_t len
)
1296 unsigned long dos_ds_limit
= __dpmi_get_segment_limit (_dos_ds
);
1298 /* For the low memory, we can simply use _dos_ds. */
1299 if (addr
<= dos_ds_limit
- len
)
1300 dosmemget (addr
, len
, dest
);
1303 /* For memory above 1MB we need to set up a special segment to
1304 be able to access that memory. */
1305 int sel
= __dpmi_allocate_ldt_descriptors (1);
1308 || __dpmi_set_segment_base_address (sel
, addr
) == -1
1309 || __dpmi_set_segment_limit (sel
, len
- 1) == -1)
1311 movedata (sel
, 0, _my_ds (), (unsigned)dest
, len
);
1312 __dpmi_free_ldt_descriptor (sel
);
1317 /* Get a segment descriptor stored at index IDX in the descriptor
1318 table whose base address is TABLE_BASE. Return the descriptor
1319 type, or -1 if failure. */
1321 get_descriptor (unsigned long table_base
, int idx
, void *descr
)
1323 unsigned long addr
= table_base
+ idx
* 8; /* 8 bytes per entry */
1325 if (read_memory_region (addr
, descr
, 8))
1326 return (int)((struct seg_descr
*)descr
)->stype
;
1331 unsigned short limit
__attribute__((packed
));
1332 unsigned long base
__attribute__((packed
));
1335 /* Display a segment descriptor stored at index IDX in a descriptor
1336 table whose type is TYPE and whose base address is BASE_ADDR. If
1337 FORCE is non-zero, display even invalid descriptors. */
1339 display_descriptor (unsigned type
, unsigned long base_addr
, int idx
, int force
)
1341 struct seg_descr descr
;
1342 struct gate_descr gate
;
1344 /* Get the descriptor from the table. */
1345 if (idx
== 0 && type
== 0)
1346 puts_filtered ("0x000: null descriptor\n");
1347 else if (get_descriptor (base_addr
, idx
, &descr
) != -1)
1349 /* For each type of descriptor table, this has a bit set if the
1350 corresponding type of selectors is valid in that table. */
1351 static unsigned allowed_descriptors
[] = {
1352 0xffffdafeL
, /* GDT */
1353 0x0000c0e0L
, /* IDT */
1354 0xffffdafaL
/* LDT */
1357 /* If the program hasn't started yet, assume the debuggee will
1358 have the same CPL as the debugger. */
1359 int cpl
= prog_has_started
? (a_tss
.tss_cs
& 3) : _my_cs () & 3;
1360 unsigned long limit
= (descr
.limit1
<< 16) | descr
.limit0
;
1363 && (allowed_descriptors
[type
] & (1 << descr
.stype
)) != 0)
1365 printf_filtered ("0x%03x: ",
1367 ? idx
: (idx
* 8) | (type
? (cpl
| 4) : 0));
1368 if (descr
.page_granular
)
1369 limit
= (limit
<< 12) | 0xfff; /* big segment: low 12 bit set */
1370 if (descr
.stype
== 1 || descr
.stype
== 2 || descr
.stype
== 3
1371 || descr
.stype
== 9 || descr
.stype
== 11
1372 || (descr
.stype
>= 16 && descr
.stype
< 32))
1373 printf_filtered ("base=0x%02x%02x%04x limit=0x%08lx",
1374 descr
.base2
, descr
.base1
, descr
.base0
, limit
);
1376 switch (descr
.stype
)
1380 printf_filtered (" 16-bit TSS (task %sactive)",
1381 descr
.stype
== 3 ? "" : "in");
1384 puts_filtered (" LDT");
1387 memcpy (&gate
, &descr
, sizeof gate
);
1388 printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1389 gate
.selector
, gate
.offset1
, gate
.offset0
);
1390 printf_filtered (" 16-bit Call Gate (params=%d)",
1394 printf_filtered ("TSS selector=0x%04x", descr
.base0
);
1395 printfi_filtered (16, "Task Gate");
1399 memcpy (&gate
, &descr
, sizeof gate
);
1400 printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1401 gate
.selector
, gate
.offset1
, gate
.offset0
);
1402 printf_filtered (" 16-bit %s Gate",
1403 descr
.stype
== 6 ? "Interrupt" : "Trap");
1407 printf_filtered (" 32-bit TSS (task %sactive)",
1408 descr
.stype
== 3 ? "" : "in");
1411 memcpy (&gate
, &descr
, sizeof gate
);
1412 printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1413 gate
.selector
, gate
.offset1
, gate
.offset0
);
1414 printf_filtered (" 32-bit Call Gate (params=%d)",
1419 memcpy (&gate
, &descr
, sizeof gate
);
1420 printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1421 gate
.selector
, gate
.offset1
, gate
.offset0
);
1422 printf_filtered (" 32-bit %s Gate",
1423 descr
.stype
== 14 ? "Interrupt" : "Trap");
1425 case 16: /* data segments */
1433 printf_filtered (" %s-bit Data (%s Exp-%s%s)",
1434 descr
.bit32
? "32" : "16",
1435 descr
.stype
& 2 ? "Read/Write," : "Read-Only, ",
1436 descr
.stype
& 4 ? "down" : "up",
1437 descr
.stype
& 1 ? "" : ", N.Acc");
1439 case 24: /* code segments */
1447 printf_filtered (" %s-bit Code (%s, %sConf%s)",
1448 descr
.bit32
? "32" : "16",
1449 descr
.stype
& 2 ? "Exec/Read" : "Exec-Only",
1450 descr
.stype
& 4 ? "" : "N.",
1451 descr
.stype
& 1 ? "" : ", N.Acc");
1454 printf_filtered ("Unknown type 0x%02x", descr
.stype
);
1457 puts_filtered ("\n");
1461 printf_filtered ("0x%03x: ",
1463 ? idx
: (idx
* 8) | (type
? (cpl
| 4) : 0));
1465 puts_filtered ("Segment not present\n");
1467 printf_filtered ("Segment type 0x%02x is invalid in this table\n",
1472 printf_filtered ("0x%03x: Cannot read this descriptor\n", idx
);
1476 go32_sldt (char *arg
, int from_tty
)
1478 struct dtr_reg gdtr
;
1479 unsigned short ldtr
= 0;
1481 struct seg_descr ldt_descr
;
1482 long ldt_entry
= -1L;
1483 int cpl
= (prog_has_started
? a_tss
.tss_cs
: _my_cs ()) & 3;
1487 while (*arg
&& isspace(*arg
))
1492 ldt_entry
= parse_and_eval_long (arg
);
1494 || (ldt_entry
& 4) == 0
1495 || (ldt_entry
& 3) != (cpl
& 3))
1496 error ("Invalid LDT entry 0x%03x.", ldt_entry
);
1500 __asm__
__volatile__ ("sgdt %0" : "=m" (gdtr
) : /* no inputs */ );
1501 __asm__
__volatile__ ("sldt %0" : "=m" (ldtr
) : /* no inputs */ );
1504 puts_filtered ("There is no LDT.\n");
1505 /* LDT's entry in the GDT must have the type LDT, which is 2. */
1506 else if (get_descriptor (gdtr
.base
, ldt_idx
, &ldt_descr
) != 2)
1507 printf_filtered ("LDT is present (at %#x), but unreadable by GDB.\n",
1509 | (ldt_descr
.base1
<< 16)
1510 | (ldt_descr
.base2
<< 24));
1515 | (ldt_descr
.base1
<< 16)
1516 | (ldt_descr
.base2
<< 24);
1517 unsigned limit
= ldt_descr
.limit0
| (ldt_descr
.limit1
<< 16);
1520 if (ldt_descr
.page_granular
)
1521 /* Page-granular segments must have the low 12 bits of their
1523 limit
= (limit
<< 12) | 0xfff;
1524 /* LDT cannot have more than 8K 8-byte entries, i.e. more than
1529 max_entry
= (limit
+ 1) / 8;
1533 if (ldt_entry
> limit
)
1534 error ("Invalid LDT entry %#x: outside valid limits [0..%#x]",
1537 display_descriptor (ldt_descr
.stype
, base
, ldt_entry
/ 8, 1);
1543 for (i
= 0; i
< max_entry
; i
++)
1544 display_descriptor (ldt_descr
.stype
, base
, i
, 0);
1550 go32_sgdt (char *arg
, int from_tty
)
1552 struct dtr_reg gdtr
;
1553 long gdt_entry
= -1L;
1558 while (*arg
&& isspace(*arg
))
1563 gdt_entry
= parse_and_eval_long (arg
);
1564 if (gdt_entry
< 0 || (gdt_entry
& 7) != 0)
1565 error ("Invalid GDT entry 0x%03x: not an integral multiple of 8.",
1570 __asm__
__volatile__ ("sgdt %0" : "=m" (gdtr
) : /* no inputs */ );
1571 max_entry
= (gdtr
.limit
+ 1) / 8;
1575 if (gdt_entry
> gdtr
.limit
)
1576 error ("Invalid GDT entry %#x: outside valid limits [0..%#x]",
1577 gdt_entry
, gdtr
.limit
);
1579 display_descriptor (0, gdtr
.base
, gdt_entry
/ 8, 1);
1585 for (i
= 0; i
< max_entry
; i
++)
1586 display_descriptor (0, gdtr
.base
, i
, 0);
1591 go32_sidt (char *arg
, int from_tty
)
1593 struct dtr_reg idtr
;
1594 long idt_entry
= -1L;
1599 while (*arg
&& isspace(*arg
))
1604 idt_entry
= parse_and_eval_long (arg
);
1606 error ("Invalid (negative) IDT entry 0x%03x.", idt_entry
);
1610 __asm__
__volatile__ ("sidt %0" : "=m" (idtr
) : /* no inputs */ );
1611 max_entry
= (idtr
.limit
+ 1) / 8;
1612 if (max_entry
> 0x100) /* no more than 256 entries */
1617 if (idt_entry
> idtr
.limit
)
1618 error ("Invalid IDT entry %#x: outside valid limits [0..%#x]",
1619 idt_entry
, idtr
.limit
);
1621 display_descriptor (1, idtr
.base
, idt_entry
, 1);
1627 for (i
= 0; i
< max_entry
; i
++)
1628 display_descriptor (1, idtr
.base
, i
, 0);
1632 static struct cmd_list_element
*info_dos_cmdlist
= NULL
;
1635 go32_info_dos_command (char *args
, int from_tty
)
1637 help_list (info_dos_cmdlist
, "info dos ", class_info
, gdb_stdout
);
1641 _initialize_go32_nat (void)
1644 add_target (&go32_ops
);
1646 add_prefix_cmd ("dos", class_info
, go32_info_dos_command
,
1647 "Print information specific to DJGPP (a.k.a. MS-DOS) debugging.",
1648 &info_dos_cmdlist
, "info dos ", 0, &infolist
);
1650 add_cmd ("sysinfo", class_info
, go32_sysinfo
,
1651 "Display information about the target system, including CPU, OS, DPMI, etc.",
1653 add_cmd ("ldt", class_info
, go32_sldt
,
1654 "Display entries in the LDT (Local Descriptor Table).\n"
1655 "Entry number (an expression) as an argument means display only that entry.",
1657 add_cmd ("gdt", class_info
, go32_sgdt
,
1658 "Display entries in the GDT (Global Descriptor Table).\n"
1659 "Entry number (an expression) as an argument means display only that entry.",
1661 add_cmd ("idt", class_info
, go32_sidt
,
1662 "Display entries in the IDT (Interrupt Descriptor Table).\n"
1663 "Entry number (an expression) as an argument means display only that entry.",
1677 tcsetpgrp (int fd
, pid_t pgid
)
1679 if (isatty (fd
) && pgid
== SOME_PID
)
1681 errno
= pgid
== SOME_PID
? ENOTTY
: ENOSYS
;