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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [gdb/] [go32-nat.c] - Blame information for rev 363

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* Native debugging support for Intel x86 running DJGPP.
2
   Copyright (C) 1997, 1999, 2000, 2001, 2005, 2006, 2007, 2008
3
   Free Software Foundation, Inc.
4
   Written by Robert Hoehne.
5
 
6
   This file is part of GDB.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
 
21
#include <fcntl.h>
22
 
23
#include "defs.h"
24
#include "inferior.h"
25
#include "gdb_wait.h"
26
#include "gdbcore.h"
27
#include "command.h"
28
#include "gdbcmd.h"
29
#include "floatformat.h"
30
#include "buildsym.h"
31
#include "i387-tdep.h"
32
#include "i386-tdep.h"
33
#include "value.h"
34
#include "regcache.h"
35
#include "gdb_string.h"
36
#include "top.h"
37
 
38
#include <stdio.h>              /* might be required for __DJGPP_MINOR__ */
39
#include <stdlib.h>
40
#include <ctype.h>
41
#include <errno.h>
42
#include <unistd.h>
43
#include <sys/utsname.h>
44
#include <io.h>
45
#include <dos.h>
46
#include <dpmi.h>
47
#include <go32.h>
48
#include <sys/farptr.h>
49
#include <debug/v2load.h>
50
#include <debug/dbgcom.h>
51
#if __DJGPP_MINOR__ > 2
52
#include <debug/redir.h>
53
#endif
54
 
55
#if __DJGPP_MINOR__ < 3
56
/* This code will be provided from DJGPP 2.03 on. Until then I code it
57
   here */
58
typedef struct
59
  {
60
    unsigned short sig0;
61
    unsigned short sig1;
62
    unsigned short sig2;
63
    unsigned short sig3;
64
    unsigned short exponent:15;
65
    unsigned short sign:1;
66
  }
67
NPXREG;
68
 
69
typedef struct
70
  {
71
    unsigned int control;
72
    unsigned int status;
73
    unsigned int tag;
74
    unsigned int eip;
75
    unsigned int cs;
76
    unsigned int dataptr;
77
    unsigned int datasel;
78
    NPXREG reg[8];
79
  }
80
NPX;
81
 
82
static NPX npx;
83
 
84
static void save_npx (void);    /* Save the FPU of the debugged program */
85
static void load_npx (void);    /* Restore the FPU of the debugged program */
86
 
87
/* ------------------------------------------------------------------------- */
88
/* Store the contents of the NPX in the global variable `npx'.  */
89
/* *INDENT-OFF* */
90
 
91
static void
92
save_npx (void)
93
{
94
  asm ("inb    $0xa0, %%al  \n\
95
       testb $0x20, %%al    \n\
96
       jz 1f                \n\
97
       xorb %%al, %%al      \n\
98
       outb %%al, $0xf0     \n\
99
       movb $0x20, %%al     \n\
100
       outb %%al, $0xa0     \n\
101
       outb %%al, $0x20     \n\
102
1:                          \n\
103
       fnsave %0            \n\
104
       fwait "
105
:     "=m" (npx)
106
:                               /* No input */
107
:     "%eax");
108
}
109
 
110
/* *INDENT-ON* */
111
 
112
 
113
/* ------------------------------------------------------------------------- */
114
/* Reload the contents of the NPX from the global variable `npx'.  */
115
 
116
static void
117
load_npx (void)
118
{
119
  asm ("frstor %0":"=m" (npx));
120
}
121
/* ------------------------------------------------------------------------- */
122
/* Stubs for the missing redirection functions.  */
123
typedef struct {
124
  char *command;
125
  int redirected;
126
} cmdline_t;
127
 
128
void
129
redir_cmdline_delete (cmdline_t *ptr)
130
{
131
  ptr->redirected = 0;
132
}
133
 
134
int
135
redir_cmdline_parse (const char *args, cmdline_t *ptr)
136
{
137
  return -1;
138
}
139
 
140
int
141
redir_to_child (cmdline_t *ptr)
142
{
143
  return 1;
144
}
145
 
146
int
147
redir_to_debugger (cmdline_t *ptr)
148
{
149
  return 1;
150
}
151
 
152
int
153
redir_debug_init (cmdline_t *ptr)
154
{
155
  return 0;
156
}
157
#endif /* __DJGPP_MINOR < 3 */
158
 
159
typedef enum { wp_insert, wp_remove, wp_count } wp_op;
160
 
161
/* This holds the current reference counts for each debug register.  */
162
static int dr_ref_count[4];
163
 
164
#define SOME_PID 42
165
 
166
static int prog_has_started = 0;
167
static void go32_open (char *name, int from_tty);
168
static void go32_close (int quitting);
169
static void go32_attach (char *args, int from_tty);
170
static void go32_detach (char *args, int from_tty);
171
static void go32_resume (ptid_t ptid, int step,
172
                         enum target_signal siggnal);
173
static ptid_t go32_wait (ptid_t ptid,
174
                               struct target_waitstatus *status);
175
static void go32_fetch_registers (struct regcache *, int regno);
176
static void store_register (const struct regcache *, int regno);
177
static void go32_store_registers (struct regcache *, int regno);
178
static void go32_prepare_to_store (struct regcache *);
179
static int go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
180
                             int write,
181
                             struct mem_attrib *attrib,
182
                             struct target_ops *target);
183
static void go32_files_info (struct target_ops *target);
184
static void go32_stop (void);
185
static void go32_kill_inferior (void);
186
static void go32_create_inferior (char *exec_file, char *args, char **env, int from_tty);
187
static void go32_mourn_inferior (void);
188
static int go32_can_run (void);
189
 
190
static struct target_ops go32_ops;
191
static void go32_terminal_init (void);
192
static void go32_terminal_inferior (void);
193
static void go32_terminal_ours (void);
194
 
195
#define r_ofs(x) (offsetof(TSS,x))
196
 
197
static struct
198
{
199
  size_t tss_ofs;
200
  size_t size;
201
}
202
regno_mapping[] =
203
{
204
  {r_ofs (tss_eax), 4}, /* normal registers, from a_tss */
205
  {r_ofs (tss_ecx), 4},
206
  {r_ofs (tss_edx), 4},
207
  {r_ofs (tss_ebx), 4},
208
  {r_ofs (tss_esp), 4},
209
  {r_ofs (tss_ebp), 4},
210
  {r_ofs (tss_esi), 4},
211
  {r_ofs (tss_edi), 4},
212
  {r_ofs (tss_eip), 4},
213
  {r_ofs (tss_eflags), 4},
214
  {r_ofs (tss_cs), 2},
215
  {r_ofs (tss_ss), 2},
216
  {r_ofs (tss_ds), 2},
217
  {r_ofs (tss_es), 2},
218
  {r_ofs (tss_fs), 2},
219
  {r_ofs (tss_gs), 2},
220
  {0, 10},               /* 8 FP registers, from npx.reg[] */
221
  {1, 10},
222
  {2, 10},
223
  {3, 10},
224
  {4, 10},
225
  {5, 10},
226
  {6, 10},
227
  {7, 10},
228
        /* The order of the next 7 registers must be consistent
229
           with their numbering in config/i386/tm-i386.h, which see.  */
230
  {0, 2},                /* control word, from npx */
231
  {4, 2},               /* status word, from npx */
232
  {8, 2},               /* tag word, from npx */
233
  {16, 2},              /* last FP exception CS from npx */
234
  {12, 4},              /* last FP exception EIP from npx */
235
  {24, 2},              /* last FP exception operand selector from npx */
236
  {20, 4},              /* last FP exception operand offset from npx */
237
  {18, 2}               /* last FP opcode from npx */
238
};
239
 
240
static struct
241
  {
242
    int go32_sig;
243
    enum target_signal gdb_sig;
244
  }
245
sig_map[] =
246
{
247
  {0, TARGET_SIGNAL_FPE},
248
  {1, TARGET_SIGNAL_TRAP},
249
  /* Exception 2 is triggered by the NMI.  DJGPP handles it as SIGILL,
250
     but I think SIGBUS is better, since the NMI is usually activated
251
     as a result of a memory parity check failure.  */
252
  {2, TARGET_SIGNAL_BUS},
253
  {3, TARGET_SIGNAL_TRAP},
254
  {4, TARGET_SIGNAL_FPE},
255
  {5, TARGET_SIGNAL_SEGV},
256
  {6, TARGET_SIGNAL_ILL},
257
  {7, TARGET_SIGNAL_EMT},       /* no-coprocessor exception */
258
  {8, TARGET_SIGNAL_SEGV},
259
  {9, TARGET_SIGNAL_SEGV},
260
  {10, TARGET_SIGNAL_BUS},
261
  {11, TARGET_SIGNAL_SEGV},
262
  {12, TARGET_SIGNAL_SEGV},
263
  {13, TARGET_SIGNAL_SEGV},
264
  {14, TARGET_SIGNAL_SEGV},
265
  {16, TARGET_SIGNAL_FPE},
266
  {17, TARGET_SIGNAL_BUS},
267
  {31, TARGET_SIGNAL_ILL},
268
  {0x1b, TARGET_SIGNAL_INT},
269
  {0x75, TARGET_SIGNAL_FPE},
270
  {0x78, TARGET_SIGNAL_ALRM},
271
  {0x79, TARGET_SIGNAL_INT},
272
  {0x7a, TARGET_SIGNAL_QUIT},
273
  {-1, TARGET_SIGNAL_LAST}
274
};
275
 
