2001-07-21 Chris Demetriou <cgd@broadcom.com>
[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 size_t cmdlen;
592
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. */
595 if (exec_file == 0)
596 exec_file = get_exec_file (1);
597
598 if (prog_has_started)
599 {
600 go32_stop ();
601 go32_kill_inferior ();
602 }
603 resume_signal = -1;
604 resume_is_step = 0;
605
606 /* Initialize child's cwd as empty to be initialized when starting
607 the child. */
608 *child_cwd = 0;
609
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");
614
615 /* Parse the command line and create redirections. */
616 if (strpbrk (args, "<>"))
617 {
618 if (redir_cmdline_parse (args, &child_cmd) == 0)
619 args = child_cmd.command;
620 else
621 error ("Syntax error in command line.");
622 }
623 else
624 child_cmd.command = xstrdup (args);
625
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.");
631
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. */
637 if (cmdlen < 127)
638 {
639 cmdline[0] = strlen (args);
640 cmdline[cmdlen + 1] = 13;
641 }
642 else
643 cmdline[0] = 0xff; /* signal v2loadimage it's a long command */
644
645 environ = env;
646
647 if (v2loadimage (exec_file, cmdline, start_state))
648 {
649 environ = env_save;
650 printf_unfiltered ("Load failed for image %s\n", exec_file);
651 exit (1);
652 }
653 environ = env_save;
654 free (cmdline);
655
656 edi_init (start_state);
657 #if __DJGPP_MINOR__ < 3
658 save_npx ();
659 #endif
660
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;
667 }
668
669 static void
670 go32_mourn_inferior (void)
671 {
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 ();
682 }
683
684 static int
685 go32_can_run (void)
686 {
687 return 1;
688 }
689
690 /* Hardware watchpoint support. */
691
692 #define D_REGS edi.dr
693 #define CONTROL D_REGS[7]
694 #define STATUS D_REGS[6]
695
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. */
699 void
700 go32_set_dr (int i, CORE_ADDR addr)
701 {
702 if (i < 0 || i > 3)
703 internal_error (__FILE__, __LINE__,
704 "Invalid register %d in go32_set_dr.\n", i);
705 D_REGS[i] = addr;
706 }
707
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. */
711 void
712 go32_set_dr7 (unsigned val)
713 {
714 CONTROL = val;
715 }
716
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. */
720 unsigned
721 go32_get_dr6 (void)
722 {
723 return STATUS;
724 }
725
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. */
728
729 static int
730 device_mode (int fd, int raw_p)
731 {
732 int oldmode, newmode;
733 __dpmi_regs regs;
734
735 regs.x.ax = 0x4400;
736 regs.x.bx = fd;
737 __dpmi_int (0x21, &regs);
738 if (regs.x.flags & 1)
739 return -1;
740 newmode = oldmode = regs.x.dx;
741
742 if (raw_p)
743 newmode |= 0x20;
744 else
745 newmode &= ~0x20;
746
747 if (oldmode & 0x80) /* Only for character dev */
748 {
749 regs.x.ax = 0x4401;
750 regs.x.bx = fd;
751 regs.x.dx = newmode & 0xff; /* Force upper byte zero, else it fails */
752 __dpmi_int (0x21, &regs);
753 if (regs.x.flags & 1)
754 return -1;
755 }
756 return (oldmode & 0x20) == 0x20;
757 }
758
759
760 static int inf_mode_valid = 0;
761 static int inf_terminal_mode;
762
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;
768
769 static void
770 go32_terminal_init (void)
771 {
772 inf_mode_valid = 0; /* reinitialize, in case they are restarting child */
773 terminal_is_ours = 1;
774 }
775
776 static void
777 go32_terminal_info (char *args, int from_tty)
778 {
779 printf_unfiltered ("Inferior's terminal is in %s mode.\n",
780 !inf_mode_valid
781 ? "default" : inf_terminal_mode ? "raw" : "cooked");
782
783 #if __DJGPP_MINOR__ > 2
784 if (child_cmd.redirection)
785 {
786 int i;
787
788 for (i = 0; i < DBG_HANDLES; i++)
789 {
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)
794 printf_unfiltered
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))
799 printf_unfiltered
800 ("\tFile handle %d appears to be redirected by inferior.\n", i);
801 }
802 }
803 #endif
804 }
805
806 static void
807 go32_terminal_inferior (void)
808 {
809 /* Redirect standard handles as child wants them. */
810 errno = 0;
811 if (redir_to_child (&child_cmd) == -1)
812 {
813 redir_to_debugger (&child_cmd);
814 error ("Cannot redirect standard handles for program: %s.",
815 strerror (errno));
816 }
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)
820 {
821 if (inf_mode_valid)
822 device_mode (0, inf_terminal_mode);
823 terminal_is_ours = 0;
824 }
825 }
826
827 static void
828 go32_terminal_ours (void)
829 {
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)
833 {
834 inf_terminal_mode = device_mode (0, 0);
835 if (inf_terminal_mode != -1)
836 inf_mode_valid = 1;
837 else
838 /* If device_mode returned -1, we don't know what happens with
839 handle 0 anymore, so make the info invalid. */
840 inf_mode_valid = 0;
841 terminal_is_ours = 1;
842
843 /* Restore debugger's standard handles. */
844 errno = 0;
845 if (redir_to_debugger (&child_cmd) == -1)
846 {
847 redir_to_child (&child_cmd);
848 error ("Cannot redirect standard handles for debugger: %s.",
849 strerror (errno));
850 }
851 }
852 }
853
854 static void
855 init_go32_ops (void)
856 {
857 go32_ops.to_shortname = "djgpp";
858 go32_ops.to_longname = "djgpp target process";
859 go32_ops.to_doc =
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;
891
892 /* Initialize child's cwd as empty to be initialized when starting
893 the child. */
894 *child_cwd = 0;
895
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");
900
901 /* We are always processing GCC-compiled programs. */
902 processing_gcc_compilation = 2;
903 }
904
905 unsigned short windows_major, windows_minor;
906
907 /* Compute the version Windows reports via Int 2Fh/AX=1600h. */
908 static void
909 go32_get_windows_version(void)
910 {
911 __dpmi_regs r;
912
913 r.x.ax = 0x1600;
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))
917 {
918 windows_major = r.h.al;
919 windows_minor = r.h.ah;
920 }
921 else
922 windows_major = 0xff; /* meaning no Windows */
923 }
924
925 /* A subroutine of go32_sysinfo to display memory info. */
926 static void
927 print_mem (unsigned long datum, const char *header, int in_pages_p)
928 {
929 if (datum != 0xffffffffUL)
930 {
931 if (in_pages_p)
932 datum <<= 12;
933 puts_filtered (header);
934 if (datum > 1024)
935 {
936 printf_filtered ("%lu KB", datum >> 10);
937 if (datum > 1024 * 1024)
938 printf_filtered (" (%lu MB)", datum >> 20);
939 }
940 else
941 printf_filtered ("%lu Bytes", datum);
942 puts_filtered ("\n");
943 }
944 }
945
946 /* Display assorted information about the underlying OS. */
947 static void
948 go32_sysinfo (char *arg, int from_tty)
949 {
950 struct utsname u;
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;
955 int dpmi_flags;
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;
960 long eflags;
961 __dpmi_free_mem_info mem_info;
962 __dpmi_regs regs;
963
964 cpuid_vendor[0] = '\0';
965 if (uname (&u))
966 strcpy (u.machine, "Unknown x86");
967 else if (u.machine[0] == 'i' && u.machine[1] > 4)
968 {
969 /* CPUID with EAX = 0 returns the Vendor ID. */
970 __asm__ __volatile__ ("xorl %%ebx, %%ebx;"
971 "xorl %%ecx, %%ecx;"
972 "xorl %%edx, %%edx;"
973 "movl $0, %%eax;"
974 "cpuid;"
975 "movl %%ebx, %0;"
976 "movl %%edx, %1;"
977 "movl %%ecx, %2;"
978 "movl %%eax, %3;"
979 : "=m" (cpuid_vendor[0]),
980 "=m" (cpuid_vendor[4]),
981 "=m" (cpuid_vendor[8]),
982 "=m" (cpuid_max)
983 :
984 : "%eax", "%ebx", "%ecx", "%edx");
985 cpuid_vendor[12] = '\0';
986 }
987
988 printf_filtered ("CPU Type.......................%s", u.machine);
989 if (cpuid_vendor[0])
990 printf_filtered (" (%s)", cpuid_vendor);
991 puts_filtered ("\n");
992
993 /* CPUID with EAX = 1 returns processor signature and features. */
994 if (cpuid_max >= 1)
995 {
996 static char *brand_name[] = {
997 "",
998 " Celeron",
999 " III",
1000 " III Xeon",
1001 "", "", "", "",
1002 " 4"
1003 };
1004 char cpu_string[80];
1005 char cpu_brand[20];
1006 unsigned brand_idx;
1007 int intel_p = strcmp (cpuid_vendor, "GenuineIntel") == 0;
1008 int amd_p = strcmp (cpuid_vendor, "AuthenticAMD") == 0;
1009 unsigned cpu_family, cpu_model;
1010
1011 __asm__ __volatile__ ("movl $1, %%eax;"
1012 "cpuid;"
1013 : "=a" (cpuid_eax),
1014 "=b" (cpuid_ebx),
1015 "=d" (cpuid_edx)
1016 :
1017 : "%ecx");
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';
1022 if (intel_p)
1023 {
1024 if (brand_idx > 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)
1029 {
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");
1036 }
1037 else if (cpu_family == 6 && cpu_model < 8)
1038 {
1039 switch (cpu_model)
1040 {
1041 case 1:
1042 strcpy (cpu_brand, " Pro");
1043 break;
1044 case 3:
1045 strcpy (cpu_brand, " II");
1046 break;
1047 case 5:
1048 strcpy (cpu_brand, " II Xeon");
1049 break;
1050 case 6:
1051 strcpy (cpu_brand, " Celeron");
1052 break;
1053 case 7:
1054 strcpy (cpu_brand, " III");
1055 break;
1056 }
1057 }
1058 }
1059 else if (amd_p)
1060 {
1061 switch (cpu_family)
1062 {
1063 case 4:
1064 strcpy (cpu_brand, "486/5x86");
1065 break;
1066 case 5:
1067 switch (cpu_model)
1068 {
1069 case 0:
1070 case 1:
1071 case 2:
1072 case 3:
1073 strcpy (cpu_brand, "-K5");
1074 break;
1075 case 6:
1076 case 7:
1077 strcpy (cpu_brand, "-K6");
1078 break;
1079 case 8:
1080 strcpy (cpu_brand, "-K6-2");
1081 break;
1082 case 9:
1083 strcpy (cpu_brand, "-K6-III");
1084 break;
1085 }
1086 break;
1087 case 6:
1088 switch (cpu_model)
1089 {
1090 case 1:
1091 case 2:
1092 case 4:
1093 strcpy (cpu_brand, " Athlon");
1094 break;
1095 case 3:
1096 strcpy (cpu_brand, " Duron");
1097 break;
1098 }
1099 break;
1100 }
1101 }
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))
1109 {
1110 puts_filtered ("CPU Features...................");
1111 /* We only list features which might be useful in the DPMI
1112 environment. */
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 ");
1127 if (amd_p)
1128 {
1129 if ((cpuid_edx & (1 << 31)) != 0)
1130 puts_filtered ("3DNow! ");
1131 if ((cpuid_edx & (1 << 30)) != 0)
1132 puts_filtered ("3DNow!Ext");
1133 }
1134 puts_filtered ("\n");
1135 }
1136 }
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");
1143 if (!windows_major)
1144 go32_get_windows_version ();
1145 if (windows_major != 0xff)
1146 {
1147 const char *windows_flavor;
1148
1149 printf_filtered ("Windows Version................%d.%02d (Windows ",
1150 windows_major, windows_minor);
1151 switch (windows_major)
1152 {
1153 case 3:
1154 windows_flavor = "3.X";
1155 break;
1156 case 4:
1157 switch (windows_minor)
1158 {
1159 case 0:
1160 windows_flavor = "95, 95A, or 95B";
1161 break;
1162 case 3:
1163 windows_flavor = "95B OSR2.1 or 95C OSR2.5";
1164 break;
1165 case 10:
1166 windows_flavor = "98 or 98 SE";
1167 break;
1168 case 90:
1169 windows_flavor = "ME";
1170 break;
1171 default:
1172 windows_flavor = "9X";
1173 break;
1174 }
1175 break;
1176 default:
1177 windows_flavor = "??";
1178 break;
1179 }
1180 printf_filtered ("%s)\n", windows_flavor);
1181 }
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)
1186 {
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));
1196 }
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);
1209
1210 /* a_tss is only initialized when the debuggee is first run. */
1211 if (prog_has_started)
1212 {
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");
1217 }
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);
1232
1233 regs.h.ah = 0x48;
1234 regs.x.bx = 0xffff;
1235 __dpmi_int (0x21, &regs);
1236 print_mem (regs.x.bx << 4, "Free DOS Memory................", 0);
1237 regs.x.ax = 0x5800;
1238 __dpmi_int (0x21, &regs);
1239 if ((regs.x.flags & 1) == 0)
1240 {
1241 static const char *dos_hilo[] = {
1242 "Low", "", "", "", "High", "", "", "", "High, then Low"
1243 };
1244 static const char *dos_fit[] = {
1245 "First", "Best", "Last"
1246 };
1247 int hilo_idx = (regs.x.ax >> 4) & 0x0f;
1248 int fit_idx = regs.x.ax & 0x0f;
1249
1250 if (hilo_idx > 8)
1251 hilo_idx = 0;
1252 if (fit_idx > 2)
1253 fit_idx = 0;
1254 printf_filtered ("DOS Memory Allocation..........%s memory, %s fit\n",
1255 dos_hilo[hilo_idx], dos_fit[fit_idx]);
1256 regs.x.ax = 0x5802;
1257 __dpmi_int (0x21, &regs);
1258 if ((regs.x.flags & 1) != 0)
1259 regs.h.al = 0;
1260 printfi_filtered (31, "UMBs %sin DOS memory chain\n",
1261 regs.h.al == 0 ? "not " : "");
1262 }
1263 }
1264
1265 struct seg_descr {
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));
1278 };
1279
1280 struct gate_descr {
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));
1289 };
1290
1291 /* Read LEN bytes starting at logical address ADDR, and put the result
1292 into DEST. Return 1 if success, zero if not. */
1293 static int
1294 read_memory_region (unsigned long addr, void *dest, size_t len)
1295 {
1296 unsigned long dos_ds_limit = __dpmi_get_segment_limit (_dos_ds);
1297
1298 /* For the low memory, we can simply use _dos_ds. */
1299 if (addr <= dos_ds_limit - len)
1300 dosmemget (addr, len, dest);
1301 else
1302 {
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);
1306
1307 if (sel <= 0
1308 || __dpmi_set_segment_base_address (sel, addr) == -1
1309 || __dpmi_set_segment_limit (sel, len - 1) == -1)
1310 return 0;
1311 movedata (sel, 0, _my_ds (), (unsigned)dest, len);
1312 __dpmi_free_ldt_descriptor (sel);
1313 }
1314 return 1;
1315 }
1316
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. */
1320 static int
1321 get_descriptor (unsigned long table_base, int idx, void *descr)
1322 {
1323 unsigned long addr = table_base + idx * 8; /* 8 bytes per entry */
1324
1325 if (read_memory_region (addr, descr, 8))
1326 return (int)((struct seg_descr *)descr)->stype;
1327 return -1;
1328 }
1329
1330 struct dtr_reg {
1331 unsigned short limit __attribute__((packed));
1332 unsigned long base __attribute__((packed));
1333 };
1334
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. */
1338 static void
1339 display_descriptor (unsigned type, unsigned long base_addr, int idx, int force)
1340 {
1341 struct seg_descr descr;
1342 struct gate_descr gate;
1343
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)
1348 {
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 */
1355 };
1356
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;
1361
1362 if (descr.present
1363 && (allowed_descriptors[type] & (1 << descr.stype)) != 0)
1364 {
1365 printf_filtered ("0x%03x: ",
1366 type == 1
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);
1375
1376 switch (descr.stype)
1377 {
1378 case 1:
1379 case 3:
1380 printf_filtered (" 16-bit TSS (task %sactive)",
1381 descr.stype == 3 ? "" : "in");
1382 break;
1383 case 2:
1384 puts_filtered (" LDT");
1385 break;
1386 case 4:
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)",
1391 gate.param_count);
1392 break;
1393 case 5:
1394 printf_filtered ("TSS selector=0x%04x", descr.base0);
1395 printfi_filtered (16, "Task Gate");
1396 break;
1397 case 6:
1398 case 7:
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");
1404 break;
1405 case 9:
1406 case 11:
1407 printf_filtered (" 32-bit TSS (task %sactive)",
1408 descr.stype == 3 ? "" : "in");
1409 break;
1410 case 12:
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)",
1415 gate.param_count);
1416 break;
1417 case 14:
1418 case 15:
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");
1424 break;
1425 case 16: /* data segments */
1426 case 17:
1427 case 18:
1428 case 19:
1429 case 20:
1430 case 21:
1431 case 22:
1432 case 23:
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");
1438 break;
1439 case 24: /* code segments */
1440 case 25:
1441 case 26:
1442 case 27:
1443 case 28:
1444 case 29:
1445 case 30:
1446 case 31:
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");
1452 break;
1453 default:
1454 printf_filtered ("Unknown type 0x%02x", descr.stype);
1455 break;
1456 }
1457 puts_filtered ("\n");
1458 }
1459 else if (force)
1460 {
1461 printf_filtered ("0x%03x: ",
1462 type == 1
1463 ? idx : (idx * 8) | (type ? (cpl | 4) : 0));
1464 if (!descr.present)
1465 puts_filtered ("Segment not present\n");
1466 else
1467 printf_filtered ("Segment type 0x%02x is invalid in this table\n",
1468 descr.stype);
1469 }
1470 }
1471 else if (force)
1472 printf_filtered ("0x%03x: Cannot read this descriptor\n", idx);
1473 }
1474
1475 static void
1476 go32_sldt (char *arg, int from_tty)
1477 {
1478 struct dtr_reg gdtr;
1479 unsigned short ldtr = 0;
1480 int ldt_idx;
1481 struct seg_descr ldt_descr;
1482 long ldt_entry = -1L;
1483 int cpl = (prog_has_started ? a_tss.tss_cs : _my_cs ()) & 3;
1484
1485 if (arg && *arg)
1486 {
1487 while (*arg && isspace(*arg))
1488 arg++;
1489
1490 if (*arg)
1491 {
1492 ldt_entry = parse_and_eval_long (arg);
1493 if (ldt_entry < 0
1494 || (ldt_entry & 4) == 0
1495 || (ldt_entry & 3) != (cpl & 3))
1496 error ("Invalid LDT entry 0x%03x.", ldt_entry);
1497 }
1498 }
1499
1500 __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ );
1501 __asm__ __volatile__ ("sldt %0" : "=m" (ldtr) : /* no inputs */ );
1502 ldt_idx = ldtr / 8;
1503 if (ldt_idx == 0)
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",
1508 ldt_descr.base0
1509 | (ldt_descr.base1 << 16)
1510 | (ldt_descr.base2 << 24));
1511 else
1512 {
1513 unsigned base =
1514 ldt_descr.base0
1515 | (ldt_descr.base1 << 16)
1516 | (ldt_descr.base2 << 24);
1517 unsigned limit = ldt_descr.limit0 | (ldt_descr.limit1 << 16);
1518 int max_entry;
1519
1520 if (ldt_descr.page_granular)
1521 /* Page-granular segments must have the low 12 bits of their
1522 limit set. */
1523 limit = (limit << 12) | 0xfff;
1524 /* LDT cannot have more than 8K 8-byte entries, i.e. more than
1525 64KB. */
1526 if (limit > 0xffff)
1527 limit = 0xffff;
1528
1529 max_entry = (limit + 1) / 8;
1530
1531 if (ldt_entry >= 0)
1532 {
1533 if (ldt_entry > limit)
1534 error ("Invalid LDT entry %#x: outside valid limits [0..%#x]",
1535 ldt_entry, limit);
1536
1537 display_descriptor (ldt_descr.stype, base, ldt_entry / 8, 1);
1538 }
1539 else
1540 {
1541 int i;
1542
1543 for (i = 0; i < max_entry; i++)
1544 display_descriptor (ldt_descr.stype, base, i, 0);
1545 }
1546 }
1547 }
1548
1549 static void
1550 go32_sgdt (char *arg, int from_tty)
1551 {
1552 struct dtr_reg gdtr;
1553 long gdt_entry = -1L;
1554 int max_entry;
1555
1556 if (arg && *arg)
1557 {
1558 while (*arg && isspace(*arg))
1559 arg++;
1560
1561 if (*arg)
1562 {
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.",
1566 gdt_entry);
1567 }
1568 }
1569
1570 __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ );
1571 max_entry = (gdtr.limit + 1) / 8;
1572
1573 if (gdt_entry >= 0)
1574 {
1575 if (gdt_entry > gdtr.limit)
1576 error ("Invalid GDT entry %#x: outside valid limits [0..%#x]",
1577 gdt_entry, gdtr.limit);
1578
1579 display_descriptor (0, gdtr.base, gdt_entry / 8, 1);
1580 }
1581 else
1582 {
1583 int i;
1584
1585 for (i = 0; i < max_entry; i++)
1586 display_descriptor (0, gdtr.base, i, 0);
1587 }
1588 }
1589
1590 static void
1591 go32_sidt (char *arg, int from_tty)
1592 {
1593 struct dtr_reg idtr;
1594 long idt_entry = -1L;
1595 int max_entry;
1596
1597 if (arg && *arg)
1598 {
1599 while (*arg && isspace(*arg))
1600 arg++;
1601
1602 if (*arg)
1603 {
1604 idt_entry = parse_and_eval_long (arg);
1605 if (idt_entry < 0)
1606 error ("Invalid (negative) IDT entry 0x%03x.", idt_entry);
1607 }
1608 }
1609
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 */
1613 max_entry = 0x100;
1614
1615 if (idt_entry >= 0)
1616 {
1617 if (idt_entry > idtr.limit)
1618 error ("Invalid IDT entry %#x: outside valid limits [0..%#x]",
1619 idt_entry, idtr.limit);
1620
1621 display_descriptor (1, idtr.base, idt_entry, 1);
1622 }
1623 else
1624 {
1625 int i;
1626
1627 for (i = 0; i < max_entry; i++)
1628 display_descriptor (1, idtr.base, i, 0);
1629 }
1630 }
1631
1632 static struct cmd_list_element *info_dos_cmdlist = NULL;
1633
1634 static void
1635 go32_info_dos_command (char *args, int from_tty)
1636 {
1637 help_list (info_dos_cmdlist, "info dos ", class_info, gdb_stdout);
1638 }
1639
1640 void
1641 _initialize_go32_nat (void)
1642 {
1643 init_go32_ops ();
1644 add_target (&go32_ops);
1645
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);
1649
1650 add_cmd ("sysinfo", class_info, go32_sysinfo,
1651 "Display information about the target system, including CPU, OS, DPMI, etc.",
1652 &info_dos_cmdlist);
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.",
1656 &info_dos_cmdlist);
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.",
1660 &info_dos_cmdlist);
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.",
1664 &info_dos_cmdlist);
1665 }
1666
1667 pid_t
1668 tcgetpgrp (int fd)
1669 {
1670 if (isatty (fd))
1671 return SOME_PID;
1672 errno = ENOTTY;
1673 return -1;
1674 }
1675
1676 int
1677 tcsetpgrp (int fd, pid_t pgid)
1678 {
1679 if (isatty (fd) && pgid == SOME_PID)
1680 return 0;
1681 errno = pgid == SOME_PID ? ENOTTY : ENOSYS;
1682 return -1;
1683 }
This page took 0.09538 seconds and 4 git commands to generate.