Fix minor bug in last change.
[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
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>
53a5351d 36#include <errno.h>
e49d4fa6 37#include <unistd.h>
53a5351d
JM
38#include <io.h>
39#include <dpmi.h>
e49d4fa6
SS
40#include <debug/v2load.h>
41#include <debug/dbgcom.h>
53a5351d
JM
42#if __DJGPP_MINOR__ > 2
43#include <debug/redir.h>
44#endif
e49d4fa6 45
b83266a0
SS
46#if __DJGPP_MINOR__ < 3
47/* This code will be provided from DJGPP 2.03 on. Until then I code it
48 here */
c5aa993b
JM
49typedef struct
50 {
51 unsigned short sig0;
52 unsigned short sig1;
53 unsigned short sig2;
54 unsigned short sig3;
55 unsigned short exponent:15;
56 unsigned short sign:1;
57 }
58NPXREG;
59
60typedef struct
61 {
62 unsigned int control;
63 unsigned int status;
64 unsigned int tag;
65 unsigned int eip;
66 unsigned int cs;
67 unsigned int dataptr;
68 unsigned int datasel;
69 NPXREG reg[8];
70 }
71NPX;
b83266a0
SS
72
73static NPX npx;
74
c5aa993b
JM
75static void save_npx (void); /* Save the FPU of the debugged program */
76static void load_npx (void); /* Restore the FPU of the debugged program */
b83266a0
SS
77
78/* ------------------------------------------------------------------------- */
79/* Store the contents of the NPX in the global variable `npx'. */
c5aa993b 80/* *INDENT-OFF* */
b83266a0
SS
81
82static void
83save_npx (void)
84{
85 asm ("inb $0xa0, %%al
c5aa993b
JM
86 testb $0x20, %%al
87 jz 1f
88 xorb %% al, %%al
89 outb %% al, $0xf0
90 movb $0x20, %%al
91 outb %% al, $0xa0
92 outb %% al, $0x20
b83266a0 931:
c5aa993b
JM
94 fnsave % 0
95 fwait "
96: "=m" (npx)
97: /* No input */
98: "%eax");
b83266a0 99}
c5aa993b
JM
100
101/* *INDENT-ON* */
102
103
104
105
106
b83266a0
SS
107/* ------------------------------------------------------------------------- */
108/* Reload the contents of the NPX from the global variable `npx'. */
109
110static void
111load_npx (void)
112{
c5aa993b 113asm ("frstor %0":"=m" (npx));
b83266a0 114}
53a5351d
JM
115/* ------------------------------------------------------------------------- */
116/* Stubs for the missing redirection functions. */
117typedef struct {
118 char *command;
119 int redirected;
120} cmdline_t;
121
122void redir_cmdline_delete (cmdline_t *ptr) {ptr->redirected = 0;}
123int redir_cmdline_parse (const char *args, cmdline_t *ptr)
124{
125 return -1;
126}
127int redir_to_child (cmdline_t *ptr)
128{
129 return 1;
130}
131int redir_to_debugger (cmdline_t *ptr)
132{
133 return 1;
134}
135int redir_debug_init (cmdline_t *ptr) { return 0; }
b83266a0
SS
136#endif /* __DJGPP_MINOR < 3 */
137
e49d4fa6
SS
138extern void _initialize_go32_nat (void);
139
140struct env387
c5aa993b
JM
141 {
142 unsigned short control;
143 unsigned short r0;
144 unsigned short status;
145 unsigned short r1;
146 unsigned short tag;
147 unsigned short r2;
148 unsigned long eip;
149 unsigned short code_seg;
150 unsigned short opcode;
151 unsigned long operand;
152 unsigned short operand_seg;
153 unsigned short r3;
154 unsigned char regs[8][10];
155 };
e49d4fa6 156
53a5351d
JM
157typedef enum { wp_insert, wp_remove, wp_count } wp_op;
158
159/* This holds the current reference counts for each debug register. */
160static int dr_ref_count[4];
161
e49d4fa6
SS
162extern char **environ;
163
164#define SOME_PID 42
165
e49d4fa6 166static int prog_has_started = 0;
c5aa993b
JM
167static void print_387_status (unsigned short status, struct env387 *ep);
168static void go32_open (char *name, int from_tty);
169static void go32_close (int quitting);
170static void go32_attach (char *args, int from_tty);
171static void go32_detach (char *args, int from_tty);
172static void go32_resume (int pid, int step, enum target_signal siggnal);
173static int go32_wait (int pid, struct target_waitstatus *status);
174static void go32_fetch_registers (int regno);
175static void store_register (int regno);
176static void go32_store_registers (int regno);
177static void go32_prepare_to_store (void);
178static int go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
179 int write, struct target_ops *target);
180static void go32_files_info (struct target_ops *target);
181static void go32_stop (void);
182static void go32_kill_inferior (void);
183static void go32_create_inferior (char *exec_file, char *args, char **env);
53a5351d 184static void cleanup_dregs (void);
c5aa993b
JM
185static void go32_mourn_inferior (void);
186static int go32_can_run (void);
187static void ignore (void);
188static void ignore2 (char *a, int b);
53a5351d
JM
189static int go32_insert_aligned_watchpoint (CORE_ADDR waddr, CORE_ADDR addr,
190 int len, int rw);
191static int go32_remove_aligned_watchpoint (CORE_ADDR waddr, CORE_ADDR addr,
192 int len, int rw);
193static int go32_handle_nonaligned_watchpoint (wp_op what, CORE_ADDR waddr,
194 CORE_ADDR addr, int len, int rw);
b83266a0
SS
195
196static struct target_ops go32_ops;
c5aa993b
JM
197static void go32_terminal_init (void);
198static void go32_terminal_inferior (void);
199static void go32_terminal_ours (void);
e49d4fa6
SS
200
201static void
202print_387_status (unsigned short status, struct env387 *ep)
203{
204 int i;
205 int bothstatus;
206 int top;
207 int fpreg;
208
209 bothstatus = ((status != 0) && (ep->status != 0));
210 if (status != 0)
211 {
212 if (bothstatus)
213 printf_unfiltered ("u: ");
214 print_387_status_word (status);
215 }
216
217 if (ep->status != 0)
218 {
219 if (bothstatus)
220 printf_unfiltered ("e: ");
221 print_387_status_word (ep->status);
222 }
223
224 print_387_control_word (ep->control & 0xffff);
53a5351d
JM
225 /* Other platforms say "last exception", but that's not true: the
226 FPU stores the last non-control instruction there. */
227 printf_unfiltered ("last FP instruction: ");
228 /* The ORing with D800h restores the upper 5 bits of the opcode that
229 are not stored by the FPU (since these bits are the same for all
230 floating-point instructions). */
231 printf_unfiltered ("opcode %s; ",
232 local_hex_string (ep->opcode ? (ep->opcode|0xd800) : 0));
e49d4fa6
SS
233 printf_unfiltered ("pc %s:", local_hex_string (ep->code_seg));
234 printf_unfiltered ("%s; ", local_hex_string (ep->eip));
235 printf_unfiltered ("operand %s", local_hex_string (ep->operand_seg));
236 printf_unfiltered (":%s\n", local_hex_string (ep->operand));
237
238 top = (ep->status >> 11) & 7;
239
53a5351d
JM
240 printf_unfiltered ("regno tag msb lsb value\n");
241 for (fpreg = 7; fpreg >= 0; fpreg--)
e49d4fa6 242 {
53a5351d
JM
243 /* FNSAVE saves the FP registers in their logical TOP-relative
244 order, beginning with ST(0). Since we need to print them in
245 their physical order, we have to remap them. */
246 int regno = fpreg - top;
e49d4fa6
SS
247 long double val;
248
53a5351d
JM
249 if (regno < 0)
250 regno += 8;
251
e49d4fa6
SS
252 printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : " ", fpreg);
253
254 switch ((ep->tag >> (fpreg * 2)) & 3)
255 {
256 case 0:
53a5351d 257 printf_unfiltered ("valid ");
e49d4fa6
SS
258 break;
259 case 1:
53a5351d 260 printf_unfiltered ("zero ");
e49d4fa6
SS
261 break;
262 case 2:
53a5351d
JM
263 /* All other versions of print_387_status use TRAP here, but I
264 think this is misleading, since Intel manuals say SPECIAL. */
265 printf_unfiltered ("special ");
e49d4fa6
SS
266 break;
267 case 3:
53a5351d 268 printf_unfiltered ("empty ");
e49d4fa6
SS
269 break;
270 }
53a5351d
JM
271 for (i = 9; i >= 0; i--)
272 printf_unfiltered ("%02x", ep->regs[regno][i]);
e49d4fa6 273
53a5351d
JM
274 REGISTER_CONVERT_TO_VIRTUAL (FP0_REGNUM+regno, builtin_type_long_double,
275 &ep->regs[regno], &val);
e49d4fa6 276
53a5351d 277 printf_unfiltered (" %.19LG\n", val);
e49d4fa6
SS
278 }
279}
280
281void
282i386_go32_float_info (void)
283{
284 print_387_status (0, (struct env387 *) &npx);
285}
286
53a5351d 287#define r_ofs(x) (offsetof(TSS,x))
e49d4fa6
SS
288
289static struct
290{
53a5351d
JM
291 size_t tss_ofs;
292 size_t size;
e49d4fa6
SS
293}
294regno_mapping[] =
295{
53a5351d 296 r_ofs (tss_eax), 4, /* normal registers, from a_tss */
c5aa993b
JM
297 r_ofs (tss_ecx), 4,
298 r_ofs (tss_edx), 4,
299 r_ofs (tss_ebx), 4,
300 r_ofs (tss_esp), 4,
301 r_ofs (tss_ebp), 4,
302 r_ofs (tss_esi), 4,
303 r_ofs (tss_edi), 4,
304 r_ofs (tss_eip), 4,
305 r_ofs (tss_eflags), 4,
306 r_ofs (tss_cs), 2,
307 r_ofs (tss_ss), 2,
308 r_ofs (tss_ds), 2,
309 r_ofs (tss_es), 2,
310 r_ofs (tss_fs), 2,
311 r_ofs (tss_gs), 2,
53a5351d 312 0, 10, /* 8 FP registers, from npx.reg[] */
c5aa993b
JM
313 1, 10,
314 2, 10,
315 3, 10,
316 4, 10,
317 5, 10,
318 6, 10,
319 7, 10,
53a5351d
JM
320 /* The order of the next 7 registers must be consistent
321 with their numbering in config/i386/tm-go32.h, which see. */
322 0, 2, /* control word, from npx */
323 4, 2, /* status word, from npx */
324 8, 2, /* tag word, from npx */
325 16, 2, /* last FP exception CS from npx */
326 24, 2, /* last FP exception operand selector from npx */
327 12, 4, /* last FP exception EIP from npx */
328 20, 4 /* last FP exception operand offset from npx */
e49d4fa6
SS
329};
330
331static struct
332 {
333 int go32_sig;
334 int gdb_sig;
335 }
336sig_map[] =
337{
338 0, TARGET_SIGNAL_FPE,
c5aa993b 339 1, TARGET_SIGNAL_TRAP,
53a5351d
JM
340 /* Exception 2 is triggered by the NMI. DJGPP handles it as SIGILL,
341 but I think SIGBUS is better, since the NMI is usually activated
342 as a result of a memory parity check failure. */
343 2, TARGET_SIGNAL_BUS,
c5aa993b
JM
344 3, TARGET_SIGNAL_TRAP,
345 4, TARGET_SIGNAL_FPE,
346 5, TARGET_SIGNAL_SEGV,
347 6, TARGET_SIGNAL_ILL,
348 7, TARGET_SIGNAL_FPE,
349 8, TARGET_SIGNAL_SEGV,
350 9, TARGET_SIGNAL_SEGV,
351 10, TARGET_SIGNAL_BUS,
352 11, TARGET_SIGNAL_SEGV,
353 12, TARGET_SIGNAL_SEGV,
53a5351d 354 13, TARGET_SIGNAL_SEGV,
c5aa993b
JM
355 14, TARGET_SIGNAL_SEGV,
356 16, TARGET_SIGNAL_FPE,
53a5351d 357 17, TARGET_SIGNAL_BUS,
c5aa993b 358 31, TARGET_SIGNAL_ILL,
53a5351d 359 0x1b, TARGET_SIGNAL_INT,
c5aa993b 360 0x75, TARGET_SIGNAL_FPE,
53a5351d 361 0x78, TARGET_SIGNAL_ALRM,
c5aa993b 362 0x79, TARGET_SIGNAL_INT,
53a5351d 363 0x7a, TARGET_SIGNAL_QUIT,
c5aa993b 364 -1, -1
e49d4fa6
SS
365};
366
53a5351d
JM
367static struct {
368 enum target_signal gdb_sig;
369 int djgpp_excepno;
370} excepn_map[] = {
371 TARGET_SIGNAL_0, -1,
372 TARGET_SIGNAL_ILL, 6, /* Invalid Opcode */
373 TARGET_SIGNAL_EMT, 7, /* triggers SIGNOFP */
374 TARGET_SIGNAL_SEGV, 13, /* GPF */
375 TARGET_SIGNAL_BUS, 17, /* Alignment Check */
376 /* The rest are fake exceptions, see dpmiexcp.c in djlsr*.zip for
377 details. */
378 TARGET_SIGNAL_TERM, 0x1b, /* triggers Ctrl-Break type of SIGINT */
379 TARGET_SIGNAL_FPE, 0x75,
380 TARGET_SIGNAL_INT, 0x79,
381 TARGET_SIGNAL_QUIT, 0x7a,
382 TARGET_SIGNAL_ALRM, 0x78, /* triggers SIGTIMR */
383 TARGET_SIGNAL_PROF, 0x78,
384 -1, -1
385};
386
e49d4fa6
SS
387static void
388go32_open (char *name, int from_tty)
389{
53a5351d 390 printf_unfiltered ("Done. Use the \"run\" command to run the program.\n");
e49d4fa6
SS
391}
392
393static void
394go32_close (int quitting)
395{
396}
397
398static void
399go32_attach (char *args, int from_tty)
400{
53a5351d
JM
401 error ("\
402You cannot attach to a running program on this platform.\n\
403Use the `run' command to run DJGPP programs.");
e49d4fa6
SS
404}
405
406static void
407go32_detach (char *args, int from_tty)
408{
409}
410
411static int resume_is_step;
53a5351d 412static int resume_signal = -1;
e49d4fa6
SS
413
414static void
415go32_resume (int pid, int step, enum target_signal siggnal)
c5aa993b 416{
53a5351d
JM
417 int i;
418
c5aa993b 419 resume_is_step = step;
53a5351d
JM
420
421 if (siggnal != TARGET_SIGNAL_0 && siggnal != TARGET_SIGNAL_TRAP)
422 {
423 for (i = 0, resume_signal = -1; excepn_map[i].gdb_sig != -1; i++)
424 if (excepn_map[i].gdb_sig == siggnal)
425 {
426 resume_signal = excepn_map[i].djgpp_excepno;
427 break;
428 }
429 if (resume_signal == -1)
430 printf_unfiltered ("Cannot deliver signal %s on this platform.\n",
431 target_signal_to_name (siggnal));
432 }
c5aa993b 433}
e49d4fa6 434
53a5351d
JM
435static char child_cwd[FILENAME_MAX];
436
e49d4fa6
SS
437static int
438go32_wait (int pid, struct target_waitstatus *status)
439{
440 int i;
53a5351d
JM
441 unsigned char saved_opcode;
442 unsigned long INT3_addr;
443 int stepping_over_INT = 0;
e49d4fa6 444
53a5351d 445 a_tss.tss_eflags &= 0xfeff; /* reset the single-step flag (TF) */
e49d4fa6 446 if (resume_is_step)
53a5351d
JM
447 {
448 /* If the next instruction is INT xx or INTO, we need to handle
449 them specially. Intel manuals say that these instructions
450 reset the single-step flag (a.k.a. TF). However, it seems
451 that, at least in the DPMI environment, and at least when
452 stepping over the DPMI interrupt 31h, the problem is having
453 TF set at all when INT 31h is executed: the debuggee either
454 crashes (and takes the system with it) or is killed by a
455 SIGTRAP.
456
457 So we need to emulate single-step mode: we put an INT3 opcode
458 right after the INT xx instruction, let the debuggee run
459 until it hits INT3 and stops, then restore the original
460 instruction which we overwrote with the INT3 opcode, and back
461 up the debuggee's EIP to that instruction. */
462 read_child (a_tss.tss_eip, &saved_opcode, 1);
463 if (saved_opcode == 0xCD || saved_opcode == 0xCE)
464 {
465 unsigned char INT3_opcode = 0xCC;
466
467 INT3_addr
468 = saved_opcode == 0xCD ? a_tss.tss_eip + 2 : a_tss.tss_eip + 1;
469 stepping_over_INT = 1;
470 read_child (INT3_addr, &saved_opcode, 1);
471 write_child (INT3_addr, &INT3_opcode, 1);
472 }
473 else
474 a_tss.tss_eflags |= 0x0100; /* normal instruction: set TF */
475 }
476
477 /* The special value FFFFh in tss_trap indicates to run_child that
478 tss_irqn holds a signal to be delivered to the debuggee. */
479 if (resume_signal <= -1)
480 {
481 a_tss.tss_trap = 0;
482 a_tss.tss_irqn = 0xff;
483 }
e49d4fa6 484 else
53a5351d
JM
485 {
486 a_tss.tss_trap = 0xffff; /* run_child looks for this */
487 a_tss.tss_irqn = resume_signal;
488 }
489
490 /* The child might change working directory behind our back. The
491 GDB users won't like the side effects of that when they work with
492 relative file names, and GDB might be confused by its current
493 directory not being in sync with the truth. So we always make a
494 point of changing back to where GDB thinks is its cwd, when we
495 return control to the debugger, but restore child's cwd before we
496 run it. */
497 chdir (child_cwd);
e49d4fa6 498
b83266a0 499#if __DJGPP_MINOR__ < 3
53a5351d 500 load_npx ();
b83266a0 501#endif
e49d4fa6 502 run_child ();
b83266a0 503#if __DJGPP_MINOR__ < 3
53a5351d 504 save_npx ();
b83266a0 505#endif
e49d4fa6 506
53a5351d
JM
507 /* Did we step over an INT xx instruction? */
508 if (stepping_over_INT && a_tss.tss_eip == INT3_addr + 1)
509 {
510 /* Restore the original opcode. */
511 a_tss.tss_eip--; /* EIP points *after* the INT3 instruction */
512 write_child (a_tss.tss_eip, &saved_opcode, 1);
513 /* Simulate a TRAP exception. */
514 a_tss.tss_irqn = 1;
515 a_tss.tss_eflags |= 0x0100;
516 }
517
518 getcwd (child_cwd, sizeof (child_cwd)); /* in case it has changed */
519 chdir (current_directory);
520
e49d4fa6
SS
521 if (a_tss.tss_irqn == 0x21)
522 {
523 status->kind = TARGET_WAITKIND_EXITED;
524 status->value.integer = a_tss.tss_eax & 0xff;
525 }
526 else
527 {
528 status->value.sig = TARGET_SIGNAL_UNKNOWN;
529 status->kind = TARGET_WAITKIND_STOPPED;
530 for (i = 0; sig_map[i].go32_sig != -1; i++)
531 {
532 if (a_tss.tss_irqn == sig_map[i].go32_sig)
533 {
53a5351d 534#if __DJGPP_MINOR__ < 3
e49d4fa6
SS
535 if ((status->value.sig = sig_map[i].gdb_sig) !=
536 TARGET_SIGNAL_TRAP)
537 status->kind = TARGET_WAITKIND_SIGNALLED;
53a5351d
JM
538#else
539 status->value.sig = sig_map[i].gdb_sig;
540#endif
e49d4fa6
SS
541 break;
542 }
543 }
544 }
545 return SOME_PID;
546}
547
548static void
549go32_fetch_registers (int regno)
550{
c5aa993b 551 /*JHW */
e49d4fa6
SS
552 int end_reg = regno + 1; /* just one reg initially */
553
554 if (regno < 0) /* do the all registers */
555 {
556 regno = 0; /* start at first register */
557 /* # regs in table */
558 end_reg = sizeof (regno_mapping) / sizeof (regno_mapping[0]);
559 }
560
561 for (; regno < end_reg; regno++)
562 {
563 if (regno < 16)
564 supply_register (regno,
565 (char *) &a_tss + regno_mapping[regno].tss_ofs);
566 else if (regno < 24)
567 supply_register (regno,
568 (char *) &npx.reg[regno_mapping[regno].tss_ofs]);
569 else if (regno < 31)
570 supply_register (regno,
53a5351d 571 (char *) &npx + regno_mapping[regno].tss_ofs);
e49d4fa6 572 else
53a5351d 573 fatal ("Invalid register no. %d in go32_fetch_register.", regno);
e49d4fa6
SS
574 }
575}
576
577static void
578store_register (int regno)
579{
580 void *rp;
581 void *v = (void *) &registers[REGISTER_BYTE (regno)];
582
583 if (regno < 16)
584 rp = (char *) &a_tss + regno_mapping[regno].tss_ofs;
585 else if (regno < 24)
586 rp = (char *) &npx.reg[regno_mapping[regno].tss_ofs];
53a5351d 587 else if (regno < 31)
e49d4fa6
SS
588 rp = (char *) &npx + regno_mapping[regno].tss_ofs;
589 else
53a5351d 590 fatal ("Invalid register no. %d in store_register.", regno);
e49d4fa6
SS
591 memcpy (rp, v, regno_mapping[regno].size);
592}
593
594static void
595go32_store_registers (int regno)
596{
597 int r;
598
599 if (regno >= 0)
600 store_register (regno);
601 else
602 {
603 for (r = 0; r < sizeof (regno_mapping) / sizeof (regno_mapping[0]); r++)
604 store_register (r);
605 }
606}
607
608static void
609go32_prepare_to_store (void)
610{
611}
612
613static int
614go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
615 struct target_ops *target)
616{
617 if (write)
618 {
619 if (write_child (memaddr, myaddr, len))
620 {
621 return 0;
622 }
623 else
624 {
625 return len;
626 }
627 }
628 else
629 {
630 if (read_child (memaddr, myaddr, len))
631 {
632 return 0;
633 }
634 else
635 {
636 return len;
637 }
638 }
639}
640
53a5351d
JM
641static cmdline_t child_cmd; /* parsed child's command line kept here */
642
e49d4fa6
SS
643static void
644go32_files_info (struct target_ops *target)
645{
53a5351d 646 printf_unfiltered ("You are running a DJGPP V2 program.\n");
e49d4fa6
SS
647}
648
649static void
650go32_stop (void)
651{
652 normal_stop ();
653 cleanup_client ();
654 inferior_pid = 0;
655 prog_has_started = 0;
656}
657
658static void
659go32_kill_inferior (void)
660{
53a5351d
JM
661 redir_cmdline_delete (&child_cmd);
662 resume_signal = -1;
663 resume_is_step = 0;
e49d4fa6
SS
664 unpush_target (&go32_ops);
665}
666
667static void
668go32_create_inferior (char *exec_file, char *args, char **env)
669{
670 jmp_buf start_state;
671 char *cmdline;
672 char **env_save = environ;
673
674 if (prog_has_started)
675 {
b83266a0 676 go32_stop ();
e49d4fa6
SS
677 go32_kill_inferior ();
678 }
53a5351d
JM
679 resume_signal = -1;
680 resume_is_step = 0;
681 /* Init command line storage. */
682 if (redir_debug_init (&child_cmd) == -1)
683 fatal ("Cannot allocate redirection storage: not enough memory.\n");
684
685 /* Parse the command line and create redirections. */
686 if (strpbrk (args, "<>"))
687 {
688 if (redir_cmdline_parse (args, &child_cmd) == 0)
689 args = child_cmd.command;
690 else
691 error ("Syntax error in command line.");
692 }
693 else
694 child_cmd.command = strdup (args);
e49d4fa6
SS
695
696 cmdline = (char *) alloca (strlen (args) + 4);
697 cmdline[0] = strlen (args);
698 strcpy (cmdline + 1, args);
699 cmdline[strlen (args) + 1] = 13;
700
701 environ = env;
702
703 if (v2loadimage (exec_file, cmdline, start_state))
704 {
705 environ = env_save;
706 printf_unfiltered ("Load failed for image %s\n", exec_file);
707 exit (1);
708 }
709 environ = env_save;
710
711 edi_init (start_state);
53a5351d
JM
712#if __DJGPP_MINOR__ < 3
713 save_npx ();
714#endif
e49d4fa6
SS
715
716 inferior_pid = SOME_PID;
717 push_target (&go32_ops);
718 clear_proceed_status ();
719 insert_breakpoints ();
720 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
b83266a0 721 prog_has_started = 1;
e49d4fa6
SS
722}
723
724static void
725go32_mourn_inferior (void)
726{
53a5351d
JM
727 /* We need to make sure all the breakpoint enable bits in the DR7
728 register are reset when the inferior exits. Otherwise, if they
729 rerun the inferior, the uncleared bits may cause random SIGTRAPs,
730 failure to set more watchpoints, and other calamities. It would
731 be nice if GDB itself would take care to remove all breakpoints
732 at all times, but it doesn't, probably under an assumption that
733 the OS cleans up when the debuggee exits. */
734 cleanup_dregs ();
e49d4fa6
SS
735 go32_kill_inferior ();
736 generic_mourn_inferior ();
737}
738
739static int
740go32_can_run (void)
741{
742 return 1;
743}
744
745static void
746ignore (void)
747{
748}
749
e49d4fa6
SS
750/* Hardware watchpoint support. */
751
752#define DR_STATUS 6
753#define DR_CONTROL 7
754#define DR_ENABLE_SIZE 2
755#define DR_LOCAL_ENABLE_SHIFT 0
756#define DR_GLOBAL_ENABLE_SHIFT 1
757#define DR_LOCAL_SLOWDOWN 0x100
758#define DR_GLOBAL_SLOWDOWN 0x200
759#define DR_CONTROL_SHIFT 16
760#define DR_CONTROL_SIZE 4
53a5351d 761#define DR_RW_READWRITE 0x3
e49d4fa6
SS
762#define DR_RW_WRITE 0x1
763#define DR_CONTROL_MASK 0xf
764#define DR_ENABLE_MASK 0x3
765#define DR_LEN_1 0x0
766#define DR_LEN_2 0x4
767#define DR_LEN_4 0xc
768
769#define D_REGS edi.dr
770#define CONTROL D_REGS[DR_CONTROL]
771#define STATUS D_REGS[DR_STATUS]
772
773#define IS_REG_FREE(index) \
53a5351d 774 (!(CONTROL & (3 << (DR_ENABLE_SIZE * (index)))))
e49d4fa6
SS
775
776#define LOCAL_ENABLE_REG(index) \
53a5351d 777 (CONTROL |= (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (index))))
e49d4fa6
SS
778
779#define GLOBAL_ENABLE_REG(index) \
53a5351d 780 (CONTROL |= (1 << (DR_GLOBAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (index))))
e49d4fa6
SS
781
782#define DISABLE_REG(index) \
53a5351d 783 (CONTROL &= ~(3 << (DR_ENABLE_SIZE * (index))))
e49d4fa6
SS
784
785#define SET_LOCAL_EXACT() \
786 (CONTROL |= DR_LOCAL_SLOWDOWN)
787
788#define SET_GLOBAL_EXACT() \
789 (CONTROL |= DR_GLOBAL_SLOWDOWN)
790
53a5351d
JM
791#define RESET_LOCAL_EXACT() \
792 (CONTROL &= ~(DR_LOCAL_SLOWDOWN))
793
794#define RESET_GLOBAL_EXACT() \
795 (CONTROL &= ~(DR_GLOBAL_SLOWDOWN))
796
e49d4fa6
SS
797#define SET_BREAK(index,address) \
798 do {\
53a5351d 799 CONTROL &= ~(DR_CONTROL_MASK << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (index)));\
e49d4fa6
SS
800 D_REGS[index] = address;\
801 } while(0)
802
803#define SET_WATCH(index,address,rw,len) \
804 do {\
805 SET_BREAK(index,address);\
53a5351d 806 CONTROL |= ((len)|(rw)) << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (index));\
e49d4fa6
SS
807 } while (0)
808
53a5351d
JM
809#define IS_WATCH(index) \
810 (CONTROL & (DR_CONTROL_MASK << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE*(index))))
811
e49d4fa6
SS
812#define WATCH_HIT(index) \
813 (\
814 (STATUS & (1 << index)) && \
815 (CONTROL & (DR_CONTROL_MASK << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * index)))\
816 )
817
53a5351d
JM
818#define DR_DEF(index) \
819 ((CONTROL >> (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (index))) & 0x0f)
820
821
822#if 0 /* use debugging macro */
823#define SHOW_DR(text,len) \
e49d4fa6 824do { \
53a5351d 825 if (!getenv ("GDB_SHOW_DR")) break; \
e49d4fa6 826 fprintf(stderr,"%08x %08x ",edi.dr[7],edi.dr[6]); \
53a5351d
JM
827 fprintf(stderr,"%08x %d %08x %d ", \
828 edi.dr[0],dr_ref_count[0],edi.dr[1],dr_ref_count[1]); \
829 fprintf(stderr,"%08x %d %08x %d ", \
830 edi.dr[2],dr_ref_count[2],edi.dr[3],dr_ref_count[3]); \
831 fprintf(stderr,(len)?"(%s:%d)\n":"(%s)\n",#text,len); \
e49d4fa6
SS
832} while (0)
833#else
53a5351d 834#define SHOW_DR(text,len) do {} while (0)
e49d4fa6
SS
835#endif
836
53a5351d
JM
837static void
838cleanup_dregs (void)
839{
840 int i;
841
842 CONTROL = 0;
843 STATUS = 0;
844 for (i = 0; i < 4; i++)
845 {
846 D_REGS[i] = 0;
847 dr_ref_count[i] = 0;
848 }
849}
850
e49d4fa6
SS
851/* Insert a watchpoint. */
852
853int
854go32_insert_watchpoint (int pid, CORE_ADDR addr, int len, int rw)
855{
53a5351d 856 int ret = go32_insert_aligned_watchpoint (addr, addr, len, rw);
e49d4fa6 857
53a5351d 858 SHOW_DR (insert_watch, len);
e49d4fa6
SS
859 return ret;
860}
861
862static int
53a5351d 863go32_insert_aligned_watchpoint (CORE_ADDR waddr, CORE_ADDR addr,
e49d4fa6
SS
864 int len, int rw)
865{
866 int i;
867 int read_write_bits, len_bits;
868
53a5351d
JM
869 /* Values of rw: 0 - write, 1 - read, 2 - access (read and write).
870 However, x86 doesn't support read-only data breakpoints. */
871 read_write_bits = rw ? DR_RW_READWRITE : DR_RW_WRITE;
872
873 switch (len)
874 {
875 case 4:
876 len_bits = DR_LEN_4;
877 break;
878 case 2:
879 len_bits = DR_LEN_2;
880 break;
881 case 1:
882 len_bits = DR_LEN_1;
883 break;
884 default:
885 /* The debug registers only have 2 bits for the length, so
886 so this value will always fail the loop below. */
887 len_bits = 0x10;
888 }
889
890 /* Look for an occupied debug register with the same address and the
891 same RW and LEN definitions. If we find one, we can use it for
892 this watchpoint as well (and save a register). */
893 for (i = 0; i < 4; i++)
894 {
895 if (!IS_REG_FREE (i) && D_REGS[i] == addr
896 && DR_DEF (i) == (len_bits | read_write_bits))
e49d4fa6 897 {
53a5351d
JM
898 dr_ref_count[i]++;
899 return 0;
e49d4fa6 900 }
53a5351d
JM
901 }
902
903 /* Look for a free debug register. */
904 for (i = 0; i <= 3; i++)
905 {
906 if (IS_REG_FREE (i))
907 break;
908 }
e49d4fa6
SS
909
910 /* No more debug registers! */
911 if (i > 3)
912 return -1;
913
53a5351d
JM
914 if (len == 2)
915 {
916 if (addr % 2)
917 return go32_handle_nonaligned_watchpoint (wp_insert, waddr, addr,
918 len, rw);
919 }
e49d4fa6 920 else if (len == 4)
53a5351d
JM
921 {
922 if (addr % 4)
923 return go32_handle_nonaligned_watchpoint (wp_insert, waddr, addr,
924 len, rw);
925 }
926 else if (len != 1)
927 return go32_handle_nonaligned_watchpoint (wp_insert, waddr, addr, len, rw);
e49d4fa6
SS
928
929 SET_WATCH (i, addr, read_write_bits, len_bits);
930 LOCAL_ENABLE_REG (i);
931 SET_LOCAL_EXACT ();
53a5351d
JM
932 SET_GLOBAL_EXACT ();
933 return 0;
e49d4fa6
SS
934}
935
936static int
53a5351d 937go32_handle_nonaligned_watchpoint (wp_op what, CORE_ADDR waddr, CORE_ADDR addr,
e49d4fa6
SS
938 int len, int rw)
939{
940 int align;
941 int size;
53a5351d 942 int rv = 0, status = 0;
e49d4fa6
SS
943
944 static int size_try_array[16] =
945 {
946 1, 1, 1, 1, /* trying size one */
947 2, 1, 2, 1, /* trying size two */
948 2, 1, 2, 1, /* trying size three */
949 4, 1, 2, 1 /* trying size four */
950 };
951
952 while (len > 0)
953 {
954 align = addr % 4;
955 /* Four is the maximum length for 386. */
956 size = (len > 4) ? 3 : len - 1;
957 size = size_try_array[size * 4 + align];
53a5351d
JM
958 if (what == wp_insert)
959 status = go32_insert_aligned_watchpoint (waddr, addr, size, rw);
960 else if (what == wp_remove)
961 status = go32_remove_aligned_watchpoint (waddr, addr, size, rw);
962 else if (what == wp_count)
963 rv++;
964 else
965 status = -1;
966 /* We keep the loop going even after a failure, because some of
967 the other aligned watchpoints might still succeed, e.g. if
968 they watch addresses that are already watched, and thus just
969 increment the reference counts of occupied debug registers.
970 If we break out of the loop too early, we could cause those
971 addresses watched by other watchpoints to be disabled when
972 GDB reacts to our failure to insert this watchpoint and tries
973 to remove it. */
974 if (status)
975 rv = status;
e49d4fa6
SS
976 addr += size;
977 len -= size;
978 }
979 return rv;
980}
981
982/* Remove a watchpoint. */
983
984int
53a5351d
JM
985go32_remove_watchpoint (int pid, CORE_ADDR addr, int len, int rw)
986{
987 int ret = go32_remove_aligned_watchpoint (addr, addr, len, rw);
988
989 SHOW_DR (remove_watch, len);
990 return ret;
991}
992
993static int
994go32_remove_aligned_watchpoint (CORE_ADDR waddr, CORE_ADDR addr,
995 int len, int rw)
e49d4fa6
SS
996{
997 int i;
53a5351d
JM
998 int read_write_bits, len_bits;
999
1000 /* Values of rw: 0 - write, 1 - read, 2 - access (read and write).
1001 However, x86 doesn't support read-only data breakpoints. */
1002 read_write_bits = rw ? DR_RW_READWRITE : DR_RW_WRITE;
1003
1004 switch (len)
1005 {
1006 case 4:
1007 len_bits = DR_LEN_4;
1008 break;
1009 case 2:
1010 len_bits = DR_LEN_2;
1011 break;
1012 case 1:
1013 len_bits = DR_LEN_1;
1014 break;
1015 default:
1016 /* The debug registers only have 2 bits for the length, so
1017 so this value will always fail the loop below. */
1018 len_bits = 0x10;
1019 }
1020
1021 if (len == 2)
1022 {
1023 if (addr % 2)
1024 return go32_handle_nonaligned_watchpoint (wp_remove, waddr, addr,
1025 len, rw);
1026 }
1027 else if (len == 4)
1028 {
1029 if (addr % 4)
1030 return go32_handle_nonaligned_watchpoint (wp_remove, waddr, addr,
1031 len, rw);
1032 }
1033 else if (len != 1)
1034 return go32_handle_nonaligned_watchpoint (wp_remove, waddr, addr, len, rw);
e49d4fa6
SS
1035
1036 for (i = 0; i <= 3; i++)
1037 {
53a5351d
JM
1038 if (!IS_REG_FREE (i) && D_REGS[i] == addr
1039 && DR_DEF (i) == (len_bits | read_write_bits))
e49d4fa6 1040 {
53a5351d
JM
1041 dr_ref_count[i]--;
1042 if (dr_ref_count[i] == 0)
1043 DISABLE_REG (i);
e49d4fa6
SS
1044 }
1045 }
53a5351d
JM
1046 RESET_LOCAL_EXACT ();
1047 RESET_GLOBAL_EXACT ();
e49d4fa6
SS
1048
1049 return 0;
1050}
1051
53a5351d
JM
1052/* Can we use debug registers to watch a region whose address is ADDR
1053 and whose length is LEN bytes? */
1054
1055int
1056go32_region_ok_for_watchpoint (CORE_ADDR addr, int len)
1057{
1058 /* Compute how many aligned watchpoints we would need to cover this
1059 region. */
1060 int nregs = go32_handle_nonaligned_watchpoint (wp_count, addr, addr, len, 0);
1061
1062 return nregs <= 4 ? 1 : 0;
1063}
1064
1065/* Check if stopped by a data watchpoint. If so, return the address
1066 whose access triggered the watchpoint. */
e49d4fa6
SS
1067
1068CORE_ADDR
53a5351d 1069go32_stopped_by_watchpoint (int pid, int data_watchpoint)
e49d4fa6
SS
1070{
1071 int i, ret = 0;
1072 int status;
1073
1074 status = edi.dr[DR_STATUS];
53a5351d 1075 SHOW_DR (stopped_by, 0);
e49d4fa6
SS
1076 for (i = 0; i <= 3; i++)
1077 {
53a5351d 1078 if (WATCH_HIT (i) && data_watchpoint)
e49d4fa6 1079 {
53a5351d 1080 SHOW_DR (WP_HIT, 0);
e49d4fa6
SS
1081 ret = D_REGS[i];
1082 }
1083 }
e49d4fa6
SS
1084
1085 return ret;
1086}
1087
1088/* Remove a breakpoint. */
1089
1090int
1091go32_remove_hw_breakpoint (CORE_ADDR addr, CORE_ADDR shadow)
1092{
1093 int i;
1094 for (i = 0; i <= 3; i++)
1095 {
53a5351d 1096 if (!IS_REG_FREE (i) && D_REGS[i] == addr && DR_DEF (i) == 0)
e49d4fa6 1097 {
53a5351d
JM
1098 dr_ref_count[i]--;
1099 if (dr_ref_count[i] == 0)
1100 DISABLE_REG (i);
e49d4fa6
SS
1101 }
1102 }
53a5351d 1103 SHOW_DR (remove_hw, 0);
e49d4fa6
SS
1104 return 0;
1105}
1106
1107int
1108go32_insert_hw_breakpoint (CORE_ADDR addr, CORE_ADDR shadow)
1109{
1110 int i;
1111 int read_write_bits, len_bits;
1112 int free_debug_register;
1113 int register_number;
1114
53a5351d
JM
1115 /* Look for an occupied debug register with the same address and the
1116 same RW and LEN definitions. If we find one, we can use it for
1117 this breakpoint as well (and save a register). */
1118 for (i = 0; i < 4; i++)
1119 {
1120 if (!IS_REG_FREE (i) && D_REGS[i] == addr && DR_DEF (i) == 0)
1121 {
1122 dr_ref_count[i]++;
1123 SHOW_DR (insert_hw, 0);
1124 return 0;
1125 }
1126 }
1127
e49d4fa6
SS
1128 /* Look for a free debug register. */
1129 for (i = 0; i <= 3; i++)
1130 {
1131 if (IS_REG_FREE (i))
1132 break;
1133 }
1134
53a5351d
JM
1135 /* No more debug registers? */
1136 if (i < 4)
1137 {
1138 SET_BREAK (i, addr);
1139 LOCAL_ENABLE_REG (i);
1140 }
1141 SHOW_DR (insert_hw, 0);
e49d4fa6 1142
53a5351d 1143 return i < 4 ? 0 : -1;
e49d4fa6
SS
1144}
1145
cce74817
JM
1146static int inf_flags_valid = 0;
1147static int inf_in_flag;
1148static int inf_out_flag;
1149
53a5351d
JM
1150/* Put the device open on handle FD into either raw or cooked
1151 mode, return 1 if it was in raw mode, zero otherwise. */
1152
1153static int
1154device_mode (int fd, int raw_p)
1155{
1156 int oldmode, newmode;
1157 __dpmi_regs regs;
1158
1159 regs.x.ax = 0x4400;
1160 regs.x.bx = fd;
1161 __dpmi_int (0x21, &regs);
1162 if (regs.x.flags & 1)
1163 return -1;
1164 newmode = oldmode = regs.x.dx;
1165
1166 if (raw_p)
1167 newmode |= 0x20;
1168 else
1169 newmode &= ~0x20;
1170
1171 if (oldmode & 0x80) /* Only for character dev */
1172 {
1173 regs.x.ax = 0x4401;
1174 regs.x.bx = fd;
1175 regs.x.dx = newmode & 0xff; /* Force upper byte zero, else it fails */
1176 __dpmi_int (0x21, &regs);
1177 if (regs.x.flags & 1)
1178 return -1;
1179 }
1180 return (oldmode & 0x20) == 0x20;
1181}
1182
1183
1184static int inf_mode_valid = 0;
1185static int inf_terminal_mode;
1186
1187/* This semaphore is needed because, amazingly enough, GDB calls
1188 target.to_terminal_ours more than once after the inferior stops.
1189 But we need the information from the first call only, since the
1190 second call will always see GDB's own cooked terminal. */
1191static int terminal_is_ours = 1;
1192
cce74817
JM
1193static void
1194go32_terminal_init (void)
1195{
53a5351d
JM
1196 inf_mode_valid = 0; /* reinitialize, in case they are restarting child */
1197 terminal_is_ours = 1;
cce74817
JM
1198}
1199
1200static void
53a5351d 1201go32_terminal_info (char *args, int from_tty)
cce74817 1202{
53a5351d
JM
1203 printf_unfiltered ("Inferior's terminal is in %s mode.\n",
1204 !inf_mode_valid
1205 ? "default" : inf_terminal_mode ? "raw" : "cooked");
1206
1207#if __DJGPP_MINOR__ > 2
1208 if (child_cmd.redirection)
1209 {
1210 int i;
1211
1212 for (i = 0; i < DBG_HANDLES; i++)
c5aa993b 1213 {
53a5351d
JM
1214 if (child_cmd.redirection[i]->file_name)
1215 printf_unfiltered ("\tFile handle %d is redirected to `%s'.\n",
1216 i, child_cmd.redirection[i]->file_name);
1217 else if (_get_dev_info (child_cmd.redirection[i]->inf_handle) == -1)
1218 printf_unfiltered
1219 ("\tFile handle %d appears to be closed by inferior.\n", i);
1220 /* Mask off the raw/cooked bit when comparing device info words. */
1221 else if ((_get_dev_info (child_cmd.redirection[i]->inf_handle) & 0xdf)
1222 != (_get_dev_info (i) & 0xdf))
1223 printf_unfiltered
1224 ("\tFile handle %d appears to be redirected by inferior.\n", i);
c5aa993b 1225 }
53a5351d
JM
1226 }
1227#endif
1228}
1229
1230static void
1231go32_terminal_inferior (void)
1232{
1233 /* Redirect standard handles as child wants them. */
1234 errno = 0;
1235 if (redir_to_child (&child_cmd) == -1)
1236 {
1237 redir_to_debugger (&child_cmd);
1238 error ("Cannot redirect standard handles for program: %s.",
1239 strerror (errno));
1240 }
1241 /* set the console device of the inferior to whatever mode
1242 (raw or cooked) we found it last time */
1243 if (terminal_is_ours)
1244 {
1245 if (inf_mode_valid)
1246 device_mode (0, inf_terminal_mode);
1247 terminal_is_ours = 0;
1248 }
cce74817
JM
1249}
1250
1251static void
1252go32_terminal_ours (void)
1253{
53a5351d
JM
1254 /* Switch to cooked mode on the gdb terminal and save the inferior
1255 terminal mode to be restored when it is resumed */
1256 if (!terminal_is_ours)
1257 {
1258 inf_terminal_mode = device_mode (0, 0);
1259 if (inf_terminal_mode != -1)
1260 inf_mode_valid = 1;
1261 else
1262 /* If device_mode returned -1, we don't know what happens with
1263 handle 0 anymore, so make the info invalid. */
1264 inf_mode_valid = 0;
1265 terminal_is_ours = 1;
1266
1267 /* Restore debugger's standard handles. */
1268 errno = 0;
1269 if (redir_to_debugger (&child_cmd) == -1)
1270 {
1271 redir_to_child (&child_cmd);
1272 error ("Cannot redirect standard handles for debugger: %s.",
1273 strerror (errno));
1274 }
1275 }
cce74817
JM
1276}
1277
e49d4fa6
SS
1278static void
1279init_go32_ops (void)
1280{
1281 go32_ops.to_shortname = "djgpp";
1282 go32_ops.to_longname = "djgpp target process";
1283 go32_ops.to_doc =
1284 "Program loaded by djgpp, when gdb is used as an external debugger";
1285 go32_ops.to_open = go32_open;
1286 go32_ops.to_close = go32_close;
53a5351d 1287 go32_ops.to_attach = go32_attach;
e49d4fa6
SS
1288 go32_ops.to_detach = go32_detach;
1289 go32_ops.to_resume = go32_resume;
1290 go32_ops.to_wait = go32_wait;
1291 go32_ops.to_fetch_registers = go32_fetch_registers;
1292 go32_ops.to_store_registers = go32_store_registers;
1293 go32_ops.to_prepare_to_store = go32_prepare_to_store;
1294 go32_ops.to_xfer_memory = go32_xfer_memory;
1295 go32_ops.to_files_info = go32_files_info;
1296 go32_ops.to_insert_breakpoint = memory_insert_breakpoint;
1297 go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
cce74817
JM
1298 go32_ops.to_terminal_init = go32_terminal_init;
1299 go32_ops.to_terminal_inferior = go32_terminal_inferior;
53a5351d 1300 go32_ops.to_terminal_ours_for_output = go32_terminal_ours;
cce74817 1301 go32_ops.to_terminal_ours = go32_terminal_ours;
53a5351d 1302 go32_ops.to_terminal_info = go32_terminal_info;
e49d4fa6
SS
1303 go32_ops.to_kill = go32_kill_inferior;
1304 go32_ops.to_create_inferior = go32_create_inferior;
1305 go32_ops.to_mourn_inferior = go32_mourn_inferior;
1306 go32_ops.to_can_run = go32_can_run;
1307 go32_ops.to_stop = go32_stop;
1308 go32_ops.to_stratum = process_stratum;
1309 go32_ops.to_has_all_memory = 1;
1310 go32_ops.to_has_memory = 1;
1311 go32_ops.to_has_stack = 1;
1312 go32_ops.to_has_registers = 1;
1313 go32_ops.to_has_execution = 1;
1314 go32_ops.to_magic = OPS_MAGIC;
53a5351d
JM
1315
1316 /* Initialize child's cwd with the current one. */
1317 getcwd (child_cwd, sizeof (child_cwd));
1318
1319 /* Initialize child's command line storage. */
1320 if (redir_debug_init (&child_cmd) == -1)
1321 fatal ("Cannot allocate redirection storage: not enough memory.\n");
e49d4fa6
SS
1322}
1323
1324void
1325_initialize_go32_nat (void)
1326{
1327 init_go32_ops ();
1328 add_target (&go32_ops);
1329}
53a5351d
JM
1330
1331pid_t
1332tcgetpgrp (int fd)
1333{
1334 if (isatty (fd))
1335 return SOME_PID;
1336 errno = ENOTTY;
1337 return -1;
1338}
1339
1340int
1341tcsetpgrp (int fd, pid_t pgid)
1342{
1343 if (isatty (fd) && pgid == SOME_PID)
1344 return 0;
1345 errno = pgid == SOME_PID ? ENOTTY : ENOSYS;
1346 return -1;
1347}
This page took 0.091046 seconds and 4 git commands to generate.