276
static struct {
277
  enum target_signal gdb_sig;
278
  int djgpp_excepno;
279
} excepn_map[] = {
280
  {TARGET_SIGNAL_0, -1},
281
  {TARGET_SIGNAL_ILL, 6},       /* Invalid Opcode */
282
  {TARGET_SIGNAL_EMT, 7},       /* triggers SIGNOFP */
283
  {TARGET_SIGNAL_SEGV, 13},     /* GPF */
284
  {TARGET_SIGNAL_BUS, 17},      /* Alignment Check */
285
  /* The rest are fake exceptions, see dpmiexcp.c in djlsr*.zip for
286
     details.  */
287
  {TARGET_SIGNAL_TERM, 0x1b},   /* triggers Ctrl-Break type of SIGINT */
288
  {TARGET_SIGNAL_FPE, 0x75},
289
  {TARGET_SIGNAL_INT, 0x79},
290
  {TARGET_SIGNAL_QUIT, 0x7a},
291
  {TARGET_SIGNAL_ALRM, 0x78},   /* triggers SIGTIMR */
292
  {TARGET_SIGNAL_PROF, 0x78},
293
  {TARGET_SIGNAL_LAST, -1}
294
};
295
 
296
static void
297
go32_open (char *name, int from_tty)
298
{
299
  printf_unfiltered ("Done.  Use the \"run\" command to run the program.\n");
300
}
301
 
302
static void
303
go32_close (int quitting)
304
{
305
}
306
 
