gdb-3.5
[deliverable/binutils-gdb.git] / gdb / symmetry-dep.c
CommitLineData
4187119d 1/* Low level interface to ptrace, for GDB when running under Unix.
2 Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
3
4This file is part of GDB.
5
6GDB is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GDB is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GDB; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20/* many 387-specific items of use taken from i386-dep.c */
21
7a67dd45 22#include <stdio.h>
4187119d 23#include "defs.h"
24#include "param.h"
25#include "frame.h"
26#include "inferior.h"
27#include "symtab.h"
28
4187119d 29#include <signal.h>
30#include <sys/param.h>
31#include <sys/user.h>
32#include <sys/dir.h>
33#include <sys/ioctl.h>
34#include <sys/stat.h>
35#include <a.out.h>
36#include <fcntl.h>
37
38static long i386_get_frame_setup ();
39static i386_follow_jump ();
40
41/* XPT_DEBUG doesn't work yet under Dynix 3.0.12, but UNDEBUG does... */
42#define PTRACE_ATTACH XPT_DEBUG
43#define PTRACE_DETACH XPT_UNDEBUG
44
45#include <sgtty.h>
46#define TERMINAL struct sgttyb
47
48extern int errno;
49
50/* Nonzero if we are debugging an attached outside process
51 rather than an inferior. */
52
53static int attach_flag;
54
55/* This function simply calls ptrace with the given arguments.
56 It exists so that all calls to ptrace are isolated in this
57 machine-dependent file. */
58int
59call_ptrace (request, pid, arg3, arg4)
60 int request, pid, arg3, arg4;
61{
62 return ptrace (request, pid, arg3, arg4);
63}
64
65
66
67kill_inferior ()
68{
69 if (remote_debugging)
70 return;
71 if (inferior_pid == 0)
72 return;
73 ptrace (8, inferior_pid, 0, 0);
74 wait (0);
75 inferior_died ();
76}
77
78/* This is used when GDB is exiting. It gives less chance of error.*/
79
80kill_inferior_fast ()
81{
82 if (remote_debugging)
83 return;
84 if (inferior_pid == 0)
85 return;
86 ptrace (8, inferior_pid, 0, 0);
87 wait (0);
88}
89
90/* Resume execution of the inferior process.
91 If STEP is nonzero, single-step it.
92 If SIGNAL is nonzero, give it that signal. */
93
94void
95resume (step, signal)
96 int step;
97 int signal;
98{
99 errno = 0;
100 if (remote_debugging)
101 remote_resume (step, signal);
102 else
103 {
104 ptrace (step ? 9 : 7, inferior_pid, 1, signal);
105 if (errno)
106 perror_with_name ("ptrace");
107 }
108}
109\f
110#ifdef ATTACH_DETACH
111
112/* Start debugging the process whose number is PID. */
113
114attach (pid)
115 int pid;
116{
117 errno = 0;
118 ptrace (PTRACE_ATTACH, pid, 0, 0);
119 if (errno)
120 perror_with_name ("ptrace");
121 attach_flag = 1;
122 return pid;
123}
124
125/* Stop debugging the process whose number is PID
126 and continue it with signal number SIGNAL.
127 SIGNAL = 0 means just continue it. */
128
129void
130detach (signal)
131 int signal;
132{
133 errno = 0;
134 ptrace (PTRACE_DETACH, inferior_pid, 1, signal);
135 if (errno)
136 perror_with_name ("ptrace");
137 attach_flag = 0;
138}
139#endif /* ATTACH_DETACH */
140\f
141
142store_inferior_registers(regno)
143int regno;
144{
145 struct pt_regset regs;
146 int reg_tmp, i;
147 extern char registers[];
148
149 if (-1 == regno)
150 {
151 regs.pr_eax = *(int *)&registers[REGISTER_BYTE(0)];
152 regs.pr_ebx = *(int *)&registers[REGISTER_BYTE(5)];
153 regs.pr_ecx = *(int *)&registers[REGISTER_BYTE(2)];
154 regs.pr_edx = *(int *)&registers[REGISTER_BYTE(1)];
155 regs.pr_esi = *(int *)&registers[REGISTER_BYTE(6)];
156 regs.pr_edi = *(int *)&registers[REGISTER_BYTE(7)];
157 regs.pr_esp = *(int *)&registers[REGISTER_BYTE(14)];
158 regs.pr_ebp = *(int *)&registers[REGISTER_BYTE(15)];
159 regs.pr_eip = *(int *)&registers[REGISTER_BYTE(16)];
160 regs.pr_flags = *(int *)&registers[REGISTER_BYTE(17)];
161 for (i = 0; i < 31; i++) {
162 regs.pr_fpa.fpa_regs[i] =
163 *(int *)&registers[REGISTER_BYTE(FP1_REGNUM+i)];
164 }
165 }
166 else
167 {
168 reg_tmp = *(int *)&registers[REGISTER_BYTE(regno)];
169 ptrace(XPT_RREGS, inferior_pid, &regs, 0);
170 switch (regno)
171 {
172 case 0:
173 regs.pr_eax = *(int *)&registers[REGISTER_BYTE(0)];
174 break;
175 case 5:
176 regs.pr_ebx = *(int *)&registers[REGISTER_BYTE(5)];
177 break;
178 case 2:
179 regs.pr_ecx = *(int *)&registers[REGISTER_BYTE(2)];
180 break;
181 case 1:
182 regs.pr_edx = *(int *)&registers[REGISTER_BYTE(1)];
183 break;
184 case 6:
185 regs.pr_esi = *(int *)&registers[REGISTER_BYTE(6)];
186 break;
187 case 7:
188 regs.pr_edi = *(int *)&registers[REGISTER_BYTE(7)];
189 break;
190 case 15:
191 regs.pr_ebp = *(int *)&registers[REGISTER_BYTE(15)];
192 break;
193 case 14:
194 regs.pr_esp = *(int *)&registers[REGISTER_BYTE(14)];
195 break;
196 case 16:
197 regs.pr_eip = *(int *)&registers[REGISTER_BYTE(16)];
198 break;
199 case 17:
200 regs.pr_flags = *(int *)&registers[REGISTER_BYTE(17)];
201 break;
202 }
203 }
204 ptrace(XPT_WREGS, inferior_pid, &regs, 0);
205}
206
207void
208fetch_inferior_registers()
209{
210 int i;
211 struct pt_regset regs;
212 extern char registers[];
213
214 ptrace(XPT_RREGS, inferior_pid, &regs, 0);
215 *(int *)&registers[REGISTER_BYTE(0)] = regs.pr_eax;
216 *(int *)&registers[REGISTER_BYTE(5)] = regs.pr_ebx;
217 *(int *)&registers[REGISTER_BYTE(2)] = regs.pr_ecx;
218 *(int *)&registers[REGISTER_BYTE(1)] = regs.pr_edx;
219 *(int *)&registers[REGISTER_BYTE(6)] = regs.pr_esi;
220 *(int *)&registers[REGISTER_BYTE(7)] = regs.pr_edi;
221 *(int *)&registers[REGISTER_BYTE(15)] = regs.pr_ebp;
222 *(int *)&registers[REGISTER_BYTE(14)] = regs.pr_esp;
223 *(int *)&registers[REGISTER_BYTE(16)] = regs.pr_eip;
224 *(int *)&registers[REGISTER_BYTE(17)] = regs.pr_flags;
225 for (i = 0; i < FPA_NREGS; i++) {
226 *(int *)&registers[REGISTER_BYTE(FP1_REGNUM+i)] = regs.pr_fpa.fpa_regs[i];
227 }
228 bcopy(regs.pr_fpu.fpu_stack[0], &registers[REGISTER_BYTE(3)], 10);
229 bcopy(regs.pr_fpu.fpu_stack[1], &registers[REGISTER_BYTE(4)], 10);
230 bcopy(regs.pr_fpu.fpu_stack[2], &registers[REGISTER_BYTE(8)], 10);
231 bcopy(regs.pr_fpu.fpu_stack[3], &registers[REGISTER_BYTE(9)], 10);
232 bcopy(regs.pr_fpu.fpu_stack[4], &registers[REGISTER_BYTE(10)], 10);
233 bcopy(regs.pr_fpu.fpu_stack[5], &registers[REGISTER_BYTE(11)], 10);
234 bcopy(regs.pr_fpu.fpu_stack[6], &registers[REGISTER_BYTE(12)], 10);
235 bcopy(regs.pr_fpu.fpu_stack[7], &registers[REGISTER_BYTE(13)], 10);
236}
237
238
239/* Copy LEN bytes from inferior's memory starting at MEMADDR
240 to debugger memory starting at MYADDR. */
241
242read_inferior_memory (memaddr, myaddr, len)
243 CORE_ADDR memaddr;
244 char *myaddr;
245 int len;
246{
247 register int i;
248 /* Round starting address down to longword boundary. */
249 register CORE_ADDR addr = memaddr & - sizeof (int);
250 /* Round ending address up; get number of longwords that makes. */
251 register int count
252 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
253 /* Allocate buffer of that many longwords. */
254 register int *buffer = (int *) alloca (count * sizeof (int));
255
256 /* Read all the longwords */
257 for (i = 0; i < count; i++, addr += sizeof (int)) {
258 errno = 0;
259 if (remote_debugging)
260 buffer[i] = remote_fetch_word (addr);
261 else
262 buffer[i] = ptrace (1, inferior_pid, addr, 0);
263 if (errno)
264 return errno;
265 }
266
267 /* Copy appropriate bytes out of the buffer. */
268 bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
269 return 0;
270}
271
272/* Copy LEN bytes of data from debugger memory at MYADDR
273 to inferior's memory at MEMADDR.
274 On failure (cannot write the inferior)
275 returns the value of errno. */
276
277int
278write_inferior_memory (memaddr, myaddr, len)
279 CORE_ADDR memaddr;
280 char *myaddr;
281 int len;
282{
283 register int i;
284 /* Round starting address down to longword boundary. */
285 register CORE_ADDR addr = memaddr & - sizeof (int);
286 /* Round ending address up; get number of longwords that makes. */
287 register int count
288 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
289 /* Allocate buffer of that many longwords. */
290 register int *buffer = (int *) alloca (count * sizeof (int));
291 extern int errno;
292
293 /* Fill start and end extra bytes of buffer with existing memory data. */
294
295 if (remote_debugging)
296 buffer[0] = remote_fetch_word (addr);
297 else
298 buffer[0] = ptrace (1, inferior_pid, addr, 0);
299
300 if (count > 1)
301 {
302 if (remote_debugging)
303 buffer[count - 1]
304 = remote_fetch_word (addr + (count - 1) * sizeof (int));
305 else
306 buffer[count - 1]
307 = ptrace (1, inferior_pid,
308 addr + (count - 1) * sizeof (int), 0);
309 }
310
311 /* Copy data to be written over corresponding part of buffer */
312
313 bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
314
315 /* Write the entire buffer. */
316
317 for (i = 0; i < count; i++, addr += sizeof (int))
318 {
319 errno = 0;
320 if (remote_debugging)
321 remote_store_word (addr, buffer[i]);
322 else
323 ptrace (4, inferior_pid, addr, buffer[i]);
324 if (errno)
325 return errno;
326 }
327
328 return 0;
329}
330
331
332/* Recognize COFF format systems because a.out.h defines AOUTHDR. */
333#ifdef AOUTHDR
334#define COFF_FORMAT
335#endif
336
337
338#ifndef N_TXTADDR
339#define N_TXTADDR(hdr) 0
340#endif /* no N_TXTADDR */
341
342#ifndef N_DATADDR
343#define N_DATADDR(hdr) hdr.a_text
344#endif /* no N_DATADDR */
345
346/* Make COFF and non-COFF names for things a little more compatible
347 to reduce conditionals later. */
348
349#ifdef COFF_FORMAT
350#define a_magic magic
351#endif
352
353#ifndef COFF_FORMAT
354#define AOUTHDR struct exec
355#endif
356
357extern char *sys_siglist[];
358
359/* Hook for `exec_file_command' command to call. */
360
361void (*exec_file_display_hook) ();
362
363/* File names of core file and executable file. */
364
365extern char *corefile;
366extern char *execfile;
367
368/* Descriptors on which core file and executable file are open.
369 Note that the execchan is closed when an inferior is created
370 and reopened if the inferior dies or is killed. */
371
372extern int corechan;
373extern int execchan;
374
375/* Last modification time of executable file.
376 Also used in source.c to compare against mtime of a source file. */
377
378int exec_mtime;
379
380/* Virtual addresses of bounds of the two areas of memory in the core file. */
381
382extern CORE_ADDR data_start;
383extern CORE_ADDR data_end;
384extern CORE_ADDR stack_start;
385extern CORE_ADDR stack_end;
386
387/* Virtual addresses of bounds of two areas of memory in the exec file.
388 Note that the data area in the exec file is used only when there is no core file. */
389
390extern CORE_ADDR text_start;
391extern CORE_ADDR text_end;
392
393extern CORE_ADDR exec_data_start;
394extern CORE_ADDR exec_data_end;
395
396/* Address in executable file of start of text area data. */
397
398extern int text_offset;
399
400/* Address in executable file of start of data area data. */
401
402extern int exec_data_offset;
403
404/* Address in core file of start of data area data. */
405
406extern int data_offset;
407
408/* Address in core file of start of stack area data. */
409
410extern int stack_offset;
411
412#ifdef COFF_FORMAT
413/* various coff data structures */
414
415extern FILHDR file_hdr;
416extern SCNHDR text_hdr;
417extern SCNHDR data_hdr;
418
419#endif /* not COFF_FORMAT */
420
421/* a.out header saved in core file. */
422
423extern AOUTHDR core_aouthdr;
424
425/* a.out header of exec file. */
426
427extern AOUTHDR exec_aouthdr;
428
429extern void validate_files ();
430unsigned int register_addr ();
431
432core_file_command (filename, from_tty)
433 char *filename;
434 int from_tty;
435{
436 int val;
437 extern char registers[];
438
439 /* Discard all vestiges of any previous core file
440 and mark data and stack spaces as empty. */
441
442 if (corefile)
443 free (corefile);
444 corefile = 0;
445
446 if (corechan >= 0)
447 close (corechan);
448 corechan = -1;
449
450 data_start = 0;
451 data_end = 0;
452 stack_start = STACK_END_ADDR;
453 stack_end = STACK_END_ADDR;
454
455 /* Now, if a new core file was specified, open it and digest it. */
456
457 if (filename)
458 {
459 filename = tilde_expand (filename);
460 make_cleanup (free, filename);
461
462 if (have_inferior_p ())
463 error ("To look at a core file, you must kill the inferior with \"kill\".");
464 corechan = open (filename, O_RDONLY, 0);
465 if (corechan < 0)
466 perror_with_name (filename);
467 /* 4.2-style (and perhaps also sysV-style) core dump file. */
468 {
469 struct user u;
470 int reg_offset;
471
472 val = myread (corechan, &u, sizeof u);
473 if (val < 0)
474 perror_with_name (filename);
475 data_start = exec_data_start;
476
477 data_end = data_start + NBPG * (u.u_dsize - u.u_tsize);
478 stack_start = stack_end - NBPG * u.u_ssize;
479 data_offset = NBPG * UPAGES;
480 stack_offset = ctob(UPAGES + u.u_dsize - u.u_tsize);
481 reg_offset = (int) u.u_ar0 - KERNEL_U_ADDR;
482printf("u.u_tsize= %#x, u.u_dsize= %#x, u.u_ssize= %#x, stack_off= %#x\n",
483 u.u_tsize, u.u_dsize, u.u_ssize, stack_offset);
484
485 core_aouthdr.a_magic = 0;
486
487 /* Read the register values out of the core file and store
488 them where `read_register' will find them. */
489
490 {
491 register int regno;
492
493 for (regno = 0; regno < NUM_REGS; regno++)
494 {
495 char buf[MAX_REGISTER_RAW_SIZE];
496
497 val = lseek (corechan, register_addr (regno, reg_offset), 0);
498 if (val < 0)
499 perror_with_name (filename);
500
501 val = myread (corechan, buf, sizeof buf);
502 if (val < 0)
503 perror_with_name (filename);
504 supply_register (regno, buf);
505 }
506 }
507 }
508 if (filename[0] == '/')
509 corefile = savestring (filename, strlen (filename));
510 else
511 {
512 corefile = concat (current_directory, "/", filename);
513 }
514
515 set_current_frame(create_new_frame(read_register(FP_REGNUM),
516 read_pc()));
517/* set_current_frame (read_register (FP_REGNUM));*/
518 select_frame (get_current_frame (), 0);
519 validate_files ();
520 }
521 else if (from_tty)
522 printf ("No core file now.\n");
523}
524
525exec_file_command (filename, from_tty)
526 char *filename;
527 int from_tty;
528{
529 int val;
530
531 /* Eliminate all traces of old exec file.
532 Mark text segment as empty. */
533
534 if (execfile)
535 free (execfile);
536 execfile = 0;
537 data_start = 0;
538 data_end -= exec_data_start;
539 text_start = 0;
540 text_end = 0;
541 exec_data_start = 0;
542 exec_data_end = 0;
543 if (execchan >= 0)
544 close (execchan);
545 execchan = -1;
546
547 /* Now open and digest the file the user requested, if any. */
548
549 if (filename)
550 {
551 filename = tilde_expand (filename);
552 make_cleanup (free, filename);
553
554 execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
555 &execfile);
556 if (execchan < 0)
557 perror_with_name (filename);
558
559#ifdef COFF_FORMAT
560 {
561 int aout_hdrsize;
562 int num_sections;
563
564 if (read_file_hdr (execchan, &file_hdr) < 0)
565 error ("\"%s\": not in executable format.", execfile);
566
567 aout_hdrsize = file_hdr.f_opthdr;
568 num_sections = file_hdr.f_nscns;
569
570 if (read_aout_hdr (execchan, &exec_aouthdr, aout_hdrsize) < 0)
571 error ("\"%s\": can't read optional aouthdr", execfile);
572
7a67dd45 573 if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections,
574 aout_hdrsize) < 0)
4187119d 575 error ("\"%s\": can't read text section header", execfile);
576
7a67dd45 577 if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections,
578 aout_hdrsize) < 0)
4187119d 579 error ("\"%s\": can't read data section header", execfile);
580
581 text_start = exec_aouthdr.text_start;
582 text_end = text_start + exec_aouthdr.tsize;
583 text_offset = text_hdr.s_scnptr;
584 exec_data_start = exec_aouthdr.data_start;
585 exec_data_end = exec_data_start + exec_aouthdr.dsize;
586 exec_data_offset = data_hdr.s_scnptr;
587 data_start = exec_data_start;
588 data_end += exec_data_start;
589 exec_mtime = file_hdr.f_timdat;
590 }
591#else /* not COFF_FORMAT */
592 {
593 struct stat st_exec;
594
595 val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR));
596
597 if (val < 0)
598 perror_with_name (filename);
599
600 text_start = N_ADDRADJ(exec_aouthdr);
601 exec_data_start = round(exec_aouthdr.a_text, NBPG*CLSIZE);
602 text_offset = N_TXTOFF (exec_aouthdr);
603 exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
604 text_end = exec_aouthdr.a_text;
605 exec_data_end = exec_data_start + exec_aouthdr.a_data;
606 data_start = exec_data_start;
607 data_end = data_start + exec_aouthdr.a_data;
608 exec_data_offset = N_TXTOFF(exec_aouthdr);
609 fstat (execchan, &st_exec);
610 exec_mtime = st_exec.st_mtime;
611 }
612#endif /* not COFF_FORMAT */
613
614 validate_files ();
615 }
616 else if (from_tty)
617 printf ("No exec file now.\n");
618
619 /* Tell display code (if any) about the changed file name. */
620 if (exec_file_display_hook)
621 (*exec_file_display_hook) (filename);
622}
623
624/* rounds 'one' up to divide evenly by 'two' */
625
626int
627round(one,two)
628register int one, two;
629
630{
631 register int temp;
632 temp = (one/two)*two;
633 if (one != temp) {
634 temp += two;
635 }
636 return temp;
637}
638
639
640static CORE_ADDR codestream_next_addr;
641static CORE_ADDR codestream_addr;
642static unsigned char codestream_buf[sizeof (int)];
643static int codestream_off;
644static int codestream_cnt;
645
646#define codestream_tell() (codestream_addr + codestream_off)
647#define codestream_peek() (codestream_cnt == 0 ? \
648 codestream_fill(1): codestream_buf[codestream_off])
649#define codestream_get() (codestream_cnt-- == 0 ? \
650 codestream_fill(0) : codestream_buf[codestream_off++])
651
652
653static unsigned char
654codestream_fill (peek_flag)
655{
656 codestream_addr = codestream_next_addr;
657 codestream_next_addr += sizeof (int);
658 codestream_off = 0;
659 codestream_cnt = sizeof (int);
660 read_memory (codestream_addr,
661 (unsigned char *)codestream_buf,
662 sizeof (int));
663
664 if (peek_flag)
665 return (codestream_peek());
666 else
667 return (codestream_get());
668}
669
670static void
671codestream_seek (place)
672{
673 codestream_next_addr = place & -sizeof (int);
674 codestream_cnt = 0;
675 codestream_fill (1);
676 while (codestream_tell() != place)
677 codestream_get ();
678}
679
680static void
681codestream_read (buf, count)
682 unsigned char *buf;
683{
684 unsigned char *p;
685 int i;
686 p = buf;
687 for (i = 0; i < count; i++)
688 *p++ = codestream_get ();
689}
690
691/*
692 * Following macro translates i386 opcode register numbers to Symmetry
693 * register numbers. This is used by FRAME_FIND_SAVED_REGS.
694 *
695 * %eax %ecx %edx %ebx %esp %ebp %esi %edi
696 * i386 0 1 2 3 4 5 6 7
697 * Symmetry 0 2 1 5 14 15 6 7
698 *
699 */
700#define I386_REGNO_TO_SYMMETRY(n) \
701((n)==0?0 :(n)==1?2 :(n)==2?1 :(n)==3?5 :(n)==4?14 :(n)==5?15 :(n))
702
703/* from i386-dep.c */
704i386_frame_find_saved_regs (fip, fsrp)
705 struct frame_info *fip;
706 struct frame_saved_regs *fsrp;
707{
708 unsigned long locals;
709 unsigned char *p;
710 unsigned char op;
711 CORE_ADDR dummy_bottom;
712 CORE_ADDR adr;
713 int i;
714
715 bzero (fsrp, sizeof *fsrp);
716
717 /* if frame is the end of a dummy, compute where the
718 * beginning would be
719 */
720 dummy_bottom = fip->frame - 4 - NUM_REGS*4 - CALL_DUMMY_LENGTH;
721
722 /* check if the PC is in the stack, in a dummy frame */
723 if (dummy_bottom <= fip->pc && fip->pc <= fip->frame)
724 {
725 /* all regs were saved by push_call_dummy () */
726 adr = fip->frame - 4;
727 for (i = 0; i < NUM_REGS; i++)
728 {
729 fsrp->regs[i] = adr;
730 adr -= 4;
731 }
732 return;
733 }
734
735 locals = i386_get_frame_setup (get_pc_function_start (fip->pc));
736
737 if (locals >= 0)
738 {
739 adr = fip->frame - 4 - locals;
740 for (i = 0; i < 8; i++)
741 {
742 op = codestream_get ();
743 if (op < 0x50 || op > 0x57)
744 break;
745 fsrp->regs[I386_REGNO_TO_SYMMETRY(op - 0x50)] = adr;
746 adr -= 4;
747 }
748 }
749
750 fsrp->regs[PC_REGNUM] = fip->frame + 4;
751 fsrp->regs[FP_REGNUM] = fip->frame;
752}
753
754/* from i386-dep.c */
755static
756print_387_control_word (control)
757unsigned short control;
758{
759 printf ("control 0x%04x: ", control);
760 printf ("compute to ");
761 switch ((control >> 8) & 3)
762 {
763 case 0: printf ("24 bits; "); break;
764 case 1: printf ("(bad); "); break;
765 case 2: printf ("53 bits; "); break;
766 case 3: printf ("64 bits; "); break;
767 }
768 printf ("round ");
769 switch ((control >> 10) & 3)
770 {
771 case 0: printf ("NEAREST; "); break;
772 case 1: printf ("DOWN; "); break;
773 case 2: printf ("UP; "); break;
774 case 3: printf ("CHOP; "); break;
775 }
776 if (control & 0x3f)
777 {
778 printf ("mask:");
779 if (control & 0x0001) printf (" INVALID");
780 if (control & 0x0002) printf (" DENORM");
781 if (control & 0x0004) printf (" DIVZ");
782 if (control & 0x0008) printf (" OVERF");
783 if (control & 0x0010) printf (" UNDERF");
784 if (control & 0x0020) printf (" LOS");
785 printf (";");
786 }
787 printf ("\n");
788 if (control & 0xe080) printf ("warning: reserved bits on 0x%x\n",
789 control & 0xe080);
790}
791
792static
793print_387_status_word (status)
794 unsigned short status;
795{
796 printf ("status %#04x: ", status);
797 if (status & 0xff) {
798 printf ("exceptions:"); /* exception names match <machine/fpu.h> */
799 if (status & 0x0001) printf (" FLTINV");
800 if (status & 0x0002) printf (" FLTDEN");
801 if (status & 0x0004) printf (" FLTDIV");
802 if (status & 0x0008) printf (" FLTOVF");
803 if (status & 0x0010) printf (" FLTUND");
804 if (status & 0x0020) printf (" FLTPRE");
805 if (status & 0x0040) printf (" FLTSTK");
806 printf ("; ");
807 }
808 printf ("flags: %d%d%d%d; ",
809 (status & 0x4000) != 0,
810 (status & 0x0400) != 0,
811 (status & 0x0200) != 0,
812 (status & 0x0100) != 0);
813
814 printf ("top %d\n", (status >> 11) & 7);
815}
816
817static
818print_fpu_status(ep)
819struct pt_regset ep;
820
821{
822 int i;
823 int bothstatus;
824 int top;
825 int fpreg;
826 unsigned char *p;
827
828 printf("80387:");
829 if (ep.pr_fpu.fpu_ip == 0) {
830 printf(" not in use.\n");
831 return;
832 } else {
833 printf("\n");
834 }
835 if (ep.pr_fpu.fpu_status != 0) {
836 print_387_status_word (ep.pr_fpu.fpu_status);
837 }
838 print_387_control_word (ep.pr_fpu.fpu_control);
839 printf ("last exception: ");
840 printf ("opcode 0x%x; ", ep.pr_fpu.fpu_rsvd4);
841 printf ("pc 0x%x:0x%x; ", ep.pr_fpu.fpu_cs, ep.pr_fpu.fpu_ip);
842 printf ("operand 0x%x:0x%x\n", ep.pr_fpu.fpu_data_offset, ep.pr_fpu.fpu_op_sel);
843
844 top = (ep.pr_fpu.fpu_status >> 11) & 7;
845
846 printf ("regno tag msb lsb value\n");
847 for (fpreg = 7; fpreg >= 0; fpreg--)
848 {
849 double val;
850
851 printf ("%s %d: ", fpreg == top ? "=>" : " ", fpreg);
852
853 switch ((ep.pr_fpu.fpu_tag >> (fpreg * 2)) & 3)
854 {
855 case 0: printf ("valid "); break;
856 case 1: printf ("zero "); break;
857 case 2: printf ("trap "); break;
858 case 3: printf ("empty "); break;
859 }
860 for (i = 9; i >= 0; i--)
861 printf ("%02x", ep.pr_fpu.fpu_stack[fpreg][i]);
862
863 i387_to_double (ep.pr_fpu.fpu_stack[fpreg], (char *)&val);
864 printf (" %g\n", val);
865 }
866 if (ep.pr_fpu.fpu_rsvd1)
867 printf ("warning: rsvd1 is 0x%x\n", ep.pr_fpu.fpu_rsvd1);
868 if (ep.pr_fpu.fpu_rsvd2)
869 printf ("warning: rsvd2 is 0x%x\n", ep.pr_fpu.fpu_rsvd2);
870 if (ep.pr_fpu.fpu_rsvd3)
871 printf ("warning: rsvd3 is 0x%x\n", ep.pr_fpu.fpu_rsvd3);
872 if (ep.pr_fpu.fpu_rsvd5)
873 printf ("warning: rsvd5 is 0x%x\n", ep.pr_fpu.fpu_rsvd5);
874}
875
876
877print_1167_control_word(pcr)
878unsigned int pcr;
879
880{
881 int pcr_tmp;
882
883 pcr_tmp = pcr & FPA_PCR_MODE;
884 printf("\tMODE= %#x; RND= %#x ", pcr_tmp, pcr_tmp & 12);
885 switch (pcr_tmp & 12) {
886 case 0:
887 printf("RN (Nearest Value)");
888 break;
889 case 1:
890 printf("RZ (Zero)");
891 break;
892 case 2:
893 printf("RP (Positive Infinity)");
894 break;
895 case 3:
896 printf("RM (Negative Infinity)");
897 break;
898 }
899 printf("; IRND= %d ", pcr_tmp & 2);
900 if (0 == pcr_tmp & 2) {
901 printf("(same as RND)\n");
902 } else {
903 printf("(toward zero)\n");
904 }
905 pcr_tmp = pcr & FPA_PCR_EM;
906 printf("\tEM= %#x", pcr_tmp);
907 if (pcr_tmp & FPA_PCR_EM_DM) printf(" DM");
908 if (pcr_tmp & FPA_PCR_EM_UOM) printf(" UOM");
909 if (pcr_tmp & FPA_PCR_EM_PM) printf(" PM");
910 if (pcr_tmp & FPA_PCR_EM_UM) printf(" UM");
911 if (pcr_tmp & FPA_PCR_EM_OM) printf(" OM");
912 if (pcr_tmp & FPA_PCR_EM_ZM) printf(" ZM");
913 if (pcr_tmp & FPA_PCR_EM_IM) printf(" IM");
914 printf("\n");
915 pcr_tmp = FPA_PCR_CC;
916 printf("\tCC= %#x", pcr_tmp);
917 if (pcr_tmp & FPA_PCR_20MHZ) printf(" 20MHZ");
918 if (pcr_tmp & FPA_PCR_CC_Z) printf(" Z");
919 if (pcr_tmp & FPA_PCR_CC_C2) printf(" C2");
920 if (pcr_tmp & FPA_PCR_CC_C1) printf(" C1");
921 switch (pcr_tmp) {
922 case FPA_PCR_CC_Z:
923 printf(" (Equal)");
924 break;
925 case FPA_PCR_CC_C1:
926 printf(" (Less than)");
927 break;
928 case 0:
929 printf(" (Greater than)");
930 break;
931 case FPA_PCR_CC_Z | FPA_PCR_CC_C1 | FPA_PCR_CC_C2:
932 printf(" (Unordered)");
933 break;
934 default:
935 printf(" (Undefined)");
936 break;
937 }
938 printf("\n");
939 pcr_tmp = pcr & FPA_PCR_AE;
940 printf("\tAE= %#x", pcr_tmp);
941 if (pcr_tmp & FPA_PCR_AE_DE) printf(" DE");
942 if (pcr_tmp & FPA_PCR_AE_UOE) printf(" UOE");
943 if (pcr_tmp & FPA_PCR_AE_PE) printf(" PE");
944 if (pcr_tmp & FPA_PCR_AE_UE) printf(" UE");
945 if (pcr_tmp & FPA_PCR_AE_OE) printf(" OE");
946 if (pcr_tmp & FPA_PCR_AE_ZE) printf(" ZE");
947 if (pcr_tmp & FPA_PCR_AE_EE) printf(" EE");
948 if (pcr_tmp & FPA_PCR_AE_IE) printf(" IE");
949 printf("\n");
950}
951
952print_1167_regs(regs)
953long regs[FPA_NREGS];
954
955{
956 int i;
957
958 union {
959 double d;
960 long l[2];
961 } xd;
962 union {
963 float f;
964 long l;
965 } xf;
966
967
968 for (i = 0; i < FPA_NREGS; i++) {
969 xf.l = regs[i];
970 printf("%%fp%d: raw= %#x, single= %f", i+1, regs[i], xf.f);
971 if (!(i & 1)) {
972 printf("\n");
973 } else {
974 xd.l[1] = regs[i];
975 xd.l[0] = regs[i+1];
976 printf(", double= %f\n", xd.d);
977 }
978 }
979}
980
981print_fpa_status(ep)
982struct pt_regset ep;
983
984{
985
986 printf("WTL 1167:");
987 if (ep.pr_fpa.fpa_pcr !=0) {
988 printf("\n");
989 print_1167_control_word(ep.pr_fpa.fpa_pcr);
990 print_1167_regs(ep.pr_fpa.fpa_regs);
991 } else {
992 printf(" not in use.\n");
993 }
994}
995
996i386_float_info ()
997
998{
999 char ubuf[UPAGES*NBPG];
1000 struct pt_regset regset;
1001 extern int corechan;
1002
1003 if (have_inferior_p()) {
1004 call_ptrace(XPT_RREGS, inferior_pid, &regset, 0);
1005 } else {
1006 if (lseek (corechan, 0, 0) < 0) {
1007 perror ("seek on core file");
1008 }
1009 if (myread (corechan, ubuf, UPAGES*NBPG) < 0) {
1010 perror ("read on core file");
1011 }
1012 /* only interested in the floating point registers */
1013 regset.pr_fpu = ((struct user *) ubuf)->u_fpusave;
1014 regset.pr_fpa = ((struct user *) ubuf)->u_fpasave;
1015 }
1016 print_fpu_status(regset);
1017 print_fpa_status(regset);
1018}
1019
1020i387_to_double (from, to)
1021 char *from;
1022 char *to;
1023{
1024 long *lp;
1025 /* push extended mode on 387 stack, then pop in double mode
1026 *
1027 * first, set exception masks so no error is generated -
1028 * number will be rounded to inf or 0, if necessary
1029 */
1030 asm ("pushl %eax"); /* grab a stack slot */
1031 asm ("fstcw (%esp)"); /* get 387 control word */
1032 asm ("movl (%esp),%eax"); /* save old value */
1033 asm ("orl $0x3f,%eax"); /* mask all exceptions */
1034 asm ("pushl %eax");
1035 asm ("fldcw (%esp)"); /* load new value into 387 */
1036
1037 asm ("movl 8(%ebp),%eax");
1038 asm ("fldt (%eax)"); /* push extended number on 387 stack */
1039 asm ("fwait");
1040 asm ("movl 12(%ebp),%eax");
1041 asm ("fstpl (%eax)"); /* pop double */
1042 asm ("fwait");
1043
1044 asm ("popl %eax"); /* flush modified control word */
1045 asm ("fnclex"); /* clear exceptions */
1046 asm ("fldcw (%esp)"); /* restore original control word */
1047 asm ("popl %eax"); /* flush saved copy */
1048}
1049
1050double_to_i387 (from, to)
1051 char *from;
1052 char *to;
1053{
1054 /* push double mode on 387 stack, then pop in extended mode
1055 * no errors are possible because every 64-bit pattern
1056 * can be converted to an extended
1057 */
1058 asm ("movl 8(%ebp),%eax");
1059 asm ("fldl (%eax)");
1060 asm ("fwait");
1061 asm ("movl 12(%ebp),%eax");
1062 asm ("fstpt (%eax)");
1063 asm ("fwait");
1064}
1065
1066static long
1067i386_get_frame_setup (pc)
1068{
1069 unsigned char op;
1070
1071 codestream_seek (pc);
1072
1073 i386_follow_jump ();
1074
1075 op = codestream_get ();
1076
1077 if (op == 0x58) /* popl %eax */
1078 {
1079 /*
1080 * this function must start with
1081 *
1082 * popl %eax 0x58
1083 * xchgl %eax, (%esp) 0x87 0x04 0x24
1084 * or xchgl %eax, 0(%esp) 0x87 0x44 0x24 0x00
1085 *
1086 * (the system 5 compiler puts out the second xchg
1087 * inst, and the assembler doesn't try to optimize it,
1088 * so the 'sib' form gets generated)
1089 *
1090 * this sequence is used to get the address of the return
1091 * buffer for a function that returns a structure
1092 */
1093 int pos;
1094 unsigned char buf[4];
1095 static unsigned char proto1[3] = { 0x87,0x04,0x24 };
1096 static unsigned char proto2[4] = { 0x87,0x44,0x24,0x00 };
1097 pos = codestream_tell ();
1098 codestream_read (buf, 4);
1099 if (bcmp (buf, proto1, 3) == 0)
1100 pos += 3;
1101 else if (bcmp (buf, proto2, 4) == 0)
1102 pos += 4;
1103
1104 codestream_seek (pos);
1105 op = codestream_get (); /* update next opcode */
1106 }
1107
1108 if (op == 0x55) /* pushl %esp */
1109 {
1110 if (codestream_get () != 0x8b) /* movl %esp, %ebp (2bytes) */
1111 return (-1);
1112 if (codestream_get () != 0xec)
1113 return (-1);
1114 /*
1115 * check for stack adjustment
1116 *
1117 * subl $XXX, %esp
1118 *
1119 * note: you can't subtract a 16 bit immediate
1120 * from a 32 bit reg, so we don't have to worry
1121 * about a data16 prefix
1122 */
1123 op = codestream_peek ();
1124 if (op == 0x83) /* subl with 8 bit immed */
1125 {
1126 codestream_get ();
1127 if (codestream_get () != 0xec)
1128 return (-1);
1129 /* subl with signed byte immediate
1130 * (though it wouldn't make sense to be negative)
1131 */
1132 return (codestream_get());
1133 }
1134 else if (op == 0x81) /* subl with 32 bit immed */
1135 {
1136 int locals;
1137 if (codestream_get () != 0xec)
1138 return (-1);
1139 /* subl with 32 bit immediate */
1140 codestream_read ((unsigned char *)&locals, 4);
1141 return (locals);
1142 }
1143 else
1144 {
1145 return (0);
1146 }
1147 }
1148 else if (op == 0xc8)
1149 {
1150 /* enter instruction: arg is 16 unsigned immed */
1151 unsigned short slocals;
1152 codestream_read ((unsigned char *)&slocals, 2);
1153 codestream_get (); /* flush final byte of enter instruction */
1154 return (slocals);
1155 }
1156 return (-1);
1157}
1158
1159/* next instruction is a jump, move to target */
1160static
1161i386_follow_jump ()
1162{
1163 int long_delta;
1164 short short_delta;
1165 char byte_delta;
1166 int data16;
1167 int pos;
1168
1169 pos = codestream_tell ();
1170
1171 data16 = 0;
1172 if (codestream_peek () == 0x66)
1173 {
1174 codestream_get ();
1175 data16 = 1;
1176 }
1177
1178 switch (codestream_get ())
1179 {
1180 case 0xe9:
1181 /* relative jump: if data16 == 0, disp32, else disp16 */
1182 if (data16)
1183 {
1184 codestream_read ((unsigned char *)&short_delta, 2);
1185 pos += short_delta + 3; /* include size of jmp inst */
1186 }
1187 else
1188 {
1189 codestream_read ((unsigned char *)&long_delta, 4);
1190 pos += long_delta + 5;
1191 }
1192 break;
1193 case 0xeb:
1194 /* relative jump, disp8 (ignore data16) */
1195 codestream_read ((unsigned char *)&byte_delta, 1);
1196 pos += byte_delta + 2;
1197 break;
1198 }
1199 codestream_seek (pos + data16);
1200}
1201
1202/* return pc of first real instruction */
1203/* from i386-dep.c */
1204
1205i386_skip_prologue (pc)
1206{
1207 unsigned char op;
1208 int i;
1209
1210 if (i386_get_frame_setup (pc) < 0)
1211 return (pc);
1212
1213 /* found valid frame setup - codestream now points to
1214 * start of push instructions for saving registers
1215 */
1216
1217 /* skip over register saves */
1218 for (i = 0; i < 8; i++)
1219 {
1220 op = codestream_peek ();
1221 /* break if not pushl inst */
1222 if (op < 0x50 || op > 0x57)
1223 break;
1224 codestream_get ();
1225 }
1226
1227 i386_follow_jump ();
1228
1229 return (codestream_tell ());
1230}
1231
1232symmetry_extract_return_value(type, regbuf, valbuf)
1233 struct type *type;
1234 char *regbuf;
1235 char *valbuf;
1236{
1237 union {
1238 double d;
1239 int l[2];
1240 } xd;
1241 int i;
1242 float f;
1243
1244 if (TYPE_CODE_FLT == TYPE_CODE(type)) {
1245 for (i = 0; i < misc_function_count; i++) {
1246 if (!strcmp(misc_function_vector[i].name, "1167_flt"))
1247 break;
1248 }
1249 if (i < misc_function_count) {
1250 /* found "1167_flt" means 1167, %fp2-%fp3 */
1251 /* float & double; 19= %fp2, 20= %fp3 */
1252 /* no single precision on 1167 */
1253 xd.l[1] = *((int *)&regbuf[REGISTER_BYTE(19)]);
1254 xd.l[0] = *((int *)&regbuf[REGISTER_BYTE(20)]);
1255 switch (TYPE_LENGTH(type)) {
1256 case 4:
1257 f = (float) xd.d;
1258 bcopy(&f, valbuf, TYPE_LENGTH(type));
1259 break;
1260 case 8:
1261 bcopy(&xd.d, valbuf, TYPE_LENGTH(type));
1262 break;
1263 default:
1264 error("Unknown floating point size");
1265 break;
1266 }
1267 } else {
1268 /* 387 %st(0), gcc uses this */
1269 i387_to_double(((int *)&regbuf[REGISTER_BYTE(3)]),
1270 &xd.d);
1271 switch (TYPE_LENGTH(type)) {
1272 case 4: /* float */
1273 f = (float) xd.d;
1274 bcopy(&f, valbuf, 4);
1275 break;
1276 case 8: /* double */
1277 bcopy(&xd.d, valbuf, 8);
1278 break;
1279 default:
1280 error("Unknown floating point size");
1281 break;
1282 }
1283 }
1284 } else {
1285 bcopy (regbuf, valbuf, TYPE_LENGTH (type));
1286 }
1287}
This page took 0.070726 seconds and 4 git commands to generate.