]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/go32-nat.c
2001-03-26 Andreas Jaeger <aj@suse.de>
[thirdparty/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"
4e052eda 32#include "regcache.h"
e49d4fa6 33
c5aa993b 34#include <stdio.h> /* required for __DJGPP_MINOR__ */
e49d4fa6
SS
35#include <stdlib.h>
36#include <string.h>
53a5351d 37#include <errno.h>
c2c6d25f 38#include <unistd.h>
53a5351d
JM
39#include <io.h>
40#include <dpmi.h>
e49d4fa6
SS
41#include <debug/v2load.h>
42#include <debug/dbgcom.h>
53a5351d
JM
43#if __DJGPP_MINOR__ > 2
44#include <debug/redir.h>
45#endif
e49d4fa6 46
b83266a0
SS
47#if __DJGPP_MINOR__ < 3
48/* This code will be provided from DJGPP 2.03 on. Until then I code it
49 here */
c5aa993b
JM
50typedef struct
51 {
52 unsigned short sig0;
53 unsigned short sig1;
54 unsigned short sig2;
55 unsigned short sig3;
56 unsigned short exponent:15;
57 unsigned short sign:1;
58 }
59NPXREG;
60
61typedef struct
62 {
63 unsigned int control;
64 unsigned int status;
65 unsigned int tag;
66 unsigned int eip;
67 unsigned int cs;
68 unsigned int dataptr;
69 unsigned int datasel;
70 NPXREG reg[8];
71 }
72NPX;
b83266a0
SS
73
74static NPX npx;
75
c5aa993b
JM
76static void save_npx (void); /* Save the FPU of the debugged program */
77static void load_npx (void); /* Restore the FPU of the debugged program */
b83266a0
SS
78
79/* ------------------------------------------------------------------------- */
80/* Store the contents of the NPX in the global variable `npx'. */
c5aa993b 81/* *INDENT-OFF* */
b83266a0
SS
82
83static void
84save_npx (void)
85{
86 asm ("inb $0xa0, %%al
c5aa993b
JM
87 testb $0x20, %%al
88 jz 1f
89 xorb %% al, %%al
90 outb %% al, $0xf0
91 movb $0x20, %%al
92 outb %% al, $0xa0
93 outb %% al, $0x20
b83266a0 941:
c5aa993b
JM
95 fnsave % 0
96 fwait "
97: "=m" (npx)
98: /* No input */
99: "%eax");
b83266a0 100}
c5aa993b
JM
101
102/* *INDENT-ON* */
103
104
105
106
107
b83266a0
SS
108/* ------------------------------------------------------------------------- */
109/* Reload the contents of the NPX from the global variable `npx'. */
110
111static void
112load_npx (void)
113{
c5aa993b 114asm ("frstor %0":"=m" (npx));
b83266a0 115}
53a5351d
JM
116/* ------------------------------------------------------------------------- */
117/* Stubs for the missing redirection functions. */
118typedef struct {
119 char *command;
120 int redirected;
121} cmdline_t;
122
123void redir_cmdline_delete (cmdline_t *ptr) {ptr->redirected = 0;}
124int redir_cmdline_parse (const char *args, cmdline_t *ptr)
125{
126 return -1;
127}
128int redir_to_child (cmdline_t *ptr)
129{
130 return 1;
131}
132int redir_to_debugger (cmdline_t *ptr)
133{
134 return 1;
135}
136int redir_debug_init (cmdline_t *ptr) { return 0; }
b83266a0
SS
137#endif /* __DJGPP_MINOR < 3 */
138
e49d4fa6
SS
139extern void _initialize_go32_nat (void);
140
53a5351d
JM
141typedef enum { wp_insert, wp_remove, wp_count } wp_op;
142
143/* This holds the current reference counts for each debug register. */
144static int dr_ref_count[4];
145
e49d4fa6
SS
146extern char **environ;
147
148#define SOME_PID 42
149
e49d4fa6 150static int prog_has_started = 0;
c5aa993b
JM
151static void go32_open (char *name, int from_tty);
152static void go32_close (int quitting);
153static void go32_attach (char *args, int from_tty);
154static void go32_detach (char *args, int from_tty);
155static void go32_resume (int pid, int step, enum target_signal siggnal);
156static int go32_wait (int pid, struct target_waitstatus *status);
157static void go32_fetch_registers (int regno);
158static void store_register (int regno);
159static void go32_store_registers (int regno);
160static void go32_prepare_to_store (void);
161static int go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
a17b5c4e
EZ
162 int write,
163 struct mem_attrib *attrib,
164 struct target_ops *target);
c5aa993b
JM
165static void go32_files_info (struct target_ops *target);
166static void go32_stop (void);
167static void go32_kill_inferior (void);
168static void go32_create_inferior (char *exec_file, char *args, char **env);
169static void go32_mourn_inferior (void);
170static int go32_can_run (void);
b83266a0
SS
171
172static struct target_ops go32_ops;
c5aa993b
JM
173static void go32_terminal_init (void);
174static void go32_terminal_inferior (void);
175static void go32_terminal_ours (void);
e49d4fa6 176
53a5351d 177#define r_ofs(x) (offsetof(TSS,x))
e49d4fa6
SS
178
179static struct
180{
53a5351d
JM
181 size_t tss_ofs;
182 size_t size;
e49d4fa6
SS
183}
184regno_mapping[] =
185{
0fff5247
EZ
186 {r_ofs (tss_eax), 4}, /* normal registers, from a_tss */
187 {r_ofs (tss_ecx), 4},
188 {r_ofs (tss_edx), 4},
189 {r_ofs (tss_ebx), 4},
190 {r_ofs (tss_esp), 4},
191 {r_ofs (tss_ebp), 4},
192 {r_ofs (tss_esi), 4},
193 {r_ofs (tss_edi), 4},
194 {r_ofs (tss_eip), 4},
195 {r_ofs (tss_eflags), 4},
196 {r_ofs (tss_cs), 2},
197 {r_ofs (tss_ss), 2},
198 {r_ofs (tss_ds), 2},
199 {r_ofs (tss_es), 2},
200 {r_ofs (tss_fs), 2},
201 {r_ofs (tss_gs), 2},
202 {0, 10}, /* 8 FP registers, from npx.reg[] */
203 {1, 10},
204 {2, 10},
205 {3, 10},
206 {4, 10},
207 {5, 10},
208 {6, 10},
209 {7, 10},
53a5351d 210 /* The order of the next 7 registers must be consistent
0fff5247
EZ
211 with their numbering in config/i386/tm-i386.h, which see. */
212 {0, 2}, /* control word, from npx */
213 {4, 2}, /* status word, from npx */
214 {8, 2}, /* tag word, from npx */
215 {16, 2}, /* last FP exception CS from npx */
216 {12, 4}, /* last FP exception EIP from npx */
217 {24, 2}, /* last FP exception operand selector from npx */
218 {20, 4}, /* last FP exception operand offset from npx */
219 {18, 2} /* last FP opcode from npx */
e49d4fa6
SS
220};
221
222static struct
223 {
224 int go32_sig;
0fff5247 225 enum target_signal gdb_sig;
e49d4fa6
SS
226 }
227sig_map[] =
228{
0fff5247
EZ
229 {0, TARGET_SIGNAL_FPE},
230 {1, TARGET_SIGNAL_TRAP},
53a5351d
JM
231 /* Exception 2 is triggered by the NMI. DJGPP handles it as SIGILL,
232 but I think SIGBUS is better, since the NMI is usually activated
233 as a result of a memory parity check failure. */
0fff5247
EZ
234 {2, TARGET_SIGNAL_BUS},
235 {3, TARGET_SIGNAL_TRAP},
236 {4, TARGET_SIGNAL_FPE},
237 {5, TARGET_SIGNAL_SEGV},
238 {6, TARGET_SIGNAL_ILL},
239 {7, TARGET_SIGNAL_EMT}, /* no-coprocessor exception */
240 {8, TARGET_SIGNAL_SEGV},
241 {9, TARGET_SIGNAL_SEGV},
242 {10, TARGET_SIGNAL_BUS},
243 {11, TARGET_SIGNAL_SEGV},
244 {12, TARGET_SIGNAL_SEGV},
245 {13, TARGET_SIGNAL_SEGV},
246 {14, TARGET_SIGNAL_SEGV},
247 {16, TARGET_SIGNAL_FPE},
248 {17, TARGET_SIGNAL_BUS},
249 {31, TARGET_SIGNAL_ILL},
250 {0x1b, TARGET_SIGNAL_INT},
251 {0x75, TARGET_SIGNAL_FPE},
252 {0x78, TARGET_SIGNAL_ALRM},
253 {0x79, TARGET_SIGNAL_INT},
254 {0x7a, TARGET_SIGNAL_QUIT},
255 {-1, TARGET_SIGNAL_LAST}
e49d4fa6
SS
256};
257
53a5351d
JM
258static struct {
259 enum target_signal gdb_sig;
260 int djgpp_excepno;
261} excepn_map[] = {
0fff5247
EZ
262 {TARGET_SIGNAL_0, -1},
263 {TARGET_SIGNAL_ILL, 6}, /* Invalid Opcode */
264 {TARGET_SIGNAL_EMT, 7}, /* triggers SIGNOFP */
265 {TARGET_SIGNAL_SEGV, 13}, /* GPF */
266 {TARGET_SIGNAL_BUS, 17}, /* Alignment Check */
53a5351d
JM
267 /* The rest are fake exceptions, see dpmiexcp.c in djlsr*.zip for
268 details. */
0fff5247
EZ
269 {TARGET_SIGNAL_TERM, 0x1b}, /* triggers Ctrl-Break type of SIGINT */
270 {TARGET_SIGNAL_FPE, 0x75},
271 {TARGET_SIGNAL_INT, 0x79},
272 {TARGET_SIGNAL_QUIT, 0x7a},
273 {TARGET_SIGNAL_ALRM, 0x78}, /* triggers SIGTIMR */
274 {TARGET_SIGNAL_PROF, 0x78},
275 {TARGET_SIGNAL_LAST, -1}
53a5351d
JM
276};
277
e49d4fa6 278static void
0fff5247 279go32_open (char *name ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
e49d4fa6 280{
53a5351d 281 printf_unfiltered ("Done. Use the \"run\" command to run the program.\n");
e49d4fa6
SS
282}
283
284static void
0fff5247 285go32_close (int quitting ATTRIBUTE_UNUSED)
e49d4fa6
SS
286{
287}
288
289static void
0fff5247 290go32_attach (char *args ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
e49d4fa6 291{
53a5351d
JM
292 error ("\
293You cannot attach to a running program on this platform.\n\
294Use the `run' command to run DJGPP programs.");
e49d4fa6
SS
295}
296
297static void
0fff5247 298go32_detach (char *args ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
e49d4fa6
SS
299{
300}
301
302static int resume_is_step;
53a5351d 303static int resume_signal = -1;
e49d4fa6
SS
304
305static void
0fff5247 306go32_resume (int pid ATTRIBUTE_UNUSED, int step, enum target_signal siggnal)
c5aa993b 307{
53a5351d
JM
308 int i;
309
c5aa993b 310 resume_is_step = step;
53a5351d
JM
311
312 if (siggnal != TARGET_SIGNAL_0 && siggnal != TARGET_SIGNAL_TRAP)
313 {
0fff5247
EZ
314 for (i = 0, resume_signal = -1;
315 excepn_map[i].gdb_sig != TARGET_SIGNAL_LAST; i++)
53a5351d
JM
316 if (excepn_map[i].gdb_sig == siggnal)
317 {
318 resume_signal = excepn_map[i].djgpp_excepno;
319 break;
320 }
321 if (resume_signal == -1)
322 printf_unfiltered ("Cannot deliver signal %s on this platform.\n",
323 target_signal_to_name (siggnal));
324 }
c5aa993b 325}
e49d4fa6 326
53a5351d
JM
327static char child_cwd[FILENAME_MAX];
328
e49d4fa6 329static int
0fff5247 330go32_wait (int pid ATTRIBUTE_UNUSED, struct target_waitstatus *status)
e49d4fa6
SS
331{
332 int i;
53a5351d 333 unsigned char saved_opcode;
0fff5247 334 unsigned long INT3_addr = 0;
53a5351d 335 int stepping_over_INT = 0;
e49d4fa6 336
53a5351d 337 a_tss.tss_eflags &= 0xfeff; /* reset the single-step flag (TF) */
e49d4fa6 338 if (resume_is_step)
53a5351d
JM
339 {
340 /* If the next instruction is INT xx or INTO, we need to handle
341 them specially. Intel manuals say that these instructions
342 reset the single-step flag (a.k.a. TF). However, it seems
343 that, at least in the DPMI environment, and at least when
344 stepping over the DPMI interrupt 31h, the problem is having
345 TF set at all when INT 31h is executed: the debuggee either
346 crashes (and takes the system with it) or is killed by a
347 SIGTRAP.
348
349 So we need to emulate single-step mode: we put an INT3 opcode
350 right after the INT xx instruction, let the debuggee run
351 until it hits INT3 and stops, then restore the original
352 instruction which we overwrote with the INT3 opcode, and back
353 up the debuggee's EIP to that instruction. */
354 read_child (a_tss.tss_eip, &saved_opcode, 1);
355 if (saved_opcode == 0xCD || saved_opcode == 0xCE)
356 {
357 unsigned char INT3_opcode = 0xCC;
358
359 INT3_addr
360 = saved_opcode == 0xCD ? a_tss.tss_eip + 2 : a_tss.tss_eip + 1;
361 stepping_over_INT = 1;
362 read_child (INT3_addr, &saved_opcode, 1);
363 write_child (INT3_addr, &INT3_opcode, 1);
364 }
365 else
366 a_tss.tss_eflags |= 0x0100; /* normal instruction: set TF */
367 }
368
369 /* The special value FFFFh in tss_trap indicates to run_child that
370 tss_irqn holds a signal to be delivered to the debuggee. */
371 if (resume_signal <= -1)
372 {
373 a_tss.tss_trap = 0;
374 a_tss.tss_irqn = 0xff;
375 }
e49d4fa6 376 else
53a5351d
JM
377 {
378 a_tss.tss_trap = 0xffff; /* run_child looks for this */
379 a_tss.tss_irqn = resume_signal;
380 }
381
382 /* The child might change working directory behind our back. The
383 GDB users won't like the side effects of that when they work with
384 relative file names, and GDB might be confused by its current
385 directory not being in sync with the truth. So we always make a
386 point of changing back to where GDB thinks is its cwd, when we
387 return control to the debugger, but restore child's cwd before we
388 run it. */
3a45aed8
EZ
389 /* Initialize child_cwd, before the first call to run_child and not
390 in the initialization, so the child get also the changed directory
391 set with the gdb-command "cd ..." */
392 if (!*child_cwd)
393 /* Initialize child's cwd with the current one. */
394 getcwd (child_cwd, sizeof (child_cwd));
395
53a5351d 396 chdir (child_cwd);
e49d4fa6 397
b83266a0 398#if __DJGPP_MINOR__ < 3
53a5351d 399 load_npx ();
b83266a0 400#endif
e49d4fa6 401 run_child ();
b83266a0 402#if __DJGPP_MINOR__ < 3
53a5351d 403 save_npx ();
b83266a0 404#endif
e49d4fa6 405
53a5351d
JM
406 /* Did we step over an INT xx instruction? */
407 if (stepping_over_INT && a_tss.tss_eip == INT3_addr + 1)
408 {
409 /* Restore the original opcode. */
410 a_tss.tss_eip--; /* EIP points *after* the INT3 instruction */
411 write_child (a_tss.tss_eip, &saved_opcode, 1);
412 /* Simulate a TRAP exception. */
413 a_tss.tss_irqn = 1;
414 a_tss.tss_eflags |= 0x0100;
415 }
416
417 getcwd (child_cwd, sizeof (child_cwd)); /* in case it has changed */
418 chdir (current_directory);
419
e49d4fa6
SS
420 if (a_tss.tss_irqn == 0x21)
421 {
422 status->kind = TARGET_WAITKIND_EXITED;
423 status->value.integer = a_tss.tss_eax & 0xff;
424 }
425 else
426 {
427 status->value.sig = TARGET_SIGNAL_UNKNOWN;
428 status->kind = TARGET_WAITKIND_STOPPED;
429 for (i = 0; sig_map[i].go32_sig != -1; i++)
430 {
431 if (a_tss.tss_irqn == sig_map[i].go32_sig)
432 {
53a5351d 433#if __DJGPP_MINOR__ < 3
e49d4fa6
SS
434 if ((status->value.sig = sig_map[i].gdb_sig) !=
435 TARGET_SIGNAL_TRAP)
436 status->kind = TARGET_WAITKIND_SIGNALLED;
53a5351d
JM
437#else
438 status->value.sig = sig_map[i].gdb_sig;
439#endif
e49d4fa6
SS
440 break;
441 }
442 }
443 }
444 return SOME_PID;
445}
446
447static void
89dea5aa 448fetch_register (int regno)
e49d4fa6 449{
89dea5aa
EZ
450 if (regno < FP0_REGNUM)
451 supply_register (regno, (char *) &a_tss + regno_mapping[regno].tss_ofs);
452 else if (regno <= LAST_FPU_CTRL_REGNUM)
453 i387_supply_register (regno, (char *) &npx);
454 else
455 internal_error (__FILE__, __LINE__,
456 "Invalid register no. %d in fetch_register.", regno);
457}
e49d4fa6 458
89dea5aa
EZ
459static void
460go32_fetch_registers (int regno)
461{
462 if (regno >= 0)
463 fetch_register (regno);
464 else
e49d4fa6 465 {
89dea5aa
EZ
466 for (regno = 0; regno < FP0_REGNUM; regno++)
467 fetch_register (regno);
468 i387_supply_fsave ((char *) &npx);
e49d4fa6
SS
469 }
470}
471
472static void
473store_register (int regno)
474{
475 void *rp;
476 void *v = (void *) &registers[REGISTER_BYTE (regno)];
477
89dea5aa
EZ
478 if (regno < FP0_REGNUM)
479 memcpy ((char *) &a_tss + regno_mapping[regno].tss_ofs,
480 v, regno_mapping[regno].size);
481 else if (regno <= LAST_FPU_CTRL_REGNUM)
482 i387_fill_fsave ((char *)&npx, regno);
e49d4fa6 483 else
8e65ff28
AC
484 internal_error (__FILE__, __LINE__,
485 "Invalid register no. %d in store_register.", regno);
e49d4fa6
SS
486}
487
488static void
489go32_store_registers (int regno)
490{
0fff5247 491 unsigned r;
e49d4fa6
SS
492
493 if (regno >= 0)
494 store_register (regno);
495 else
496 {
89dea5aa 497 for (r = 0; r < FP0_REGNUM; r++)
e49d4fa6 498 store_register (r);
89dea5aa 499 i387_fill_fsave ((char *) &npx, -1);
e49d4fa6
SS
500 }
501}
502
503static void
504go32_prepare_to_store (void)
505{
506}
507
508static int
509go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
a17b5c4e 510 struct mem_attrib *attrib ATTRIBUTE_UNUSED,
0fff5247 511 struct target_ops *target ATTRIBUTE_UNUSED)
e49d4fa6
SS
512{
513 if (write)
514 {
515 if (write_child (memaddr, myaddr, len))
516 {
517 return 0;
518 }
519 else
520 {
521 return len;
522 }
523 }
524 else
525 {
526 if (read_child (memaddr, myaddr, len))
527 {
528 return 0;
529 }
530 else
531 {
532 return len;
533 }
534 }
535}
536
53a5351d
JM
537static cmdline_t child_cmd; /* parsed child's command line kept here */
538
e49d4fa6 539static void
0fff5247 540go32_files_info (struct target_ops *target ATTRIBUTE_UNUSED)
e49d4fa6 541{
53a5351d 542 printf_unfiltered ("You are running a DJGPP V2 program.\n");
e49d4fa6
SS
543}
544
545static void
546go32_stop (void)
547{
548 normal_stop ();
549 cleanup_client ();
550 inferior_pid = 0;
551 prog_has_started = 0;
552}
553
554static void
555go32_kill_inferior (void)
556{
53a5351d
JM
557 redir_cmdline_delete (&child_cmd);
558 resume_signal = -1;
559 resume_is_step = 0;
e49d4fa6
SS
560 unpush_target (&go32_ops);
561}
562
563static void
564go32_create_inferior (char *exec_file, char *args, char **env)
565{
566 jmp_buf start_state;
567 char *cmdline;
568 char **env_save = environ;
569
0fff5247
EZ
570 /* If no exec file handed to us, get it from the exec-file command -- with
571 a good, common error message if none is specified. */
572 if (exec_file == 0)
573 exec_file = get_exec_file (1);
574
e49d4fa6
SS
575 if (prog_has_started)
576 {
b83266a0 577 go32_stop ();
e49d4fa6
SS
578 go32_kill_inferior ();
579 }
53a5351d
JM
580 resume_signal = -1;
581 resume_is_step = 0;
3a45aed8
EZ
582
583 /* Initialize child's cwd as empty to be initialized when starting
584 the child. */
585 *child_cwd = 0;
586
53a5351d
JM
587 /* Init command line storage. */
588 if (redir_debug_init (&child_cmd) == -1)
8e65ff28
AC
589 internal_error (__FILE__, __LINE__,
590 "Cannot allocate redirection storage: not enough memory.\n");
53a5351d
JM
591
592 /* Parse the command line and create redirections. */
593 if (strpbrk (args, "<>"))
594 {
595 if (redir_cmdline_parse (args, &child_cmd) == 0)
596 args = child_cmd.command;
597 else
598 error ("Syntax error in command line.");
599 }
600 else
c2d11a7d 601 child_cmd.command = xstrdup (args);
e49d4fa6
SS
602
603 cmdline = (char *) alloca (strlen (args) + 4);
604 cmdline[0] = strlen (args);
605 strcpy (cmdline + 1, args);
606 cmdline[strlen (args) + 1] = 13;
607
608 environ = env;
609
610 if (v2loadimage (exec_file, cmdline, start_state))
611 {
612 environ = env_save;
613 printf_unfiltered ("Load failed for image %s\n", exec_file);
614 exit (1);
615 }
616 environ = env_save;
617
618 edi_init (start_state);
53a5351d
JM
619#if __DJGPP_MINOR__ < 3
620 save_npx ();
621#endif
e49d4fa6
SS
622
623 inferior_pid = SOME_PID;
624 push_target (&go32_ops);
625 clear_proceed_status ();
626 insert_breakpoints ();
2acceee2 627 proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
b83266a0 628 prog_has_started = 1;
e49d4fa6
SS
629}
630
631static void
632go32_mourn_inferior (void)
633{
53a5351d
JM
634 /* We need to make sure all the breakpoint enable bits in the DR7
635 register are reset when the inferior exits. Otherwise, if they
636 rerun the inferior, the uncleared bits may cause random SIGTRAPs,
637 failure to set more watchpoints, and other calamities. It would
638 be nice if GDB itself would take care to remove all breakpoints
639 at all times, but it doesn't, probably under an assumption that
640 the OS cleans up when the debuggee exits. */
e24d4c64 641 i386_cleanup_dregs ();
e49d4fa6
SS
642 go32_kill_inferior ();
643 generic_mourn_inferior ();
644}
645
646static int
647go32_can_run (void)
648{
649 return 1;
650}
651
e49d4fa6
SS
652/* Hardware watchpoint support. */
653
e49d4fa6 654#define D_REGS edi.dr
e24d4c64
EZ
655#define CONTROL D_REGS[7]
656#define STATUS D_REGS[6]
53a5351d 657
e24d4c64
EZ
658/* Pass the address ADDR to the inferior in the I'th debug register.
659 Here we just store the address in D_REGS, the watchpoint will be
660 actually set up when go32_wait runs the debuggee. */
661void
662go32_set_dr (int i, CORE_ADDR addr)
e49d4fa6 663{
e24d4c64 664 D_REGS[i] = addr;
e49d4fa6
SS
665}
666
e24d4c64
EZ
667/* Pass the value VAL to the inferior in the DR7 debug control
668 register. Here we just store the address in D_REGS, the watchpoint
669 will be actually set up when go32_wait runs the debuggee. */
670void
671go32_set_dr7 (unsigned val)
53a5351d 672{
e24d4c64 673 CONTROL = val;
53a5351d
JM
674}
675
e24d4c64
EZ
676/* Get the value of the DR6 debug status register from the inferior.
677 Here we just return the value stored in D_REGS, as we've got it
678 from the last go32_wait call. */
679unsigned
680go32_get_dr6 (void)
e49d4fa6 681{
e24d4c64 682 return STATUS;
e49d4fa6
SS
683}
684
53a5351d
JM
685/* Put the device open on handle FD into either raw or cooked
686 mode, return 1 if it was in raw mode, zero otherwise. */
687
688static int
689device_mode (int fd, int raw_p)
690{
691 int oldmode, newmode;
692 __dpmi_regs regs;
693
694 regs.x.ax = 0x4400;
695 regs.x.bx = fd;
696 __dpmi_int (0x21, &regs);
697 if (regs.x.flags & 1)
698 return -1;
699 newmode = oldmode = regs.x.dx;
700
701 if (raw_p)
702 newmode |= 0x20;
703 else
704 newmode &= ~0x20;
705
706 if (oldmode & 0x80) /* Only for character dev */
707 {
708 regs.x.ax = 0x4401;
709 regs.x.bx = fd;
710 regs.x.dx = newmode & 0xff; /* Force upper byte zero, else it fails */
711 __dpmi_int (0x21, &regs);
712 if (regs.x.flags & 1)
713 return -1;
714 }
715 return (oldmode & 0x20) == 0x20;
716}
717
718
719static int inf_mode_valid = 0;
720static int inf_terminal_mode;
721
722/* This semaphore is needed because, amazingly enough, GDB calls
723 target.to_terminal_ours more than once after the inferior stops.
724 But we need the information from the first call only, since the
725 second call will always see GDB's own cooked terminal. */
726static int terminal_is_ours = 1;
727
cce74817
JM
728static void
729go32_terminal_init (void)
730{
53a5351d
JM
731 inf_mode_valid = 0; /* reinitialize, in case they are restarting child */
732 terminal_is_ours = 1;
cce74817
JM
733}
734
735static void
0fff5247 736go32_terminal_info (char *args ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
cce74817 737{
53a5351d
JM
738 printf_unfiltered ("Inferior's terminal is in %s mode.\n",
739 !inf_mode_valid
740 ? "default" : inf_terminal_mode ? "raw" : "cooked");
741
742#if __DJGPP_MINOR__ > 2
743 if (child_cmd.redirection)
744 {
745 int i;
746
747 for (i = 0; i < DBG_HANDLES; i++)
c5aa993b 748 {
53a5351d
JM
749 if (child_cmd.redirection[i]->file_name)
750 printf_unfiltered ("\tFile handle %d is redirected to `%s'.\n",
751 i, child_cmd.redirection[i]->file_name);
752 else if (_get_dev_info (child_cmd.redirection[i]->inf_handle) == -1)
753 printf_unfiltered
754 ("\tFile handle %d appears to be closed by inferior.\n", i);
755 /* Mask off the raw/cooked bit when comparing device info words. */
756 else if ((_get_dev_info (child_cmd.redirection[i]->inf_handle) & 0xdf)
757 != (_get_dev_info (i) & 0xdf))
758 printf_unfiltered
759 ("\tFile handle %d appears to be redirected by inferior.\n", i);
c5aa993b 760 }
53a5351d
JM
761 }
762#endif
763}
764
765static void
766go32_terminal_inferior (void)
767{
768 /* Redirect standard handles as child wants them. */
769 errno = 0;
770 if (redir_to_child (&child_cmd) == -1)
771 {
772 redir_to_debugger (&child_cmd);
773 error ("Cannot redirect standard handles for program: %s.",
774 strerror (errno));
775 }
776 /* set the console device of the inferior to whatever mode
777 (raw or cooked) we found it last time */
778 if (terminal_is_ours)
779 {
780 if (inf_mode_valid)
781 device_mode (0, inf_terminal_mode);
782 terminal_is_ours = 0;
783 }
cce74817
JM
784}
785
786static void
787go32_terminal_ours (void)
788{
53a5351d
JM
789 /* Switch to cooked mode on the gdb terminal and save the inferior
790 terminal mode to be restored when it is resumed */
791 if (!terminal_is_ours)
792 {
793 inf_terminal_mode = device_mode (0, 0);
794 if (inf_terminal_mode != -1)
795 inf_mode_valid = 1;
796 else
797 /* If device_mode returned -1, we don't know what happens with
798 handle 0 anymore, so make the info invalid. */
799 inf_mode_valid = 0;
800 terminal_is_ours = 1;
801
802 /* Restore debugger's standard handles. */
803 errno = 0;
804 if (redir_to_debugger (&child_cmd) == -1)
805 {
806 redir_to_child (&child_cmd);
807 error ("Cannot redirect standard handles for debugger: %s.",
808 strerror (errno));
809 }
810 }
cce74817
JM
811}
812
e49d4fa6
SS
813static void
814init_go32_ops (void)
815{
816 go32_ops.to_shortname = "djgpp";
817 go32_ops.to_longname = "djgpp target process";
818 go32_ops.to_doc =
819 "Program loaded by djgpp, when gdb is used as an external debugger";
820 go32_ops.to_open = go32_open;
821 go32_ops.to_close = go32_close;
53a5351d 822 go32_ops.to_attach = go32_attach;
e49d4fa6
SS
823 go32_ops.to_detach = go32_detach;
824 go32_ops.to_resume = go32_resume;
825 go32_ops.to_wait = go32_wait;
826 go32_ops.to_fetch_registers = go32_fetch_registers;
827 go32_ops.to_store_registers = go32_store_registers;
828 go32_ops.to_prepare_to_store = go32_prepare_to_store;
829 go32_ops.to_xfer_memory = go32_xfer_memory;
830 go32_ops.to_files_info = go32_files_info;
831 go32_ops.to_insert_breakpoint = memory_insert_breakpoint;
832 go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
cce74817
JM
833 go32_ops.to_terminal_init = go32_terminal_init;
834 go32_ops.to_terminal_inferior = go32_terminal_inferior;
53a5351d 835 go32_ops.to_terminal_ours_for_output = go32_terminal_ours;
cce74817 836 go32_ops.to_terminal_ours = go32_terminal_ours;
53a5351d 837 go32_ops.to_terminal_info = go32_terminal_info;
e49d4fa6
SS
838 go32_ops.to_kill = go32_kill_inferior;
839 go32_ops.to_create_inferior = go32_create_inferior;
840 go32_ops.to_mourn_inferior = go32_mourn_inferior;
841 go32_ops.to_can_run = go32_can_run;
842 go32_ops.to_stop = go32_stop;
843 go32_ops.to_stratum = process_stratum;
844 go32_ops.to_has_all_memory = 1;
845 go32_ops.to_has_memory = 1;
846 go32_ops.to_has_stack = 1;
847 go32_ops.to_has_registers = 1;
848 go32_ops.to_has_execution = 1;
849 go32_ops.to_magic = OPS_MAGIC;
53a5351d 850
3a45aed8
EZ
851 /* Initialize child's cwd as empty to be initialized when starting
852 the child. */
853 *child_cwd = 0;
53a5351d
JM
854
855 /* Initialize child's command line storage. */
856 if (redir_debug_init (&child_cmd) == -1)
8e65ff28
AC
857 internal_error (__FILE__, __LINE__,
858 "Cannot allocate redirection storage: not enough memory.\n");
0fff5247
EZ
859
860 /* We are always processing GCC-compiled programs. */
861 processing_gcc_compilation = 2;
e49d4fa6
SS
862}
863
864void
865_initialize_go32_nat (void)
866{
867 init_go32_ops ();
868 add_target (&go32_ops);
869}
53a5351d
JM
870
871pid_t
872tcgetpgrp (int fd)
873{
874 if (isatty (fd))
875 return SOME_PID;
876 errno = ENOTTY;
877 return -1;
878}
879
880int
881tcsetpgrp (int fd, pid_t pgid)
882{
883 if (isatty (fd) && pgid == SOME_PID)
884 return 0;
885 errno = pgid == SOME_PID ? ENOTTY : ENOSYS;
886 return -1;
887}