307
static void
308
go32_attach (char *args, int from_tty)
309
{
310
  error (_("\
311
You cannot attach to a running program on this platform.\n\
312
Use the `run' command to run DJGPP programs."));
313
}
314
 
315
static void
316
go32_detach (char *args, int from_tty)
317
{
318
}
319
 
320
static int resume_is_step;
321
static int resume_signal = -1;
322
 
323
static void
324
go32_resume (ptid_t ptid, int step, enum target_signal siggnal)
325
{
326
  int i;
327
 
328
  resume_is_step = step;
329
 
330
  if (siggnal != TARGET_SIGNAL_0 && siggnal != TARGET_SIGNAL_TRAP)
331
  {
332
    for (i = 0, resume_signal = -1;
333
         excepn_map[i].gdb_sig != TARGET_SIGNAL_LAST; i++)
334
      if (excepn_map[i].gdb_sig == siggnal)
335
      {
336
        resume_signal = excepn_map[i].djgpp_excepno;
337
        break;
338
      }
339
    if (resume_signal == -1)
340
      printf_unfiltered ("Cannot deliver signal %s on this platform.\n",
341
                         target_signal_to_name (siggnal));
342
  }
343
}
344
 
345
static char child_cwd[FILENAME_MAX];
346
 
347
static ptid_t
348
go32_wait (ptid_t ptid, struct target_waitstatus *status)
349
{
350
  int i;
351
  unsigned char saved_opcode;
352
  unsigned long INT3_addr = 0;
353
  int stepping_over_INT = 0;
354
 
355
  a_tss.tss_eflags &= 0xfeff;   /* reset the single-step flag (TF) */
356
  if (resume_is_step)
357
    {
358
      /* If the next instruction is INT xx or INTO, we need to handle
359
         them specially.  Intel manuals say that these instructions
360
         reset the single-step flag (a.k.a. TF).  However, it seems
361
         that, at least in the DPMI environment, and at least when
362
         stepping over the DPMI interrupt 31h, the problem is having
363
         TF set at all when INT 31h is executed: the debuggee either
364
         crashes (and takes the system with it) or is killed by a
365
         SIGTRAP.
366
 
367
         So we need to emulate single-step mode: we put an INT3 opcode
368
         right after the INT xx instruction, let the debuggee run
369
         until it hits INT3 and stops, then restore the original
370
         instruction which we overwrote with the INT3 opcode, and back
371
         up the debuggee's EIP to that instruction.  */
372
      read_child (a_tss.tss_eip, &saved_opcode, 1);
373
      if (saved_opcode == 0xCD || saved_opcode == 0xCE)
374
        {
375
          unsigned char INT3_opcode = 0xCC;
376
 
377
          INT3_addr
378
            = saved_opcode == 0xCD ? a_tss.tss_eip + 2 : a_tss.tss_eip + 1;
379
          stepping_over_INT = 1;
380
          read_child (INT3_addr, &saved_opcode, 1);
381
          write_child (INT3_addr, &INT3_opcode, 1);
382
        }
383
      else
384
        a_tss.tss_eflags |= 0x0100; /* normal instruction: set TF */
385
    }
386
 
387
  /* The special value FFFFh in tss_trap indicates to run_child that
388
     tss_irqn holds a signal to be delivered to the debuggee.  */
389
  if (resume_signal <= -1)
390
    {
391
      a_tss.tss_trap = 0;
392
      a_tss.tss_irqn = 0xff;
393
    }
394
  else
395
    {
396
      a_tss.tss_trap = 0xffff;  /* run_child looks for this */
397
      a_tss.tss_irqn = resume_signal;
398
    }
399
 
400
  /* The child might change working directory behind our back.  The
401
     GDB users won't like the side effects of that when they work with
402
     relative file names, and GDB might be confused by its current
403
     directory not being in sync with the truth.  So we always make a
404
     point of changing back to where GDB thinks is its cwd, when we
405
     return control to the debugger, but restore child's cwd before we
406
     run it.  */
407
  /* Initialize child_cwd, before the first call to run_child and not
408
     in the initialization, so the child get also the changed directory
409
     set with the gdb-command "cd ..." */
410
  if (!*child_cwd)
411
    /* Initialize child's cwd with the current one.  */
412
    getcwd (child_cwd, sizeof (child_cwd));
413
 
414
  chdir (child_cwd);
415
 
416
#if __DJGPP_MINOR__ < 3
417
  load_npx ();
418
#endif
419
  run_child ();
420
#if __DJGPP_MINOR__ < 3
421
  save_npx ();
422
#endif
423
 
424
  /* Did we step over an INT xx instruction?  */
425
  if (stepping_over_INT && a_tss.tss_eip == INT3_addr + 1)
426
    {
427
      /* Restore the original opcode.  */
428
      a_tss.tss_eip--;  /* EIP points *after* the INT3 instruction */
429
      write_child (a_tss.tss_eip, &saved_opcode, 1);
430
      /* Simulate a TRAP exception.  */
431
      a_tss.tss_irqn = 1;
432
      a_tss.tss_eflags |= 0x0100;
433
    }
434
 
435
  getcwd (child_cwd, sizeof (child_cwd)); /* in case it has changed */
436
  chdir (current_directory);
437
 
438
  if (a_tss.tss_irqn == 0x21)
439
    {
440
      status->kind = TARGET_WAITKIND_EXITED;
441
      status->value.integer = a_tss.tss_eax & 0xff;
442
    }
443
  else
444
    {
445
      status->value.sig = TARGET_SIGNAL_UNKNOWN;
446
      status->kind = TARGET_WAITKIND_STOPPED;
447
      for (i = 0; sig_map[i].go32_sig != -1; i++)
448
        {
449
          if (a_tss.tss_irqn == sig_map[i].go32_sig)
450
            {
451
#if __DJGPP_MINOR__ < 3
452
              if ((status->value.sig = sig_map[i].gdb_sig) !=
453
                  TARGET_SIGNAL_TRAP)
454
                status->kind = TARGET_WAITKIND_SIGNALLED;
455
#else
456
              status->value.sig = sig_map[i].gdb_sig;
457
#endif
458
              break;
459
            }
460
        }
461
    }
462
  return pid_to_ptid (SOME_PID);
463
}
464
 
465
static void
466
fetch_register (struct regcache *regcache, int regno)
467
{
468
  if (regno < gdbarch_fp0_regnum (get_regcache_arch (regcache)))
469
    regcache_raw_supply (regcache, regno,
470
                         (char *) &a_tss + regno_mapping[regno].tss_ofs);
471
  else if (i386_fp_regnum_p (regno) || i386_fpc_regnum_p (regno))
472
    i387_supply_fsave (regcache, regno, &npx);
473
  else
474
    internal_error (__FILE__, __LINE__,
475
                    _("Invalid register no. %d in fetch_register."), regno);
476
}
477
 
478
static void
479
go32_fetch_registers (struct regcache *regcache, int regno)
480
{
481
  if (regno >= 0)
482
    fetch_register (regcache, regno);
483
  else
484
    {
485
      for (regno = 0;
486
           regno < gdbarch_fp0_regnum (get_regcache_arch (regcache));
487
           regno++)
488
        fetch_register (regcache, regno);
489
      i387_supply_fsave (regcache, -1, &npx);
490
    }
491
}
492
 
493
static void
494
store_register (const struct regcache *regcache, int regno)
495
{
496
  if (regno < gdbarch_fp0_regnum (get_regcache_arch (regcache)))
497
    regcache_raw_collect (regcache, regno,
498
                          (char *) &a_tss + regno_mapping[regno].tss_ofs);
499
  else if (i386_fp_regnum_p (regno) || i386_fpc_regnum_p (regno))
500
    i387_collect_fsave (regcache, regno, &npx);
501
  else
502
    internal_error (__FILE__, __LINE__,
503
                    _("Invalid register no. %d in store_register."), regno);
504
}
505
 
506
static void
507
go32_store_registers (struct regcache *regcache, int regno)
508
{
509
  unsigned r;
510
 
511
  if (regno >= 0)
512
    store_register (regcache, regno);
513
  else
514
    {
515
      for (r = 0; r < gdbarch_fp0_regnum (get_regcache_arch (regcache)); r++)
516
        store_register (regcache, r);
517
      i387_collect_fsave (regcache, -1, &npx);
518
    }
519
}
520
 
521
static void
522
go32_prepare_to_store (struct regcache *regcache)
523
{
524
}
525
 
526
static int
527
go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
528
                  struct mem_attrib *attrib, struct target_ops *target)
529
{
530
  if (write)
531
    {
532
      if (write_child (memaddr, myaddr, len))
533
        {
534
          return 0;
535
        }
536
      else
537
        {
538
          return len;
539
        }
540
    }
541
  else
542
    {
543
      if (read_child (memaddr, myaddr, len))
544
        {
545
          return 0;
546
        }
547
      else
548
        {
549
          return len;
550
        }
551
    }
552
}
553
 
554
static cmdline_t child_cmd;     /* parsed child's command line kept here */
555
 
556
static void
557
go32_files_info (struct target_ops *target)
558
{
559
  printf_unfiltered ("You are running a DJGPP V2 program.\n");
560
}
561
 
562
static void
563
go32_stop (void)
564
{
565
  normal_stop ();
566
  cleanup_client ();
567
  inferior_ptid = null_ptid;
568
  prog_has_started = 0;
569
}
570
 
571
static void
572
go32_kill_inferior (void)
573
{
574
  redir_cmdline_delete (&child_cmd);
575
  resume_signal = -1;
576
  resume_is_step = 0;
577
  unpush_target (&go32_ops);
578
}
579
 
580
static void
581
go32_create_inferior (char *exec_file, char *args, char **env, int from_tty)
582
{
583
  extern char **environ;
584
  jmp_buf start_state;
585
  char *cmdline;
586
  char **env_save = environ;
587
  size_t cmdlen;
588
 
589
  /* If no exec file handed to us, get it from the exec-file command -- with
590
     a good, common error message if none is specified.  */
591
  if (exec_file == 0)
592
    exec_file = get_exec_file (1);
593
 
594
  if (prog_has_started)
595
    {
596
      go32_stop ();
597
      go32_kill_inferior ();
598
    }
599
  resume_signal = -1;
600
  resume_is_step = 0;
601
 
602
  /* Initialize child's cwd as empty to be initialized when starting
603
     the child.  */
604
  *child_cwd = 0;
605
 
606
  /* Init command line storage.  */
607
  if (redir_debug_init (&child_cmd) == -1)
608
    internal_error (__FILE__, __LINE__,
609
                    _("Cannot allocate redirection storage: not enough memory.\n"));
610
 
611
  /* Parse the command line and create redirections.  */
612
  if (strpbrk (args, "<>"))
613
    {
614
      if (redir_cmdline_parse (args, &child_cmd) == 0)
615
        args = child_cmd.command;
616
      else
617
        error (_("Syntax error in command line."));
618
    }
619
  else
620
    child_cmd.command = xstrdup (args);
621
 
622
  cmdlen = strlen (args);
623
  /* v2loadimage passes command lines via DOS memory, so it cannot
624
     possibly handle commands longer than 1MB.  */
625
  if (cmdlen > 1024*1024)
626
    error (_("Command line too long."));
627
 
628
  cmdline = xmalloc (cmdlen + 4);
629
  strcpy (cmdline + 1, args);
630
  /* If the command-line length fits into DOS 126-char limits, use the
631
     DOS command tail format; otherwise, tell v2loadimage to pass it
632
     through a buffer in conventional memory.  */
633
  if (cmdlen < 127)
634
    {
635
      cmdline[0] = strlen (args);
636
      cmdline[cmdlen + 1] = 13;
637
    }
638
  else
639
    cmdline[0] = 0xff;   /* signal v2loadimage it's a long command */
640
 
641
  environ = env;
642
 
643
  if (v2loadimage (exec_file, cmdline, start_state))
644
    {
645
      environ = env_save;
646
      printf_unfiltered ("Load failed for image %s\n", exec_file);
647
      exit (1);
648
    }
649
  environ = env_save;
650
  xfree (cmdline);
651
 
652
  edi_init (start_state);
653
#if __DJGPP_MINOR__ < 3
654
  save_npx ();
655
#endif
656
 
657
  inferior_ptid = pid_to_ptid (SOME_PID);
658
  push_target (&go32_ops);
659
  clear_proceed_status ();
660
  insert_breakpoints ();
661
  prog_has_started = 1;
662
}
663
 
664
static void
665
go32_mourn_inferior (void)
666
{
667
  /* We need to make sure all the breakpoint enable bits in the DR7
668
     register are reset when the inferior exits.  Otherwise, if they
669
     rerun the inferior, the uncleared bits may cause random SIGTRAPs,
670
     failure to set more watchpoints, and other calamities.  It would
671
     be nice if GDB itself would take care to remove all breakpoints
672
     at all times, but it doesn't, probably under an assumption that
673
     the OS cleans up when the debuggee exits.  */
674
  i386_cleanup_dregs ();
675
  go32_kill_inferior ();
676
  generic_mourn_inferior ();
677
}
678
 
679
static int
680
go32_can_run (void)
681
{
682
  return 1;
683
}
684
 
685
/* Hardware watchpoint support.  */
686
 
687
#define D_REGS edi.dr
688
#define CONTROL D_REGS[7]
689
#define STATUS D_REGS[6]
690
 
691
/* Pass the address ADDR to the inferior in the I'th debug register.
692
   Here we just store the address in D_REGS, the watchpoint will be
693
   actually set up when go32_wait runs the debuggee.  */
694
void
695
go32_set_dr (int i, CORE_ADDR addr)
696
{
697
  if (i < 0 || i > 3)
698
    internal_error (__FILE__, __LINE__,
699
                    _("Invalid register %d in go32_set_dr.\n"), i);
700
  D_REGS[i] = addr;
701
}
702
 
703
/* Pass the value VAL to the inferior in the DR7 debug control
704
   register.  Here we just store the address in D_REGS, the watchpoint
705
   will be actually set up when go32_wait runs the debuggee.  */
706
void
707
go32_set_dr7 (unsigned val)
708
{
709
  CONTROL = val;
710
}
711
 
712
/* Get the value of the DR6 debug status register from the inferior.
713
   Here we just return the value stored in D_REGS, as we've got it
714
   from the last go32_wait call.  */
715
unsigned
716
go32_get_dr6 (void)
717
{
718
  return STATUS;
719
}
720
 
721
/* Put the device open on handle FD into either raw or cooked
722
   mode, return 1 if it was in raw mode, zero otherwise.  */
723
 
724
static int
725
device_mode (int fd, int raw_p)
726
{
727
  int oldmode, newmode;
728
  __dpmi_regs regs;
729
 
730
  regs.x.ax = 0x4400;
731
  regs.x.bx = fd;
732
  __dpmi_int (0x21, &regs);
733
  if (regs.x.flags & 1)
734
    return -1;
735
  newmode = oldmode = regs.x.dx;
736
 
737
  if (raw_p)
738
    newmode |= 0x20;
739
  else
740
    newmode &= ~0x20;
741
 
742
  if (oldmode & 0x80)   /* Only for character dev */
743
  {
744
    regs.x.ax = 0x4401;
745
    regs.x.bx = fd;
746
    regs.x.dx = newmode & 0xff;   /* Force upper byte zero, else it fails */
747
    __dpmi_int (0x21, &regs);
748
    if (regs.x.flags & 1)
749
      return -1;
750
  }
751
  return (oldmode & 0x20) == 0x20;
752
}
753
 
754
 
755
static int inf_mode_valid = 0;
756
static int inf_terminal_mode;
757
 
758
/* This semaphore is needed because, amazingly enough, GDB calls
759
   target.to_terminal_ours more than once after the inferior stops.
760
   But we need the information from the first call only, since the
761
   second call will always see GDB's own cooked terminal.  */
762
static int terminal_is_ours = 1;
763
 
764
static void
765
go32_terminal_init (void)
766
{
767
  inf_mode_valid = 0;    /* reinitialize, in case they are restarting child */
768
  terminal_is_ours = 1;
769
}
770
 
771
static void
772
go32_terminal_info (char *args, int from_tty)
773
{
774
  printf_unfiltered ("Inferior's terminal is in %s mode.\n",
775
                     !inf_mode_valid
776
                     ? "default" : inf_terminal_mode ? "raw" : "cooked");
777
 
778
#if __DJGPP_MINOR__ > 2
779
  if (child_cmd.redirection)
780
  {
781
    int i;
782
 
783
    for (i = 0; i < DBG_HANDLES; i++)
784
    {
785
      if (child_cmd.redirection[i]->file_name)
786
        printf_unfiltered ("\tFile handle %d is redirected to `%s'.\n",
787
                           i, child_cmd.redirection[i]->file_name);
788
      else if (_get_dev_info (child_cmd.redirection[i]->inf_handle) == -1)
789
        printf_unfiltered
790
          ("\tFile handle %d appears to be closed by inferior.\n", i);
791
      /* Mask off the raw/cooked bit when comparing device info words.  */
792
      else if ((_get_dev_info (child_cmd.redirection[i]->inf_handle) & 0xdf)
793
               != (_get_dev_info (i) & 0xdf))
794
        printf_unfiltered
795
          ("\tFile handle %d appears to be redirected by inferior.\n", i);
796
    }
797
  }
798
#endif
799
}
800
 
801
static void
802
go32_terminal_inferior (void)
803
{
804
  /* Redirect standard handles as child wants them.  */
805
  errno = 0;
806
  if (redir_to_child (&child_cmd) == -1)
807
  {
808
    redir_to_debugger (&child_cmd);
809
    error (_("Cannot redirect standard handles for program: %s."),
810
           safe_strerror (errno));
811
  }
812
  /* set the console device of the inferior to whatever mode
813
     (raw or cooked) we found it last time */
814
  if (terminal_is_ours)
815
  {
816
    if (inf_mode_valid)
817
      device_mode (0, inf_terminal_mode);
818
    terminal_is_ours = 0;
819
  }
820
}
821
 
