go32-nat.c revision 1.1.1.2 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.2 christos if (res <= 0)
591 1.1.1.2 christos return TARGET_XFER_E_IO;
592 1.1.1.2 christos
593 1.1.1.2 christos *xfered_len = res;
594 1.1.1.2 christos return TARGET_XFER_OK;
595 1.1.1.2 christos }
596 1.1.1.2 christos
597 1.1.1.2 christos /* Target to_xfer_partial implementation. */
598 1.1.1.2 christos
599 1.1.1.2 christos static enum target_xfer_status
600 1.1.1.2 christos go32_xfer_partial (struct target_ops *ops, enum target_object object,
601 1.1.1.2 christos const char *annex, gdb_byte *readbuf,
602 1.1.1.2 christos const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
603 1.1.1.2 christos ULONGEST *xfered_len)
604 1.1.1.2 christos {
605 1.1.1.2 christos switch (object)
606 1.1 christos {
607 1.1.1.2 christos case TARGET_OBJECT_MEMORY:
608 1.1.1.2 christos return go32_xfer_memory (readbuf, writebuf, offset, len, xfered_len);
609 1.1.1.2 christos
610 1.1.1.2 christos default:
611 1.1.1.2 christos return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
612 1.1.1.2 christos readbuf, writebuf, offset, len,
613 1.1.1.2 christos xfered_len);
614 1.1 christos }
615 1.1 christos }
616 1.1 christos
617 1.1 christos static cmdline_t child_cmd; /* Parsed child's command line kept here. */
618 1.1 christos
619 1.1 christos static void
620 1.1 christos go32_files_info (struct target_ops *target)
621 1.1 christos {
622 1.1 christos printf_unfiltered ("You are running a DJGPP V2 program.\n");
623 1.1 christos }
624 1.1 christos
625 1.1 christos static void
626 1.1 christos go32_kill_inferior (struct target_ops *ops)
627 1.1 christos {
628 1.1 christos go32_mourn_inferior (ops);
629 1.1 christos }
630 1.1 christos
631 1.1 christos static void
632 1.1 christos go32_create_inferior (struct target_ops *ops, char *exec_file,
633 1.1 christos char *args, char **env, int from_tty)
634 1.1 christos {
635 1.1 christos extern char **environ;
636 1.1 christos jmp_buf start_state;
637 1.1 christos char *cmdline;
638 1.1 christos char **env_save = environ;
639 1.1 christos size_t cmdlen;
640 1.1 christos struct inferior *inf;
641 1.1.1.2 christos int result;
642 1.1 christos
643 1.1 christos /* If no exec file handed to us, get it from the exec-file command -- with
644 1.1 christos a good, common error message if none is specified. */
645 1.1 christos if (exec_file == 0)
646 1.1 christos exec_file = get_exec_file (1);
647 1.1 christos
648 1.1 christos resume_signal = -1;
649 1.1 christos resume_is_step = 0;
650 1.1 christos
651 1.1 christos /* Initialize child's cwd as empty to be initialized when starting
652 1.1 christos the child. */
653 1.1 christos *child_cwd = 0;
654 1.1 christos
655 1.1 christos /* Init command line storage. */
656 1.1 christos if (redir_debug_init (&child_cmd) == -1)
657 1.1 christos internal_error (__FILE__, __LINE__,
658 1.1 christos _("Cannot allocate redirection storage: "
659 1.1 christos "not enough memory.\n"));
660 1.1 christos
661 1.1 christos /* Parse the command line and create redirections. */
662 1.1 christos if (strpbrk (args, "<>"))
663 1.1 christos {
664 1.1 christos if (redir_cmdline_parse (args, &child_cmd) == 0)
665 1.1 christos args = child_cmd.command;
666 1.1 christos else
667 1.1 christos error (_("Syntax error in command line."));
668 1.1 christos }
669 1.1 christos else
670 1.1 christos child_cmd.command = xstrdup (args);
671 1.1 christos
672 1.1 christos cmdlen = strlen (args);
673 1.1 christos /* v2loadimage passes command lines via DOS memory, so it cannot
674 1.1 christos possibly handle commands longer than 1MB. */
675 1.1 christos if (cmdlen > 1024*1024)
676 1.1 christos error (_("Command line too long."));
677 1.1 christos
678 1.1 christos cmdline = xmalloc (cmdlen + 4);
679 1.1 christos strcpy (cmdline + 1, args);
680 1.1 christos /* If the command-line length fits into DOS 126-char limits, use the
681 1.1 christos DOS command tail format; otherwise, tell v2loadimage to pass it
682 1.1 christos through a buffer in conventional memory. */
683 1.1 christos if (cmdlen < 127)
684 1.1 christos {
685 1.1 christos cmdline[0] = strlen (args);
686 1.1 christos cmdline[cmdlen + 1] = 13;
687 1.1 christos }
688 1.1 christos else
689 1.1 christos cmdline[0] = 0xff; /* Signal v2loadimage it's a long command. */
690 1.1 christos
691 1.1 christos environ = env;
692 1.1 christos
693 1.1.1.2 christos result = v2loadimage (exec_file, cmdline, start_state);
694 1.1.1.2 christos
695 1.1 christos environ = env_save;
696 1.1 christos xfree (cmdline);
697 1.1 christos
698 1.1.1.2 christos if (result != 0)
699 1.1.1.2 christos error (_("Load failed for image %s"), exec_file);
700 1.1.1.2 christos
701 1.1 christos edi_init (start_state);
702 1.1 christos #if __DJGPP_MINOR__ < 3
703 1.1 christos save_npx ();
704 1.1 christos #endif
705 1.1 christos
706 1.1 christos inferior_ptid = pid_to_ptid (SOME_PID);
707 1.1 christos inf = current_inferior ();
708 1.1 christos inferior_appeared (inf, SOME_PID);
709 1.1 christos
710 1.1.1.2 christos if (!target_is_pushed (ops))
711 1.1.1.2 christos push_target (ops);
712 1.1 christos
713 1.1 christos add_thread_silent (inferior_ptid);
714 1.1 christos
715 1.1.1.2 christos clear_proceed_status (0);
716 1.1 christos insert_breakpoints ();
717 1.1 christos prog_has_started = 1;
718 1.1 christos }
719 1.1 christos
720 1.1 christos static void
721 1.1 christos go32_mourn_inferior (struct target_ops *ops)
722 1.1 christos {
723 1.1 christos ptid_t ptid;
724 1.1 christos
725 1.1 christos redir_cmdline_delete (&child_cmd);
726 1.1 christos resume_signal = -1;
727 1.1 christos resume_is_step = 0;
728 1.1 christos
729 1.1 christos cleanup_client ();
730 1.1 christos
731 1.1 christos /* We need to make sure all the breakpoint enable bits in the DR7
732 1.1 christos register are reset when the inferior exits. Otherwise, if they
733 1.1 christos rerun the inferior, the uncleared bits may cause random SIGTRAPs,
734 1.1 christos failure to set more watchpoints, and other calamities. It would
735 1.1 christos be nice if GDB itself would take care to remove all breakpoints
736 1.1 christos at all times, but it doesn't, probably under an assumption that
737 1.1 christos the OS cleans up when the debuggee exits. */
738 1.1.1.2 christos x86_cleanup_dregs ();
739 1.1 christos
740 1.1 christos ptid = inferior_ptid;
741 1.1 christos inferior_ptid = null_ptid;
742 1.1 christos delete_thread_silent (ptid);
743 1.1 christos prog_has_started = 0;
744 1.1 christos
745 1.1 christos generic_mourn_inferior ();
746 1.1.1.2 christos inf_child_maybe_unpush_target (ops);
747 1.1 christos }
748 1.1 christos
749 1.1 christos /* Hardware watchpoint support. */
750 1.1 christos
751 1.1 christos #define D_REGS edi.dr
752 1.1 christos #define CONTROL D_REGS[7]
753 1.1 christos #define STATUS D_REGS[6]
754 1.1 christos
755 1.1 christos /* Pass the address ADDR to the inferior in the I'th debug register.
756 1.1 christos Here we just store the address in D_REGS, the watchpoint will be
757 1.1 christos actually set up when go32_wait runs the debuggee. */
758 1.1 christos static void
759 1.1 christos go32_set_dr (int i, CORE_ADDR addr)
760 1.1 christos {
761 1.1 christos if (i < 0 || i > 3)
762 1.1 christos internal_error (__FILE__, __LINE__,
763 1.1 christos _("Invalid register %d in go32_set_dr.\n"), i);
764 1.1 christos D_REGS[i] = addr;
765 1.1 christos }
766 1.1 christos
767 1.1 christos /* Pass the value VAL to the inferior in the DR7 debug control
768 1.1 christos register. Here we just store the address in D_REGS, the watchpoint
769 1.1 christos will be actually set up when go32_wait runs the debuggee. */
770 1.1 christos static void
771 1.1 christos go32_set_dr7 (unsigned long val)
772 1.1 christos {
773 1.1 christos CONTROL = val;
774 1.1 christos }
775 1.1 christos
776 1.1 christos /* Get the value of the DR6 debug status register from the inferior.
777 1.1 christos Here we just return the value stored in D_REGS, as we've got it
778 1.1 christos from the last go32_wait call. */
779 1.1 christos static unsigned long
780 1.1 christos go32_get_dr6 (void)
781 1.1 christos {
782 1.1 christos return STATUS;
783 1.1 christos }
784 1.1 christos
785 1.1 christos /* Get the value of the DR7 debug status register from the inferior.
786 1.1 christos Here we just return the value stored in D_REGS, as we've got it
787 1.1 christos from the last go32_wait call. */
788 1.1 christos
789 1.1 christos static unsigned long
790 1.1 christos go32_get_dr7 (void)
791 1.1 christos {
792 1.1 christos return CONTROL;
793 1.1 christos }
794 1.1 christos
795 1.1 christos /* Get the value of the DR debug register I from the inferior. Here
796 1.1 christos we just return the value stored in D_REGS, as we've got it from the
797 1.1 christos last go32_wait call. */
798 1.1 christos
799 1.1 christos static CORE_ADDR
800 1.1 christos go32_get_dr (int i)
801 1.1 christos {
802 1.1 christos if (i < 0 || i > 3)
803 1.1 christos internal_error (__FILE__, __LINE__,
804 1.1 christos _("Invalid register %d in go32_get_dr.\n"), i);
805 1.1 christos return D_REGS[i];
806 1.1 christos }
807 1.1 christos
808 1.1 christos /* Put the device open on handle FD into either raw or cooked
809 1.1 christos mode, return 1 if it was in raw mode, zero otherwise. */
810 1.1 christos
811 1.1 christos static int
812 1.1 christos device_mode (int fd, int raw_p)
813 1.1 christos {
814 1.1 christos int oldmode, newmode;
815 1.1 christos __dpmi_regs regs;
816 1.1 christos
817 1.1 christos regs.x.ax = 0x4400;
818 1.1 christos regs.x.bx = fd;
819 1.1 christos __dpmi_int (0x21, ®s);
820 1.1 christos if (regs.x.flags & 1)
821 1.1 christos return -1;
822 1.1 christos newmode = oldmode = regs.x.dx;
823 1.1 christos
824 1.1 christos if (raw_p)
825 1.1 christos newmode |= 0x20;
826 1.1 christos else
827 1.1 christos newmode &= ~0x20;
828 1.1 christos
829 1.1 christos if (oldmode & 0x80) /* Only for character dev. */
830 1.1 christos {
831 1.1 christos regs.x.ax = 0x4401;
832 1.1 christos regs.x.bx = fd;
833 1.1 christos regs.x.dx = newmode & 0xff; /* Force upper byte zero, else it fails. */
834 1.1 christos __dpmi_int (0x21, ®s);
835 1.1 christos if (regs.x.flags & 1)
836 1.1 christos return -1;
837 1.1 christos }
838 1.1 christos return (oldmode & 0x20) == 0x20;
839 1.1 christos }
840 1.1 christos
841 1.1 christos
842 1.1 christos static int inf_mode_valid = 0;
843 1.1 christos static int inf_terminal_mode;
844 1.1 christos
845 1.1 christos /* This semaphore is needed because, amazingly enough, GDB calls
846 1.1 christos target.to_terminal_ours more than once after the inferior stops.
847 1.1 christos But we need the information from the first call only, since the
848 1.1 christos second call will always see GDB's own cooked terminal. */
849 1.1 christos static int terminal_is_ours = 1;
850 1.1 christos
851 1.1 christos static void
852 1.1.1.2 christos go32_terminal_init (struct target_ops *self)
853 1.1 christos {
854 1.1 christos inf_mode_valid = 0; /* Reinitialize, in case they are restarting child. */
855 1.1 christos terminal_is_ours = 1;
856 1.1 christos }
857 1.1 christos
858 1.1 christos static void
859 1.1.1.2 christos go32_terminal_info (struct target_ops *self, const char *args, int from_tty)
860 1.1 christos {
861 1.1 christos printf_unfiltered ("Inferior's terminal is in %s mode.\n",
862 1.1 christos !inf_mode_valid
863 1.1 christos ? "default" : inf_terminal_mode ? "raw" : "cooked");
864 1.1 christos
865 1.1 christos #if __DJGPP_MINOR__ > 2
866 1.1 christos if (child_cmd.redirection)
867 1.1 christos {
868 1.1 christos int i;
869 1.1 christos
870 1.1 christos for (i = 0; i < DBG_HANDLES; i++)
871 1.1 christos {
872 1.1 christos if (child_cmd.redirection[i]->file_name)
873 1.1 christos printf_unfiltered ("\tFile handle %d is redirected to `%s'.\n",
874 1.1 christos i, child_cmd.redirection[i]->file_name);
875 1.1 christos else if (_get_dev_info (child_cmd.redirection[i]->inf_handle) == -1)
876 1.1 christos printf_unfiltered
877 1.1 christos ("\tFile handle %d appears to be closed by inferior.\n", i);
878 1.1 christos /* Mask off the raw/cooked bit when comparing device info words. */
879 1.1 christos else if ((_get_dev_info (child_cmd.redirection[i]->inf_handle) & 0xdf)
880 1.1 christos != (_get_dev_info (i) & 0xdf))
881 1.1 christos printf_unfiltered
882 1.1 christos ("\tFile handle %d appears to be redirected by inferior.\n", i);
883 1.1 christos }
884 1.1 christos }
885 1.1 christos #endif
886 1.1 christos }
887 1.1 christos
888 1.1 christos static void
889 1.1.1.2 christos go32_terminal_inferior (struct target_ops *self)
890 1.1 christos {
891 1.1 christos /* Redirect standard handles as child wants them. */
892 1.1 christos errno = 0;
893 1.1 christos if (redir_to_child (&child_cmd) == -1)
894 1.1 christos {
895 1.1 christos redir_to_debugger (&child_cmd);
896 1.1 christos error (_("Cannot redirect standard handles for program: %s."),
897 1.1 christos safe_strerror (errno));
898 1.1 christos }
899 1.1 christos /* Set the console device of the inferior to whatever mode
900 1.1 christos (raw or cooked) we found it last time. */
901 1.1 christos if (terminal_is_ours)
902 1.1 christos {
903 1.1 christos if (inf_mode_valid)
904 1.1 christos device_mode (0, inf_terminal_mode);
905 1.1 christos terminal_is_ours = 0;
906 1.1 christos }
907 1.1 christos }
908 1.1 christos
909 1.1 christos static void
910 1.1.1.2 christos go32_terminal_ours (struct target_ops *self)
911 1.1 christos {
912 1.1 christos /* Switch to cooked mode on the gdb terminal and save the inferior
913 1.1 christos terminal mode to be restored when it is resumed. */
914 1.1 christos if (!terminal_is_ours)
915 1.1 christos {
916 1.1 christos inf_terminal_mode = device_mode (0, 0);
917 1.1 christos if (inf_terminal_mode != -1)
918 1.1 christos inf_mode_valid = 1;
919 1.1 christos else
920 1.1 christos /* If device_mode returned -1, we don't know what happens with
921 1.1 christos handle 0 anymore, so make the info invalid. */
922 1.1 christos inf_mode_valid = 0;
923 1.1 christos terminal_is_ours = 1;
924 1.1 christos
925 1.1 christos /* Restore debugger's standard handles. */
926 1.1 christos errno = 0;
927 1.1 christos if (redir_to_debugger (&child_cmd) == -1)
928 1.1 christos {
929 1.1 christos redir_to_child (&child_cmd);
930 1.1 christos error (_("Cannot redirect standard handles for debugger: %s."),
931 1.1 christos safe_strerror (errno));
932 1.1 christos }
933 1.1 christos }
934 1.1 christos }
935 1.1 christos
936 1.1 christos static int
937 1.1 christos go32_thread_alive (struct target_ops *ops, ptid_t ptid)
938 1.1 christos {
939 1.1 christos return !ptid_equal (inferior_ptid, null_ptid);
940 1.1 christos }
941 1.1 christos
942 1.1 christos static char *
943 1.1 christos go32_pid_to_str (struct target_ops *ops, ptid_t ptid)
944 1.1 christos {
945 1.1 christos return normal_pid_to_str (ptid);
946 1.1 christos }
947 1.1 christos
948 1.1.1.2 christos /* Create a go32 target. */
949 1.1 christos
950 1.1.1.2 christos static struct target_ops *
951 1.1.1.2 christos go32_target (void)
952 1.1.1.2 christos {
953 1.1.1.2 christos struct target_ops *t = inf_child_target ();
954 1.1 christos
955 1.1.1.2 christos t->to_attach = go32_attach;
956 1.1.1.2 christos t->to_resume = go32_resume;
957 1.1.1.2 christos t->to_wait = go32_wait;
958 1.1.1.2 christos t->to_fetch_registers = go32_fetch_registers;
959 1.1.1.2 christos t->to_store_registers = go32_store_registers;
960 1.1.1.2 christos t->to_xfer_partial = go32_xfer_partial;
961 1.1.1.2 christos t->to_files_info = go32_files_info;
962 1.1.1.2 christos t->to_terminal_init = go32_terminal_init;
963 1.1.1.2 christos t->to_terminal_inferior = go32_terminal_inferior;
964 1.1.1.2 christos t->to_terminal_ours_for_output = go32_terminal_ours;
965 1.1.1.2 christos t->to_terminal_ours = go32_terminal_ours;
966 1.1.1.2 christos t->to_terminal_info = go32_terminal_info;
967 1.1.1.2 christos t->to_kill = go32_kill_inferior;
968 1.1.1.2 christos t->to_create_inferior = go32_create_inferior;
969 1.1.1.2 christos t->to_mourn_inferior = go32_mourn_inferior;
970 1.1.1.2 christos t->to_thread_alive = go32_thread_alive;
971 1.1.1.2 christos t->to_pid_to_str = go32_pid_to_str;
972 1.1 christos
973 1.1.1.2 christos return t;
974 1.1 christos }
975 1.1 christos
976 1.1 christos /* Return the current DOS codepage number. */
977 1.1 christos static int
978 1.1 christos dos_codepage (void)
979 1.1 christos {
980 1.1 christos __dpmi_regs regs;
981 1.1 christos
982 1.1 christos regs.x.ax = 0x6601;
983 1.1 christos __dpmi_int (0x21, ®s);
984 1.1 christos if (!(regs.x.flags & 1))
985 1.1 christos return regs.x.bx & 0xffff;
986 1.1 christos else
987 1.1 christos return 437; /* default */
988 1.1 christos }
989 1.1 christos
990 1.1 christos /* Limited emulation of `nl_langinfo', for charset.c. */
991 1.1 christos char *
992 1.1 christos nl_langinfo (nl_item item)
993 1.1 christos {
994 1.1 christos char *retval;
995 1.1 christos
996 1.1 christos switch (item)
997 1.1 christos {
998 1.1 christos case CODESET:
999 1.1 christos {
1000 1.1 christos /* 8 is enough for SHORT_MAX + "CP" + null. */
1001 1.1 christos char buf[8];
1002 1.1 christos int blen = sizeof (buf);
1003 1.1 christos int needed = snprintf (buf, blen, "CP%d", dos_codepage ());
1004 1.1 christos
1005 1.1 christos if (needed > blen) /* Should never happen. */
1006 1.1 christos buf[0] = 0;
1007 1.1 christos retval = xstrdup (buf);
1008 1.1 christos }
1009 1.1 christos break;
1010 1.1 christos default:
1011 1.1 christos retval = xstrdup ("");
1012 1.1 christos break;
1013 1.1 christos }
1014 1.1 christos return retval;
1015 1.1 christos }
1016 1.1 christos
1017 1.1 christos unsigned short windows_major, windows_minor;
1018 1.1 christos
1019 1.1 christos /* Compute the version Windows reports via Int 2Fh/AX=1600h. */
1020 1.1 christos static void
1021 1.1 christos go32_get_windows_version(void)
1022 1.1 christos {
1023 1.1 christos __dpmi_regs r;
1024 1.1 christos
1025 1.1 christos r.x.ax = 0x1600;
1026 1.1 christos __dpmi_int(0x2f, &r);
1027 1.1 christos if (r.h.al > 2 && r.h.al != 0x80 && r.h.al != 0xff
1028 1.1 christos && (r.h.al > 3 || r.h.ah > 0))
1029 1.1 christos {
1030 1.1 christos windows_major = r.h.al;
1031 1.1 christos windows_minor = r.h.ah;
1032 1.1 christos }
1033 1.1 christos else
1034 1.1 christos windows_major = 0xff; /* meaning no Windows */
1035 1.1 christos }
1036 1.1 christos
1037 1.1 christos /* A subroutine of go32_sysinfo to display memory info. */
1038 1.1 christos static void
1039 1.1 christos print_mem (unsigned long datum, const char *header, int in_pages_p)
1040 1.1 christos {
1041 1.1 christos if (datum != 0xffffffffUL)
1042 1.1 christos {
1043 1.1 christos if (in_pages_p)
1044 1.1 christos datum <<= 12;
1045 1.1 christos puts_filtered (header);
1046 1.1 christos if (datum > 1024)
1047 1.1 christos {
1048 1.1 christos printf_filtered ("%lu KB", datum >> 10);
1049 1.1 christos if (datum > 1024 * 1024)
1050 1.1 christos printf_filtered (" (%lu MB)", datum >> 20);
1051 1.1 christos }
1052 1.1 christos else
1053 1.1 christos printf_filtered ("%lu Bytes", datum);
1054 1.1 christos puts_filtered ("\n");
1055 1.1 christos }
1056 1.1 christos }
1057 1.1 christos
1058 1.1 christos /* Display assorted information about the underlying OS. */
1059 1.1 christos static void
1060 1.1 christos go32_sysinfo (char *arg, int from_tty)
1061 1.1 christos {
1062 1.1 christos static const char test_pattern[] =
1063 1.1 christos "deadbeafdeadbeafdeadbeafdeadbeafdeadbeaf"
1064 1.1 christos "deadbeafdeadbeafdeadbeafdeadbeafdeadbeaf"
1065 1.1 christos "deadbeafdeadbeafdeadbeafdeadbeafdeadbeafdeadbeaf";
1066 1.1 christos struct utsname u;
1067 1.1 christos char cpuid_vendor[13];
1068 1.1 christos unsigned cpuid_max = 0, cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
1069 1.1 christos unsigned true_dos_version = _get_dos_version (1);
1070 1.1 christos unsigned advertized_dos_version = ((unsigned int)_osmajor << 8) | _osminor;
1071 1.1 christos int dpmi_flags;
1072 1.1 christos char dpmi_vendor_info[129];
1073 1.1 christos int dpmi_vendor_available;
1074 1.1 christos __dpmi_version_ret dpmi_version_data;
1075 1.1 christos long eflags;
1076 1.1 christos __dpmi_free_mem_info mem_info;
1077 1.1 christos __dpmi_regs regs;
1078 1.1 christos
1079 1.1 christos cpuid_vendor[0] = '\0';
1080 1.1 christos if (uname (&u))
1081 1.1 christos strcpy (u.machine, "Unknown x86");
1082 1.1 christos else if (u.machine[0] == 'i' && u.machine[1] > 4)
1083 1.1 christos {
1084 1.1 christos /* CPUID with EAX = 0 returns the Vendor ID. */
1085 1.1 christos #if 0
1086 1.1.1.2 christos /* Ideally we would use x86_cpuid(), but it needs someone to run
1087 1.1 christos native tests first to make sure things actually work. They should.
1088 1.1 christos http://sourceware.org/ml/gdb-patches/2013-05/msg00164.html */
1089 1.1 christos unsigned int eax, ebx, ecx, edx;
1090 1.1 christos
1091 1.1.1.2 christos if (x86_cpuid (0, &eax, &ebx, &ecx, &edx))
1092 1.1 christos {
1093 1.1 christos cpuid_max = eax;
1094 1.1 christos memcpy (&vendor[0], &ebx, 4);
1095 1.1 christos memcpy (&vendor[4], &ecx, 4);
1096 1.1 christos memcpy (&vendor[8], &edx, 4);
1097 1.1 christos cpuid_vendor[12] = '\0';
1098 1.1 christos }
1099 1.1 christos #else
1100 1.1 christos __asm__ __volatile__ ("xorl %%ebx, %%ebx;"
1101 1.1 christos "xorl %%ecx, %%ecx;"
1102 1.1 christos "xorl %%edx, %%edx;"
1103 1.1 christos "movl $0, %%eax;"
1104 1.1 christos "cpuid;"
1105 1.1 christos "movl %%ebx, %0;"
1106 1.1 christos "movl %%edx, %1;"
1107 1.1 christos "movl %%ecx, %2;"
1108 1.1 christos "movl %%eax, %3;"
1109 1.1 christos : "=m" (cpuid_vendor[0]),
1110 1.1 christos "=m" (cpuid_vendor[4]),
1111 1.1 christos "=m" (cpuid_vendor[8]),
1112 1.1 christos "=m" (cpuid_max)
1113 1.1 christos :
1114 1.1 christos : "%eax", "%ebx", "%ecx", "%edx");
1115 1.1 christos cpuid_vendor[12] = '\0';
1116 1.1 christos #endif
1117 1.1 christos }
1118 1.1 christos
1119 1.1 christos printf_filtered ("CPU Type.......................%s", u.machine);
1120 1.1 christos if (cpuid_vendor[0])
1121 1.1 christos printf_filtered (" (%s)", cpuid_vendor);
1122 1.1 christos puts_filtered ("\n");
1123 1.1 christos
1124 1.1 christos /* CPUID with EAX = 1 returns processor signature and features. */
1125 1.1 christos if (cpuid_max >= 1)
1126 1.1 christos {
1127 1.1 christos static char *brand_name[] = {
1128 1.1 christos "",
1129 1.1 christos " Celeron",
1130 1.1 christos " III",
1131 1.1 christos " III Xeon",
1132 1.1 christos "", "", "", "",
1133 1.1 christos " 4"
1134 1.1 christos };
1135 1.1 christos char cpu_string[80];
1136 1.1 christos char cpu_brand[20];
1137 1.1 christos unsigned brand_idx;
1138 1.1 christos int intel_p = strcmp (cpuid_vendor, "GenuineIntel") == 0;
1139 1.1 christos int amd_p = strcmp (cpuid_vendor, "AuthenticAMD") == 0;
1140 1.1 christos unsigned cpu_family, cpu_model;
1141 1.1 christos
1142 1.1 christos #if 0
1143 1.1 christos /* See comment above about cpuid usage. */
1144 1.1.1.2 christos x86_cpuid (1, &cpuid_eax, &cpuid_ebx, NULL, &cpuid_edx);
1145 1.1 christos #else
1146 1.1 christos __asm__ __volatile__ ("movl $1, %%eax;"
1147 1.1 christos "cpuid;"
1148 1.1 christos : "=a" (cpuid_eax),
1149 1.1 christos "=b" (cpuid_ebx),
1150 1.1 christos "=d" (cpuid_edx)
1151 1.1 christos :
1152 1.1 christos : "%ecx");
1153 1.1 christos #endif
1154 1.1 christos brand_idx = cpuid_ebx & 0xff;
1155 1.1 christos cpu_family = (cpuid_eax >> 8) & 0xf;
1156 1.1 christos cpu_model = (cpuid_eax >> 4) & 0xf;
1157 1.1 christos cpu_brand[0] = '\0';
1158 1.1 christos if (intel_p)
1159 1.1 christos {
1160 1.1 christos if (brand_idx > 0
1161 1.1 christos && brand_idx < sizeof(brand_name)/sizeof(brand_name[0])
1162 1.1 christos && *brand_name[brand_idx])
1163 1.1 christos strcpy (cpu_brand, brand_name[brand_idx]);
1164 1.1 christos else if (cpu_family == 5)
1165 1.1 christos {
1166 1.1 christos if (((cpuid_eax >> 12) & 3) == 0 && cpu_model == 4)
1167 1.1 christos strcpy (cpu_brand, " MMX");
1168 1.1 christos else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 1)
1169 1.1 christos strcpy (cpu_brand, " OverDrive");
1170 1.1 christos else if (cpu_model > 1 && ((cpuid_eax >> 12) & 3) == 2)
1171 1.1 christos strcpy (cpu_brand, " Dual");
1172 1.1 christos }
1173 1.1 christos else if (cpu_family == 6 && cpu_model < 8)
1174 1.1 christos {
1175 1.1 christos switch (cpu_model)
1176 1.1 christos {
1177 1.1 christos case 1:
1178 1.1 christos strcpy (cpu_brand, " Pro");
1179 1.1 christos break;
1180 1.1 christos case 3:
1181 1.1 christos strcpy (cpu_brand, " II");
1182 1.1 christos break;
1183 1.1 christos case 5:
1184 1.1 christos strcpy (cpu_brand, " II Xeon");
1185 1.1 christos break;
1186 1.1 christos case 6:
1187 1.1 christos strcpy (cpu_brand, " Celeron");
1188 1.1 christos break;
1189 1.1 christos case 7:
1190 1.1 christos strcpy (cpu_brand, " III");
1191 1.1 christos break;
1192 1.1 christos }
1193 1.1 christos }
1194 1.1 christos }
1195 1.1 christos else if (amd_p)
1196 1.1 christos {
1197 1.1 christos switch (cpu_family)
1198 1.1 christos {
1199 1.1 christos case 4:
1200 1.1 christos strcpy (cpu_brand, "486/5x86");
1201 1.1 christos break;
1202 1.1 christos case 5:
1203 1.1 christos switch (cpu_model)
1204 1.1 christos {
1205 1.1 christos case 0:
1206 1.1 christos case 1:
1207 1.1 christos case 2:
1208 1.1 christos case 3:
1209 1.1 christos strcpy (cpu_brand, "-K5");
1210 1.1 christos break;
1211 1.1 christos case 6:
1212 1.1 christos case 7:
1213 1.1 christos strcpy (cpu_brand, "-K6");
1214 1.1 christos break;
1215 1.1 christos case 8:
1216 1.1 christos strcpy (cpu_brand, "-K6-2");
1217 1.1 christos break;
1218 1.1 christos case 9:
1219 1.1 christos strcpy (cpu_brand, "-K6-III");
1220 1.1 christos break;
1221 1.1 christos }
1222 1.1 christos break;
1223 1.1 christos case 6:
1224 1.1 christos switch (cpu_model)
1225 1.1 christos {
1226 1.1 christos case 1:
1227 1.1 christos case 2:
1228 1.1 christos case 4:
1229 1.1 christos strcpy (cpu_brand, " Athlon");
1230 1.1 christos break;
1231 1.1 christos case 3:
1232 1.1 christos strcpy (cpu_brand, " Duron");
1233 1.1 christos break;
1234 1.1 christos }
1235 1.1 christos break;
1236 1.1 christos }
1237 1.1 christos }
1238 1.1 christos xsnprintf (cpu_string, sizeof (cpu_string), "%s%s Model %d Stepping %d",
1239 1.1 christos intel_p ? "Pentium" : (amd_p ? "AMD" : "ix86"),
1240 1.1 christos cpu_brand, cpu_model, cpuid_eax & 0xf);
1241 1.1 christos printfi_filtered (31, "%s\n", cpu_string);
1242 1.1 christos if (((cpuid_edx & (6 | (0x0d << 23))) != 0)
1243 1.1 christos || ((cpuid_edx & 1) == 0)
1244 1.1 christos || (amd_p && (cpuid_edx & (3 << 30)) != 0))
1245 1.1 christos {
1246 1.1 christos puts_filtered ("CPU Features...................");
1247 1.1 christos /* We only list features which might be useful in the DPMI
1248 1.1 christos environment. */
1249 1.1 christos if ((cpuid_edx & 1) == 0)
1250 1.1 christos puts_filtered ("No FPU "); /* It's unusual to not have an FPU. */
1251 1.1 christos if ((cpuid_edx & (1 << 1)) != 0)
1252 1.1 christos puts_filtered ("VME ");
1253 1.1 christos if ((cpuid_edx & (1 << 2)) != 0)
1254 1.1 christos puts_filtered ("DE ");
1255 1.1 christos if ((cpuid_edx & (1 << 4)) != 0)
1256 1.1 christos puts_filtered ("TSC ");
1257 1.1 christos if ((cpuid_edx & (1 << 23)) != 0)
1258 1.1 christos puts_filtered ("MMX ");
1259 1.1 christos if ((cpuid_edx & (1 << 25)) != 0)
1260 1.1 christos puts_filtered ("SSE ");
1261 1.1 christos if ((cpuid_edx & (1 << 26)) != 0)
1262 1.1 christos puts_filtered ("SSE2 ");
1263 1.1 christos if (amd_p)
1264 1.1 christos {
1265 1.1 christos if ((cpuid_edx & (1 << 31)) != 0)
1266 1.1 christos puts_filtered ("3DNow! ");
1267 1.1 christos if ((cpuid_edx & (1 << 30)) != 0)
1268 1.1 christos puts_filtered ("3DNow!Ext");
1269 1.1 christos }
1270 1.1 christos puts_filtered ("\n");
1271 1.1 christos }
1272 1.1 christos }
1273 1.1 christos puts_filtered ("\n");
1274 1.1 christos printf_filtered ("DOS Version....................%s %s.%s",
1275 1.1 christos _os_flavor, u.release, u.version);
1276 1.1 christos if (true_dos_version != advertized_dos_version)
1277 1.1 christos printf_filtered (" (disguised as v%d.%d)", _osmajor, _osminor);
1278 1.1 christos puts_filtered ("\n");
1279 1.1 christos if (!windows_major)
1280 1.1 christos go32_get_windows_version ();
1281 1.1 christos if (windows_major != 0xff)
1282 1.1 christos {
1283 1.1 christos const char *windows_flavor;
1284 1.1 christos
1285 1.1 christos printf_filtered ("Windows Version................%d.%02d (Windows ",
1286 1.1 christos windows_major, windows_minor);
1287 1.1 christos switch (windows_major)
1288 1.1 christos {
1289 1.1 christos case 3:
1290 1.1 christos windows_flavor = "3.X";
1291 1.1 christos break;
1292 1.1 christos case 4:
1293 1.1 christos switch (windows_minor)
1294 1.1 christos {
1295 1.1 christos case 0:
1296 1.1 christos windows_flavor = "95, 95A, or 95B";
1297 1.1 christos break;
1298 1.1 christos case 3:
1299 1.1 christos windows_flavor = "95B OSR2.1 or 95C OSR2.5";
1300 1.1 christos break;
1301 1.1 christos case 10:
1302 1.1 christos windows_flavor = "98 or 98 SE";
1303 1.1 christos break;
1304 1.1 christos case 90:
1305 1.1 christos windows_flavor = "ME";
1306 1.1 christos break;
1307 1.1 christos default:
1308 1.1 christos windows_flavor = "9X";
1309 1.1 christos break;
1310 1.1 christos }
1311 1.1 christos break;
1312 1.1 christos default:
1313 1.1 christos windows_flavor = "??";
1314 1.1 christos break;
1315 1.1 christos }
1316 1.1 christos printf_filtered ("%s)\n", windows_flavor);
1317 1.1 christos }
1318 1.1 christos else if (true_dos_version == 0x532 && advertized_dos_version == 0x500)
1319 1.1 christos printf_filtered ("Windows Version................"
1320 1.1 christos "Windows NT family (W2K/XP/W2K3/Vista/W2K8)\n");
1321 1.1 christos puts_filtered ("\n");
1322 1.1 christos /* On some versions of Windows, __dpmi_get_capabilities returns
1323 1.1 christos zero, but the buffer is not filled with info, so we fill the
1324 1.1 christos buffer with a known pattern and test for it afterwards. */
1325 1.1 christos memcpy (dpmi_vendor_info, test_pattern, sizeof(dpmi_vendor_info));
1326 1.1 christos dpmi_vendor_available =
1327 1.1 christos __dpmi_get_capabilities (&dpmi_flags, dpmi_vendor_info);
1328 1.1 christos if (dpmi_vendor_available == 0
1329 1.1 christos && memcmp (dpmi_vendor_info, test_pattern,
1330 1.1 christos sizeof(dpmi_vendor_info)) != 0)
1331 1.1 christos {
1332 1.1 christos /* The DPMI spec says the vendor string should be ASCIIZ, but
1333 1.1 christos I don't trust the vendors to follow that... */
1334 1.1 christos if (!memchr (&dpmi_vendor_info[2], 0, 126))
1335 1.1 christos dpmi_vendor_info[128] = '\0';
1336 1.1 christos printf_filtered ("DPMI Host......................"
1337 1.1 christos "%s v%d.%d (capabilities: %#x)\n",
1338 1.1 christos &dpmi_vendor_info[2],
1339 1.1 christos (unsigned)dpmi_vendor_info[0],
1340 1.1 christos (unsigned)dpmi_vendor_info[1],
1341 1.1 christos ((unsigned)dpmi_flags & 0x7f));
1342 1.1 christos }
1343 1.1 christos else
1344 1.1 christos printf_filtered ("DPMI Host......................(Info not available)\n");
1345 1.1 christos __dpmi_get_version (&dpmi_version_data);
1346 1.1 christos printf_filtered ("DPMI Version...................%d.%02d\n",
1347 1.1 christos dpmi_version_data.major, dpmi_version_data.minor);
1348 1.1 christos printf_filtered ("DPMI Info......................"
1349 1.1 christos "%s-bit DPMI, with%s Virtual Memory support\n",
1350 1.1 christos (dpmi_version_data.flags & 1) ? "32" : "16",
1351 1.1 christos (dpmi_version_data.flags & 4) ? "" : "out");
1352 1.1 christos printfi_filtered (31, "Interrupts reflected to %s mode\n",
1353 1.1 christos (dpmi_version_data.flags & 2) ? "V86" : "Real");
1354 1.1 christos printfi_filtered (31, "Processor type: i%d86\n",
1355 1.1 christos dpmi_version_data.cpu);
1356 1.1 christos printfi_filtered (31, "PIC base interrupt: Master: %#x Slave: %#x\n",
1357 1.1 christos dpmi_version_data.master_pic, dpmi_version_data.slave_pic);
1358 1.1 christos
1359 1.1 christos /* a_tss is only initialized when the debuggee is first run. */
1360 1.1 christos if (prog_has_started)
1361 1.1 christos {
1362 1.1 christos __asm__ __volatile__ ("pushfl ; popl %0" : "=g" (eflags));
1363 1.1 christos printf_filtered ("Protection....................."
1364 1.1 christos "Ring %d (in %s), with%s I/O protection\n",
1365 1.1 christos a_tss.tss_cs & 3, (a_tss.tss_cs & 4) ? "LDT" : "GDT",
1366 1.1 christos (a_tss.tss_cs & 3) > ((eflags >> 12) & 3) ? "" : "out");
1367 1.1 christos }
1368 1.1 christos puts_filtered ("\n");
1369 1.1 christos __dpmi_get_free_memory_information (&mem_info);
1370 1.1 christos print_mem (mem_info.total_number_of_physical_pages,
1371 1.1 christos "DPMI Total Physical Memory.....", 1);
1372 1.1 christos print_mem (mem_info.total_number_of_free_pages,
1373 1.1 christos "DPMI Free Physical Memory......", 1);
1374 1.1 christos print_mem (mem_info.size_of_paging_file_partition_in_pages,
1375 1.1 christos "DPMI Swap Space................", 1);
1376 1.1 christos print_mem (mem_info.linear_address_space_size_in_pages,
1377 1.1 christos "DPMI Total Linear Address Size.", 1);
1378 1.1 christos print_mem (mem_info.free_linear_address_space_in_pages,
1379 1.1 christos "DPMI Free Linear Address Size..", 1);
1380 1.1 christos print_mem (mem_info.largest_available_free_block_in_bytes,
1381 1.1 christos "DPMI Largest Free Memory Block.", 0);
1382 1.1 christos
1383 1.1 christos regs.h.ah = 0x48;
1384 1.1 christos regs.x.bx = 0xffff;
1385 1.1 christos __dpmi_int (0x21, ®s);
1386 1.1 christos print_mem (regs.x.bx << 4, "Free DOS Memory................", 0);
1387 1.1 christos regs.x.ax = 0x5800;
1388 1.1 christos __dpmi_int (0x21, ®s);
1389 1.1 christos if ((regs.x.flags & 1) == 0)
1390 1.1 christos {
1391 1.1 christos static const char *dos_hilo[] = {
1392 1.1 christos "Low", "", "", "", "High", "", "", "", "High, then Low"
1393 1.1 christos };
1394 1.1 christos static const char *dos_fit[] = {
1395 1.1 christos "First", "Best", "Last"
1396 1.1 christos };
1397 1.1 christos int hilo_idx = (regs.x.ax >> 4) & 0x0f;
1398 1.1 christos int fit_idx = regs.x.ax & 0x0f;
1399 1.1 christos
1400 1.1 christos if (hilo_idx > 8)
1401 1.1 christos hilo_idx = 0;
1402 1.1 christos if (fit_idx > 2)
1403 1.1 christos fit_idx = 0;
1404 1.1 christos printf_filtered ("DOS Memory Allocation..........%s memory, %s fit\n",
1405 1.1 christos dos_hilo[hilo_idx], dos_fit[fit_idx]);
1406 1.1 christos regs.x.ax = 0x5802;
1407 1.1 christos __dpmi_int (0x21, ®s);
1408 1.1 christos if ((regs.x.flags & 1) != 0)
1409 1.1 christos regs.h.al = 0;
1410 1.1 christos printfi_filtered (31, "UMBs %sin DOS memory chain\n",
1411 1.1 christos regs.h.al == 0 ? "not " : "");
1412 1.1 christos }
1413 1.1 christos }
1414 1.1 christos
1415 1.1 christos struct seg_descr {
1416 1.1 christos unsigned short limit0;
1417 1.1 christos unsigned short base0;
1418 1.1 christos unsigned char base1;
1419 1.1 christos unsigned stype:5;
1420 1.1 christos unsigned dpl:2;
1421 1.1 christos unsigned present:1;
1422 1.1 christos unsigned limit1:4;
1423 1.1 christos unsigned available:1;
1424 1.1 christos unsigned dummy:1;
1425 1.1 christos unsigned bit32:1;
1426 1.1 christos unsigned page_granular:1;
1427 1.1 christos unsigned char base2;
1428 1.1 christos } __attribute__ ((packed));
1429 1.1 christos
1430 1.1 christos struct gate_descr {
1431 1.1 christos unsigned short offset0;
1432 1.1 christos unsigned short selector;
1433 1.1 christos unsigned param_count:5;
1434 1.1 christos unsigned dummy:3;
1435 1.1 christos unsigned stype:5;
1436 1.1 christos unsigned dpl:2;
1437 1.1 christos unsigned present:1;
1438 1.1 christos unsigned short offset1;
1439 1.1 christos } __attribute__ ((packed));
1440 1.1 christos
1441 1.1 christos /* Read LEN bytes starting at logical address ADDR, and put the result
1442 1.1 christos into DEST. Return 1 if success, zero if not. */
1443 1.1 christos static int
1444 1.1 christos read_memory_region (unsigned long addr, void *dest, size_t len)
1445 1.1 christos {
1446 1.1 christos unsigned long dos_ds_limit = __dpmi_get_segment_limit (_dos_ds);
1447 1.1 christos int retval = 1;
1448 1.1 christos
1449 1.1 christos /* For the low memory, we can simply use _dos_ds. */
1450 1.1 christos if (addr <= dos_ds_limit - len)
1451 1.1 christos dosmemget (addr, len, dest);
1452 1.1 christos else
1453 1.1 christos {
1454 1.1 christos /* For memory above 1MB we need to set up a special segment to
1455 1.1 christos be able to access that memory. */
1456 1.1 christos int sel = __dpmi_allocate_ldt_descriptors (1);
1457 1.1 christos
1458 1.1 christos if (sel <= 0)
1459 1.1 christos retval = 0;
1460 1.1 christos else
1461 1.1 christos {
1462 1.1 christos int access_rights = __dpmi_get_descriptor_access_rights (sel);
1463 1.1 christos size_t segment_limit = len - 1;
1464 1.1 christos
1465 1.1 christos /* Make sure the crucial bits in the descriptor access
1466 1.1 christos rights are set correctly. Some DPMI providers might barf
1467 1.1 christos if we set the segment limit to something that is not an
1468 1.1 christos integral multiple of 4KB pages if the granularity bit is
1469 1.1 christos not set to byte-granular, even though the DPMI spec says
1470 1.1 christos it's the host's responsibility to set that bit correctly. */
1471 1.1 christos if (len > 1024 * 1024)
1472 1.1 christos {
1473 1.1 christos access_rights |= 0x8000;
1474 1.1 christos /* Page-granular segments should have the low 12 bits of
1475 1.1 christos the limit set. */
1476 1.1 christos segment_limit |= 0xfff;
1477 1.1 christos }
1478 1.1 christos else
1479 1.1 christos access_rights &= ~0x8000;
1480 1.1 christos
1481 1.1 christos if (__dpmi_set_segment_base_address (sel, addr) != -1
1482 1.1 christos && __dpmi_set_descriptor_access_rights (sel, access_rights) != -1
1483 1.1 christos && __dpmi_set_segment_limit (sel, segment_limit) != -1
1484 1.1 christos /* W2K silently fails to set the segment limit, leaving
1485 1.1 christos it at zero; this test avoids the resulting crash. */
1486 1.1 christos && __dpmi_get_segment_limit (sel) >= segment_limit)
1487 1.1 christos movedata (sel, 0, _my_ds (), (unsigned)dest, len);
1488 1.1 christos else
1489 1.1 christos retval = 0;
1490 1.1 christos
1491 1.1 christos __dpmi_free_ldt_descriptor (sel);
1492 1.1 christos }
1493 1.1 christos }
1494 1.1 christos return retval;
1495 1.1 christos }
1496 1.1 christos
1497 1.1 christos /* Get a segment descriptor stored at index IDX in the descriptor
1498 1.1 christos table whose base address is TABLE_BASE. Return the descriptor
1499 1.1 christos type, or -1 if failure. */
1500 1.1 christos static int
1501 1.1 christos get_descriptor (unsigned long table_base, int idx, void *descr)
1502 1.1 christos {
1503 1.1 christos unsigned long addr = table_base + idx * 8; /* 8 bytes per entry */
1504 1.1 christos
1505 1.1 christos if (read_memory_region (addr, descr, 8))
1506 1.1 christos return (int)((struct seg_descr *)descr)->stype;
1507 1.1 christos return -1;
1508 1.1 christos }
1509 1.1 christos
1510 1.1 christos struct dtr_reg {
1511 1.1 christos unsigned short limit __attribute__((packed));
1512 1.1 christos unsigned long base __attribute__((packed));
1513 1.1 christos };
1514 1.1 christos
1515 1.1 christos /* Display a segment descriptor stored at index IDX in a descriptor
1516 1.1 christos table whose type is TYPE and whose base address is BASE_ADDR. If
1517 1.1 christos FORCE is non-zero, display even invalid descriptors. */
1518 1.1 christos static void
1519 1.1 christos display_descriptor (unsigned type, unsigned long base_addr, int idx, int force)
1520 1.1 christos {
1521 1.1 christos struct seg_descr descr;
1522 1.1 christos struct gate_descr gate;
1523 1.1 christos
1524 1.1 christos /* Get the descriptor from the table. */
1525 1.1 christos if (idx == 0 && type == 0)
1526 1.1 christos puts_filtered ("0x000: null descriptor\n");
1527 1.1 christos else if (get_descriptor (base_addr, idx, &descr) != -1)
1528 1.1 christos {
1529 1.1 christos /* For each type of descriptor table, this has a bit set if the
1530 1.1 christos corresponding type of selectors is valid in that table. */
1531 1.1 christos static unsigned allowed_descriptors[] = {
1532 1.1 christos 0xffffdafeL, /* GDT */
1533 1.1 christos 0x0000c0e0L, /* IDT */
1534 1.1 christos 0xffffdafaL /* LDT */
1535 1.1 christos };
1536 1.1 christos
1537 1.1 christos /* If the program hasn't started yet, assume the debuggee will
1538 1.1 christos have the same CPL as the debugger. */
1539 1.1 christos int cpl = prog_has_started ? (a_tss.tss_cs & 3) : _my_cs () & 3;
1540 1.1 christos unsigned long limit = (descr.limit1 << 16) | descr.limit0;
1541 1.1 christos
1542 1.1 christos if (descr.present
1543 1.1 christos && (allowed_descriptors[type] & (1 << descr.stype)) != 0)
1544 1.1 christos {
1545 1.1 christos printf_filtered ("0x%03x: ",
1546 1.1 christos type == 1
1547 1.1 christos ? idx : (idx * 8) | (type ? (cpl | 4) : 0));
1548 1.1 christos if (descr.page_granular)
1549 1.1 christos limit = (limit << 12) | 0xfff; /* big segment: low 12 bit set */
1550 1.1 christos if (descr.stype == 1 || descr.stype == 2 || descr.stype == 3
1551 1.1 christos || descr.stype == 9 || descr.stype == 11
1552 1.1 christos || (descr.stype >= 16 && descr.stype < 32))
1553 1.1 christos printf_filtered ("base=0x%02x%02x%04x limit=0x%08lx",
1554 1.1 christos descr.base2, descr.base1, descr.base0, limit);
1555 1.1 christos
1556 1.1 christos switch (descr.stype)
1557 1.1 christos {
1558 1.1 christos case 1:
1559 1.1 christos case 3:
1560 1.1 christos printf_filtered (" 16-bit TSS (task %sactive)",
1561 1.1 christos descr.stype == 3 ? "" : "in");
1562 1.1 christos break;
1563 1.1 christos case 2:
1564 1.1 christos puts_filtered (" LDT");
1565 1.1 christos break;
1566 1.1 christos case 4:
1567 1.1 christos memcpy (&gate, &descr, sizeof gate);
1568 1.1 christos printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1569 1.1 christos gate.selector, gate.offset1, gate.offset0);
1570 1.1 christos printf_filtered (" 16-bit Call Gate (params=%d)",
1571 1.1 christos gate.param_count);
1572 1.1 christos break;
1573 1.1 christos case 5:
1574 1.1 christos printf_filtered ("TSS selector=0x%04x", descr.base0);
1575 1.1 christos printfi_filtered (16, "Task Gate");
1576 1.1 christos break;
1577 1.1 christos case 6:
1578 1.1 christos case 7:
1579 1.1 christos memcpy (&gate, &descr, sizeof gate);
1580 1.1 christos printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1581 1.1 christos gate.selector, gate.offset1, gate.offset0);
1582 1.1 christos printf_filtered (" 16-bit %s Gate",
1583 1.1 christos descr.stype == 6 ? "Interrupt" : "Trap");
1584 1.1 christos break;
1585 1.1 christos case 9:
1586 1.1 christos case 11:
1587 1.1 christos printf_filtered (" 32-bit TSS (task %sactive)",
1588 1.1 christos descr.stype == 3 ? "" : "in");
1589 1.1 christos break;
1590 1.1 christos case 12:
1591 1.1 christos memcpy (&gate, &descr, sizeof gate);
1592 1.1 christos printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1593 1.1 christos gate.selector, gate.offset1, gate.offset0);
1594 1.1 christos printf_filtered (" 32-bit Call Gate (params=%d)",
1595 1.1 christos gate.param_count);
1596 1.1 christos break;
1597 1.1 christos case 14:
1598 1.1 christos case 15:
1599 1.1 christos memcpy (&gate, &descr, sizeof gate);
1600 1.1 christos printf_filtered ("selector=0x%04x offs=0x%04x%04x",
1601 1.1 christos gate.selector, gate.offset1, gate.offset0);
1602 1.1 christos printf_filtered (" 32-bit %s Gate",
1603 1.1 christos descr.stype == 14 ? "Interrupt" : "Trap");
1604 1.1 christos break;
1605 1.1 christos case 16: /* data segments */
1606 1.1 christos case 17:
1607 1.1 christos case 18:
1608 1.1 christos case 19:
1609 1.1 christos case 20:
1610 1.1 christos case 21:
1611 1.1 christos case 22:
1612 1.1 christos case 23:
1613 1.1 christos printf_filtered (" %s-bit Data (%s Exp-%s%s)",
1614 1.1 christos descr.bit32 ? "32" : "16",
1615 1.1 christos descr.stype & 2
1616 1.1 christos ? "Read/Write," : "Read-Only, ",
1617 1.1 christos descr.stype & 4 ? "down" : "up",
1618 1.1 christos descr.stype & 1 ? "" : ", N.Acc");
1619 1.1 christos break;
1620 1.1 christos case 24: /* code segments */
1621 1.1 christos case 25:
1622 1.1 christos case 26:
1623 1.1 christos case 27:
1624 1.1 christos case 28:
1625 1.1 christos case 29:
1626 1.1 christos case 30:
1627 1.1 christos case 31:
1628 1.1 christos printf_filtered (" %s-bit Code (%s, %sConf%s)",
1629 1.1 christos descr.bit32 ? "32" : "16",
1630 1.1 christos descr.stype & 2 ? "Exec/Read" : "Exec-Only",
1631 1.1 christos descr.stype & 4 ? "" : "N.",
1632 1.1 christos descr.stype & 1 ? "" : ", N.Acc");
1633 1.1 christos break;
1634 1.1 christos default:
1635 1.1 christos printf_filtered ("Unknown type 0x%02x", descr.stype);
1636 1.1 christos break;
1637 1.1 christos }
1638 1.1 christos puts_filtered ("\n");
1639 1.1 christos }
1640 1.1 christos else if (force)
1641 1.1 christos {
1642 1.1 christos printf_filtered ("0x%03x: ",
1643 1.1 christos type == 1
1644 1.1 christos ? idx : (idx * 8) | (type ? (cpl | 4) : 0));
1645 1.1 christos if (!descr.present)
1646 1.1 christos puts_filtered ("Segment not present\n");
1647 1.1 christos else
1648 1.1 christos printf_filtered ("Segment type 0x%02x is invalid in this table\n",
1649 1.1 christos descr.stype);
1650 1.1 christos }
1651 1.1 christos }
1652 1.1 christos else if (force)
1653 1.1 christos printf_filtered ("0x%03x: Cannot read this descriptor\n", idx);
1654 1.1 christos }
1655 1.1 christos
1656 1.1 christos static void
1657 1.1 christos go32_sldt (char *arg, int from_tty)
1658 1.1 christos {
1659 1.1 christos struct dtr_reg gdtr;
1660 1.1 christos unsigned short ldtr = 0;
1661 1.1 christos int ldt_idx;
1662 1.1 christos struct seg_descr ldt_descr;
1663 1.1 christos long ldt_entry = -1L;
1664 1.1 christos int cpl = (prog_has_started ? a_tss.tss_cs : _my_cs ()) & 3;
1665 1.1 christos
1666 1.1 christos if (arg && *arg)
1667 1.1 christos {
1668 1.1 christos arg = skip_spaces (arg);
1669 1.1 christos
1670 1.1 christos if (*arg)
1671 1.1 christos {
1672 1.1 christos ldt_entry = parse_and_eval_long (arg);
1673 1.1 christos if (ldt_entry < 0
1674 1.1 christos || (ldt_entry & 4) == 0
1675 1.1 christos || (ldt_entry & 3) != (cpl & 3))
1676 1.1 christos error (_("Invalid LDT entry 0x%03lx."), (unsigned long)ldt_entry);
1677 1.1 christos }
1678 1.1 christos }
1679 1.1 christos
1680 1.1 christos __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ );
1681 1.1 christos __asm__ __volatile__ ("sldt %0" : "=m" (ldtr) : /* no inputs */ );
1682 1.1 christos ldt_idx = ldtr / 8;
1683 1.1 christos if (ldt_idx == 0)
1684 1.1 christos puts_filtered ("There is no LDT.\n");
1685 1.1 christos /* LDT's entry in the GDT must have the type LDT, which is 2. */
1686 1.1 christos else if (get_descriptor (gdtr.base, ldt_idx, &ldt_descr) != 2)
1687 1.1 christos printf_filtered ("LDT is present (at %#x), but unreadable by GDB.\n",
1688 1.1 christos ldt_descr.base0
1689 1.1 christos | (ldt_descr.base1 << 16)
1690 1.1 christos | (ldt_descr.base2 << 24));
1691 1.1 christos else
1692 1.1 christos {
1693 1.1 christos unsigned base =
1694 1.1 christos ldt_descr.base0
1695 1.1 christos | (ldt_descr.base1 << 16)
1696 1.1 christos | (ldt_descr.base2 << 24);
1697 1.1 christos unsigned limit = ldt_descr.limit0 | (ldt_descr.limit1 << 16);
1698 1.1 christos int max_entry;
1699 1.1 christos
1700 1.1 christos if (ldt_descr.page_granular)
1701 1.1 christos /* Page-granular segments must have the low 12 bits of their
1702 1.1 christos limit set. */
1703 1.1 christos limit = (limit << 12) | 0xfff;
1704 1.1 christos /* LDT cannot have more than 8K 8-byte entries, i.e. more than
1705 1.1 christos 64KB. */
1706 1.1 christos if (limit > 0xffff)
1707 1.1 christos limit = 0xffff;
1708 1.1 christos
1709 1.1 christos max_entry = (limit + 1) / 8;
1710 1.1 christos
1711 1.1 christos if (ldt_entry >= 0)
1712 1.1 christos {
1713 1.1 christos if (ldt_entry > limit)
1714 1.1 christos error (_("Invalid LDT entry %#lx: outside valid limits [0..%#x]"),
1715 1.1 christos (unsigned long)ldt_entry, limit);
1716 1.1 christos
1717 1.1 christos display_descriptor (ldt_descr.stype, base, ldt_entry / 8, 1);
1718 1.1 christos }
1719 1.1 christos else
1720 1.1 christos {
1721 1.1 christos int i;
1722 1.1 christos
1723 1.1 christos for (i = 0; i < max_entry; i++)
1724 1.1 christos display_descriptor (ldt_descr.stype, base, i, 0);
1725 1.1 christos }
1726 1.1 christos }
1727 1.1 christos }
1728 1.1 christos
1729 1.1 christos static void
1730 1.1 christos go32_sgdt (char *arg, int from_tty)
1731 1.1 christos {
1732 1.1 christos struct dtr_reg gdtr;
1733 1.1 christos long gdt_entry = -1L;
1734 1.1 christos int max_entry;
1735 1.1 christos
1736 1.1 christos if (arg && *arg)
1737 1.1 christos {
1738 1.1 christos arg = skip_spaces (arg);
1739 1.1 christos
1740 1.1 christos if (*arg)
1741 1.1 christos {
1742 1.1 christos gdt_entry = parse_and_eval_long (arg);
1743 1.1 christos if (gdt_entry < 0 || (gdt_entry & 7) != 0)
1744 1.1 christos error (_("Invalid GDT entry 0x%03lx: "
1745 1.1 christos "not an integral multiple of 8."),
1746 1.1 christos (unsigned long)gdt_entry);
1747 1.1 christos }
1748 1.1 christos }
1749 1.1 christos
1750 1.1 christos __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ );
1751 1.1 christos max_entry = (gdtr.limit + 1) / 8;
1752 1.1 christos
1753 1.1 christos if (gdt_entry >= 0)
1754 1.1 christos {
1755 1.1 christos if (gdt_entry > gdtr.limit)
1756 1.1 christos error (_("Invalid GDT entry %#lx: outside valid limits [0..%#x]"),
1757 1.1 christos (unsigned long)gdt_entry, gdtr.limit);
1758 1.1 christos
1759 1.1 christos display_descriptor (0, gdtr.base, gdt_entry / 8, 1);
1760 1.1 christos }
1761 1.1 christos else
1762 1.1 christos {
1763 1.1 christos int i;
1764 1.1 christos
1765 1.1 christos for (i = 0; i < max_entry; i++)
1766 1.1 christos display_descriptor (0, gdtr.base, i, 0);
1767 1.1 christos }
1768 1.1 christos }
1769 1.1 christos
1770 1.1 christos static void
1771 1.1 christos go32_sidt (char *arg, int from_tty)
1772 1.1 christos {
1773 1.1 christos struct dtr_reg idtr;
1774 1.1 christos long idt_entry = -1L;
1775 1.1 christos int max_entry;
1776 1.1 christos
1777 1.1 christos if (arg && *arg)
1778 1.1 christos {
1779 1.1 christos arg = skip_spaces (arg);
1780 1.1 christos
1781 1.1 christos if (*arg)
1782 1.1 christos {
1783 1.1 christos idt_entry = parse_and_eval_long (arg);
1784 1.1 christos if (idt_entry < 0)
1785 1.1 christos error (_("Invalid (negative) IDT entry %ld."), idt_entry);
1786 1.1 christos }
1787 1.1 christos }
1788 1.1 christos
1789 1.1 christos __asm__ __volatile__ ("sidt %0" : "=m" (idtr) : /* no inputs */ );
1790 1.1 christos max_entry = (idtr.limit + 1) / 8;
1791 1.1 christos if (max_entry > 0x100) /* No more than 256 entries. */
1792 1.1 christos max_entry = 0x100;
1793 1.1 christos
1794 1.1 christos if (idt_entry >= 0)
1795 1.1 christos {
1796 1.1 christos if (idt_entry > idtr.limit)
1797 1.1 christos error (_("Invalid IDT entry %#lx: outside valid limits [0..%#x]"),
1798 1.1 christos (unsigned long)idt_entry, idtr.limit);
1799 1.1 christos
1800 1.1 christos display_descriptor (1, idtr.base, idt_entry, 1);
1801 1.1 christos }
1802 1.1 christos else
1803 1.1 christos {
1804 1.1 christos int i;
1805 1.1 christos
1806 1.1 christos for (i = 0; i < max_entry; i++)
1807 1.1 christos display_descriptor (1, idtr.base, i, 0);
1808 1.1 christos }
1809 1.1 christos }
1810 1.1 christos
1811 1.1 christos /* Cached linear address of the base of the page directory. For
1812 1.1 christos now, available only under CWSDPMI. Code based on ideas and
1813 1.1 christos suggestions from Charles Sandmann <sandmann (at) clio.rice.edu>. */
1814 1.1 christos static unsigned long pdbr;
1815 1.1 christos
1816 1.1 christos static unsigned long
1817 1.1 christos get_cr3 (void)
1818 1.1 christos {
1819 1.1 christos unsigned offset;
1820 1.1 christos unsigned taskreg;
1821 1.1 christos unsigned long taskbase, cr3;
1822 1.1 christos struct dtr_reg gdtr;
1823 1.1 christos
1824 1.1 christos if (pdbr > 0 && pdbr <= 0xfffff)
1825 1.1 christos return pdbr;
1826 1.1 christos
1827 1.1 christos /* Get the linear address of GDT and the Task Register. */
1828 1.1 christos __asm__ __volatile__ ("sgdt %0" : "=m" (gdtr) : /* no inputs */ );
1829 1.1 christos __asm__ __volatile__ ("str %0" : "=m" (taskreg) : /* no inputs */ );
1830 1.1 christos
1831 1.1 christos /* Task Register is a segment selector for the TSS of the current
1832 1.1 christos task. Therefore, it can be used as an index into the GDT to get
1833 1.1 christos at the segment descriptor for the TSS. To get the index, reset
1834 1.1 christos the low 3 bits of the selector (which give the CPL). Add 2 to the
1835 1.1 christos offset to point to the 3 low bytes of the base address. */
1836 1.1 christos offset = gdtr.base + (taskreg & 0xfff8) + 2;
1837 1.1 christos
1838 1.1 christos
1839 1.1 christos /* CWSDPMI's task base is always under the 1MB mark. */
1840 1.1 christos if (offset > 0xfffff)
1841 1.1 christos return 0;
1842 1.1 christos
1843 1.1 christos _farsetsel (_dos_ds);
1844 1.1 christos taskbase = _farnspeekl (offset) & 0xffffffU;
1845 1.1 christos taskbase += _farnspeekl (offset + 2) & 0xff000000U;
1846 1.1 christos if (taskbase > 0xfffff)
1847 1.1 christos return 0;
1848 1.1 christos
1849 1.1 christos /* CR3 (a.k.a. PDBR, the Page Directory Base Register) is stored at
1850 1.1 christos offset 1Ch in the TSS. */
1851 1.1 christos cr3 = _farnspeekl (taskbase + 0x1c) & ~0xfff;
1852 1.1 christos if (cr3 > 0xfffff)
1853 1.1 christos {
1854 1.1 christos #if 0 /* Not fullly supported yet. */
1855 1.1 christos /* The Page Directory is in UMBs. In that case, CWSDPMI puts
1856 1.1 christos the first Page Table right below the Page Directory. Thus,
1857 1.1 christos the first Page Table's entry for its own address and the Page
1858 1.1 christos Directory entry for that Page Table will hold the same
1859 1.1 christos physical address. The loop below searches the entire UMB
1860 1.1 christos range of addresses for such an occurence. */
1861 1.1 christos unsigned long addr, pte_idx;
1862 1.1 christos
1863 1.1 christos for (addr = 0xb0000, pte_idx = 0xb0;
1864 1.1 christos pte_idx < 0xff;
1865 1.1 christos addr += 0x1000, pte_idx++)
1866 1.1 christos {
1867 1.1 christos if (((_farnspeekl (addr + 4 * pte_idx) & 0xfffff027) ==
1868 1.1 christos (_farnspeekl (addr + 0x1000) & 0xfffff027))
1869 1.1 christos && ((_farnspeekl (addr + 4 * pte_idx + 4) & 0xfffff000) == cr3))
1870 1.1 christos {
1871 1.1 christos cr3 = addr + 0x1000;
1872 1.1 christos break;
1873 1.1 christos }
1874 1.1 christos }
1875 1.1 christos #endif
1876 1.1 christos
1877 1.1 christos if (cr3 > 0xfffff)
1878 1.1 christos cr3 = 0;
1879 1.1 christos }
1880 1.1 christos
1881 1.1 christos return cr3;
1882 1.1 christos }
1883 1.1 christos
1884 1.1 christos /* Return the N'th Page Directory entry. */
1885 1.1 christos static unsigned long
1886 1.1 christos get_pde (int n)
1887 1.1 christos {
1888 1.1 christos unsigned long pde = 0;
1889 1.1 christos
1890 1.1 christos if (pdbr && n >= 0 && n < 1024)
1891 1.1 christos {
1892 1.1 christos pde = _farpeekl (_dos_ds, pdbr + 4*n);
1893 1.1 christos }
1894 1.1 christos return pde;
1895 1.1 christos }
1896 1.1 christos
1897 1.1 christos /* Return the N'th entry of the Page Table whose Page Directory entry
1898 1.1 christos is PDE. */
1899 1.1 christos static unsigned long
1900 1.1 christos get_pte (unsigned long pde, int n)
1901 1.1 christos {
1902 1.1 christos unsigned long pte = 0;
1903 1.1 christos
1904 1.1 christos /* pde & 0x80 tests the 4MB page bit. We don't support 4MB
1905 1.1 christos page tables, for now. */
1906 1.1 christos if ((pde & 1) && !(pde & 0x80) && n >= 0 && n < 1024)
1907 1.1 christos {
1908 1.1 christos pde &= ~0xfff; /* Clear non-address bits. */
1909 1.1 christos pte = _farpeekl (_dos_ds, pde + 4*n);
1910 1.1 christos }
1911 1.1 christos return pte;
1912 1.1 christos }
1913 1.1 christos
1914 1.1 christos /* Display a Page Directory or Page Table entry. IS_DIR, if non-zero,
1915 1.1 christos says this is a Page Directory entry. If FORCE is non-zero, display
1916 1.1 christos the entry even if its Present flag is off. OFF is the offset of the
1917 1.1 christos address from the page's base address. */
1918 1.1 christos static void
1919 1.1 christos display_ptable_entry (unsigned long entry, int is_dir, int force, unsigned off)
1920 1.1 christos {
1921 1.1 christos if ((entry & 1) != 0)
1922 1.1 christos {
1923 1.1 christos printf_filtered ("Base=0x%05lx000", entry >> 12);
1924 1.1 christos if ((entry & 0x100) && !is_dir)
1925 1.1 christos puts_filtered (" Global");
1926 1.1 christos if ((entry & 0x40) && !is_dir)
1927 1.1 christos puts_filtered (" Dirty");
1928 1.1 christos printf_filtered (" %sAcc.", (entry & 0x20) ? "" : "Not-");
1929 1.1 christos printf_filtered (" %sCached", (entry & 0x10) ? "" : "Not-");
1930 1.1 christos printf_filtered (" Write-%s", (entry & 8) ? "Thru" : "Back");
1931 1.1 christos printf_filtered (" %s", (entry & 4) ? "Usr" : "Sup");
1932 1.1 christos printf_filtered (" Read-%s", (entry & 2) ? "Write" : "Only");
1933 1.1 christos if (off)
1934 1.1 christos printf_filtered (" +0x%x", off);
1935 1.1 christos puts_filtered ("\n");
1936 1.1 christos }
1937 1.1 christos else if (force)
1938 1.1 christos printf_filtered ("Page%s not present or not supported; value=0x%lx.\n",
1939 1.1 christos is_dir ? " Table" : "", entry >> 1);
1940 1.1 christos }
1941 1.1 christos
1942 1.1 christos static void
1943 1.1 christos go32_pde (char *arg, int from_tty)
1944 1.1 christos {
1945 1.1 christos long pde_idx = -1, i;
1946 1.1 christos
1947 1.1 christos if (arg && *arg)
1948 1.1 christos {
1949 1.1 christos arg = skip_spaces (arg);
1950 1.1 christos
1951 1.1 christos if (*arg)
1952 1.1 christos {
1953 1.1 christos pde_idx = parse_and_eval_long (arg);
1954 1.1 christos if (pde_idx < 0 || pde_idx >= 1024)
1955 1.1 christos error (_("Entry %ld is outside valid limits [0..1023]."), pde_idx);
1956 1.1 christos }
1957 1.1 christos }
1958 1.1 christos
1959 1.1 christos pdbr = get_cr3 ();
1960 1.1 christos if (!pdbr)
1961 1.1 christos puts_filtered ("Access to Page Directories is "
1962 1.1 christos "not supported on this system.\n");
1963 1.1 christos else if (pde_idx >= 0)
1964 1.1 christos display_ptable_entry (get_pde (pde_idx), 1, 1, 0);
1965 1.1 christos else
1966 1.1 christos for (i = 0; i < 1024; i++)
1967 1.1 christos display_ptable_entry (get_pde (i), 1, 0, 0);
1968 1.1 christos }
1969 1.1 christos
1970 1.1 christos /* A helper function to display entries in a Page Table pointed to by
1971 1.1 christos the N'th entry in the Page Directory. If FORCE is non-zero, say
1972 1.1 christos something even if the Page Table is not accessible. */
1973 1.1 christos static void
1974 1.1 christos display_page_table (long n, int force)
1975 1.1 christos {
1976 1.1 christos unsigned long pde = get_pde (n);
1977 1.1 christos
1978 1.1 christos if ((pde & 1) != 0)
1979 1.1 christos {
1980 1.1 christos int i;
1981 1.1 christos
1982 1.1 christos printf_filtered ("Page Table pointed to by "
1983 1.1 christos "Page Directory entry 0x%lx:\n", n);
1984 1.1 christos for (i = 0; i < 1024; i++)
1985 1.1 christos display_ptable_entry (get_pte (pde, i), 0, 0, 0);
1986 1.1 christos puts_filtered ("\n");
1987 1.1 christos }
1988 1.1 christos else if (force)
1989 1.1 christos printf_filtered ("Page Table not present; value=0x%lx.\n", pde >> 1);
1990 1.1 christos }
1991 1.1 christos
1992 1.1 christos static void
1993 1.1 christos go32_pte (char *arg, int from_tty)
1994 1.1 christos {
1995 1.1 christos long pde_idx = -1L, i;
1996 1.1 christos
1997 1.1 christos if (arg && *arg)
1998 1.1 christos {
1999 1.1 christos arg = skip_spaces (arg);
2000 1.1 christos
2001 1.1 christos if (*arg)
2002 1.1 christos {
2003 1.1 christos pde_idx = parse_and_eval_long (arg);
2004 1.1 christos if (pde_idx < 0 || pde_idx >= 1024)
2005 1.1 christos error (_("Entry %ld is outside valid limits [0..1023]."), pde_idx);
2006 1.1 christos }
2007 1.1 christos }
2008 1.1 christos
2009 1.1 christos pdbr = get_cr3 ();
2010 1.1 christos if (!pdbr)
2011 1.1 christos puts_filtered ("Access to Page Tables is not supported on this system.\n");
2012 1.1 christos else if (pde_idx >= 0)
2013 1.1 christos display_page_table (pde_idx, 1);
2014 1.1 christos else
2015 1.1 christos for (i = 0; i < 1024; i++)
2016 1.1 christos display_page_table (i, 0);
2017 1.1 christos }
2018 1.1 christos
2019 1.1 christos static void
2020 1.1 christos go32_pte_for_address (char *arg, int from_tty)
2021 1.1 christos {
2022 1.1 christos CORE_ADDR addr = 0, i;
2023 1.1 christos
2024 1.1 christos if (arg && *arg)
2025 1.1 christos {
2026 1.1 christos arg = skip_spaces (arg);
2027 1.1 christos
2028 1.1 christos if (*arg)
2029 1.1 christos addr = parse_and_eval_address (arg);
2030 1.1 christos }
2031 1.1 christos if (!addr)
2032 1.1 christos error_no_arg (_("linear address"));
2033 1.1 christos
2034 1.1 christos pdbr = get_cr3 ();
2035 1.1 christos if (!pdbr)
2036 1.1 christos puts_filtered ("Access to Page Tables is not supported on this system.\n");
2037 1.1 christos else
2038 1.1 christos {
2039 1.1 christos int pde_idx = (addr >> 22) & 0x3ff;
2040 1.1 christos int pte_idx = (addr >> 12) & 0x3ff;
2041 1.1 christos unsigned offs = addr & 0xfff;
2042 1.1 christos
2043 1.1 christos printf_filtered ("Page Table entry for address %s:\n",
2044 1.1 christos hex_string(addr));
2045 1.1 christos display_ptable_entry (get_pte (get_pde (pde_idx), pte_idx), 0, 1, offs);
2046 1.1 christos }
2047 1.1 christos }
2048 1.1 christos
2049 1.1 christos static struct cmd_list_element *info_dos_cmdlist = NULL;
2050 1.1 christos
2051 1.1 christos static void
2052 1.1 christos go32_info_dos_command (char *args, int from_tty)
2053 1.1 christos {
2054 1.1 christos help_list (info_dos_cmdlist, "info dos ", class_info, gdb_stdout);
2055 1.1 christos }
2056 1.1 christos
2057 1.1 christos /* -Wmissing-prototypes */
2058 1.1 christos extern initialize_file_ftype _initialize_go32_nat;
2059 1.1 christos
2060 1.1 christos void
2061 1.1 christos _initialize_go32_nat (void)
2062 1.1 christos {
2063 1.1.1.2 christos struct target_ops *t = go32_target ();
2064 1.1.1.2 christos
2065 1.1.1.2 christos x86_dr_low.set_control = go32_set_dr7;
2066 1.1.1.2 christos x86_dr_low.set_addr = go32_set_dr;
2067 1.1.1.2 christos x86_dr_low.get_status = go32_get_dr6;
2068 1.1.1.2 christos x86_dr_low.get_control = go32_get_dr7;
2069 1.1.1.2 christos x86_dr_low.get_addr = go32_get_dr;
2070 1.1.1.2 christos x86_set_debug_register_length (4);
2071 1.1.1.2 christos
2072 1.1.1.2 christos x86_use_watchpoints (t);
2073 1.1.1.2 christos add_target (t);
2074 1.1.1.2 christos
2075 1.1.1.2 christos /* Initialize child's cwd as empty to be initialized when starting
2076 1.1.1.2 christos the child. */
2077 1.1.1.2 christos *child_cwd = 0;
2078 1.1.1.2 christos
2079 1.1.1.2 christos /* Initialize child's command line storage. */
2080 1.1.1.2 christos if (redir_debug_init (&child_cmd) == -1)
2081 1.1.1.2 christos internal_error (__FILE__, __LINE__,
2082 1.1.1.2 christos _("Cannot allocate redirection storage: "
2083 1.1.1.2 christos "not enough memory.\n"));
2084 1.1.1.2 christos
2085 1.1.1.2 christos /* We are always processing GCC-compiled programs. */
2086 1.1.1.2 christos processing_gcc_compilation = 2;
2087 1.1 christos
2088 1.1 christos add_prefix_cmd ("dos", class_info, go32_info_dos_command, _("\
2089 1.1 christos Print information specific to DJGPP (aka MS-DOS) debugging."),
2090 1.1 christos &info_dos_cmdlist, "info dos ", 0, &infolist);
2091 1.1 christos
2092 1.1 christos add_cmd ("sysinfo", class_info, go32_sysinfo, _("\
2093 1.1 christos Display information about the target system, including CPU, OS, DPMI, etc."),
2094 1.1 christos &info_dos_cmdlist);
2095 1.1 christos add_cmd ("ldt", class_info, go32_sldt, _("\
2096 1.1 christos Display entries in the LDT (Local Descriptor Table).\n\
2097 1.1 christos Entry number (an expression) as an argument means display only that entry."),
2098 1.1 christos &info_dos_cmdlist);
2099 1.1 christos add_cmd ("gdt", class_info, go32_sgdt, _("\
2100 1.1 christos Display entries in the GDT (Global Descriptor Table).\n\
2101 1.1 christos Entry number (an expression) as an argument means display only that entry."),
2102 1.1 christos &info_dos_cmdlist);
2103 1.1 christos add_cmd ("idt", class_info, go32_sidt, _("\
2104 1.1 christos Display entries in the IDT (Interrupt Descriptor Table).\n\
2105 1.1 christos Entry number (an expression) as an argument means display only that entry."),
2106 1.1 christos &info_dos_cmdlist);
2107 1.1 christos add_cmd ("pde", class_info, go32_pde, _("\
2108 1.1 christos Display entries in the Page Directory.\n\
2109 1.1 christos Entry number (an expression) as an argument means display only that entry."),
2110 1.1 christos &info_dos_cmdlist);
2111 1.1 christos add_cmd ("pte", class_info, go32_pte, _("\
2112 1.1 christos Display entries in Page Tables.\n\
2113 1.1 christos Entry number (an expression) as an argument means display only entries\n\
2114 1.1 christos from the Page Table pointed to by the specified Page Directory entry."),
2115 1.1 christos &info_dos_cmdlist);
2116 1.1 christos add_cmd ("address-pte", class_info, go32_pte_for_address, _("\
2117 1.1 christos Display a Page Table entry for a linear address.\n\
2118 1.1 christos The address argument must be a linear address, after adding to\n\
2119 1.1 christos it the base address of the appropriate segment.\n\
2120 1.1 christos The base address of variables and functions in the debuggee's data\n\
2121 1.1 christos or code segment is stored in the variable __djgpp_base_address,\n\
2122 1.1 christos so use `__djgpp_base_address + (char *)&var' as the argument.\n\
2123 1.1 christos For other segments, look up their base address in the output of\n\
2124 1.1 christos the `info dos ldt' command."),
2125 1.1 christos &info_dos_cmdlist);
2126 1.1 christos }
2127 1.1 christos
2128 1.1 christos pid_t
2129 1.1 christos tcgetpgrp (int fd)
2130 1.1 christos {
2131 1.1 christos if (isatty (fd))
2132 1.1 christos return SOME_PID;
2133 1.1 christos errno = ENOTTY;
2134 1.1 christos return -1;
2135 1.1 christos }
2136 1.1 christos
2137 1.1 christos int
2138 1.1 christos tcsetpgrp (int fd, pid_t pgid)
2139 1.1 christos {
2140 1.1 christos if (isatty (fd) && pgid == SOME_PID)
2141 1.1 christos return 0;
2142 1.1 christos errno = pgid == SOME_PID ? ENOTTY : ENOSYS;
2143 1.1 christos return -1;
2144 1.1 christos }
2145