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