822
static void
823
go32_terminal_ours (void)
824
{
825
  /* Switch to cooked mode on the gdb terminal and save the inferior
826
     terminal mode to be restored when it is resumed */
827
  if (!terminal_is_ours)
828
  {
829
    inf_terminal_mode = device_mode (0, 0);
830
    if (inf_terminal_mode != -1)
831
      inf_mode_valid = 1;
832
    else
833
      /* If device_mode returned -1, we don't know what happens with
834
         handle 0 anymore, so make the info invalid.  */
835
      inf_mode_valid = 0;
836
    terminal_is_ours = 1;
837
 
838
    /* Restore debugger's standard handles.  */
839
    errno = 0;
840
    if (redir_to_debugger (&child_cmd) == -1)
841
    {
842
      redir_to_child (&child_cmd);
843
      error (_("Cannot redirect standard handles for debugger: %s."),
844
             safe_strerror (errno));
845
    }
846
  }
847
}
848
 
849
static void
850
init_go32_ops (void)
851
{
852
  go32_ops.to_shortname = "djgpp";
853
  go32_ops.to_longname = "djgpp target process";
854
  go32_ops.to_doc =
855
    "Program loaded by djgpp, when gdb is used as an external debugger";
856
  go32_ops.to_open = go32_open;
857
  go32_ops.to_close = go32_close;
858
  go32_ops.to_attach = go32_attach;
859
  go32_ops.to_detach = go32_detach;
860
  go32_ops.to_resume = go32_resume;
861
  go32_ops.to_wait = go32_wait;
862
  go32_ops.to_fetch_registers = go32_fetch_registers;
863
  go32_ops.to_store_registers = go32_store_registers;
864
  go32_ops.to_prepare_to_store = go32_prepare_to_store;
865
  go32_ops.deprecated_xfer_memory = go32_xfer_memory;
866
  go32_ops.to_files_info = go32_files_info;
867
  go32_ops.to_insert_breakpoint = memory_insert_breakpoint;
868
  go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
869
  go32_ops.to_terminal_init = go32_terminal_init;
870
  go32_ops.to_terminal_inferior = go32_terminal_inferior;
871
  go32_ops.to_terminal_ours_for_output = go32_terminal_ours;
872
  go32_ops.to_terminal_ours = go32_terminal_ours;
873
  go32_ops.to_terminal_info = go32_terminal_info;
874
  go32_ops.to_kill = go32_kill_inferior;
875
  go32_ops.to_create_inferior = go32_create_inferior;
876
  go32_ops.to_mourn_inferior = go32_mourn_inferior;
877
  go32_ops.to_can_run = go32_can_run;
878
  go32_ops.to_stop = go32_stop;
879
  go32_ops.to_stratum = process_stratum;
880
  go32_ops.to_has_all_memory = 1;
881
  go32_ops.to_has_memory = 1;
882
  go32_ops.to_has_stack = 1;
883
  go32_ops.to_has_registers = 1;
884
  go32_ops.to_has_execution = 1;
885
  go32_ops.to_magic = OPS_MAGIC;
886
 
887
  /* Initialize child's cwd as empty to be initialized when starting
888
     the child.  */
889
  *child_cwd = 0;
890
 
891
  /* Initialize child's command line storage.  */
892
  if (redir_debug_init (&child_cmd) == -1)
893
    internal_error (__FILE__, __LINE__,
894
                    _("Cannot allocate redirection storage: not enough memory.\n"));
895
 
896
  /* We are always processing GCC-compiled programs.  */
897
  processing_gcc_compilation = 2;
898
 
899
  /* Override the default name of the GDB init file.  */
900
  strcpy (gdbinit, "gdb.ini");
901
}
902
 
903
unsigned short windows_major, windows_minor;
904
 
905
/* Compute the version Windows reports via Int 2Fh/AX=1600h.  */
906
static void
907
go32_get_windows_version(void)
908
{
909
  __dpmi_regs r;
910
 
911
  r.x.ax = 0x1600;
912
  __dpmi_int(0x2f, &r);
913
  if (r.h.al > 2 && r.h.al != 0x80 && r.h.al != 0xff
914
      && (r.h.al > 3 || r.h.ah > 0))
915
    {
916
      windows_major = r.h.al;
917
      windows_minor = r.h.ah;
918
    }
919
  else
920
    windows_major = 0xff;       /* meaning no Windows */
921
}
922
 
923
/* A subroutine of go32_sysinfo to display memory info.  */
924
static void
925
print_mem (unsigned long datum, const char *header, int in_pages_p)
926
{
927
  if (datum != 0xffffffffUL)
928
    {
929
      if (in_pages_p)
930
        datum <<= 12;
931
      puts_filtered (header);
932
      if (datum > 1024)
933
        {
934
          printf_filtered ("%lu KB", datum >> 10);
935
          if (datum > 1024 * 1024)
936
            printf_filtered (" (%lu MB)", datum >> 20);
937
        }
938
      else
939
        printf_filtered ("%lu Bytes", datum);
940
      puts_filtered ("\n");
941
    }
942
}
943
 
944
/* Display assorted information about the underlying OS.  */
945
static void
946
go32_sysinfo (char *arg, int from_tty)
947
{
948
  struct utsname u;
949
  char cpuid_vendor[13];
950
  unsigned cpuid_max = 0, cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
951
  unsigned true_dos_version = _get_dos_version (1);
952
  unsigned advertized_dos_version = ((unsigned int)_osmajor << 8) | _osminor;
953
  int dpmi_flags;
954
  char dpmi_vendor_info[129];
955
  int dpmi_vendor_available =
956
    __dpmi_get_capabilities (&dpmi_flags, dpmi_vendor_info);
957
  __dpmi_version_ret dpmi_version_data;
958
  long eflags;
959
  __dpmi_free_mem_info mem_info;
960
  __dpmi_regs regs;
961
 
962
  cpuid_vendor[0] = '\0';
963
  if (uname (&u))
964
    strcpy (u.machine, "Unknown x86");
965
  else if (u.machine[0] == 'i' && u.machine[1] > 4)
966
    {
967
      /* CPUID with EAX = 0 returns the Vendor ID.  */
968
      __asm__ __volatile__ ("xorl   %%ebx, %%ebx;"
969
                            "xorl   %%ecx, %%ecx;"
970
                            "xorl   %%edx, %%edx;"
971
                            "movl   $0,    %%eax;"
972
                            "cpuid;"
973
                            "movl   %%ebx,  %0;"
974
                            "movl   %%edx,  %1;"
975
                            "movl   %%ecx,  %2;"
976
                            "movl   %%eax,  %3;"
977
                            : "=m" (cpuid_vendor[0]),
978
                              "=m" (cpuid_vendor[4]),
979
                              "=m" (cpuid_vendor[8]),
980
                              "=m" (cpuid_max)
981
                            :
982
                            : "%eax", "%ebx", "%ecx", "%edx");
983
      cpuid_vendor[12] = '\0';
984
    }
985
 
986
  printf_filtered ("CPU Type.......................%s", u.machine);
987
  if (cpuid_vendor[0])
988
    printf_filtered (" (%s)", cpuid_vendor);
989
  puts_filtered ("\n");
990
 
991
  /* CPUID with EAX = 1 returns processor signature and features.  */
992
  if (cpuid_max >= 1)
993
    {
994
      static char *brand_name[] = {
995
        "",
996
        " Celeron",
997
        " III",
998
        " III Xeon",
999
        "", "", "", "",
1000
        " 4"
1001
      };
1002
      char cpu_string[80];
1003
      char cpu_brand[20];
1004
      unsigned brand_idx;
1005
      int intel_p = strcmp (cpuid_vendor, "GenuineIntel") == 0;
1006
      int amd_p = strcmp (cpuid_vendor, "AuthenticAMD") == 0;
1007
      unsigned cpu_family, cpu_model;
1008
 
1009
      __asm__ __volatile__ ("movl   $1, %%eax;"
1010
                            "cpuid;"
1011
                            : "=a" (cpuid_eax),
1012
                              "=b" (cpuid_ebx),
1013
                              "=d" (cpuid_edx)
1014
                            :
1015
                            : "%ecx");
1016
      brand_idx = cpuid_ebx & 0xff;
1017
      cpu_family = (cpuid_eax >> 8) & 0xf;
1018
      cpu_model  = (cpuid_eax >> 4) & 0xf;
1019
      cpu_brand[0] = '\0';
1020
      if (intel_p)
1021
        {
1022
          if (brand_idx > 0
1023
              && brand_idx < sizeof(brand_name)/sizeof(brand_name[0])
1024
              && *brand_name[brand_idx])
1025
            strcpy (cpu_brand, brand_name[brand_idx]);
1026
          else if (cpu_family == 5)
1027
            {
1028
              if (((cpuid_eax >> 12) & 3) == 0 && cpu_model == 4)
1029
                strcpy (cpu_brand, " MMX");
1030
              else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 1)
1031
                strcpy (cpu_brand, " OverDrive");
1032
              else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 2)
1033
                strcpy (cpu_brand, " Dual");
1034
            }
1035
          else if (cpu_family == 6 && cpu_model < 8)
1036
            {
1037
              switch (cpu_model)
1038
                {
1039
                  case 1:
1040
                    strcpy (cpu_brand, " Pro");
1041
                    break;
1042
                  case 3:
1043
                    strcpy (cpu_brand, " II");
1044
                    break;
1045
                  case 5:
1046
                    strcpy (cpu_brand, " II Xeon");
1047
                    break;
1048
                  case 6:
1049
                    strcpy (cpu_brand, " Celeron");
1050
                    break;
1051
                  case 7:
1052
                    strcpy (cpu_brand, " III");
1053
                    break;
1054
                }
1055
            }
1056
        }
1057
      else if (amd_p)
