import gdb-1999-12-06 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
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>
c2c6d25f 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,
4ce44c66 348 7, TARGET_SIGNAL_EMT, /* no-coprocessor exception */
c5aa993b
JM
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
4ce44c66
JM
573 internal_error ("Invalid register no. %d in go32_fetch_register.",
574 regno);
e49d4fa6
SS
575 }
576}
577
578static void
579store_register (int regno)
580{
581 void *rp;
582 void *v = (void *) &registers[REGISTER_BYTE (regno)];
583
584 if (regno < 16)
585 rp = (char *) &a_tss + regno_mapping[regno].tss_ofs;
586 else if (regno < 24)
587 rp = (char *) &npx.reg[regno_mapping[regno].tss_ofs];
53a5351d 588 else if (regno < 31)
e49d4fa6
SS
589 rp = (char *) &npx + regno_mapping[regno].tss_ofs;
590 else
4ce44c66 591 internal_error ("Invalid register no. %d in store_register.", regno);
e49d4fa6
SS
592 memcpy (rp, v, regno_mapping[regno].size);
593}
594
595static void
596go32_store_registers (int regno)
597{
598 int r;
599
600 if (regno >= 0)
601 store_register (regno);
602 else
603 {
604 for (r = 0; r < sizeof (regno_mapping) / sizeof (regno_mapping[0]); r++)
605 store_register (r);
606 }
607}
608
609static void
610go32_prepare_to_store (void)
611{
612}
613
614static int
615go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
616 struct target_ops *target)
617{
618 if (write)
619 {
620 if (write_child (memaddr, myaddr, len))
621 {
622 return 0;
623 }
624 else
625 {
626 return len;
627 }
628 }
629 else
630 {
631 if (read_child (memaddr, myaddr, len))
632 {
633 return 0;
634 }
635 else
636 {
637 return len;
638 }
639 }
640}
641
53a5351d
JM
642static cmdline_t child_cmd; /* parsed child's command line kept here */
643
e49d4fa6
SS
644static void
645go32_files_info (struct target_ops *target)
646{
53a5351d 647 printf_unfiltered ("You are running a DJGPP V2 program.\n");
e49d4fa6
SS
648}
649
650static void
651go32_stop (void)
652{
653 normal_stop ();
654 cleanup_client ();
655 inferior_pid = 0;
656 prog_has_started = 0;
657}
658
659static void
660go32_kill_inferior (void)
661{
53a5351d
JM
662 redir_cmdline_delete (&child_cmd);
663 resume_signal = -1;
664 resume_is_step = 0;
e49d4fa6
SS
665 unpush_target (&go32_ops);
666}
667
668static void
669go32_create_inferior (char *exec_file, char *args, char **env)
670{
671 jmp_buf start_state;
672 char *cmdline;
673 char **env_save = environ;
674
675 if (prog_has_started)
676 {
b83266a0 677 go32_stop ();
e49d4fa6
SS
678 go32_kill_inferior ();
679 }
53a5351d
JM
680 resume_signal = -1;
681 resume_is_step = 0;
682 /* Init command line storage. */
683 if (redir_debug_init (&child_cmd) == -1)
4ce44c66 684 internal_error ("Cannot allocate redirection storage: not enough memory.\n");
53a5351d
JM
685
686 /* Parse the command line and create redirections. */
687 if (strpbrk (args, "<>"))
688 {
689 if (redir_cmdline_parse (args, &child_cmd) == 0)
690 args = child_cmd.command;
691 else
692 error ("Syntax error in command line.");
693 }
694 else
695 child_cmd.command = strdup (args);
e49d4fa6
SS
696
697 cmdline = (char *) alloca (strlen (args) + 4);
698 cmdline[0] = strlen (args);
699 strcpy (cmdline + 1, args);
700 cmdline[strlen (args) + 1] = 13;
701
702 environ = env;
703
704 if (v2loadimage (exec_file, cmdline, start_state))
705 {
706 environ = env_save;
707 printf_unfiltered ("Load failed for image %s\n", exec_file);
708 exit (1);
709 }
710 environ = env_save;
711
712 edi_init (start_state);
53a5351d
JM
713#if __DJGPP_MINOR__ < 3
714 save_npx ();
715#endif
e49d4fa6
SS
716
717 inferior_pid = SOME_PID;
718 push_target (&go32_ops);
719 clear_proceed_status ();
720 insert_breakpoints ();
2acceee2 721 proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
b83266a0 722 prog_has_started = 1;
e49d4fa6
SS
723}
724
725static void
726go32_mourn_inferior (void)
727{
53a5351d
JM
728 /* We need to make sure all the breakpoint enable bits in the DR7
729 register are reset when the inferior exits. Otherwise, if they
730 rerun the inferior, the uncleared bits may cause random SIGTRAPs,
731 failure to set more watchpoints, and other calamities. It would
732 be nice if GDB itself would take care to remove all breakpoints
733 at all times, but it doesn't, probably under an assumption that
734 the OS cleans up when the debuggee exits. */
735 cleanup_dregs ();
e49d4fa6
SS
736 go32_kill_inferior ();
737 generic_mourn_inferior ();
738}
739
740static int
741go32_can_run (void)
742{
743 return 1;
744}
745
746static void
747ignore (void)
748{
749}
750
e49d4fa6
SS
751/* Hardware watchpoint support. */
752
753#define DR_STATUS 6
754#define DR_CONTROL 7
755#define DR_ENABLE_SIZE 2
756#define DR_LOCAL_ENABLE_SHIFT 0
757#define DR_GLOBAL_ENABLE_SHIFT 1
758#define DR_LOCAL_SLOWDOWN 0x100
759#define DR_GLOBAL_SLOWDOWN 0x200
760#define DR_CONTROL_SHIFT 16
761#define DR_CONTROL_SIZE 4
53a5351d 762#define DR_RW_READWRITE 0x3
e49d4fa6
SS
763#define DR_RW_WRITE 0x1
764#define DR_CONTROL_MASK 0xf
765#define DR_ENABLE_MASK 0x3
766#define DR_LEN_1 0x0
767#define DR_LEN_2 0x4
768#define DR_LEN_4 0xc
769
770#define D_REGS edi.dr
771#define CONTROL D_REGS[DR_CONTROL]
772#define STATUS D_REGS[DR_STATUS]
773
774#define IS_REG_FREE(index) \
53a5351d 775 (!(CONTROL & (3 << (DR_ENABLE_SIZE * (index)))))
e49d4fa6
SS
776
777#define LOCAL_ENABLE_REG(index) \
53a5351d 778 (CONTROL |= (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (index))))
e49d4fa6
SS
779
780#define GLOBAL_ENABLE_REG(index) \
53a5351d 781 (CONTROL |= (1 << (DR_GLOBAL_ENABLE_SHIFT + DR_ENABLE_SIZE * (index))))
e49d4fa6
SS
782
783#define DISABLE_REG(index) \
53a5351d 784 (CONTROL &= ~(3 << (DR_ENABLE_SIZE * (index))))
e49d4fa6
SS
785
786#define SET_LOCAL_EXACT() \
787 (CONTROL |= DR_LOCAL_SLOWDOWN)
788
789#define SET_GLOBAL_EXACT() \
790 (CONTROL |= DR_GLOBAL_SLOWDOWN)
791
53a5351d
JM
792#define RESET_LOCAL_EXACT() \
793 (CONTROL &= ~(DR_LOCAL_SLOWDOWN))
794
795#define RESET_GLOBAL_EXACT() \
796 (CONTROL &= ~(DR_GLOBAL_SLOWDOWN))
797
e49d4fa6
SS
798#define SET_BREAK(index,address) \
799 do {\
53a5351d 800 CONTROL &= ~(DR_CONTROL_MASK << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (index)));\
e49d4fa6 801 D_REGS[index] = address;\
c2c6d25f 802 dr_ref_count[index]++;\
e49d4fa6
SS
803 } while(0)
804
805#define SET_WATCH(index,address,rw,len) \
806 do {\
807 SET_BREAK(index,address);\
53a5351d 808 CONTROL |= ((len)|(rw)) << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (index));\
e49d4fa6
SS
809 } while (0)
810
53a5351d
JM
811#define IS_WATCH(index) \
812 (CONTROL & (DR_CONTROL_MASK << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE*(index))))
813
c2c6d25f 814#define WATCH_HIT(index) ((STATUS & (1 << (index))) && IS_WATCH(index))
e49d4fa6 815
53a5351d
JM
816#define DR_DEF(index) \
817 ((CONTROL >> (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * (index))) & 0x0f)
818
819
820#if 0 /* use debugging macro */
821#define SHOW_DR(text,len) \
e49d4fa6 822do { \
53a5351d 823 if (!getenv ("GDB_SHOW_DR")) break; \
e49d4fa6 824 fprintf(stderr,"%08x %08x ",edi.dr[7],edi.dr[6]); \
53a5351d
JM
825 fprintf(stderr,"%08x %d %08x %d ", \
826 edi.dr[0],dr_ref_count[0],edi.dr[1],dr_ref_count[1]); \
827 fprintf(stderr,"%08x %d %08x %d ", \
828 edi.dr[2],dr_ref_count[2],edi.dr[3],dr_ref_count[3]); \
829 fprintf(stderr,(len)?"(%s:%d)\n":"(%s)\n",#text,len); \
e49d4fa6
SS
830} while (0)
831#else
53a5351d 832#define SHOW_DR(text,len) do {} while (0)
e49d4fa6
SS
833#endif
834
53a5351d
JM
835static void
836cleanup_dregs (void)
837{
838 int i;
839
840 CONTROL = 0;
841 STATUS = 0;
842 for (i = 0; i < 4; i++)
843 {
844 D_REGS[i] = 0;
845 dr_ref_count[i] = 0;
846 }
847}
848
e49d4fa6
SS
849/* Insert a watchpoint. */
850
851int
852go32_insert_watchpoint (int pid, CORE_ADDR addr, int len, int rw)
853{
53a5351d 854 int ret = go32_insert_aligned_watchpoint (addr, addr, len, rw);
e49d4fa6 855
53a5351d 856 SHOW_DR (insert_watch, len);
e49d4fa6
SS
857 return ret;
858}
859
860static int
53a5351d 861go32_insert_aligned_watchpoint (CORE_ADDR waddr, CORE_ADDR addr,
e49d4fa6
SS
862 int len, int rw)
863{
864 int i;
865 int read_write_bits, len_bits;
866
53a5351d
JM
867 /* Values of rw: 0 - write, 1 - read, 2 - access (read and write).
868 However, x86 doesn't support read-only data breakpoints. */
869 read_write_bits = rw ? DR_RW_READWRITE : DR_RW_WRITE;
870
871 switch (len)
872 {
873 case 4:
874 len_bits = DR_LEN_4;
875 break;
876 case 2:
877 len_bits = DR_LEN_2;
878 break;
879 case 1:
880 len_bits = DR_LEN_1;
881 break;
882 default:
883 /* The debug registers only have 2 bits for the length, so
884 so this value will always fail the loop below. */
885 len_bits = 0x10;
886 }
887
888 /* Look for an occupied debug register with the same address and the
889 same RW and LEN definitions. If we find one, we can use it for
890 this watchpoint as well (and save a register). */
891 for (i = 0; i < 4; i++)
892 {
893 if (!IS_REG_FREE (i) && D_REGS[i] == addr
894 && DR_DEF (i) == (len_bits | read_write_bits))
e49d4fa6 895 {
53a5351d
JM
896 dr_ref_count[i]++;
897 return 0;
e49d4fa6 898 }
53a5351d
JM
899 }
900
901 /* Look for a free debug register. */
902 for (i = 0; i <= 3; i++)
903 {
904 if (IS_REG_FREE (i))
905 break;
906 }
e49d4fa6
SS
907
908 /* No more debug registers! */
909 if (i > 3)
910 return -1;
911
53a5351d
JM
912 if (len == 2)
913 {
914 if (addr % 2)
915 return go32_handle_nonaligned_watchpoint (wp_insert, waddr, addr,
916 len, rw);
917 }
e49d4fa6 918 else if (len == 4)
53a5351d
JM
919 {
920 if (addr % 4)
921 return go32_handle_nonaligned_watchpoint (wp_insert, waddr, addr,
922 len, rw);
923 }
924 else if (len != 1)
925 return go32_handle_nonaligned_watchpoint (wp_insert, waddr, addr, len, rw);
e49d4fa6
SS
926
927 SET_WATCH (i, addr, read_write_bits, len_bits);
928 LOCAL_ENABLE_REG (i);
929 SET_LOCAL_EXACT ();
53a5351d
JM
930 SET_GLOBAL_EXACT ();
931 return 0;
e49d4fa6
SS
932}
933
934static int
53a5351d 935go32_handle_nonaligned_watchpoint (wp_op what, CORE_ADDR waddr, CORE_ADDR addr,
e49d4fa6
SS
936 int len, int rw)
937{
938 int align;
939 int size;
53a5351d 940 int rv = 0, status = 0;
e49d4fa6
SS
941
942 static int size_try_array[16] =
943 {
944 1, 1, 1, 1, /* trying size one */
945 2, 1, 2, 1, /* trying size two */
946 2, 1, 2, 1, /* trying size three */
947 4, 1, 2, 1 /* trying size four */
948 };
949
950 while (len > 0)
951 {
952 align = addr % 4;
953 /* Four is the maximum length for 386. */
954 size = (len > 4) ? 3 : len - 1;
955 size = size_try_array[size * 4 + align];
53a5351d
JM
956 if (what == wp_insert)
957 status = go32_insert_aligned_watchpoint (waddr, addr, size, rw);
958 else if (what == wp_remove)
959 status = go32_remove_aligned_watchpoint (waddr, addr, size, rw);
960 else if (what == wp_count)
961 rv++;
962 else
963 status = -1;
964 /* We keep the loop going even after a failure, because some of
965 the other aligned watchpoints might still succeed, e.g. if
966 they watch addresses that are already watched, and thus just
967 increment the reference counts of occupied debug registers.
968 If we break out of the loop too early, we could cause those
969 addresses watched by other watchpoints to be disabled when
970 GDB reacts to our failure to insert this watchpoint and tries
971 to remove it. */
972 if (status)
973 rv = status;
e49d4fa6
SS
974 addr += size;
975 len -= size;
976 }
977 return rv;
978}
979
980/* Remove a watchpoint. */
981
982int
53a5351d
JM
983go32_remove_watchpoint (int pid, CORE_ADDR addr, int len, int rw)
984{
985 int ret = go32_remove_aligned_watchpoint (addr, addr, len, rw);
986
987 SHOW_DR (remove_watch, len);
988 return ret;
989}
990
991static int
992go32_remove_aligned_watchpoint (CORE_ADDR waddr, CORE_ADDR addr,
993 int len, int rw)
e49d4fa6
SS
994{
995 int i;
53a5351d
JM
996 int read_write_bits, len_bits;
997
998 /* Values of rw: 0 - write, 1 - read, 2 - access (read and write).
999 However, x86 doesn't support read-only data breakpoints. */
1000 read_write_bits = rw ? DR_RW_READWRITE : DR_RW_WRITE;
1001
1002 switch (len)
1003 {
1004 case 4:
1005 len_bits = DR_LEN_4;
1006 break;
1007 case 2:
1008 len_bits = DR_LEN_2;
1009 break;
1010 case 1:
1011 len_bits = DR_LEN_1;
1012 break;
1013 default:
1014 /* The debug registers only have 2 bits for the length, so
1015 so this value will always fail the loop below. */
1016 len_bits = 0x10;
1017 }
1018
1019 if (len == 2)
1020 {
1021 if (addr % 2)
1022 return go32_handle_nonaligned_watchpoint (wp_remove, waddr, addr,
1023 len, rw);
1024 }
1025 else if (len == 4)
1026 {
1027 if (addr % 4)
1028 return go32_handle_nonaligned_watchpoint (wp_remove, waddr, addr,
1029 len, rw);
1030 }
1031 else if (len != 1)
1032 return go32_handle_nonaligned_watchpoint (wp_remove, waddr, addr, len, rw);
e49d4fa6
SS
1033
1034 for (i = 0; i <= 3; i++)
1035 {
53a5351d
JM
1036 if (!IS_REG_FREE (i) && D_REGS[i] == addr
1037 && DR_DEF (i) == (len_bits | read_write_bits))
e49d4fa6 1038 {
53a5351d
JM
1039 dr_ref_count[i]--;
1040 if (dr_ref_count[i] == 0)
1041 DISABLE_REG (i);
e49d4fa6
SS
1042 }
1043 }
53a5351d
JM
1044 RESET_LOCAL_EXACT ();
1045 RESET_GLOBAL_EXACT ();
e49d4fa6
SS
1046
1047 return 0;
1048}
1049
53a5351d
JM
1050/* Can we use debug registers to watch a region whose address is ADDR
1051 and whose length is LEN bytes? */
1052
1053int
1054go32_region_ok_for_watchpoint (CORE_ADDR addr, int len)
1055{
1056 /* Compute how many aligned watchpoints we would need to cover this
1057 region. */
1058 int nregs = go32_handle_nonaligned_watchpoint (wp_count, addr, addr, len, 0);
1059
1060 return nregs <= 4 ? 1 : 0;
1061}
1062
1063/* Check if stopped by a data watchpoint. If so, return the address
1064 whose access triggered the watchpoint. */
e49d4fa6
SS
1065
1066CORE_ADDR
53a5351d 1067go32_stopped_by_watchpoint (int pid, int data_watchpoint)
e49d4fa6
SS
1068{
1069 int i, ret = 0;
1070 int status;
1071
1072 status = edi.dr[DR_STATUS];
53a5351d 1073 SHOW_DR (stopped_by, 0);
e49d4fa6
SS
1074 for (i = 0; i <= 3; i++)
1075 {
53a5351d 1076 if (WATCH_HIT (i) && data_watchpoint)
e49d4fa6 1077 {
53a5351d 1078 SHOW_DR (WP_HIT, 0);
e49d4fa6
SS
1079 ret = D_REGS[i];
1080 }
1081 }
e49d4fa6
SS
1082
1083 return ret;
1084}
1085
1086/* Remove a breakpoint. */
1087
1088int
1089go32_remove_hw_breakpoint (CORE_ADDR addr, CORE_ADDR shadow)
1090{
1091 int i;
1092 for (i = 0; i <= 3; i++)
1093 {
53a5351d 1094 if (!IS_REG_FREE (i) && D_REGS[i] == addr && DR_DEF (i) == 0)
e49d4fa6 1095 {
53a5351d
JM
1096 dr_ref_count[i]--;
1097 if (dr_ref_count[i] == 0)
1098 DISABLE_REG (i);
e49d4fa6
SS
1099 }
1100 }
53a5351d 1101 SHOW_DR (remove_hw, 0);
e49d4fa6
SS
1102 return 0;
1103}
1104
1105int
1106go32_insert_hw_breakpoint (CORE_ADDR addr, CORE_ADDR shadow)
1107{
1108 int i;
1109 int read_write_bits, len_bits;
1110 int free_debug_register;
1111 int register_number;
1112
53a5351d
JM
1113 /* Look for an occupied debug register with the same address and the
1114 same RW and LEN definitions. If we find one, we can use it for
1115 this breakpoint as well (and save a register). */
1116 for (i = 0; i < 4; i++)
1117 {
1118 if (!IS_REG_FREE (i) && D_REGS[i] == addr && DR_DEF (i) == 0)
1119 {
1120 dr_ref_count[i]++;
1121 SHOW_DR (insert_hw, 0);
1122 return 0;
1123 }
1124 }
1125
e49d4fa6
SS
1126 /* Look for a free debug register. */
1127 for (i = 0; i <= 3; i++)
1128 {
1129 if (IS_REG_FREE (i))
1130 break;
1131 }
1132
53a5351d
JM
1133 /* No more debug registers? */
1134 if (i < 4)
1135 {
1136 SET_BREAK (i, addr);
1137 LOCAL_ENABLE_REG (i);
1138 }
1139 SHOW_DR (insert_hw, 0);
e49d4fa6 1140
53a5351d 1141 return i < 4 ? 0 : -1;
e49d4fa6
SS
1142}
1143
53a5351d
JM
1144/* Put the device open on handle FD into either raw or cooked
1145 mode, return 1 if it was in raw mode, zero otherwise. */
1146
1147static int
1148device_mode (int fd, int raw_p)
1149{
1150 int oldmode, newmode;
1151 __dpmi_regs regs;
1152
1153 regs.x.ax = 0x4400;
1154 regs.x.bx = fd;
1155 __dpmi_int (0x21, &regs);
1156 if (regs.x.flags & 1)
1157 return -1;
1158 newmode = oldmode = regs.x.dx;
1159
1160 if (raw_p)
1161 newmode |= 0x20;
1162 else
1163 newmode &= ~0x20;
1164
1165 if (oldmode & 0x80) /* Only for character dev */
1166 {
1167 regs.x.ax = 0x4401;
1168 regs.x.bx = fd;
1169 regs.x.dx = newmode & 0xff; /* Force upper byte zero, else it fails */
1170 __dpmi_int (0x21, &regs);
1171 if (regs.x.flags & 1)
1172 return -1;
1173 }
1174 return (oldmode & 0x20) == 0x20;
1175}
1176
1177
1178static int inf_mode_valid = 0;
1179static int inf_terminal_mode;
1180
1181/* This semaphore is needed because, amazingly enough, GDB calls
1182 target.to_terminal_ours more than once after the inferior stops.
1183 But we need the information from the first call only, since the
1184 second call will always see GDB's own cooked terminal. */
1185static int terminal_is_ours = 1;
1186
cce74817
JM
1187static void
1188go32_terminal_init (void)
1189{
53a5351d
JM
1190 inf_mode_valid = 0; /* reinitialize, in case they are restarting child */
1191 terminal_is_ours = 1;
cce74817
JM
1192}
1193
1194static void
53a5351d 1195go32_terminal_info (char *args, int from_tty)
cce74817 1196{
53a5351d
JM
1197 printf_unfiltered ("Inferior's terminal is in %s mode.\n",
1198 !inf_mode_valid
1199 ? "default" : inf_terminal_mode ? "raw" : "cooked");
1200
1201#if __DJGPP_MINOR__ > 2
1202 if (child_cmd.redirection)
1203 {
1204 int i;
1205
1206 for (i = 0; i < DBG_HANDLES; i++)
c5aa993b 1207 {
53a5351d
JM
1208 if (child_cmd.redirection[i]->file_name)
1209 printf_unfiltered ("\tFile handle %d is redirected to `%s'.\n",
1210 i, child_cmd.redirection[i]->file_name);
1211 else if (_get_dev_info (child_cmd.redirection[i]->inf_handle) == -1)
1212 printf_unfiltered
1213 ("\tFile handle %d appears to be closed by inferior.\n", i);
1214 /* Mask off the raw/cooked bit when comparing device info words. */
1215 else if ((_get_dev_info (child_cmd.redirection[i]->inf_handle) & 0xdf)
1216 != (_get_dev_info (i) & 0xdf))
1217 printf_unfiltered
1218 ("\tFile handle %d appears to be redirected by inferior.\n", i);
c5aa993b 1219 }
53a5351d
JM
1220 }
1221#endif
1222}
1223
1224static void
1225go32_terminal_inferior (void)
1226{
1227 /* Redirect standard handles as child wants them. */
1228 errno = 0;
1229 if (redir_to_child (&child_cmd) == -1)
1230 {
1231 redir_to_debugger (&child_cmd);
1232 error ("Cannot redirect standard handles for program: %s.",
1233 strerror (errno));
1234 }
1235 /* set the console device of the inferior to whatever mode
1236 (raw or cooked) we found it last time */
1237 if (terminal_is_ours)
1238 {
1239 if (inf_mode_valid)
1240 device_mode (0, inf_terminal_mode);
1241 terminal_is_ours = 0;
1242 }
cce74817
JM
1243}
1244
1245static void
1246go32_terminal_ours (void)
1247{
53a5351d
JM
1248 /* Switch to cooked mode on the gdb terminal and save the inferior
1249 terminal mode to be restored when it is resumed */
1250 if (!terminal_is_ours)
1251 {
1252 inf_terminal_mode = device_mode (0, 0);
1253 if (inf_terminal_mode != -1)
1254 inf_mode_valid = 1;
1255 else
1256 /* If device_mode returned -1, we don't know what happens with
1257 handle 0 anymore, so make the info invalid. */
1258 inf_mode_valid = 0;
1259 terminal_is_ours = 1;
1260
1261 /* Restore debugger's standard handles. */
1262 errno = 0;
1263 if (redir_to_debugger (&child_cmd) == -1)
1264 {
1265 redir_to_child (&child_cmd);
1266 error ("Cannot redirect standard handles for debugger: %s.",
1267 strerror (errno));
1268 }
1269 }
cce74817
JM
1270}
1271
e49d4fa6
SS
1272static void
1273init_go32_ops (void)
1274{
1275 go32_ops.to_shortname = "djgpp";
1276 go32_ops.to_longname = "djgpp target process";
1277 go32_ops.to_doc =
1278 "Program loaded by djgpp, when gdb is used as an external debugger";
1279 go32_ops.to_open = go32_open;
1280 go32_ops.to_close = go32_close;
53a5351d 1281 go32_ops.to_attach = go32_attach;
e49d4fa6
SS
1282 go32_ops.to_detach = go32_detach;
1283 go32_ops.to_resume = go32_resume;
1284 go32_ops.to_wait = go32_wait;
1285 go32_ops.to_fetch_registers = go32_fetch_registers;
1286 go32_ops.to_store_registers = go32_store_registers;
1287 go32_ops.to_prepare_to_store = go32_prepare_to_store;
1288 go32_ops.to_xfer_memory = go32_xfer_memory;
1289 go32_ops.to_files_info = go32_files_info;
1290 go32_ops.to_insert_breakpoint = memory_insert_breakpoint;
1291 go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
cce74817
JM
1292 go32_ops.to_terminal_init = go32_terminal_init;
1293 go32_ops.to_terminal_inferior = go32_terminal_inferior;
53a5351d 1294 go32_ops.to_terminal_ours_for_output = go32_terminal_ours;
cce74817 1295 go32_ops.to_terminal_ours = go32_terminal_ours;
53a5351d 1296 go32_ops.to_terminal_info = go32_terminal_info;
e49d4fa6
SS
1297 go32_ops.to_kill = go32_kill_inferior;
1298 go32_ops.to_create_inferior = go32_create_inferior;
1299 go32_ops.to_mourn_inferior = go32_mourn_inferior;
1300 go32_ops.to_can_run = go32_can_run;
1301 go32_ops.to_stop = go32_stop;
1302 go32_ops.to_stratum = process_stratum;
1303 go32_ops.to_has_all_memory = 1;
1304 go32_ops.to_has_memory = 1;
1305 go32_ops.to_has_stack = 1;
1306 go32_ops.to_has_registers = 1;
1307 go32_ops.to_has_execution = 1;
1308 go32_ops.to_magic = OPS_MAGIC;
53a5351d
JM
1309
1310 /* Initialize child's cwd with the current one. */
1311 getcwd (child_cwd, sizeof (child_cwd));
1312
1313 /* Initialize child's command line storage. */
1314 if (redir_debug_init (&child_cmd) == -1)
4ce44c66 1315 internal_error ("Cannot allocate redirection storage: not enough memory.\n");
e49d4fa6
SS
1316}
1317
1318void
1319_initialize_go32_nat (void)
1320{
1321 init_go32_ops ();
1322 add_target (&go32_ops);
1323}
53a5351d
JM
1324
1325pid_t
1326tcgetpgrp (int fd)
1327{
1328 if (isatty (fd))
1329 return SOME_PID;
1330 errno = ENOTTY;
1331 return -1;
1332}
1333
1334int
1335tcsetpgrp (int fd, pid_t pgid)
1336{
1337 if (isatty (fd) && pgid == SOME_PID)
1338 return 0;
1339 errno = pgid == SOME_PID ? ENOTTY : ENOSYS;
1340 return -1;
1341}
This page took 0.089383 seconds and 4 git commands to generate.