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