OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [go32-nat.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* Native debugging support for Intel x86 running DJGPP.
2
   Copyright 1997, 1999, 2000, 2001 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,
20
   Boston, MA 02111-1307, USA.  */
21
 
22
#include <fcntl.h>
23
 
24
#include "defs.h"
25
#include "inferior.h"
26
#include "gdb_wait.h"
27
#include "gdbcore.h"
28
#include "command.h"
29
#include "floatformat.h"
30
#include "buildsym.h"
31
#include "i387-nat.h"
32
#include "value.h"
33
#include "regcache.h"
34
#include "gdb_string.h"
35
 
36
#include <stdio.h>              /* required for __DJGPP_MINOR__ */
37
#include <stdlib.h>
38
#include <errno.h>
39
#include <unistd.h>
40
#include <io.h>
41
#include <dpmi.h>
42
#include <debug/v2load.h>
43
#include <debug/dbgcom.h>
44
#if __DJGPP_MINOR__ > 2
45
#include <debug/redir.h>
46
#endif
47
 
48
#if __DJGPP_MINOR__ < 3
49
/* This code will be provided from DJGPP 2.03 on. Until then I code it
50
   here */
51
typedef struct
52
  {
53
    unsigned short sig0;
54
    unsigned short sig1;
55
    unsigned short sig2;
56
    unsigned short sig3;
57
    unsigned short exponent:15;
58
    unsigned short sign:1;
59
  }
60
NPXREG;
61
 
62
typedef struct
63
  {
64
    unsigned int control;
65
    unsigned int status;
66
    unsigned int tag;
67
    unsigned int eip;
68
    unsigned int cs;
69
    unsigned int dataptr;
70
    unsigned int datasel;
71
    NPXREG reg[8];
72
  }
73
NPX;
74
 
75
static NPX npx;
76
 
77
static void save_npx (void);    /* Save the FPU of the debugged program */
78
static void load_npx (void);    /* Restore the FPU of the debugged program */
79
 
80
/* ------------------------------------------------------------------------- */
81
/* Store the contents of the NPX in the global variable `npx'.  */
82
/* *INDENT-OFF* */
83
 
84
static void
85
save_npx (void)
86
{
87
  asm ("inb    $0xa0, %%al
88
       testb $0x20, %%al
89
       jz 1f
90
       xorb %% al, %%al
91
       outb %% al, $0xf0
92
       movb $0x20, %%al
93
       outb %% al, $0xa0
94
       outb %% al, $0x20
95
1:
96
       fnsave % 0
97
       fwait "
98
:     "=m" (npx)
99
:                               /* No input */
100
:     "%eax");
101
}
102
 
103
/* *INDENT-ON* */
104
 
105
 
106
 
107
 
108
 
109
/* ------------------------------------------------------------------------- */
110
/* Reload the contents of the NPX from the global variable `npx'.  */
111
 
112
static void
113
load_npx (void)
114
{
115
  asm ("frstor %0":"=m" (npx));
116
}
117
/* ------------------------------------------------------------------------- */
118
/* Stubs for the missing redirection functions.  */
119
typedef struct {
120
  char *command;
121
  int redirected;
122
} cmdline_t;
123
 
124
void
125
redir_cmdline_delete (cmdline_t *ptr)
126
{
127
  ptr->redirected = 0;
128
}
129
 
130
int
131
redir_cmdline_parse (const char *args, cmdline_t *ptr)
132
{
133
  return -1;
134
}
135
 
136
int
137
redir_to_child (cmdline_t *ptr)
138
{
139
  return 1;
140
}
141
 
142
int
143
redir_to_debugger (cmdline_t *ptr)
144
{
145
  return 1;
146
}
147
 
148
int
149
redir_debug_init (cmdline_t *ptr)
150
{
151
  return 0;
152
}
153
#endif /* __DJGPP_MINOR < 3 */
154
 
155
typedef enum { wp_insert, wp_remove, wp_count } wp_op;
156
 
157
/* This holds the current reference counts for each debug register.  */
158
static int dr_ref_count[4];
159
 
160
#define SOME_PID 42
161
 
162
static int prog_has_started = 0;
163
static void go32_open (char *name, int from_tty);
164
static void go32_close (int quitting);
165
static void go32_attach (char *args, int from_tty);
166
static void go32_detach (char *args, int from_tty);
167
static void go32_resume (ptid_t ptid, int step,
168
                         enum target_signal siggnal);
169
static ptid_t go32_wait (ptid_t ptid,
170
                               struct target_waitstatus *status);
171
static void go32_fetch_registers (int regno);
172
static void store_register (int regno);
173
static void go32_store_registers (int regno);
174
static void go32_prepare_to_store (void);
175
static int go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
176
                             int write,
177
                             struct mem_attrib *attrib,
178
                             struct target_ops *target);
