Remove extra copy of elf32_m68k_copy_private_bfd_data.
[deliverable/binutils-gdb.git] / gdb / go32-nat.c
CommitLineData
e49d4fa6
SS
1/* Native debugging support for Intel x86 running DJGPP.
2 Copyright 1997, 1999 Free Software Foundation, Inc.
3 Written by Robert Hoehne.
4
5This file is part of GDB.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21#include <fcntl.h>
22
23#include "defs.h"
24#include "frame.h" /* required by inferior.h */
25#include "inferior.h"
26#include "target.h"
27#include "wait.h"
28#include "gdbcore.h"
29#include "command.h"
30#include "floatformat.h"
31
32#include <stdlib.h>
33#include <string.h>
34#include <unistd.h>
35#include <debug/v2load.h>
36#include <debug/dbgcom.h>
37
38extern void _initialize_go32_nat (void);
39
40struct env387
41{
42 unsigned short control;
43 unsigned short r0;
44 unsigned short status;
45 unsigned short r1;
46 unsigned short tag;
47 unsigned short r2;
48 unsigned long eip;
49 unsigned short code_seg;
50 unsigned short opcode;
51 unsigned long operand;
52 unsigned short operand_seg;
53 unsigned short r3;
54 unsigned char regs[8][10];
55};
56
57extern char **environ;
58
59#define SOME_PID 42
60
61/* FIXME add decls of all static functions here */
62
63static int prog_has_started = 0;
64
65static void
66print_387_status (unsigned short status, struct env387 *ep)
67{
68 int i;
69 int bothstatus;
70 int top;
71 int fpreg;
72
73 bothstatus = ((status != 0) && (ep->status != 0));
74 if (status != 0)
75 {
76 if (bothstatus)
77 printf_unfiltered ("u: ");
78 print_387_status_word (status);
79 }
80
81 if (ep->status != 0)
82 {
83 if (bothstatus)
84 printf_unfiltered ("e: ");
85 print_387_status_word (ep->status);
86 }
87
88 print_387_control_word (ep->control & 0xffff);
89 printf_unfiltered ("last exception: ");
90 printf_unfiltered ("opcode %s; ", local_hex_string (ep->opcode));
91 printf_unfiltered ("pc %s:", local_hex_string (ep->code_seg));
92 printf_unfiltered ("%s; ", local_hex_string (ep->eip));
93 printf_unfiltered ("operand %s", local_hex_string (ep->operand_seg));
94 printf_unfiltered (":%s\n", local_hex_string (ep->operand));
95
96 top = (ep->status >> 11) & 7;
97
98 printf_unfiltered ("regno tag msb lsb value\n");
99 for (fpreg = 0; fpreg < 8; fpreg++)
100 {
101 long double val;
102
103 printf_unfiltered ("%s %d: ", fpreg == top ? "=>" : " ", fpreg);
104
105 switch ((ep->tag >> (fpreg * 2)) & 3)
106 {
107 case 0:
108 printf_unfiltered ("valid ");
109 break;
110 case 1:
111 printf_unfiltered ("zero ");
112 break;
113 case 2:
114 printf_unfiltered ("trap ");
115 break;
116 case 3:
117 printf_unfiltered ("empty ");
118 break;
119 }
120 for (i = 0; i < 8; i++)
121 printf_unfiltered ("%02x", ep->regs[fpreg][i]);
122
123 REGISTER_CONVERT_TO_VIRTUAL (FP0_REGNUM + fpreg, builtin_type_long_double,
124 &ep->regs[fpreg], &val);
125
126 printf_unfiltered (" %LG\n", val);
127 }
128}
129
130void
131i386_go32_float_info (void)
132{
133 print_387_status (0, (struct env387 *) &npx);
134}
135
136#define r_ofs(x) ((int)(&(((TSS *)0)->x)))
137
138static struct
139{
140 int tss_ofs;
141 int size;
142}
143regno_mapping[] =
144{
145 r_ofs (tss_eax), 4,
146 r_ofs (tss_ecx), 4,
147 r_ofs (tss_edx), 4,
148 r_ofs (tss_ebx), 4,
149 r_ofs (tss_esp), 4,
150 r_ofs (tss_ebp), 4,
151 r_ofs (tss_esi), 4,
152 r_ofs (tss_edi), 4,
153 r_ofs (tss_eip), 4,
154 r_ofs (tss_eflags), 4,
155 r_ofs (tss_cs), 2,
156 r_ofs (tss_ss), 2,
157 r_ofs (tss_ds), 2,
158 r_ofs (tss_es), 2,
159 r_ofs (tss_fs), 2,
160 r_ofs (tss_gs), 2,
161 0, 10,
162 1, 10,
163 2, 10,
164 3, 10,
165 4, 10,
166 5, 10,
167 6, 10,
168 7, 10,
169 0, 2,
170 4, 2,
171 8, 2,
172 12, 4,
173 16, 2,
174 20, 4,
175 24, 2
176};
177
178static struct
179 {
180 int go32_sig;
181 int gdb_sig;
182 }
183sig_map[] =
184{
185 0, TARGET_SIGNAL_FPE,
186 1, TARGET_SIGNAL_TRAP,
187 2, TARGET_SIGNAL_UNKNOWN,
188 3, TARGET_SIGNAL_TRAP,
189 4, TARGET_SIGNAL_FPE,
190 5, TARGET_SIGNAL_SEGV,
191 6, TARGET_SIGNAL_ILL,
192 7, TARGET_SIGNAL_FPE,
193 8, TARGET_SIGNAL_SEGV,
194 9, TARGET_SIGNAL_SEGV,
195 10, TARGET_SIGNAL_BUS,
196 11, TARGET_SIGNAL_SEGV,
197 12, TARGET_SIGNAL_SEGV,
198 13, TARGET_SIGNAL_ABRT,
199 14, TARGET_SIGNAL_SEGV,
200 16, TARGET_SIGNAL_FPE,
201 31, TARGET_SIGNAL_ILL,
202 0x75, TARGET_SIGNAL_FPE,
203 0x79, TARGET_SIGNAL_INT,
204 0x1b, TARGET_SIGNAL_INT,
205 -1, -1
206};
207
208static void
209go32_open (char *name, int from_tty)
210{
211 printf_unfiltered ("Use the `run' command to run go32 programs\n");
212}
213
214static void
215go32_close (int quitting)
216{
217}
218
219static void
220go32_attach (char *args, int from_tty)
221{
222 printf_unfiltered ("Use the `run' command to run go32 programs\n");
223}
224
225static void
226go32_detach (char *args, int from_tty)
227{
228}
229
230static int resume_is_step;
231
232static void
233go32_resume (int pid, int step, enum target_signal siggnal)
234 {
235 resume_is_step = step;
236 }
237
238static int
239go32_wait (int pid, struct target_waitstatus *status)
240{
241 int i;
242
243 if (resume_is_step)
244 a_tss.tss_eflags |= 0x0100;
245 else
246 a_tss.tss_eflags &= 0xfeff;
247
248 run_child ();
249
250 if (a_tss.tss_irqn == 0x21)
251 {
252 status->kind = TARGET_WAITKIND_EXITED;
253 status->value.integer = a_tss.tss_eax & 0xff;
254 }
255 else
256 {
257 status->value.sig = TARGET_SIGNAL_UNKNOWN;
258 status->kind = TARGET_WAITKIND_STOPPED;
259 for (i = 0; sig_map[i].go32_sig != -1; i++)
260 {
261 if (a_tss.tss_irqn == sig_map[i].go32_sig)
262 {
263 if ((status->value.sig = sig_map[i].gdb_sig) !=
264 TARGET_SIGNAL_TRAP)
265 status->kind = TARGET_WAITKIND_SIGNALLED;
266 break;
267 }
268 }
269 }
270 return SOME_PID;
271}
272
273static void
274go32_fetch_registers (int regno)
275{
276 /*JHW*/
277 int end_reg = regno + 1; /* just one reg initially */
278
279 if (regno < 0) /* do the all registers */
280 {
281 regno = 0; /* start at first register */
282 /* # regs in table */
283 end_reg = sizeof (regno_mapping) / sizeof (regno_mapping[0]);
284 }
285
286 for (; regno < end_reg; regno++)
287 {
288 if (regno < 16)
289 supply_register (regno,
290 (char *) &a_tss + regno_mapping[regno].tss_ofs);
291 else if (regno < 24)
292 supply_register (regno,
293 (char *) &npx.reg[regno_mapping[regno].tss_ofs]);
294 else if (regno < 31)
295 supply_register (regno,
296 (char *) &npx.reg + regno_mapping[regno].tss_ofs);
297 else
298 {
299 printf_unfiltered ("Invalid register in go32_fetch_register(%d)",
300 regno);
301 exit (1);
302 }
303 }
304}
305
306static void
307store_register (int regno)
308{
309 void *rp;
310 void *v = (void *) &registers[REGISTER_BYTE (regno)];
311
312 if (regno < 16)
313 rp = (char *) &a_tss + regno_mapping[regno].tss_ofs;
314 else if (regno < 24)
315 rp = (char *) &npx.reg[regno_mapping[regno].tss_ofs];
316 else if (regno > 31)
317 rp = (char *) &npx + regno_mapping[regno].tss_ofs;
318 else
319 {
320 printf_unfiltered ("Invalid register in store_register(%d)", regno);
321 exit (1);
322 }
323 memcpy (rp, v, regno_mapping[regno].size);
324}
325
326static void
327go32_store_registers (int regno)
328{
329 int r;
330
331 if (regno >= 0)
332 store_register (regno);
333 else
334 {
335 for (r = 0; r < sizeof (regno_mapping) / sizeof (regno_mapping[0]); r++)
336 store_register (r);
337 }
338}
339
340static void
341go32_prepare_to_store (void)
342{
343}
344
345static int
346go32_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
347 struct target_ops *target)
348{
349 if (write)
350 {
351 if (write_child (memaddr, myaddr, len))
352 {
353 return 0;
354 }
355 else
356 {
357 return len;
358 }
359 }
360 else
361 {
362 if (read_child (memaddr, myaddr, len))
363 {
364 return 0;
365 }
366 else
367 {
368 return len;
369 }
370 }
371}
372
373static void
374go32_files_info (struct target_ops *target)
375{
376 printf_unfiltered ("You are running a DJGPP V2 program\n");
377}
378
379static void
380go32_stop (void)
381{
382 normal_stop ();
383 cleanup_client ();
384 inferior_pid = 0;
385 prog_has_started = 0;
386}
387
388static void
389go32_kill_inferior (void)
390{
391 go32_stop ();
392 unpush_target (&go32_ops);
393}
394
395static void
396go32_create_inferior (char *exec_file, char *args, char **env)
397{
398 jmp_buf start_state;
399 char *cmdline;
400 char **env_save = environ;
401
402 if (prog_has_started)
403 {
404 go32_kill_inferior ();
405 }
406
407 cmdline = (char *) alloca (strlen (args) + 4);
408 cmdline[0] = strlen (args);
409 strcpy (cmdline + 1, args);
410 cmdline[strlen (args) + 1] = 13;
411
412 environ = env;
413
414 if (v2loadimage (exec_file, cmdline, start_state))
415 {
416 environ = env_save;
417 printf_unfiltered ("Load failed for image %s\n", exec_file);
418 exit (1);
419 }
420 environ = env_save;
421
422 edi_init (start_state);
423
424 inferior_pid = SOME_PID;
425 push_target (&go32_ops);
426 clear_proceed_status ();
427 insert_breakpoints ();
428 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
429}
430
431static void
432go32_mourn_inferior (void)
433{
434 go32_kill_inferior ();
435 generic_mourn_inferior ();
436}
437
438static int
439go32_can_run (void)
440{
441 return 1;
442}
443
444static void
445ignore (void)
446{
447}
448
449static void
450ignore2 (char *a, int b)
451{
452}
453
454/* Hardware watchpoint support. */
455
456#define DR_STATUS 6
457#define DR_CONTROL 7
458#define DR_ENABLE_SIZE 2
459#define DR_LOCAL_ENABLE_SHIFT 0
460#define DR_GLOBAL_ENABLE_SHIFT 1
461#define DR_LOCAL_SLOWDOWN 0x100
462#define DR_GLOBAL_SLOWDOWN 0x200
463#define DR_CONTROL_SHIFT 16
464#define DR_CONTROL_SIZE 4
465#define DR_RW_READ 0x3
466#define DR_RW_WRITE 0x1
467#define DR_CONTROL_MASK 0xf
468#define DR_ENABLE_MASK 0x3
469#define DR_LEN_1 0x0
470#define DR_LEN_2 0x4
471#define DR_LEN_4 0xc
472
473#define D_REGS edi.dr
474#define CONTROL D_REGS[DR_CONTROL]
475#define STATUS D_REGS[DR_STATUS]
476
477#define IS_REG_FREE(index) \
478 (!(CONTROL & (3 << (DR_ENABLE_SIZE * index))))
479
480#define LOCAL_ENABLE_REG(index) \
481 (CONTROL |= (1 << (DR_LOCAL_ENABLE_SHIFT + DR_ENABLE_SIZE * index)))
482
483#define GLOBAL_ENABLE_REG(index) \
484 (CONTROL |= (1 << (DR_GLOBAL_ENABLE_SHIFT + DR_ENABLE_SIZE * index)))
485
486#define DISABLE_REG(index) \
487 (CONTROL &= ~(3 << (DR_ENABLE_SIZE * index)))
488
489#define SET_LOCAL_EXACT() \
490 (CONTROL |= DR_LOCAL_SLOWDOWN)
491
492#define SET_GLOBAL_EXACT() \
493 (CONTROL |= DR_GLOBAL_SLOWDOWN)
494
495#define SET_BREAK(index,address) \
496 do {\
497 CONTROL &= ~(DR_CONTROL_MASK << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * index));\
498 D_REGS[index] = address;\
499 } while(0)
500
501#define SET_WATCH(index,address,rw,len) \
502 do {\
503 SET_BREAK(index,address);\
504 CONTROL |= (len | rw) << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * index);\
505 } while (0)
506
507#define WATCH_HIT(index) \
508 (\
509 (STATUS & (1 << index)) && \
510 (CONTROL & (DR_CONTROL_MASK << (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * index)))\
511 )
512
513#if 0 /* use debugging macro */
514#define SHOW_DR(text) \
515do { \
516 fprintf(stderr,"%08x %08x ",edi.dr[7],edi.dr[6]); \
517 fprintf(stderr,"%08x %08x ",edi.dr[0],edi.dr[1]); \
518 fprintf(stderr,"%08x %08x ",edi.dr[2],edi.dr[3]); \
519 fprintf(stderr,"(%s)\n",#text); \
520} while (0)
521#else
522#define SHOW_DR(text) do {} while (0)
523#endif
524
525static int go32_insert_aligned_watchpoint (int pid, CORE_ADDR waddr,
526 CORE_ADDR addr, int len, int rw);
527
528static int go32_insert_nonaligned_watchpoint (int pid, CORE_ADDR waddr,
529 CORE_ADDR addr, int len, int rw);
530
531/* Insert a watchpoint. */
532
533int
534go32_insert_watchpoint (int pid, CORE_ADDR addr, int len, int rw)
535{
536 int ret = go32_insert_aligned_watchpoint (pid, addr, addr, len, rw);
537
538 SHOW_DR (insert_watch);
539 return ret;
540}
541
542static int
543go32_insert_aligned_watchpoint (int pid, CORE_ADDR waddr, CORE_ADDR addr,
544 int len, int rw)
545{
546 int i;
547 int read_write_bits, len_bits;
548
549 /* Look for a free debug register. */
550 for (i = 0; i <= 3; i++)
551 {
552 if (IS_REG_FREE (i))
553 break;
554 }
555
556 /* No more debug registers! */
557 if (i > 3)
558 return -1;
559
560 read_write_bits = ((rw & 1) ? DR_RW_READ : 0) | ((rw & 2) ? DR_RW_WRITE : 0);
561
562 if (len == 1)
563 len_bits = DR_LEN_1;
564 else if (len == 2)
565 {
566 if (addr % 2)
567 return go32_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw);
568 len_bits = DR_LEN_2;
569 }
570 else if (len == 4)
571 {
572 if (addr % 4)
573 return go32_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw);
574 len_bits = DR_LEN_4;
575 }
576 else
577 return go32_insert_nonaligned_watchpoint (pid, waddr, addr, len, rw);
578
579 SET_WATCH (i, addr, read_write_bits, len_bits);
580 LOCAL_ENABLE_REG (i);
581 SET_LOCAL_EXACT ();
582}
583
584static int
585go32_insert_nonaligned_watchpoint (int pid, CORE_ADDR waddr, CORE_ADDR addr,
586 int len, int rw)
587{
588 int align;
589 int size;
590 int rv = 0;
591
592 static int size_try_array[16] =
593 {
594 1, 1, 1, 1, /* trying size one */
595 2, 1, 2, 1, /* trying size two */
596 2, 1, 2, 1, /* trying size three */
597 4, 1, 2, 1 /* trying size four */
598 };
599
600 while (len > 0)
601 {
602 align = addr % 4;
603 /* Four is the maximum length for 386. */
604 size = (len > 4) ? 3 : len - 1;
605 size = size_try_array[size * 4 + align];
606 rv = go32_insert_aligned_watchpoint (pid, waddr, addr, size, rw);
607 if (rv)
608 {
609 go32_remove_watchpoint (pid, waddr, size);
610 return rv;
611 }
612 addr += size;
613 len -= size;
614 }
615 return rv;
616}
617
618/* Remove a watchpoint. */
619
620int
621go32_remove_watchpoint (int pid, CORE_ADDR addr, int len)
622{
623 int i;
624
625 for (i = 0; i <= 3; i++)
626 {
627 if (D_REGS[i] == addr)
628 {
629 DISABLE_REG (i);
630 }
631 }
632 SHOW_DR (remove_watch);
633
634 return 0;
635}
636
637/* Check if stopped by a watchpoint. */
638
639CORE_ADDR
640go32_stopped_by_watchpoint (int pid)
641{
642 int i, ret = 0;
643 int status;
644
645 status = edi.dr[DR_STATUS];
646 SHOW_DR (stopped_by);
647 for (i = 0; i <= 3; i++)
648 {
649 if (WATCH_HIT (i))
650 {
651 SHOW_DR (HIT);
652 ret = D_REGS[i];
653 }
654 }
655 /* this is a hack to GDB. If we stopped at a hardware breakpoint,
656 the stop_pc must incremented by DECR_PC_AFTER_BREAK. I tried everything
657 with the DECR_PC_AFTER_HW_BREAK, but nothing works. */
658 /* This is probably fixed by jtc's recent patch -sts 2/19/99 */
659 if (STATUS && !ret)
660 stop_pc += DECR_PC_AFTER_BREAK;
661 STATUS = 0;
662
663 return ret;
664}
665
666/* Remove a breakpoint. */
667
668int
669go32_remove_hw_breakpoint (CORE_ADDR addr, CORE_ADDR shadow)
670{
671 int i;
672 for (i = 0; i <= 3; i++)
673 {
674 if (D_REGS[i] == addr)
675 {
676 DISABLE_REG (i);
677 }
678 }
679 SHOW_DR (remove_hw);
680 return 0;
681}
682
683int
684go32_insert_hw_breakpoint (CORE_ADDR addr, CORE_ADDR shadow)
685{
686 int i;
687 int read_write_bits, len_bits;
688 int free_debug_register;
689 int register_number;
690
691 /* Look for a free debug register. */
692 for (i = 0; i <= 3; i++)
693 {
694 if (IS_REG_FREE (i))
695 break;
696 }
697
698 /* No more debug registers! */
699 if (i > 3)
700 return -1;
701
702 SET_BREAK (i, addr);
703 LOCAL_ENABLE_REG (i);
704 SHOW_DR (insert_hw);
705
706 return 0;
707}
708
709static struct target_ops go32_ops;
710
711static void
712init_go32_ops (void)
713{
714 go32_ops.to_shortname = "djgpp";
715 go32_ops.to_longname = "djgpp target process";
716 go32_ops.to_doc =
717 "Program loaded by djgpp, when gdb is used as an external debugger";
718 go32_ops.to_open = go32_open;
719 go32_ops.to_close = go32_close;
720 go32_ops.to_detach = go32_detach;
721 go32_ops.to_resume = go32_resume;
722 go32_ops.to_wait = go32_wait;
723 go32_ops.to_fetch_registers = go32_fetch_registers;
724 go32_ops.to_store_registers = go32_store_registers;
725 go32_ops.to_prepare_to_store = go32_prepare_to_store;
726 go32_ops.to_xfer_memory = go32_xfer_memory;
727 go32_ops.to_files_info = go32_files_info;
728 go32_ops.to_insert_breakpoint = memory_insert_breakpoint;
729 go32_ops.to_remove_breakpoint = memory_remove_breakpoint;
730 go32_ops.to_terminal_init = ignore;
731 go32_ops.to_terminal_inferior = ignore;
732 go32_ops.to_terminal_ours_for_output = ignore;
733 go32_ops.to_terminal_ours = ignore;
734 go32_ops.to_terminal_info = ignore2;
735 go32_ops.to_kill = go32_kill_inferior;
736 go32_ops.to_create_inferior = go32_create_inferior;
737 go32_ops.to_mourn_inferior = go32_mourn_inferior;
738 go32_ops.to_can_run = go32_can_run;
739 go32_ops.to_stop = go32_stop;
740 go32_ops.to_stratum = process_stratum;
741 go32_ops.to_has_all_memory = 1;
742 go32_ops.to_has_memory = 1;
743 go32_ops.to_has_stack = 1;
744 go32_ops.to_has_registers = 1;
745 go32_ops.to_has_execution = 1;
746 go32_ops.to_magic = OPS_MAGIC;
747}
748
749void
750_initialize_go32_nat (void)
751{
752 init_go32_ops ();
753 add_target (&go32_ops);
754}
This page took 0.048594 seconds and 4 git commands to generate.