1058
        {
1059
          switch (cpu_family)
1060
            {
1061
              case 4:
1062
                strcpy (cpu_brand, "486/5x86");
1063
                break;
1064
              case 5:
1065
                switch (cpu_model)
1066
                  {
1067
                    case 0:
1068
                    case 1:
1069
                    case 2:
1070
                    case 3:
1071
                      strcpy (cpu_brand, "-K5");
1072
                      break;
1073
                    case 6:
1074
                    case 7:
1075
                      strcpy (cpu_brand, "-K6");
1076
                      break;
1077
                    case 8:
1078
                      strcpy (cpu_brand, "-K6-2");
1079
                      break;
1080
                    case 9:
1081
                      strcpy (cpu_brand, "-K6-III");
1082
                      break;
1083
                  }
1084
                break;
1085
              case 6:
1086
                switch (cpu_model)
1087
                  {
1088
                    case 1:
1089
                    case 2:
1090
                    case 4:
1091
                      strcpy (cpu_brand, " Athlon");
1092
                      break;
1093
                    case 3:
1094
                      strcpy (cpu_brand, " Duron");
1095
                      break;
1096
                  }
1097
                break;
1098
            }
1099
        }
1100
      sprintf (cpu_string, "%s%s Model %d Stepping %d",
1101
               intel_p ? "Pentium" : (amd_p ? "AMD" : "ix86"),
1102
               cpu_brand, cpu_model, cpuid_eax & 0xf);
1103
      printfi_filtered (31, "%s\n", cpu_string);
1104
      if (((cpuid_edx & (6 | (0x0d << 23))) != 0)
1105
          || ((cpuid_edx & 1) == 0)
1106
          || (amd_p && (cpuid_edx & (3 << 30)) != 0))
1107
        {
1108
          puts_filtered ("CPU Features...................");
1109
          /* We only list features which might be useful in the DPMI
1110
             environment.  */
1111
          if ((cpuid_edx & 1) == 0)
1112
            puts_filtered ("No FPU "); /* it's unusual to not have an FPU */
1113
          if ((cpuid_edx & (1 << 1)) != 0)
1114
            puts_filtered ("VME ");
1115
          if ((cpuid_edx & (1 << 2)) != 0)
1116
            puts_filtered ("DE ");
1117
          if ((cpuid_edx & (1 << 4)) != 0)
1118
            puts_filtered ("TSC ");
1119
          if ((cpuid_edx & (1 << 23)) != 0)
1120
            puts_filtered ("MMX ");
1121
          if ((cpuid_edx & (1 << 25)) != 0)
1122
            puts_filtered ("SSE ");
1123
          if ((cpuid_edx & (1 << 26)) != 0)
1124
            puts_filtered ("SSE2 ");
1125
          if (amd_p)
1126
            {
1127
              if ((cpuid_edx & (1 << 31)) != 0)
1128
                puts_filtered ("3DNow! ");
1129
              if ((cpuid_edx & (1 << 30)) != 0)
1130
                puts_filtered ("3DNow!Ext");
1131
            }
1132
          puts_filtered ("\n");
1133
        }
1134
    }
1135
  puts_filtered ("\n");
1136
  printf_filtered ("DOS Version....................%s %s.%s",
1137
                   _os_flavor, u.release, u.version);
1138
  if (true_dos_version != advertized_dos_version)
1139
    printf_filtered (" (disguised as v%d.%d)", _osmajor, _osminor);
1140
  puts_filtered ("\n");
1141
  if (!windows_major)
1142
    go32_get_windows_version ();
1143
  if (windows_major != 0xff)
1144
    {
1145
      const char *windows_flavor;
1146
 
1147
      printf_filtered ("Windows Version................%d.%02d (Windows ",
1148
                       windows_major, windows_minor);
1149
      switch (windows_major)
1150
        {
1151
          case 3:
1152
            windows_flavor = "3.X";
1153
            break;
1154
          case 4:
1155
            switch (windows_minor)
1156
              {
1157
                case 0:
1158
                  windows_flavor = "95, 95A, or 95B";
1159
                  break;
1160
                case 3:
1161
                  windows_flavor = "95B OSR2.1 or 95C OSR2.5";
1162
                  break;
1163
                case 10:
1164
                  windows_flavor = "98 or 98 SE";
1165
                  break;
1166
                case 90:
1167
                  windows_flavor = "ME";
1168
                  break;
1169
                default:
1170
                  windows_flavor = "9X";
1171
                  break;
1172
              }
1173
            break;
1174
          default:
1175
            windows_flavor = "??";
1176
            break;
1177
        }
1178
      printf_filtered ("%s)\n", windows_flavor);
1179
    }
1180
  else if (true_dos_version == 0x532 && advertized_dos_version == 0x500)
1181
    printf_filtered ("Windows Version................Windows NT or Windows 2000\n");
1182
  puts_filtered ("\n");
1183
  if (dpmi_vendor_available == 0)
1184
    {
1185
      /* The DPMI spec says the vendor string should be ASCIIZ, but
1186
         I don't trust the vendors to follow that...  */
1187
      if (!memchr (&dpmi_vendor_info[2], 0, 126))
1188
        dpmi_vendor_info[128] = '\0';
1189
      printf_filtered ("DPMI Host......................%s v%d.%d (capabilities: %#x)\n",
1190
                       &dpmi_vendor_info[2],
1191
                       (unsigned)dpmi_vendor_info[0],
1192
                       (unsigned)dpmi_vendor_info[1],
1193
                       ((unsigned)dpmi_flags & 0x7f));
1194
    }
1195
  __dpmi_get_version (&dpmi_version_data);
1196
  printf_filtered ("DPMI Version...................%d.%02d\n",
1197
                   dpmi_version_data.major, dpmi_version_data.minor);
1198
  printf_filtered ("DPMI Info......................%s-bit DPMI, with%s Virtual Memory support\n",
1199
                   (dpmi_version_data.flags & 1) ? "32" : "16",
1200
                   (dpmi_version_data.flags & 4) ? "" : "out");
1201
  printfi_filtered (31, "Interrupts reflected to %s mode\n",
1202
                   (dpmi_version_data.flags & 2) ? "V86" : "Real");
1203
  printfi_filtered (31, "Processor type: i%d86\n",
1204
                   dpmi_version_data.cpu);
1205
  printfi_filtered (31, "PIC base interrupt: Master: %#x  Slave: %#x\n",
1206
                   dpmi_version_data.master_pic, dpmi_version_data.slave_pic);
1207
 
1208
  /* a_tss is only initialized when the debuggee is first run.  */
1209
  if (prog_has_started)
1210
    {
1211
      __asm__ __volatile__ ("pushfl ; popl %0" : "=g" (eflags));
1212
      printf_filtered ("Protection.....................Ring %d (in %s), with%s I/O protection\n",
1213
                       a_tss.tss_cs & 3, (a_tss.tss_cs & 4) ? "LDT" : "GDT",
1214
                       (a_tss.tss_cs & 3) > ((eflags >> 12) & 3) ? "" : "out");
1215
    }
1216
  puts_filtered ("\n");
1217
  __dpmi_get_free_memory_information (&mem_info);
1218
  print_mem (mem_info.total_number_of_physical_pages,
1219
             "DPMI Total Physical Memory.....", 1);
1220
  print_mem (mem_info.total_number_of_free_pages,
1221
             "DPMI Free Physical Memory......", 1);
1222
  print_mem (mem_info.size_of_paging_file_partition_in_pages,
1223
             "DPMI Swap Space................", 1);
1224
  print_mem (mem_info.linear_address_space_size_in_pages,
1225
             "DPMI Total Linear Address Size.", 1);
1226
  print_mem (mem_info.free_linear_address_space_in_pages,
1227
             "DPMI Free Linear Address Size..", 1);
1228
  print_mem (mem_info.largest_available_free_block_in_bytes,
1229
             "DPMI Largest Free Memory Block.", 0);
1230
 
1231
  regs.h.ah = 0x48;
1232
  regs.x.bx = 0xffff;
1233
  __dpmi_int (0x21, &regs);
1234
  print_mem (regs.x.bx << 4, "Free DOS Memory................", 0);
1235
  regs.x.ax = 0x5800;
1236
  __dpmi_int (0x21, &regs);
1237
  if ((regs.x.flags & 1) == 0)
1238
    {
1239
      static const char *dos_hilo[] = {
1240
        "Low", "", "", "", "High", "", "", "", "High, then Low"
1241
      };
1242
      static const char *dos_fit[] = {
1243
        "First", "Best", "Last"
1244
      };
1245
      int hilo_idx = (regs.x.ax >> 4) & 0x0f;
1246
      int fit_idx  = regs.x.ax & 0x0f;
1247
 
1248
      if (hilo_idx > 8)
1249
        hilo_idx = 0;
1250
      if (fit_idx > 2)
1251
        fit_idx = 0;
1252
      printf_filtered ("DOS Memory Allocation..........%s memory, %s fit\n",
1253
                       dos_hilo[hilo_idx], dos_fit[fit_idx]);
1254
      regs.x.ax = 0x5802;
1255
      __dpmi_int (0x21, &regs);
1256
      if ((regs.x.flags & 1) != 0)
1257
        regs.h.al = 0;
1258
      printfi_filtered (31, "UMBs %sin DOS memory chain\n",
1259
                        regs.h.al == 0 ? "not " : "");
1260
    }
1261
}
1262
 
1263
struct seg_descr {
1264
  unsigned short limit0          __attribute__((packed));
1265
  unsigned short base0           __attribute__((packed));
1266
  unsigned char  base1           __attribute__((packed));
1267
  unsigned       stype:5         __attribute__((packed));
1268
  unsigned       dpl:2           __attribute__((packed));
1269
  unsigned       present:1       __attribute__((packed));
1270
  unsigned       limit1:4        __attribute__((packed));
1271
  unsigned       available:1     __attribute__((packed));
1272
  unsigned       dummy:1         __attribute__((packed));
1273
  unsigned       bit32:1         __attribute__((packed));
1274
  unsigned       page_granular:1 __attribute__((packed));
1275
  unsigned char  base2           __attribute__((packed));
1276
};
1277
 