179
static void go32_files_info (struct target_ops *target);
180
static void go32_stop (void);
181
static void go32_kill_inferior (void);
182
static void go32_create_inferior (char *exec_file, char *args, char **env);
183
static void go32_mourn_inferior (void);
184
static int go32_can_run (void);
185
 
186
static struct target_ops go32_ops;
187
static void go32_terminal_init (void);
188
static void go32_terminal_inferior (void);
189
static void go32_terminal_ours (void);
190
 
191
#define r_ofs(x) (offsetof(TSS,x))
192
 
193
static struct
194
{
195
  size_t tss_ofs;
196
  size_t size;
197
}
198
regno_mapping[] =
199
{
200
  {r_ofs (tss_eax), 4}, /* normal registers, from a_tss */
201
  {r_ofs (tss_ecx), 4},
202
  {r_ofs (tss_edx), 4},
203
  {r_ofs (tss_ebx), 4},
204
  {r_ofs (tss_esp), 4},
205
  {r_ofs (tss_ebp), 4},
206
  {r_ofs (tss_esi), 4},
207
  {r_ofs (tss_edi), 4},
208
  {r_ofs (tss_eip), 4},
209
  {r_ofs (tss_eflags), 4},
210
  {r_ofs (tss_cs), 2},
211
  {r_ofs (tss_ss), 2},
212
  {r_ofs (tss_ds), 2},
213
  {r_ofs (tss_es), 2},
214
  {r_ofs (tss_fs), 2},
215
  {r_ofs (tss_gs), 2},
216
  {0, 10},               /* 8 FP registers, from npx.reg[] */
217
  {1, 10},
218
  {2, 10},
219
  {3, 10},
220
  {4, 10},
221
  {5, 10},
222
  {6, 10},
223
  {7, 10},
224
        /* The order of the next 7 registers must be consistent
225
           with their numbering in config/i386/tm-i386.h, which see.  */
226
  {0, 2},                /* control word, from npx */
227
  {4, 2},               /* status word, from npx */
228
  {8, 2},               /* tag word, from npx */
229
  {16, 2},              /* last FP exception CS from npx */
230
  {12, 4},              /* last FP exception EIP from npx */
231
  {24, 2},              /* last FP exception operand selector from npx */
232
  {20, 4},              /* last FP exception operand offset from npx */
233
  {18, 2}               /* last FP opcode from npx */
234
};
235
 
236
static struct
237
  {
238
    int go32_sig;
239
    enum target_signal gdb_sig;
240
  }
