BSD 4_3_Net_2 development
[unix-history] / usr / src / usr.bin / gdb / config / i386-dep.c
CommitLineData
124193f3
C
1/* Low level interface to ptrace, for GDB when running on the Intel 386.
2 Copyright (C) 1988, 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#include <stdio.h>
21#include "defs.h"
22#include "param.h"
23#include "frame.h"
24#include "inferior.h"
25
26#ifdef USG
27#include <sys/types.h>
28#endif
29
30#include <sys/param.h>
31#include <sys/dir.h>
32#include <signal.h>
33#include <sys/user.h>
34#include <sys/ioctl.h>
35#include <fcntl.h>
36
37#ifdef COFF_ENCAPSULATE
38#include "a.out.encap.h"
39#else
40#include <a.out.h>
41#endif
42
43#ifndef N_SET_MAGIC
44#ifdef COFF_FORMAT
45#define N_SET_MAGIC(exec, val) ((exec).magic = (val))
46#else
47#define N_SET_MAGIC(exec, val) ((exec).a_magic = (val))
48#endif
49#endif
50
51#include <sys/file.h>
52#include <sys/stat.h>
53
54#include <sys/reg.h>
55
56extern int errno;
57\f
58/* This function simply calls ptrace with the given arguments.
59 It exists so that all calls to ptrace are isolated in this
60 machine-dependent file. */
61int
62call_ptrace (request, pid, arg3, arg4)
63 int request, pid, arg3, arg4;
64{
65 return ptrace (request, pid, arg3, arg4);
66}
67
68kill_inferior ()
69{
70 if (remote_debugging)
71 return;
72 if (inferior_pid == 0)
73 return;
74 ptrace (8, inferior_pid, 0, 0);
75 wait (0);
76 inferior_died ();
77}
78
79/* This is used when GDB is exiting. It gives less chance of error.*/
80
81kill_inferior_fast ()
82{
83 if (remote_debugging)
84 return;
85 if (inferior_pid == 0)
86 return;
87 ptrace (8, inferior_pid, 0, 0);
88 wait (0);
89}
90
91/* Resume execution of the inferior process.
92 If STEP is nonzero, single-step it.
93 If SIGNAL is nonzero, give it that signal. */
94
95void
96resume (step, signal)
97 int step;
98 int signal;
99{
100 errno = 0;
101 if (remote_debugging)
102 remote_resume (step, signal);
103 else
104 {
105 ptrace (step ? 9 : 7, inferior_pid, 1, signal);
106 if (errno)
107 perror_with_name ("ptrace");
108 }
109}
110\f
111void
112fetch_inferior_registers ()
113{
114 register int regno;
115 register unsigned int regaddr;
116 char buf[MAX_REGISTER_RAW_SIZE];
117 register int i;
118
119 struct user u;
120 unsigned int offset = (char *) &u.u_ar0 - (char *) &u;
121 offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR;
122
123 for (regno = 0; regno < NUM_REGS; regno++)
124 {
125 regaddr = register_addr (regno, offset);
126 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
127 {
128 *(int *) &buf[i] = ptrace (3, inferior_pid, regaddr, 0);
129 regaddr += sizeof (int);
130 }
131 supply_register (regno, buf);
132 }
133}
134
135/* Store our register values back into the inferior.
136 If REGNO is -1, do this for all registers.
137 Otherwise, REGNO specifies which register (so we can save time). */
138
139store_inferior_registers (regno)
140 int regno;
141{
142 register unsigned int regaddr;
143 char buf[80];
144
145 struct user u;
146 unsigned int offset = (char *) &u.u_ar0 - (char *) &u;
147 offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR;
148
149 if (regno >= 0)
150 {
151 regaddr = register_addr (regno, offset);
152 errno = 0;
153 ptrace (6, inferior_pid, regaddr, read_register (regno));
154 if (errno != 0)
155 {
156 sprintf (buf, "writing register number %d", regno);
157 perror_with_name (buf);
158 }
159 }
160 else for (regno = 0; regno < NUM_REGS; regno++)
161 {
162 regaddr = register_addr (regno, offset);
163 errno = 0;
164 ptrace (6, inferior_pid, regaddr, read_register (regno));
165 if (errno != 0)
166 {
167 sprintf (buf, "writing register number %d", regno);
168 perror_with_name (buf);
169 }
170 }
171}
172\f
173/* Copy LEN bytes from inferior's memory starting at MEMADDR
174 to debugger memory starting at MYADDR.
175 On failure (cannot read from inferior, usually because address is out
176 of bounds) returns the value of errno. */
177
178int
179read_inferior_memory (memaddr, myaddr, len)
180 CORE_ADDR memaddr;
181 char *myaddr;
182 int len;
183{
184 register int i;
185 /* Round starting address down to longword boundary. */
186 register CORE_ADDR addr = memaddr & - sizeof (int);
187 /* Round ending address up; get number of longwords that makes. */
188 register int count
189 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
190 /* Allocate buffer of that many longwords. */
191 register int *buffer = (int *) alloca (count * sizeof (int));
192 extern int errno;
193
194 /* Read all the longwords */
195 for (i = 0; i < count; i++, addr += sizeof (int))
196 {
197 errno = 0;
198 if (remote_debugging)
199 buffer[i] = remote_fetch_word (addr);
200 else
201 buffer[i] = ptrace (1, inferior_pid, addr, 0);
202 if (errno)
203 return errno;
204 }
205
206 /* Copy appropriate bytes out of the buffer. */
207 bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
208 return 0;
209}
210
211/* Copy LEN bytes of data from debugger memory at MYADDR
212 to inferior's memory at MEMADDR.
213 On failure (cannot write the inferior)
214 returns the value of errno. */
215
216int
217write_inferior_memory (memaddr, myaddr, len)
218 CORE_ADDR memaddr;
219 char *myaddr;
220 int len;
221{
222 register int i;
223 /* Round starting address down to longword boundary. */
224 register CORE_ADDR addr = memaddr & - sizeof (int);
225 /* Round ending address up; get number of longwords that makes. */
226 register int count
227 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
228 /* Allocate buffer of that many longwords. */
229 register int *buffer = (int *) alloca (count * sizeof (int));
230 extern int errno;
231
232 /* Fill start and end extra bytes of buffer with existing memory data. */
233
234 if (remote_debugging)
235 buffer[0] = remote_fetch_word (addr);
236 else
237 buffer[0] = ptrace (1, inferior_pid, addr, 0);
238
239 if (count > 1)
240 {
241 if (remote_debugging)
242 buffer[count - 1]
243 = remote_fetch_word (addr + (count - 1) * sizeof (int));
244 else
245 buffer[count - 1]
246 = ptrace (1, inferior_pid,
247 addr + (count - 1) * sizeof (int), 0);
248 }
249
250 /* Copy data to be written over corresponding part of buffer */
251
252 bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
253
254 /* Write the entire buffer. */
255
256 for (i = 0; i < count; i++, addr += sizeof (int))
257 {
258 errno = 0;
259 if (remote_debugging)
260 remote_store_word (addr, buffer[i]);
261 else
262 ptrace (4, inferior_pid, addr, buffer[i]);
263 if (errno)
264 return errno;
265 }
266
267 return 0;
268}
269\f
270/* Work with core dump and executable files, for GDB.
271 This code would be in core.c if it weren't machine-dependent. */
272
273#ifndef N_TXTADDR
274#define N_TXTADDR(hdr) 0
275#endif /* no N_TXTADDR */
276
277#ifndef N_DATADDR
278#define N_DATADDR(hdr) hdr.a_text
279#endif /* no N_DATADDR */
280
281/* Make COFF and non-COFF names for things a little more compatible
282 to reduce conditionals later. */
283
284#ifndef COFF_FORMAT
285#ifndef AOUTHDR
286#define AOUTHDR struct exec
287#endif
288#endif
289
290extern char *sys_siglist[];
291
292
293/* Hook for `exec_file_command' command to call. */
294
295extern void (*exec_file_display_hook) ();
296
297/* File names of core file and executable file. */
298
299extern char *corefile;
300extern char *execfile;
301
302/* Descriptors on which core file and executable file are open.
303 Note that the execchan is closed when an inferior is created
304 and reopened if the inferior dies or is killed. */
305
306extern int corechan;
307extern int execchan;
308
309/* Last modification time of executable file.
310 Also used in source.c to compare against mtime of a source file. */
311
312extern int exec_mtime;
313
314/* Virtual addresses of bounds of the two areas of memory in the core file. */
315
316extern CORE_ADDR data_start;
317extern CORE_ADDR data_end;
318extern CORE_ADDR stack_start;
319extern CORE_ADDR stack_end;
320
321/* Virtual addresses of bounds of two areas of memory in the exec file.
322 Note that the data area in the exec file is used only when there is no core file. */
323
324extern CORE_ADDR text_start;
325extern CORE_ADDR text_end;
326
327extern CORE_ADDR exec_data_start;
328extern CORE_ADDR exec_data_end;
329
330/* Address in executable file of start of text area data. */
331
332extern int text_offset;
333
334/* Address in executable file of start of data area data. */
335
336extern int exec_data_offset;
337
338/* Address in core file of start of data area data. */
339
340extern int data_offset;
341
342/* Address in core file of start of stack area data. */
343
344extern int stack_offset;
345
346#ifdef COFF_FORMAT
347/* various coff data structures */
348
349extern FILHDR file_hdr;
350extern SCNHDR text_hdr;
351extern SCNHDR data_hdr;
352
353#endif /* not COFF_FORMAT */
354
355/* a.out header saved in core file. */
356
357extern AOUTHDR core_aouthdr;
358
359/* a.out header of exec file. */
360
361extern AOUTHDR exec_aouthdr;
362
363extern void validate_files ();
364\f
365core_file_command (filename, from_tty)
366 char *filename;
367 int from_tty;
368{
369 int val;
370 extern char registers[];
371
372 /* Discard all vestiges of any previous core file
373 and mark data and stack spaces as empty. */
374
375 if (corefile)
376 free (corefile);
377 corefile = 0;
378
379 if (corechan >= 0)
380 close (corechan);
381 corechan = -1;
382
383 data_start = 0;
384 data_end = 0;
385 stack_start = STACK_END_ADDR;
386 stack_end = STACK_END_ADDR;
387
388 /* Now, if a new core file was specified, open it and digest it. */
389
390 if (filename)
391 {
392 filename = tilde_expand (filename);
393 make_cleanup (free, filename);
394
395 if (have_inferior_p ())
396 error ("To look at a core file, you must kill the inferior with \"kill\".");
397 corechan = open (filename, O_RDONLY, 0);
398 if (corechan < 0)
399 perror_with_name (filename);
400 /* 4.2-style (and perhaps also sysV-style) core dump file. */
401 {
402 struct user u;
403
404 int reg_offset;
405
406 val = myread (corechan, &u, sizeof u);
407 if (val < 0)
408 perror_with_name (filename);
409 data_start = exec_data_start;
410
411 data_end = data_start + NBPG * u.u_dsize;
412 stack_start = stack_end - NBPG * u.u_ssize;
413 data_offset = NBPG * UPAGES;
414 stack_offset = NBPG * (UPAGES + u.u_dsize);
415 reg_offset = (int) u.u_ar0 - KERNEL_U_ADDR;
416
417 /* I don't know where to find this info.
418 So, for now, mark it as not available. */
419/* N_SET_MAGIC (core_aouthdr, 0); */
420 bzero ((char *) &core_aouthdr, sizeof core_aouthdr);
421
422 /* Read the register values out of the core file and store
423 them where `read_register' will find them. */
424
425 {
426 register int regno;
427
428 for (regno = 0; regno < NUM_REGS; regno++)
429 {
430 char buf[MAX_REGISTER_RAW_SIZE];
431
432 val = lseek (corechan, register_addr (regno, reg_offset), 0);
433 if (val < 0)
434 perror_with_name (filename);
435
436 val = myread (corechan, buf, sizeof buf);
437 if (val < 0)
438 perror_with_name (filename);
439 supply_register (regno, buf);
440 }
441 }
442 }
443 if (filename[0] == '/')
444 corefile = savestring (filename, strlen (filename));
445 else
446 {
447 corefile = concat (current_directory, "/", filename);
448 }
449
450 set_current_frame ( create_new_frame (read_register (FP_REGNUM),
451 read_pc ()));
452 select_frame (get_current_frame (), 0);
453 validate_files ();
454 }
455 else if (from_tty)
456 printf ("No core file now.\n");
457}
458\f
459exec_file_command (filename, from_tty)
460 char *filename;
461 int from_tty;
462{
463 int val;
464
465 /* Eliminate all traces of old exec file.
466 Mark text segment as empty. */
467
468 if (execfile)
469 free (execfile);
470 execfile = 0;
471 data_start = 0;
472 data_end -= exec_data_start;
473 text_start = 0;
474 text_end = 0;
475 exec_data_start = 0;
476 exec_data_end = 0;
477 if (execchan >= 0)
478 close (execchan);
479 execchan = -1;
480
481 /* Now open and digest the file the user requested, if any. */
482
483 if (filename)
484 {
485 filename = tilde_expand (filename);
486 make_cleanup (free, filename);
487
488 execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
489 &execfile);
490 if (execchan < 0)
491 perror_with_name (filename);
492
493#ifdef COFF_FORMAT
494 {
495 int aout_hdrsize;
496 int num_sections;
497
498 if (read_file_hdr (execchan, &file_hdr) < 0)
499 error ("\"%s\": not in executable format.", execfile);
500
501 aout_hdrsize = file_hdr.f_opthdr;
502 num_sections = file_hdr.f_nscns;
503
504 if (read_aout_hdr (execchan, &exec_aouthdr, aout_hdrsize) < 0)
505 error ("\"%s\": can't read optional aouthdr", execfile);
506
507 if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections,
508 aout_hdrsize) < 0)
509 error ("\"%s\": can't read text section header", execfile);
510
511 if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections,
512 aout_hdrsize) < 0)
513 error ("\"%s\": can't read data section header", execfile);
514
515 text_start = exec_aouthdr.text_start;
516 text_end = text_start + exec_aouthdr.tsize;
517 text_offset = text_hdr.s_scnptr;
518 exec_data_start = exec_aouthdr.data_start;
519 exec_data_end = exec_data_start + exec_aouthdr.dsize;
520 exec_data_offset = data_hdr.s_scnptr;
521 data_start = exec_data_start;
522 data_end += exec_data_start;
523 exec_mtime = file_hdr.f_timdat;
524 }
525#else /* not COFF_FORMAT */
526 {
527 struct stat st_exec;
528
529#ifdef HEADER_SEEK_FD
530 HEADER_SEEK_FD (execchan);
531#endif
532
533 val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR));
534
535 if (val < 0)
536 perror_with_name (filename);
537
538 text_start = N_TXTADDR (exec_aouthdr);
539 exec_data_start = N_DATADDR (exec_aouthdr);
540
541 text_offset = N_TXTOFF (exec_aouthdr);
542 exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
543
544 text_end = text_start + exec_aouthdr.a_text;
545 exec_data_end = exec_data_start + exec_aouthdr.a_data;
546 data_start = exec_data_start;
547 data_end += exec_data_start;
548
549 fstat (execchan, &st_exec);
550 exec_mtime = st_exec.st_mtime;
551 }
552#endif /* not COFF_FORMAT */
553
554 validate_files ();
555 }
556 else if (from_tty)
557 printf ("No exec file now.\n");
558
559 /* Tell display code (if any) about the changed file name. */
560 if (exec_file_display_hook)
561 (*exec_file_display_hook) (filename);
562}
563
564/* helper functions for m-i386.h */
565
566/* stdio style buffering to minimize calls to ptrace */
567static CORE_ADDR codestream_next_addr;
568static CORE_ADDR codestream_addr;
569static unsigned char codestream_buf[sizeof (int)];
570static int codestream_off;
571static int codestream_cnt;
572
573#define codestream_tell() (codestream_addr + codestream_off)
574#define codestream_peek() (codestream_cnt == 0 ? \
575 codestream_fill(1): codestream_buf[codestream_off])
576#define codestream_get() (codestream_cnt-- == 0 ? \
577 codestream_fill(0) : codestream_buf[codestream_off++])
578
579static unsigned char
580codestream_fill (peek_flag)
581{
582 codestream_addr = codestream_next_addr;
583 codestream_next_addr += sizeof (int);
584 codestream_off = 0;
585 codestream_cnt = sizeof (int);
586 read_memory (codestream_addr,
587 (unsigned char *)codestream_buf,
588 sizeof (int));
589
590 if (peek_flag)
591 return (codestream_peek());
592 else
593 return (codestream_get());
594}
595
596static void
597codestream_seek (place)
598{
599 codestream_next_addr = place & -sizeof (int);
600 codestream_cnt = 0;
601 codestream_fill (1);
602 while (codestream_tell() != place)
603 codestream_get ();
604}
605
606static void
607codestream_read (buf, count)
608 unsigned char *buf;
609{
610 unsigned char *p;
611 int i;
612 p = buf;
613 for (i = 0; i < count; i++)
614 *p++ = codestream_get ();
615}
616
617/* next instruction is a jump, move to target */
618static
619i386_follow_jump ()
620{
621 int long_delta;
622 short short_delta;
623 char byte_delta;
624 int data16;
625 int pos;
626
627 pos = codestream_tell ();
628
629 data16 = 0;
630 if (codestream_peek () == 0x66)
631 {
632 codestream_get ();
633 data16 = 1;
634 }
635
636 switch (codestream_get ())
637 {
638 case 0xe9:
639 /* relative jump: if data16 == 0, disp32, else disp16 */
640 if (data16)
641 {
642 codestream_read ((unsigned char *)&short_delta, 2);
643 pos += short_delta + 3; /* include size of jmp inst */
644 }
645 else
646 {
647 codestream_read ((unsigned char *)&long_delta, 4);
648 pos += long_delta + 5;
649 }
650 break;
651 case 0xeb:
652 /* relative jump, disp8 (ignore data16) */
653 codestream_read ((unsigned char *)&byte_delta, 1);
654 pos += byte_delta + 2;
655 break;
656 }
657 codestream_seek (pos + data16);
658}
659
660/*
661 * find & return amound a local space allocated, and advance codestream to
662 * first register push (if any)
663 *
664 * if entry sequence doesn't make sense, return -1, and leave
665 * codestream pointer random
666 */
667static long
668i386_get_frame_setup (pc)
669{
670 unsigned char op;
671
672 codestream_seek (pc);
673
674 i386_follow_jump ();
675
676 op = codestream_get ();
677
678 if (op == 0x58) /* popl %eax */
679 {
680 /*
681 * this function must start with
682 *
683 * popl %eax 0x58
684 * xchgl %eax, (%esp) 0x87 0x04 0x24
685 * or xchgl %eax, 0(%esp) 0x87 0x44 0x24 0x00
686 *
687 * (the system 5 compiler puts out the second xchg
688 * inst, and the assembler doesn't try to optimize it,
689 * so the 'sib' form gets generated)
690 *
691 * this sequence is used to get the address of the return
692 * buffer for a function that returns a structure
693 */
694 int pos;
695 unsigned char buf[4];
696 static unsigned char proto1[3] = { 0x87,0x04,0x24 };
697 static unsigned char proto2[4] = { 0x87,0x44,0x24,0x00 };
698 pos = codestream_tell ();
699 codestream_read (buf, 4);
700 if (bcmp (buf, proto1, 3) == 0)
701 pos += 3;
702 else if (bcmp (buf, proto2, 4) == 0)
703 pos += 4;
704
705 codestream_seek (pos);
706 op = codestream_get (); /* update next opcode */
707 }
708
709 if (op == 0x55) /* pushl %esp */
710 {
711 /* check for movl %esp, %ebp - can be written two ways */
712 switch (codestream_get ())
713 {
714 case 0x8b:
715 if (codestream_get () != 0xec)
716 return (-1);
717 break;
718 case 0x89:
719 if (codestream_get () != 0xe5)
720 return (-1);
721 break;
722 default:
723 return (-1);
724 }
725 /* check for stack adjustment
726 *
727 * subl $XXX, %esp
728 *
729 * note: you can't subtract a 16 bit immediate
730 * from a 32 bit reg, so we don't have to worry
731 * about a data16 prefix
732 */
733 op = codestream_peek ();
734 if (op == 0x83)
735 {
736 /* subl with 8 bit immed */
737 codestream_get ();
738 if (codestream_get () != 0xec)
739 return (-1);
740 /* subl with signed byte immediate
741 * (though it wouldn't make sense to be negative)
742 */
743 return (codestream_get());
744 }
745 else if (op == 0x81)
746 {
747 /* subl with 32 bit immed */
748 int locals;
749 codestream_get();
750 if (codestream_get () != 0xec)
751 return (-1);
752 /* subl with 32 bit immediate */
753 codestream_read ((unsigned char *)&locals, 4);
754 return (locals);
755 }
756 else
757 {
758 return (0);
759 }
760 }
761 else if (op == 0xc8)
762 {
763 /* enter instruction: arg is 16 bit unsigned immed */
764 unsigned short slocals;
765 codestream_read ((unsigned char *)&slocals, 2);
766 codestream_get (); /* flush final byte of enter instruction */
767 return (slocals);
768 }
769 return (-1);
770}
771
772/* Return number of args passed to a frame.
773 Can return -1, meaning no way to tell. */
774
775/* on the 386, the instruction following the call could be:
776 * popl %ecx - one arg
777 * addl $imm, %esp - imm/4 args; imm may be 8 or 32 bits
778 * anything else - zero args
779 */
780
781int
782i386_frame_num_args (fi)
783 struct frame_info fi;
784{
785 int retpc;
786 unsigned char op;
787 struct frame_info *pfi;
788
789 pfi = get_prev_frame_info ((fi));
790 if (pfi == 0)
791 {
792 /* Note: this can happen if we are looking at the frame for
793 main, because FRAME_CHAIN_VALID won't let us go into
794 start. If we have debugging symbols, that's not really
795 a big deal; it just means it will only show as many arguments
796 to main as are declared. */
797 return -1;
798 }
799 else
800 {
801 retpc = pfi->pc;
802 op = read_memory_integer (retpc, 1);
803 if (op == 0x59)
804 /* pop %ecx */
805 return 1;
806 else if (op == 0x83)
807 {
808 op = read_memory_integer (retpc+1, 1);
809 if (op == 0xc4)
810 /* addl $<signed imm 8 bits>, %esp */
811 return (read_memory_integer (retpc+2,1)&0xff)/4;
812 else
813 return 0;
814 }
815 else if (op == 0x81)
816 { /* add with 32 bit immediate */
817 op = read_memory_integer (retpc+1, 1);
818 if (op == 0xc4)
819 /* addl $<imm 32>, %esp */
820 return read_memory_integer (retpc+2, 4) / 4;
821 else
822 return 0;
823 }
824 else
825 {
826 return 0;
827 }
828 }
829}
830
831/*
832 * parse the first few instructions of the function to see
833 * what registers were stored.
834 *
835 * We handle these cases:
836 *
837 * The startup sequence can be at the start of the function,
838 * or the function can start with a branch to startup code at the end.
839 *
840 * %ebp can be set up with either the 'enter' instruction, or
841 * 'pushl %ebp, movl %esp, %ebp' (enter is too slow to be useful,
842 * but was once used in the sys5 compiler)
843 *
844 * Local space is allocated just below the saved %ebp by either the
845 * 'enter' instruction, or by 'subl $<size>, %esp'. 'enter' has
846 * a 16 bit unsigned argument for space to allocate, and the
847 * 'addl' instruction could have either a signed byte, or
848 * 32 bit immediate.
849 *
850 * Next, the registers used by this function are pushed. In
851 * the sys5 compiler they will always be in the order: %edi, %esi, %ebx
852 * (and sometimes a harmless bug causes it to also save but not restore %eax);
853 * however, the code below is willing to see the pushes in any order,
854 * and will handle up to 8 of them.
855 *
856 * If the setup sequence is at the end of the function, then the
857 * next instruction will be a branch back to the start.
858 */
859
860i386_frame_find_saved_regs (fip, fsrp)
861 struct frame_info *fip;
862 struct frame_saved_regs *fsrp;
863{
864 unsigned long locals;
865 unsigned char *p;
866 unsigned char op;
867 CORE_ADDR dummy_bottom;
868 CORE_ADDR adr;
869 int i;
870
871 bzero (fsrp, sizeof *fsrp);
872
873 /* if frame is the end of a dummy, compute where the
874 * beginning would be
875 */
876 dummy_bottom = fip->frame - 4 - NUM_REGS*4 - CALL_DUMMY_LENGTH;
877
878 /* check if the PC is in the stack, in a dummy frame */
879 if (dummy_bottom <= fip->pc && fip->pc <= fip->frame)
880 {
881 /* all regs were saved by push_call_dummy () */
882 adr = fip->frame - 4;
883 for (i = 0; i < NUM_REGS; i++)
884 {
885 fsrp->regs[i] = adr;
886 adr -= 4;
887 }
888 return;
889 }
890
891 locals = i386_get_frame_setup (get_pc_function_start (fip->pc));
892
893 if (locals >= 0)
894 {
895 adr = fip->frame - 4 - locals;
896 for (i = 0; i < 8; i++)
897 {
898 op = codestream_get ();
899 if (op < 0x50 || op > 0x57)
900 break;
901 fsrp->regs[op - 0x50] = adr;
902 adr -= 4;
903 }
904 }
905
906 fsrp->regs[PC_REGNUM] = fip->frame + 4;
907 fsrp->regs[FP_REGNUM] = fip->frame;
908}
909
910/* return pc of first real instruction */
911i386_skip_prologue (pc)
912{
913 unsigned char op;
914 int i;
915
916 if (i386_get_frame_setup (pc) < 0)
917 return (pc);
918
919 /* found valid frame setup - codestream now points to
920 * start of push instructions for saving registers
921 */
922
923 /* skip over register saves */
924 for (i = 0; i < 8; i++)
925 {
926 op = codestream_peek ();
927 /* break if not pushl inst */
928 if (op < 0x50 || op > 0x57)
929 break;
930 codestream_get ();
931 }
932
933 i386_follow_jump ();
934
935 return (codestream_tell ());
936}
937
938i386_push_dummy_frame ()
939{
940 CORE_ADDR sp = read_register (SP_REGNUM);
941 int regnum;
942
943 sp = push_word (sp, read_register (PC_REGNUM));
944 sp = push_word (sp, read_register (FP_REGNUM));
945 write_register (FP_REGNUM, sp);
946 for (regnum = 0; regnum < NUM_REGS; regnum++)
947 sp = push_word (sp, read_register (regnum));
948 write_register (SP_REGNUM, sp);
949}
950
951i386_pop_frame ()
952{
953 FRAME frame = get_current_frame ();
954 CORE_ADDR fp;
955 int regnum;
956 struct frame_saved_regs fsr;
957 struct frame_info *fi;
958
959 fi = get_frame_info (frame);
960 fp = fi->frame;
961 get_frame_saved_regs (fi, &fsr);
962 for (regnum = 0; regnum < NUM_REGS; regnum++)
963 {
964 CORE_ADDR adr;
965 adr = fsr.regs[regnum];
966 if (adr)
967 write_register (regnum, read_memory_integer (adr, 4));
968 }
969 write_register (FP_REGNUM, read_memory_integer (fp, 4));
970 write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
971 write_register (SP_REGNUM, fp + 8);
972 flush_cached_frames ();
973 set_current_frame ( create_new_frame (read_register (FP_REGNUM),
974 read_pc ()));
975}
976
977/* this table must line up with REGISTER_NAMES in m-i386.h */
978/* symbols like 'EAX' come from <sys/reg.h> */
979static int regmap[] =
980{
981 EAX, ECX, EDX, EBX,
982 UESP, EBP, ESI, EDI,
983 EIP, EFL, CS, SS,
984 DS, ES, FS, GS,
985};
986
987/* blockend is the value of u.u_ar0, and points to the
988 * place where GS is stored
989 */
990i386_register_u_addr (blockend, regnum)
991{
992#if 0
993 /* this will be needed if fp registers are reinstated */
994 /* for now, you can look at them with 'info float'
995 * sys5 wont let you change them with ptrace anyway
996 */
997 if (regnum >= FP0_REGNUM && regnum <= FP7_REGNUM)
998 {
999 int ubase, fpstate;
1000 struct user u;
1001 ubase = blockend + 4 * (SS + 1) - KSTKSZ;
1002 fpstate = ubase + ((char *)&u.u_fpstate - (char *)&u);
1003 return (fpstate + 0x1c + 10 * (regnum - FP0_REGNUM));
1004 }
1005 else
1006#endif
1007 return (blockend + 4 * regmap[regnum]);
1008
1009}
1010
1011i387_to_double (from, to)
1012 char *from;
1013 char *to;
1014{
1015 long *lp;
1016 /* push extended mode on 387 stack, then pop in double mode
1017 *
1018 * first, set exception masks so no error is generated -
1019 * number will be rounded to inf or 0, if necessary
1020 */
1021 asm ("pushl %eax"); /* grab a stack slot */
1022 asm ("fstcw (%esp)"); /* get 387 control word */
1023 asm ("movl (%esp),%eax"); /* save old value */
1024 asm ("orl $0x3f,%eax"); /* mask all exceptions */
1025 asm ("pushl %eax");
1026 asm ("fldcw (%esp)"); /* load new value into 387 */
1027
1028 asm ("movl 8(%ebp),%eax");
1029 asm ("fldt (%eax)"); /* push extended number on 387 stack */
1030 asm ("fwait");
1031 asm ("movl 12(%ebp),%eax");
1032 asm ("fstpl (%eax)"); /* pop double */
1033 asm ("fwait");
1034
1035 asm ("popl %eax"); /* flush modified control word */
1036 asm ("fnclex"); /* clear exceptions */
1037 asm ("fldcw (%esp)"); /* restore original control word */
1038 asm ("popl %eax"); /* flush saved copy */
1039}
1040
1041double_to_i387 (from, to)
1042 char *from;
1043 char *to;
1044{
1045 /* push double mode on 387 stack, then pop in extended mode
1046 * no errors are possible because every 64-bit pattern
1047 * can be converted to an extended
1048 */
1049 asm ("movl 8(%ebp),%eax");
1050 asm ("fldl (%eax)");
1051 asm ("fwait");
1052 asm ("movl 12(%ebp),%eax");
1053 asm ("fstpt (%eax)");
1054 asm ("fwait");
1055}
1056
1057struct env387
1058{
1059 unsigned short control;
1060 unsigned short r0;
1061 unsigned short status;
1062 unsigned short r1;
1063 unsigned short tag;
1064 unsigned short r2;
1065 unsigned long eip;
1066 unsigned short code_seg;
1067 unsigned short opcode;
1068 unsigned long operand;
1069 unsigned short operand_seg;
1070 unsigned short r3;
1071 unsigned char regs[8][10];
1072};
1073
1074static
1075print_387_control_word (control)
1076unsigned short control;
1077{
1078 printf ("control 0x%04x: ", control);
1079 printf ("compute to ");
1080 switch ((control >> 8) & 3)
1081 {
1082 case 0: printf ("24 bits; "); break;
1083 case 1: printf ("(bad); "); break;
1084 case 2: printf ("53 bits; "); break;
1085 case 3: printf ("64 bits; "); break;
1086 }
1087 printf ("round ");
1088 switch ((control >> 10) & 3)
1089 {
1090 case 0: printf ("NEAREST; "); break;
1091 case 1: printf ("DOWN; "); break;
1092 case 2: printf ("UP; "); break;
1093 case 3: printf ("CHOP; "); break;
1094 }
1095 if (control & 0x3f)
1096 {
1097 printf ("mask:");
1098 if (control & 0x0001) printf (" INVALID");
1099 if (control & 0x0002) printf (" DENORM");
1100 if (control & 0x0004) printf (" DIVZ");
1101 if (control & 0x0008) printf (" OVERF");
1102 if (control & 0x0010) printf (" UNDERF");
1103 if (control & 0x0020) printf (" LOS");
1104 printf (";");
1105 }
1106 printf ("\n");
1107 if (control & 0xe080) printf ("warning: reserved bits on 0x%x\n",
1108 control & 0xe080);
1109}
1110
1111static
1112print_387_status_word (status)
1113 unsigned short status;
1114{
1115 printf ("status 0x%04x: ", status);
1116 if (status & 0xff)
1117 {
1118 printf ("exceptions:");
1119 if (status & 0x0001) printf (" INVALID");
1120 if (status & 0x0002) printf (" DENORM");
1121 if (status & 0x0004) printf (" DIVZ");
1122 if (status & 0x0008) printf (" OVERF");
1123 if (status & 0x0010) printf (" UNDERF");
1124 if (status & 0x0020) printf (" LOS");
1125 if (status & 0x0040) printf (" FPSTACK");
1126 printf ("; ");
1127 }
1128 printf ("flags: %d%d%d%d; ",
1129 (status & 0x4000) != 0,
1130 (status & 0x0400) != 0,
1131 (status & 0x0200) != 0,
1132 (status & 0x0100) != 0);
1133
1134 printf ("top %d\n", (status >> 11) & 7);
1135}
1136
1137static
1138print_387_status (status, ep)
1139 unsigned short status;
1140 struct env387 *ep;
1141{
1142 int i;
1143 int bothstatus;
1144 int top;
1145 int fpreg;
1146 unsigned char *p;
1147
1148 bothstatus = ((status != 0) && (ep->status != 0));
1149 if (status != 0)
1150 {
1151 if (bothstatus)
1152 printf ("u: ");
1153 print_387_status_word (status);
1154 }
1155
1156 if (ep->status != 0)
1157 {
1158 if (bothstatus)
1159 printf ("e: ");
1160 print_387_status_word (ep->status);
1161 }
1162
1163 print_387_control_word (ep->control);
1164 printf ("last exception: ");
1165 printf ("opcode 0x%x; ", ep->opcode);
1166 printf ("pc 0x%x:0x%x; ", ep->code_seg, ep->eip);
1167 printf ("operand 0x%x:0x%x\n", ep->operand_seg, ep->operand);
1168
1169 top = (ep->status >> 11) & 7;
1170
1171 printf ("regno tag msb lsb value\n");
1172 for (fpreg = 7; fpreg >= 0; fpreg--)
1173 {
1174 double val;
1175
1176 printf ("%s %d: ", fpreg == top ? "=>" : " ", fpreg);
1177
1178 switch ((ep->tag >> (fpreg * 2)) & 3)
1179 {
1180 case 0: printf ("valid "); break;
1181 case 1: printf ("zero "); break;
1182 case 2: printf ("trap "); break;
1183 case 3: printf ("empty "); break;
1184 }
1185 for (i = 9; i >= 0; i--)
1186 printf ("%02x", ep->regs[fpreg][i]);
1187
1188 i387_to_double (ep->regs[fpreg], (char *)&val);
1189 printf (" %g\n", val);
1190 }
1191 if (ep->r0)
1192 printf ("warning: reserved0 is 0x%x\n", ep->r0);
1193 if (ep->r1)
1194 printf ("warning: reserved1 is 0x%x\n", ep->r1);
1195 if (ep->r2)
1196 printf ("warning: reserved2 is 0x%x\n", ep->r2);
1197 if (ep->r3)
1198 printf ("warning: reserved3 is 0x%x\n", ep->r3);
1199}
1200
1201#ifndef U_FPSTATE
1202#define U_FPSTATE(u) u.u_fpstate
1203#endif
1204
1205i386_float_info ()
1206{
1207 struct user u; /* just for address computations */
1208 int i;
1209 /* fpstate defined in <sys/user.h> */
1210 struct fpstate *fpstatep;
1211 char buf[sizeof (struct fpstate) + 2 * sizeof (int)];
1212 unsigned int uaddr;
1213 char fpvalid;
1214 unsigned int rounded_addr;
1215 unsigned int rounded_size;
1216 extern int corechan;
1217 int skip;
1218
1219 uaddr = (char *)&u.u_fpvalid - (char *)&u;
1220 if (have_inferior_p())
1221 {
1222 unsigned int data;
1223 unsigned int mask;
1224
1225 rounded_addr = uaddr & -sizeof (int);
1226 data = ptrace (3, inferior_pid, rounded_addr, 0);
1227 mask = 0xff << ((uaddr - rounded_addr) * 8);
1228
1229 fpvalid = ((data & mask) != 0);
1230 }
1231 else
1232 {
1233 if (lseek (corechan, uaddr, 0) < 0)
1234 perror ("seek on core file");
1235 if (myread (corechan, &fpvalid, 1) < 0)
1236 perror ("read on core file");
1237
1238 }
1239
1240 if (fpvalid == 0)
1241 {
1242 printf ("no floating point status saved\n");
1243 return;
1244 }
1245
1246 uaddr = (char *)&U_FPSTATE(u) - (char *)&u;
1247 if (have_inferior_p ())
1248 {
1249 int *ip;
1250
1251 rounded_addr = uaddr & -sizeof (int);
1252 rounded_size = (((uaddr + sizeof (struct fpstate)) - uaddr) +
1253 sizeof (int) - 1) / sizeof (int);
1254 skip = uaddr - rounded_addr;
1255
1256 ip = (int *)buf;
1257 for (i = 0; i < rounded_size; i++)
1258 {
1259 *ip++ = ptrace (3, inferior_pid, rounded_addr, 0);
1260 rounded_addr += sizeof (int);
1261 }
1262 }
1263 else
1264 {
1265 if (lseek (corechan, uaddr, 0) < 0)
1266 perror_with_name ("seek on core file");
1267 if (myread (corechan, buf, sizeof (struct fpstate)) < 0)
1268 perror_with_name ("read from core file");
1269 skip = 0;
1270 }
1271
1272 fpstatep = (struct fpstate *)(buf + skip);
1273 print_387_status (fpstatep->status, (struct env387 *)fpstatep->state);
1274}
1275