1278
struct gate_descr {
1279
  unsigned short offset0         __attribute__((packed));
1280
  unsigned short selector        __attribute__((packed));
1281
  unsigned       param_count:5   __attribute__((packed));
1282
  unsigned       dummy:3         __attribute__((packed));
1283
  unsigned       stype:5         __attribute__((packed));
1284
  unsigned       dpl:2           __attribute__((packed));
1285
  unsigned       present:1       __attribute__((packed));
1286
  unsigned short offset1         __attribute__((packed));
1287
};
1288
 
1289
/* Read LEN bytes starting at logical address ADDR, and put the result
1290
   into DEST.  Return 1 if success, zero if not.  */
1291
static int
1292
read_memory_region (unsigned long addr, void *dest, size_t len)
1293
{
1294
  unsigned long dos_ds_limit = __dpmi_get_segment_limit (_dos_ds);
1295
  int retval = 1;
1296
 
1297
  /* For the low memory, we can simply use _dos_ds.  */
1298
  if (addr <= dos_ds_limit - len)
1299
    dosmemget (addr, len, dest);
1300
  else
1301
    {
1302
      /* For memory above 1MB we need to set up a special segment to
1303
         be able to access that memory.  */
1304
      int sel = __dpmi_allocate_ldt_descriptors (1);
1305
 
1306
      if (sel <= 0)
1307
        retval = 0;
1308
      else
1309
        {
1310
          int access_rights = __dpmi_get_descriptor_access_rights (sel);
1311
          size_t segment_limit = len - 1;
1312
 
1313
          /* Make sure the crucial bits in the descriptor access
1314
             rights are set correctly.  Some DPMI providers might barf
1315
             if we set the segment limit to something that is not an
1316
             integral multiple of 4KB pages if the granularity bit is
1317
             not set to byte-granular, even though the DPMI spec says
1318
             it's the host's responsibility to set that bit correctly.  */
1319
          if (len > 1024 * 1024)
1320
            {
1321
              access_rights |= 0x8000;
1322
              /* Page-granular segments should have the low 12 bits of
1323
                 the limit set.  */
1324
              segment_limit |= 0xfff;
1325
            }
1326
          else
1327
            access_rights &= ~0x8000;
1328
 
1329
          if (__dpmi_set_segment_base_address (sel, addr) != -1
1330
              && __dpmi_set_descriptor_access_rights (sel, access_rights) != -1
1331
              && __dpmi_set_segment_limit (sel, segment_limit) != -1
1332
              /* W2K silently fails to set the segment limit, leaving
1333
                 it at zero; this test avoids the resulting crash.  */
1334
              && __dpmi_get_segment_limit (sel) >= segment_limit)
1335
            movedata (sel, 0, _my_ds (), (unsigned)dest, len);
1336
          else
1337
            retval = 0;
1338
 
1339
          __dpmi_free_ldt_descriptor (sel);
1340
        }
1341
    }
1342
  return retval;
1343
}
1344
 
1345
/* Get a segment descriptor stored at index IDX in the descriptor
1346
   table whose base address is TABLE_BASE.  Return the descriptor
1347
   type, or -1 if failure.  */
1348
static int
1349
get_descriptor (unsigned long table_base, int idx, void *descr)
1350
{
1351
  unsigned long addr = table_base + idx * 8; /* 8 bytes per entry */
1352
 
1353
  if (read_memory_region (addr, descr, 8))
1354
    return (int)((struct seg_descr *)descr)->stype;
1355
  return -1;
1356
}
1357
 
1358
struct dtr_reg {
1359
  unsigned short limit __attribute__((packed));
1360
  unsigned long  base  __attribute__((packed));
1361
};
1362
 
1363
/* Display a segment descriptor stored at index IDX in a descriptor
1364
   table whose type is TYPE and whose base address is BASE_ADDR.  If
1365
   FORCE is non-zero, display even invalid descriptors.  */
1366
static void
1367
display_descriptor (unsigned type, unsigned long base_addr, int idx, int force)
1368
{
1369
  struct seg_descr descr;
1370
  struct gate_descr gate;
1371
 
1372
  /* Get the descriptor from the table.  */
1373
  if (idx == 0 && type == 0)
1374
    puts_filtered ("0x000: null descriptor\n");
1375
  else if (get_descriptor (base_addr, idx, &descr) != -1)
1376
    {
1377
      /* For each type of descriptor table, this has a bit set if the
1378
         corresponding type of selectors is valid in that table.  */
1379
      static unsigned allowed_descriptors[] = {
1380
          0xffffdafeL,   /* GDT */
1381
          0x0000c0e0L,   /* IDT */
1382
          0xffffdafaL    /* LDT */
1383
      };
1384
 
1385
      /* If the program hasn't started yet, assume the debuggee will
1386
         have the same CPL as the debugger.  */
1387
      int cpl = prog_has_started ? (a_tss.tss_cs & 3) : _my_cs () & 3;
1388
      unsigned long limit = (descr.limit1 << 16) | descr.limit0;
1389
 
1390
      if (descr.present
1391
          && (allowed_descriptors[type] & (1 << descr.stype)) != 0)
1392
        {
1393
          printf_filtered ("0x%03x: ",
1394
                           type == 1
1395
                           ? idx : (idx * 8) | (type ? (cpl | 4) : 0));
1396
          if (descr.page_granular)
1397
            limit = (limit << 12) | 0xfff; /* big segment: low 12 bit set */
1398
          if (descr.stype == 1 || descr.stype == 2 || descr.stype == 3
1399
              || descr.stype == 9 || descr.stype == 11
1400
              || (descr.stype >= 16 && descr.stype < 32))
1401
            printf_filtered ("base=0x%02x%02x%04x limit=0x%08lx",
1402
                             descr.base2, descr.base1, descr.base0, limit);
1403
 
1404
          switch (descr.stype)
1405
            {
1406
              case 1:
1407
              case 3:
1408
                printf_filtered (" 16-bit TSS  (task %sactive)",
1409
                                 descr.stype == 3 ? "" : "in");
1410
                break;
1411
              case 2:
1412
                puts_filtered (" LDT");
1413
                break;
1414
              case 4:
1415
                memcpy (&gate, &descr, sizeof gate);
1416
                printf_filtered ("selector=0x%04x  offs=0x%04x%04x",
1417
                                 gate.selector, gate.offset1, gate.offset0);
1418
                printf_filtered (" 16-bit Call Gate (params=%d)",
1419
                                 gate.param_count);
1420
                break;
1421
              case 5:
1422
                printf_filtered ("TSS selector=0x%04x", descr.base0);
1423
                printfi_filtered (16, "Task Gate");
1424
                break;
1425
              case 6:
1426
              case 7:
1427
                memcpy (&gate, &descr, sizeof gate);
1428
                printf_filtered ("selector=0x%04x  offs=0x%04x%04x",
1429
                                 gate.selector, gate.offset1, gate.offset0);
1430
                printf_filtered (" 16-bit %s Gate",
1431
                                 descr.stype == 6 ? "Interrupt" : "Trap");
1432
                break;
1433
              case 9:
1434
              case 11:
1435
                printf_filtered (" 32-bit TSS (task %sactive)",
1436
                                 descr.stype == 3 ? "" : "in");
1437
                break;
1438
              case 12:
1439
                memcpy (&gate, &descr, sizeof gate);
1440
                printf_filtered ("selector=0x%04x  offs=0x%04x%04x",
1441
                                 gate.selector, gate.offset1, gate.offset0);
1442
                printf_filtered (" 32-bit Call Gate (params=%d)",
1443
                                 gate.param_count);
1444
                break;
1445
              case 14:
1446
              case 15:
1447
                memcpy (&gate, &descr, sizeof gate);
1448
                printf_filtered ("selector=0x%04x  offs=0x%04x%04x",
1449
                                 gate.selector, gate.offset1, gate.offset0);
1450
                printf_filtered (" 32-bit %s Gate",
1451
                                 descr.stype == 14 ? "Interrupt" : "Trap");
1452
                break;
1453
              case 16:          /* data segments */
1454
              case 17:
1455
              case 18:
1456
              case 19:
1457
              case 20:
1458
              case 21:
1459
              case 22:
1460
              case 23:
1461
                printf_filtered (" %s-bit Data (%s Exp-%s%s)",
1462
                                 descr.bit32 ? "32" : "16",
1463
                                 descr.stype & 2 ? "Read/Write," : "Read-Only, ",
1464
                                 descr.stype & 4 ? "down" : "up",
1465
                                 descr.stype & 1 ? "" : ", N.Acc");
1466
                break;
1467
              case 24:          /* code segments */
1468
              case 25:
1469
              case 26:
1470
              case 27:
1471
              case 28:
1472
              case 29:
1473
              case 30:
1474
              case 31:
1475
                printf_filtered (" %s-bit Code (%s,  %sConf%s)",
1476
                                 descr.bit32 ? "32" : "16",
1477
                                 descr.stype & 2 ? "Exec/Read" : "Exec-Only",
1478
                                 descr.stype & 4 ? "" : "N.",
1479
                                 descr.stype & 1 ? "" : ", N.Acc");
1480
                break;
1481
              default:
1482
                printf_filtered ("Unknown type 0x%02x", descr.stype);
1483
                break;
1484
            }
1485
          puts_filtered ("\n");
1486
        }
1487
      else if (force)
1488
        {
1489
          printf_filtered ("0x%03x: ",
1490
                           type == 1
1491
                           ? idx : (idx * 8) | (type ? (cpl | 4) : 0));
1492
          if (!descr.present)
1493
            puts_filtered ("Segment not present\n");
1494
          else
1495
            printf_filtered ("Segment type 0x%02x is invalid in this table\n",
1496
                             descr.stype);
1497
        }
1498
    }
1499
  else if (force)
1500
    printf_filtered ("0x%03x: Cannot read this descriptor\n", idx);
1501
}
1502
 