241
sig_map[] =
242
{
243
  {0, TARGET_SIGNAL_FPE},
244
  {1, TARGET_SIGNAL_TRAP},
245
  /* Exception 2 is triggered by the NMI.  DJGPP handles it as SIGILL,
246
     but I think SIGBUS is better, since the NMI is usually activated
247
     as a result of a memory parity check failure.  */
248
  {2, TARGET_SIGNAL_BUS},
249
  {3, TARGET_SIGNAL_TRAP},
250
  {4, TARGET_SIGNAL_FPE},
251
  {5, TARGET_SIGNAL_SEGV},
252
  {6, TARGET_SIGNAL_ILL},
253
  {7, TARGET_SIGNAL_EMT},       /* no-coprocessor exception */
254
  {8, TARGET_SIGNAL_SEGV},
255
  {9, TARGET_SIGNAL_SEGV},
256
  {10, TARGET_SIGNAL_BUS},
257
  {11, TARGET_SIGNAL_SEGV},
258
  {12, TARGET_SIGNAL_SEGV},
259
  {13, TARGET_SIGNAL_SEGV},
260
  {14, TARGET_SIGNAL_SEGV},
261
  {16, TARGET_SIGNAL_FPE},
262
  {17, TARGET_SIGNAL_BUS},
263
  {31, TARGET_SIGNAL_ILL},
264
  {0x1b, TARGET_SIGNAL_INT},
265
  {0x75, TARGET_SIGNAL_FPE},
266
  {0x78, TARGET_SIGNAL_ALRM},
267
  {0x79, TARGET_SIGNAL_INT},
268
  {0x7a, TARGET_SIGNAL_QUIT},
269
  {-1, TARGET_SIGNAL_LAST}
270
};
271
 
272
static struct {
273
  enum target_signal gdb_sig;
274
  int djgpp_excepno;
275
} excepn_map[] = {
276
  {TARGET_SIGNAL_0, -1},
277
  {TARGET_SIGNAL_ILL, 6},       /* Invalid Opcode */
278
  {TARGET_SIGNAL_EMT, 7},       /* triggers SIGNOFP */
279
  {TARGET_SIGNAL_SEGV, 13},     /* GPF */
280
  {TARGET_SIGNAL_BUS, 17},      /* Alignment Check */
281
  /* The rest are fake exceptions, see dpmiexcp.c in djlsr*.zip for
282
     details.  */
283
  {TARGET_SIGNAL_TERM, 0x1b},   /* triggers Ctrl-Break type of SIGINT */
284
  {TARGET_SIGNAL_FPE, 0x75},
285
  {TARGET_SIGNAL_INT, 0x79},
286
  {TARGET_SIGNAL_QUIT, 0x7a},
287
  {TARGET_SIGNAL_ALRM, 0x78},   /* triggers SIGTIMR */
288
  {TARGET_SIGNAL_PROF, 0x78},
289
  {TARGET_SIGNAL_LAST, -1}
290
};
291
 
292
static void
293
go32_open (char *name, int from_tty)
294
{
295
  printf_unfiltered ("Done.  Use the \"run\" command to run the program.\n");
296
}
297
 
298
static void
299
go32_close (int quitting)
300
{
301
}
302
 
