* go32-nat.c (info_dos_cmdlist): New variable.
[deliverable/binutils-gdb.git] / gdb / go32-nat.c
1 /* Native debugging support for Intel x86 running DJGPP.
2 Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
3 Written by Robert Hoehne.
4
5 This file is part of GDB.
6
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.
11
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.
16
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. */
21
22 #include <fcntl.h>
23
24 #include "defs.h"
25 #include "inferior.h"
26 #include "gdb_wait.h"
27 #include "gdbcore.h"
28 #include "command.h"
29 #include "gdbcmd.h"
30 #include "floatformat.h"
31 #include "buildsym.h"
32 #include "i387-nat.h"
33 #include "value.h"
34 #include "regcache.h"
35 #include "gdb_string.h"
36
37 #include <stdio.h> /* might be required for __DJGPP_MINOR__ */
38 #include <stdlib.h>
39 #include <ctype.h>
40 #include <errno.h>
41 #include <unistd.h>
42 #include <sys/utsname.h>
43 #include <io.h>
44 /* breakpoint.h defines `disable' which is an enum member. */
45 #define disable interrup_disable
46 #include <dos.h>
47 #undef disable
48 #include <dpmi.h>
49 #include <go32.h>
50 #include <debug/v2load.h>
51 #include <debug/dbgcom.h>
52 #if __DJGPP_MINOR__ > 2
53 #include <debug/redir.h>
54 #endif
55
56 #if __DJGPP_MINOR__ < 3
57 /* This code will be provided from DJGPP 2.03 on. Until then I code it
58 here */
59 typedef struct
60 {
61 unsigned short sig0;
62 unsigned short sig1;
63 unsigned short sig2;
64 unsigned short sig3;
65 unsigned short exponent:15;
66 unsigned short sign:1;
67 }
68 NPXREG;
69
70 typedef struct
71 {
72 unsigned int control;
73 unsigned int status;
74 unsigned int tag;
75 unsigned int eip;
76 unsigned int cs;
77 unsigned int dataptr;
78 unsigned int datasel;
79 NPXREG reg[8];
80 }
81 NPX;
82
83 static NPX npx;
84
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 */
87
88 /* ------------------------------------------------------------------------- */
89 /* Store the contents of the NPX in the global variable `npx'. */
90 /* *INDENT-OFF* */
91
92 static void
93 save_npx (void)
94 {
95 asm ("inb $0xa0, %%al
96 testb $0x20, %%al
97 jz 1f
98 xorb %% al, %%al
99 outb %% al, $0xf0
100 movb $0x20, %%al
101 outb %% al, $0xa0
102 outb %% al, $0x20
103 1:
104 fnsave % 0
105 fwait "
106 : "=m" (npx)
107 : /* No input */
108 : "%eax");
109 }
110
111 /* *INDENT-ON* */
112
113
114
115
116
117 /* ------------------------------------------------------------------------- */
118 /* Reload the contents of the NPX from the global variable `npx'. */
119
120 static void
121 load_npx (void)
122 {
123 asm ("frstor %0":"=m" (npx));
124 }
125 /* ------------------------------------------------------------------------- */
126 /* Stubs for the missing redirection functions. */
127 typedef struct {
128 char *command;
129 int redirected;
130 } cmdline_t;
131
132 void
133 redir_cmdline_delete (cmdline_t *ptr)
134 {
135 ptr->redirected = 0;
136 }
137
138 int
139 redir_cmdline_parse (const char *args, cmdline_t *ptr)
140 {
141 return -1;
142 }
143
144 int
145 redir_to_child (cmdline_t *ptr)
146 {
147 return 1;
148 }
149
150 int
151 redir_to_debugger (cmdline_t *ptr)
152 {
153 return 1;
154 }
155
156 int
157 redir_debug_init (cmdline_t *ptr)
158 {
159 return 0;
160 }
161 #endif /* __DJGPP_MINOR < 3 */
162
163 typedef enum { wp_insert, wp_remove, wp_count } wp_op;
164
165 /* This holds the current reference counts for each debug register. */
166 static int dr_ref_count[4];
167
168 #define SOME_PID 42
169
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,
184 int write,
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);
193
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);
198
199 #define r_ofs(x) (offsetof(TSS,x))
200
201 static struct
202 {
203 size_t tss_ofs;
204 size_t size;
205 }
206 regno_mapping[] =
207 {
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},
218 {r_ofs (tss_cs), 2},
219 {r_ofs (tss_ss), 2},
220 {r_ofs (tss_ds), 2},
221 {r_ofs (tss_es), 2},
222 {r_ofs (tss_fs), 2},
223 {r_ofs (tss_gs), 2},
224 {0, 10}, /* 8 FP registers, from npx.reg[] */
225 {1, 10},
226 {2, 10},
227 {3, 10},
228 {4, 10},
229 {5, 10},
230 {6, 10},
231 {7, 10},
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 */
242 };
243
244 static struct
245 {
246 int go32_sig;
247 enum target_signal gdb_sig;
248 }
249 sig_map[] =
250 {
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}
278 };
279
280 static struct {
281 enum target_signal gdb_sig;
282 int djgpp_excepno;
283 } excepn_map[] = {
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
290 details. */
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}
298 };
299
300 static void
301 go32_open (char *name, int from_tty)
302 {
303 printf_unfiltered ("Done. Use the \"run\" command to run the program.\n");
304 }
305
306 static void
307 go32_close (int quitting)
308 {
309 }
310
311 static void
312 go32_attach (char *args, int from_tty)
313 {
314 error ("\
315 You cannot attach to a running program on this platform.\n\
316 Use the `run' command to run DJGPP programs.");
317 }
318
319 static void
320 go32_detach (char *args, int from_tty)
321 {
322 }
323
324 static int resume_is_step;
325 static int resume_signal = -1;
326
327 static void
328 go32_resume (ptid_t ptid, int step, enum target_signal siggnal)
329 {
330 int i;
331
332 resume_is_step = step;
333
334 if (siggnal != TARGET_SIGNAL_0 && siggnal != TARGET_SIGNAL_TRAP)
335 {
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)
339 {
340 resume_signal = excepn_map[i].djgpp_excepno;
341 break;
342 }
343 if (resume_signal == -1)
344 printf_unfiltered ("Cannot deliver signal %s on this platform.\n",
345 target_signal_to_name (siggnal));
346 }
347 }
348
349 static char child_cwd[FILENAME_MAX];
350
351 static ptid_t
352 go32_wait (ptid_t ptid, struct target_waitstatus *status)
353 {
354 int i;
355 unsigned char saved_opcode;
356 unsigned long INT3_addr = 0;
357 int stepping_over_INT = 0;
358
359 a_tss.tss_eflags &= 0xfeff; /* reset the single-step flag (TF) */
360 if (resume_is_step)
361 {
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
369 SIGTRAP.
370
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)
378 {
379 unsigned char INT3_opcode = 0xCC;
380
381 INT3_addr
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);
386 }
387 else
388 a_tss.tss_eflags |= 0x0100; /* normal instruction: set TF */
389 }
390
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)
394 {
395 a_tss.tss_trap = 0;
396 a_tss.tss_irqn = 0xff;
397 }
398 else
399 {
400 a_tss.tss_trap = 0xffff; /* run_child looks for this */
401 a_tss.tss_irqn = resume_signal;
402 }
403
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
410 run it. */
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 ..." */
414 if (!*child_cwd)
415 /* Initialize child's cwd with the current one. */
416 getcwd (child_cwd, sizeof (child_cwd));
417
418 chdir (child_cwd);
419
420 #if __DJGPP_MINOR__ < 3
421 load_npx ();
422 #endif
423 run_child ();
424 #if __DJGPP_MINOR__ < 3
425 save_npx ();
426 #endif
427
428 /* Did we step over an INT xx instruction? */
429 if (stepping_over_INT && a_tss.tss_eip == INT3_addr + 1)
430 {
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. */
435 a_tss.tss_irqn = 1;
436 a_tss.tss_eflags |= 0x0100;
437 }
438
439 getcwd (child_cwd, sizeof (child_cwd)); /* in case it has changed */
440 chdir (current_directory);
441
442 if (a_tss.tss_irqn == 0x21)
443 {
444 status->kind = TARGET_WAITKIND_EXITED;
445 status->value.integer = a_tss.tss_eax & 0xff;
446 }
447 else
448 {
449 status->value.sig = TARGET_SIGNAL_UNKNOWN;
450 status->kind = TARGET_WAITKIND_STOPPED;
451 for (i = 0; sig_map[i].go32_sig != -1; i++)
452 {
453 if (a_tss.tss_irqn == sig_map[i].go32_sig)
454 {
455 #if __DJGPP_MINOR__ < 3
456 if ((status->value.sig = sig_map[i].gdb_sig) !=
457 TARGET_SIGNAL_TRAP)
458 status->kind = TARGET_WAITKIND_SIGNALLED;
459 #else
460 status->value.sig = sig_map[i].gdb_sig;
461 #endif
462 break;
463 }
464 }
465 }
466 return pid_to_ptid (SOME_PID);
467 }
468
469 static void
470 fetch_register (int regno)
471 {
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);
476 else
477 internal_error (__FILE__, __LINE__,
478 "Invalid register no. %d in fetch_register.", regno);
479 }
480
481 static void
482 go32_fetch_registers (int regno)
483 {
484 if (regno >= 0)
485 fetch_register (regno);
486 else
487 {
488 for (regno = 0; regno < FP0_REGNUM; regno++)
489 fetch_register (regno);
490 i387_supply_fsave ((char *) &npx);
491 }
492 }
493
494 static void
495 store_register (int regno)
496 {
497 void *rp;
498 void *v = (void *) register_buffer (regno);
499
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);
505 else
506 internal_error (__FILE__, __LINE__,
507 "Invalid register no. %d in store_register.", regno);
508 }
509
510 static void
511 go32_store_registers (int regno)
512 {
513 unsigned r;
514
515 if (regno >= 0)
516 store_register (regno);
517 else
518 {
519 for (r = 0; r < FP0_REGNUM; r++)
520 store_register (r);
521 i387_fill_fsave ((char *) &npx, -1);
522 }
523 }
524
525 static void
526 go32_prepare_to_store (void)
527 {
528 }
529
530 static int
531 go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
532 struct mem_attrib *attrib, struct target_ops *target)
533 {
534 if (write)
535 {
536 if (write_child (memaddr, myaddr, len))
537 {
538 return 0;
539 }
540 else
541 {
542 return len;
543 }
544 }
545 else
546 {
547 if (read_child (memaddr, myaddr, len))
548 {
549 return 0;
550 }
551 else
552 {
553 return len;
554 }
555 }
556 }
557
558 static cmdline_t child_cmd; /* parsed child's command line kept here */
559
560 static void
561 go32_files_info (struct target_ops *target)
562 {
563 printf_unfiltered ("You are running a DJGPP V2 program.\n");
564 }
565
566 static void
567 go32_stop (void)
568 {
569 normal_stop ();
570 cleanup_client ();
571 inferior_ptid = null_ptid;
572 prog_has_started = 0;
573 }
574
575 static void
576 go32_kill_inferior (void)
577 {
578 redir_cmdline_delete (&child_cmd);
579 resume_signal = -1;
580 resume_is_step = 0;
581 unpush_target (&go32_ops);
582 }
583
584 static void
585 go32_create_inferior (char *exec_file, char *args, char **env)
586 {
587 extern char **environ;
588 jmp_buf start_state;
589 char *cmdline;
590 char **env_save = environ;
591
592 /* If no exec file handed to us, get it from the exec-file command -- with
593 a good, common error message if none is specified. */
594 if (exec_file == 0)
595 exec_file = get_exec_file (1);
596
597 if (prog_has_started)
598 {
599 go32_stop ();
600 go32_kill_inferior ();
601 }
602 resume_signal = -1;
603 resume_is_step = 0;
604
605 /* Initialize child's cwd as empty to be initialized when starting
606 the child. */
607 *child_cwd = 0;
608
609 /* Init command line storage. */
610 if (redir_debug_init (&child_cmd) == -1)
611 internal_error (__FILE__, __LINE__,
612 "Cannot allocate redirection storage: not enough memory.\n");
613
614 /* Parse the command line and create redirections. */
615 if (strpbrk (args, "<>"))
616 {
617 if (redir_cmdline_parse (args, &child_cmd) == 0)
618 args = child_cmd.command;
619 else
620 error ("Syntax error in command line.");
621 }
622 else
623 child_cmd.command = xstrdup (args);
624
625 cmdline = (char *) alloca (strlen (args) + 4);
626 cmdline[0] = strlen (args);
627 strcpy (cmdline + 1, args);
628 cmdline[strlen (args) + 1] = 13;
629
630 environ = env;
631
632 if (v2loadimage (exec_file, cmdline, start_state))
633 {
634 environ = env_save;
635 printf_unfiltered ("Load failed for image %s\n", exec_file);
636 exit (1);
637 }
638 environ = env_save;
639
640 edi_init (start_state);
641 #if __DJGPP_MINOR__ < 3
642 save_npx ();
643 #endif
644
645 inferior_ptid = pid_to_ptid (SOME_PID);
646 push_target (&go32_ops);
647 clear_proceed_status ();
648 insert_breakpoints ();
649 proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
650 prog_has_started = 1;
651 }
652
653 static void
654 go32_mourn_inferior (void)
655 {
656 /* We need to make sure all the breakpoint enable bits in the DR7
657 register are reset when the inferior exits. Otherwise, if they
658 rerun the inferior, the uncleared bits may cause random SIGTRAPs,
659 failure to set more watchpoints, and other calamities. It would
660 be nice if GDB itself would take care to remove all breakpoints
661 at all times, but it doesn't, probably under an assumption that
662 the OS cleans up when the debuggee exits. */
663 i386_cleanup_dregs ();
664 go32_kill_inferior ();
665 generic_mourn_inferior ();
666 }
667
668 static int
669 go32_can_run (void)
670 {
671 return 1;
672 }
673
674 /* Hardware watchpoint support. */
675
676 #define D_REGS edi.dr
677 #define CONTROL D_REGS[7]
678 #define STATUS D_REGS[6]
679
680 /* Pass the address ADDR to the inferior in the I'th debug register.
681 Here we just store the address in D_REGS, the watchpoint will be
682 actually set up when go32_wait runs the debuggee. */
683 void
684 go32_set_dr (int i, CORE_ADDR addr)
685 {
686 if (i < 0 || i > 3)
687 internal_error (__FILE__, __LINE__,
688 "Invalid register %d in go32_set_dr.\n", i);
689 D_REGS[i] = addr;
690 }
691
692 /* Pass the value VAL to the inferior in the DR7 debug control
693 register. Here we just store the address in D_REGS, the watchpoint
694 will be actually set up when go32_wait runs the debuggee. */
695 void
696 go32_set_dr7 (unsigned val)
697 {
698 CONTROL = val;
699 }
700
701 /* Get the value of the DR6 debug status register from the inferior.
702 Here we just return the value stored in D_REGS, as we've got it
703 from the last go32_wait call. */
704 unsigned
705 go32_get_dr6 (void)
706 {
707 return STATUS;
708 }
709
710 /* Put the device open on handle FD into either raw or cooked
711 mode, return 1 if it was in raw mode, zero otherwise. */
712
713 static int
714 device_mode (int fd, int raw_p)
715 {
716 int oldmode, newmode;
717 __dpmi_regs regs;
718
719 regs.x.ax = 0x4400;
720 regs.x.bx = fd;
721 __dpmi_int (0x21, &regs);
722 if (regs.x.flags & 1)
723 return -1;
724 newmode = oldmode = regs.x.dx;
725
726 if (raw_p)
727 newmode |= 0x20;
728 else
729 newmode &= ~0x20;
730
731 if (oldmode & 0x80) /* Only for character dev */
732 {
733 regs.x.ax = 0x4401;
734 regs.x.bx = fd;
735 regs.x.dx = newmode & 0xff; /* Force upper byte zero, else it fails */
736 __dpmi_int (0x21, &regs);
737 if (regs.x.flags & 1)
738 return -1;
739 }
740 return (oldmode & 0x20) == 0x20;
741 }
742
743
744 static int inf_mode_valid = 0;
745 static int inf_terminal_mode;
746
747 /* This semaphore is needed because, amazingly enough, GDB calls
748 target.to_terminal_ours more than once after the inferior stops.
749 But we need the information from the first call only, since the
750 second call will always see GDB's own cooked terminal. */
751 static int terminal_is_ours = 1;
752
753 static void
754 go32_terminal_init (void)
755 {
756 inf_mode_valid = 0; /* reinitialize, in case they are restarting child */
757 terminal_is_ours = 1;
758 }
759
760 static void
761 go32_terminal_info (char *args, int from_tty)
762 {
763 printf_unfiltered ("Inferior's terminal is in %s mode.\n",
764 !inf_mode_valid
765 ? "default" : inf_terminal_mode ? "raw" : "cooked");
766
767 #if __DJGPP_MINOR__ > 2
768 if (child_cmd.redirection)
769 {
770 int i;
771
772 for (i = 0; i < DBG_HANDLES; i++)
773 {
774 if (child_cmd.redirection[i]->file_name)
775 printf_unfiltered ("\tFile handle %d is redirected to `%s'.\n",
776 i, child_cmd.redirection[i]->file_name);
777 else if (_get_dev_info (child_cmd.redirection[i]->inf_handle) == -1)
778 printf_unfiltered
779 ("\tFile handle %d appears to be closed by inferior.\n", i);
780 /* Mask off the raw/cooked bit when comparing device info words. */
781 else if ((_get_dev_info (child_cmd.redirection[i]->inf_handle) & 0xdf)
782 != (_get_dev_info (i) & 0xdf))
783 printf_unfiltered
784 ("\tFile handle %d appears to be redirected by inferior.\n", i);
785 }
786 }
787 #endif
788 }
789
790 static void
791 go32_terminal_inferior (void)
792 {
793 /* Redirect standard handles as child wants them. */
794 errno = 0;
795 if (redir_to_child (&child_cmd) == -1)
796 {
797 redir_to_debugger (&child_cmd);
798 error ("Cannot redirect standard handles for program: %s.",
799 strerror (errno));
800 }
801 /* set the console device of the inferior to whatever mode
802 (raw or cooked) we found it last time */
803 if (terminal_is_ours)
804 {
805 if (inf_mode_valid)
806 device_mode (0, inf_terminal_mode);
807 terminal_is_ours = 0;
808 }
809 }
810
811 static void
812 go32_terminal_ours (void)
813 {
814 /* Switch to cooked mode on the gdb terminal and save the inferior
815 terminal mode to be restored when it is resumed */
816 if (!terminal_is_ours)
817 {
818 inf_terminal_mode = device_mode (0, 0);
819 if (inf_terminal_mode != -1)
820 inf_mode_valid = 1;
821 else
822 /* If device_mode returned -1, we don't know what happens with
823 handle 0 anymore, so make the info invalid. */
824 inf_mode_valid = 0;
825 terminal_is_ours = 1;
826
827 /* Restore debugger's standard handles. */
828 errno = 0;
829 if (redir_to_debugger (&child_cmd) == -1)
830 {
831 redir_to_child (&child_cmd);
832 error ("Cannot redirect standard handles for debugger: %s.",
833 strerror (errno));
834 }
835 }
836 }
837
838 static void
839 init_go32_ops (void)
840 {
841 go32_ops.to_shortname = "djgpp";
842 go32_ops.to_longname = "djgpp target process";
843 go32_ops.to_doc =
844 "Program loaded by djgpp, when gdb is used as an external debugger";
845 go32_ops.to_open = go32_open;
846 go32_ops.to_close = go32_close;
847 go32_ops.to_attach = go32_attach;
848 go32_ops.to_detach = go32_detach;
849 go32_ops.to_resume = go32_resume;
850 go32_ops.to_wait = go32_wait;
851 go32_ops.to_fetch_registers = go32_fetch_registers;
852 go32_ops.to_store_registers = go32_store_registers;
853 go32_ops.to_prepare_to_store = go32_prepare_to_store;
854 go32_ops.to_xfer_memory = go32_xfer_memory;
855 go32_ops.to_files_info = go32_files_info;
856 go32_ops.to_insert_breakpoint = memory_insert_breakpoint;
857 go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
858 go32_ops.to_terminal_init = go32_terminal_init;
859 go32_ops.to_terminal_inferior = go32_terminal_inferior;
860 go32_ops.to_terminal_ours_for_output = go32_terminal_ours;
861 go32_ops.to_terminal_ours = go32_terminal_ours;
862 go32_ops.to_terminal_info = go32_terminal_info;
863 go32_ops.to_kill = go32_kill_inferior;
864 go32_ops.to_create_inferior = go32_create_inferior;
865 go32_ops.to_mourn_inferior = go32_mourn_inferior;
866 go32_ops.to_can_run = go32_can_run;
867 go32_ops.to_stop = go32_stop;
868 go32_ops.to_stratum = process_stratum;
869 go32_ops.to_has_all_memory = 1;
870 go32_ops.to_has_memory = 1;
871 go32_ops.to_has_stack = 1;
872 go32_ops.to_has_registers = 1;
873 go32_ops.to_has_execution = 1;
874 go32_ops.to_magic = OPS_MAGIC;
875
876 /* Initialize child's cwd as empty to be initialized when starting
877 the child. */
878 *child_cwd = 0;
879
880 /* Initialize child's command line storage. */
881 if (redir_debug_init (&child_cmd) == -1)
882 internal_error (__FILE__, __LINE__,
883 "Cannot allocate redirection storage: not enough memory.\n");
884
885 /* We are always processing GCC-compiled programs. */
886 processing_gcc_compilation = 2;
887 }
888
889 unsigned short windows_major, windows_minor;
890
891 /* Compute the version Windows reports via Int 2Fh/AX=1600h. */
892 static void
893 go32_get_windows_version(void)
894 {
895 __dpmi_regs r;
896
897 r.x.ax = 0x1600;
898 __dpmi_int(0x2f, &r);
899 if (r.h.al > 2 && r.h.al != 0x80 && r.h.al != 0xff
900 && (r.h.al > 3 || r.h.ah > 0))
901 {
902 windows_major = r.h.al;
903 windows_minor = r.h.ah;
904 }
905 else
906 windows_major = 0xff; /* meaning no Windows */
907 }
908
909 /* A subroutine of go32_sysinfo to display memory info. */
910 static void
911 print_mem (unsigned long datum, const char *header, int in_pages_p)
912 {
913 if (datum != 0xffffffffUL)
914 {
915 if (in_pages_p)
916 datum <<= 12;
917 puts_filtered (header);
918 if (datum > 1024)
919 {
920 printf_filtered ("%lu KB", datum >> 10);
921 if (datum > 1024 * 1024)
922 printf_filtered (" (%lu MB)", datum >> 20);
923 }
924 else
925 printf_filtered ("%lu Bytes", datum);
926 puts_filtered ("\n");
927 }
928 }
929
930 /* Display assorted information about the underlying OS. */
931 static void
932 go32_sysinfo (char *arg, int from_tty)
933 {
934 struct utsname u;
935 char cpuid_vendor[13];
936 unsigned cpuid_max = 0, cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
937 unsigned true_dos_version = _get_dos_version (1);
938 unsigned advertized_dos_version = ((unsigned int)_osmajor << 8) | _osminor;
939 int dpmi_flags;
940 char dpmi_vendor_info[129];
941 int dpmi_vendor_available =
942 __dpmi_get_capabilities (&dpmi_flags, dpmi_vendor_info);
943 __dpmi_version_ret dpmi_version_data;
944 long eflags;
945 __dpmi_free_mem_info mem_info;
946 __dpmi_regs regs;
947
948 cpuid_vendor[0] = '\0';
949 if (uname (&u))
950 strcpy (u.machine, "Unknown x86");
951 else if (u.machine[0] == 'i' && u.machine[1] > 4)
952 {
953 /* CPUID with EAX = 0 returns the Vendor ID. */
954 __asm__ __volatile__ ("xorl %%ebx, %%ebx;"
955 "xorl %%ecx, %%ecx;"
956 "xorl %%edx, %%edx;"
957 "movl $0, %%eax;"
958 "cpuid;"
959 "movl %%ebx, %0;"
960 "movl %%edx, %1;"
961 "movl %%ecx, %2;"
962 "movl %%eax, %3;"
963 : "=m" (cpuid_vendor[0]),
964 "=m" (cpuid_vendor[4]),
965 "=m" (cpuid_vendor[8]),
966 "=m" (cpuid_max)
967 :
968 : "%eax", "%ebx", "%ecx", "%edx");
969 cpuid_vendor[12] = '\0';
970 }
971
972 printf_filtered ("CPU Type.......................%s", u.machine);
973 if (cpuid_vendor[0])
974 printf_filtered (" (%s)", cpuid_vendor);
975 puts_filtered ("\n");
976
977 /* CPUID with EAX = 1 returns processor signature and features. */
978 if (cpuid_max >= 1)
979 {
980 static char *brand_name[] = {
981 "",
982 " Celeron",
983 " III",
984 " III Xeon",
985 "", "", "", "",
986 " 4"
987 };
988 char cpu_string[80];
989 char cpu_brand[20];
990 unsigned brand_idx;
991 int intel_p = strcmp (cpuid_vendor, "GenuineIntel") == 0;
992 int amd_p = strcmp (cpuid_vendor, "AuthenticAMD") == 0;
993 unsigned cpu_family, cpu_model;
994
995 __asm__ __volatile__ ("movl $1, %%eax;"
996 "cpuid;"
997 : "=a" (cpuid_eax),
998 "=b" (cpuid_ebx),
999 "=d" (cpuid_edx)
1000 :
1001 : "%ecx");
1002 brand_idx = cpuid_ebx & 0xff;
1003 cpu_family = (cpuid_eax >> 8) & 0xf;
1004 cpu_model = (cpuid_eax >> 4) & 0xf;
1005 cpu_brand[0] = '\0';
1006 if (intel_p)
1007 {
1008 if (brand_idx > 0
1009 && brand_idx < sizeof(brand_name)/sizeof(brand_name[0])
1010 && *brand_name[brand_idx])
1011 strcpy (cpu_brand, brand_name[brand_idx]);
1012 else if (cpu_family == 5)
1013 {
1014 if (((cpuid_eax >> 12) & 3) == 0 && cpu_model == 4)
1015 strcpy (cpu_brand, " MMX");
1016 else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 1)
1017 strcpy (cpu_brand, " OverDrive");
1018 else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 2)
1019 strcpy (cpu_brand, " Dual");
1020 }
1021 else if (cpu_family == 6 && cpu_model < 8)
1022 {
1023 switch (cpu_model)
1024 {
1025 case 1:
1026 strcpy (cpu_brand, " Pro");
1027 break;
1028 case 3:
1029 strcpy (cpu_brand, " II");
1030 break;
1031 case 5:
1032 strcpy (cpu_brand, " II Xeon");
1033 break;
1034 case 6:
1035 strcpy (cpu_brand, " Celeron");
1036 break;
1037 case 7:
1038 strcpy (cpu_brand, " III");
1039 break;
1040 }
1041 }
1042 }
1043 else if (amd_p)
1044 {
1045 switch (cpu_family)
1046 {
1047 case 4:
1048 strcpy (cpu_brand, "486/5x86");
1049 break;
1050 case 5:
1051 switch (cpu_model)
1052 {
1053 case 0:
1054 case 1:
1055 case 2:
1056 case 3:
1057 strcpy (cpu_brand, "-K5");
1058 break;
1059 case 6:
1060 case 7:
1061 strcpy (cpu_brand, "-K6");
1062 break;
1063 case 8:
1064 strcpy (cpu_brand, "-K6-2");
1065 break;
1066 case 9:
1067 strcpy (cpu_brand, "-K6-III");
1068 break;
1069 }
1070 break;
1071 case 6:
1072 switch (cpu_model)
1073 {
1074 case 1:
1075 case 2:
1076 case 4:
1077 strcpy (cpu_brand, " Athlon");
1078 break;
1079 case 3:
1080 strcpy (cpu_brand, " Duron");
1081 break;
1082 }
1083 break;
1084 }
1085 }
1086 sprintf (cpu_string, "%s%s Model %d Stepping %d",
1087 intel_p ? "Pentium" : (amd_p ? "AMD" : "ix86"),
1088 cpu_brand, cpu_model, cpuid_eax & 0xf);
1089 printfi_filtered (31, "%s\n", cpu_string);
1090 if (((cpuid_edx & (6 | (0x0d << 23))) != 0)
1091 || ((cpuid_edx & 1) == 0)
1092 || (amd_p && (cpuid_edx & (3 << 30)) != 0))
1093 {
1094 puts_filtered ("CPU Features...................");
1095 /* We only list features which might be useful in the DPMI
1096 environment. */
1097 if ((cpuid_edx & 1) == 0)
1098 puts_filtered ("No FPU "); /* it's unusual to not have an FPU */
1099 if ((cpuid_edx & (1 << 1)) != 0)
1100 puts_filtered ("VME ");
1101 if ((cpuid_edx & (1 << 2)) != 0)
1102 puts_filtered ("DE ");
1103 if ((cpuid_edx & (1 << 4)) != 0)
1104 puts_filtered ("TSC ");
1105 if ((cpuid_edx & (1 << 23)) != 0)
1106 puts_filtered ("MMX ");
1107 if ((cpuid_edx & (1 << 25)) != 0)
1108 puts_filtered ("SSE ");
1109 if ((cpuid_edx & (1 << 26)) != 0)
1110 puts_filtered ("SSE2 ");
1111 if (amd_p)
1112 {
1113 if ((cpuid_edx & (1 << 31)) != 0)
1114 puts_filtered ("3DNow! ");
1115 if ((cpuid_edx & (1 << 30)) != 0)
1116 puts_filtered ("3DNow!Ext");
1117 }
1118 puts_filtered ("\n");
1119 }
1120 }
1121 puts_filtered ("\n");
1122 printf_filtered ("DOS Version....................%s %s.%s",
1123 _os_flavor, u.release, u.version);
1124 if (true_dos_version != advertized_dos_version)
1125 printf_filtered (" (disguised as v%d.%d)", _osmajor, _osminor);
1126 puts_filtered ("\n");
1127 if (!windows_major)
1128 go32_get_windows_version ();
1129 if (windows_major != 0xff)
1130 {
1131 const char *windows_flavor;
1132
1133 printf_filtered ("Windows Version................%d.%02d (Windows ",
1134 windows_major, windows_minor);
1135 switch (windows_major)
1136 {
1137 case 3:
1138 windows_flavor = "3.X";
1139 break;
1140 case 4:
1141 switch (windows_minor)
1142 {
1143 case 0:
1144 windows_flavor = "95, 95A, or 95B";
1145 break;
1146 case 3:
1147 windows_flavor = "95B OSR2.1 or 95C OSR2.5";
1148 break;
1149 case 10:
1150 windows_flavor = "98 or 98 SE";
1151 break;
1152 case 90:
1153 windows_flavor = "ME";
1154 break;
1155 default:
1156 windows_flavor = "9X";
1157 break;
1158 }
1159 break;
1160 default:
1161 windows_flavor = "??";
1162 break;
1163 }
1164 printf_filtered ("%s)\n", windows_flavor);
1165 }
1166 else if (true_dos_version == 0x532 && advertized_dos_version == 0x500)
1167 printf_filtered ("Windows Version................Windows NT or Windows 2000\n");
1168 puts_filtered ("\n");
1169 if (dpmi_vendor_available == 0)
1170 {
1171 /* The DPMI spec says the vendor string should be ASCIIZ, but
1172 I don't trust the vendors to follow that... */
1173 if (!memchr (&dpmi_vendor_info[2], 0, 126))
1174 dpmi_vendor_info[128] = '\0';
1175 printf_filtered ("DPMI Host......................%s v%d.%d (capabilities: %#x)\n",
1176 &dpmi_vendor_info[2],
1177 (unsigned)dpmi_vendor_info[0],
1178 (unsigned)dpmi_vendor_info[1],
1179 ((unsigned)dpmi_flags & 0x7f));
1180 }
1181 __dpmi_get_version (&dpmi_version_data);
1182 printf_filtered ("DPMI Version...................%d.%02d\n",
1183 dpmi_version_data.major, dpmi_version_data.minor);
1184 printf_filtered ("DPMI Info......................%s-bit DPMI, with%s Virtual Memory support\n",
1185 (dpmi_version_data.flags & 1) ? "32" : "16",
1186 (dpmi_version_data.flags & 4) ? "" : "out");
1187 printfi_filtered (31, "Interrupts reflected to %s mode\n",
1188 (dpmi_version_data.flags & 2) ? "V86" : "Real");
1189 printfi_filtered (31, "Processor type: i%d86\n",
1190 dpmi_version_data.cpu);
1191 printfi_filtered (31, "PIC base interrupt: Master: %#x Slave: %#x\n",
1192 dpmi_version_data.master_pic, dpmi_version_data.slave_pic);
1193
1194 /* a_tss is only initialized when the debuggee is first run. */
1195 if (prog_has_started)
1196 {
1197 __asm__ __volatile__ ("pushfl ; popl %0" : "=g" (eflags));
1198 printf_filtered ("Protection.....................Ring %d (in %s), with%s I/O protection\n",
1199 a_tss.tss_cs & 3, (a_tss.tss_cs & 4) ? "LDT" : "GDT",
1200 (a_tss.tss_cs & 3) > ((eflags >> 12) & 3) ? "" : "out");
1201 }
1202 puts_filtered ("\n");
1203 __dpmi_get_free_memory_information (&mem_info);
1204 print_mem (mem_info.total_number_of_physical_pages,
1205 "DPMI Total Physical Memory.....", 1);
1206 print_mem (mem_info.total_number_of_free_pages,
1207 "DPMI Free Physical Memory......", 1);
1208 print_mem (mem_info.size_of_paging_file_partition_in_pages,
1209 "DPMI Swap Space................", 1);
1210 print_mem (mem_info.linear_address_space_size_in_pages,
1211 "DPMI Total Linear Address Size.", 1);
1212 print_mem (mem_info.free_linear_address_space_in_pages,
1213 "DPMI Free Linear Address Size..", 1);
1214 print_mem (mem_info.largest_available_free_block_in_bytes,
1215 "DPMI Largest Free Memory Block.", 0);
1216
1217 regs.h.ah = 0x48;
1218 regs.x.bx = 0xffff;
1219 __dpmi_int (0x21, &regs);
1220 print_mem (regs.x.bx << 4, "Free DOS Memory................", 0);
1221 regs.x.ax = 0x5800;
1222 __dpmi_int (0x21, &regs);
1223 if ((regs.x.flags & 1) == 0)
1224 {
1225 static const char *dos_hilo[] = {
1226 "Low", "", "", "", "High", "", "", "", "High, then Low"
1227 };
1228 static const char *dos_fit[] = {
1229 "First", "Best", "Last"
1230 };
1231 int hilo_idx = (regs.x.ax >> 4) & 0x0f;
1232 int fit_idx = regs.x.ax & 0x0f;
1233
1234 if (hilo_idx > 8)
1235 hilo_idx = 0;
1236 if (fit_idx > 2)
1237 fit_idx = 0;
1238 printf_filtered ("DOS Memory Allocation..........%s memory, %s fit\n",
1239 dos_hilo[hilo_idx], dos_fit[fit_idx]);
1240 regs.x.ax = 0x5802;
1241 __dpmi_int (0x21, &regs);
1242 if ((regs.x.flags & 1) != 0)
1243 regs.h.al = 0;
1244 printfi_filtered (31, "UMBs %sin DOS memory chain\n",
1245 regs.h.al == 0 ? "not " : "");
1246 }
1247 }
1248
1249 struct seg_descr {
1250 unsigned short limit0 __attribute__((packed));
1251 unsigned short base0 __attribute__((packed));
1252 unsigned char base1 __attribute__((packed));
1253 unsigned stype:5 __attribute__((packed));
1254 unsigned dpl:2 __attribute__((packed));
1255 unsigned present:1 __attribute__((packed));
1256 unsigned limit1:4 __attribute__((packed));
1257 unsigned available:1 __attribute__((packed));
1258 unsigned dummy:1 __attribute__((packed));
1259 unsigned bit32:1 __attribute__((packed));
1260 unsigned page_granular:1 __attribute__((packed));
1261 unsigned char base2 __attribute__((packed));
1262 };
1263
1264 struct gate_descr {
1265 unsigned short offset0 __attribute__((packed));
1266 unsigned short selector __attribute__((packed));
1267 unsigned param_count:5 __attribute__((packed));
1268 unsigned dummy:3 __attribute__((packed));
1269 unsigned stype:5 __attribute__((packed));
1270 unsigned dpl:2 __attribute__((packed));
1271 unsigned present:1 __attribute__((packed));
1272 unsigned short offset1 __attribute__((packed));
1273 };
1274
1275 /* Read LEN bytes starting at logical address ADDR, and put the result
1276 into DEST. Return 1 if success, zero if not. */
1277 static int
1278 read_memory_region (unsigned long addr, void *dest, size_t len)
1279 {
1280 unsigned long dos_ds_limit = __dpmi_get_segment_limit (_dos_ds);
1281
1282 /* For the low memory, we can simply use _dos_ds. */
1283 if (addr <= dos_ds_limit - len)
1284 dosmemget (addr, len, dest);
1285 else
1286 {
1287 /* For memory above 1MB we need to set up a special segment to
1288 be able to access that memory. */
1289 int sel = __dpmi_allocate_ldt_descriptors (1);
1290
1291 if (sel <= 0
1292 || __dpmi_set_segment_base_address (sel, addr) == -1
1293 || __dpmi_set_segment_limit (sel, len - 1) == -1)
1294 return 0;
1295 movedata (sel, 0, _my_ds (), (unsigned)dest, len);
1296 __dpmi_free_ldt_descriptor (sel);
1297 }
1298 return 1;
1299 }
1300
1301 /* Get a segment descriptor stored at index IDX in the descriptor
1302 table whose base address is TABLE_BASE. Return the descriptor
1303 type, or -1 if failure. */
1304 static int
1305 get_descriptor (unsigned long table_base, int idx, void *descr)
1306 {
1307 unsigned long addr = table_base + idx * 8; /* 8 bytes per entry */
1308
1309 if (read_memory_region (addr, descr, 8))
1310 return (int)((struct seg_descr *)descr)->stype;
1311 return -1;
1312 }
1313
1314 struct dtr_reg {
1315 unsigned short limit __attribute__((packed));
1316 unsigned long base __attribute__((packed));
1317 };
1318
1319 /* Display a segment descriptor stored at index IDX in a descriptor
1320 table whose type is TYPE and whose base address is BASE_ADDR. If
1321 FORCE is non-zero, display even invalid descriptors. */
1322 static void
1323 display_descriptor (unsigned type, unsigned long base_addr, int idx, int force)
1324 {
1325 struct seg_descr descr;
1326 struct gate_descr gate;
1327
1328 /* Get the descriptor from the table. */
1329 if (idx == 0 && type == 0)
1330 puts_filtered ("0x000: null descriptor\n");
1331 else if (get_descriptor (base_addr, idx, &descr) != -1)
1332 {
1333 /* For each type of descriptor table, this has a bit set if the
1334 corresponding type of selectors is valid in that table. */
1335 static unsigned allowed_descriptors[] = {
1336 0xffffdafeL, /* GDT */
1337 0x0000c0e0L, /* IDT */
1338 0xffffdafaL /* LDT */
1339 };
1340
1341 /* If the program hasn't started yet, assume the debuggee will
1342 have the same CPL as the debugger. */
1343 int cpl = prog_has_started ? (a_tss.tss_cs & 3) : _my_cs () & 3;
1344 unsigned long limit = (descr.limit1 << 16) | descr.limit0;
1345
1346 if (descr.present
1347 && (allowed_descriptors[type] & (1 << descr.stype)) != 0)
1348 {
1349 printf_filtered ("0x%03x: ",
1350 type == 1
1351 ? idx : (idx * 8) | (type ? (cpl | 4) : 0));
1352 if (descr.page_granular)
1353 limit = (limit << 12) | 0xfff; /* big segment: low 12 bit set */
1354 if (descr.stype == 1 || descr.stype == 2 || descr.stype == 3
1355 || descr.stype == 9 || descr.stype == 11
1356 || (descr.stype >= 16 && descr.stype < 32))
1357 printf_filtered ("base=0x%02x%02x%04x limit=0x%08lx",
1358 descr.base2, descr.base1, descr.base0, limit);
1359
1360 switch (descr.stype)
1361 {
1362 case 1:
1363 case 3:
1364 printf_filtered (" 16-bit TSS (task %sactive)",
1365 descr.stype == 3 ? "" : "in");
1366 break;
1367 case 2:
1368 puts_filtered (" LDT");
1369 break;
1370 case 4:
1371 memcpy (&gate, &descr, sizeof gate);
1372 printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1373 gate.selector, gate.offset1, gate.offset0);
1374 printf_filtered (" 16-bit Call Gate (params=%d)",
1375 gate.param_count);
1376 break;
1377 case 5:
1378 printf_filtered ("TSS selector=0x%04x", descr.base0);
1379 printfi_filtered (16, "Task Gate");
1380 break;
1381 case 6:
1382 case 7:
1383 memcpy (&gate, &descr, sizeof gate);
1384 printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1385 gate.selector, gate.offset1, gate.offset0);
1386 printf_filtered (" 16-bit %s Gate",
1387 descr.stype == 6 ? "Interrupt" : "Trap");
1388 break;
1389 case 9:
1390 case 11:
1391 printf_filtered (" 32-bit TSS (task %sactive)",
1392 descr.stype == 3 ? "" : "in");
1393 break;
1394 case 12:
1395 memcpy (&gate, &descr, sizeof gate);
1396 printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1397 gate.selector, gate.offset1, gate.offset0);
1398 printf_filtered (" 32-bit Call Gate (params=%d)",
1399 gate.param_count);
1400 break;
1401 case 14:
1402 case 15:
1403 memcpy (&gate, &descr, sizeof gate);
1404 printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1405 gate.selector, gate.offset1, gate.offset0);
1406 printf_filtered (" 32-bit %s Gate",
1407 descr.stype == 14 ? "Interrupt" : "Trap");
1408 break;
1409 case 16: /* data segments */
1410 case 17:
1411 case 18:
1412 case 19:
1413 case 20:
1414 case 21:
1415 case 22:
1416 case 23:
1417 printf_filtered (" %s-bit Data (%s Exp-%s%s)",
1418 descr.bit32 ? "32" : "16",
1419 descr.stype & 2 ? "Read/Write," : "Read-Only, ",
1420 descr.stype & 4 ? "down" : "up",
1421 descr.stype & 1 ? "" : ", N.Acc");
1422 break;
1423 case 24: /* code segments */
1424 case 25:
1425 case 26:
1426 case 27:
1427 case 28:
1428 case 29:
1429 case 30:
1430 case 31:
1431 printf_filtered (" %s-bit Code (%s, %sConf%s)",
1432 descr.bit32 ? "32" : "16",
1433 descr.stype & 2 ? "Exec/Read" : "Exec-Only",
1434 descr.stype & 4 ? "" : "N.",
1435 descr.stype & 1 ? "" : ", N.Acc");
1436 break;
1437 default:
1438 printf_filtered ("Unknown type 0x%02x", descr.stype);
1439 break;
1440 }
1441 puts_filtered ("\n");
1442 }
1443 else if (force)
1444 {
1445 printf_filtered ("0x%03x: ",
1446 type == 1
1447 ? idx : (idx * 8) | (type ? (cpl | 4) : 0));
1448 if (!descr.present)
1449 puts_filtered ("Segment not present\n");
1450 else
1451 printf_filtered ("Segment type 0x%02x is invalid in this table\n",
1452 descr.stype);
1453 }
1454 }
1455 else if (force)
1456 printf_filtered ("0x%03x: Cannot read this descriptor\n", idx);
1457 }
1458
1459 static void
1460 go32_sldt (char *arg, int from_tty)
1461 {
1462 struct dtr_reg gdtr;
1463 unsigned short ldtr = 0;
1464 int ldt_idx;
1465 struct seg_descr ldt_descr;
1466 long ldt_entry = -1L;
1467 int cpl = (prog_has_started ? a_tss.tss_cs : _my_cs ()) & 3;
1468
1469 if (arg && *arg)
1470 {
1471 while (*arg && isspace(*arg))
1472 arg++;
1473
1474 if (*arg)
1475 {
1476 ldt_entry = parse_and_eval_long (arg);
1477 if (ldt_entry < 0
1478 || (ldt_entry & 4) == 0
1479 || (ldt_entry & 3) != (cpl & 3))
1480 error ("Invalid LDT entry 0x%03x.", ldt_entry);
1481 }
1482 }
1483
1484 __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ );
1485 __asm__ __volatile__ ("sldt %0" : "=m" (ldtr) : /* no inputs */ );
1486 ldt_idx = ldtr / 8;
1487 if (ldt_idx == 0)
1488 puts_filtered ("There is no LDT.\n");
1489 /* LDT's entry in the GDT must have the type LDT, which is 2. */
1490 else if (get_descriptor (gdtr.base, ldt_idx, &ldt_descr) != 2)
1491 printf_filtered ("LDT is present (at %#x), but unreadable by GDB.\n",
1492 ldt_descr.base0
1493 | (ldt_descr.base1 << 16)
1494 | (ldt_descr.base2 << 24));
1495 else
1496 {
1497 unsigned base =
1498 ldt_descr.base0
1499 | (ldt_descr.base1 << 16)
1500 | (ldt_descr.base2 << 24);
1501 unsigned limit = ldt_descr.limit0 | (ldt_descr.limit1 << 16);
1502 int max_entry;
1503
1504 if (ldt_descr.page_granular)
1505 /* Page-granular segments must have the low 12 bits of their
1506 limit set. */
1507 limit = (limit << 12) | 0xfff;
1508 /* LDT cannot have more than 8K 8-byte entries, i.e. more than
1509 64KB. */
1510 if (limit > 0xffff)
1511 limit = 0xffff;
1512
1513 max_entry = (limit + 1) / 8;
1514
1515 if (ldt_entry >= 0)
1516 {
1517 if (ldt_entry > limit)
1518 error ("Invalid LDT entry %#x: outside valid limits [0..%#x]",
1519 ldt_entry, limit);
1520
1521 display_descriptor (ldt_descr.stype, base, ldt_entry / 8, 1);
1522 }
1523 else
1524 {
1525 int i;
1526
1527 for (i = 0; i < max_entry; i++)
1528 display_descriptor (ldt_descr.stype, base, i, 0);
1529 }
1530 }
1531 }
1532
1533 static void
1534 go32_sgdt (char *arg, int from_tty)
1535 {
1536 struct dtr_reg gdtr;
1537 long gdt_entry = -1L;
1538 int max_entry;
1539
1540 if (arg && *arg)
1541 {
1542 while (*arg && isspace(*arg))
1543 arg++;
1544
1545 if (*arg)
1546 {
1547 gdt_entry = parse_and_eval_long (arg);
1548 if (gdt_entry < 0 || (gdt_entry & 7) != 0)
1549 error ("Invalid GDT entry 0x%03x: not an integral multiple of 8.",
1550 gdt_entry);
1551 }
1552 }
1553
1554 __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ );
1555 max_entry = (gdtr.limit + 1) / 8;
1556
1557 if (gdt_entry >= 0)
1558 {
1559 if (gdt_entry > gdtr.limit)
1560 error ("Invalid GDT entry %#x: outside valid limits [0..%#x]",
1561 gdt_entry, gdtr.limit);
1562
1563 display_descriptor (0, gdtr.base, gdt_entry / 8, 1);
1564 }
1565 else
1566 {
1567 int i;
1568
1569 for (i = 0; i < max_entry; i++)
1570 display_descriptor (0, gdtr.base, i, 0);
1571 }
1572 }
1573
1574 static void
1575 go32_sidt (char *arg, int from_tty)
1576 {
1577 struct dtr_reg idtr;
1578 long idt_entry = -1L;
1579 int max_entry;
1580
1581 if (arg && *arg)
1582 {
1583 while (*arg && isspace(*arg))
1584 arg++;
1585
1586 if (*arg)
1587 {
1588 idt_entry = parse_and_eval_long (arg);
1589 if (idt_entry < 0)
1590 error ("Invalid (negative) IDT entry 0x%03x.", idt_entry);
1591 }
1592 }
1593
1594 __asm__ __volatile__ ("sidt %0" : "=m" (idtr) : /* no inputs */ );
1595 max_entry = (idtr.limit + 1) / 8;
1596 if (max_entry > 0x100) /* no more than 256 entries */
1597 max_entry = 0x100;
1598
1599 if (idt_entry >= 0)
1600 {
1601 if (idt_entry > idtr.limit)
1602 error ("Invalid IDT entry %#x: outside valid limits [0..%#x]",
1603 idt_entry, idtr.limit);
1604
1605 display_descriptor (1, idtr.base, idt_entry, 1);
1606 }
1607 else
1608 {
1609 int i;
1610
1611 for (i = 0; i < max_entry; i++)
1612 display_descriptor (1, idtr.base, i, 0);
1613 }
1614 }
1615
1616 static struct cmd_list_element *info_dos_cmdlist = NULL;
1617
1618 static void
1619 go32_info_dos_command (char *args, int from_tty)
1620 {
1621 help_list (info_dos_cmdlist, "info dos ", class_info, gdb_stdout);
1622 }
1623
1624 void
1625 _initialize_go32_nat (void)
1626 {
1627 init_go32_ops ();
1628 add_target (&go32_ops);
1629
1630 add_prefix_cmd ("dos", class_info, go32_info_dos_command,
1631 "Print information specific to DJGPP (a.k.a. MS-DOS) debugging.",
1632 &info_dos_cmdlist, "info dos ", 0, &infolist);
1633
1634 add_cmd ("sysinfo", class_info, go32_sysinfo,
1635 "Display information about the target system, including CPU, OS, DPMI, etc.",
1636 &info_dos_cmdlist);
1637 add_cmd ("ldt", class_info, go32_sldt,
1638 "Display entries in the LDT (Local Descriptor Table).\n"
1639 "Entry number (an expression) as an argument means display only that entry.",
1640 &info_dos_cmdlist);
1641 add_cmd ("gdt", class_info, go32_sgdt,
1642 "Display entries in the GDT (Global Descriptor Table).\n"
1643 "Entry number (an expression) as an argument means display only that entry.",
1644 &info_dos_cmdlist);
1645 add_cmd ("idt", class_info, go32_sidt,
1646 "Display entries in the IDT (Interrupt Descriptor Table).\n"
1647 "Entry number (an expression) as an argument means display only that entry.",
1648 &info_dos_cmdlist);
1649 }
1650
1651 pid_t
1652 tcgetpgrp (int fd)
1653 {
1654 if (isatty (fd))
1655 return SOME_PID;
1656 errno = ENOTTY;
1657 return -1;
1658 }
1659
1660 int
1661 tcsetpgrp (int fd, pid_t pgid)
1662 {
1663 if (isatty (fd) && pgid == SOME_PID)
1664 return 0;
1665 errno = pgid == SOME_PID ? ENOTTY : ENOSYS;
1666 return -1;
1667 }
This page took 0.067026 seconds and 4 git commands to generate.