1 /* Machine-dependent code which would otherwise be in inflow.c and core.c,
2 for GDB, the GNU debugger.
3 Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
4 This code is for the sparc cpu.
6 This file is part of GDB.
8 GDB is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 1, or (at your option)
13 GDB is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GDB; see the file COPYING. If not, write to
20 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
29 #include <sys/param.h>
33 #include <sys/ioctl.h>
36 #include <sys/ptrace.h>
37 #include <machine/reg.h>
45 extern int attach_flag
;
49 Error
, not_branch
, bicc
, bicca
, ba
, baa
, ticc
, ta
,
52 /* This function simply calls ptrace with the given arguments.
53 It exists so that all calls to ptrace are isolated in this
54 machine-dependent file. */
56 call_ptrace (request
, pid
, arg3
, arg4
)
57 int request
, pid
, arg3
, arg4
;
59 return ptrace (request
, pid
, arg3
, arg4
);
67 if (inferior_pid
== 0)
69 ptrace (8, inferior_pid
, 0, 0);
74 /* This is used when GDB is exiting. It gives less chance of error.*/
81 if (inferior_pid
== 0)
83 ptrace (8, inferior_pid
, 0, 0);
87 /* Simulate single-step ptrace call for sun4. Code written by Gary
88 Beihl (beihl@mcc.com). */
91 * Duplicated from breakpoint.c because (at least for now) this is a
92 * machine dependent routine.
94 static char break_insn
[] = BREAKPOINT
;
97 extern int stop_after_trap
, stop_after_attach
;
99 static CORE_ADDR next_pc
, npc4
, target
;
100 static int brknpc4
, brktrg
;
101 typedef char binsn_quantum
[sizeof break_insn
];
102 static binsn_quantum break_mem
[3];
104 /* Non-zero if we just simulated a single-step ptrace call. This is
105 needed because we cannot remove the breakpoints in the inferior
106 process until after the `wait' in `wait_for_inferior'. Used for
115 branch_type br
, isannulled();
118 next_pc
= read_register (NPC_REGNUM
);
119 npc4
= next_pc
+ 4; /* branch not taken */
123 /* Always set breakpoint for NPC. */
124 read_memory (next_pc
, break_mem
[0], sizeof break_insn
);
125 write_memory (next_pc
, break_insn
, sizeof break_insn
);
126 /* printf ("set break at %x\n",next_pc); */
128 pc
= read_register (PC_REGNUM
);
129 br
= isannulled (pc
, &target
);
130 brknpc4
= brktrg
= 0;
134 /* Conditional annulled branch will either end up at
135 npc (if taken) or at npc+4 (if not taken).
138 read_memory (npc4
, break_mem
[1], sizeof break_insn
);
139 write_memory (npc4
, break_insn
, sizeof break_insn
);
141 else if (br
== baa
&& target
!= next_pc
)
143 /* Unconditional annulled branch will always end up at
146 read_memory (target
, break_mem
[2], sizeof break_insn
);
147 write_memory (target
, break_insn
, sizeof break_insn
);
151 ptrace (7, inferior_pid
, 1, signal
);
157 /* Remove breakpoints */
158 write_memory (next_pc
, break_mem
[0], sizeof break_insn
);
162 write_memory (npc4
, break_mem
[1], sizeof break_insn
);
166 write_memory (target
, break_mem
[2], sizeof break_insn
);
172 /* Resume execution of the inferior process.
173 If STEP is nonzero, single-step it.
174 If SIGNAL is nonzero, give it that signal. */
177 resume (step
, signal
)
182 if (remote_debugging
)
183 remote_resume (step
, signal
);
186 /* Sparc doesn't have single step on ptrace */
188 single_step (signal
);
190 ptrace (7, inferior_pid
, 1, signal
);
192 perror_with_name ("ptrace");
198 /* Start debugging the process whose number is PID. */
205 ptrace (PTRACE_ATTACH
, pid
, 0, 0);
207 perror_with_name ("ptrace");
212 /* Stop debugging the process whose number is PID
213 and continue it with signal number SIGNAL.
214 SIGNAL = 0 means just continue it. */
221 ptrace (PTRACE_DETACH
, inferior_pid
, 1, signal
);
223 perror_with_name ("ptrace");
226 #endif /* ATTACH_DETACH */
229 fetch_inferior_registers ()
231 struct regs inferior_registers
;
232 struct fp_status inferior_fp_registers
;
233 extern char registers
[];
235 struct rwindow local_and_ins
;
237 if (remote_debugging
)
238 remote_fetch_registers (registers
);
241 ptrace (PTRACE_GETREGS
, inferior_pid
, &inferior_registers
);
242 ptrace (PTRACE_GETFPREGS
, inferior_pid
, &inferior_fp_registers
);
244 registers
[REGISTER_BYTE (0)] = 0;
245 bcopy (&inferior_registers
.r_g1
, ®isters
[REGISTER_BYTE (1)], 15 * 4);
246 bcopy (&inferior_fp_registers
, ®isters
[REGISTER_BYTE (FP0_REGNUM
)],
247 sizeof inferior_fp_registers
.fpu_fr
);
248 *(int *)®isters
[REGISTER_BYTE (PS_REGNUM
)] = inferior_registers
.r_ps
;
249 *(int *)®isters
[REGISTER_BYTE (PC_REGNUM
)] = inferior_registers
.r_pc
;
250 *(int *)®isters
[REGISTER_BYTE (NPC_REGNUM
)] = inferior_registers
.r_npc
;
251 *(int *)®isters
[REGISTER_BYTE (Y_REGNUM
)] = inferior_registers
.r_y
;
252 /* *(int *)®isters[REGISTER_BYTE (RP_REGNUM)] =
253 inferior_registers.r_o7 + 8;
254 bcopy (&inferior_fp_registers.Fpu_fsr,
255 ®isters[REGISTER_BYTE (FPS_REGNUM)],
256 sizeof (FPU_FSR_TYPE)); */
258 read_inferior_memory (inferior_registers
.r_sp
,
259 ®isters
[REGISTER_BYTE (16)],
264 /* Store our register values back into the inferior.
265 If REGNO is -1, do this for all registers.
266 Otherwise, REGNO specifies which register (so we can save time). */
269 store_inferior_registers (regno
)
272 struct regs inferior_registers
;
273 struct fp_status inferior_fp_registers
;
274 extern char registers
[];
276 if (remote_debugging
)
277 remote_store_registers (registers
);
280 int in_regs
= 1, in_fpregs
= 1, in_fparegs
, in_cpregs
= 1;
283 if (FP0_REGNUM
<= regno
&& regno
<= FP0_REGNUM
+ 32)
290 bcopy (®isters
[REGISTER_BYTE (1)],
291 &inferior_registers
.r_g1
, 15 * 4);
293 inferior_registers
.r_ps
=
294 *(int *)®isters
[REGISTER_BYTE (PS_REGNUM
)];
295 inferior_registers
.r_pc
=
296 *(int *)®isters
[REGISTER_BYTE (PC_REGNUM
)];
297 inferior_registers
.r_npc
=
298 *(int *)®isters
[REGISTER_BYTE (NPC_REGNUM
)];
299 inferior_registers
.r_y
=
300 *(int *)®isters
[REGISTER_BYTE (Y_REGNUM
)];
302 write_inferior_memory (*(int *)®isters
[REGISTER_BYTE (SP_REGNUM
)],
303 ®isters
[REGISTER_BYTE (16)],
308 bcopy (®isters
[REGISTER_BYTE (FP0_REGNUM
)],
309 &inferior_fp_registers
,
310 sizeof inferior_fp_registers
.fpu_fr
);
312 /* bcopy (®isters[REGISTER_BYTE (FPS_REGNUM)],
313 &inferior_fp_registers.Fpu_fsr,
314 sizeof (FPU_FSR_TYPE));
319 ptrace (PTRACE_SETREGS
, inferior_pid
, &inferior_registers
);
321 ptrace (PTRACE_SETFPREGS
, inferior_pid
, &inferior_fp_registers
);
325 /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
326 in the NEW_SUN_PTRACE case.
327 It ought to be straightforward. But it appears that writing did
328 not write the data that I specified. I cannot understand where
329 it got the data that it actually did write. */
331 /* Copy LEN bytes from inferior's memory starting at MEMADDR
332 to debugger memory starting at MYADDR.
333 On failure (cannot read from inferior, usually because address is out
334 of bounds) returns the value of errno. */
337 read_inferior_memory (memaddr
, myaddr
, len
)
343 /* Round starting address down to longword boundary. */
344 register CORE_ADDR addr
= memaddr
& - sizeof (int);
345 /* Round ending address up; get number of longwords that makes. */
347 = (((memaddr
+ len
) - addr
) + sizeof (int) - 1) / sizeof (int);
348 /* Allocate buffer of that many longwords. */
349 register int *buffer
= (int *) alloca (count
* sizeof (int));
352 /* Read all the longwords */
353 for (i
= 0; i
< count
; i
++, addr
+= sizeof (int))
356 if (remote_debugging
)
357 buffer
[i
] = remote_fetch_word (addr
);
359 buffer
[i
] = ptrace (1, inferior_pid
, addr
, 0);
364 /* Copy appropriate bytes out of the buffer. */
365 bcopy ((char *) buffer
+ (memaddr
& (sizeof (int) - 1)), myaddr
, len
);
369 /* Copy LEN bytes of data from debugger memory at MYADDR
370 to inferior's memory at MEMADDR.
371 On failure (cannot write the inferior)
372 returns the value of errno. */
375 write_inferior_memory (memaddr
, myaddr
, len
)
381 /* Round starting address down to longword boundary. */
382 register CORE_ADDR addr
= memaddr
& - sizeof (int);
383 /* Round ending address up; get number of longwords that makes. */
385 = (((memaddr
+ len
) - addr
) + sizeof (int) - 1) / sizeof (int);
386 /* Allocate buffer of that many longwords. */
387 register int *buffer
= (int *) alloca (count
* sizeof (int));
390 /* Fill start and end extra bytes of buffer with existing memory data. */
392 if (remote_debugging
)
393 buffer
[0] = remote_fetch_word (addr
);
395 buffer
[0] = ptrace (1, inferior_pid
, addr
, 0);
399 if (remote_debugging
)
401 = remote_fetch_word (addr
+ (count
- 1) * sizeof (int));
404 = ptrace (1, inferior_pid
,
405 addr
+ (count
- 1) * sizeof (int), 0);
408 /* Copy data to be written over corresponding part of buffer */
410 bcopy (myaddr
, (char *) buffer
+ (memaddr
& (sizeof (int) - 1)), len
);
412 /* Write the entire buffer. */
414 for (i
= 0; i
< count
; i
++, addr
+= sizeof (int))
417 if (remote_debugging
)
418 remote_store_word (addr
, buffer
[i
]);
420 ptrace (4, inferior_pid
, addr
, buffer
[i
]);
429 /* Machine-dependent code which would otherwise be in core.c */
430 /* Work with core dump and executable files, for GDB. */
433 #define N_TXTADDR(hdr) 0
434 #endif /* no N_TXTADDR */
437 #define N_DATADDR(hdr) hdr.a_text
438 #endif /* no N_DATADDR */
440 /* Non-zero if this is an object (.o) file, rather than an executable.
441 Distinguishing between the two is rarely necessary (and seems like
442 a hack, but there is no other way to get the text and data
443 addresses--N_TXTADDR should probably take care of
444 this, but it doesn't). */
445 /* This definition will not work
446 if someone decides to make ld preserve relocation info. */
447 #define IS_OBJECT_FILE(hdr) (hdr.a_trsize != 0)
449 /* Make COFF and non-COFF names for things a little more compatible
450 to reduce conditionals later. */
453 #define a_magic magic
458 #define AOUTHDR struct exec
462 extern char *sys_siglist
[];
464 /* Hook for `exec_file_command' command to call. */
466 extern void (*exec_file_display_hook
) ();
468 /* File names of core file and executable file. */
470 extern char *corefile
;
471 extern char *execfile
;
473 /* Descriptors on which core file and executable file are open.
474 Note that the execchan is closed when an inferior is created
475 and reopened if the inferior dies or is killed. */
480 /* Last modification time of executable file.
481 Also used in source.c to compare against mtime of a source file. */
483 extern int exec_mtime
;
485 /* Virtual addresses of bounds of the two areas of memory in the core file. */
487 extern CORE_ADDR data_start
;
488 extern CORE_ADDR data_end
;
489 extern CORE_ADDR stack_start
;
490 extern CORE_ADDR stack_end
;
492 /* Virtual addresses of bounds of two areas of memory in the exec file.
493 Note that the data area in the exec file is used only when there is no core file. */
495 extern CORE_ADDR text_start
;
496 extern CORE_ADDR text_end
;
498 extern CORE_ADDR exec_data_start
;
499 extern CORE_ADDR exec_data_end
;
501 /* Address in executable file of start of text area data. */
503 extern int text_offset
;
505 /* Address in executable file of start of data area data. */
507 extern int exec_data_offset
;
509 /* Address in core file of start of data area data. */
511 extern int data_offset
;
513 /* Address in core file of start of stack area data. */
515 extern int stack_offset
;
518 /* various coff data structures */
520 extern FILHDR file_hdr
;
521 extern SCNHDR text_hdr
;
522 extern SCNHDR data_hdr
;
524 #endif /* not COFF_FORMAT */
526 /* a.out header saved in core file. */
528 extern AOUTHDR core_aouthdr
;
530 /* a.out header of exec file. */
532 extern AOUTHDR exec_aouthdr
;
534 extern void validate_files ();
537 core_file_command (filename
, from_tty
)
542 extern char registers
[];
544 /* Discard all vestiges of any previous core file
545 and mark data and stack spaces as empty. */
557 stack_start
= STACK_END_ADDR
;
558 stack_end
= STACK_END_ADDR
;
560 /* Now, if a new core file was specified, open it and digest it. */
564 filename
= tilde_expand (filename
);
565 make_cleanup (free
, filename
);
567 if (have_inferior_p ())
568 error ("To look at a core file, you must kill the inferior with \"kill\".");
569 corechan
= open (filename
, O_RDONLY
, 0);
571 perror_with_name (filename
);
576 val
= myread (corechan
, &corestr
, sizeof corestr
);
578 perror_with_name (filename
);
579 if (corestr
.c_magic
!= CORE_MAGIC
)
580 error ("\"%s\" does not appear to be a core dump file (magic 0x%x, expected 0x%x)",
581 filename
, corestr
.c_magic
, (int) CORE_MAGIC
);
582 else if (sizeof (struct core
) != corestr
.c_len
)
583 error ("\"%s\" has an invalid struct core length (%d, expected %d)",
584 filename
, corestr
.c_len
, (int) sizeof (struct core
));
586 data_start
= exec_data_start
;
587 data_end
= data_start
+ corestr
.c_dsize
;
588 stack_start
= stack_end
- corestr
.c_ssize
;
589 data_offset
= sizeof corestr
;
590 stack_offset
= sizeof corestr
+ corestr
.c_dsize
;
592 /* G0 *always* holds 0. */
593 *(int *)®isters
[REGISTER_BYTE (0)] = 0;
594 /* The globals and output registers. */
596 bcopy (&corestr
.c_regs
.r_g1
, ((int *) registers
) + 1, 15 * 4);
597 *(int *)®isters
[REGISTER_BYTE (PS_REGNUM
)] = corestr
.c_regs
.r_ps
;
598 *(int *)®isters
[REGISTER_BYTE (PC_REGNUM
)] = corestr
.c_regs
.r_pc
;
599 *(int *)®isters
[REGISTER_BYTE (NPC_REGNUM
)] = corestr
.c_regs
.r_npc
;
600 *(int *)®isters
[REGISTER_BYTE (Y_REGNUM
)] = corestr
.c_regs
.r_y
;
602 /* My best guess at where to get the locals and input
603 registers is exactly where they usually are, right above
604 the stack pointer. If the core dump was caused by a bus
605 writing off the stack pointer (as is possible) then this
606 won't work, but it's worth the try. */
610 sp
= *(int *)®isters
[REGISTER_BYTE (SP_REGNUM
)];
611 lseek (corechan
, sp
- stack_start
+ stack_offset
, L_SET
);
612 if (16 * 4 != myread (corechan
,
613 ®isters
[REGISTER_BYTE (16)],
615 /* fprintf so user can still use gdb */
616 fprintf (stderr
, "Couldn't read input and local registers from core file\n");
619 bcopy (corestr
.c_fpu
.fpu_regs
,
620 ®isters
[REGISTER_BYTE (FP0_REGNUM
)],
621 sizeof corestr
.c_fpu
.fpu_regs
);
623 bcopy (&corestr
.c_fpu
.fpu_fsr
,
624 ®isters
[REGISTER_BYTE (FPS_REGNUM
)],
625 sizeof (FPU_FSR_TYPE
));
628 bcopy (&corestr
.c_aouthdr
, &core_aouthdr
, sizeof (struct exec
));
630 printf ("Core file is from \"%s\".\n", corestr
.c_cmdname
);
631 if (corestr
.c_signo
> 0)
632 printf ("Program terminated with signal %d, %s.\n",
634 corestr
.c_signo
< NSIG
635 ? sys_siglist
[corestr
.c_signo
]
638 if (filename
[0] == '/')
639 corefile
= savestring (filename
, strlen (filename
));
642 corefile
= concat (current_directory
, "/", filename
);
645 set_current_frame ( create_new_frame (read_register (FP_REGNUM
),
647 select_frame (get_current_frame (), 0);
651 printf ("No core file now.\n");
655 exec_file_command (filename
, from_tty
)
661 /* Eliminate all traces of old exec file.
662 Mark text segment as empty. */
668 data_end
-= exec_data_start
;
677 /* Now open and digest the file the user requested, if any. */
681 filename
= tilde_expand (filename
);
682 make_cleanup (free
, filename
);
684 execchan
= openp (getenv ("PATH"), 1, filename
, O_RDONLY
, 0,
687 perror_with_name (filename
);
694 if (read_file_hdr (execchan
, &file_hdr
) < 0)
695 error ("\"%s\": not in executable format.", execfile
);
697 aout_hdrsize
= file_hdr
.f_opthdr
;
698 num_sections
= file_hdr
.f_nscns
;
700 if (read_aout_hdr (execchan
, &exec_aouthdr
, aout_hdrsize
) < 0)
701 error ("\"%s\": can't read optional aouthdr", execfile
);
703 if (read_section_hdr (execchan
, _TEXT
, &text_hdr
, num_sections
,
705 error ("\"%s\": can't read text section header", execfile
);
707 if (read_section_hdr (execchan
, _DATA
, &data_hdr
, num_sections
,
709 error ("\"%s\": can't read data section header", execfile
);
711 text_start
= exec_aouthdr
.text_start
;
712 text_end
= text_start
+ exec_aouthdr
.tsize
;
713 text_offset
= text_hdr
.s_scnptr
;
714 exec_data_start
= exec_aouthdr
.data_start
;
715 exec_data_end
= exec_data_start
+ exec_aouthdr
.dsize
;
716 exec_data_offset
= data_hdr
.s_scnptr
;
717 data_start
= exec_data_start
;
718 data_end
+= exec_data_start
;
719 exec_mtime
= file_hdr
.f_timdat
;
721 #else /* not COFF_FORMAT */
724 val
= myread (execchan
, &exec_aouthdr
, sizeof (AOUTHDR
));
727 perror_with_name (filename
);
730 IS_OBJECT_FILE (exec_aouthdr
) ? 0 : N_TXTADDR (exec_aouthdr
);
731 exec_data_start
= IS_OBJECT_FILE (exec_aouthdr
)
732 ? exec_aouthdr
.a_text
: N_DATADDR (exec_aouthdr
);
733 text_offset
= N_TXTOFF (exec_aouthdr
);
734 exec_data_offset
= N_TXTOFF (exec_aouthdr
) + exec_aouthdr
.a_text
;
736 text_end
= text_start
+ exec_aouthdr
.a_text
;
737 exec_data_end
= exec_data_start
+ exec_aouthdr
.a_data
;
738 data_start
= exec_data_start
;
739 data_end
+= exec_data_start
;
741 fstat (execchan
, &st_exec
);
742 exec_mtime
= st_exec
.st_mtime
;
744 #endif /* not COFF_FORMAT */
749 printf ("No exec file now.\n");
751 /* Tell display code (if any) about the changed file name. */
752 if (exec_file_display_hook
)
753 (*exec_file_display_hook
) (filename
);
757 * Find the pc saved in frame FRAME.
760 frame_saved_pc (frame
)
765 /* If it's at the bottom, the return value's stored in i7/rp */
766 if (get_current_frame () == frame
)
767 prev_pc
= GET_RWINDOW_REG (read_register (SP_REGNUM
), rw_in
[7]);
769 /* Wouldn't this always work? This would allow this routine to
770 be completely a macro. */
771 prev_pc
= GET_RWINDOW_REG (frame
->bottom
, rw_in
[7]);
773 return PC_ADJUST (prev_pc
);
777 * Since an individual frame in the frame cache is defined by two
778 * arguments (a frame pointer and a stack pointer), we need two
779 * arguments to get info for an arbitrary stack frame. This routine
780 * takes two arguments and makes the cached frames look as if these
781 * two arguments defined a frame on the cache. This allows the rest
782 * of info frame to extract the important arguments without
786 setup_arbitrary_frame (frame
, stack
)
787 FRAME_ADDR frame
, stack
;
789 struct frame_info
*fci
;
790 FRAME fid
= create_new_frame (frame
, 0);
793 fatal ("internal: create_new_frame returned invalid frame id");
800 /* This code was written by Gary Beihl (beihl@mcc.com).
801 It was modified by Michael Tiemann (tiemann@corto.inria.fr). */
803 struct command_line
*get_breakpoint_commands ();
806 * This routine appears to be passed a size by which to increase the
807 * stack. It then executes a save instruction in the inferior to
808 * increase the stack by this amount. Only the register window system
809 * should be affected by this; the program counter & etc. will not be.
811 * This instructions used for this purpose are:
813 * sethi %hi(0x0),g1 *
816 * sethi %hi(0x0),g1 *
819 * sethi %hi(0x0),g0 (nop)
821 * I presume that these set g1 to be the negative of the size, do a
822 * save (putting the stack pointer at sp - size) and restore the
823 * original contents of g1. A * indicates that the actual value of
824 * the instruction is modified below.
826 static int save_insn_opcodes
[] = {
827 0x03000000, 0x82007ee0, 0x9de38001, 0x03000000,
828 0x82007ee0, 0x91d02001, 0x01000000 };
830 /* Neither do_save_insn or do_restore_insn save stack configuration
831 (since the stack is in an indeterminate state through the call to
832 each of them); that responsibility of the routine which calls them. */
838 int g1
= read_register (1);
839 CORE_ADDR sp
= read_register (SP_REGNUM
);
840 CORE_ADDR pc
= read_register (PC_REGNUM
);
841 CORE_ADDR npc
= read_register (NPC_REGNUM
);
842 CORE_ADDR fake_pc
= sp
- sizeof (save_insn_opcodes
);
843 struct inferior_status inf_status
;
845 save_inferior_status (&inf_status
, 0); /* Don't restore stack info */
849 save_insn_opcodes
[0] = 0x03000000 | ((-size
>> 10) & 0x3fffff);
850 save_insn_opcodes
[1] = 0x82006000 | (-size
& 0x3ff);
851 save_insn_opcodes
[3] = 0x03000000 | ((g1
>> 10) & 0x3fffff);
852 save_insn_opcodes
[4] = 0x82006000 | (g1
& 0x3ff);
853 write_memory (fake_pc
, save_insn_opcodes
, sizeof (save_insn_opcodes
));
855 clear_proceed_status ();
857 proceed (fake_pc
, 0, 0);
859 write_register (PC_REGNUM
, pc
);
860 write_register (NPC_REGNUM
, npc
);
861 restore_inferior_status (&inf_status
);
865 * This routine takes a program counter value. It restores the
866 * register window system to the frame above the current one, and sets
867 * the pc and npc to the correct values.
870 /* The following insns translate to:
874 sethi %hi(0x0), g0 */
876 static int restore_insn_opcodes
[] = { 0x81e80000, 0x91d02001, 0x01000000 };
882 CORE_ADDR sp
= read_register (SP_REGNUM
);
883 CORE_ADDR npc
= pc
+ 4;
884 CORE_ADDR fake_pc
= sp
- sizeof (restore_insn_opcodes
);
885 struct inferior_status inf_status
;
887 save_inferior_status (&inf_status
, 0); /* Don't restore stack info */
892 write_memory (fake_pc
, restore_insn_opcodes
, sizeof (restore_insn_opcodes
));
894 clear_proceed_status ();
896 proceed (fake_pc
, 0, 0);
898 write_register (PC_REGNUM
, pc
);
899 write_register (NPC_REGNUM
, npc
);
900 restore_inferior_status (&inf_status
);
904 * This routine should be more specific in it's actions; making sure
905 * that it uses the same register in the initial prologue section.
913 unsigned long int code
;
919 unsigned int imm22
:22;
928 unsigned int simm13
:13;
934 x
.i
= read_memory_integer (pc
, 4);
936 /* Recognize the `sethi' insn and record its destination. */
937 if (x
.sethi
.op
== 0 && x
.sethi
.op2
== 4)
941 x
.i
= read_memory_integer (pc
, 4);
944 /* Recognize an add immediate value to register to either %g1 or
945 the destination register recorded above. Actually, this might
946 well recognize several different arithmetic operations. */
947 if (x
.add
.op
== 2 && x
.add
.i
&& (x
.add
.rd
== 1 || x
.add
.rd
== dest
))
950 x
.i
= read_memory_integer (pc
, 4);
953 /* This recognizes any SAVE insn. But why do the XOR and then
954 the compare? That's identical to comparing against 60 (as long
955 as there isn't any sign extension). */
956 if (x
.add
.op
== 2 && (x
.add
.op3
^ 32) == 28)
959 x
.i
= read_memory_integer (pc
, 4);
962 /* Now we need to recognize stores into the frame from the input
963 registers. This recognizes all non alternate stores of input
964 register, into a location offset from the frame pointer. */
966 && (x
.add
.op3
& 0x3c) == 4 /* Store, non-alternate. */
967 && (x
.add
.rd
& 0x18) == 0x18 /* Input register. */
968 && x
.add
.i
/* Immediate mode. */
969 && x
.add
.rs1
== 30 /* Off of frame pointer. */
970 /* Into reserved stack space. */
971 && x
.add
.simm13
>= 0x44
972 && x
.add
.simm13
< 0x5b)
975 x
.i
= read_memory_integer (pc
, 4);
980 /* Check instruction at ADDR to see if it is an annulled branch.
981 All other instructions will go to NPC or will trap.
982 Set *TARGET if we find a canidate branch; set to zero if not. */
985 isannulled (addr
, target
)
986 CORE_ADDR addr
, *target
;
988 branch_type val
= not_branch
;
989 long int offset
; /* Must be signed for sign-extend. */
992 unsigned long int code
;
999 unsigned int disp22
:22;
1004 insn
.code
= read_memory_integer (addr
, 4);
1007 && (insn
.b
.op2
== 2 || insn
.b
.op2
== 6 || insn
.b
.op2
== 7))
1009 if (insn
.b
.cond
== 8)
1010 val
= insn
.b
.a
? baa
: ba
;
1012 val
= insn
.b
.a
? bicca
: bicc
;
1013 offset
= 4 * ((int) (insn
.b
.disp22
<< 10) >> 10);
1014 *target
= addr
+ offset
;