303
static void
304
go32_attach (char *args, int from_tty)
305
{
306
  error ("\
307
You cannot attach to a running program on this platform.\n\
308
Use the `run' command to run DJGPP programs.");
309
}
310
 
311
static void
312
go32_detach (char *args, int from_tty)
313
{
314
}
315
 
316
static int resume_is_step;
317
static int resume_signal = -1;
318
 
319
static void
320
go32_resume (ptid_t ptid, int step, enum target_signal siggnal)
321
{
322
  int i;
323
 
324
  resume_is_step = step;
325
 
326
  if (siggnal != TARGET_SIGNAL_0 && siggnal != TARGET_SIGNAL_TRAP)
327
  {
328
    for (i = 0, resume_signal = -1;
329
         excepn_map[i].gdb_sig != TARGET_SIGNAL_LAST; i++)
330
      if (excepn_map[i].gdb_sig == siggnal)
331
      {
332
        resume_signal = excepn_map[i].djgpp_excepno;
333
        break;
334
      }
335
    if (resume_signal == -1)
336
      printf_unfiltered ("Cannot deliver signal %s on this platform.\n",
337
                         target_signal_to_name (siggnal));
338
  }
339
}
340
 
341
static char child_cwd[FILENAME_MAX];
342
 
343
static ptid_t
344
go32_wait (ptid_t ptid, struct target_waitstatus *status)
345
{
346
  int i;
347
  unsigned char saved_opcode;
348
  unsigned long INT3_addr = 0;
349
  int stepping_over_INT = 0;
350
 
351
  a_tss.tss_eflags &= 0xfeff;   /* reset the single-step flag (TF) */
352
  if (resume_is_step)
353
    {
354
      /* If the next instruction is INT xx or INTO, we need to handle
355
         them specially.  Intel manuals say that these instructions
356
         reset the single-step flag (a.k.a. TF).  However, it seems
357
         that, at least in the DPMI environment, and at least when
358
         stepping over the DPMI interrupt 31h, the problem is having
359
         TF set at all when INT 31h is executed: the debuggee either
360
         crashes (and takes the system with it) or is killed by a
361
         SIGTRAP.
362
 
363
         So we need to emulate single-step mode: we put an INT3 opcode
364
         right after the INT xx instruction, let the debuggee run
365
         until it hits INT3 and stops, then restore the original
366
         instruction which we overwrote with the INT3 opcode, and back
367
         up the debuggee's EIP to that instruction.  */
368
      read_child (a_tss.tss_eip, &saved_opcode, 1);
369
      if (saved_opcode == 0xCD || saved_opcode == 0xCE)
370
        {
371
          unsigned char INT3_opcode = 0xCC;
372
 
373
          INT3_addr
374
            = saved_opcode == 0xCD ? a_tss.tss_eip + 2 : a_tss.tss_eip + 1;
375
          stepping_over_INT = 1;
376
          read_child (INT3_addr, &saved_opcode, 1);
377
          write_child (INT3_addr, &INT3_opcode, 1);
378
        }
379
      else
380
        a_tss.tss_eflags |= 0x0100; /* normal instruction: set TF */
381
    }
382
 
383
  /* The special value FFFFh in tss_trap indicates to run_child that
384
     tss_irqn holds a signal to be delivered to the debuggee.  */
385
  if (resume_signal <= -1)
386
    {
387
      a_tss.tss_trap = 0;
388
      a_tss.tss_irqn = 0xff;
389
    }
390
  else
391
    {
392
      a_tss.tss_trap = 0xffff;  /* run_child looks for this */
393
      a_tss.tss_irqn = resume_signal;
394
    }
395
 
396
  /* The child might change working directory behind our back.  The
397
     GDB users won't like the side effects of that when they work with
398
     relative file names, and GDB might be confused by its current
399
     directory not being in sync with the truth.  So we always make a
400
     point of changing back to where GDB thinks is its cwd, when we
401
     return control to the debugger, but restore child's cwd before we
402
     run it.  */
403
  /* Initialize child_cwd, before the first call to run_child and not
404
     in the initialization, so the child get also the changed directory
405
     set with the gdb-command "cd ..." */
406
  if (!*child_cwd)
407
    /* Initialize child's cwd with the current one.  */
408
    getcwd (child_cwd, sizeof (child_cwd));
409
 
410
  chdir (child_cwd);
411
 
412
#if __DJGPP_MINOR__ < 3
413
  load_npx ();
414
#endif
415
  run_child ();
416
#if __DJGPP_MINOR__ < 3
417
  save_npx ();
418
#endif
419
 
420
  /* Did we step over an INT xx instruction?  */
421
  if (stepping_over_INT && a_tss.tss_eip == INT3_addr + 1)
422
    {
423
      /* Restore the original opcode.  */
424
      a_tss.tss_eip--;  /* EIP points *after* the INT3 instruction */
425
      write_child (a_tss.tss_eip, &saved_opcode, 1);
426
      /* Simulate a TRAP exception.  */
427
      a_tss.tss_irqn = 1;
428
      a_tss.tss_eflags |= 0x0100;
429
    }
430
 
431
  getcwd (child_cwd, sizeof (child_cwd)); /* in case it has changed */
432
  chdir (current_directory);
433
 
434
  if (a_tss.tss_irqn == 0x21)
435
    {
436
      status->kind = TARGET_WAITKIND_EXITED;
437
      status->value.integer = a_tss.tss_eax & 0xff;
438
    }
439
  else
440
    {
441
      status->value.sig = TARGET_SIGNAL_UNKNOWN;
442
      status->kind = TARGET_WAITKIND_STOPPED;
443
      for (i = 0; sig_map[i].go32_sig != -1; i++)
444
        {
445
          if (a_tss.tss_irqn == sig_map[i].go32_sig)
446
            {
447
#if __DJGPP_MINOR__ < 3
448
              if ((status->value.sig = sig_map[i].gdb_sig) !=
449
                  TARGET_SIGNAL_TRAP)
450
                status->kind = TARGET_WAITKIND_SIGNALLED;
451
#else
452
              status->value.sig = sig_map[i].gdb_sig;
453
#endif
454
              break;
455
            }
456
        }
457
    }
458
  return pid_to_ptid (SOME_PID);
459
}
460
 
461
static void
462
fetch_register (int regno)
463
{
464
  if (regno < FP0_REGNUM)
465
    supply_register (regno, (char *) &a_tss + regno_mapping[regno].tss_ofs);
466
  else if (regno <= LAST_FPU_CTRL_REGNUM)
467
    i387_supply_register (regno, (char *) &npx);
468
  else
469
    internal_error (__FILE__, __LINE__,
470
                    "Invalid register no. %d in fetch_register.", regno);
471
}
472
 
473
static void
474
go32_fetch_registers (int regno)
475
{
476
  if (regno >= 0)
477
    fetch_register (regno);
478
  else
479
    {
480
      for (regno = 0; regno < FP0_REGNUM; regno++)
481
        fetch_register (regno);
482
      i387_supply_fsave ((char *) &npx);
483
    }
484
}
485
 
486
static void
487
store_register (int regno)
488
{
489
  void *rp;
490
  void *v = (void *) register_buffer (regno);
491
 
492
  if (regno < FP0_REGNUM)
493
    memcpy ((char *) &a_tss + regno_mapping[regno].tss_ofs,
494
            v, regno_mapping[regno].size);
495
  else if (regno <= LAST_FPU_CTRL_REGNUM)
496
    i387_fill_fsave ((char *)&npx, regno);
497
  else
498
    internal_error (__FILE__, __LINE__,
499
                    "Invalid register no. %d in store_register.", regno);
500
}
501
 
502
static void
503
go32_store_registers (int regno)
504
{
505
  unsigned r;
506
 
507
  if (regno >= 0)
508
    store_register (regno);
509
  else
510
    {
511
      for (r = 0; r < FP0_REGNUM; r++)
512
        store_register (r);
513
      i387_fill_fsave ((char *) &npx, -1);
514
    }
515
}
516
 
517
static void
518
go32_prepare_to_store (void)
519
{
520
}
521
 
522
static int
523
go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
524
                  struct mem_attrib *attrib, struct target_ops *target)
525
{
526
  if (write)
527
    {
528
      if (write_child (memaddr, myaddr, len))
529
        {
530
          return 0;
531
        }
532
      else
533
        {
534
          return len;
535
        }
536
    }
537
  else
538
    {
539
      if (read_child (memaddr, myaddr, len))
540
        {
541
          return 0;
542
        }
543
      else
544
        {
545
          return len;
546
        }
547
    }
548
}
549
 
550
static cmdline_t child_cmd;     /* parsed child's command line kept here */
551
 
552
static void
553
go32_files_info (struct target_ops *target)
554
{
555
  printf_unfiltered ("You are running a DJGPP V2 program.\n");
556
}
557
 
558
static void
559
go32_stop (void)
560
{
561
  normal_stop ();
562
  cleanup_client ();
563
  inferior_ptid = null_ptid;
564
  prog_has_started = 0;
565
}
566
 
567
static void
568
go32_kill_inferior (void)
569
{
570
  redir_cmdline_delete (&child_cmd);
571
  resume_signal = -1;
572
  resume_is_step = 0;
573
  unpush_target (&go32_ops);
574
}
575
 
576
static void
577
go32_create_inferior (char *exec_file, char *args, char **env)
578
{
579
  extern char **environ;
580
  jmp_buf start_state;
581
  char *cmdline;
582
  char **env_save = environ;
583
 
584
  /* If no exec file handed to us, get it from the exec-file command -- with
585
     a good, common error message if none is specified.  */
586
  if (exec_file == 0)
587
    exec_file = get_exec_file (1);
588
 
589
  if (prog_has_started)
590
    {
591
      go32_stop ();
592
      go32_kill_inferior ();
593
    }
594
  resume_signal = -1;
595
  resume_is_step = 0;
596
 
597
  /* Initialize child's cwd as empty to be initialized when starting
598
     the child.  */
599
  *child_cwd = 0;
600
 
601
  /* Init command line storage.  */
602
  if (redir_debug_init (&child_cmd) == -1)
603
    internal_error (__FILE__, __LINE__,
604
                    "Cannot allocate redirection storage: not enough memory.\n");
605
 
606
  /* Parse the command line and create redirections.  */
607
  if (strpbrk (args, "<>"))
608
    {
609
      if (redir_cmdline_parse (args, &child_cmd) == 0)
610
        args = child_cmd.command;
611
      else
612
        error ("Syntax error in command line.");
613
    }
614
  else
615
    child_cmd.command = xstrdup (args);
616
 
617
  cmdline = (char *) alloca (strlen (args) + 4);
618
  cmdline[0] = strlen (args);
619
  strcpy (cmdline + 1, args);
620
  cmdline[strlen (args) + 1] = 13;
621
 
622
  environ = env;
623
 
624
  if (v2loadimage (exec_file, cmdline, start_state))
625
    {
626
      environ = env_save;
627
      printf_unfiltered ("Load failed for image %s\n", exec_file);
628
      exit (1);
629
    }
630
  environ = env_save;
631
 
632
  edi_init (start_state);
633
#if __DJGPP_MINOR__ < 3
634
  save_npx ();
635
#endif
636
 
637
  inferior_ptid = pid_to_ptid (SOME_PID);
638
  push_target (&go32_ops);
639
  clear_proceed_status ();
640
  insert_breakpoints ();
641
  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
642
  prog_has_started = 1;
643
}
644
 
645
static void
646
go32_mourn_inferior (void)
647
{
648
  /* We need to make sure all the breakpoint enable bits in the DR7
649
     register are reset when the inferior exits.  Otherwise, if they
650
     rerun the inferior, the uncleared bits may cause random SIGTRAPs,
651
     failure to set more watchpoints, and other calamities.  It would
652
     be nice if GDB itself would take care to remove all breakpoints
653
     at all times, but it doesn't, probably under an assumption that
654
     the OS cleans up when the debuggee exits.  */
655
  i386_cleanup_dregs ();
656
  go32_kill_inferior ();
657
  generic_mourn_inferior ();
658
}
659
 
660
static int
661
go32_can_run (void)
662
{
663
  return 1;
664
}
665
 
666
/* Hardware watchpoint support.  */
667
 
668
#define D_REGS edi.dr
669
#define CONTROL D_REGS[7]
670
#define STATUS D_REGS[6]
671
 
672
/* Pass the address ADDR to the inferior in the I'th debug register.
673
   Here we just store the address in D_REGS, the watchpoint will be
674
   actually set up when go32_wait runs the debuggee.  */
675
void
676
go32_set_dr (int i, CORE_ADDR addr)
677
{
678
  if (i < 0 || i > 3)
679
    internal_error (__FILE__, __LINE__,
680
                    "Invalid register %d in go32_set_dr.\n", i);
681
  D_REGS[i] = addr;
682
}
683
 
684
/* Pass the value VAL to the inferior in the DR7 debug control
685
   register.  Here we just store the address in D_REGS, the watchpoint
686
   will be actually set up when go32_wait runs the debuggee.  */
687
void
688
go32_set_dr7 (unsigned val)
689
{
690
  CONTROL = val;
691
}
692
 
693
/* Get the value of the DR6 debug status register from the inferior.
694
   Here we just return the value stored in D_REGS, as we've got it
695
   from the last go32_wait call.  */
696
unsigned
697
go32_get_dr6 (void)
698
{
699
  return STATUS;
700
}
701
 
702
/* Put the device open on handle FD into either raw or cooked
703
   mode, return 1 if it was in raw mode, zero otherwise.  */
704
 
705
static int
706
device_mode (int fd, int raw_p)
707
{
708
  int oldmode, newmode;
709
  __dpmi_regs regs;
710
 
711
  regs.x.ax = 0x4400;
712
  regs.x.bx = fd;
713
  __dpmi_int (0x21, &regs);
714
  if (regs.x.flags & 1)
715
    return -1;
716
  newmode = oldmode = regs.x.dx;
717
 
718
  if (raw_p)
719
    newmode |= 0x20;
720
  else
721
    newmode &= ~0x20;
722
 
723
  if (oldmode & 0x80)   /* Only for character dev */
724
  {
725
    regs.x.ax = 0x4401;
726
    regs.x.bx = fd;
727
    regs.x.dx = newmode & 0xff;   /* Force upper byte zero, else it fails */
728
    __dpmi_int (0x21, &regs);
729
    if (regs.x.flags & 1)
730
      return -1;
731
  }
732
  return (oldmode & 0x20) == 0x20;
733
}
734
 
735
 
736
static int inf_mode_valid = 0;
737
static int inf_terminal_mode;
738
 
739
/* This semaphore is needed because, amazingly enough, GDB calls
740
   target.to_terminal_ours more than once after the inferior stops.
741
   But we need the information from the first call only, since the
742
   second call will always see GDB's own cooked terminal.  */
743
static int terminal_is_ours = 1;
744
 
745
static void
746
go32_terminal_init (void)
747
{
748
  inf_mode_valid = 0;    /* reinitialize, in case they are restarting child */
749
  terminal_is_ours = 1;
750
}
751
 
752
static void
753
go32_terminal_info (char *args, int from_tty)
754
{
755
  printf_unfiltered ("Inferior's terminal is in %s mode.\n",
756
                     !inf_mode_valid
757
                     ? "default" : inf_terminal_mode ? "raw" : "cooked");
758
 
759
#if __DJGPP_MINOR__ > 2
760
  if (child_cmd.redirection)
761
  {
762
    int i;
763
 
764
    for (i = 0; i < DBG_HANDLES; i++)
765
    {
766
      if (child_cmd.redirection[i]->file_name)
767
        printf_unfiltered ("\tFile handle %d is redirected to `%s'.\n",
768
                           i, child_cmd.redirection[i]->file_name);
769
      else if (_get_dev_info (child_cmd.redirection[i]->inf_handle) == -1)
770
        printf_unfiltered
771
          ("\tFile handle %d appears to be closed by inferior.\n", i);
772
      /* Mask off the raw/cooked bit when comparing device info words.  */
773
      else if ((_get_dev_info (child_cmd.redirection[i]->inf_handle) & 0xdf)
774
               != (_get_dev_info (i) & 0xdf))
775
        printf_unfiltered
776
          ("\tFile handle %d appears to be redirected by inferior.\n", i);
777
    }