1503
static void
1504
go32_sldt (char *arg, int from_tty)
1505
{
1506
  struct dtr_reg gdtr;
1507
  unsigned short ldtr = 0;
1508
  int ldt_idx;
1509
  struct seg_descr ldt_descr;
1510
  long ldt_entry = -1L;
1511
  int cpl = (prog_has_started ? a_tss.tss_cs : _my_cs ()) & 3;
1512
 
1513
  if (arg && *arg)
1514
    {
1515
      while (*arg && isspace(*arg))
1516
        arg++;
1517
 
1518
      if (*arg)
1519
        {
1520
          ldt_entry = parse_and_eval_long (arg);
1521
          if (ldt_entry < 0
1522
              || (ldt_entry & 4) == 0
1523
              || (ldt_entry & 3) != (cpl & 3))
1524
            error (_("Invalid LDT entry 0x%03lx."), (unsigned long)ldt_entry);
1525
        }
1526
    }
1527
 
1528
  __asm__ __volatile__ ("sgdt   %0" : "=m" (gdtr) : /* no inputs */ );
1529
  __asm__ __volatile__ ("sldt   %0" : "=m" (ldtr) : /* no inputs */ );
1530
  ldt_idx = ldtr / 8;
1531
  if (ldt_idx == 0)
1532
    puts_filtered ("There is no LDT.\n");
1533
  /* LDT's entry in the GDT must have the type LDT, which is 2.  */
1534
  else if (get_descriptor (gdtr.base, ldt_idx, &ldt_descr) != 2)
1535
    printf_filtered ("LDT is present (at %#x), but unreadable by GDB.\n",
1536
                     ldt_descr.base0
1537
                     | (ldt_descr.base1 << 16)
1538
                     | (ldt_descr.base2 << 24));
1539
  else
1540
    {
1541
      unsigned base =
1542
        ldt_descr.base0
1543
        | (ldt_descr.base1 << 16)
1544
        | (ldt_descr.base2 << 24);
1545
      unsigned limit = ldt_descr.limit0 | (ldt_descr.limit1 << 16);
1546
      int max_entry;
1547
 
1548
      if (ldt_descr.page_granular)
1549
        /* Page-granular segments must have the low 12 bits of their
1550
           limit set.  */
1551
        limit = (limit << 12) | 0xfff;
1552
      /* LDT cannot have more than 8K 8-byte entries, i.e. more than
1553
         64KB.  */
1554
      if (limit > 0xffff)
1555
        limit = 0xffff;
1556
 
1557
      max_entry = (limit + 1) / 8;
1558
 
1559
      if (ldt_entry >= 0)
1560
        {
1561
          if (ldt_entry > limit)
1562
            error (_("Invalid LDT entry %#lx: outside valid limits [0..%#x]"),
1563
                   (unsigned long)ldt_entry, limit);
1564
 
1565
          display_descriptor (ldt_descr.stype, base, ldt_entry / 8, 1);
1566
        }
1567
      else
1568
        {
1569
          int i;
1570
 
1571
          for (i = 0; i < max_entry; i++)
1572
            display_descriptor (ldt_descr.stype, base, i, 0);
1573
        }
1574
    }
1575
}
1576
 
1577
static void
1578
go32_sgdt (char *arg, int from_tty)
1579
{
1580
  struct dtr_reg gdtr;
1581
  long gdt_entry = -1L;
1582
  int max_entry;
1583
 
1584
  if (arg && *arg)
1585
    {
1586
      while (*arg && isspace(*arg))
1587
        arg++;
1588
 
1589
      if (*arg)
1590
        {
1591
          gdt_entry = parse_and_eval_long (arg);
1592
          if (gdt_entry < 0 || (gdt_entry & 7) != 0)
1593
            error (_("Invalid GDT entry 0x%03lx: not an integral multiple of 8."),
1594
                   (unsigned long)gdt_entry);
1595
        }
1596
    }
1597
 
1598
  __asm__ __volatile__ ("sgdt   %0" : "=m" (gdtr) : /* no inputs */ );
1599
  max_entry = (gdtr.limit + 1) / 8;
1600
 
1601
  if (gdt_entry >= 0)
1602
    {
1603
      if (gdt_entry > gdtr.limit)
1604
        error (_("Invalid GDT entry %#lx: outside valid limits [0..%#x]"),
1605
               (unsigned long)gdt_entry, gdtr.limit);
1606
 
1607
      display_descriptor (0, gdtr.base, gdt_entry / 8, 1);
1608
    }
1609
  else
1610
    {
1611
      int i;
1612
 
1613
      for (i = 0; i < max_entry; i++)
1614
        display_descriptor (0, gdtr.base, i, 0);
1615
    }
1616
}
1617
 
1618
static void
1619
go32_sidt (char *arg, int from_tty)
1620
{
1621
  struct dtr_reg idtr;
1622
  long idt_entry = -1L;
1623
  int max_entry;
1624
 
1625
  if (arg && *arg)
1626
    {
1627
      while (*arg && isspace(*arg))
1628
        arg++;
1629
 
1630
      if (*arg)
1631
        {
1632
          idt_entry = parse_and_eval_long (arg);
1633
          if (idt_entry < 0)
1634
            error (_("Invalid (negative) IDT entry %ld."), idt_entry);
1635
        }
1636
    }
1637
 
1638
  __asm__ __volatile__ ("sidt   %0" : "=m" (idtr) : /* no inputs */ );
1639
  max_entry = (idtr.limit + 1) / 8;
1640
  if (max_entry > 0x100)        /* no more than 256 entries */
1641
    max_entry = 0x100;
1642
 
1643
  if (idt_entry >= 0)
1644
    {
1645
      if (idt_entry > idtr.limit)
1646
        error (_("Invalid IDT entry %#lx: outside valid limits [0..%#x]"),
1647
               (unsigned long)idt_entry, idtr.limit);
1648
 
1649
      display_descriptor (1, idtr.base, idt_entry, 1);
1650
    }
1651
  else
1652
    {
1653
      int i;
1654
 
1655
      for (i = 0; i < max_entry; i++)
1656
        display_descriptor (1, idtr.base, i, 0);
1657
    }
1658
}
1659
 
1660
/* Cached linear address of the base of the page directory.  For
1661
   now, available only under CWSDPMI.  Code based on ideas and
1662
   suggestions from Charles Sandmann <sandmann@clio.rice.edu>.  */
1663
static unsigned long pdbr;
1664
 
1665
static unsigned long
1666
get_cr3 (void)
1667
{
1668
  unsigned offset;
1669
  unsigned taskreg;
1670
  unsigned long taskbase, cr3;
1671
  struct dtr_reg gdtr;
1672
 
1673
  if (pdbr > 0 && pdbr <= 0xfffff)
1674
    return pdbr;
1675
 
1676
  /* Get the linear address of GDT and the Task Register.  */
1677
  __asm__ __volatile__ ("sgdt   %0" : "=m" (gdtr) : /* no inputs */ );
1678
  __asm__ __volatile__ ("str    %0" : "=m" (taskreg) : /* no inputs */ );
1679
 
1680
  /* Task Register is a segment selector for the TSS of the current
1681
     task.  Therefore, it can be used as an index into the GDT to get
1682
     at the segment descriptor for the TSS.  To get the index, reset
1683
     the low 3 bits of the selector (which give the CPL).  Add 2 to the
1684
     offset to point to the 3 low bytes of the base address.  */
1685
  offset = gdtr.base + (taskreg & 0xfff8) + 2;
1686
 
1687
 
1688
  /* CWSDPMI's task base is always under the 1MB mark.  */
1689
  if (offset > 0xfffff)
1690
    return 0;
1691
 
1692
  _farsetsel (_dos_ds);
1693
  taskbase  = _farnspeekl (offset) & 0xffffffU;
1694
  taskbase += _farnspeekl (offset + 2) & 0xff000000U;
1695
  if (taskbase > 0xfffff)
1696
    return 0;
1697
 
1698
  /* CR3 (a.k.a. PDBR, the Page Directory Base Register) is stored at
1699
     offset 1Ch in the TSS.  */
1700
  cr3 = _farnspeekl (taskbase + 0x1c) & ~0xfff;
1701
  if (cr3 > 0xfffff)
1702
    {
1703
#if 0  /* not fullly supported yet */
1704
      /* The Page Directory is in UMBs.  In that case, CWSDPMI puts
1705
         the first Page Table right below the Page Directory.  Thus,
1706
         the first Page Table's entry for its own address and the Page
1707
         Directory entry for that Page Table will hold the same
1708
         physical address.  The loop below searches the entire UMB
1709
         range of addresses for such an occurence.  */
1710
      unsigned long addr, pte_idx;
1711
 
1712
      for (addr = 0xb0000, pte_idx = 0xb0;
1713
           pte_idx < 0xff;
1714
           addr += 0x1000, pte_idx++)
1715
        {
1716
          if (((_farnspeekl (addr + 4 * pte_idx) & 0xfffff027) ==
1717
               (_farnspeekl (addr + 0x1000) & 0xfffff027))
1718
              && ((_farnspeekl (addr + 4 * pte_idx + 4) & 0xfffff000) == cr3))
1719
            {
1720
              cr3 = addr + 0x1000;
1721
              break;
1722
            }
1723
        }
1724
#endif
1725
 
1726
      if (cr3 > 0xfffff)
1727
        cr3 = 0;
1728
    }
1729
 
1730
  return cr3;
1731
}
1732
 
