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