778
  }
779
#endif
780
}
781
 
782
static void
783
go32_terminal_inferior (void)
784
{
785
  /* Redirect standard handles as child wants them.  */
786
  errno = 0;
787
  if (redir_to_child (&child_cmd) == -1)
788
  {
789
    redir_to_debugger (&child_cmd);
790
    error ("Cannot redirect standard handles for program: %s.",
791
           strerror (errno));
792
  }
793
  /* set the console device of the inferior to whatever mode
794
     (raw or cooked) we found it last time */
795
  if (terminal_is_ours)
796
  {
797
    if (inf_mode_valid)
798
      device_mode (0, inf_terminal_mode);
799
    terminal_is_ours = 0;
800
  }
801
}
802
 
803
static void
804
go32_terminal_ours (void)
805
{
806
  /* Switch to cooked mode on the gdb terminal and save the inferior
807
     terminal mode to be restored when it is resumed */
808
  if (!terminal_is_ours)
809
  {
810
    inf_terminal_mode = device_mode (0, 0);
811
    if (inf_terminal_mode != -1)
812
      inf_mode_valid = 1;
813
    else
814
      /* If device_mode returned -1, we don't know what happens with
815
         handle 0 anymore, so make the info invalid.  */
816
      inf_mode_valid = 0;
817
    terminal_is_ours = 1;
818
 
819
    /* Restore debugger's standard handles.  */
820
    errno = 0;
821
    if (redir_to_debugger (&child_cmd) == -1)
822
    {
823
      redir_to_child (&child_cmd);
824
      error ("Cannot redirect standard handles for debugger: %s.",
825
             strerror (errno));
826
    }
827
  }
828
}
829
 
