Switch the license of all .c files to GPLv3.
[deliverable/binutils-gdb.git] / gdb / go32-nat.c
CommitLineData
e49d4fa6 1/* Native debugging support for Intel x86 running DJGPP.
6aba47ca 2 Copyright (C) 1997, 1999, 2000, 2001, 2005, 2006, 2007
281b533b 3 Free Software Foundation, Inc.
e49d4fa6
SS
4 Written by Robert Hoehne.
5
c5aa993b 6 This file is part of GDB.
e49d4fa6 7
c5aa993b
JM
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
c5aa993b 11 (at your option) any later version.
e49d4fa6 12
c5aa993b
JM
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
e49d4fa6 17
c5aa993b 18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
e49d4fa6
SS
20
21#include <fcntl.h>
22
23#include "defs.h"
e49d4fa6 24#include "inferior.h"
03f2053f 25#include "gdb_wait.h"
e49d4fa6
SS
26#include "gdbcore.h"
27#include "command.h"
d8c852a1 28#include "gdbcmd.h"
e49d4fa6 29#include "floatformat.h"
0fff5247 30#include "buildsym.h"
e750d25e 31#include "i387-tdep.h"
e1195560 32#include "i386-tdep.h"
4d277981 33#include "value.h"
4e052eda 34#include "regcache.h"
4d277981 35#include "gdb_string.h"
eaae3919 36#include "top.h"
e49d4fa6 37
10ba702d 38#include <stdio.h> /* might be required for __DJGPP_MINOR__ */
e49d4fa6 39#include <stdlib.h>
10ba702d 40#include <ctype.h>
53a5351d 41#include <errno.h>
c2c6d25f 42#include <unistd.h>
10ba702d 43#include <sys/utsname.h>
53a5351d 44#include <io.h>
10ba702d 45#include <dos.h>
53a5351d 46#include <dpmi.h>
10ba702d 47#include <go32.h>
9f20bf26 48#include <sys/farptr.h>
e49d4fa6
SS
49#include <debug/v2load.h>
50#include <debug/dbgcom.h>
53a5351d
JM
51#if __DJGPP_MINOR__ > 2
52#include <debug/redir.h>
53#endif
e49d4fa6 54
b83266a0
SS
55#if __DJGPP_MINOR__ < 3
56/* This code will be provided from DJGPP 2.03 on. Until then I code it
57 here */
c5aa993b
JM
58typedef struct
59 {
60 unsigned short sig0;
61 unsigned short sig1;
62 unsigned short sig2;
63 unsigned short sig3;
64 unsigned short exponent:15;
65 unsigned short sign:1;
66 }
67NPXREG;
68
69typedef struct
70 {
71 unsigned int control;
72 unsigned int status;
73 unsigned int tag;
74 unsigned int eip;
75 unsigned int cs;
76 unsigned int dataptr;
77 unsigned int datasel;
78 NPXREG reg[8];
79 }
80NPX;
b83266a0
SS
81
82static NPX npx;
83
c5aa993b
JM
84static void save_npx (void); /* Save the FPU of the debugged program */
85static void load_npx (void); /* Restore the FPU of the debugged program */
b83266a0
SS
86
87/* ------------------------------------------------------------------------- */
88/* Store the contents of the NPX in the global variable `npx'. */
c5aa993b 89/* *INDENT-OFF* */
b83266a0
SS
90
91static void
92save_npx (void)
93{
1f5dc670
EZ
94 asm ("inb $0xa0, %%al \n\
95 testb $0x20, %%al \n\
96 jz 1f \n\
82cc5033
EZ
97 xorb %%al, %%al \n\
98 outb %%al, $0xf0 \n\
1f5dc670 99 movb $0x20, %%al \n\
82cc5033
EZ
100 outb %%al, $0xa0 \n\
101 outb %%al, $0x20 \n\
1f5dc670 1021: \n\
82cc5033 103 fnsave %0 \n\
c5aa993b
JM
104 fwait "
105: "=m" (npx)
106: /* No input */
107: "%eax");
b83266a0 108}
c5aa993b
JM
109
110/* *INDENT-ON* */
111
112
b83266a0
SS
113/* ------------------------------------------------------------------------- */
114/* Reload the contents of the NPX from the global variable `npx'. */
115
116static void
117load_npx (void)
118{
ba8629a9 119 asm ("frstor %0":"=m" (npx));
b83266a0 120}
53a5351d
JM
121/* ------------------------------------------------------------------------- */
122/* Stubs for the missing redirection functions. */
123typedef struct {
124 char *command;
125 int redirected;
126} cmdline_t;
127
4d277981 128void
ba8629a9
EZ
129redir_cmdline_delete (cmdline_t *ptr)
130{
131 ptr->redirected = 0;
132}
4d277981
EZ
133
134int
135redir_cmdline_parse (const char *args, cmdline_t *ptr)
53a5351d
JM
136{
137 return -1;
138}
ba8629a9 139
4d277981
EZ
140int
141redir_to_child (cmdline_t *ptr)
53a5351d
JM
142{
143 return 1;
144}
ba8629a9 145
4d277981
EZ
146int
147redir_to_debugger (cmdline_t *ptr)
53a5351d
JM
148{
149 return 1;
150}
ba8629a9 151
4d277981 152int
ba8629a9
EZ
153redir_debug_init (cmdline_t *ptr)
154{
155 return 0;
156}
b83266a0
SS
157#endif /* __DJGPP_MINOR < 3 */
158
53a5351d
JM
159typedef enum { wp_insert, wp_remove, wp_count } wp_op;
160
161/* This holds the current reference counts for each debug register. */
162static int dr_ref_count[4];
163
e49d4fa6
SS
164#define SOME_PID 42
165
e49d4fa6 166static int prog_has_started = 0;
c5aa993b
JM
167static void go32_open (char *name, int from_tty);
168static void go32_close (int quitting);
169static void go32_attach (char *args, int from_tty);
170static void go32_detach (char *args, int from_tty);
39f77062
KB
171static void go32_resume (ptid_t ptid, int step,
172 enum target_signal siggnal);
173static ptid_t go32_wait (ptid_t ptid,
174 struct target_waitstatus *status);
56be3814
UW
175static void go32_fetch_registers (struct regcache *, int regno);
176static void store_register (const struct regcache *, int regno);
177static void go32_store_registers (struct regcache *, int regno);
316f2060 178static void go32_prepare_to_store (struct regcache *);
c5aa993b 179static int go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
a17b5c4e
EZ
180 int write,
181 struct mem_attrib *attrib,
182 struct target_ops *target);
c5aa993b
JM
183static void go32_files_info (struct target_ops *target);
184static void go32_stop (void);
185static void go32_kill_inferior (void);
c27cda74 186static void go32_create_inferior (char *exec_file, char *args, char **env, int from_tty);
c5aa993b
JM
187static void go32_mourn_inferior (void);
188static int go32_can_run (void);
b83266a0
SS
189
190static struct target_ops go32_ops;
c5aa993b
JM
191static void go32_terminal_init (void);
192static void go32_terminal_inferior (void);
193static void go32_terminal_ours (void);
e49d4fa6 194
53a5351d 195#define r_ofs(x) (offsetof(TSS,x))
e49d4fa6
SS
196
197static struct
198{
53a5351d
JM
199 size_t tss_ofs;
200 size_t size;
e49d4fa6
SS
201}
202regno_mapping[] =
203{
0fff5247
EZ
204 {r_ofs (tss_eax), 4}, /* normal registers, from a_tss */
205 {r_ofs (tss_ecx), 4},
206 {r_ofs (tss_edx), 4},
207 {r_ofs (tss_ebx), 4},
208 {r_ofs (tss_esp), 4},
209 {r_ofs (tss_ebp), 4},
210 {r_ofs (tss_esi), 4},
211 {r_ofs (tss_edi), 4},
212 {r_ofs (tss_eip), 4},
213 {r_ofs (tss_eflags), 4},
214 {r_ofs (tss_cs), 2},
215 {r_ofs (tss_ss), 2},
216 {r_ofs (tss_ds), 2},
217 {r_ofs (tss_es), 2},
218 {r_ofs (tss_fs), 2},
219 {r_ofs (tss_gs), 2},
220 {0, 10}, /* 8 FP registers, from npx.reg[] */
221 {1, 10},
222 {2, 10},
223 {3, 10},
224 {4, 10},
225 {5, 10},
226 {6, 10},
227 {7, 10},
53a5351d 228 /* The order of the next 7 registers must be consistent
0fff5247
EZ
229 with their numbering in config/i386/tm-i386.h, which see. */
230 {0, 2}, /* control word, from npx */
231 {4, 2}, /* status word, from npx */
232 {8, 2}, /* tag word, from npx */
233 {16, 2}, /* last FP exception CS from npx */
234 {12, 4}, /* last FP exception EIP from npx */
235 {24, 2}, /* last FP exception operand selector from npx */
236 {20, 4}, /* last FP exception operand offset from npx */
237 {18, 2} /* last FP opcode from npx */
e49d4fa6
SS
238};
239
240static struct
241 {
242 int go32_sig;
0fff5247 243 enum target_signal gdb_sig;
e49d4fa6
SS
244 }
245sig_map[] =
246{
0fff5247
EZ
247 {0, TARGET_SIGNAL_FPE},
248 {1, TARGET_SIGNAL_TRAP},
53a5351d
JM
249 /* Exception 2 is triggered by the NMI. DJGPP handles it as SIGILL,
250 but I think SIGBUS is better, since the NMI is usually activated
251 as a result of a memory parity check failure. */
0fff5247
EZ
252 {2, TARGET_SIGNAL_BUS},
253 {3, TARGET_SIGNAL_TRAP},
254 {4, TARGET_SIGNAL_FPE},
255 {5, TARGET_SIGNAL_SEGV},
256 {6, TARGET_SIGNAL_ILL},
257 {7, TARGET_SIGNAL_EMT}, /* no-coprocessor exception */
258 {8, TARGET_SIGNAL_SEGV},
259 {9, TARGET_SIGNAL_SEGV},
260 {10, TARGET_SIGNAL_BUS},
261 {11, TARGET_SIGNAL_SEGV},
262 {12, TARGET_SIGNAL_SEGV},
263 {13, TARGET_SIGNAL_SEGV},
264 {14, TARGET_SIGNAL_SEGV},
265 {16, TARGET_SIGNAL_FPE},
266 {17, TARGET_SIGNAL_BUS},
267 {31, TARGET_SIGNAL_ILL},
268 {0x1b, TARGET_SIGNAL_INT},
269 {0x75, TARGET_SIGNAL_FPE},
270 {0x78, TARGET_SIGNAL_ALRM},
271 {0x79, TARGET_SIGNAL_INT},
272 {0x7a, TARGET_SIGNAL_QUIT},
273 {-1, TARGET_SIGNAL_LAST}
e49d4fa6
SS
274};
275
53a5351d
JM
276static struct {
277 enum target_signal gdb_sig;
278 int djgpp_excepno;
279} excepn_map[] = {
0fff5247
EZ
280 {TARGET_SIGNAL_0, -1},
281 {TARGET_SIGNAL_ILL, 6}, /* Invalid Opcode */
282 {TARGET_SIGNAL_EMT, 7}, /* triggers SIGNOFP */
283 {TARGET_SIGNAL_SEGV, 13}, /* GPF */
284 {TARGET_SIGNAL_BUS, 17}, /* Alignment Check */
53a5351d
JM
285 /* The rest are fake exceptions, see dpmiexcp.c in djlsr*.zip for
286 details. */
0fff5247
EZ
287 {TARGET_SIGNAL_TERM, 0x1b}, /* triggers Ctrl-Break type of SIGINT */
288 {TARGET_SIGNAL_FPE, 0x75},
289 {TARGET_SIGNAL_INT, 0x79},
290 {TARGET_SIGNAL_QUIT, 0x7a},
291 {TARGET_SIGNAL_ALRM, 0x78}, /* triggers SIGTIMR */
292 {TARGET_SIGNAL_PROF, 0x78},
293 {TARGET_SIGNAL_LAST, -1}
53a5351d
JM
294};
295
e49d4fa6 296static void
4d277981 297go32_open (char *name, int from_tty)
e49d4fa6 298{
53a5351d 299 printf_unfiltered ("Done. Use the \"run\" command to run the program.\n");
e49d4fa6
SS
300}
301
302static void
4d277981 303go32_close (int quitting)
e49d4fa6
SS
304{
305}
306
307static void
4d277981 308go32_attach (char *args, int from_tty)
e49d4fa6 309{
8a3fe4f8 310 error (_("\
53a5351d 311You cannot attach to a running program on this platform.\n\
8a3fe4f8 312Use the `run' command to run DJGPP programs."));
e49d4fa6
SS
313}
314
315static void
4d277981 316go32_detach (char *args, int from_tty)
e49d4fa6
SS
317{
318}
319
320static int resume_is_step;
53a5351d 321static int resume_signal = -1;
e49d4fa6
SS
322
323static void
39f77062 324go32_resume (ptid_t ptid, int step, enum target_signal siggnal)
c5aa993b 325{
53a5351d
JM
326 int i;
327
c5aa993b 328 resume_is_step = step;
53a5351d
JM
329
330 if (siggnal != TARGET_SIGNAL_0 && siggnal != TARGET_SIGNAL_TRAP)
331 {
0fff5247
EZ
332 for (i = 0, resume_signal = -1;
333 excepn_map[i].gdb_sig != TARGET_SIGNAL_LAST; i++)
53a5351d
JM
334 if (excepn_map[i].gdb_sig == siggnal)
335 {
336 resume_signal = excepn_map[i].djgpp_excepno;
337 break;
338 }
339 if (resume_signal == -1)
340 printf_unfiltered ("Cannot deliver signal %s on this platform.\n",
341 target_signal_to_name (siggnal));
342 }
c5aa993b 343}
e49d4fa6 344
53a5351d
JM
345static char child_cwd[FILENAME_MAX];
346
31616044 347static ptid_t
39f77062 348go32_wait (ptid_t ptid, struct target_waitstatus *status)
e49d4fa6
SS
349{
350 int i;
53a5351d 351 unsigned char saved_opcode;
0fff5247 352 unsigned long INT3_addr = 0;
53a5351d 353 int stepping_over_INT = 0;
e49d4fa6 354
53a5351d 355 a_tss.tss_eflags &= 0xfeff; /* reset the single-step flag (TF) */
e49d4fa6 356 if (resume_is_step)
53a5351d
JM
357 {
358 /* If the next instruction is INT xx or INTO, we need to handle
359 them specially. Intel manuals say that these instructions
360 reset the single-step flag (a.k.a. TF). However, it seems
361 that, at least in the DPMI environment, and at least when
362 stepping over the DPMI interrupt 31h, the problem is having
363 TF set at all when INT 31h is executed: the debuggee either
364 crashes (and takes the system with it) or is killed by a
365 SIGTRAP.
366
367 So we need to emulate single-step mode: we put an INT3 opcode
368 right after the INT xx instruction, let the debuggee run
369 until it hits INT3 and stops, then restore the original
370 instruction which we overwrote with the INT3 opcode, and back
371 up the debuggee's EIP to that instruction. */
372 read_child (a_tss.tss_eip, &saved_opcode, 1);
373 if (saved_opcode == 0xCD || saved_opcode == 0xCE)
374 {
375 unsigned char INT3_opcode = 0xCC;
376
377 INT3_addr
378 = saved_opcode == 0xCD ? a_tss.tss_eip + 2 : a_tss.tss_eip + 1;
379 stepping_over_INT = 1;
380 read_child (INT3_addr, &saved_opcode, 1);
381 write_child (INT3_addr, &INT3_opcode, 1);
382 }
383 else
384 a_tss.tss_eflags |= 0x0100; /* normal instruction: set TF */
385 }
386
387 /* The special value FFFFh in tss_trap indicates to run_child that
388 tss_irqn holds a signal to be delivered to the debuggee. */
389 if (resume_signal <= -1)
390 {
391 a_tss.tss_trap = 0;
392 a_tss.tss_irqn = 0xff;
393 }
e49d4fa6 394 else
53a5351d
JM
395 {
396 a_tss.tss_trap = 0xffff; /* run_child looks for this */
397 a_tss.tss_irqn = resume_signal;
398 }
399
400 /* The child might change working directory behind our back. The
401 GDB users won't like the side effects of that when they work with
402 relative file names, and GDB might be confused by its current
403 directory not being in sync with the truth. So we always make a
404 point of changing back to where GDB thinks is its cwd, when we
405 return control to the debugger, but restore child's cwd before we
406 run it. */
3a45aed8
EZ
407 /* Initialize child_cwd, before the first call to run_child and not
408 in the initialization, so the child get also the changed directory
409 set with the gdb-command "cd ..." */
410 if (!*child_cwd)
411 /* Initialize child's cwd with the current one. */
412 getcwd (child_cwd, sizeof (child_cwd));
4d277981 413
53a5351d 414 chdir (child_cwd);
e49d4fa6 415
b83266a0 416#if __DJGPP_MINOR__ < 3
53a5351d 417 load_npx ();
b83266a0 418#endif
e49d4fa6 419 run_child ();
b83266a0 420#if __DJGPP_MINOR__ < 3
53a5351d 421 save_npx ();
b83266a0 422#endif
e49d4fa6 423
53a5351d
JM
424 /* Did we step over an INT xx instruction? */
425 if (stepping_over_INT && a_tss.tss_eip == INT3_addr + 1)
426 {
427 /* Restore the original opcode. */
428 a_tss.tss_eip--; /* EIP points *after* the INT3 instruction */
429 write_child (a_tss.tss_eip, &saved_opcode, 1);
430 /* Simulate a TRAP exception. */
431 a_tss.tss_irqn = 1;
432 a_tss.tss_eflags |= 0x0100;
433 }
434
435 getcwd (child_cwd, sizeof (child_cwd)); /* in case it has changed */
436 chdir (current_directory);
437
e49d4fa6
SS
438 if (a_tss.tss_irqn == 0x21)
439 {
440 status->kind = TARGET_WAITKIND_EXITED;
441 status->value.integer = a_tss.tss_eax & 0xff;
442 }
443 else
444 {
445 status->value.sig = TARGET_SIGNAL_UNKNOWN;
446 status->kind = TARGET_WAITKIND_STOPPED;
447 for (i = 0; sig_map[i].go32_sig != -1; i++)
448 {
449 if (a_tss.tss_irqn == sig_map[i].go32_sig)
450 {
53a5351d 451#if __DJGPP_MINOR__ < 3
e49d4fa6
SS
452 if ((status->value.sig = sig_map[i].gdb_sig) !=
453 TARGET_SIGNAL_TRAP)
454 status->kind = TARGET_WAITKIND_SIGNALLED;
53a5351d
JM
455#else
456 status->value.sig = sig_map[i].gdb_sig;
457#endif
e49d4fa6
SS
458 break;
459 }
460 }
461 }
31616044 462 return pid_to_ptid (SOME_PID);
e49d4fa6
SS
463}
464
465static void
56be3814 466fetch_register (struct regcache *regcache, int regno)
e49d4fa6 467{
3e8c568d 468 if (regno < gdbarch_fp0_regnum (current_gdbarch))
56be3814 469 regcache_raw_supply (regcache, regno,
23a6d369 470 (char *) &a_tss + regno_mapping[regno].tss_ofs);
23a34459 471 else if (i386_fp_regnum_p (regno) || i386_fpc_regnum_p (regno))
56be3814 472 i387_supply_fsave (regcache, regno, &npx);
89dea5aa
EZ
473 else
474 internal_error (__FILE__, __LINE__,
e2e0b3e5 475 _("Invalid register no. %d in fetch_register."), regno);
89dea5aa 476}
e49d4fa6 477
89dea5aa 478static void
56be3814 479go32_fetch_registers (struct regcache *regcache, int regno)
89dea5aa
EZ
480{
481 if (regno >= 0)
56be3814 482 fetch_register (regcache, regno);
89dea5aa 483 else
e49d4fa6 484 {
3e8c568d 485 for (regno = 0; regno < gdbarch_fp0_regnum (current_gdbarch); regno++)
56be3814
UW
486 fetch_register (regcache, regno);
487 i387_supply_fsave (regcache, -1, &npx);
e49d4fa6
SS
488 }
489}
490
491static void
56be3814 492store_register (const struct regcache *regcache, int regno)
e49d4fa6 493{
3e8c568d 494 if (regno < gdbarch_fp0_regnum (current_gdbarch))
56be3814 495 regcache_raw_collect (regcache, regno,
822c9732 496 (char *) &a_tss + regno_mapping[regno].tss_ofs);
23a34459 497 else if (i386_fp_regnum_p (regno) || i386_fpc_regnum_p (regno))
56be3814 498 i387_collect_fsave (regcache, regno, &npx);
e49d4fa6 499 else
8e65ff28 500 internal_error (__FILE__, __LINE__,
e2e0b3e5 501 _("Invalid register no. %d in store_register."), regno);
e49d4fa6
SS
502}
503
504static void
56be3814 505go32_store_registers (struct regcache *regcache, int regno)
e49d4fa6 506{
0fff5247 507 unsigned r;
e49d4fa6
SS
508
509 if (regno >= 0)
56be3814 510 store_register (regcache, regno);
e49d4fa6
SS
511 else
512 {
3e8c568d 513 for (r = 0; r < gdbarch_fp0_regnum (current_gdbarch); r++)
56be3814
UW
514 store_register (regcache, r);
515 i387_collect_fsave (regcache, -1, &npx);
e49d4fa6
SS
516 }
517}
518
519static void
316f2060 520go32_prepare_to_store (struct regcache *regcache)
e49d4fa6
SS
521{
522}
523
524static int
525go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
4d277981 526 struct mem_attrib *attrib, struct target_ops *target)
e49d4fa6
SS
527{
528 if (write)
529 {
530 if (write_child (memaddr, myaddr, len))
531 {
532 return 0;
533 }
534 else
535 {
536 return len;
537 }
538 }
539 else
540 {
541 if (read_child (memaddr, myaddr, len))
542 {
543 return 0;
544 }
545 else
546 {
547 return len;
548 }
549 }
550}
551
53a5351d
JM
552static cmdline_t child_cmd; /* parsed child's command line kept here */
553
e49d4fa6 554static void
4d277981 555go32_files_info (struct target_ops *target)
e49d4fa6 556{
53a5351d 557 printf_unfiltered ("You are running a DJGPP V2 program.\n");
e49d4fa6
SS
558}
559
560static void
561go32_stop (void)
562{
563 normal_stop ();
564 cleanup_client ();
39f77062 565 inferior_ptid = null_ptid;
e49d4fa6
SS
566 prog_has_started = 0;
567}
568
569static void
570go32_kill_inferior (void)
571{
53a5351d
JM
572 redir_cmdline_delete (&child_cmd);
573 resume_signal = -1;
574 resume_is_step = 0;
e49d4fa6
SS
575 unpush_target (&go32_ops);
576}
577
578static void
c27cda74 579go32_create_inferior (char *exec_file, char *args, char **env, int from_tty)
e49d4fa6 580{
4d277981 581 extern char **environ;
e49d4fa6
SS
582 jmp_buf start_state;
583 char *cmdline;
584 char **env_save = environ;
150985e3 585 size_t cmdlen;
e49d4fa6 586
0fff5247
EZ
587 /* If no exec file handed to us, get it from the exec-file command -- with
588 a good, common error message if none is specified. */
589 if (exec_file == 0)
590 exec_file = get_exec_file (1);
591
e49d4fa6
SS
592 if (prog_has_started)
593 {
b83266a0 594 go32_stop ();
e49d4fa6
SS
595 go32_kill_inferior ();
596 }
53a5351d
JM
597 resume_signal = -1;
598 resume_is_step = 0;
3a45aed8
EZ
599
600 /* Initialize child's cwd as empty to be initialized when starting
601 the child. */
602 *child_cwd = 0;
603
53a5351d
JM
604 /* Init command line storage. */
605 if (redir_debug_init (&child_cmd) == -1)
8e65ff28 606 internal_error (__FILE__, __LINE__,
e2e0b3e5 607 _("Cannot allocate redirection storage: not enough memory.\n"));
53a5351d
JM
608
609 /* Parse the command line and create redirections. */
610 if (strpbrk (args, "<>"))
611 {
612 if (redir_cmdline_parse (args, &child_cmd) == 0)
613 args = child_cmd.command;
614 else
8a3fe4f8 615 error (_("Syntax error in command line."));
53a5351d
JM
616 }
617 else
c2d11a7d 618 child_cmd.command = xstrdup (args);
e49d4fa6 619
150985e3
EZ
620 cmdlen = strlen (args);
621 /* v2loadimage passes command lines via DOS memory, so it cannot
622 possibly handle commands longer than 1MB. */
623 if (cmdlen > 1024*1024)
8a3fe4f8 624 error (_("Command line too long."));
150985e3
EZ
625
626 cmdline = xmalloc (cmdlen + 4);
e49d4fa6 627 strcpy (cmdline + 1, args);
150985e3
EZ
628 /* If the command-line length fits into DOS 126-char limits, use the
629 DOS command tail format; otherwise, tell v2loadimage to pass it
630 through a buffer in conventional memory. */
631 if (cmdlen < 127)
632 {
633 cmdline[0] = strlen (args);
634 cmdline[cmdlen + 1] = 13;
635 }
636 else
637 cmdline[0] = 0xff; /* signal v2loadimage it's a long command */
e49d4fa6
SS
638
639 environ = env;
640
641 if (v2loadimage (exec_file, cmdline, start_state))
642 {
643 environ = env_save;
644 printf_unfiltered ("Load failed for image %s\n", exec_file);
645 exit (1);
646 }
647 environ = env_save;
12a498f3 648 xfree (cmdline);
e49d4fa6
SS
649
650 edi_init (start_state);
53a5351d
JM
651#if __DJGPP_MINOR__ < 3
652 save_npx ();
653#endif
e49d4fa6 654
39f77062 655 inferior_ptid = pid_to_ptid (SOME_PID);
e49d4fa6
SS
656 push_target (&go32_ops);
657 clear_proceed_status ();
658 insert_breakpoints ();
b83266a0 659 prog_has_started = 1;
e49d4fa6
SS
660}
661
662static void
663go32_mourn_inferior (void)
664{
53a5351d
JM
665 /* We need to make sure all the breakpoint enable bits in the DR7
666 register are reset when the inferior exits. Otherwise, if they
667 rerun the inferior, the uncleared bits may cause random SIGTRAPs,
668 failure to set more watchpoints, and other calamities. It would
669 be nice if GDB itself would take care to remove all breakpoints
670 at all times, but it doesn't, probably under an assumption that
671 the OS cleans up when the debuggee exits. */
e24d4c64 672 i386_cleanup_dregs ();
e49d4fa6
SS
673 go32_kill_inferior ();
674 generic_mourn_inferior ();
675}
676
677static int
678go32_can_run (void)
679{
680 return 1;
681}
682
e49d4fa6
SS
683/* Hardware watchpoint support. */
684
e49d4fa6 685#define D_REGS edi.dr
e24d4c64
EZ
686#define CONTROL D_REGS[7]
687#define STATUS D_REGS[6]
53a5351d 688
e24d4c64
EZ
689/* Pass the address ADDR to the inferior in the I'th debug register.
690 Here we just store the address in D_REGS, the watchpoint will be
691 actually set up when go32_wait runs the debuggee. */
692void
693go32_set_dr (int i, CORE_ADDR addr)
e49d4fa6 694{
4d277981
EZ
695 if (i < 0 || i > 3)
696 internal_error (__FILE__, __LINE__,
e2e0b3e5 697 _("Invalid register %d in go32_set_dr.\n"), i);
e24d4c64 698 D_REGS[i] = addr;
e49d4fa6
SS
699}
700
e24d4c64
EZ
701/* Pass the value VAL to the inferior in the DR7 debug control
702 register. Here we just store the address in D_REGS, the watchpoint
703 will be actually set up when go32_wait runs the debuggee. */
704void
705go32_set_dr7 (unsigned val)
53a5351d 706{
e24d4c64 707 CONTROL = val;
53a5351d
JM
708}
709
e24d4c64
EZ
710/* Get the value of the DR6 debug status register from the inferior.
711 Here we just return the value stored in D_REGS, as we've got it
712 from the last go32_wait call. */
713unsigned
714go32_get_dr6 (void)
e49d4fa6 715{
e24d4c64 716 return STATUS;
e49d4fa6
SS
717}
718
53a5351d
JM
719/* Put the device open on handle FD into either raw or cooked
720 mode, return 1 if it was in raw mode, zero otherwise. */
721
722static int
723device_mode (int fd, int raw_p)
724{
725 int oldmode, newmode;
726 __dpmi_regs regs;
727
728 regs.x.ax = 0x4400;
729 regs.x.bx = fd;
730 __dpmi_int (0x21, &regs);
731 if (regs.x.flags & 1)
732 return -1;
733 newmode = oldmode = regs.x.dx;
734
735 if (raw_p)
736 newmode |= 0x20;
737 else
738 newmode &= ~0x20;
739
740 if (oldmode & 0x80) /* Only for character dev */
741 {
742 regs.x.ax = 0x4401;
743 regs.x.bx = fd;
744 regs.x.dx = newmode & 0xff; /* Force upper byte zero, else it fails */
745 __dpmi_int (0x21, &regs);
746 if (regs.x.flags & 1)
747 return -1;
748 }
749 return (oldmode & 0x20) == 0x20;
750}
751
752
753static int inf_mode_valid = 0;
754static int inf_terminal_mode;
755
756/* This semaphore is needed because, amazingly enough, GDB calls
757 target.to_terminal_ours more than once after the inferior stops.
758 But we need the information from the first call only, since the
759 second call will always see GDB's own cooked terminal. */
760static int terminal_is_ours = 1;
761
cce74817
JM
762static void
763go32_terminal_init (void)
764{
53a5351d
JM
765 inf_mode_valid = 0; /* reinitialize, in case they are restarting child */
766 terminal_is_ours = 1;
cce74817
JM
767}
768
769static void
4d277981 770go32_terminal_info (char *args, int from_tty)
cce74817 771{
53a5351d
JM
772 printf_unfiltered ("Inferior's terminal is in %s mode.\n",
773 !inf_mode_valid
774 ? "default" : inf_terminal_mode ? "raw" : "cooked");
775
776#if __DJGPP_MINOR__ > 2
777 if (child_cmd.redirection)
778 {
779 int i;
780
781 for (i = 0; i < DBG_HANDLES; i++)
c5aa993b 782 {
53a5351d
JM
783 if (child_cmd.redirection[i]->file_name)
784 printf_unfiltered ("\tFile handle %d is redirected to `%s'.\n",
785 i, child_cmd.redirection[i]->file_name);
786 else if (_get_dev_info (child_cmd.redirection[i]->inf_handle) == -1)
787 printf_unfiltered
788 ("\tFile handle %d appears to be closed by inferior.\n", i);
789 /* Mask off the raw/cooked bit when comparing device info words. */
790 else if ((_get_dev_info (child_cmd.redirection[i]->inf_handle) & 0xdf)
791 != (_get_dev_info (i) & 0xdf))
792 printf_unfiltered
793 ("\tFile handle %d appears to be redirected by inferior.\n", i);
c5aa993b 794 }
53a5351d
JM
795 }
796#endif
797}
798
799static void
800go32_terminal_inferior (void)
801{
802 /* Redirect standard handles as child wants them. */
803 errno = 0;
804 if (redir_to_child (&child_cmd) == -1)
805 {
806 redir_to_debugger (&child_cmd);
8a3fe4f8 807 error (_("Cannot redirect standard handles for program: %s."),
dc672865 808 safe_strerror (errno));
53a5351d
JM
809 }
810 /* set the console device of the inferior to whatever mode
811 (raw or cooked) we found it last time */
812 if (terminal_is_ours)
813 {
814 if (inf_mode_valid)
815 device_mode (0, inf_terminal_mode);
816 terminal_is_ours = 0;
817 }
cce74817
JM
818}
819
820static void
821go32_terminal_ours (void)
822{
53a5351d
JM
823 /* Switch to cooked mode on the gdb terminal and save the inferior
824 terminal mode to be restored when it is resumed */
825 if (!terminal_is_ours)
826 {
827 inf_terminal_mode = device_mode (0, 0);
828 if (inf_terminal_mode != -1)
829 inf_mode_valid = 1;
830 else
831 /* If device_mode returned -1, we don't know what happens with
832 handle 0 anymore, so make the info invalid. */
833 inf_mode_valid = 0;
834 terminal_is_ours = 1;
835
836 /* Restore debugger's standard handles. */
837 errno = 0;
838 if (redir_to_debugger (&child_cmd) == -1)
839 {
840 redir_to_child (&child_cmd);
8a3fe4f8 841 error (_("Cannot redirect standard handles for debugger: %s."),
dc672865 842 safe_strerror (errno));
53a5351d
JM
843 }
844 }
cce74817
JM
845}
846
e49d4fa6
SS
847static void
848init_go32_ops (void)
849{
850 go32_ops.to_shortname = "djgpp";
851 go32_ops.to_longname = "djgpp target process";
852 go32_ops.to_doc =
853 "Program loaded by djgpp, when gdb is used as an external debugger";
854 go32_ops.to_open = go32_open;
855 go32_ops.to_close = go32_close;
53a5351d 856 go32_ops.to_attach = go32_attach;
e49d4fa6
SS
857 go32_ops.to_detach = go32_detach;
858 go32_ops.to_resume = go32_resume;
859 go32_ops.to_wait = go32_wait;
860 go32_ops.to_fetch_registers = go32_fetch_registers;
861 go32_ops.to_store_registers = go32_store_registers;
862 go32_ops.to_prepare_to_store = go32_prepare_to_store;
c8e73a31 863 go32_ops.deprecated_xfer_memory = go32_xfer_memory;
e49d4fa6
SS
864 go32_ops.to_files_info = go32_files_info;
865 go32_ops.to_insert_breakpoint = memory_insert_breakpoint;
866 go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
cce74817
JM
867 go32_ops.to_terminal_init = go32_terminal_init;
868 go32_ops.to_terminal_inferior = go32_terminal_inferior;
53a5351d 869 go32_ops.to_terminal_ours_for_output = go32_terminal_ours;
cce74817 870 go32_ops.to_terminal_ours = go32_terminal_ours;
53a5351d 871 go32_ops.to_terminal_info = go32_terminal_info;
e49d4fa6
SS
872 go32_ops.to_kill = go32_kill_inferior;
873 go32_ops.to_create_inferior = go32_create_inferior;
874 go32_ops.to_mourn_inferior = go32_mourn_inferior;
875 go32_ops.to_can_run = go32_can_run;
876 go32_ops.to_stop = go32_stop;
877 go32_ops.to_stratum = process_stratum;
878 go32_ops.to_has_all_memory = 1;
879 go32_ops.to_has_memory = 1;
880 go32_ops.to_has_stack = 1;
881 go32_ops.to_has_registers = 1;
882 go32_ops.to_has_execution = 1;
883 go32_ops.to_magic = OPS_MAGIC;
53a5351d 884
3a45aed8
EZ
885 /* Initialize child's cwd as empty to be initialized when starting
886 the child. */
887 *child_cwd = 0;
53a5351d
JM
888
889 /* Initialize child's command line storage. */
890 if (redir_debug_init (&child_cmd) == -1)
8e65ff28 891 internal_error (__FILE__, __LINE__,
e2e0b3e5 892 _("Cannot allocate redirection storage: not enough memory.\n"));
0fff5247
EZ
893
894 /* We are always processing GCC-compiled programs. */
895 processing_gcc_compilation = 2;
eaae3919
EZ
896
897 /* Override the default name of the GDB init file. */
898 strcpy (gdbinit, "gdb.ini");
e49d4fa6
SS
899}
900
10ba702d
EZ
901unsigned short windows_major, windows_minor;
902
903/* Compute the version Windows reports via Int 2Fh/AX=1600h. */
904static void
905go32_get_windows_version(void)
906{
907 __dpmi_regs r;
908
909 r.x.ax = 0x1600;
910 __dpmi_int(0x2f, &r);
911 if (r.h.al > 2 && r.h.al != 0x80 && r.h.al != 0xff
912 && (r.h.al > 3 || r.h.ah > 0))
913 {
914 windows_major = r.h.al;
915 windows_minor = r.h.ah;
916 }
917 else
918 windows_major = 0xff; /* meaning no Windows */
919}
920
921/* A subroutine of go32_sysinfo to display memory info. */
922static void
923print_mem (unsigned long datum, const char *header, int in_pages_p)
924{
925 if (datum != 0xffffffffUL)
926 {
927 if (in_pages_p)
928 datum <<= 12;
929 puts_filtered (header);
930 if (datum > 1024)
931 {
932 printf_filtered ("%lu KB", datum >> 10);
933 if (datum > 1024 * 1024)
934 printf_filtered (" (%lu MB)", datum >> 20);
935 }
936 else
937 printf_filtered ("%lu Bytes", datum);
938 puts_filtered ("\n");
939 }
940}
941
942/* Display assorted information about the underlying OS. */
943static void
944go32_sysinfo (char *arg, int from_tty)
945{
946 struct utsname u;
947 char cpuid_vendor[13];
948 unsigned cpuid_max = 0, cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
949 unsigned true_dos_version = _get_dos_version (1);
950 unsigned advertized_dos_version = ((unsigned int)_osmajor << 8) | _osminor;
951 int dpmi_flags;
952 char dpmi_vendor_info[129];
953 int dpmi_vendor_available =
954 __dpmi_get_capabilities (&dpmi_flags, dpmi_vendor_info);
955 __dpmi_version_ret dpmi_version_data;
956 long eflags;
957 __dpmi_free_mem_info mem_info;
958 __dpmi_regs regs;
959
960 cpuid_vendor[0] = '\0';
961 if (uname (&u))
962 strcpy (u.machine, "Unknown x86");
963 else if (u.machine[0] == 'i' && u.machine[1] > 4)
964 {
965 /* CPUID with EAX = 0 returns the Vendor ID. */
966 __asm__ __volatile__ ("xorl %%ebx, %%ebx;"
967 "xorl %%ecx, %%ecx;"
968 "xorl %%edx, %%edx;"
969 "movl $0, %%eax;"
970 "cpuid;"
971 "movl %%ebx, %0;"
972 "movl %%edx, %1;"
973 "movl %%ecx, %2;"
974 "movl %%eax, %3;"
975 : "=m" (cpuid_vendor[0]),
976 "=m" (cpuid_vendor[4]),
977 "=m" (cpuid_vendor[8]),
978 "=m" (cpuid_max)
979 :
980 : "%eax", "%ebx", "%ecx", "%edx");
981 cpuid_vendor[12] = '\0';
982 }
983
984 printf_filtered ("CPU Type.......................%s", u.machine);
985 if (cpuid_vendor[0])
986 printf_filtered (" (%s)", cpuid_vendor);
987 puts_filtered ("\n");
988
989 /* CPUID with EAX = 1 returns processor signature and features. */
990 if (cpuid_max >= 1)
991 {
992 static char *brand_name[] = {
993 "",
994 " Celeron",
995 " III",
996 " III Xeon",
997 "", "", "", "",
998 " 4"
999 };
1000 char cpu_string[80];
1001 char cpu_brand[20];
1002 unsigned brand_idx;
1003 int intel_p = strcmp (cpuid_vendor, "GenuineIntel") == 0;
1004 int amd_p = strcmp (cpuid_vendor, "AuthenticAMD") == 0;
1005 unsigned cpu_family, cpu_model;
1006
1007 __asm__ __volatile__ ("movl $1, %%eax;"
1008 "cpuid;"
1009 : "=a" (cpuid_eax),
1010 "=b" (cpuid_ebx),
1011 "=d" (cpuid_edx)
1012 :
1013 : "%ecx");
1014 brand_idx = cpuid_ebx & 0xff;
1015 cpu_family = (cpuid_eax >> 8) & 0xf;
1016 cpu_model = (cpuid_eax >> 4) & 0xf;
1017 cpu_brand[0] = '\0';
1018 if (intel_p)
1019 {
1020 if (brand_idx > 0
1021 && brand_idx < sizeof(brand_name)/sizeof(brand_name[0])
1022 && *brand_name[brand_idx])
1023 strcpy (cpu_brand, brand_name[brand_idx]);
1024 else if (cpu_family == 5)
1025 {
1026 if (((cpuid_eax >> 12) & 3) == 0 && cpu_model == 4)
1027 strcpy (cpu_brand, " MMX");
1028 else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 1)
1029 strcpy (cpu_brand, " OverDrive");
1030 else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 2)
1031 strcpy (cpu_brand, " Dual");
1032 }
1033 else if (cpu_family == 6 && cpu_model < 8)
1034 {
1035 switch (cpu_model)
1036 {
1037 case 1:
1038 strcpy (cpu_brand, " Pro");
1039 break;
1040 case 3:
1041 strcpy (cpu_brand, " II");
1042 break;
1043 case 5:
1044 strcpy (cpu_brand, " II Xeon");
1045 break;
1046 case 6:
1047 strcpy (cpu_brand, " Celeron");
1048 break;
1049 case 7:
1050 strcpy (cpu_brand, " III");
1051 break;
1052 }
1053 }
1054 }
1055 else if (amd_p)
1056 {
1057 switch (cpu_family)
1058 {
1059 case 4:
1060 strcpy (cpu_brand, "486/5x86");
1061 break;
1062 case 5:
1063 switch (cpu_model)
1064 {
1065 case 0:
1066 case 1:
1067 case 2:
1068 case 3:
1069 strcpy (cpu_brand, "-K5");
1070 break;
1071 case 6:
1072 case 7:
1073 strcpy (cpu_brand, "-K6");
1074 break;
1075 case 8:
1076 strcpy (cpu_brand, "-K6-2");
1077 break;
1078 case 9:
1079 strcpy (cpu_brand, "-K6-III");
1080 break;
1081 }
1082 break;
1083 case 6:
1084 switch (cpu_model)
1085 {
1086 case 1:
1087 case 2:
1088 case 4:
1089 strcpy (cpu_brand, " Athlon");
1090 break;
1091 case 3:
1092 strcpy (cpu_brand, " Duron");
1093 break;
1094 }
1095 break;
1096 }
1097 }
1098 sprintf (cpu_string, "%s%s Model %d Stepping %d",
1099 intel_p ? "Pentium" : (amd_p ? "AMD" : "ix86"),
1100 cpu_brand, cpu_model, cpuid_eax & 0xf);
1101 printfi_filtered (31, "%s\n", cpu_string);
1102 if (((cpuid_edx & (6 | (0x0d << 23))) != 0)
1103 || ((cpuid_edx & 1) == 0)
1104 || (amd_p && (cpuid_edx & (3 << 30)) != 0))
1105 {
1106 puts_filtered ("CPU Features...................");
1107 /* We only list features which might be useful in the DPMI
1108 environment. */
1109 if ((cpuid_edx & 1) == 0)
1110 puts_filtered ("No FPU "); /* it's unusual to not have an FPU */
1111 if ((cpuid_edx & (1 << 1)) != 0)
1112 puts_filtered ("VME ");
1113 if ((cpuid_edx & (1 << 2)) != 0)
1114 puts_filtered ("DE ");
1115 if ((cpuid_edx & (1 << 4)) != 0)
1116 puts_filtered ("TSC ");
1117 if ((cpuid_edx & (1 << 23)) != 0)
1118 puts_filtered ("MMX ");
1119 if ((cpuid_edx & (1 << 25)) != 0)
1120 puts_filtered ("SSE ");
1121 if ((cpuid_edx & (1 << 26)) != 0)
1122 puts_filtered ("SSE2 ");
1123 if (amd_p)
1124 {
1125 if ((cpuid_edx & (1 << 31)) != 0)
1126 puts_filtered ("3DNow! ");
1127 if ((cpuid_edx & (1 << 30)) != 0)
1128 puts_filtered ("3DNow!Ext");
1129 }
1130 puts_filtered ("\n");
1131 }
1132 }
1133 puts_filtered ("\n");
1134 printf_filtered ("DOS Version....................%s %s.%s",
1135 _os_flavor, u.release, u.version);
1136 if (true_dos_version != advertized_dos_version)
1137 printf_filtered (" (disguised as v%d.%d)", _osmajor, _osminor);
1138 puts_filtered ("\n");
1139 if (!windows_major)
1140 go32_get_windows_version ();
1141 if (windows_major != 0xff)
1142 {
1143 const char *windows_flavor;
1144
1145 printf_filtered ("Windows Version................%d.%02d (Windows ",
1146 windows_major, windows_minor);
1147 switch (windows_major)
1148 {
1149 case 3:
1150 windows_flavor = "3.X";
1151 break;
1152 case 4:
1153 switch (windows_minor)
1154 {
1155 case 0:
1156 windows_flavor = "95, 95A, or 95B";
1157 break;
1158 case 3:
1159 windows_flavor = "95B OSR2.1 or 95C OSR2.5";
1160 break;
1161 case 10:
1162 windows_flavor = "98 or 98 SE";
1163 break;
1164 case 90:
1165 windows_flavor = "ME";
1166 break;
1167 default:
1168 windows_flavor = "9X";
1169 break;
1170 }
1171 break;
1172 default:
1173 windows_flavor = "??";
1174 break;
1175 }
1176 printf_filtered ("%s)\n", windows_flavor);
1177 }
1178 else if (true_dos_version == 0x532 && advertized_dos_version == 0x500)
1179 printf_filtered ("Windows Version................Windows NT or Windows 2000\n");
1180 puts_filtered ("\n");
1181 if (dpmi_vendor_available == 0)
1182 {
1183 /* The DPMI spec says the vendor string should be ASCIIZ, but
1184 I don't trust the vendors to follow that... */
1185 if (!memchr (&dpmi_vendor_info[2], 0, 126))
1186 dpmi_vendor_info[128] = '\0';
1187 printf_filtered ("DPMI Host......................%s v%d.%d (capabilities: %#x)\n",
1188 &dpmi_vendor_info[2],
1189 (unsigned)dpmi_vendor_info[0],
1190 (unsigned)dpmi_vendor_info[1],
1191 ((unsigned)dpmi_flags & 0x7f));
1192 }
1193 __dpmi_get_version (&dpmi_version_data);
1194 printf_filtered ("DPMI Version...................%d.%02d\n",
1195 dpmi_version_data.major, dpmi_version_data.minor);
1196 printf_filtered ("DPMI Info......................%s-bit DPMI, with%s Virtual Memory support\n",
1197 (dpmi_version_data.flags & 1) ? "32" : "16",
1198 (dpmi_version_data.flags & 4) ? "" : "out");
1199 printfi_filtered (31, "Interrupts reflected to %s mode\n",
1200 (dpmi_version_data.flags & 2) ? "V86" : "Real");
1201 printfi_filtered (31, "Processor type: i%d86\n",
1202 dpmi_version_data.cpu);
1203 printfi_filtered (31, "PIC base interrupt: Master: %#x Slave: %#x\n",
1204 dpmi_version_data.master_pic, dpmi_version_data.slave_pic);
1205
1206 /* a_tss is only initialized when the debuggee is first run. */
1207 if (prog_has_started)
1208 {
1209 __asm__ __volatile__ ("pushfl ; popl %0" : "=g" (eflags));
1210 printf_filtered ("Protection.....................Ring %d (in %s), with%s I/O protection\n",
1211 a_tss.tss_cs & 3, (a_tss.tss_cs & 4) ? "LDT" : "GDT",
1212 (a_tss.tss_cs & 3) > ((eflags >> 12) & 3) ? "" : "out");
1213 }
1214 puts_filtered ("\n");
1215 __dpmi_get_free_memory_information (&mem_info);
1216 print_mem (mem_info.total_number_of_physical_pages,
1217 "DPMI Total Physical Memory.....", 1);
1218 print_mem (mem_info.total_number_of_free_pages,
1219 "DPMI Free Physical Memory......", 1);
1220 print_mem (mem_info.size_of_paging_file_partition_in_pages,
1221 "DPMI Swap Space................", 1);
1222 print_mem (mem_info.linear_address_space_size_in_pages,
1223 "DPMI Total Linear Address Size.", 1);
1224 print_mem (mem_info.free_linear_address_space_in_pages,
1225 "DPMI Free Linear Address Size..", 1);
1226 print_mem (mem_info.largest_available_free_block_in_bytes,
1227 "DPMI Largest Free Memory Block.", 0);
1228
1229 regs.h.ah = 0x48;
1230 regs.x.bx = 0xffff;
1231 __dpmi_int (0x21, &regs);
1232 print_mem (regs.x.bx << 4, "Free DOS Memory................", 0);
1233 regs.x.ax = 0x5800;
1234 __dpmi_int (0x21, &regs);
1235 if ((regs.x.flags & 1) == 0)
1236 {
1237 static const char *dos_hilo[] = {
1238 "Low", "", "", "", "High", "", "", "", "High, then Low"
1239 };
1240 static const char *dos_fit[] = {
1241 "First", "Best", "Last"
1242 };
1243 int hilo_idx = (regs.x.ax >> 4) & 0x0f;
1244 int fit_idx = regs.x.ax & 0x0f;
1245
1246 if (hilo_idx > 8)
1247 hilo_idx = 0;
1248 if (fit_idx > 2)
1249 fit_idx = 0;
1250 printf_filtered ("DOS Memory Allocation..........%s memory, %s fit\n",
1251 dos_hilo[hilo_idx], dos_fit[fit_idx]);
1252 regs.x.ax = 0x5802;
1253 __dpmi_int (0x21, &regs);
1254 if ((regs.x.flags & 1) != 0)
1255 regs.h.al = 0;
1256 printfi_filtered (31, "UMBs %sin DOS memory chain\n",
1257 regs.h.al == 0 ? "not " : "");
1258 }
1259}
1260
1261struct seg_descr {
1262 unsigned short limit0 __attribute__((packed));
1263 unsigned short base0 __attribute__((packed));
1264 unsigned char base1 __attribute__((packed));
1265 unsigned stype:5 __attribute__((packed));
1266 unsigned dpl:2 __attribute__((packed));
1267 unsigned present:1 __attribute__((packed));
1268 unsigned limit1:4 __attribute__((packed));
1269 unsigned available:1 __attribute__((packed));
1270 unsigned dummy:1 __attribute__((packed));
1271 unsigned bit32:1 __attribute__((packed));
1272 unsigned page_granular:1 __attribute__((packed));
1273 unsigned char base2 __attribute__((packed));
1274};
1275
1276struct gate_descr {
1277 unsigned short offset0 __attribute__((packed));
1278 unsigned short selector __attribute__((packed));
1279 unsigned param_count:5 __attribute__((packed));
1280 unsigned dummy:3 __attribute__((packed));
1281 unsigned stype:5 __attribute__((packed));
1282 unsigned dpl:2 __attribute__((packed));
1283 unsigned present:1 __attribute__((packed));
1284 unsigned short offset1 __attribute__((packed));
1285};
1286
1287/* Read LEN bytes starting at logical address ADDR, and put the result
1288 into DEST. Return 1 if success, zero if not. */
1289static int
1290read_memory_region (unsigned long addr, void *dest, size_t len)
1291{
1292 unsigned long dos_ds_limit = __dpmi_get_segment_limit (_dos_ds);
9f20bf26 1293 int retval = 1;
10ba702d
EZ
1294
1295 /* For the low memory, we can simply use _dos_ds. */
1296 if (addr <= dos_ds_limit - len)
1297 dosmemget (addr, len, dest);
1298 else
1299 {
1300 /* For memory above 1MB we need to set up a special segment to
1301 be able to access that memory. */
1302 int sel = __dpmi_allocate_ldt_descriptors (1);
1303
9f20bf26
EZ
1304 if (sel <= 0)
1305 retval = 0;
1306 else
1307 {
1308 int access_rights = __dpmi_get_descriptor_access_rights (sel);
1309 size_t segment_limit = len - 1;
1310
1311 /* Make sure the crucial bits in the descriptor access
1312 rights are set correctly. Some DPMI providers might barf
1313 if we set the segment limit to something that is not an
1314 integral multiple of 4KB pages if the granularity bit is
1315 not set to byte-granular, even though the DPMI spec says
1316 it's the host's responsibility to set that bit correctly. */
1317 if (len > 1024 * 1024)
1318 {
1319 access_rights |= 0x8000;
1320 /* Page-granular segments should have the low 12 bits of
1321 the limit set. */
1322 segment_limit |= 0xfff;
1323 }
1324 else
1325 access_rights &= ~0x8000;
1326
1327 if (__dpmi_set_segment_base_address (sel, addr) != -1
1328 && __dpmi_set_descriptor_access_rights (sel, access_rights) != -1
2033c18a
EZ
1329 && __dpmi_set_segment_limit (sel, segment_limit) != -1
1330 /* W2K silently fails to set the segment limit, leaving
1331 it at zero; this test avoids the resulting crash. */
1332 && __dpmi_get_segment_limit (sel) >= segment_limit)
9f20bf26
EZ
1333 movedata (sel, 0, _my_ds (), (unsigned)dest, len);
1334 else
1335 retval = 0;
1336
1337 __dpmi_free_ldt_descriptor (sel);
1338 }
10ba702d 1339 }
9f20bf26 1340 return retval;
10ba702d
EZ
1341}
1342
1343/* Get a segment descriptor stored at index IDX in the descriptor
1344 table whose base address is TABLE_BASE. Return the descriptor
1345 type, or -1 if failure. */
1346static int
1347get_descriptor (unsigned long table_base, int idx, void *descr)
1348{
1349 unsigned long addr = table_base + idx * 8; /* 8 bytes per entry */
1350
1351 if (read_memory_region (addr, descr, 8))
1352 return (int)((struct seg_descr *)descr)->stype;
1353 return -1;
1354}
1355
1356struct dtr_reg {
1357 unsigned short limit __attribute__((packed));
1358 unsigned long base __attribute__((packed));
1359};
1360
1361/* Display a segment descriptor stored at index IDX in a descriptor
1362 table whose type is TYPE and whose base address is BASE_ADDR. If
1363 FORCE is non-zero, display even invalid descriptors. */
1364static void
1365display_descriptor (unsigned type, unsigned long base_addr, int idx, int force)
1366{
1367 struct seg_descr descr;
1368 struct gate_descr gate;
1369
1370 /* Get the descriptor from the table. */
1371 if (idx == 0 && type == 0)
1372 puts_filtered ("0x000: null descriptor\n");
1373 else if (get_descriptor (base_addr, idx, &descr) != -1)
1374 {
1375 /* For each type of descriptor table, this has a bit set if the
1376 corresponding type of selectors is valid in that table. */
1377 static unsigned allowed_descriptors[] = {
1378 0xffffdafeL, /* GDT */
1379 0x0000c0e0L, /* IDT */
1380 0xffffdafaL /* LDT */
1381 };
1382
1383 /* If the program hasn't started yet, assume the debuggee will
1384 have the same CPL as the debugger. */
1385 int cpl = prog_has_started ? (a_tss.tss_cs & 3) : _my_cs () & 3;
1386 unsigned long limit = (descr.limit1 << 16) | descr.limit0;
1387
1388 if (descr.present
1389 && (allowed_descriptors[type] & (1 << descr.stype)) != 0)
1390 {
1391 printf_filtered ("0x%03x: ",
1392 type == 1
1393 ? idx : (idx * 8) | (type ? (cpl | 4) : 0));
1394 if (descr.page_granular)
1395 limit = (limit << 12) | 0xfff; /* big segment: low 12 bit set */
1396 if (descr.stype == 1 || descr.stype == 2 || descr.stype == 3
1397 || descr.stype == 9 || descr.stype == 11
1398 || (descr.stype >= 16 && descr.stype < 32))
1399 printf_filtered ("base=0x%02x%02x%04x limit=0x%08lx",
1400 descr.base2, descr.base1, descr.base0, limit);
1401
1402 switch (descr.stype)
1403 {
1404 case 1:
1405 case 3:
1406 printf_filtered (" 16-bit TSS (task %sactive)",
1407 descr.stype == 3 ? "" : "in");
1408 break;
1409 case 2:
1410 puts_filtered (" LDT");
1411 break;
1412 case 4:
1413 memcpy (&gate, &descr, sizeof gate);
1414 printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1415 gate.selector, gate.offset1, gate.offset0);
1416 printf_filtered (" 16-bit Call Gate (params=%d)",
1417 gate.param_count);
1418 break;
1419 case 5:
1420 printf_filtered ("TSS selector=0x%04x", descr.base0);
1421 printfi_filtered (16, "Task Gate");
1422 break;
1423 case 6:
1424 case 7:
1425 memcpy (&gate, &descr, sizeof gate);
1426 printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1427 gate.selector, gate.offset1, gate.offset0);
1428 printf_filtered (" 16-bit %s Gate",
1429 descr.stype == 6 ? "Interrupt" : "Trap");
1430 break;
1431 case 9:
1432 case 11:
1433 printf_filtered (" 32-bit TSS (task %sactive)",
1434 descr.stype == 3 ? "" : "in");
1435 break;
1436 case 12:
1437 memcpy (&gate, &descr, sizeof gate);
1438 printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1439 gate.selector, gate.offset1, gate.offset0);
1440 printf_filtered (" 32-bit Call Gate (params=%d)",
1441 gate.param_count);
1442 break;
1443 case 14:
1444 case 15:
1445 memcpy (&gate, &descr, sizeof gate);
1446 printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1447 gate.selector, gate.offset1, gate.offset0);
1448 printf_filtered (" 32-bit %s Gate",
1449 descr.stype == 14 ? "Interrupt" : "Trap");
1450 break;
1451 case 16: /* data segments */
1452 case 17:
1453 case 18:
1454 case 19:
1455 case 20:
1456 case 21:
1457 case 22:
1458 case 23:
1459 printf_filtered (" %s-bit Data (%s Exp-%s%s)",
1460 descr.bit32 ? "32" : "16",
1461 descr.stype & 2 ? "Read/Write," : "Read-Only, ",
1462 descr.stype & 4 ? "down" : "up",
1463 descr.stype & 1 ? "" : ", N.Acc");
1464 break;
1465 case 24: /* code segments */
1466 case 25:
1467 case 26:
1468 case 27:
1469 case 28:
1470 case 29:
1471 case 30:
1472 case 31:
1473 printf_filtered (" %s-bit Code (%s, %sConf%s)",
1474 descr.bit32 ? "32" : "16",
1475 descr.stype & 2 ? "Exec/Read" : "Exec-Only",
1476 descr.stype & 4 ? "" : "N.",
1477 descr.stype & 1 ? "" : ", N.Acc");
1478 break;
1479 default:
1480 printf_filtered ("Unknown type 0x%02x", descr.stype);
1481 break;
1482 }
1483 puts_filtered ("\n");
1484 }
1485 else if (force)
1486 {
1487 printf_filtered ("0x%03x: ",
1488 type == 1
1489 ? idx : (idx * 8) | (type ? (cpl | 4) : 0));
1490 if (!descr.present)
1491 puts_filtered ("Segment not present\n");
1492 else
1493 printf_filtered ("Segment type 0x%02x is invalid in this table\n",
1494 descr.stype);
1495 }
1496 }
1497 else if (force)
1498 printf_filtered ("0x%03x: Cannot read this descriptor\n", idx);
1499}
1500
1501static void
1502go32_sldt (char *arg, int from_tty)
1503{
1504 struct dtr_reg gdtr;
1505 unsigned short ldtr = 0;
1506 int ldt_idx;
1507 struct seg_descr ldt_descr;
1508 long ldt_entry = -1L;
1509 int cpl = (prog_has_started ? a_tss.tss_cs : _my_cs ()) & 3;
1510
1511 if (arg && *arg)
1512 {
1513 while (*arg && isspace(*arg))
1514 arg++;
1515
1516 if (*arg)
1517 {
1518 ldt_entry = parse_and_eval_long (arg);
1519 if (ldt_entry < 0
1520 || (ldt_entry & 4) == 0
1521 || (ldt_entry & 3) != (cpl & 3))
8a3fe4f8 1522 error (_("Invalid LDT entry 0x%03lx."), (unsigned long)ldt_entry);
10ba702d
EZ
1523 }
1524 }
1525
1526 __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ );
1527 __asm__ __volatile__ ("sldt %0" : "=m" (ldtr) : /* no inputs */ );
1528 ldt_idx = ldtr / 8;
1529 if (ldt_idx == 0)
1530 puts_filtered ("There is no LDT.\n");
1531 /* LDT's entry in the GDT must have the type LDT, which is 2. */
1532 else if (get_descriptor (gdtr.base, ldt_idx, &ldt_descr) != 2)
1533 printf_filtered ("LDT is present (at %#x), but unreadable by GDB.\n",
1534 ldt_descr.base0
1535 | (ldt_descr.base1 << 16)
1536 | (ldt_descr.base2 << 24));
1537 else
1538 {
1539 unsigned base =
1540 ldt_descr.base0
1541 | (ldt_descr.base1 << 16)
1542 | (ldt_descr.base2 << 24);
1543 unsigned limit = ldt_descr.limit0 | (ldt_descr.limit1 << 16);
1544 int max_entry;
1545
1546 if (ldt_descr.page_granular)
1547 /* Page-granular segments must have the low 12 bits of their
1548 limit set. */
1549 limit = (limit << 12) | 0xfff;
1550 /* LDT cannot have more than 8K 8-byte entries, i.e. more than
1551 64KB. */
1552 if (limit > 0xffff)
1553 limit = 0xffff;
1554
1555 max_entry = (limit + 1) / 8;
1556
1557 if (ldt_entry >= 0)
1558 {
1559 if (ldt_entry > limit)
8a3fe4f8 1560 error (_("Invalid LDT entry %#lx: outside valid limits [0..%#x]"),
ccbc3e6f 1561 (unsigned long)ldt_entry, limit);
10ba702d
EZ
1562
1563 display_descriptor (ldt_descr.stype, base, ldt_entry / 8, 1);
1564 }
1565 else
1566 {
1567 int i;
1568
1569 for (i = 0; i < max_entry; i++)
1570 display_descriptor (ldt_descr.stype, base, i, 0);
1571 }
1572 }
1573}
1574
1575static void
1576go32_sgdt (char *arg, int from_tty)
1577{
1578 struct dtr_reg gdtr;
1579 long gdt_entry = -1L;
1580 int max_entry;
1581
1582 if (arg && *arg)
1583 {
1584 while (*arg && isspace(*arg))
1585 arg++;
1586
1587 if (*arg)
1588 {
1589 gdt_entry = parse_and_eval_long (arg);
1590 if (gdt_entry < 0 || (gdt_entry & 7) != 0)
8a3fe4f8 1591 error (_("Invalid GDT entry 0x%03lx: not an integral multiple of 8."),
ccbc3e6f 1592 (unsigned long)gdt_entry);
10ba702d
EZ
1593 }
1594 }
1595
1596 __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ );
1597 max_entry = (gdtr.limit + 1) / 8;
1598
1599 if (gdt_entry >= 0)
1600 {
1601 if (gdt_entry > gdtr.limit)
8a3fe4f8 1602 error (_("Invalid GDT entry %#lx: outside valid limits [0..%#x]"),
ccbc3e6f 1603 (unsigned long)gdt_entry, gdtr.limit);
10ba702d
EZ
1604
1605 display_descriptor (0, gdtr.base, gdt_entry / 8, 1);
1606 }
1607 else
1608 {
1609 int i;
1610
1611 for (i = 0; i < max_entry; i++)
1612 display_descriptor (0, gdtr.base, i, 0);
1613 }
1614}
1615
1616static void
1617go32_sidt (char *arg, int from_tty)
1618{
1619 struct dtr_reg idtr;
1620 long idt_entry = -1L;
1621 int max_entry;
1622
1623 if (arg && *arg)
1624 {
1625 while (*arg && isspace(*arg))
1626 arg++;
1627
1628 if (*arg)
1629 {
1630 idt_entry = parse_and_eval_long (arg);
1631 if (idt_entry < 0)
8a3fe4f8 1632 error (_("Invalid (negative) IDT entry %ld."), idt_entry);
10ba702d
EZ
1633 }
1634 }
1635
1636 __asm__ __volatile__ ("sidt %0" : "=m" (idtr) : /* no inputs */ );
1637 max_entry = (idtr.limit + 1) / 8;
1638 if (max_entry > 0x100) /* no more than 256 entries */
1639 max_entry = 0x100;
1640
1641 if (idt_entry >= 0)
1642 {
1643 if (idt_entry > idtr.limit)
8a3fe4f8 1644 error (_("Invalid IDT entry %#lx: outside valid limits [0..%#x]"),
ccbc3e6f 1645 (unsigned long)idt_entry, idtr.limit);
10ba702d
EZ
1646
1647 display_descriptor (1, idtr.base, idt_entry, 1);
1648 }
1649 else
1650 {
1651 int i;
1652
1653 for (i = 0; i < max_entry; i++)
1654 display_descriptor (1, idtr.base, i, 0);
1655 }
1656}
1657
9f20bf26
EZ
1658/* Cached linear address of the base of the page directory. For
1659 now, available only under CWSDPMI. Code based on ideas and
1660 suggestions from Charles Sandmann <sandmann@clio.rice.edu>. */
1661static unsigned long pdbr;
1662
1663static unsigned long
1664get_cr3 (void)
1665{
1666 unsigned offset;
1667 unsigned taskreg;
1668 unsigned long taskbase, cr3;
1669 struct dtr_reg gdtr;
1670
1671 if (pdbr > 0 && pdbr <= 0xfffff)
1672 return pdbr;
1673
1674 /* Get the linear address of GDT and the Task Register. */
1675 __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ );
1676 __asm__ __volatile__ ("str %0" : "=m" (taskreg) : /* no inputs */ );
1677
1678 /* Task Register is a segment selector for the TSS of the current
1679 task. Therefore, it can be used as an index into the GDT to get
1680 at the segment descriptor for the TSS. To get the index, reset
1681 the low 3 bits of the selector (which give the CPL). Add 2 to the
1682 offset to point to the 3 low bytes of the base address. */
1683 offset = gdtr.base + (taskreg & 0xfff8) + 2;
1684
1685
1686 /* CWSDPMI's task base is always under the 1MB mark. */
1687 if (offset > 0xfffff)
1688 return 0;
1689
1690 _farsetsel (_dos_ds);
1691 taskbase = _farnspeekl (offset) & 0xffffffU;
1692 taskbase += _farnspeekl (offset + 2) & 0xff000000U;
1693 if (taskbase > 0xfffff)
1694 return 0;
1695
1696 /* CR3 (a.k.a. PDBR, the Page Directory Base Register) is stored at
1697 offset 1Ch in the TSS. */
1698 cr3 = _farnspeekl (taskbase + 0x1c) & ~0xfff;
1699 if (cr3 > 0xfffff)
1700 {
1f5dc670 1701#if 0 /* not fullly supported yet */
9f20bf26
EZ
1702 /* The Page Directory is in UMBs. In that case, CWSDPMI puts
1703 the first Page Table right below the Page Directory. Thus,
1704 the first Page Table's entry for its own address and the Page
1705 Directory entry for that Page Table will hold the same
1706 physical address. The loop below searches the entire UMB
1707 range of addresses for such an occurence. */
1708 unsigned long addr, pte_idx;
1709
1710 for (addr = 0xb0000, pte_idx = 0xb0;
1711 pte_idx < 0xff;
1712 addr += 0x1000, pte_idx++)
1713 {
1714 if (((_farnspeekl (addr + 4 * pte_idx) & 0xfffff027) ==
1715 (_farnspeekl (addr + 0x1000) & 0xfffff027))
1716 && ((_farnspeekl (addr + 4 * pte_idx + 4) & 0xfffff000) == cr3))
1717 {
1718 cr3 = addr + 0x1000;
1719 break;
1720 }
1721 }
a3b9cbb3 1722#endif
9f20bf26
EZ
1723
1724 if (cr3 > 0xfffff)
1725 cr3 = 0;
1726 }
1727
1728 return cr3;
1729}
1730
1731/* Return the N'th Page Directory entry. */
1732static unsigned long
1733get_pde (int n)
1734{
1735 unsigned long pde = 0;
1736
1737 if (pdbr && n >= 0 && n < 1024)
1738 {
1739 pde = _farpeekl (_dos_ds, pdbr + 4*n);
1740 }
1741 return pde;
1742}
1743
1744/* Return the N'th entry of the Page Table whose Page Directory entry
1745 is PDE. */
1746static unsigned long
1747get_pte (unsigned long pde, int n)
1748{
1749 unsigned long pte = 0;
1750
1751 /* pde & 0x80 tests the 4MB page bit. We don't support 4MB
1752 page tables, for now. */
1753 if ((pde & 1) && !(pde & 0x80) && n >= 0 && n < 1024)
1754 {
1755 pde &= ~0xfff; /* clear non-address bits */
1756 pte = _farpeekl (_dos_ds, pde + 4*n);
1757 }
1758 return pte;
1759}
1760
1761/* Display a Page Directory or Page Table entry. IS_DIR, if non-zero,
1762 says this is a Page Directory entry. If FORCE is non-zero, display
1763 the entry even if its Present flag is off. OFF is the offset of the
1764 address from the page's base address. */
1765static void
1766display_ptable_entry (unsigned long entry, int is_dir, int force, unsigned off)
1767{
1768 if ((entry & 1) != 0)
1769 {
1770 printf_filtered ("Base=0x%05lx000", entry >> 12);
1771 if ((entry & 0x100) && !is_dir)
1772 puts_filtered (" Global");
1773 if ((entry & 0x40) && !is_dir)
1774 puts_filtered (" Dirty");
1775 printf_filtered (" %sAcc.", (entry & 0x20) ? "" : "Not-");
1776 printf_filtered (" %sCached", (entry & 0x10) ? "" : "Not-");
1777 printf_filtered (" Write-%s", (entry & 8) ? "Thru" : "Back");
1778 printf_filtered (" %s", (entry & 4) ? "Usr" : "Sup");
1779 printf_filtered (" Read-%s", (entry & 2) ? "Write" : "Only");
1780 if (off)
1781 printf_filtered (" +0x%x", off);
1782 puts_filtered ("\n");
1783 }
1784 else if (force)
1785 printf_filtered ("Page%s not present or not supported; value=0x%lx.\n",
1786 is_dir ? " Table" : "", entry >> 1);
1787}
1788
1789static void
1790go32_pde (char *arg, int from_tty)
1791{
1792 long pde_idx = -1, i;
1793
1794 if (arg && *arg)
1795 {
1796 while (*arg && isspace(*arg))
1797 arg++;
1798
1799 if (*arg)
1800 {
1801 pde_idx = parse_and_eval_long (arg);
1802 if (pde_idx < 0 || pde_idx >= 1024)
8a3fe4f8 1803 error (_("Entry %ld is outside valid limits [0..1023]."), pde_idx);
9f20bf26
EZ
1804 }
1805 }
1806
1807 pdbr = get_cr3 ();
1808 if (!pdbr)
1809 puts_filtered ("Access to Page Directories is not supported on this system.\n");
1810 else if (pde_idx >= 0)
1811 display_ptable_entry (get_pde (pde_idx), 1, 1, 0);
1812 else
1813 for (i = 0; i < 1024; i++)
1814 display_ptable_entry (get_pde (i), 1, 0, 0);
1815}
1816
1817/* A helper function to display entries in a Page Table pointed to by
1818 the N'th entry in the Page Directory. If FORCE is non-zero, say
1819 something even if the Page Table is not accessible. */
1820static void
1821display_page_table (long n, int force)
1822{
1823 unsigned long pde = get_pde (n);
1824
1825 if ((pde & 1) != 0)
1826 {
1827 int i;
1828
1829 printf_filtered ("Page Table pointed to by Page Directory entry 0x%lx:\n", n);
1830 for (i = 0; i < 1024; i++)
1831 display_ptable_entry (get_pte (pde, i), 0, 0, 0);
1832 puts_filtered ("\n");
1833 }
1834 else if (force)
1835 printf_filtered ("Page Table not present; value=0x%lx.\n", pde >> 1);
1836}
1837
1838static void
1839go32_pte (char *arg, int from_tty)
1840{
ccbc3e6f 1841 long pde_idx = -1L, i;
9f20bf26
EZ
1842
1843 if (arg && *arg)
1844 {
1845 while (*arg && isspace(*arg))
1846 arg++;
1847
1848 if (*arg)
1849 {
1850 pde_idx = parse_and_eval_long (arg);
1851 if (pde_idx < 0 || pde_idx >= 1024)
8a3fe4f8 1852 error (_("Entry %ld is outside valid limits [0..1023]."), pde_idx);
9f20bf26
EZ
1853 }
1854 }
1855
1856 pdbr = get_cr3 ();
1857 if (!pdbr)
1858 puts_filtered ("Access to Page Tables is not supported on this system.\n");
1859 else if (pde_idx >= 0)
1860 display_page_table (pde_idx, 1);
1861 else
1862 for (i = 0; i < 1024; i++)
1863 display_page_table (i, 0);
1864}
1865
1866static void
1867go32_pte_for_address (char *arg, int from_tty)
1868{
1869 CORE_ADDR addr = 0, i;
1870
1871 if (arg && *arg)
1872 {
1873 while (*arg && isspace(*arg))
1874 arg++;
1875
1876 if (*arg)
1877 addr = parse_and_eval_address (arg);
1878 }
1879 if (!addr)
e2e0b3e5 1880 error_no_arg (_("linear address"));
9f20bf26
EZ
1881
1882 pdbr = get_cr3 ();
1883 if (!pdbr)
1884 puts_filtered ("Access to Page Tables is not supported on this system.\n");
1885 else
1886 {
1887 int pde_idx = (addr >> 22) & 0x3ff;
1888 int pte_idx = (addr >> 12) & 0x3ff;
1889 unsigned offs = addr & 0xfff;
1890
1891 printf_filtered ("Page Table entry for address 0x%llx:\n",
1892 (unsigned long long)addr);
1893 display_ptable_entry (get_pte (get_pde (pde_idx), pte_idx), 0, 1, offs);
1894 }
1895}
1896
d8c852a1
EZ
1897static struct cmd_list_element *info_dos_cmdlist = NULL;
1898
1899static void
1900go32_info_dos_command (char *args, int from_tty)
1901{
1902 help_list (info_dos_cmdlist, "info dos ", class_info, gdb_stdout);
1903}
1904
e49d4fa6
SS
1905void
1906_initialize_go32_nat (void)
1907{
1908 init_go32_ops ();
1909 add_target (&go32_ops);
10ba702d 1910
1bedd215
AC
1911 add_prefix_cmd ("dos", class_info, go32_info_dos_command, _("\
1912Print information specific to DJGPP (aka MS-DOS) debugging."),
d8c852a1
EZ
1913 &info_dos_cmdlist, "info dos ", 0, &infolist);
1914
1a966eab
AC
1915 add_cmd ("sysinfo", class_info, go32_sysinfo, _("\
1916Display information about the target system, including CPU, OS, DPMI, etc."),
d8c852a1 1917 &info_dos_cmdlist);
1a966eab
AC
1918 add_cmd ("ldt", class_info, go32_sldt, _("\
1919Display entries in the LDT (Local Descriptor Table).\n\
1920Entry number (an expression) as an argument means display only that entry."),
d8c852a1 1921 &info_dos_cmdlist);
1a966eab
AC
1922 add_cmd ("gdt", class_info, go32_sgdt, _("\
1923Display entries in the GDT (Global Descriptor Table).\n\
1924Entry number (an expression) as an argument means display only that entry."),
d8c852a1 1925 &info_dos_cmdlist);
1a966eab
AC
1926 add_cmd ("idt", class_info, go32_sidt, _("\
1927Display entries in the IDT (Interrupt Descriptor Table).\n\
1928Entry number (an expression) as an argument means display only that entry."),
d8c852a1 1929 &info_dos_cmdlist);
1a966eab
AC
1930 add_cmd ("pde", class_info, go32_pde, _("\
1931Display entries in the Page Directory.\n\
1932Entry number (an expression) as an argument means display only that entry."),
9f20bf26 1933 &info_dos_cmdlist);
1a966eab
AC
1934 add_cmd ("pte", class_info, go32_pte, _("\
1935Display entries in Page Tables.\n\
1936Entry number (an expression) as an argument means display only entries\n\
1937from the Page Table pointed to by the specified Page Directory entry."),
9f20bf26 1938 &info_dos_cmdlist);
1a966eab
AC
1939 add_cmd ("address-pte", class_info, go32_pte_for_address, _("\
1940Display a Page Table entry for a linear address.\n\
1941The address argument must be a linear address, after adding to\n\
1942it the base address of the appropriate segment.\n\
1943The base address of variables and functions in the debuggee's data\n\
1944or code segment is stored in the variable __djgpp_base_address,\n\
1945so use `__djgpp_base_address + (char *)&var' as the argument.\n\
1946For other segments, look up their base address in the output of\n\
1947the `info dos ldt' command."),
9f20bf26 1948 &info_dos_cmdlist);
e49d4fa6 1949}
53a5351d
JM
1950
1951pid_t
1952tcgetpgrp (int fd)
1953{
1954 if (isatty (fd))
1955 return SOME_PID;
1956 errno = ENOTTY;
1957 return -1;
1958}
1959
1960int
1961tcsetpgrp (int fd, pid_t pgid)
1962{
1963 if (isatty (fd) && pgid == SOME_PID)
1964 return 0;
1965 errno = pgid == SOME_PID ? ENOTTY : ENOSYS;
1966 return -1;
1967}
This page took 0.625046 seconds and 4 git commands to generate.