]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/go32-nat.c
import gdb-1999-07-07 post reformat
[thirdparty/binutils-gdb.git] / gdb / go32-nat.c
CommitLineData
e49d4fa6
SS
1/* Native debugging support for Intel x86 running DJGPP.
2 Copyright 1997, 1999 Free Software Foundation, Inc.
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"
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
c5aa993b 33#include <stdio.h> /* required for __DJGPP_MINOR__ */
e49d4fa6
SS
34#include <stdlib.h>
35#include <string.h>
36#include <unistd.h>
37#include <debug/v2load.h>
38#include <debug/dbgcom.h>
39
b83266a0
SS
40#if __DJGPP_MINOR__ < 3
41/* This code will be provided from DJGPP 2.03 on. Until then I code it
42 here */
c5aa993b
JM
43typedef 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 }
52NPXREG;
53
54typedef 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 }
65NPX;
b83266a0
SS
66
67static NPX npx;
68
c5aa993b
JM
69static void save_npx (void); /* Save the FPU of the debugged program */
70static void load_npx (void); /* Restore the FPU of the debugged program */
b83266a0
SS
71
72/* ------------------------------------------------------------------------- */
73/* Store the contents of the NPX in the global variable `npx'. */
c5aa993b 74/* *INDENT-OFF* */
b83266a0
SS
75
76static void
77save_npx (void)
78{
79 asm ("inb $0xa0, %%al
c5aa993b
JM
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
b83266a0 871:
c5aa993b
JM
88 fnsave % 0
89 fwait "
90: "=m" (npx)
91: /* No input */
92: "%eax");
b83266a0 93}
c5aa993b
JM
94
95/* *INDENT-ON* */
96
97
98
99
100
b83266a0
SS
101/* ------------------------------------------------------------------------- */
102/* Reload the contents of the NPX from the global variable `npx'. */
103
104static void
105load_npx (void)
106{
c5aa993b 107asm ("frstor %0":"=m" (npx));
b83266a0
SS
108}
109#endif /* __DJGPP_MINOR < 3 */
110
e49d4fa6
SS
111extern void _initialize_go32_nat (void);
112
113struct env387
c5aa993b
JM
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 };
e49d4fa6
SS
129
130extern char **environ;
131
132#define SOME_PID 42
133
e49d4fa6 134static int prog_has_started = 0;
c5aa993b
JM
135static void print_387_status (unsigned short status, struct env387 *ep);
136static void go32_open (char *name, int from_tty);
137static void go32_close (int quitting);
138static void go32_attach (char *args, int from_tty);
139static void go32_detach (char *args, int from_tty);
140static void go32_resume (int pid, int step, enum target_signal siggnal);
141static int go32_wait (int pid, struct target_waitstatus *status);
142static void go32_fetch_registers (int regno);
143static void store_register (int regno);
144static void go32_store_registers (int regno);
145static void go32_prepare_to_store (void);
146static int go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
147 int write, struct target_ops *target);
148static void go32_files_info (struct target_ops *target);
149static void go32_stop (void);
150static void go32_kill_inferior (void);
151static void go32_create_inferior (char *exec_file, char *args, char **env);
152static void go32_mourn_inferior (void);
153static int go32_can_run (void);
154static void ignore (void);
155static void ignore2 (char *a, int b);
b83266a0 156static int go32_insert_aligned_watchpoint (int pid, CORE_ADDR waddr,
c5aa993b 157 CORE_ADDR addr, int len, int rw);
b83266a0 158static int go32_insert_nonaligned_watchpoint (int pid, CORE_ADDR waddr,
c5aa993b 159 CORE_ADDR addr, int len, int rw);
b83266a0
SS
160
161static struct target_ops go32_ops;
c5aa993b
JM
162static void go32_terminal_init (void);
163static void go32_terminal_inferior (void);
164static void go32_terminal_ours (void);
e49d4fa6
SS
165
166static void
167print_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
231void
232i386_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
239static struct
240{
241 int tss_ofs;
242 int size;
243}
244regno_mapping[] =
245{
246 r_ofs (tss_eax), 4,
c5aa993b
JM
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
e49d4fa6
SS
277};
278
279static struct
280 {
281 int go32_sig;
282 int gdb_sig;
283 }
284sig_map[] =
285{
286 0, TARGET_SIGNAL_FPE,
c5aa993b
JM
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
e49d4fa6
SS
307};
308
309static void
310go32_open (char *name, int from_tty)
311{
312 printf_unfiltered ("Use the `run' command to run go32 programs\n");
313}
314
315static void
316go32_close (int quitting)
317{
318}
319
320static void
321go32_attach (char *args, int from_tty)
322{
323 printf_unfiltered ("Use the `run' command to run go32 programs\n");
324}
325
326static void
327go32_detach (char *args, int from_tty)
328{
329}
330
331static int resume_is_step;
332
333static void
334go32_resume (int pid, int step, enum target_signal siggnal)
c5aa993b
JM
335{
336 resume_is_step = step;
337}
e49d4fa6
SS
338
339static int
340go32_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
b83266a0
SS
349#if __DJGPP_MINOR__ < 3
350 save_npx ();
351#endif
e49d4fa6 352 run_child ();
b83266a0
SS
353#if __DJGPP_MINOR__ < 3
354 load_npx ();
355#endif
e49d4fa6
SS
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
380static void
381go32_fetch_registers (int regno)
382{
c5aa993b 383 /*JHW */
e49d4fa6
SS
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
413static void
414store_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
433static void
434go32_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
447static void
448go32_prepare_to_store (void)
449{
450}
451
452static int
453go32_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
480static void
481go32_files_info (struct target_ops *target)
482{
483 printf_unfiltered ("You are running a DJGPP V2 program\n");
484}
485
486static void
487go32_stop (void)
488{
489 normal_stop ();
490 cleanup_client ();
491 inferior_pid = 0;
492 prog_has_started = 0;
493}
494
495static void
496go32_kill_inferior (void)
497{
e49d4fa6
SS
498 unpush_target (&go32_ops);
499}
500
501static void
502go32_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 {
b83266a0 510 go32_stop ();
e49d4fa6
SS
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);
b83266a0 536 prog_has_started = 1;
e49d4fa6
SS
537}
538
539static void
540go32_mourn_inferior (void)
541{
542 go32_kill_inferior ();
543 generic_mourn_inferior ();
544}
545
546static int
547go32_can_run (void)
548{
549 return 1;
550}
551
552static void
553ignore (void)
554{
555}
556
557static void
558ignore2 (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
c5aa993b 621#if 0 /* use debugging macro */
e49d4fa6
SS
622#define SHOW_DR(text) \
623do { \
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
e49d4fa6
SS
633/* Insert a watchpoint. */
634
635int
636go32_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
644static int
645go32_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
686static int
687go32_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
722int
723go32_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
741CORE_ADDR
742go32_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
770int
771go32_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
785int
786go32_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
cce74817
JM
811static int inf_flags_valid = 0;
812static int inf_in_flag;
813static int inf_out_flag;
814
815static void
816go32_terminal_init (void)
817{
818 /* Save the filemodes for stdin/stout */
c5aa993b
JM
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);
cce74817
JM
823 inf_flags_valid = 1;
824}
825
826static void
827go32_terminal_inferior (void)
828{
829 /* set the filemodes for stdin/stdout of the inferior */
830 if (inf_flags_valid)
c5aa993b
JM
831 {
832 setmode (0, inf_in_flag);
833 setmode (1, inf_out_flag);
834 }
cce74817
JM
835}
836
837static void
838go32_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 */
c5aa993b
JM
842 inf_in_flag = setmode (0, O_TEXT);
843 inf_out_flag = setmode (1, O_TEXT);
cce74817
JM
844}
845
e49d4fa6
SS
846static void
847init_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;
cce74817
JM
865 go32_ops.to_terminal_init = go32_terminal_init;
866 go32_ops.to_terminal_inferior = go32_terminal_inferior;
e49d4fa6 867 go32_ops.to_terminal_ours_for_output = ignore;
cce74817 868 go32_ops.to_terminal_ours = go32_terminal_ours;
e49d4fa6
SS
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
884void
885_initialize_go32_nat (void)
886{
887 init_go32_ops ();
888 add_target (&go32_ops);
889}