830
static void
831
init_go32_ops (void)
832
{
833
  go32_ops.to_shortname = "djgpp";
834
  go32_ops.to_longname = "djgpp target process";
835
  go32_ops.to_doc =
836
    "Program loaded by djgpp, when gdb is used as an external debugger";
837
  go32_ops.to_open = go32_open;
838
  go32_ops.to_close = go32_close;
839
  go32_ops.to_attach = go32_attach;
840
  go32_ops.to_detach = go32_detach;
841
  go32_ops.to_resume = go32_resume;
842
  go32_ops.to_wait = go32_wait;
843
  go32_ops.to_fetch_registers = go32_fetch_registers;
844
  go32_ops.to_store_registers = go32_store_registers;
845
  go32_ops.to_prepare_to_store = go32_prepare_to_store;
846
  go32_ops.to_xfer_memory = go32_xfer_memory;
847
  go32_ops.to_files_info = go32_files_info;
848
  go32_ops.to_insert_breakpoint = memory_insert_breakpoint;
849
  go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
850
  go32_ops.to_terminal_init = go32_terminal_init;
851
  go32_ops.to_terminal_inferior = go32_terminal_inferior;
852
  go32_ops.to_terminal_ours_for_output = go32_terminal_ours;
853
  go32_ops.to_terminal_ours = go32_terminal_ours;
854
  go32_ops.to_terminal_info = go32_terminal_info;
855
  go32_ops.to_kill = go32_kill_inferior;
856
  go32_ops.to_create_inferior = go32_create_inferior;
857
  go32_ops.to_mourn_inferior = go32_mourn_inferior;
858
  go32_ops.to_can_run = go32_can_run;
859
  go32_ops.to_stop = go32_stop;
860
  go32_ops.to_stratum = process_stratum;
861
  go32_ops.to_has_all_memory = 1;
862
  go32_ops.to_has_memory = 1;
863
  go32_ops.to_has_stack = 1;
864
  go32_ops.to_has_registers = 1;
865
  go32_ops.to_has_execution = 1;
866
  go32_ops.to_magic = OPS_MAGIC;
867
 
868
  /* Initialize child's cwd as empty to be initialized when starting
869
     the child.  */
870
  *child_cwd = 0;
871
 
872
  /* Initialize child's command line storage.  */
873
  if (redir_debug_init (&child_cmd) == -1)
874
    internal_error (__FILE__, __LINE__,
875
                    "Cannot allocate redirection storage: not enough memory.\n");
876
 
877
  /* We are always processing GCC-compiled programs.  */
878
  processing_gcc_compilation = 2;
879
}
880
 
881
void
882
_initialize_go32_nat (void)
883
{
884
  init_go32_ops ();
885
  add_target (&go32_ops);
886
}
887
 
888
pid_t
889
tcgetpgrp (int fd)
890
{
891
  if (isatty (fd))
892
    return SOME_PID;
893
  errno = ENOTTY;
894
  return -1;
895
}
896
 
897
int
898
tcsetpgrp (int fd, pid_t pgid)
899
{
900
  if (isatty (fd) && pgid == SOME_PID)
901
    return 0;
902
  errno = pgid == SOME_PID ? ENOTTY : ENOSYS;
903
  return -1;
904
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.