]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/go32-nat.c
import gdb-1999-07-07 post reformat
[thirdparty/binutils-gdb.git] / gdb / go32-nat.c
1 /* Native debugging support for Intel x86 running DJGPP.
2 Copyright 1997, 1999 Free Software Foundation, Inc.
3 Written by Robert Hoehne.
4
5 This file is part of GDB.
6
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.
11
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.
16
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. */
21
22 #include <fcntl.h>
23
24 #include "defs.h"
25 #include "frame.h" /* required by inferior.h */
26 #include "inferior.h"
27 #include "target.h"
28 #include "wait.h"
29 #include "gdbcore.h"
30 #include "command.h"
31 #include "floatformat.h"
32
33 #include <stdio.h> /* required for __DJGPP_MINOR__ */
34 #include <stdlib.h>
35 #include <string.h>
36 #include <unistd.h>
37 #include <debug/v2load.h>
38 #include <debug/dbgcom.h>
39
40 #if __DJGPP_MINOR__ < 3
41 /* This code will be provided from DJGPP 2.03 on. Until then I code it
42 here */
43 typedef struct
44 {
45 unsigned short sig0;
46 unsigned short sig1;
47 unsigned short sig2;
48 unsigned short sig3;
49 unsigned short exponent:15;
50 unsigned short sign:1;
51 }
52 NPXREG;
53
54 typedef struct
55 {
56 unsigned int control;
57 unsigned int status;
58 unsigned int tag;
59 unsigned int eip;
60 unsigned int cs;
61 unsigned int dataptr;
62 unsigned int datasel;
63 NPXREG reg[8];
64 }
65 NPX;
66
67 static NPX npx;
68
69 static void save_npx (void); /* Save the FPU of the debugged program */
70 static void load_npx (void); /* Restore the FPU of the debugged program */
71
72 /* ------------------------------------------------------------------------- */
73 /* Store the contents of the NPX in the global variable `npx'. */
74 /* *INDENT-OFF* */
75
76 static void
77 save_npx (void)
78 {
79 asm ("inb $0xa0, %%al
80 testb $0x20, %%al
81 jz 1f
82 xorb %% al, %%al
83 outb %% al, $0xf0
84 movb $0x20, %%al
85 outb %% al, $0xa0
86 outb %% al, $0x20
87 1:
88 fnsave % 0
89 fwait "
90 : "=m" (npx)
91 : /* No input */
92 : "%eax");
93 }
94
95 /* *INDENT-ON* */
96
97
98
99
100
101 /* ------------------------------------------------------------------------- */
102 /* Reload the contents of the NPX from the global variable `npx'. */
103
104 static void
105 load_npx (void)
106 {
107 asm ("frstor %0":"=m" (npx));
108 }
109 #endif /* __DJGPP_MINOR < 3 */
110
111 extern void _initialize_go32_nat (void);
112
113 struct env387
114 {
115 unsigned short control;
116 unsigned short r0;
117 unsigned short status;
118 unsigned short r1;
119 unsigned short tag;
120 unsigned short r2;
121 unsigned long eip;
122 unsigned short code_seg;
123 unsigned short opcode;
124 unsigned long operand;
125 unsigned short operand_seg;
126 unsigned short r3;
127 unsigned char regs[8][10];
128 };
129
130 extern char **environ;
131
132 #define SOME_PID 42
133
134 static int prog_has_started = 0;
135 static void print_387_status (unsigned short status, struct env387 *ep);
136 static void go32_open (char *name, int from_tty);
137 static void go32_close (int quitting);
138 static void go32_attach (char *args, int from_tty);
139 static void go32_detach (char *args, int from_tty);
140 static void go32_resume (int pid, int step, enum target_signal siggnal);
141 static int go32_wait (int pid, struct target_waitstatus *status);
142 static void go32_fetch_registers (int regno);
143 static void store_register (int regno);
144 static void go32_store_registers (int regno);
145 static void go32_prepare_to_store (void);
146 static int go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
147 int write, struct target_ops *target);
148 static void go32_files_info (struct target_ops *target);
149 static void go32_stop (void);
150 static void go32_kill_inferior (void);
151 static void go32_create_inferior (char *exec_file, char *args, char **env);
152 static void go32_mourn_inferior (void);
153 static int go32_can_run (void);
154 static void ignore (void);
155 static void ignore2 (char *a, int b);
156 static int go32_insert_aligned_watchpoint (int pid, CORE_ADDR waddr,
157 CORE_ADDR addr, int len, int rw);
158 static int go32_insert_nonaligned_watchpoint (int pid, CORE_ADDR waddr,
159 CORE_ADDR addr, int len, int rw);
160
161 static struct target_ops go32_ops;
162 static void go32_terminal_init (void);
163 static void go32_terminal_inferior (void);
164 static void go32_terminal_ours (void);
165
166 static void
167 print_387_status (unsigned short status, struct env387 *ep)
168 {
169 int i;
170 int bothstatus;
171 int top;
172 int fpreg;
173
174 bothstatus = ((status != 0) && (ep->status != 0));
175 if (status != 0)
176 {
177 if (bothstatus)
178 printf_unfiltered ("u: ");
179 print_387_status_word (status);
180 }
181
182 if (ep->status != 0)
183 {
184 if (bothstatus)
185 printf_unfiltered ("e: ");
186 print_387_status_word (ep->status);
187 }
188
189 print_387_control_word (ep->control & 0xffff);
190 printf_unfiltered ("last exception: ");
191 printf_unfiltered ("opcode %s; ", local_hex_string (ep->opcode));
192 printf_unfiltered ("pc %s:", local_hex_string (ep->code_seg));
193 printf_unfiltered ("%s; ", local_hex_string (ep->eip));
194 printf_unfiltered ("operand %s", local_hex_string (ep->operand_seg));
195 printf_unfiltered (":%s\n", local_hex_string (ep->operand));
196
197 top = (ep->status >> 11) & 7;
198
199 printf_unfiltered ("regno tag msb lsb value\n");
200 for (fpreg = 0; fpreg < 8; fpreg++)
201 {
202 long double val;
203
204 printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : " ", fpreg);
205
206 switch ((ep->tag >> (fpreg * 2)) & 3)
207 {
208 case 0:
209 printf_unfiltered ("valid ");
210 break;
211 case 1:
212 printf_unfiltered ("zero ");
213 break;
214 case 2:
215 printf_unfiltered ("trap ");
216 break;
217 case 3:
218 printf_unfiltered ("empty ");
219 break;
220 }
221 for (i = 0; i < 8; i++)
222 printf_unfiltered ("%02x", ep->regs[fpreg][i]);
223
224 REGISTER_CONVERT_TO_VIRTUAL (FP0_REGNUM + fpreg, builtin_type_long_double,
225 &ep->regs[fpreg], &val);
226
227 printf_unfiltered (" %LG\n", val);
228 }
229 }
230
231 void
232 i386_go32_float_info (void)
233 {
234 print_387_status (0, (struct env387 *) &npx);
235 }
236
237 #define r_ofs(x) ((int)(&(((TSS *)0)->x)))
238
239 static struct
240 {
241 int tss_ofs;
242 int size;
243 }
244 regno_mapping[] =
245 {
246 r_ofs (tss_eax), 4,
247 r_ofs (tss_ecx), 4,
248 r_ofs (tss_edx), 4,
249 r_ofs (tss_ebx), 4,
250 r_ofs (tss_esp), 4,
251 r_ofs (tss_ebp), 4,
252 r_ofs (tss_esi), 4,
253 r_ofs (tss_edi), 4,
254 r_ofs (tss_eip), 4,
255 r_ofs (tss_eflags), 4,
256 r_ofs (tss_cs), 2,
257 r_ofs (tss_ss), 2,
258 r_ofs (tss_ds), 2,
259 r_ofs (tss_es), 2,
260 r_ofs (tss_fs), 2,
261 r_ofs (tss_gs), 2,
262 0, 10,
263 1, 10,
264 2, 10,
265 3, 10,
266 4, 10,
267 5, 10,
268 6, 10,
269 7, 10,
270 0, 2,
271 4, 2,
272 8, 2,
273 12, 4,
274 16, 2,
275 20, 4,
276 24, 2
277 };
278
279 static struct
280 {
281 int go32_sig;
282 int gdb_sig;
283 }
284 sig_map[] =
285 {
286 0, TARGET_SIGNAL_FPE,
287 1, TARGET_SIGNAL_TRAP,
288 2, TARGET_SIGNAL_UNKNOWN,
289 3, TARGET_SIGNAL_TRAP,
290 4, TARGET_SIGNAL_FPE,
291 5, TARGET_SIGNAL_SEGV,
292 6, TARGET_SIGNAL_ILL,
293 7, TARGET_SIGNAL_FPE,
294 8, TARGET_SIGNAL_SEGV,
295 9, TARGET_SIGNAL_SEGV,
296 10, TARGET_SIGNAL_BUS,
297 11, TARGET_SIGNAL_SEGV,
298 12, TARGET_SIGNAL_SEGV,
299 13, TARGET_SIGNAL_ABRT,
300 14, TARGET_SIGNAL_SEGV,
301 16, TARGET_SIGNAL_FPE,
302 31, TARGET_SIGNAL_ILL,
303 0x75, TARGET_SIGNAL_FPE,
304 0x79, TARGET_SIGNAL_INT,
305 0x1b, TARGET_SIGNAL_INT,
306 -1, -1
307 };
308
309 static void
310 go32_open (char *name, int from_tty)
311 {
312 printf_unfiltered ("Use the `run' command to run go32 programs\n");
313 }
314
315 static void
316 go32_close (int quitting)
317 {
318 }
319
320 static void
321 go32_attach (char *args, int from_tty)
322 {
323 printf_unfiltered ("Use the `run' command to run go32 programs\n");
324 }
325
326 static void
327 go32_detach (char *args, int from_tty)
328 {
329 }
330
331 static int resume_is_step;
332
333 static void
334 go32_resume (int pid, int step, enum target_signal siggnal)
335 {
336 resume_is_step = step;
337 }
338
339 static int
340 go32_wait (int pid, struct target_waitstatus *status)
341 {
342 int i;
343
344 if (resume_is_step)
345 a_tss.tss_eflags |= 0x0100;
346 else
347 a_tss.tss_eflags &= 0xfeff;
348
349 #if __DJGPP_MINOR__ < 3
350 save_npx ();
351 #endif
352 run_child ();
353 #if __DJGPP_MINOR__ < 3
354 load_npx ();
355 #endif
356
357 if (a_tss.tss_irqn == 0x21)
358 {
359 status->kind = TARGET_WAITKIND_EXITED;
360 status->value.integer = a_tss.tss_eax & 0xff;
361 }
362 else
363 {
364 status->value.sig = TARGET_SIGNAL_UNKNOWN;
365 status->kind = TARGET_WAITKIND_STOPPED;
366 for (i = 0; sig_map[i].go32_sig != -1; i++)
367 {
368 if (a_tss.tss_irqn == sig_map[i].go32_sig)
369 {
370 if ((status->value.sig = sig_map[i].gdb_sig) !=
371 TARGET_SIGNAL_TRAP)
372 status->kind = TARGET_WAITKIND_SIGNALLED;
373 break;
374 }
375 }
376 }
377 return SOME_PID;
378 }
379
380 static void
381 go32_fetch_registers (int regno)
382 {
383 /*JHW */
384 int end_reg = regno + 1; /* just one reg initially */
385
386 if (regno < 0) /* do the all registers */
387 {
388 regno = 0; /* start at first register */
389 /* # regs in table */
390 end_reg = sizeof (regno_mapping) / sizeof (regno_mapping[0]);
391 }
392
393 for (; regno < end_reg; regno++)
394 {
395 if (regno < 16)
396 supply_register (regno,
397 (char *) &a_tss + regno_mapping[regno].tss_ofs);
398 else if (regno < 24)
399 supply_register (regno,
400 (char *) &npx.reg[regno_mapping[regno].tss_ofs]);
401 else if (regno < 31)
402 supply_register (regno,
403 (char *) &npx.reg + regno_mapping[regno].tss_ofs);
404 else
405 {
406 printf_unfiltered ("Invalid register in go32_fetch_register(%d)",
407 regno);
408 exit (1);
409 }
410 }
411 }
412
413 static void
414 store_register (int regno)
415 {
416 void *rp;
417 void *v = (void *) &registers[REGISTER_BYTE (regno)];
418
419 if (regno < 16)
420 rp = (char *) &a_tss + regno_mapping[regno].tss_ofs;
421 else if (regno < 24)
422 rp = (char *) &npx.reg[regno_mapping[regno].tss_ofs];
423 else if (regno > 31)
424 rp = (char *) &npx + regno_mapping[regno].tss_ofs;
425 else
426 {
427 printf_unfiltered ("Invalid register in store_register(%d)", regno);
428 exit (1);
429 }
430 memcpy (rp, v, regno_mapping[regno].size);
431 }
432
433 static void
434 go32_store_registers (int regno)
435 {
436 int r;
437
438 if (regno >= 0)
439 store_register (regno);
440 else
441 {
442 for (r = 0; r < sizeof (regno_mapping) / sizeof (regno_mapping[0]); r++)
443 store_register (r);
444 }
445 }
446
447 static void
448 go32_prepare_to_store (void)
449 {
450 }
451
452 static int
453 go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
454 struct target_ops *target)
455 {
456 if (write)
457 {
458 if (write_child (memaddr, myaddr, len))
459 {
460 return 0;
461 }
462 else
463 {
464 return len;
465 }
466 }
467 else
468 {
469 if (read_child (memaddr, myaddr, len))
470 {
471 return 0;
472 }
473 else
474 {
475 return len;
476 }
477 }
478 }
479
480 static void
481 go32_files_info (struct target_ops *target)
482 {
483 printf_unfiltered ("You are running a DJGPP V2 program\n");
484 }
485
486 static void
487 go32_stop (void)
488 {
489 normal_stop ();
490 cleanup_client ();
491 inferior_pid = 0;
492 prog_has_started = 0;
493 }
494
495 static void
496 go32_kill_inferior (void)
497 {
498 unpush_target (&go32_ops);
499 }
500
501 static void
502 go32_create_inferior (char *exec_file, char *args, char **env)
503 {
504 jmp_buf start_state;
505 char *cmdline;
506 char **env_save = environ;
507
508 if (prog_has_started)
509 {
510 go32_stop ();
511 go32_kill_inferior ();
512 }
513
514 cmdline = (char *) alloca (strlen (args) + 4);
515 cmdline[0] = strlen (args);
516 strcpy (cmdline + 1, args);
517 cmdline[strlen (args) + 1] = 13;
518
519 environ = env;
520
521 if (v2loadimage (exec_file, cmdline, start_state))
522 {
523 environ = env_save;
524 printf_unfiltered ("Load failed for image %s\n", exec_file);
525 exit (1);
526 }
527 environ = env_save;
528
529 edi_init (start_state);
530
531 inferior_pid = SOME_PID;
532 push_target (&go32_ops);
533 clear_proceed_status ();
534 insert_breakpoints ();
535 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
536 prog_has_started = 1;
537 }
538
539 static void
540 go32_mourn_inferior (void)
541 {
542 go32_kill_inferior ();
543 generic_mourn_inferior ();
544 }
545
546 static int
547 go32_can_run (void)
548 {
549 return 1;
550 }
551
552 static void
553 ignore (void)
554 {
555 }
556
557 static void
558 ignore2 (char *a, int b)
559 {
560 }
561
562 /* Hardware watchpoint support. */
563
564 #define DR_STATUS 6
565 #define DR_CONTROL 7
566 #define DR_ENABLE_SIZE 2
567 #define DR_LOCAL_ENABLE_SHIFT 0
568 #define DR_GLOBAL_ENABLE_SHIFT 1
569 #define DR_LOCAL_SLOWDOWN 0x100
570 #define DR_GLOBAL_SLOWDOWN 0x200
571 #define DR_CONTROL_SHIFT 16
572 #define DR_CONTROL_SIZE 4
573 #define DR_RW_READ 0x3
574 #define DR_RW_WRITE 0x1
575 #define DR_CONTROL_MASK 0xf
576 #define DR_ENABLE_MASK 0x3
577 #define DR_LEN_1 0x0
578 #define DR_LEN_2 0x4
579 #define DR_LEN_4 0xc
580
581 #define D_REGS edi.dr
582 #define CONTROL D_REGS[DR_CONTROL]
583 #define STATUS D_REGS[DR_STATUS]
584
585 #define IS_REG_FREE(index) \
586 (!(CONTROL & (3 << (DR_ENABLE_SIZE * index))))
587
588 #define LOCAL_ENABLE_REG(index) \
589 (CONTROL |= (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * index)))
590
591 #define GLOBAL_ENABLE_REG(index) \
592 (CONTROL |= (1 << (DR_GLOBAL_ENABLE_SHIFT + DR_ENABLE_SIZE * index)))
593
594 #define DISABLE_REG(index) \
595 (CONTROL &= ~(3 << (DR_ENABLE_SIZE * index)))
596
597 #define SET_LOCAL_EXACT() \
598 (CONTROL |= DR_LOCAL_SLOWDOWN)
599
600 #define SET_GLOBAL_EXACT() \
601 (CONTROL |= DR_GLOBAL_SLOWDOWN)
602
603 #define SET_BREAK(index,address) \
604 do {\
605 CONTROL &= ~(DR_CONTROL_MASK << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * index));\
606 D_REGS[index] = address;\
607 } while(0)
608
609 #define SET_WATCH(index,address,rw,len) \
610 do {\
611 SET_BREAK(index,address);\
612 CONTROL |= (len | rw) << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * index);\
613 } while (0)
614
615 #define WATCH_HIT(index) \
616 (\
617 (STATUS & (1 << index)) && \
618 (CONTROL & (DR_CONTROL_MASK << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * index)))\
619 )
620
621 #if 0 /* use debugging macro */
622 #define SHOW_DR(text) \
623 do { \
624 fprintf(stderr,"%08x %08x ",edi.dr[7],edi.dr[6]); \
625 fprintf(stderr,"%08x %08x ",edi.dr[0],edi.dr[1]); \
626 fprintf(stderr,"%08x %08x ",edi.dr[2],edi.dr[3]); \
627 fprintf(stderr,"(%s)\n",#text); \
628 } while (0)
629 #else
630 #define SHOW_DR(text) do {} while (0)
631 #endif
632
633 /* Insert a watchpoint. */
634
635 int
636 go32_insert_watchpoint (int pid, CORE_ADDR addr, int len, int rw)
637 {
638 int ret = go32_insert_aligned_watchpoint (pid, addr, addr, len, rw);
639
640 SHOW_DR (insert_watch);
641 return ret;
642 }
643
644 static int
645 go32_insert_aligned_watchpoint (int pid, CORE_ADDR waddr, CORE_ADDR addr,
646 int len, int rw)
647 {
648 int i;
649 int read_write_bits, len_bits;
650
651 /* Look for a free debug register. */
652 for (i = 0; i <= 3; i++)
653 {
654 if (IS_REG_FREE (i))
655 break;
656 }
657
658 /* No more debug registers! */
659 if (i > 3)
660 return -1;
661
662 read_write_bits = ((rw & 1) ? DR_RW_READ : 0) | ((rw & 2) ? DR_RW_WRITE : 0);
663
664 if (len == 1)
665 len_bits = DR_LEN_1;
666 else if (len == 2)
667 {
668 if (addr % 2)
669 return go32_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw);
670 len_bits = DR_LEN_2;
671 }
672 else if (len == 4)
673 {
674 if (addr % 4)
675 return go32_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw);
676 len_bits = DR_LEN_4;
677 }
678 else
679 return go32_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw);
680
681 SET_WATCH (i, addr, read_write_bits, len_bits);
682 LOCAL_ENABLE_REG (i);
683 SET_LOCAL_EXACT ();
684 }
685
686 static int
687 go32_insert_nonaligned_watchpoint (int pid, CORE_ADDR waddr, CORE_ADDR addr,
688 int len, int rw)
689 {
690 int align;
691 int size;
692 int rv = 0;
693
694 static int size_try_array[16] =
695 {
696 1, 1, 1, 1, /* trying size one */
697 2, 1, 2, 1, /* trying size two */
698 2, 1, 2, 1, /* trying size three */
699 4, 1, 2, 1 /* trying size four */
700 };
701
702 while (len > 0)
703 {
704 align = addr % 4;
705 /* Four is the maximum length for 386. */
706 size = (len > 4) ? 3 : len - 1;
707 size = size_try_array[size * 4 + align];
708 rv = go32_insert_aligned_watchpoint (pid, waddr, addr, size, rw);
709 if (rv)
710 {
711 go32_remove_watchpoint (pid, waddr, size);
712 return rv;
713 }
714 addr += size;
715 len -= size;
716 }
717 return rv;
718 }
719
720 /* Remove a watchpoint. */
721
722 int
723 go32_remove_watchpoint (int pid, CORE_ADDR addr, int len)
724 {
725 int i;
726
727 for (i = 0; i <= 3; i++)
728 {
729 if (D_REGS[i] == addr)
730 {
731 DISABLE_REG (i);
732 }
733 }
734 SHOW_DR (remove_watch);
735
736 return 0;
737 }
738
739 /* Check if stopped by a watchpoint. */
740
741 CORE_ADDR
742 go32_stopped_by_watchpoint (int pid)
743 {
744 int i, ret = 0;
745 int status;
746
747 status = edi.dr[DR_STATUS];
748 SHOW_DR (stopped_by);
749 for (i = 0; i <= 3; i++)
750 {
751 if (WATCH_HIT (i))
752 {
753 SHOW_DR (HIT);
754 ret = D_REGS[i];
755 }
756 }
757 /* this is a hack to GDB. If we stopped at a hardware breakpoint,
758 the stop_pc must incremented by DECR_PC_AFTER_BREAK. I tried everything
759 with the DECR_PC_AFTER_HW_BREAK, but nothing works. */
760 /* This is probably fixed by jtc's recent patch -sts 2/19/99 */
761 if (STATUS && !ret)
762 stop_pc += DECR_PC_AFTER_BREAK;
763 STATUS = 0;
764
765 return ret;
766 }
767
768 /* Remove a breakpoint. */
769
770 int
771 go32_remove_hw_breakpoint (CORE_ADDR addr, CORE_ADDR shadow)
772 {
773 int i;
774 for (i = 0; i <= 3; i++)
775 {
776 if (D_REGS[i] == addr)
777 {
778 DISABLE_REG (i);
779 }
780 }
781 SHOW_DR (remove_hw);
782 return 0;
783 }
784
785 int
786 go32_insert_hw_breakpoint (CORE_ADDR addr, CORE_ADDR shadow)
787 {
788 int i;
789 int read_write_bits, len_bits;
790 int free_debug_register;
791 int register_number;
792
793 /* Look for a free debug register. */
794 for (i = 0; i <= 3; i++)
795 {
796 if (IS_REG_FREE (i))
797 break;
798 }
799
800 /* No more debug registers! */
801 if (i > 3)
802 return -1;
803
804 SET_BREAK (i, addr);
805 LOCAL_ENABLE_REG (i);
806 SHOW_DR (insert_hw);
807
808 return 0;
809 }
810
811 static int inf_flags_valid = 0;
812 static int inf_in_flag;
813 static int inf_out_flag;
814
815 static void
816 go32_terminal_init (void)
817 {
818 /* Save the filemodes for stdin/stout */
819 inf_in_flag = setmode (0, 0);
820 setmode (0, inf_in_flag);
821 inf_out_flag = setmode (1, 0);
822 setmode (1, inf_out_flag);
823 inf_flags_valid = 1;
824 }
825
826 static void
827 go32_terminal_inferior (void)
828 {
829 /* set the filemodes for stdin/stdout of the inferior */
830 if (inf_flags_valid)
831 {
832 setmode (0, inf_in_flag);
833 setmode (1, inf_out_flag);
834 }
835 }
836
837 static void
838 go32_terminal_ours (void)
839 {
840 /* Switch to text mode on stdin/stdout always on the gdb terminal and
841 save the inferior modes to be restored later */
842 inf_in_flag = setmode (0, O_TEXT);
843 inf_out_flag = setmode (1, O_TEXT);
844 }
845
846 static void
847 init_go32_ops (void)
848 {
849 go32_ops.to_shortname = "djgpp";
850 go32_ops.to_longname = "djgpp target process";
851 go32_ops.to_doc =
852 "Program loaded by djgpp, when gdb is used as an external debugger";
853 go32_ops.to_open = go32_open;
854 go32_ops.to_close = go32_close;
855 go32_ops.to_detach = go32_detach;
856 go32_ops.to_resume = go32_resume;
857 go32_ops.to_wait = go32_wait;
858 go32_ops.to_fetch_registers = go32_fetch_registers;
859 go32_ops.to_store_registers = go32_store_registers;
860 go32_ops.to_prepare_to_store = go32_prepare_to_store;
861 go32_ops.to_xfer_memory = go32_xfer_memory;
862 go32_ops.to_files_info = go32_files_info;
863 go32_ops.to_insert_breakpoint = memory_insert_breakpoint;
864 go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
865 go32_ops.to_terminal_init = go32_terminal_init;
866 go32_ops.to_terminal_inferior = go32_terminal_inferior;
867 go32_ops.to_terminal_ours_for_output = ignore;
868 go32_ops.to_terminal_ours = go32_terminal_ours;
869 go32_ops.to_terminal_info = ignore2;
870 go32_ops.to_kill = go32_kill_inferior;
871 go32_ops.to_create_inferior = go32_create_inferior;
872 go32_ops.to_mourn_inferior = go32_mourn_inferior;
873 go32_ops.to_can_run = go32_can_run;
874 go32_ops.to_stop = go32_stop;
875 go32_ops.to_stratum = process_stratum;
876 go32_ops.to_has_all_memory = 1;
877 go32_ops.to_has_memory = 1;
878 go32_ops.to_has_stack = 1;
879 go32_ops.to_has_registers = 1;
880 go32_ops.to_has_execution = 1;
881 go32_ops.to_magic = OPS_MAGIC;
882 }
883
884 void
885 _initialize_go32_nat (void)
886 {
887 init_go32_ops ();
888 add_target (&go32_ops);
889 }