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