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