GDB (API)
/home/stan/gdb/src/gdb/go32-nat.c
Go to the documentation of this file.
00001 /* Native debugging support for Intel x86 running DJGPP.
00002    Copyright (C) 1997-2013 Free Software Foundation, Inc.
00003    Written by Robert Hoehne.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 /* To whomever it may concern, here's a general description of how
00021    debugging in DJGPP works, and the special quirks GDB does to
00022    support that.
00023 
00024    When the DJGPP port of GDB is debugging a DJGPP program natively,
00025    there aren't 2 separate processes, the debuggee and GDB itself, as
00026    on other systems.  (This is DOS, where there can only be one active
00027    process at any given time, remember?)  Instead, GDB and the
00028    debuggee live in the same process.  So when GDB calls
00029    go32_create_inferior below, and that function calls edi_init from
00030    the DJGPP debug support library libdbg.a, we load the debuggee's
00031    executable file into GDB's address space, set it up for execution
00032    as the stub loader (a short real-mode program prepended to each
00033    DJGPP executable) normally would, and do a lot of preparations for
00034    swapping between GDB's and debuggee's internal state, primarily wrt
00035    the exception handlers.  This swapping happens every time we resume
00036    the debuggee or switch back to GDB's code, and it includes:
00037 
00038     . swapping all the segment registers
00039     . swapping the PSP (the Program Segment Prefix)
00040     . swapping the signal handlers
00041     . swapping the exception handlers
00042     . swapping the FPU status
00043     . swapping the 3 standard file handles (more about this below)
00044 
00045    Then running the debuggee simply means longjmp into it where its PC
00046    is and let it run until it stops for some reason.  When it stops,
00047    GDB catches the exception that stopped it and longjmp's back into
00048    its own code.  All the possible exit points of the debuggee are
00049    watched; for example, the normal exit point is recognized because a
00050    DOS program issues a special system call to exit.  If one of those
00051    exit points is hit, we mourn the inferior and clean up after it.
00052    Cleaning up is very important, even if the process exits normally,
00053    because otherwise we might leave behind traces of previous
00054    execution, and in several cases GDB itself might be left hosed,
00055    because all the exception handlers were not restored.
00056 
00057    Swapping of the standard handles (in redir_to_child and
00058    redir_to_debugger) is needed because, since both GDB and the
00059    debuggee live in the same process, as far as the OS is concerned,
00060    the share the same file table.  This means that the standard
00061    handles 0, 1, and 2 point to the same file table entries, and thus
00062    are connected to the same devices.  Therefore, if the debugger
00063    redirects its standard output, the standard output of the debuggee
00064    is also automagically redirected to the same file/device!
00065    Similarly, if the debuggee redirects its stdout to a file, you
00066    won't be able to see debugger's output (it will go to the same file
00067    where the debuggee has its output); and if the debuggee closes its
00068    standard input, you will lose the ability to talk to debugger!
00069 
00070    For this reason, every time the debuggee is about to be resumed, we
00071    call redir_to_child, which redirects the standard handles to where
00072    the debuggee expects them to be.  When the debuggee stops and GDB
00073    regains control, we call redir_to_debugger, which redirects those 3
00074    handles back to where GDB expects.
00075 
00076    Note that only the first 3 handles are swapped, so if the debuggee
00077    redirects or closes any other handles, GDB will not notice.  In
00078    particular, the exit code of a DJGPP program forcibly closes all
00079    file handles beyond the first 3 ones, so when the debuggee exits,
00080    GDB currently loses its stdaux and stdprn streams.  Fortunately,
00081    GDB does not use those as of this writing, and will never need
00082    to.  */
00083 
00084 #include "defs.h"
00085 
00086 #include <fcntl.h>
00087 
00088 #include "i386-nat.h"
00089 #include "inferior.h"
00090 #include "gdbthread.h"
00091 #include "gdb_wait.h"
00092 #include "gdbcore.h"
00093 #include "command.h"
00094 #include "gdbcmd.h"
00095 #include "floatformat.h"
00096 #include "buildsym.h"
00097 #include "i387-tdep.h"
00098 #include "i386-tdep.h"
00099 #include "i386-cpuid.h"
00100 #include "value.h"
00101 #include "regcache.h"
00102 #include "gdb_string.h"
00103 #include "top.h"
00104 #include "cli/cli-utils.h"
00105 
00106 #include <stdio.h>              /* might be required for __DJGPP_MINOR__ */
00107 #include <stdlib.h>
00108 #include <ctype.h>
00109 #include <errno.h>
00110 #include <unistd.h>
00111 #include <sys/utsname.h>
00112 #include <io.h>
00113 #include <dos.h>
00114 #include <dpmi.h>
00115 #include <go32.h>
00116 #include <sys/farptr.h>
00117 #include <debug/v2load.h>
00118 #include <debug/dbgcom.h>
00119 #if __DJGPP_MINOR__ > 2
00120 #include <debug/redir.h>
00121 #endif
00122 
00123 #include <langinfo.h>
00124 
00125 #if __DJGPP_MINOR__ < 3
00126 /* This code will be provided from DJGPP 2.03 on.  Until then I code it
00127    here.  */
00128 typedef struct
00129   {
00130     unsigned short sig0;
00131     unsigned short sig1;
00132     unsigned short sig2;
00133     unsigned short sig3;
00134     unsigned short exponent:15;
00135     unsigned short sign:1;
00136   }
00137 NPXREG;
00138 
00139 typedef struct
00140   {
00141     unsigned int control;
00142     unsigned int status;
00143     unsigned int tag;
00144     unsigned int eip;
00145     unsigned int cs;
00146     unsigned int dataptr;
00147     unsigned int datasel;
00148     NPXREG reg[8];
00149   }
00150 NPX;
00151 
00152 static NPX npx;
00153 
00154 static void save_npx (void);    /* Save the FPU of the debugged program.  */
00155 static void load_npx (void);    /* Restore the FPU of the debugged program.  */
00156 
00157 /* ------------------------------------------------------------------------- */
00158 /* Store the contents of the NPX in the global variable `npx'.  */
00159 /* *INDENT-OFF* */
00160 
00161 static void
00162 save_npx (void)
00163 {
00164   asm ("inb    $0xa0, %%al  \n\
00165        testb $0x20, %%al    \n\
00166        jz 1f                \n\
00167        xorb %%al, %%al      \n\
00168        outb %%al, $0xf0     \n\
00169        movb $0x20, %%al     \n\
00170        outb %%al, $0xa0     \n\
00171        outb %%al, $0x20     \n\
00172 1:                          \n\
00173        fnsave %0            \n\
00174        fwait "
00175 :     "=m" (npx)
00176 :                               /* No input */
00177 :     "%eax");
00178 }
00179 
00180 /* *INDENT-ON* */
00181 
00182 
00183 /* ------------------------------------------------------------------------- */
00184 /* Reload the contents of the NPX from the global variable `npx'.  */
00185 
00186 static void
00187 load_npx (void)
00188 {
00189   asm ("frstor %0":"=m" (npx));
00190 }
00191 /* ------------------------------------------------------------------------- */
00192 /* Stubs for the missing redirection functions.  */
00193 typedef struct {
00194   char *command;
00195   int redirected;
00196 } cmdline_t;
00197 
00198 void
00199 redir_cmdline_delete (cmdline_t *ptr)
00200 {
00201   ptr->redirected = 0;
00202 }
00203 
00204 int
00205 redir_cmdline_parse (const char *args, cmdline_t *ptr)
00206 {
00207   return -1;
00208 }
00209 
00210 int
00211 redir_to_child (cmdline_t *ptr)
00212 {
00213   return 1;
00214 }
00215 
00216 int
00217 redir_to_debugger (cmdline_t *ptr)
00218 {
00219   return 1;
00220 }
00221 
00222 int
00223 redir_debug_init (cmdline_t *ptr)
00224 {
00225   return 0;
00226 }
00227 #endif /* __DJGPP_MINOR < 3 */
00228 
00229 typedef enum { wp_insert, wp_remove, wp_count } wp_op;
00230 
00231 /* This holds the current reference counts for each debug register.  */
00232 static int dr_ref_count[4];
00233 
00234 #define SOME_PID 42
00235 
00236 static int prog_has_started = 0;
00237 static void go32_open (char *name, int from_tty);
00238 static void go32_close (void);
00239 static void go32_attach (struct target_ops *ops, char *args, int from_tty);
00240 static void go32_detach (struct target_ops *ops, char *args, int from_tty);
00241 static void go32_resume (struct target_ops *ops,
00242                          ptid_t ptid, int step,
00243                          enum gdb_signal siggnal);
00244 static void go32_fetch_registers (struct target_ops *ops,
00245                                   struct regcache *, int regno);
00246 static void store_register (const struct regcache *, int regno);
00247 static void go32_store_registers (struct target_ops *ops,
00248                                   struct regcache *, int regno);
00249 static void go32_prepare_to_store (struct regcache *);
00250 static int go32_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
00251                              int write,
00252                              struct mem_attrib *attrib,
00253                              struct target_ops *target);
00254 static void go32_files_info (struct target_ops *target);
00255 static void go32_kill_inferior (struct target_ops *ops);
00256 static void go32_create_inferior (struct target_ops *ops, char *exec_file,
00257                                   char *args, char **env, int from_tty);
00258 static void go32_mourn_inferior (struct target_ops *ops);
00259 static int go32_can_run (void);
00260 
00261 static struct target_ops go32_ops;
00262 static void go32_terminal_init (void);
00263 static void go32_terminal_inferior (void);
00264 static void go32_terminal_ours (void);
00265 
00266 #define r_ofs(x) (offsetof(TSS,x))
00267 
00268 static struct
00269 {
00270   size_t tss_ofs;
00271   size_t size;
00272 }
00273 regno_mapping[] =
00274 {
00275   {r_ofs (tss_eax), 4}, /* normal registers, from a_tss */
00276   {r_ofs (tss_ecx), 4},
00277   {r_ofs (tss_edx), 4},
00278   {r_ofs (tss_ebx), 4},
00279   {r_ofs (tss_esp), 4},
00280   {r_ofs (tss_ebp), 4},
00281   {r_ofs (tss_esi), 4},
00282   {r_ofs (tss_edi), 4},
00283   {r_ofs (tss_eip), 4},
00284   {r_ofs (tss_eflags), 4},
00285   {r_ofs (tss_cs), 2},
00286   {r_ofs (tss_ss), 2},
00287   {r_ofs (tss_ds), 2},
00288   {r_ofs (tss_es), 2},
00289   {r_ofs (tss_fs), 2},
00290   {r_ofs (tss_gs), 2},
00291   {0, 10},              /* 8 FP registers, from npx.reg[] */
00292   {1, 10},
00293   {2, 10},
00294   {3, 10},
00295   {4, 10},
00296   {5, 10},
00297   {6, 10},
00298   {7, 10},
00299         /* The order of the next 7 registers must be consistent
00300            with their numbering in config/i386/tm-i386.h, which see.  */
00301   {0, 2},               /* control word, from npx */
00302   {4, 2},               /* status word, from npx */
00303   {8, 2},               /* tag word, from npx */
00304   {16, 2},              /* last FP exception CS from npx */
00305   {12, 4},              /* last FP exception EIP from npx */
00306   {24, 2},              /* last FP exception operand selector from npx */
00307   {20, 4},              /* last FP exception operand offset from npx */
00308   {18, 2}               /* last FP opcode from npx */
00309 };
00310 
00311 static struct
00312   {
00313     int go32_sig;
00314     enum gdb_signal gdb_sig;
00315   }
00316 sig_map[] =
00317 {
00318   {0, GDB_SIGNAL_FPE},
00319   {1, GDB_SIGNAL_TRAP},
00320   /* Exception 2 is triggered by the NMI.  DJGPP handles it as SIGILL,
00321      but I think SIGBUS is better, since the NMI is usually activated
00322      as a result of a memory parity check failure.  */
00323   {2, GDB_SIGNAL_BUS},
00324   {3, GDB_SIGNAL_TRAP},
00325   {4, GDB_SIGNAL_FPE},
00326   {5, GDB_SIGNAL_SEGV},
00327   {6, GDB_SIGNAL_ILL},
00328   {7, GDB_SIGNAL_EMT},  /* no-coprocessor exception */
00329   {8, GDB_SIGNAL_SEGV},
00330   {9, GDB_SIGNAL_SEGV},
00331   {10, GDB_SIGNAL_BUS},
00332   {11, GDB_SIGNAL_SEGV},
00333   {12, GDB_SIGNAL_SEGV},
00334   {13, GDB_SIGNAL_SEGV},
00335   {14, GDB_SIGNAL_SEGV},
00336   {16, GDB_SIGNAL_FPE},
00337   {17, GDB_SIGNAL_BUS},
00338   {31, GDB_SIGNAL_ILL},
00339   {0x1b, GDB_SIGNAL_INT},
00340   {0x75, GDB_SIGNAL_FPE},
00341   {0x78, GDB_SIGNAL_ALRM},
00342   {0x79, GDB_SIGNAL_INT},
00343   {0x7a, GDB_SIGNAL_QUIT},
00344   {-1, GDB_SIGNAL_LAST}
00345 };
00346 
00347 static struct {
00348   enum gdb_signal gdb_sig;
00349   int djgpp_excepno;
00350 } excepn_map[] = {
00351   {GDB_SIGNAL_0, -1},
00352   {GDB_SIGNAL_ILL, 6},  /* Invalid Opcode */
00353   {GDB_SIGNAL_EMT, 7},  /* triggers SIGNOFP */
00354   {GDB_SIGNAL_SEGV, 13},        /* GPF */
00355   {GDB_SIGNAL_BUS, 17}, /* Alignment Check */
00356   /* The rest are fake exceptions, see dpmiexcp.c in djlsr*.zip for
00357      details.  */
00358   {GDB_SIGNAL_TERM, 0x1b},      /* triggers Ctrl-Break type of SIGINT */
00359   {GDB_SIGNAL_FPE, 0x75},
00360   {GDB_SIGNAL_INT, 0x79},
00361   {GDB_SIGNAL_QUIT, 0x7a},
00362   {GDB_SIGNAL_ALRM, 0x78},      /* triggers SIGTIMR */
00363   {GDB_SIGNAL_PROF, 0x78},
00364   {GDB_SIGNAL_LAST, -1}
00365 };
00366 
00367 static void
00368 go32_open (char *name, int from_tty)
00369 {
00370   printf_unfiltered ("Done.  Use the \"run\" command to run the program.\n");
00371 }
00372 
00373 static void
00374 go32_close (void)
00375 {
00376 }
00377 
00378 static void
00379 go32_attach (struct target_ops *ops, char *args, int from_tty)
00380 {
00381   error (_("\
00382 You cannot attach to a running program on this platform.\n\
00383 Use the `run' command to run DJGPP programs."));
00384 }
00385 
00386 static void
00387 go32_detach (struct target_ops *ops, char *args, int from_tty)
00388 {
00389 }
00390 
00391 static int resume_is_step;
00392 static int resume_signal = -1;
00393 
00394 static void
00395 go32_resume (struct target_ops *ops,
00396              ptid_t ptid, int step, enum gdb_signal siggnal)
00397 {
00398   int i;
00399 
00400   resume_is_step = step;
00401 
00402   if (siggnal != GDB_SIGNAL_0 && siggnal != GDB_SIGNAL_TRAP)
00403   {
00404     for (i = 0, resume_signal = -1;
00405          excepn_map[i].gdb_sig != GDB_SIGNAL_LAST; i++)
00406       if (excepn_map[i].gdb_sig == siggnal)
00407       {
00408         resume_signal = excepn_map[i].djgpp_excepno;
00409         break;
00410       }
00411     if (resume_signal == -1)
00412       printf_unfiltered ("Cannot deliver signal %s on this platform.\n",
00413                          gdb_signal_to_name (siggnal));
00414   }
00415 }
00416 
00417 static char child_cwd[FILENAME_MAX];
00418 
00419 static ptid_t
00420 go32_wait (struct target_ops *ops,
00421            ptid_t ptid, struct target_waitstatus *status, int options)
00422 {
00423   int i;
00424   unsigned char saved_opcode;
00425   unsigned long INT3_addr = 0;
00426   int stepping_over_INT = 0;
00427 
00428   a_tss.tss_eflags &= 0xfeff;   /* Reset the single-step flag (TF).  */
00429   if (resume_is_step)
00430     {
00431       /* If the next instruction is INT xx or INTO, we need to handle
00432          them specially.  Intel manuals say that these instructions
00433          reset the single-step flag (a.k.a. TF).  However, it seems
00434          that, at least in the DPMI environment, and at least when
00435          stepping over the DPMI interrupt 31h, the problem is having
00436          TF set at all when INT 31h is executed: the debuggee either
00437          crashes (and takes the system with it) or is killed by a
00438          SIGTRAP.
00439 
00440          So we need to emulate single-step mode: we put an INT3 opcode
00441          right after the INT xx instruction, let the debuggee run
00442          until it hits INT3 and stops, then restore the original
00443          instruction which we overwrote with the INT3 opcode, and back
00444          up the debuggee's EIP to that instruction.  */
00445       read_child (a_tss.tss_eip, &saved_opcode, 1);
00446       if (saved_opcode == 0xCD || saved_opcode == 0xCE)
00447         {
00448           unsigned char INT3_opcode = 0xCC;
00449 
00450           INT3_addr
00451             = saved_opcode == 0xCD ? a_tss.tss_eip + 2 : a_tss.tss_eip + 1;
00452           stepping_over_INT = 1;
00453           read_child (INT3_addr, &saved_opcode, 1);
00454           write_child (INT3_addr, &INT3_opcode, 1);
00455         }
00456       else
00457         a_tss.tss_eflags |= 0x0100; /* normal instruction: set TF */
00458     }
00459 
00460   /* The special value FFFFh in tss_trap indicates to run_child that
00461      tss_irqn holds a signal to be delivered to the debuggee.  */
00462   if (resume_signal <= -1)
00463     {
00464       a_tss.tss_trap = 0;
00465       a_tss.tss_irqn = 0xff;
00466     }
00467   else
00468     {
00469       a_tss.tss_trap = 0xffff;  /* run_child looks for this.  */
00470       a_tss.tss_irqn = resume_signal;
00471     }
00472 
00473   /* The child might change working directory behind our back.  The
00474      GDB users won't like the side effects of that when they work with
00475      relative file names, and GDB might be confused by its current
00476      directory not being in sync with the truth.  So we always make a
00477      point of changing back to where GDB thinks is its cwd, when we
00478      return control to the debugger, but restore child's cwd before we
00479      run it.  */
00480   /* Initialize child_cwd, before the first call to run_child and not
00481      in the initialization, so the child get also the changed directory
00482      set with the gdb-command "cd ..."  */
00483   if (!*child_cwd)
00484     /* Initialize child's cwd with the current one.  */
00485     getcwd (child_cwd, sizeof (child_cwd));
00486 
00487   chdir (child_cwd);
00488 
00489 #if __DJGPP_MINOR__ < 3
00490   load_npx ();
00491 #endif
00492   run_child ();
00493 #if __DJGPP_MINOR__ < 3
00494   save_npx ();
00495 #endif
00496 
00497   /* Did we step over an INT xx instruction?  */
00498   if (stepping_over_INT && a_tss.tss_eip == INT3_addr + 1)
00499     {
00500       /* Restore the original opcode.  */
00501       a_tss.tss_eip--;  /* EIP points *after* the INT3 instruction.  */
00502       write_child (a_tss.tss_eip, &saved_opcode, 1);
00503       /* Simulate a TRAP exception.  */
00504       a_tss.tss_irqn = 1;
00505       a_tss.tss_eflags |= 0x0100;
00506     }
00507 
00508   getcwd (child_cwd, sizeof (child_cwd)); /* in case it has changed */
00509   chdir (current_directory);
00510 
00511   if (a_tss.tss_irqn == 0x21)
00512     {
00513       status->kind = TARGET_WAITKIND_EXITED;
00514       status->value.integer = a_tss.tss_eax & 0xff;
00515     }
00516   else
00517     {
00518       status->value.sig = GDB_SIGNAL_UNKNOWN;
00519       status->kind = TARGET_WAITKIND_STOPPED;
00520       for (i = 0; sig_map[i].go32_sig != -1; i++)
00521         {
00522           if (a_tss.tss_irqn == sig_map[i].go32_sig)
00523             {
00524 #if __DJGPP_MINOR__ < 3
00525               if ((status->value.sig = sig_map[i].gdb_sig) !=
00526                   GDB_SIGNAL_TRAP)
00527                 status->kind = TARGET_WAITKIND_SIGNALLED;
00528 #else
00529               status->value.sig = sig_map[i].gdb_sig;
00530 #endif
00531               break;
00532             }
00533         }
00534     }
00535   return pid_to_ptid (SOME_PID);
00536 }
00537 
00538 static void
00539 fetch_register (struct regcache *regcache, int regno)
00540 {
00541   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00542   if (regno < gdbarch_fp0_regnum (gdbarch))
00543     regcache_raw_supply (regcache, regno,
00544                          (char *) &a_tss + regno_mapping[regno].tss_ofs);
00545   else if (i386_fp_regnum_p (gdbarch, regno) || i386_fpc_regnum_p (gdbarch,
00546                                                                    regno))
00547     i387_supply_fsave (regcache, regno, &npx);
00548   else
00549     internal_error (__FILE__, __LINE__,
00550                     _("Invalid register no. %d in fetch_register."), regno);
00551 }
00552 
00553 static void
00554 go32_fetch_registers (struct target_ops *ops,
00555                       struct regcache *regcache, int regno)
00556 {
00557   if (regno >= 0)
00558     fetch_register (regcache, regno);
00559   else
00560     {
00561       for (regno = 0;
00562            regno < gdbarch_fp0_regnum (get_regcache_arch (regcache));
00563            regno++)
00564         fetch_register (regcache, regno);
00565       i387_supply_fsave (regcache, -1, &npx);
00566     }
00567 }
00568 
00569 static void
00570 store_register (const struct regcache *regcache, int regno)
00571 {
00572   struct gdbarch *gdbarch = get_regcache_arch (regcache);
00573   if (regno < gdbarch_fp0_regnum (gdbarch))
00574     regcache_raw_collect (regcache, regno,
00575                           (char *) &a_tss + regno_mapping[regno].tss_ofs);
00576   else if (i386_fp_regnum_p (gdbarch, regno) || i386_fpc_regnum_p (gdbarch,
00577                                                                    regno))
00578     i387_collect_fsave (regcache, regno, &npx);
00579   else
00580     internal_error (__FILE__, __LINE__,
00581                     _("Invalid register no. %d in store_register."), regno);
00582 }
00583 
00584 static void
00585 go32_store_registers (struct target_ops *ops,
00586                       struct regcache *regcache, int regno)
00587 {
00588   unsigned r;
00589 
00590   if (regno >= 0)
00591     store_register (regcache, regno);
00592   else
00593     {
00594       for (r = 0; r < gdbarch_fp0_regnum (get_regcache_arch (regcache)); r++)
00595         store_register (regcache, r);
00596       i387_collect_fsave (regcache, -1, &npx);
00597     }
00598 }
00599 
00600 static void
00601 go32_prepare_to_store (struct regcache *regcache)
00602 {
00603 }
00604 
00605 static int
00606 go32_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write,
00607                   struct mem_attrib *attrib, struct target_ops *target)
00608 {
00609   if (write)
00610     {
00611       if (write_child (memaddr, myaddr, len))
00612         {
00613           return 0;
00614         }
00615       else
00616         {
00617           return len;
00618         }
00619     }
00620   else
00621     {
00622       if (read_child (memaddr, myaddr, len))
00623         {
00624           return 0;
00625         }
00626       else
00627         {
00628           return len;
00629         }
00630     }
00631 }
00632 
00633 static cmdline_t child_cmd;     /* Parsed child's command line kept here.  */
00634 
00635 static void
00636 go32_files_info (struct target_ops *target)
00637 {
00638   printf_unfiltered ("You are running a DJGPP V2 program.\n");
00639 }
00640 
00641 static void
00642 go32_kill_inferior (struct target_ops *ops)
00643 {
00644   go32_mourn_inferior (ops);
00645 }
00646 
00647 static void
00648 go32_create_inferior (struct target_ops *ops, char *exec_file,
00649                       char *args, char **env, int from_tty)
00650 {
00651   extern char **environ;
00652   jmp_buf start_state;
00653   char *cmdline;
00654   char **env_save = environ;
00655   size_t cmdlen;
00656   struct inferior *inf;
00657 
00658   /* If no exec file handed to us, get it from the exec-file command -- with
00659      a good, common error message if none is specified.  */
00660   if (exec_file == 0)
00661     exec_file = get_exec_file (1);
00662 
00663   resume_signal = -1;
00664   resume_is_step = 0;
00665 
00666   /* Initialize child's cwd as empty to be initialized when starting
00667      the child.  */
00668   *child_cwd = 0;
00669 
00670   /* Init command line storage.  */
00671   if (redir_debug_init (&child_cmd) == -1)
00672     internal_error (__FILE__, __LINE__,
00673                     _("Cannot allocate redirection storage: "
00674                       "not enough memory.\n"));
00675 
00676   /* Parse the command line and create redirections.  */
00677   if (strpbrk (args, "<>"))
00678     {
00679       if (redir_cmdline_parse (args, &child_cmd) == 0)
00680         args = child_cmd.command;
00681       else
00682         error (_("Syntax error in command line."));
00683     }
00684   else
00685     child_cmd.command = xstrdup (args);
00686 
00687   cmdlen = strlen (args);
00688   /* v2loadimage passes command lines via DOS memory, so it cannot
00689      possibly handle commands longer than 1MB.  */
00690   if (cmdlen > 1024*1024)
00691     error (_("Command line too long."));
00692 
00693   cmdline = xmalloc (cmdlen + 4);
00694   strcpy (cmdline + 1, args);
00695   /* If the command-line length fits into DOS 126-char limits, use the
00696      DOS command tail format; otherwise, tell v2loadimage to pass it
00697      through a buffer in conventional memory.  */
00698   if (cmdlen < 127)
00699     {
00700       cmdline[0] = strlen (args);
00701       cmdline[cmdlen + 1] = 13;
00702     }
00703   else
00704     cmdline[0] = 0xff;  /* Signal v2loadimage it's a long command.  */
00705 
00706   environ = env;
00707 
00708   if (v2loadimage (exec_file, cmdline, start_state))
00709     {
00710       environ = env_save;
00711       printf_unfiltered ("Load failed for image %s\n", exec_file);
00712       exit (1);
00713     }
00714   environ = env_save;
00715   xfree (cmdline);
00716 
00717   edi_init (start_state);
00718 #if __DJGPP_MINOR__ < 3
00719   save_npx ();
00720 #endif
00721 
00722   inferior_ptid = pid_to_ptid (SOME_PID);
00723   inf = current_inferior ();
00724   inferior_appeared (inf, SOME_PID);
00725 
00726   push_target (&go32_ops);
00727 
00728   add_thread_silent (inferior_ptid);
00729 
00730   clear_proceed_status ();
00731   insert_breakpoints ();
00732   prog_has_started = 1;
00733 }
00734 
00735 static void
00736 go32_mourn_inferior (struct target_ops *ops)
00737 {
00738   ptid_t ptid;
00739 
00740   redir_cmdline_delete (&child_cmd);
00741   resume_signal = -1;
00742   resume_is_step = 0;
00743 
00744   cleanup_client ();
00745 
00746   /* We need to make sure all the breakpoint enable bits in the DR7
00747      register are reset when the inferior exits.  Otherwise, if they
00748      rerun the inferior, the uncleared bits may cause random SIGTRAPs,
00749      failure to set more watchpoints, and other calamities.  It would
00750      be nice if GDB itself would take care to remove all breakpoints
00751      at all times, but it doesn't, probably under an assumption that
00752      the OS cleans up when the debuggee exits.  */
00753   i386_cleanup_dregs ();
00754 
00755   ptid = inferior_ptid;
00756   inferior_ptid = null_ptid;
00757   delete_thread_silent (ptid);
00758   prog_has_started = 0;
00759 
00760   unpush_target (ops);
00761   generic_mourn_inferior ();
00762 }
00763 
00764 static int
00765 go32_can_run (void)
00766 {
00767   return 1;
00768 }
00769 
00770 /* Hardware watchpoint support.  */
00771 
00772 #define D_REGS edi.dr
00773 #define CONTROL D_REGS[7]
00774 #define STATUS D_REGS[6]
00775 
00776 /* Pass the address ADDR to the inferior in the I'th debug register.
00777    Here we just store the address in D_REGS, the watchpoint will be
00778    actually set up when go32_wait runs the debuggee.  */
00779 static void
00780 go32_set_dr (int i, CORE_ADDR addr)
00781 {
00782   if (i < 0 || i > 3)
00783     internal_error (__FILE__, __LINE__, 
00784                     _("Invalid register %d in go32_set_dr.\n"), i);
00785   D_REGS[i] = addr;
00786 }
00787 
00788 /* Pass the value VAL to the inferior in the DR7 debug control
00789    register.  Here we just store the address in D_REGS, the watchpoint
00790    will be actually set up when go32_wait runs the debuggee.  */
00791 static void
00792 go32_set_dr7 (unsigned long val)
00793 {
00794   CONTROL = val;
00795 }
00796 
00797 /* Get the value of the DR6 debug status register from the inferior.
00798    Here we just return the value stored in D_REGS, as we've got it
00799    from the last go32_wait call.  */
00800 static unsigned long
00801 go32_get_dr6 (void)
00802 {
00803   return STATUS;
00804 }
00805 
00806 /* Get the value of the DR7 debug status register from the inferior.
00807    Here we just return the value stored in D_REGS, as we've got it
00808    from the last go32_wait call.  */
00809 
00810 static unsigned long
00811 go32_get_dr7 (void)
00812 {
00813   return CONTROL;
00814 }
00815 
00816 /* Get the value of the DR debug register I from the inferior.  Here
00817    we just return the value stored in D_REGS, as we've got it from the
00818    last go32_wait call.  */
00819 
00820 static CORE_ADDR
00821 go32_get_dr (int i)
00822 {
00823   if (i < 0 || i > 3)
00824     internal_error (__FILE__, __LINE__,
00825                     _("Invalid register %d in go32_get_dr.\n"), i);
00826   return D_REGS[i];
00827 }
00828 
00829 /* Put the device open on handle FD into either raw or cooked
00830    mode, return 1 if it was in raw mode, zero otherwise.  */
00831 
00832 static int
00833 device_mode (int fd, int raw_p)
00834 {
00835   int oldmode, newmode;
00836   __dpmi_regs regs;
00837 
00838   regs.x.ax = 0x4400;
00839   regs.x.bx = fd;
00840   __dpmi_int (0x21, &regs);
00841   if (regs.x.flags & 1)
00842     return -1;
00843   newmode = oldmode = regs.x.dx;
00844 
00845   if (raw_p)
00846     newmode |= 0x20;
00847   else
00848     newmode &= ~0x20;
00849 
00850   if (oldmode & 0x80)   /* Only for character dev.  */
00851   {
00852     regs.x.ax = 0x4401;
00853     regs.x.bx = fd;
00854     regs.x.dx = newmode & 0xff;   /* Force upper byte zero, else it fails.  */
00855     __dpmi_int (0x21, &regs);
00856     if (regs.x.flags & 1)
00857       return -1;
00858   }
00859   return (oldmode & 0x20) == 0x20;
00860 }
00861 
00862 
00863 static int inf_mode_valid = 0;
00864 static int inf_terminal_mode;
00865 
00866 /* This semaphore is needed because, amazingly enough, GDB calls
00867    target.to_terminal_ours more than once after the inferior stops.
00868    But we need the information from the first call only, since the
00869    second call will always see GDB's own cooked terminal.  */
00870 static int terminal_is_ours = 1;
00871 
00872 static void
00873 go32_terminal_init (void)
00874 {
00875   inf_mode_valid = 0;   /* Reinitialize, in case they are restarting child.  */
00876   terminal_is_ours = 1;
00877 }
00878 
00879 static void
00880 go32_terminal_info (const char *args, int from_tty)
00881 {
00882   printf_unfiltered ("Inferior's terminal is in %s mode.\n",
00883                      !inf_mode_valid
00884                      ? "default" : inf_terminal_mode ? "raw" : "cooked");
00885 
00886 #if __DJGPP_MINOR__ > 2
00887   if (child_cmd.redirection)
00888   {
00889     int i;
00890 
00891     for (i = 0; i < DBG_HANDLES; i++)
00892     {
00893       if (child_cmd.redirection[i]->file_name)
00894         printf_unfiltered ("\tFile handle %d is redirected to `%s'.\n",
00895                            i, child_cmd.redirection[i]->file_name);
00896       else if (_get_dev_info (child_cmd.redirection[i]->inf_handle) == -1)
00897         printf_unfiltered
00898           ("\tFile handle %d appears to be closed by inferior.\n", i);
00899       /* Mask off the raw/cooked bit when comparing device info words.  */
00900       else if ((_get_dev_info (child_cmd.redirection[i]->inf_handle) & 0xdf)
00901                != (_get_dev_info (i) & 0xdf))
00902         printf_unfiltered
00903           ("\tFile handle %d appears to be redirected by inferior.\n", i);
00904     }
00905   }
00906 #endif
00907 }
00908 
00909 static void
00910 go32_terminal_inferior (void)
00911 {
00912   /* Redirect standard handles as child wants them.  */
00913   errno = 0;
00914   if (redir_to_child (&child_cmd) == -1)
00915   {
00916     redir_to_debugger (&child_cmd);
00917     error (_("Cannot redirect standard handles for program: %s."),
00918            safe_strerror (errno));
00919   }
00920   /* Set the console device of the inferior to whatever mode
00921      (raw or cooked) we found it last time.  */
00922   if (terminal_is_ours)
00923   {
00924     if (inf_mode_valid)
00925       device_mode (0, inf_terminal_mode);
00926     terminal_is_ours = 0;
00927   }
00928 }
00929 
00930 static void
00931 go32_terminal_ours (void)
00932 {
00933   /* Switch to cooked mode on the gdb terminal and save the inferior
00934      terminal mode to be restored when it is resumed.  */
00935   if (!terminal_is_ours)
00936   {
00937     inf_terminal_mode = device_mode (0, 0);
00938     if (inf_terminal_mode != -1)
00939       inf_mode_valid = 1;
00940     else
00941       /* If device_mode returned -1, we don't know what happens with
00942          handle 0 anymore, so make the info invalid.  */
00943       inf_mode_valid = 0;
00944     terminal_is_ours = 1;
00945 
00946     /* Restore debugger's standard handles.  */
00947     errno = 0;
00948     if (redir_to_debugger (&child_cmd) == -1)
00949     {
00950       redir_to_child (&child_cmd);
00951       error (_("Cannot redirect standard handles for debugger: %s."),
00952              safe_strerror (errno));
00953     }
00954   }
00955 }
00956 
00957 static int
00958 go32_thread_alive (struct target_ops *ops, ptid_t ptid)
00959 {
00960   return !ptid_equal (inferior_ptid, null_ptid);
00961 }
00962 
00963 static char *
00964 go32_pid_to_str (struct target_ops *ops, ptid_t ptid)
00965 {
00966   return normal_pid_to_str (ptid);
00967 }
00968 
00969 static void
00970 init_go32_ops (void)
00971 {
00972   go32_ops.to_shortname = "djgpp";
00973   go32_ops.to_longname = "djgpp target process";
00974   go32_ops.to_doc =
00975     "Program loaded by djgpp, when gdb is used as an external debugger";
00976   go32_ops.to_open = go32_open;
00977   go32_ops.to_close = go32_close;
00978   go32_ops.to_attach = go32_attach;
00979   go32_ops.to_detach = go32_detach;
00980   go32_ops.to_resume = go32_resume;
00981   go32_ops.to_wait = go32_wait;
00982   go32_ops.to_fetch_registers = go32_fetch_registers;
00983   go32_ops.to_store_registers = go32_store_registers;
00984   go32_ops.to_prepare_to_store = go32_prepare_to_store;
00985   go32_ops.deprecated_xfer_memory = go32_xfer_memory;
00986   go32_ops.to_files_info = go32_files_info;
00987   go32_ops.to_insert_breakpoint = memory_insert_breakpoint;
00988   go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
00989   go32_ops.to_terminal_init = go32_terminal_init;
00990   go32_ops.to_terminal_inferior = go32_terminal_inferior;
00991   go32_ops.to_terminal_ours_for_output = go32_terminal_ours;
00992   go32_ops.to_terminal_ours = go32_terminal_ours;
00993   go32_ops.to_terminal_info = go32_terminal_info;
00994   go32_ops.to_kill = go32_kill_inferior;
00995   go32_ops.to_create_inferior = go32_create_inferior;
00996   go32_ops.to_mourn_inferior = go32_mourn_inferior;
00997   go32_ops.to_can_run = go32_can_run;
00998   go32_ops.to_thread_alive = go32_thread_alive;
00999   go32_ops.to_pid_to_str = go32_pid_to_str;
01000   go32_ops.to_stratum = process_stratum;
01001   go32_ops.to_has_all_memory = default_child_has_all_memory;
01002   go32_ops.to_has_memory = default_child_has_memory;
01003   go32_ops.to_has_stack = default_child_has_stack;
01004   go32_ops.to_has_registers = default_child_has_registers;
01005   go32_ops.to_has_execution = default_child_has_execution;
01006 
01007   i386_use_watchpoints (&go32_ops);
01008 
01009 
01010   i386_dr_low.set_control = go32_set_dr7;
01011   i386_dr_low.set_addr = go32_set_dr;
01012   i386_dr_low.get_status = go32_get_dr6;
01013   i386_dr_low.get_control = go32_get_dr7;
01014   i386_dr_low.get_addr = go32_get_dr;
01015   i386_set_debug_register_length (4);
01016 
01017   go32_ops.to_magic = OPS_MAGIC;
01018 
01019   /* Initialize child's cwd as empty to be initialized when starting
01020      the child.  */
01021   *child_cwd = 0;
01022 
01023   /* Initialize child's command line storage.  */
01024   if (redir_debug_init (&child_cmd) == -1)
01025     internal_error (__FILE__, __LINE__,
01026                     _("Cannot allocate redirection storage: "
01027                       "not enough memory.\n"));
01028 
01029   /* We are always processing GCC-compiled programs.  */
01030   processing_gcc_compilation = 2;
01031 }
01032 
01033 /* Return the current DOS codepage number.  */
01034 static int
01035 dos_codepage (void)
01036 {
01037   __dpmi_regs regs;
01038 
01039   regs.x.ax = 0x6601;
01040   __dpmi_int (0x21, &regs);
01041   if (!(regs.x.flags & 1))
01042     return regs.x.bx & 0xffff;
01043   else
01044     return 437; /* default */
01045 }
01046 
01047 /* Limited emulation of `nl_langinfo', for charset.c.  */
01048 char *
01049 nl_langinfo (nl_item item)
01050 {
01051   char *retval;
01052 
01053   switch (item)
01054     {
01055       case CODESET:
01056         {
01057           /* 8 is enough for SHORT_MAX + "CP" + null.  */
01058           char buf[8];
01059           int blen = sizeof (buf);
01060           int needed = snprintf (buf, blen, "CP%d", dos_codepage ());
01061 
01062           if (needed > blen)    /* Should never happen.  */
01063             buf[0] = 0;
01064           retval = xstrdup (buf);
01065         }
01066         break;
01067       default:
01068         retval = xstrdup ("");
01069         break;
01070     }
01071   return retval;
01072 }
01073 
01074 unsigned short windows_major, windows_minor;
01075 
01076 /* Compute the version Windows reports via Int 2Fh/AX=1600h.  */
01077 static void
01078 go32_get_windows_version(void)
01079 {
01080   __dpmi_regs r;
01081 
01082   r.x.ax = 0x1600;
01083   __dpmi_int(0x2f, &r);
01084   if (r.h.al > 2 && r.h.al != 0x80 && r.h.al != 0xff
01085       && (r.h.al > 3 || r.h.ah > 0))
01086     {
01087       windows_major = r.h.al;
01088       windows_minor = r.h.ah;
01089     }
01090   else
01091     windows_major = 0xff;       /* meaning no Windows */
01092 }
01093 
01094 /* A subroutine of go32_sysinfo to display memory info.  */
01095 static void
01096 print_mem (unsigned long datum, const char *header, int in_pages_p)
01097 {
01098   if (datum != 0xffffffffUL)
01099     {
01100       if (in_pages_p)
01101         datum <<= 12;
01102       puts_filtered (header);
01103       if (datum > 1024)
01104         {
01105           printf_filtered ("%lu KB", datum >> 10);
01106           if (datum > 1024 * 1024)
01107             printf_filtered (" (%lu MB)", datum >> 20);
01108         }
01109       else
01110         printf_filtered ("%lu Bytes", datum);
01111       puts_filtered ("\n");
01112     }
01113 }
01114 
01115 /* Display assorted information about the underlying OS.  */
01116 static void
01117 go32_sysinfo (char *arg, int from_tty)
01118 {
01119   static const char test_pattern[] =
01120     "deadbeafdeadbeafdeadbeafdeadbeafdeadbeaf"
01121     "deadbeafdeadbeafdeadbeafdeadbeafdeadbeaf"
01122     "deadbeafdeadbeafdeadbeafdeadbeafdeadbeafdeadbeaf";
01123   struct utsname u;
01124   char cpuid_vendor[13];
01125   unsigned cpuid_max = 0, cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
01126   unsigned true_dos_version = _get_dos_version (1);
01127   unsigned advertized_dos_version = ((unsigned int)_osmajor << 8) | _osminor;
01128   int dpmi_flags;
01129   char dpmi_vendor_info[129];
01130   int dpmi_vendor_available;
01131   __dpmi_version_ret dpmi_version_data;
01132   long eflags;
01133   __dpmi_free_mem_info mem_info;
01134   __dpmi_regs regs;
01135 
01136   cpuid_vendor[0] = '\0';
01137   if (uname (&u))
01138     strcpy (u.machine, "Unknown x86");
01139   else if (u.machine[0] == 'i' && u.machine[1] > 4)
01140     {
01141       /* CPUID with EAX = 0 returns the Vendor ID.  */
01142 #if 0
01143       /* Ideally we would use i386_cpuid(), but it needs someone to run
01144          native tests first to make sure things actually work.  They should.
01145          http://sourceware.org/ml/gdb-patches/2013-05/msg00164.html  */
01146       unsigned int eax, ebx, ecx, edx;
01147 
01148       if (i386_cpuid (0, &eax, &ebx, &ecx, &edx))
01149         {
01150           cpuid_max = eax;
01151           memcpy (&vendor[0], &ebx, 4);
01152           memcpy (&vendor[4], &ecx, 4);
01153           memcpy (&vendor[8], &edx, 4);
01154           cpuid_vendor[12] = '\0';
01155         }
01156 #else
01157       __asm__ __volatile__ ("xorl   %%ebx, %%ebx;"
01158                             "xorl   %%ecx, %%ecx;"
01159                             "xorl   %%edx, %%edx;"
01160                             "movl   $0,    %%eax;"
01161                             "cpuid;"
01162                             "movl   %%ebx,  %0;"
01163                             "movl   %%edx,  %1;"
01164                             "movl   %%ecx,  %2;"
01165                             "movl   %%eax,  %3;"
01166                             : "=m" (cpuid_vendor[0]),
01167                               "=m" (cpuid_vendor[4]),
01168                               "=m" (cpuid_vendor[8]),
01169                               "=m" (cpuid_max)
01170                             :
01171                             : "%eax", "%ebx", "%ecx", "%edx");
01172       cpuid_vendor[12] = '\0';
01173 #endif
01174     }
01175 
01176   printf_filtered ("CPU Type.......................%s", u.machine);
01177   if (cpuid_vendor[0])
01178     printf_filtered (" (%s)", cpuid_vendor);
01179   puts_filtered ("\n");
01180 
01181   /* CPUID with EAX = 1 returns processor signature and features.  */
01182   if (cpuid_max >= 1)
01183     {
01184       static char *brand_name[] = {
01185         "",
01186         " Celeron",
01187         " III",
01188         " III Xeon",
01189         "", "", "", "",
01190         " 4"
01191       };
01192       char cpu_string[80];
01193       char cpu_brand[20];
01194       unsigned brand_idx;
01195       int intel_p = strcmp (cpuid_vendor, "GenuineIntel") == 0;
01196       int amd_p = strcmp (cpuid_vendor, "AuthenticAMD") == 0;
01197       unsigned cpu_family, cpu_model;
01198 
01199 #if 0
01200       /* See comment above about cpuid usage.  */
01201       i386_cpuid (1, &cpuid_eax, &cpuid_ebx, NULL, &cpuid_edx);
01202 #else
01203       __asm__ __volatile__ ("movl   $1, %%eax;"
01204                             "cpuid;"
01205                             : "=a" (cpuid_eax),
01206                               "=b" (cpuid_ebx),
01207                               "=d" (cpuid_edx)
01208                             :
01209                             : "%ecx");
01210 #endif
01211       brand_idx = cpuid_ebx & 0xff;
01212       cpu_family = (cpuid_eax >> 8) & 0xf;
01213       cpu_model  = (cpuid_eax >> 4) & 0xf;
01214       cpu_brand[0] = '\0';
01215       if (intel_p)
01216         {
01217           if (brand_idx > 0
01218               && brand_idx < sizeof(brand_name)/sizeof(brand_name[0])
01219               && *brand_name[brand_idx])
01220             strcpy (cpu_brand, brand_name[brand_idx]);
01221           else if (cpu_family == 5)
01222             {
01223               if (((cpuid_eax >> 12) & 3) == 0 && cpu_model == 4)
01224                 strcpy (cpu_brand, " MMX");
01225               else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 1)
01226                 strcpy (cpu_brand, " OverDrive");
01227               else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 2)
01228                 strcpy (cpu_brand, " Dual");
01229             }
01230           else if (cpu_family == 6 && cpu_model < 8)
01231             {
01232               switch (cpu_model)
01233                 {
01234                   case 1:
01235                     strcpy (cpu_brand, " Pro");
01236                     break;
01237                   case 3:
01238                     strcpy (cpu_brand, " II");
01239                     break;
01240                   case 5:
01241                     strcpy (cpu_brand, " II Xeon");
01242                     break;
01243                   case 6:
01244                     strcpy (cpu_brand, " Celeron");
01245                     break;
01246                   case 7:
01247                     strcpy (cpu_brand, " III");
01248                     break;
01249                 }
01250             }
01251         }
01252       else if (amd_p)
01253         {
01254           switch (cpu_family)
01255             {
01256               case 4:
01257                 strcpy (cpu_brand, "486/5x86");
01258                 break;
01259               case 5:
01260                 switch (cpu_model)
01261                   {
01262                     case 0:
01263                     case 1:
01264                     case 2:
01265                     case 3:
01266                       strcpy (cpu_brand, "-K5");
01267                       break;
01268                     case 6:
01269                     case 7:
01270                       strcpy (cpu_brand, "-K6");
01271                       break;
01272                     case 8:
01273                       strcpy (cpu_brand, "-K6-2");
01274                       break;
01275                     case 9:
01276                       strcpy (cpu_brand, "-K6-III");
01277                       break;
01278                   }
01279                 break;
01280               case 6:
01281                 switch (cpu_model)
01282                   {
01283                     case 1:
01284                     case 2:
01285                     case 4:
01286                       strcpy (cpu_brand, " Athlon");
01287                       break;
01288                     case 3:
01289                       strcpy (cpu_brand, " Duron");
01290                       break;
01291                   }
01292                 break;
01293             }
01294         }
01295       xsnprintf (cpu_string, sizeof (cpu_string), "%s%s Model %d Stepping %d",
01296                  intel_p ? "Pentium" : (amd_p ? "AMD" : "ix86"),
01297                  cpu_brand, cpu_model, cpuid_eax & 0xf);
01298       printfi_filtered (31, "%s\n", cpu_string);
01299       if (((cpuid_edx & (6 | (0x0d << 23))) != 0)
01300           || ((cpuid_edx & 1) == 0)
01301           || (amd_p && (cpuid_edx & (3 << 30)) != 0))
01302         {
01303           puts_filtered ("CPU Features...................");
01304           /* We only list features which might be useful in the DPMI
01305              environment.  */
01306           if ((cpuid_edx & 1) == 0)
01307             puts_filtered ("No FPU "); /* It's unusual to not have an FPU.  */
01308           if ((cpuid_edx & (1 << 1)) != 0)
01309             puts_filtered ("VME ");
01310           if ((cpuid_edx & (1 << 2)) != 0)
01311             puts_filtered ("DE ");
01312           if ((cpuid_edx & (1 << 4)) != 0)
01313             puts_filtered ("TSC ");
01314           if ((cpuid_edx & (1 << 23)) != 0)
01315             puts_filtered ("MMX ");
01316           if ((cpuid_edx & (1 << 25)) != 0)
01317             puts_filtered ("SSE ");
01318           if ((cpuid_edx & (1 << 26)) != 0)
01319             puts_filtered ("SSE2 ");
01320           if (amd_p)
01321             {
01322               if ((cpuid_edx & (1 << 31)) != 0)
01323                 puts_filtered ("3DNow! ");
01324               if ((cpuid_edx & (1 << 30)) != 0)
01325                 puts_filtered ("3DNow!Ext");
01326             }
01327           puts_filtered ("\n");
01328         }
01329     }
01330   puts_filtered ("\n");
01331   printf_filtered ("DOS Version....................%s %s.%s",
01332                    _os_flavor, u.release, u.version);
01333   if (true_dos_version != advertized_dos_version)
01334     printf_filtered (" (disguised as v%d.%d)", _osmajor, _osminor);
01335   puts_filtered ("\n");
01336   if (!windows_major)
01337     go32_get_windows_version ();
01338   if (windows_major != 0xff)
01339     {
01340       const char *windows_flavor;
01341 
01342       printf_filtered ("Windows Version................%d.%02d (Windows ",
01343                        windows_major, windows_minor);
01344       switch (windows_major)
01345         {
01346           case 3:
01347             windows_flavor = "3.X";
01348             break;
01349           case 4:
01350             switch (windows_minor)
01351               {
01352                 case 0:
01353                   windows_flavor = "95, 95A, or 95B";
01354                   break;
01355                 case 3:
01356                   windows_flavor = "95B OSR2.1 or 95C OSR2.5";
01357                   break;
01358                 case 10:
01359                   windows_flavor = "98 or 98 SE";
01360                   break;
01361                 case 90:
01362                   windows_flavor = "ME";
01363                   break;
01364                 default:
01365                   windows_flavor = "9X";
01366                   break;
01367               }
01368             break;
01369           default:
01370             windows_flavor = "??";
01371             break;
01372         }
01373       printf_filtered ("%s)\n", windows_flavor);
01374     }
01375   else if (true_dos_version == 0x532 && advertized_dos_version == 0x500)
01376     printf_filtered ("Windows Version................"
01377                      "Windows NT family (W2K/XP/W2K3/Vista/W2K8)\n");
01378   puts_filtered ("\n");
01379   /* On some versions of Windows, __dpmi_get_capabilities returns
01380      zero, but the buffer is not filled with info, so we fill the
01381      buffer with a known pattern and test for it afterwards.  */
01382   memcpy (dpmi_vendor_info, test_pattern, sizeof(dpmi_vendor_info));
01383   dpmi_vendor_available =
01384     __dpmi_get_capabilities (&dpmi_flags, dpmi_vendor_info);
01385   if (dpmi_vendor_available == 0
01386       && memcmp (dpmi_vendor_info, test_pattern,
01387                  sizeof(dpmi_vendor_info)) != 0)
01388     {
01389       /* The DPMI spec says the vendor string should be ASCIIZ, but
01390          I don't trust the vendors to follow that...  */
01391       if (!memchr (&dpmi_vendor_info[2], 0, 126))
01392         dpmi_vendor_info[128] = '\0';
01393       printf_filtered ("DPMI Host......................"
01394                        "%s v%d.%d (capabilities: %#x)\n",
01395                        &dpmi_vendor_info[2],
01396                        (unsigned)dpmi_vendor_info[0],
01397                        (unsigned)dpmi_vendor_info[1],
01398                        ((unsigned)dpmi_flags & 0x7f));
01399     }
01400   else
01401     printf_filtered ("DPMI Host......................(Info not available)\n");
01402   __dpmi_get_version (&dpmi_version_data);
01403   printf_filtered ("DPMI Version...................%d.%02d\n",
01404                    dpmi_version_data.major, dpmi_version_data.minor);
01405   printf_filtered ("DPMI Info......................"
01406                    "%s-bit DPMI, with%s Virtual Memory support\n",
01407                    (dpmi_version_data.flags & 1) ? "32" : "16",
01408                    (dpmi_version_data.flags & 4) ? "" : "out");
01409   printfi_filtered (31, "Interrupts reflected to %s mode\n",
01410                    (dpmi_version_data.flags & 2) ? "V86" : "Real");
01411   printfi_filtered (31, "Processor type: i%d86\n",
01412                    dpmi_version_data.cpu);
01413   printfi_filtered (31, "PIC base interrupt: Master: %#x  Slave: %#x\n",
01414                    dpmi_version_data.master_pic, dpmi_version_data.slave_pic);
01415 
01416   /* a_tss is only initialized when the debuggee is first run.  */
01417   if (prog_has_started)
01418     {
01419       __asm__ __volatile__ ("pushfl ; popl %0" : "=g" (eflags));
01420       printf_filtered ("Protection....................."
01421                        "Ring %d (in %s), with%s I/O protection\n",
01422                        a_tss.tss_cs & 3, (a_tss.tss_cs & 4) ? "LDT" : "GDT",
01423                        (a_tss.tss_cs & 3) > ((eflags >> 12) & 3) ? "" : "out");
01424     }
01425   puts_filtered ("\n");
01426   __dpmi_get_free_memory_information (&mem_info);
01427   print_mem (mem_info.total_number_of_physical_pages,
01428              "DPMI Total Physical Memory.....", 1);
01429   print_mem (mem_info.total_number_of_free_pages,
01430              "DPMI Free Physical Memory......", 1);
01431   print_mem (mem_info.size_of_paging_file_partition_in_pages,
01432              "DPMI Swap Space................", 1);
01433   print_mem (mem_info.linear_address_space_size_in_pages,
01434              "DPMI Total Linear Address Size.", 1);
01435   print_mem (mem_info.free_linear_address_space_in_pages,
01436              "DPMI Free Linear Address Size..", 1);
01437   print_mem (mem_info.largest_available_free_block_in_bytes,
01438              "DPMI Largest Free Memory Block.", 0);
01439 
01440   regs.h.ah = 0x48;
01441   regs.x.bx = 0xffff;
01442   __dpmi_int (0x21, &regs);
01443   print_mem (regs.x.bx << 4, "Free DOS Memory................", 0);
01444   regs.x.ax = 0x5800;
01445   __dpmi_int (0x21, &regs);
01446   if ((regs.x.flags & 1) == 0)
01447     {
01448       static const char *dos_hilo[] = {
01449         "Low", "", "", "", "High", "", "", "", "High, then Low"
01450       };
01451       static const char *dos_fit[] = {
01452         "First", "Best", "Last"
01453       };
01454       int hilo_idx = (regs.x.ax >> 4) & 0x0f;
01455       int fit_idx  = regs.x.ax & 0x0f;
01456 
01457       if (hilo_idx > 8)
01458         hilo_idx = 0;
01459       if (fit_idx > 2)
01460         fit_idx = 0;
01461       printf_filtered ("DOS Memory Allocation..........%s memory, %s fit\n",
01462                        dos_hilo[hilo_idx], dos_fit[fit_idx]);
01463       regs.x.ax = 0x5802;
01464       __dpmi_int (0x21, &regs);
01465       if ((regs.x.flags & 1) != 0)
01466         regs.h.al = 0;
01467       printfi_filtered (31, "UMBs %sin DOS memory chain\n",
01468                         regs.h.al == 0 ? "not " : "");
01469     }
01470 }
01471 
01472 struct seg_descr {
01473   unsigned short limit0;
01474   unsigned short base0;
01475   unsigned char  base1;
01476   unsigned       stype:5;
01477   unsigned       dpl:2;
01478   unsigned       present:1;
01479   unsigned       limit1:4;
01480   unsigned       available:1;
01481   unsigned       dummy:1;
01482   unsigned       bit32:1;
01483   unsigned       page_granular:1;
01484   unsigned char  base2;
01485 } __attribute__ ((packed));
01486 
01487 struct gate_descr {
01488   unsigned short offset0;
01489   unsigned short selector;
01490   unsigned       param_count:5;
01491   unsigned       dummy:3;
01492   unsigned       stype:5;
01493   unsigned       dpl:2;
01494   unsigned       present:1;
01495   unsigned short offset1;
01496 } __attribute__ ((packed));
01497 
01498 /* Read LEN bytes starting at logical address ADDR, and put the result
01499    into DEST.  Return 1 if success, zero if not.  */
01500 static int
01501 read_memory_region (unsigned long addr, void *dest, size_t len)
01502 {
01503   unsigned long dos_ds_limit = __dpmi_get_segment_limit (_dos_ds);
01504   int retval = 1;
01505 
01506   /* For the low memory, we can simply use _dos_ds.  */
01507   if (addr <= dos_ds_limit - len)
01508     dosmemget (addr, len, dest);
01509   else
01510     {
01511       /* For memory above 1MB we need to set up a special segment to
01512          be able to access that memory.  */
01513       int sel = __dpmi_allocate_ldt_descriptors (1);
01514 
01515       if (sel <= 0)
01516         retval = 0;
01517       else
01518         {
01519           int access_rights = __dpmi_get_descriptor_access_rights (sel);
01520           size_t segment_limit = len - 1;
01521 
01522           /* Make sure the crucial bits in the descriptor access
01523              rights are set correctly.  Some DPMI providers might barf
01524              if we set the segment limit to something that is not an
01525              integral multiple of 4KB pages if the granularity bit is
01526              not set to byte-granular, even though the DPMI spec says
01527              it's the host's responsibility to set that bit correctly.  */
01528           if (len > 1024 * 1024)
01529             {
01530               access_rights |= 0x8000;
01531               /* Page-granular segments should have the low 12 bits of
01532                  the limit set.  */
01533               segment_limit |= 0xfff;
01534             }
01535           else
01536             access_rights &= ~0x8000;
01537 
01538           if (__dpmi_set_segment_base_address (sel, addr) != -1
01539               && __dpmi_set_descriptor_access_rights (sel, access_rights) != -1
01540               && __dpmi_set_segment_limit (sel, segment_limit) != -1
01541               /* W2K silently fails to set the segment limit, leaving
01542                  it at zero; this test avoids the resulting crash.  */
01543               && __dpmi_get_segment_limit (sel) >= segment_limit)
01544             movedata (sel, 0, _my_ds (), (unsigned)dest, len);
01545           else
01546             retval = 0;
01547 
01548           __dpmi_free_ldt_descriptor (sel);
01549         }
01550     }
01551   return retval;
01552 }
01553 
01554 /* Get a segment descriptor stored at index IDX in the descriptor
01555    table whose base address is TABLE_BASE.  Return the descriptor
01556    type, or -1 if failure.  */
01557 static int
01558 get_descriptor (unsigned long table_base, int idx, void *descr)
01559 {
01560   unsigned long addr = table_base + idx * 8; /* 8 bytes per entry */
01561 
01562   if (read_memory_region (addr, descr, 8))
01563     return (int)((struct seg_descr *)descr)->stype;
01564   return -1;
01565 }
01566 
01567 struct dtr_reg {
01568   unsigned short limit __attribute__((packed));
01569   unsigned long  base  __attribute__((packed));
01570 };
01571 
01572 /* Display a segment descriptor stored at index IDX in a descriptor
01573    table whose type is TYPE and whose base address is BASE_ADDR.  If
01574    FORCE is non-zero, display even invalid descriptors.  */
01575 static void
01576 display_descriptor (unsigned type, unsigned long base_addr, int idx, int force)
01577 {
01578   struct seg_descr descr;
01579   struct gate_descr gate;
01580 
01581   /* Get the descriptor from the table.  */
01582   if (idx == 0 && type == 0)
01583     puts_filtered ("0x000: null descriptor\n");
01584   else if (get_descriptor (base_addr, idx, &descr) != -1)
01585     {
01586       /* For each type of descriptor table, this has a bit set if the
01587          corresponding type of selectors is valid in that table.  */
01588       static unsigned allowed_descriptors[] = {
01589           0xffffdafeL,   /* GDT */
01590           0x0000c0e0L,   /* IDT */
01591           0xffffdafaL    /* LDT */
01592       };
01593 
01594       /* If the program hasn't started yet, assume the debuggee will
01595          have the same CPL as the debugger.  */
01596       int cpl = prog_has_started ? (a_tss.tss_cs & 3) : _my_cs () & 3;
01597       unsigned long limit = (descr.limit1 << 16) | descr.limit0;
01598 
01599       if (descr.present
01600           && (allowed_descriptors[type] & (1 << descr.stype)) != 0)
01601         {
01602           printf_filtered ("0x%03x: ",
01603                            type == 1
01604                            ? idx : (idx * 8) | (type ? (cpl | 4) : 0));
01605           if (descr.page_granular)
01606             limit = (limit << 12) | 0xfff; /* big segment: low 12 bit set */
01607           if (descr.stype == 1 || descr.stype == 2 || descr.stype == 3
01608               || descr.stype == 9 || descr.stype == 11
01609               || (descr.stype >= 16 && descr.stype < 32))
01610             printf_filtered ("base=0x%02x%02x%04x limit=0x%08lx",
01611                              descr.base2, descr.base1, descr.base0, limit);
01612 
01613           switch (descr.stype)
01614             {
01615               case 1:
01616               case 3:
01617                 printf_filtered (" 16-bit TSS  (task %sactive)",
01618                                  descr.stype == 3 ? "" : "in");
01619                 break;
01620               case 2:
01621                 puts_filtered (" LDT");
01622                 break;
01623               case 4:
01624                 memcpy (&gate, &descr, sizeof gate);
01625                 printf_filtered ("selector=0x%04x  offs=0x%04x%04x",
01626                                  gate.selector, gate.offset1, gate.offset0);
01627                 printf_filtered (" 16-bit Call Gate (params=%d)",
01628                                  gate.param_count);
01629                 break;
01630               case 5:
01631                 printf_filtered ("TSS selector=0x%04x", descr.base0);
01632                 printfi_filtered (16, "Task Gate");
01633                 break;
01634               case 6:
01635               case 7:
01636                 memcpy (&gate, &descr, sizeof gate);
01637                 printf_filtered ("selector=0x%04x  offs=0x%04x%04x",
01638                                  gate.selector, gate.offset1, gate.offset0);
01639                 printf_filtered (" 16-bit %s Gate",
01640                                  descr.stype == 6 ? "Interrupt" : "Trap");
01641                 break;
01642               case 9:
01643               case 11:
01644                 printf_filtered (" 32-bit TSS (task %sactive)",
01645                                  descr.stype == 3 ? "" : "in");
01646                 break;
01647               case 12:
01648                 memcpy (&gate, &descr, sizeof gate);
01649                 printf_filtered ("selector=0x%04x  offs=0x%04x%04x",
01650                                  gate.selector, gate.offset1, gate.offset0);
01651                 printf_filtered (" 32-bit Call Gate (params=%d)",
01652                                  gate.param_count);
01653                 break;
01654               case 14:
01655               case 15:
01656                 memcpy (&gate, &descr, sizeof gate);
01657                 printf_filtered ("selector=0x%04x  offs=0x%04x%04x",
01658                                  gate.selector, gate.offset1, gate.offset0);
01659                 printf_filtered (" 32-bit %s Gate",
01660                                  descr.stype == 14 ? "Interrupt" : "Trap");
01661                 break;
01662               case 16:          /* data segments */
01663               case 17:
01664               case 18:
01665               case 19:
01666               case 20:
01667               case 21:
01668               case 22:
01669               case 23:
01670                 printf_filtered (" %s-bit Data (%s Exp-%s%s)",
01671                                  descr.bit32 ? "32" : "16",
01672                                  descr.stype & 2
01673                                  ? "Read/Write," : "Read-Only, ",
01674                                  descr.stype & 4 ? "down" : "up",
01675                                  descr.stype & 1 ? "" : ", N.Acc");
01676                 break;
01677               case 24:          /* code segments */
01678               case 25:
01679               case 26:
01680               case 27:
01681               case 28:
01682               case 29:
01683               case 30:
01684               case 31:
01685                 printf_filtered (" %s-bit Code (%s,  %sConf%s)",
01686                                  descr.bit32 ? "32" : "16",
01687                                  descr.stype & 2 ? "Exec/Read" : "Exec-Only",
01688                                  descr.stype & 4 ? "" : "N.",
01689                                  descr.stype & 1 ? "" : ", N.Acc");
01690                 break;
01691               default:
01692                 printf_filtered ("Unknown type 0x%02x", descr.stype);
01693                 break;
01694             }
01695           puts_filtered ("\n");
01696         }
01697       else if (force)
01698         {
01699           printf_filtered ("0x%03x: ",
01700                            type == 1
01701                            ? idx : (idx * 8) | (type ? (cpl | 4) : 0));
01702           if (!descr.present)
01703             puts_filtered ("Segment not present\n");
01704           else
01705             printf_filtered ("Segment type 0x%02x is invalid in this table\n",
01706                              descr.stype);
01707         }
01708     }
01709   else if (force)
01710     printf_filtered ("0x%03x: Cannot read this descriptor\n", idx);
01711 }
01712 
01713 static void
01714 go32_sldt (char *arg, int from_tty)
01715 {
01716   struct dtr_reg gdtr;
01717   unsigned short ldtr = 0;
01718   int ldt_idx;
01719   struct seg_descr ldt_descr;
01720   long ldt_entry = -1L;
01721   int cpl = (prog_has_started ? a_tss.tss_cs : _my_cs ()) & 3;
01722 
01723   if (arg && *arg)
01724     {
01725       arg = skip_spaces (arg);
01726 
01727       if (*arg)
01728         {
01729           ldt_entry = parse_and_eval_long (arg);
01730           if (ldt_entry < 0
01731               || (ldt_entry & 4) == 0
01732               || (ldt_entry & 3) != (cpl & 3))
01733             error (_("Invalid LDT entry 0x%03lx."), (unsigned long)ldt_entry);
01734         }
01735     }
01736 
01737   __asm__ __volatile__ ("sgdt   %0" : "=m" (gdtr) : /* no inputs */ );
01738   __asm__ __volatile__ ("sldt   %0" : "=m" (ldtr) : /* no inputs */ );
01739   ldt_idx = ldtr / 8;
01740   if (ldt_idx == 0)
01741     puts_filtered ("There is no LDT.\n");
01742   /* LDT's entry in the GDT must have the type LDT, which is 2.  */
01743   else if (get_descriptor (gdtr.base, ldt_idx, &ldt_descr) != 2)
01744     printf_filtered ("LDT is present (at %#x), but unreadable by GDB.\n",
01745                      ldt_descr.base0
01746                      | (ldt_descr.base1 << 16)
01747                      | (ldt_descr.base2 << 24));
01748   else
01749     {
01750       unsigned base =
01751         ldt_descr.base0
01752         | (ldt_descr.base1 << 16)
01753         | (ldt_descr.base2 << 24);
01754       unsigned limit = ldt_descr.limit0 | (ldt_descr.limit1 << 16);
01755       int max_entry;
01756 
01757       if (ldt_descr.page_granular)
01758         /* Page-granular segments must have the low 12 bits of their
01759            limit set.  */
01760         limit = (limit << 12) | 0xfff;
01761       /* LDT cannot have more than 8K 8-byte entries, i.e. more than
01762          64KB.  */
01763       if (limit > 0xffff)
01764         limit = 0xffff;
01765 
01766       max_entry = (limit + 1) / 8;
01767 
01768       if (ldt_entry >= 0)
01769         {
01770           if (ldt_entry > limit)
01771             error (_("Invalid LDT entry %#lx: outside valid limits [0..%#x]"),
01772                    (unsigned long)ldt_entry, limit);
01773 
01774           display_descriptor (ldt_descr.stype, base, ldt_entry / 8, 1);
01775         }
01776       else
01777         {
01778           int i;
01779 
01780           for (i = 0; i < max_entry; i++)
01781             display_descriptor (ldt_descr.stype, base, i, 0);
01782         }
01783     }
01784 }
01785 
01786 static void
01787 go32_sgdt (char *arg, int from_tty)
01788 {
01789   struct dtr_reg gdtr;
01790   long gdt_entry = -1L;
01791   int max_entry;
01792 
01793   if (arg && *arg)
01794     {
01795       arg = skip_spaces (arg);
01796 
01797       if (*arg)
01798         {
01799           gdt_entry = parse_and_eval_long (arg);
01800           if (gdt_entry < 0 || (gdt_entry & 7) != 0)
01801             error (_("Invalid GDT entry 0x%03lx: "
01802                      "not an integral multiple of 8."),
01803                    (unsigned long)gdt_entry);
01804         }
01805     }
01806 
01807   __asm__ __volatile__ ("sgdt   %0" : "=m" (gdtr) : /* no inputs */ );
01808   max_entry = (gdtr.limit + 1) / 8;
01809 
01810   if (gdt_entry >= 0)
01811     {
01812       if (gdt_entry > gdtr.limit)
01813         error (_("Invalid GDT entry %#lx: outside valid limits [0..%#x]"),
01814                (unsigned long)gdt_entry, gdtr.limit);
01815 
01816       display_descriptor (0, gdtr.base, gdt_entry / 8, 1);
01817     }
01818   else
01819     {
01820       int i;
01821 
01822       for (i = 0; i < max_entry; i++)
01823         display_descriptor (0, gdtr.base, i, 0);
01824     }
01825 }
01826 
01827 static void
01828 go32_sidt (char *arg, int from_tty)
01829 {
01830   struct dtr_reg idtr;
01831   long idt_entry = -1L;
01832   int max_entry;
01833 
01834   if (arg && *arg)
01835     {
01836       arg = skip_spaces (arg);
01837 
01838       if (*arg)
01839         {
01840           idt_entry = parse_and_eval_long (arg);
01841           if (idt_entry < 0)
01842             error (_("Invalid (negative) IDT entry %ld."), idt_entry);
01843         }
01844     }
01845 
01846   __asm__ __volatile__ ("sidt   %0" : "=m" (idtr) : /* no inputs */ );
01847   max_entry = (idtr.limit + 1) / 8;
01848   if (max_entry > 0x100)        /* No more than 256 entries.  */
01849     max_entry = 0x100;
01850 
01851   if (idt_entry >= 0)
01852     {
01853       if (idt_entry > idtr.limit)
01854         error (_("Invalid IDT entry %#lx: outside valid limits [0..%#x]"),
01855                (unsigned long)idt_entry, idtr.limit);
01856 
01857       display_descriptor (1, idtr.base, idt_entry, 1);
01858     }
01859   else
01860     {
01861       int i;
01862 
01863       for (i = 0; i < max_entry; i++)
01864         display_descriptor (1, idtr.base, i, 0);
01865     }
01866 }
01867 
01868 /* Cached linear address of the base of the page directory.  For
01869    now, available only under CWSDPMI.  Code based on ideas and
01870    suggestions from Charles Sandmann <sandmann@clio.rice.edu>.  */
01871 static unsigned long pdbr;
01872 
01873 static unsigned long
01874 get_cr3 (void)
01875 {
01876   unsigned offset;
01877   unsigned taskreg;
01878   unsigned long taskbase, cr3;
01879   struct dtr_reg gdtr;
01880 
01881   if (pdbr > 0 && pdbr <= 0xfffff)
01882     return pdbr;
01883 
01884   /* Get the linear address of GDT and the Task Register.  */
01885   __asm__ __volatile__ ("sgdt   %0" : "=m" (gdtr) : /* no inputs */ );
01886   __asm__ __volatile__ ("str    %0" : "=m" (taskreg) : /* no inputs */ );
01887 
01888   /* Task Register is a segment selector for the TSS of the current
01889      task.  Therefore, it can be used as an index into the GDT to get
01890      at the segment descriptor for the TSS.  To get the index, reset
01891      the low 3 bits of the selector (which give the CPL).  Add 2 to the
01892      offset to point to the 3 low bytes of the base address.  */
01893   offset = gdtr.base + (taskreg & 0xfff8) + 2;
01894 
01895 
01896   /* CWSDPMI's task base is always under the 1MB mark.  */
01897   if (offset > 0xfffff)
01898     return 0;
01899 
01900   _farsetsel (_dos_ds);
01901   taskbase  = _farnspeekl (offset) & 0xffffffU;
01902   taskbase += _farnspeekl (offset + 2) & 0xff000000U;
01903   if (taskbase > 0xfffff)
01904     return 0;
01905 
01906   /* CR3 (a.k.a. PDBR, the Page Directory Base Register) is stored at
01907      offset 1Ch in the TSS.  */
01908   cr3 = _farnspeekl (taskbase + 0x1c) & ~0xfff;
01909   if (cr3 > 0xfffff)
01910     {
01911 #if 0  /* Not fullly supported yet.  */
01912       /* The Page Directory is in UMBs.  In that case, CWSDPMI puts
01913          the first Page Table right below the Page Directory.  Thus,
01914          the first Page Table's entry for its own address and the Page
01915          Directory entry for that Page Table will hold the same
01916          physical address.  The loop below searches the entire UMB
01917          range of addresses for such an occurence.  */
01918       unsigned long addr, pte_idx;
01919 
01920       for (addr = 0xb0000, pte_idx = 0xb0;
01921            pte_idx < 0xff;
01922            addr += 0x1000, pte_idx++)
01923         {
01924           if (((_farnspeekl (addr + 4 * pte_idx) & 0xfffff027) ==
01925                (_farnspeekl (addr + 0x1000) & 0xfffff027))
01926               && ((_farnspeekl (addr + 4 * pte_idx + 4) & 0xfffff000) == cr3))
01927             {
01928               cr3 = addr + 0x1000;
01929               break;
01930             }
01931         }
01932 #endif
01933 
01934       if (cr3 > 0xfffff)
01935         cr3 = 0;
01936     }
01937 
01938   return cr3;
01939 }
01940 
01941 /* Return the N'th Page Directory entry.  */
01942 static unsigned long
01943 get_pde (int n)
01944 {
01945   unsigned long pde = 0;
01946 
01947   if (pdbr && n >= 0 && n < 1024)
01948     {
01949       pde = _farpeekl (_dos_ds, pdbr + 4*n);
01950     }
01951   return pde;
01952 }
01953 
01954 /* Return the N'th entry of the Page Table whose Page Directory entry
01955    is PDE.  */
01956 static unsigned long
01957 get_pte (unsigned long pde, int n)
01958 {
01959   unsigned long pte = 0;
01960 
01961   /* pde & 0x80 tests the 4MB page bit.  We don't support 4MB
01962      page tables, for now.  */
01963   if ((pde & 1) && !(pde & 0x80) && n >= 0 && n < 1024)
01964     {
01965       pde &= ~0xfff;    /* Clear non-address bits.  */
01966       pte = _farpeekl (_dos_ds, pde + 4*n);
01967     }
01968   return pte;
01969 }
01970 
01971 /* Display a Page Directory or Page Table entry.  IS_DIR, if non-zero,
01972    says this is a Page Directory entry.  If FORCE is non-zero, display
01973    the entry even if its Present flag is off.  OFF is the offset of the
01974    address from the page's base address.  */
01975 static void
01976 display_ptable_entry (unsigned long entry, int is_dir, int force, unsigned off)
01977 {
01978   if ((entry & 1) != 0)
01979     {
01980       printf_filtered ("Base=0x%05lx000", entry >> 12);
01981       if ((entry & 0x100) && !is_dir)
01982         puts_filtered (" Global");
01983       if ((entry & 0x40) && !is_dir)
01984         puts_filtered (" Dirty");
01985       printf_filtered (" %sAcc.", (entry & 0x20) ? "" : "Not-");
01986       printf_filtered (" %sCached", (entry & 0x10) ? "" : "Not-");
01987       printf_filtered (" Write-%s", (entry & 8) ? "Thru" : "Back");
01988       printf_filtered (" %s", (entry & 4) ? "Usr" : "Sup");
01989       printf_filtered (" Read-%s", (entry & 2) ? "Write" : "Only");
01990       if (off)
01991         printf_filtered (" +0x%x", off);
01992       puts_filtered ("\n");
01993     }
01994   else if (force)
01995     printf_filtered ("Page%s not present or not supported; value=0x%lx.\n",
01996                      is_dir ? " Table" : "", entry >> 1);
01997 }
01998 
01999 static void
02000 go32_pde (char *arg, int from_tty)
02001 {
02002   long pde_idx = -1, i;
02003 
02004   if (arg && *arg)
02005     {
02006       arg = skip_spaces (arg);
02007 
02008       if (*arg)
02009         {
02010           pde_idx = parse_and_eval_long (arg);
02011           if (pde_idx < 0 || pde_idx >= 1024)
02012             error (_("Entry %ld is outside valid limits [0..1023]."), pde_idx);
02013         }
02014     }
02015 
02016   pdbr = get_cr3 ();
02017   if (!pdbr)
02018     puts_filtered ("Access to Page Directories is "
02019                    "not supported on this system.\n");
02020   else if (pde_idx >= 0)
02021     display_ptable_entry (get_pde (pde_idx), 1, 1, 0);
02022   else
02023     for (i = 0; i < 1024; i++)
02024       display_ptable_entry (get_pde (i), 1, 0, 0);
02025 }
02026 
02027 /* A helper function to display entries in a Page Table pointed to by
02028    the N'th entry in the Page Directory.  If FORCE is non-zero, say
02029    something even if the Page Table is not accessible.  */
02030 static void
02031 display_page_table (long n, int force)
02032 {
02033   unsigned long pde = get_pde (n);
02034 
02035   if ((pde & 1) != 0)
02036     {
02037       int i;
02038 
02039       printf_filtered ("Page Table pointed to by "
02040                        "Page Directory entry 0x%lx:\n", n);
02041       for (i = 0; i < 1024; i++)
02042         display_ptable_entry (get_pte (pde, i), 0, 0, 0);
02043       puts_filtered ("\n");
02044     }
02045   else if (force)
02046     printf_filtered ("Page Table not present; value=0x%lx.\n", pde >> 1);
02047 }
02048 
02049 static void
02050 go32_pte (char *arg, int from_tty)
02051 {
02052   long pde_idx = -1L, i;
02053 
02054   if (arg && *arg)
02055     {
02056       arg = skip_spaces (arg);
02057 
02058       if (*arg)
02059         {
02060           pde_idx = parse_and_eval_long (arg);
02061           if (pde_idx < 0 || pde_idx >= 1024)
02062             error (_("Entry %ld is outside valid limits [0..1023]."), pde_idx);
02063         }
02064     }
02065 
02066   pdbr = get_cr3 ();
02067   if (!pdbr)
02068     puts_filtered ("Access to Page Tables is not supported on this system.\n");
02069   else if (pde_idx >= 0)
02070     display_page_table (pde_idx, 1);
02071   else
02072     for (i = 0; i < 1024; i++)
02073       display_page_table (i, 0);
02074 }
02075 
02076 static void
02077 go32_pte_for_address (char *arg, int from_tty)
02078 {
02079   CORE_ADDR addr = 0, i;
02080 
02081   if (arg && *arg)
02082     {
02083       arg = skip_spaces (arg);
02084 
02085       if (*arg)
02086         addr = parse_and_eval_address (arg);
02087     }
02088   if (!addr)
02089     error_no_arg (_("linear address"));
02090 
02091   pdbr = get_cr3 ();
02092   if (!pdbr)
02093     puts_filtered ("Access to Page Tables is not supported on this system.\n");
02094   else
02095     {
02096       int pde_idx = (addr >> 22) & 0x3ff;
02097       int pte_idx = (addr >> 12) & 0x3ff;
02098       unsigned offs = addr & 0xfff;
02099 
02100       printf_filtered ("Page Table entry for address %s:\n",
02101                        hex_string(addr));
02102       display_ptable_entry (get_pte (get_pde (pde_idx), pte_idx), 0, 1, offs);
02103     }
02104 }
02105 
02106 static struct cmd_list_element *info_dos_cmdlist = NULL;
02107 
02108 static void
02109 go32_info_dos_command (char *args, int from_tty)
02110 {
02111   help_list (info_dos_cmdlist, "info dos ", class_info, gdb_stdout);
02112 }
02113 
02114 /* -Wmissing-prototypes */
02115 extern initialize_file_ftype _initialize_go32_nat;
02116 
02117 void
02118 _initialize_go32_nat (void)
02119 {
02120   init_go32_ops ();
02121   add_target (&go32_ops);
02122 
02123   add_prefix_cmd ("dos", class_info, go32_info_dos_command, _("\
02124 Print information specific to DJGPP (aka MS-DOS) debugging."),
02125                   &info_dos_cmdlist, "info dos ", 0, &infolist);
02126 
02127   add_cmd ("sysinfo", class_info, go32_sysinfo, _("\
02128 Display information about the target system, including CPU, OS, DPMI, etc."),
02129            &info_dos_cmdlist);
02130   add_cmd ("ldt", class_info, go32_sldt, _("\
02131 Display entries in the LDT (Local Descriptor Table).\n\
02132 Entry number (an expression) as an argument means display only that entry."),
02133            &info_dos_cmdlist);
02134   add_cmd ("gdt", class_info, go32_sgdt, _("\
02135 Display entries in the GDT (Global Descriptor Table).\n\
02136 Entry number (an expression) as an argument means display only that entry."),
02137            &info_dos_cmdlist);
02138   add_cmd ("idt", class_info, go32_sidt, _("\
02139 Display entries in the IDT (Interrupt Descriptor Table).\n\
02140 Entry number (an expression) as an argument means display only that entry."),
02141            &info_dos_cmdlist);
02142   add_cmd ("pde", class_info, go32_pde, _("\
02143 Display entries in the Page Directory.\n\
02144 Entry number (an expression) as an argument means display only that entry."),
02145            &info_dos_cmdlist);
02146   add_cmd ("pte", class_info, go32_pte, _("\
02147 Display entries in Page Tables.\n\
02148 Entry number (an expression) as an argument means display only entries\n\
02149 from the Page Table pointed to by the specified Page Directory entry."),
02150            &info_dos_cmdlist);
02151   add_cmd ("address-pte", class_info, go32_pte_for_address, _("\
02152 Display a Page Table entry for a linear address.\n\
02153 The address argument must be a linear address, after adding to\n\
02154 it the base address of the appropriate segment.\n\
02155 The base address of variables and functions in the debuggee's data\n\
02156 or code segment is stored in the variable __djgpp_base_address,\n\
02157 so use `__djgpp_base_address + (char *)&var' as the argument.\n\
02158 For other segments, look up their base address in the output of\n\
02159 the `info dos ldt' command."),
02160            &info_dos_cmdlist);
02161 }
02162 
02163 pid_t
02164 tcgetpgrp (int fd)
02165 {
02166   if (isatty (fd))
02167     return SOME_PID;
02168   errno = ENOTTY;
02169   return -1;
02170 }
02171 
02172 int
02173 tcsetpgrp (int fd, pid_t pgid)
02174 {
02175   if (isatty (fd) && pgid == SOME_PID)
02176     return 0;
02177   errno = pgid == SOME_PID ? ENOTTY : ENOSYS;
02178   return -1;
02179 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines