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