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