2001-07-21 Chris Demetriou <cgd@broadcom.com>
[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;
150985e3 591 size_t cmdlen;
e49d4fa6 592
0fff5247
EZ
593 /* If no exec file handed to us, get it from the exec-file command -- with
594 a good, common error message if none is specified. */
595 if (exec_file == 0)
596 exec_file = get_exec_file (1);
597
e49d4fa6
SS
598 if (prog_has_started)
599 {
b83266a0 600 go32_stop ();
e49d4fa6
SS
601 go32_kill_inferior ();
602 }
53a5351d
JM
603 resume_signal = -1;
604 resume_is_step = 0;
3a45aed8
EZ
605
606 /* Initialize child's cwd as empty to be initialized when starting
607 the child. */
608 *child_cwd = 0;
609
53a5351d
JM
610 /* Init command line storage. */
611 if (redir_debug_init (&child_cmd) == -1)
8e65ff28
AC
612 internal_error (__FILE__, __LINE__,
613 "Cannot allocate redirection storage: not enough memory.\n");
53a5351d
JM
614
615 /* Parse the command line and create redirections. */
616 if (strpbrk (args, "<>"))
617 {
618 if (redir_cmdline_parse (args, &child_cmd) == 0)
619 args = child_cmd.command;
620 else
621 error ("Syntax error in command line.");
622 }
623 else
c2d11a7d 624 child_cmd.command = xstrdup (args);
e49d4fa6 625
150985e3
EZ
626 cmdlen = strlen (args);
627 /* v2loadimage passes command lines via DOS memory, so it cannot
628 possibly handle commands longer than 1MB. */
629 if (cmdlen > 1024*1024)
630 error ("Command line too long.");
631
632 cmdline = xmalloc (cmdlen + 4);
e49d4fa6 633 strcpy (cmdline + 1, args);
150985e3
EZ
634 /* If the command-line length fits into DOS 126-char limits, use the
635 DOS command tail format; otherwise, tell v2loadimage to pass it
636 through a buffer in conventional memory. */
637 if (cmdlen < 127)
638 {
639 cmdline[0] = strlen (args);
640 cmdline[cmdlen + 1] = 13;
641 }
642 else
643 cmdline[0] = 0xff; /* signal v2loadimage it's a long command */
e49d4fa6
SS
644
645 environ = env;
646
647 if (v2loadimage (exec_file, cmdline, start_state))
648 {
649 environ = env_save;
650 printf_unfiltered ("Load failed for image %s\n", exec_file);
651 exit (1);
652 }
653 environ = env_save;
150985e3 654 free (cmdline);
e49d4fa6
SS
655
656 edi_init (start_state);
53a5351d
JM
657#if __DJGPP_MINOR__ < 3
658 save_npx ();
659#endif
e49d4fa6 660
39f77062 661 inferior_ptid = pid_to_ptid (SOME_PID);
e49d4fa6
SS
662 push_target (&go32_ops);
663 clear_proceed_status ();
664 insert_breakpoints ();
2acceee2 665 proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
b83266a0 666 prog_has_started = 1;
e49d4fa6
SS
667}
668
669static void
670go32_mourn_inferior (void)
671{
53a5351d
JM
672 /* We need to make sure all the breakpoint enable bits in the DR7
673 register are reset when the inferior exits. Otherwise, if they
674 rerun the inferior, the uncleared bits may cause random SIGTRAPs,
675 failure to set more watchpoints, and other calamities. It would
676 be nice if GDB itself would take care to remove all breakpoints
677 at all times, but it doesn't, probably under an assumption that
678 the OS cleans up when the debuggee exits. */
e24d4c64 679 i386_cleanup_dregs ();
e49d4fa6
SS
680 go32_kill_inferior ();
681 generic_mourn_inferior ();
682}
683
684static int
685go32_can_run (void)
686{
687 return 1;
688}
689
e49d4fa6
SS
690/* Hardware watchpoint support. */
691
e49d4fa6 692#define D_REGS edi.dr
e24d4c64
EZ
693#define CONTROL D_REGS[7]
694#define STATUS D_REGS[6]
53a5351d 695
e24d4c64
EZ
696/* Pass the address ADDR to the inferior in the I'th debug register.
697 Here we just store the address in D_REGS, the watchpoint will be
698 actually set up when go32_wait runs the debuggee. */
699void
700go32_set_dr (int i, CORE_ADDR addr)
e49d4fa6 701{
4d277981
EZ
702 if (i < 0 || i > 3)
703 internal_error (__FILE__, __LINE__,
704 "Invalid register %d in go32_set_dr.\n", i);
e24d4c64 705 D_REGS[i] = addr;
e49d4fa6
SS
706}
707
e24d4c64
EZ
708/* Pass the value VAL to the inferior in the DR7 debug control
709 register. Here we just store the address in D_REGS, the watchpoint
710 will be actually set up when go32_wait runs the debuggee. */
711void
712go32_set_dr7 (unsigned val)
53a5351d 713{
e24d4c64 714 CONTROL = val;
53a5351d
JM
715}
716
e24d4c64
EZ
717/* Get the value of the DR6 debug status register from the inferior.
718 Here we just return the value stored in D_REGS, as we've got it
719 from the last go32_wait call. */
720unsigned
721go32_get_dr6 (void)
e49d4fa6 722{
e24d4c64 723 return STATUS;
e49d4fa6
SS
724}
725
53a5351d
JM
726/* Put the device open on handle FD into either raw or cooked
727 mode, return 1 if it was in raw mode, zero otherwise. */
728
729static int
730device_mode (int fd, int raw_p)
731{
732 int oldmode, newmode;
733 __dpmi_regs regs;
734
735 regs.x.ax = 0x4400;
736 regs.x.bx = fd;
737 __dpmi_int (0x21, &regs);
738 if (regs.x.flags & 1)
739 return -1;
740 newmode = oldmode = regs.x.dx;
741
742 if (raw_p)
743 newmode |= 0x20;
744 else
745 newmode &= ~0x20;
746
747 if (oldmode & 0x80) /* Only for character dev */
748 {
749 regs.x.ax = 0x4401;
750 regs.x.bx = fd;
751 regs.x.dx = newmode & 0xff; /* Force upper byte zero, else it fails */
752 __dpmi_int (0x21, &regs);
753 if (regs.x.flags & 1)
754 return -1;
755 }
756 return (oldmode & 0x20) == 0x20;
757}
758
759
760static int inf_mode_valid = 0;
761static int inf_terminal_mode;
762
763/* This semaphore is needed because, amazingly enough, GDB calls
764 target.to_terminal_ours more than once after the inferior stops.
765 But we need the information from the first call only, since the
766 second call will always see GDB's own cooked terminal. */
767static int terminal_is_ours = 1;
768
cce74817
JM
769static void
770go32_terminal_init (void)
771{
53a5351d
JM
772 inf_mode_valid = 0; /* reinitialize, in case they are restarting child */
773 terminal_is_ours = 1;
cce74817
JM
774}
775
776static void
4d277981 777go32_terminal_info (char *args, int from_tty)
cce74817 778{
53a5351d
JM
779 printf_unfiltered ("Inferior's terminal is in %s mode.\n",
780 !inf_mode_valid
781 ? "default" : inf_terminal_mode ? "raw" : "cooked");
782
783#if __DJGPP_MINOR__ > 2
784 if (child_cmd.redirection)
785 {
786 int i;
787
788 for (i = 0; i < DBG_HANDLES; i++)
c5aa993b 789 {
53a5351d
JM
790 if (child_cmd.redirection[i]->file_name)
791 printf_unfiltered ("\tFile handle %d is redirected to `%s'.\n",
792 i, child_cmd.redirection[i]->file_name);
793 else if (_get_dev_info (child_cmd.redirection[i]->inf_handle) == -1)
794 printf_unfiltered
795 ("\tFile handle %d appears to be closed by inferior.\n", i);
796 /* Mask off the raw/cooked bit when comparing device info words. */
797 else if ((_get_dev_info (child_cmd.redirection[i]->inf_handle) & 0xdf)
798 != (_get_dev_info (i) & 0xdf))
799 printf_unfiltered
800 ("\tFile handle %d appears to be redirected by inferior.\n", i);
c5aa993b 801 }
53a5351d
JM
802 }
803#endif
804}
805
806static void
807go32_terminal_inferior (void)
808{
809 /* Redirect standard handles as child wants them. */
810 errno = 0;
811 if (redir_to_child (&child_cmd) == -1)
812 {
813 redir_to_debugger (&child_cmd);
814 error ("Cannot redirect standard handles for program: %s.",
815 strerror (errno));
816 }
817 /* set the console device of the inferior to whatever mode
818 (raw or cooked) we found it last time */
819 if (terminal_is_ours)
820 {
821 if (inf_mode_valid)
822 device_mode (0, inf_terminal_mode);
823 terminal_is_ours = 0;
824 }
cce74817
JM
825}
826
827static void
828go32_terminal_ours (void)
829{
53a5351d
JM
830 /* Switch to cooked mode on the gdb terminal and save the inferior
831 terminal mode to be restored when it is resumed */
832 if (!terminal_is_ours)
833 {
834 inf_terminal_mode = device_mode (0, 0);
835 if (inf_terminal_mode != -1)
836 inf_mode_valid = 1;
837 else
838 /* If device_mode returned -1, we don't know what happens with
839 handle 0 anymore, so make the info invalid. */
840 inf_mode_valid = 0;
841 terminal_is_ours = 1;
842
843 /* Restore debugger's standard handles. */
844 errno = 0;
845 if (redir_to_debugger (&child_cmd) == -1)
846 {
847 redir_to_child (&child_cmd);
848 error ("Cannot redirect standard handles for debugger: %s.",
849 strerror (errno));
850 }
851 }
cce74817
JM
852}
853
e49d4fa6
SS
854static void
855init_go32_ops (void)
856{
857 go32_ops.to_shortname = "djgpp";
858 go32_ops.to_longname = "djgpp target process";
859 go32_ops.to_doc =
860 "Program loaded by djgpp, when gdb is used as an external debugger";
861 go32_ops.to_open = go32_open;
862 go32_ops.to_close = go32_close;
53a5351d 863 go32_ops.to_attach = go32_attach;
e49d4fa6
SS
864 go32_ops.to_detach = go32_detach;
865 go32_ops.to_resume = go32_resume;
866 go32_ops.to_wait = go32_wait;
867 go32_ops.to_fetch_registers = go32_fetch_registers;
868 go32_ops.to_store_registers = go32_store_registers;
869 go32_ops.to_prepare_to_store = go32_prepare_to_store;
870 go32_ops.to_xfer_memory = go32_xfer_memory;
871 go32_ops.to_files_info = go32_files_info;
872 go32_ops.to_insert_breakpoint = memory_insert_breakpoint;
873 go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
cce74817
JM
874 go32_ops.to_terminal_init = go32_terminal_init;
875 go32_ops.to_terminal_inferior = go32_terminal_inferior;
53a5351d 876 go32_ops.to_terminal_ours_for_output = go32_terminal_ours;
cce74817 877 go32_ops.to_terminal_ours = go32_terminal_ours;
53a5351d 878 go32_ops.to_terminal_info = go32_terminal_info;
e49d4fa6
SS
879 go32_ops.to_kill = go32_kill_inferior;
880 go32_ops.to_create_inferior = go32_create_inferior;
881 go32_ops.to_mourn_inferior = go32_mourn_inferior;
882 go32_ops.to_can_run = go32_can_run;
883 go32_ops.to_stop = go32_stop;
884 go32_ops.to_stratum = process_stratum;
885 go32_ops.to_has_all_memory = 1;
886 go32_ops.to_has_memory = 1;
887 go32_ops.to_has_stack = 1;
888 go32_ops.to_has_registers = 1;
889 go32_ops.to_has_execution = 1;
890 go32_ops.to_magic = OPS_MAGIC;
53a5351d 891
3a45aed8
EZ
892 /* Initialize child's cwd as empty to be initialized when starting
893 the child. */
894 *child_cwd = 0;
53a5351d
JM
895
896 /* Initialize child's command line storage. */
897 if (redir_debug_init (&child_cmd) == -1)
8e65ff28
AC
898 internal_error (__FILE__, __LINE__,
899 "Cannot allocate redirection storage: not enough memory.\n");
0fff5247
EZ
900
901 /* We are always processing GCC-compiled programs. */
902 processing_gcc_compilation = 2;
e49d4fa6
SS
903}
904
10ba702d
EZ
905unsigned short windows_major, windows_minor;
906
907/* Compute the version Windows reports via Int 2Fh/AX=1600h. */
908static void
909go32_get_windows_version(void)
910{
911 __dpmi_regs r;
912
913 r.x.ax = 0x1600;
914 __dpmi_int(0x2f, &r);
915 if (r.h.al > 2 && r.h.al != 0x80 && r.h.al != 0xff
916 && (r.h.al > 3 || r.h.ah > 0))
917 {
918 windows_major = r.h.al;
919 windows_minor = r.h.ah;
920 }
921 else
922 windows_major = 0xff; /* meaning no Windows */
923}
924
925/* A subroutine of go32_sysinfo to display memory info. */
926static void
927print_mem (unsigned long datum, const char *header, int in_pages_p)
928{
929 if (datum != 0xffffffffUL)
930 {
931 if (in_pages_p)
932 datum <<= 12;
933 puts_filtered (header);
934 if (datum > 1024)
935 {
936 printf_filtered ("%lu KB", datum >> 10);
937 if (datum > 1024 * 1024)
938 printf_filtered (" (%lu MB)", datum >> 20);
939 }
940 else
941 printf_filtered ("%lu Bytes", datum);
942 puts_filtered ("\n");
943 }
944}
945
946/* Display assorted information about the underlying OS. */
947static void
948go32_sysinfo (char *arg, int from_tty)
949{
950 struct utsname u;
951 char cpuid_vendor[13];
952 unsigned cpuid_max = 0, cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
953 unsigned true_dos_version = _get_dos_version (1);
954 unsigned advertized_dos_version = ((unsigned int)_osmajor << 8) | _osminor;
955 int dpmi_flags;
956 char dpmi_vendor_info[129];
957 int dpmi_vendor_available =
958 __dpmi_get_capabilities (&dpmi_flags, dpmi_vendor_info);
959 __dpmi_version_ret dpmi_version_data;
960 long eflags;
961 __dpmi_free_mem_info mem_info;
962 __dpmi_regs regs;
963
964 cpuid_vendor[0] = '\0';
965 if (uname (&u))
966 strcpy (u.machine, "Unknown x86");
967 else if (u.machine[0] == 'i' && u.machine[1] > 4)
968 {
969 /* CPUID with EAX = 0 returns the Vendor ID. */
970 __asm__ __volatile__ ("xorl %%ebx, %%ebx;"
971 "xorl %%ecx, %%ecx;"
972 "xorl %%edx, %%edx;"
973 "movl $0, %%eax;"
974 "cpuid;"
975 "movl %%ebx, %0;"
976 "movl %%edx, %1;"
977 "movl %%ecx, %2;"
978 "movl %%eax, %3;"
979 : "=m" (cpuid_vendor[0]),
980 "=m" (cpuid_vendor[4]),
981 "=m" (cpuid_vendor[8]),
982 "=m" (cpuid_max)
983 :
984 : "%eax", "%ebx", "%ecx", "%edx");
985 cpuid_vendor[12] = '\0';
986 }
987
988 printf_filtered ("CPU Type.......................%s", u.machine);
989 if (cpuid_vendor[0])
990 printf_filtered (" (%s)", cpuid_vendor);
991 puts_filtered ("\n");
992
993 /* CPUID with EAX = 1 returns processor signature and features. */
994 if (cpuid_max >= 1)
995 {
996 static char *brand_name[] = {
997 "",
998 " Celeron",
999 " III",
1000 " III Xeon",
1001 "", "", "", "",
1002 " 4"
1003 };
1004 char cpu_string[80];
1005 char cpu_brand[20];
1006 unsigned brand_idx;
1007 int intel_p = strcmp (cpuid_vendor, "GenuineIntel") == 0;
1008 int amd_p = strcmp (cpuid_vendor, "AuthenticAMD") == 0;
1009 unsigned cpu_family, cpu_model;
1010
1011 __asm__ __volatile__ ("movl $1, %%eax;"
1012 "cpuid;"
1013 : "=a" (cpuid_eax),
1014 "=b" (cpuid_ebx),
1015 "=d" (cpuid_edx)
1016 :
1017 : "%ecx");
1018 brand_idx = cpuid_ebx & 0xff;
1019 cpu_family = (cpuid_eax >> 8) & 0xf;
1020 cpu_model = (cpuid_eax >> 4) & 0xf;
1021 cpu_brand[0] = '\0';
1022 if (intel_p)
1023 {
1024 if (brand_idx > 0
1025 && brand_idx < sizeof(brand_name)/sizeof(brand_name[0])
1026 && *brand_name[brand_idx])
1027 strcpy (cpu_brand, brand_name[brand_idx]);
1028 else if (cpu_family == 5)
1029 {
1030 if (((cpuid_eax >> 12) & 3) == 0 && cpu_model == 4)
1031 strcpy (cpu_brand, " MMX");
1032 else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 1)
1033 strcpy (cpu_brand, " OverDrive");
1034 else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 2)
1035 strcpy (cpu_brand, " Dual");
1036 }
1037 else if (cpu_family == 6 && cpu_model < 8)
1038 {
1039 switch (cpu_model)
1040 {
1041 case 1:
1042 strcpy (cpu_brand, " Pro");
1043 break;
1044 case 3:
1045 strcpy (cpu_brand, " II");
1046 break;
1047 case 5:
1048 strcpy (cpu_brand, " II Xeon");
1049 break;
1050 case 6:
1051 strcpy (cpu_brand, " Celeron");
1052 break;
1053 case 7:
1054 strcpy (cpu_brand, " III");
1055 break;
1056 }
1057 }
1058 }
1059 else if (amd_p)
1060 {
1061 switch (cpu_family)
1062 {
1063 case 4:
1064 strcpy (cpu_brand, "486/5x86");
1065 break;
1066 case 5:
1067 switch (cpu_model)
1068 {
1069 case 0:
1070 case 1:
1071 case 2:
1072 case 3:
1073 strcpy (cpu_brand, "-K5");
1074 break;
1075 case 6:
1076 case 7:
1077 strcpy (cpu_brand, "-K6");
1078 break;
1079 case 8:
1080 strcpy (cpu_brand, "-K6-2");
1081 break;
1082 case 9:
1083 strcpy (cpu_brand, "-K6-III");
1084 break;
1085 }
1086 break;
1087 case 6:
1088 switch (cpu_model)
1089 {
1090 case 1:
1091 case 2:
1092 case 4:
1093 strcpy (cpu_brand, " Athlon");
1094 break;
1095 case 3:
1096 strcpy (cpu_brand, " Duron");
1097 break;
1098 }
1099 break;
1100 }
1101 }
1102 sprintf (cpu_string, "%s%s Model %d Stepping %d",
1103 intel_p ? "Pentium" : (amd_p ? "AMD" : "ix86"),
1104 cpu_brand, cpu_model, cpuid_eax & 0xf);
1105 printfi_filtered (31, "%s\n", cpu_string);
1106 if (((cpuid_edx & (6 | (0x0d << 23))) != 0)
1107 || ((cpuid_edx & 1) == 0)
1108 || (amd_p && (cpuid_edx & (3 << 30)) != 0))
1109 {
1110 puts_filtered ("CPU Features...................");
1111 /* We only list features which might be useful in the DPMI
1112 environment. */
1113 if ((cpuid_edx & 1) == 0)
1114 puts_filtered ("No FPU "); /* it's unusual to not have an FPU */
1115 if ((cpuid_edx & (1 << 1)) != 0)
1116 puts_filtered ("VME ");
1117 if ((cpuid_edx & (1 << 2)) != 0)
1118 puts_filtered ("DE ");
1119 if ((cpuid_edx & (1 << 4)) != 0)
1120 puts_filtered ("TSC ");
1121 if ((cpuid_edx & (1 << 23)) != 0)
1122 puts_filtered ("MMX ");
1123 if ((cpuid_edx & (1 << 25)) != 0)
1124 puts_filtered ("SSE ");
1125 if ((cpuid_edx & (1 << 26)) != 0)
1126 puts_filtered ("SSE2 ");
1127 if (amd_p)
1128 {
1129 if ((cpuid_edx & (1 << 31)) != 0)
1130 puts_filtered ("3DNow! ");
1131 if ((cpuid_edx & (1 << 30)) != 0)
1132 puts_filtered ("3DNow!Ext");
1133 }
1134 puts_filtered ("\n");
1135 }
1136 }
1137 puts_filtered ("\n");
1138 printf_filtered ("DOS Version....................%s %s.%s",
1139 _os_flavor, u.release, u.version);
1140 if (true_dos_version != advertized_dos_version)
1141 printf_filtered (" (disguised as v%d.%d)", _osmajor, _osminor);
1142 puts_filtered ("\n");
1143 if (!windows_major)
1144 go32_get_windows_version ();
1145 if (windows_major != 0xff)
1146 {
1147 const char *windows_flavor;
1148
1149 printf_filtered ("Windows Version................%d.%02d (Windows ",
1150 windows_major, windows_minor);
1151 switch (windows_major)
1152 {
1153 case 3:
1154 windows_flavor = "3.X";
1155 break;
1156 case 4:
1157 switch (windows_minor)
1158 {
1159 case 0:
1160 windows_flavor = "95, 95A, or 95B";
1161 break;
1162 case 3:
1163 windows_flavor = "95B OSR2.1 or 95C OSR2.5";
1164 break;
1165 case 10:
1166 windows_flavor = "98 or 98 SE";
1167 break;
1168 case 90:
1169 windows_flavor = "ME";
1170 break;
1171 default:
1172 windows_flavor = "9X";
1173 break;
1174 }
1175 break;
1176 default:
1177 windows_flavor = "??";
1178 break;
1179 }
1180 printf_filtered ("%s)\n", windows_flavor);
1181 }
1182 else if (true_dos_version == 0x532 && advertized_dos_version == 0x500)
1183 printf_filtered ("Windows Version................Windows NT or Windows 2000\n");
1184 puts_filtered ("\n");
1185 if (dpmi_vendor_available == 0)
1186 {
1187 /* The DPMI spec says the vendor string should be ASCIIZ, but
1188 I don't trust the vendors to follow that... */
1189 if (!memchr (&dpmi_vendor_info[2], 0, 126))
1190 dpmi_vendor_info[128] = '\0';
1191 printf_filtered ("DPMI Host......................%s v%d.%d (capabilities: %#x)\n",
1192 &dpmi_vendor_info[2],
1193 (unsigned)dpmi_vendor_info[0],
1194 (unsigned)dpmi_vendor_info[1],
1195 ((unsigned)dpmi_flags & 0x7f));
1196 }
1197 __dpmi_get_version (&dpmi_version_data);
1198 printf_filtered ("DPMI Version...................%d.%02d\n",
1199 dpmi_version_data.major, dpmi_version_data.minor);
1200 printf_filtered ("DPMI Info......................%s-bit DPMI, with%s Virtual Memory support\n",
1201 (dpmi_version_data.flags & 1) ? "32" : "16",
1202 (dpmi_version_data.flags & 4) ? "" : "out");
1203 printfi_filtered (31, "Interrupts reflected to %s mode\n",
1204 (dpmi_version_data.flags & 2) ? "V86" : "Real");
1205 printfi_filtered (31, "Processor type: i%d86\n",
1206 dpmi_version_data.cpu);
1207 printfi_filtered (31, "PIC base interrupt: Master: %#x Slave: %#x\n",
1208 dpmi_version_data.master_pic, dpmi_version_data.slave_pic);
1209
1210 /* a_tss is only initialized when the debuggee is first run. */
1211 if (prog_has_started)
1212 {
1213 __asm__ __volatile__ ("pushfl ; popl %0" : "=g" (eflags));
1214 printf_filtered ("Protection.....................Ring %d (in %s), with%s I/O protection\n",
1215 a_tss.tss_cs & 3, (a_tss.tss_cs & 4) ? "LDT" : "GDT",
1216 (a_tss.tss_cs & 3) > ((eflags >> 12) & 3) ? "" : "out");
1217 }
1218 puts_filtered ("\n");
1219 __dpmi_get_free_memory_information (&mem_info);
1220 print_mem (mem_info.total_number_of_physical_pages,
1221 "DPMI Total Physical Memory.....", 1);
1222 print_mem (mem_info.total_number_of_free_pages,
1223 "DPMI Free Physical Memory......", 1);
1224 print_mem (mem_info.size_of_paging_file_partition_in_pages,
1225 "DPMI Swap Space................", 1);
1226 print_mem (mem_info.linear_address_space_size_in_pages,
1227 "DPMI Total Linear Address Size.", 1);
1228 print_mem (mem_info.free_linear_address_space_in_pages,
1229 "DPMI Free Linear Address Size..", 1);
1230 print_mem (mem_info.largest_available_free_block_in_bytes,
1231 "DPMI Largest Free Memory Block.", 0);
1232
1233 regs.h.ah = 0x48;
1234 regs.x.bx = 0xffff;
1235 __dpmi_int (0x21, &regs);
1236 print_mem (regs.x.bx << 4, "Free DOS Memory................", 0);
1237 regs.x.ax = 0x5800;
1238 __dpmi_int (0x21, &regs);
1239 if ((regs.x.flags & 1) == 0)
1240 {
1241 static const char *dos_hilo[] = {
1242 "Low", "", "", "", "High", "", "", "", "High, then Low"
1243 };
1244 static const char *dos_fit[] = {
1245 "First", "Best", "Last"
1246 };
1247 int hilo_idx = (regs.x.ax >> 4) & 0x0f;
1248 int fit_idx = regs.x.ax & 0x0f;
1249
1250 if (hilo_idx > 8)
1251 hilo_idx = 0;
1252 if (fit_idx > 2)
1253 fit_idx = 0;
1254 printf_filtered ("DOS Memory Allocation..........%s memory, %s fit\n",
1255 dos_hilo[hilo_idx], dos_fit[fit_idx]);
1256 regs.x.ax = 0x5802;
1257 __dpmi_int (0x21, &regs);
1258 if ((regs.x.flags & 1) != 0)
1259 regs.h.al = 0;
1260 printfi_filtered (31, "UMBs %sin DOS memory chain\n",
1261 regs.h.al == 0 ? "not " : "");
1262 }
1263}
1264
1265struct seg_descr {
1266 unsigned short limit0 __attribute__((packed));
1267 unsigned short base0 __attribute__((packed));
1268 unsigned char base1 __attribute__((packed));
1269 unsigned stype:5 __attribute__((packed));
1270 unsigned dpl:2 __attribute__((packed));
1271 unsigned present:1 __attribute__((packed));
1272 unsigned limit1:4 __attribute__((packed));
1273 unsigned available:1 __attribute__((packed));
1274 unsigned dummy:1 __attribute__((packed));
1275 unsigned bit32:1 __attribute__((packed));
1276 unsigned page_granular:1 __attribute__((packed));
1277 unsigned char base2 __attribute__((packed));
1278};
1279
1280struct gate_descr {
1281 unsigned short offset0 __attribute__((packed));
1282 unsigned short selector __attribute__((packed));
1283 unsigned param_count:5 __attribute__((packed));
1284 unsigned dummy:3 __attribute__((packed));
1285 unsigned stype:5 __attribute__((packed));
1286 unsigned dpl:2 __attribute__((packed));
1287 unsigned present:1 __attribute__((packed));
1288 unsigned short offset1 __attribute__((packed));
1289};
1290
1291/* Read LEN bytes starting at logical address ADDR, and put the result
1292 into DEST. Return 1 if success, zero if not. */
1293static int
1294read_memory_region (unsigned long addr, void *dest, size_t len)
1295{
1296 unsigned long dos_ds_limit = __dpmi_get_segment_limit (_dos_ds);
1297
1298 /* For the low memory, we can simply use _dos_ds. */
1299 if (addr <= dos_ds_limit - len)
1300 dosmemget (addr, len, dest);
1301 else
1302 {
1303 /* For memory above 1MB we need to set up a special segment to
1304 be able to access that memory. */
1305 int sel = __dpmi_allocate_ldt_descriptors (1);
1306
1307 if (sel <= 0
1308 || __dpmi_set_segment_base_address (sel, addr) == -1
1309 || __dpmi_set_segment_limit (sel, len - 1) == -1)
1310 return 0;
1311 movedata (sel, 0, _my_ds (), (unsigned)dest, len);
1312 __dpmi_free_ldt_descriptor (sel);
1313 }
1314 return 1;
1315}
1316
1317/* Get a segment descriptor stored at index IDX in the descriptor
1318 table whose base address is TABLE_BASE. Return the descriptor
1319 type, or -1 if failure. */
1320static int
1321get_descriptor (unsigned long table_base, int idx, void *descr)
1322{
1323 unsigned long addr = table_base + idx * 8; /* 8 bytes per entry */
1324
1325 if (read_memory_region (addr, descr, 8))
1326 return (int)((struct seg_descr *)descr)->stype;
1327 return -1;
1328}
1329
1330struct dtr_reg {
1331 unsigned short limit __attribute__((packed));
1332 unsigned long base __attribute__((packed));
1333};
1334
1335/* Display a segment descriptor stored at index IDX in a descriptor
1336 table whose type is TYPE and whose base address is BASE_ADDR. If
1337 FORCE is non-zero, display even invalid descriptors. */
1338static void
1339display_descriptor (unsigned type, unsigned long base_addr, int idx, int force)
1340{
1341 struct seg_descr descr;
1342 struct gate_descr gate;
1343
1344 /* Get the descriptor from the table. */
1345 if (idx == 0 && type == 0)
1346 puts_filtered ("0x000: null descriptor\n");
1347 else if (get_descriptor (base_addr, idx, &descr) != -1)
1348 {
1349 /* For each type of descriptor table, this has a bit set if the
1350 corresponding type of selectors is valid in that table. */
1351 static unsigned allowed_descriptors[] = {
1352 0xffffdafeL, /* GDT */
1353 0x0000c0e0L, /* IDT */
1354 0xffffdafaL /* LDT */
1355 };
1356
1357 /* If the program hasn't started yet, assume the debuggee will
1358 have the same CPL as the debugger. */
1359 int cpl = prog_has_started ? (a_tss.tss_cs & 3) : _my_cs () & 3;
1360 unsigned long limit = (descr.limit1 << 16) | descr.limit0;
1361
1362 if (descr.present
1363 && (allowed_descriptors[type] & (1 << descr.stype)) != 0)
1364 {
1365 printf_filtered ("0x%03x: ",
1366 type == 1
1367 ? idx : (idx * 8) | (type ? (cpl | 4) : 0));
1368 if (descr.page_granular)
1369 limit = (limit << 12) | 0xfff; /* big segment: low 12 bit set */
1370 if (descr.stype == 1 || descr.stype == 2 || descr.stype == 3
1371 || descr.stype == 9 || descr.stype == 11
1372 || (descr.stype >= 16 && descr.stype < 32))
1373 printf_filtered ("base=0x%02x%02x%04x limit=0x%08lx",
1374 descr.base2, descr.base1, descr.base0, limit);
1375
1376 switch (descr.stype)
1377 {
1378 case 1:
1379 case 3:
1380 printf_filtered (" 16-bit TSS (task %sactive)",
1381 descr.stype == 3 ? "" : "in");
1382 break;
1383 case 2:
1384 puts_filtered (" LDT");
1385 break;
1386 case 4:
1387 memcpy (&gate, &descr, sizeof gate);
1388 printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1389 gate.selector, gate.offset1, gate.offset0);
1390 printf_filtered (" 16-bit Call Gate (params=%d)",
1391 gate.param_count);
1392 break;
1393 case 5:
1394 printf_filtered ("TSS selector=0x%04x", descr.base0);
1395 printfi_filtered (16, "Task Gate");
1396 break;
1397 case 6:
1398 case 7:
1399 memcpy (&gate, &descr, sizeof gate);
1400 printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1401 gate.selector, gate.offset1, gate.offset0);
1402 printf_filtered (" 16-bit %s Gate",
1403 descr.stype == 6 ? "Interrupt" : "Trap");
1404 break;
1405 case 9:
1406 case 11:
1407 printf_filtered (" 32-bit TSS (task %sactive)",
1408 descr.stype == 3 ? "" : "in");
1409 break;
1410 case 12:
1411 memcpy (&gate, &descr, sizeof gate);
1412 printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1413 gate.selector, gate.offset1, gate.offset0);
1414 printf_filtered (" 32-bit Call Gate (params=%d)",
1415 gate.param_count);
1416 break;
1417 case 14:
1418 case 15:
1419 memcpy (&gate, &descr, sizeof gate);
1420 printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1421 gate.selector, gate.offset1, gate.offset0);
1422 printf_filtered (" 32-bit %s Gate",
1423 descr.stype == 14 ? "Interrupt" : "Trap");
1424 break;
1425 case 16: /* data segments */
1426 case 17:
1427 case 18:
1428 case 19:
1429 case 20:
1430 case 21:
1431 case 22:
1432 case 23:
1433 printf_filtered (" %s-bit Data (%s Exp-%s%s)",
1434 descr.bit32 ? "32" : "16",
1435 descr.stype & 2 ? "Read/Write," : "Read-Only, ",
1436 descr.stype & 4 ? "down" : "up",
1437 descr.stype & 1 ? "" : ", N.Acc");
1438 break;
1439 case 24: /* code segments */
1440 case 25:
1441 case 26:
1442 case 27:
1443 case 28:
1444 case 29:
1445 case 30:
1446 case 31:
1447 printf_filtered (" %s-bit Code (%s, %sConf%s)",
1448 descr.bit32 ? "32" : "16",
1449 descr.stype & 2 ? "Exec/Read" : "Exec-Only",
1450 descr.stype & 4 ? "" : "N.",
1451 descr.stype & 1 ? "" : ", N.Acc");
1452 break;
1453 default:
1454 printf_filtered ("Unknown type 0x%02x", descr.stype);
1455 break;
1456 }
1457 puts_filtered ("\n");
1458 }
1459 else if (force)
1460 {
1461 printf_filtered ("0x%03x: ",
1462 type == 1
1463 ? idx : (idx * 8) | (type ? (cpl | 4) : 0));
1464 if (!descr.present)
1465 puts_filtered ("Segment not present\n");
1466 else
1467 printf_filtered ("Segment type 0x%02x is invalid in this table\n",
1468 descr.stype);
1469 }
1470 }
1471 else if (force)
1472 printf_filtered ("0x%03x: Cannot read this descriptor\n", idx);
1473}
1474
1475static void
1476go32_sldt (char *arg, int from_tty)
1477{
1478 struct dtr_reg gdtr;
1479 unsigned short ldtr = 0;
1480 int ldt_idx;
1481 struct seg_descr ldt_descr;
1482 long ldt_entry = -1L;
1483 int cpl = (prog_has_started ? a_tss.tss_cs : _my_cs ()) & 3;
1484
1485 if (arg && *arg)
1486 {
1487 while (*arg && isspace(*arg))
1488 arg++;
1489
1490 if (*arg)
1491 {
1492 ldt_entry = parse_and_eval_long (arg);
1493 if (ldt_entry < 0
1494 || (ldt_entry & 4) == 0
1495 || (ldt_entry & 3) != (cpl & 3))
1496 error ("Invalid LDT entry 0x%03x.", ldt_entry);
1497 }
1498 }
1499
1500 __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ );
1501 __asm__ __volatile__ ("sldt %0" : "=m" (ldtr) : /* no inputs */ );
1502 ldt_idx = ldtr / 8;
1503 if (ldt_idx == 0)
1504 puts_filtered ("There is no LDT.\n");
1505 /* LDT's entry in the GDT must have the type LDT, which is 2. */
1506 else if (get_descriptor (gdtr.base, ldt_idx, &ldt_descr) != 2)
1507 printf_filtered ("LDT is present (at %#x), but unreadable by GDB.\n",
1508 ldt_descr.base0
1509 | (ldt_descr.base1 << 16)
1510 | (ldt_descr.base2 << 24));
1511 else
1512 {
1513 unsigned base =
1514 ldt_descr.base0
1515 | (ldt_descr.base1 << 16)
1516 | (ldt_descr.base2 << 24);
1517 unsigned limit = ldt_descr.limit0 | (ldt_descr.limit1 << 16);
1518 int max_entry;
1519
1520 if (ldt_descr.page_granular)
1521 /* Page-granular segments must have the low 12 bits of their
1522 limit set. */
1523 limit = (limit << 12) | 0xfff;
1524 /* LDT cannot have more than 8K 8-byte entries, i.e. more than
1525 64KB. */
1526 if (limit > 0xffff)
1527 limit = 0xffff;
1528
1529 max_entry = (limit + 1) / 8;
1530
1531 if (ldt_entry >= 0)
1532 {
1533 if (ldt_entry > limit)
1534 error ("Invalid LDT entry %#x: outside valid limits [0..%#x]",
1535 ldt_entry, limit);
1536
1537 display_descriptor (ldt_descr.stype, base, ldt_entry / 8, 1);
1538 }
1539 else
1540 {
1541 int i;
1542
1543 for (i = 0; i < max_entry; i++)
1544 display_descriptor (ldt_descr.stype, base, i, 0);
1545 }
1546 }
1547}
1548
1549static void
1550go32_sgdt (char *arg, int from_tty)
1551{
1552 struct dtr_reg gdtr;
1553 long gdt_entry = -1L;
1554 int max_entry;
1555
1556 if (arg && *arg)
1557 {
1558 while (*arg && isspace(*arg))
1559 arg++;
1560
1561 if (*arg)
1562 {
1563 gdt_entry = parse_and_eval_long (arg);
1564 if (gdt_entry < 0 || (gdt_entry & 7) != 0)
1565 error ("Invalid GDT entry 0x%03x: not an integral multiple of 8.",
1566 gdt_entry);
1567 }
1568 }
1569
1570 __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ );
1571 max_entry = (gdtr.limit + 1) / 8;
1572
1573 if (gdt_entry >= 0)
1574 {
1575 if (gdt_entry > gdtr.limit)
1576 error ("Invalid GDT entry %#x: outside valid limits [0..%#x]",
1577 gdt_entry, gdtr.limit);
1578
1579 display_descriptor (0, gdtr.base, gdt_entry / 8, 1);
1580 }
1581 else
1582 {
1583 int i;
1584
1585 for (i = 0; i < max_entry; i++)
1586 display_descriptor (0, gdtr.base, i, 0);
1587 }
1588}
1589
1590static void
1591go32_sidt (char *arg, int from_tty)
1592{
1593 struct dtr_reg idtr;
1594 long idt_entry = -1L;
1595 int max_entry;
1596
1597 if (arg && *arg)
1598 {
1599 while (*arg && isspace(*arg))
1600 arg++;
1601
1602 if (*arg)
1603 {
1604 idt_entry = parse_and_eval_long (arg);
1605 if (idt_entry < 0)
1606 error ("Invalid (negative) IDT entry 0x%03x.", idt_entry);
1607 }
1608 }
1609
1610 __asm__ __volatile__ ("sidt %0" : "=m" (idtr) : /* no inputs */ );
1611 max_entry = (idtr.limit + 1) / 8;
1612 if (max_entry > 0x100) /* no more than 256 entries */
1613 max_entry = 0x100;
1614
1615 if (idt_entry >= 0)
1616 {
1617 if (idt_entry > idtr.limit)
1618 error ("Invalid IDT entry %#x: outside valid limits [0..%#x]",
1619 idt_entry, idtr.limit);
1620
1621 display_descriptor (1, idtr.base, idt_entry, 1);
1622 }
1623 else
1624 {
1625 int i;
1626
1627 for (i = 0; i < max_entry; i++)
1628 display_descriptor (1, idtr.base, i, 0);
1629 }
1630}
1631
d8c852a1
EZ
1632static struct cmd_list_element *info_dos_cmdlist = NULL;
1633
1634static void
1635go32_info_dos_command (char *args, int from_tty)
1636{
1637 help_list (info_dos_cmdlist, "info dos ", class_info, gdb_stdout);
1638}
1639
e49d4fa6
SS
1640void
1641_initialize_go32_nat (void)
1642{
1643 init_go32_ops ();
1644 add_target (&go32_ops);
10ba702d 1645
d8c852a1
EZ
1646 add_prefix_cmd ("dos", class_info, go32_info_dos_command,
1647 "Print information specific to DJGPP (a.k.a. MS-DOS) debugging.",
1648 &info_dos_cmdlist, "info dos ", 0, &infolist);
1649
1650 add_cmd ("sysinfo", class_info, go32_sysinfo,
1651 "Display information about the target system, including CPU, OS, DPMI, etc.",
1652 &info_dos_cmdlist);
1653 add_cmd ("ldt", class_info, go32_sldt,
1654 "Display entries in the LDT (Local Descriptor Table).\n"
1655 "Entry number (an expression) as an argument means display only that entry.",
1656 &info_dos_cmdlist);
1657 add_cmd ("gdt", class_info, go32_sgdt,
1658 "Display entries in the GDT (Global Descriptor Table).\n"
1659 "Entry number (an expression) as an argument means display only that entry.",
1660 &info_dos_cmdlist);
1661 add_cmd ("idt", class_info, go32_sidt,
1662 "Display entries in the IDT (Interrupt Descriptor Table).\n"
1663 "Entry number (an expression) as an argument means display only that entry.",
1664 &info_dos_cmdlist);
e49d4fa6 1665}
53a5351d
JM
1666
1667pid_t
1668tcgetpgrp (int fd)
1669{
1670 if (isatty (fd))
1671 return SOME_PID;
1672 errno = ENOTTY;
1673 return -1;
1674}
1675
1676int
1677tcsetpgrp (int fd, pid_t pgid)
1678{
1679 if (isatty (fd) && pgid == SOME_PID)
1680 return 0;
1681 errno = pgid == SOME_PID ? ENOTTY : ENOSYS;
1682 return -1;
1683}
This page took 0.207147 seconds and 4 git commands to generate.