1733
/* Return the N'th Page Directory entry.  */
1734
static unsigned long
1735
get_pde (int n)
1736
{
1737
  unsigned long pde = 0;
1738
 
1739
  if (pdbr && n >= 0 && n < 1024)
1740
    {
1741
      pde = _farpeekl (_dos_ds, pdbr + 4*n);
1742
    }
1743
  return pde;
1744
}
1745
 
1746
/* Return the N'th entry of the Page Table whose Page Directory entry
1747
   is PDE.  */
1748
static unsigned long
1749
get_pte (unsigned long pde, int n)
1750
{
1751
  unsigned long pte = 0;
1752
 
1753
  /* pde & 0x80 tests the 4MB page bit.  We don't support 4MB
1754
     page tables, for now.  */
1755
  if ((pde & 1) && !(pde & 0x80) && n >= 0 && n < 1024)
1756
    {
1757
      pde &= ~0xfff;    /* clear non-address bits */
1758
      pte = _farpeekl (_dos_ds, pde + 4*n);
1759
    }
1760
  return pte;
1761
}
1762
 
1763
/* Display a Page Directory or Page Table entry.  IS_DIR, if non-zero,
1764
   says this is a Page Directory entry.  If FORCE is non-zero, display
1765
   the entry even if its Present flag is off.  OFF is the offset of the
1766
   address from the page's base address.  */
1767
static void
1768
display_ptable_entry (unsigned long entry, int is_dir, int force, unsigned off)
1769
{
1770
  if ((entry & 1) != 0)
1771
    {
1772
      printf_filtered ("Base=0x%05lx000", entry >> 12);
1773
      if ((entry & 0x100) && !is_dir)
1774
        puts_filtered (" Global");
1775
      if ((entry & 0x40) && !is_dir)
1776
        puts_filtered (" Dirty");
1777
      printf_filtered (" %sAcc.", (entry & 0x20) ? "" : "Not-");
1778
      printf_filtered (" %sCached", (entry & 0x10) ? "" : "Not-");
1779
      printf_filtered (" Write-%s", (entry & 8) ? "Thru" : "Back");
1780
      printf_filtered (" %s", (entry & 4) ? "Usr" : "Sup");
1781
      printf_filtered (" Read-%s", (entry & 2) ? "Write" : "Only");
1782
      if (off)
1783
        printf_filtered (" +0x%x", off);
1784
      puts_filtered ("\n");
1785
    }
1786
  else if (force)
1787
    printf_filtered ("Page%s not present or not supported; value=0x%lx.\n",
1788
                     is_dir ? " Table" : "", entry >> 1);
1789
}
1790
 
1791
static void
1792
go32_pde (char *arg, int from_tty)
1793
{
1794
  long pde_idx = -1, i;
1795
 
1796
  if (arg && *arg)
1797
    {
1798
      while (*arg && isspace(*arg))
1799
        arg++;
1800
 
1801
      if (*arg)
1802
        {
1803
          pde_idx = parse_and_eval_long (arg);
1804
          if (pde_idx < 0 || pde_idx >= 1024)
1805
            error (_("Entry %ld is outside valid limits [0..1023]."), pde_idx);
1806
        }
1807
    }
1808
 
1809
  pdbr = get_cr3 ();
1810
  if (!pdbr)
1811
    puts_filtered ("Access to Page Directories is not supported on this system.\n");
1812
  else if (pde_idx >= 0)
1813
    display_ptable_entry (get_pde (pde_idx), 1, 1, 0);
1814
  else
1815
    for (i = 0; i < 1024; i++)
1816
      display_ptable_entry (get_pde (i), 1, 0, 0);
1817
}
1818
 
1819
/* A helper function to display entries in a Page Table pointed to by
1820
   the N'th entry in the Page Directory.  If FORCE is non-zero, say
1821
   something even if the Page Table is not accessible.  */
1822
static void
1823
display_page_table (long n, int force)
1824
{
1825
  unsigned long pde = get_pde (n);
1826
 
1827
  if ((pde & 1) != 0)
1828
    {
1829
      int i;
1830
 
1831
      printf_filtered ("Page Table pointed to by Page Directory entry 0x%lx:\n", n);
1832
      for (i = 0; i < 1024; i++)
1833
        display_ptable_entry (get_pte (pde, i), 0, 0, 0);
1834
      puts_filtered ("\n");
1835
    }
1836
  else if (force)
1837
    printf_filtered ("Page Table not present; value=0x%lx.\n", pde >> 1);
1838
}
1839
 
1840
static void
1841
go32_pte (char *arg, int from_tty)
1842
{
1843
  long pde_idx = -1L, i;
1844
 
1845
  if (arg && *arg)
1846
    {
1847
      while (*arg && isspace(*arg))
1848
        arg++;
1849
 
1850
      if (*arg)
1851
        {
1852
          pde_idx = parse_and_eval_long (arg);
1853
          if (pde_idx < 0 || pde_idx >= 1024)
1854
            error (_("Entry %ld is outside valid limits [0..1023]."), pde_idx);
1855
        }
1856
    }
1857
 
1858
  pdbr = get_cr3 ();
1859
  if (!pdbr)
1860
    puts_filtered ("Access to Page Tables is not supported on this system.\n");
1861
  else if (pde_idx >= 0)
1862
    display_page_table (pde_idx, 1);
1863
  else
1864
    for (i = 0; i < 1024; i++)
1865
      display_page_table (i, 0);
1866
}
1867
 
1868
static void
1869
go32_pte_for_address (char *arg, int from_tty)
1870
{
1871
  CORE_ADDR addr = 0, i;
1872
 
1873
  if (arg && *arg)
1874
    {
1875
      while (*arg && isspace(*arg))
1876
        arg++;
1877
 
1878
      if (*arg)
1879
        addr = parse_and_eval_address (arg);
1880
    }
1881
  if (!addr)
1882
    error_no_arg (_("linear address"));
1883
 
1884
  pdbr = get_cr3 ();
1885
  if (!pdbr)
1886
    puts_filtered ("Access to Page Tables is not supported on this system.\n");
1887
  else
1888
    {
1889
      int pde_idx = (addr >> 22) & 0x3ff;
1890
      int pte_idx = (addr >> 12) & 0x3ff;
1891
      unsigned offs = addr & 0xfff;
1892
 
1893
      printf_filtered ("Page Table entry for address 0x%llx:\n",
1894
                       (unsigned long long)addr);
1895
      display_ptable_entry (get_pte (get_pde (pde_idx), pte_idx), 0, 1, offs);
1896
    }
1897
}
1898
 
1899
static struct cmd_list_element *info_dos_cmdlist = NULL;
1900
 
1901
static void
1902
go32_info_dos_command (char *args, int from_tty)
1903
{
1904
  help_list (info_dos_cmdlist, "info dos ", class_info, gdb_stdout);
1905
}
1906
 
1907
void
1908
_initialize_go32_nat (void)
1909
{
1910
  init_go32_ops ();
1911
  add_target (&go32_ops);
1912
 
1913
  add_prefix_cmd ("dos", class_info, go32_info_dos_command, _("\
1914
Print information specific to DJGPP (aka MS-DOS) debugging."),
1915
                  &info_dos_cmdlist, "info dos ", 0, &infolist);
1916
 
1917
  add_cmd ("sysinfo", class_info, go32_sysinfo, _("\
1918
Display information about the target system, including CPU, OS, DPMI, etc."),
1919
           &info_dos_cmdlist);
1920
  add_cmd ("ldt", class_info, go32_sldt, _("\
1921
Display entries in the LDT (Local Descriptor Table).\n\
1922
Entry number (an expression) as an argument means display only that entry."),
1923
           &info_dos_cmdlist);
1924
  add_cmd ("gdt", class_info, go32_sgdt, _("\
1925
Display entries in the GDT (Global Descriptor Table).\n\
1926
Entry number (an expression) as an argument means display only that entry."),
1927
           &info_dos_cmdlist);
1928
  add_cmd ("idt", class_info, go32_sidt, _("\
1929
Display entries in the IDT (Interrupt Descriptor Table).\n\
1930
Entry number (an expression) as an argument means display only that entry."),
1931
           &info_dos_cmdlist);
1932
  add_cmd ("pde", class_info, go32_pde, _("\
1933
Display entries in the Page Directory.\n\
1934
Entry number (an expression) as an argument means display only that entry."),
1935
           &info_dos_cmdlist);
1936
  add_cmd ("pte", class_info, go32_pte, _("\
1937
Display entries in Page Tables.\n\
1938
Entry number (an expression) as an argument means display only entries\n\
1939
from the Page Table pointed to by the specified Page Directory entry."),
1940
           &info_dos_cmdlist);
1941
  add_cmd ("address-pte", class_info, go32_pte_for_address, _("\
1942
Display a Page Table entry for a linear address.\n\
1943
The address argument must be a linear address, after adding to\n\
1944
it the base address of the appropriate segment.\n\
1945
The base address of variables and functions in the debuggee's data\n\
1946
or code segment is stored in the variable __djgpp_base_address,\n\
1947
so use `__djgpp_base_address + (char *)&var' as the argument.\n\
1948
For other segments, look up their base address in the output of\n\
1949
the `info dos ldt' command."),
1950
           &info_dos_cmdlist);
1951
}
1952
 
1953
pid_t
1954
tcgetpgrp (int fd)
1955
{
1956
  if (isatty (fd))
1957
    return SOME_PID;
1958
  errno = ENOTTY;
1959
  return -1;
1960
}
1961
 
1962
int
1963
tcsetpgrp (int fd, pid_t pgid)
1964
{
1965
  if (isatty (fd) && pgid == SOME_PID)
1966
    return 0;
1967
  errno = pgid == SOME_PID ? ENOTTY : ENOSYS;
1968
  return -1;
1969
}

powered by: WebSVN 2.1.0

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