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