aboutsummaryrefslogtreecommitdiff
path: root/gdb/RCS/sparc-dep.c,v
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/RCS/sparc-dep.c,v')
-rw-r--r--gdb/RCS/sparc-dep.c,v1091
1 files changed, 0 insertions, 1091 deletions
diff --git a/gdb/RCS/sparc-dep.c,v b/gdb/RCS/sparc-dep.c,v
deleted file mode 100644
index 8178e00..0000000
--- a/gdb/RCS/sparc-dep.c,v
+++ /dev/null
@@ -1,1091 +0,0 @@
-head 1.3;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.3
-date 89.04.04.21.31.02; author gnu; state Exp;
-branches ;
-next 1.2;
-
-1.2
-date 89.02.10.01.47.27; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.02.10.01.46.36; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.3
-log
-@Fix handling of annulled branches in single step. "b foo; bcc,a bar"
-annuls the instruction at foo, not just after the bcc,a. Also,
-handle CBcc (coprocessor) annulled branch, and improve doc.
-@
-text
-@/* Machine-dependent code which would otherwise be in inflow.c and core.c,
- for GDB, the GNU debugger.
- Copyright (C) 1986, 1987 Free Software Foundation, Inc.
- This code is for the sparc cpu.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-#include "defs.h"
-#include "param.h"
-#include "frame.h"
-#include "inferior.h"
-#include "obstack.h"
-#include "sparc-opcode.h"
-#include "gdbcore.h"
-
-#include <stdio.h>
-#include <sys/param.h>
-#include <sys/dir.h>
-#include <sys/user.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-
-#include <a.out.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/core.h>
-
-extern int errno;
-extern int attach_flag;
-
-/* This function simply calls ptrace with the given arguments.
- It exists so that all calls to ptrace are isolated in this
- machine-dependent file. */
-int
-call_ptrace (request, pid, arg3, arg4)
- int request, pid, arg3, arg4;
-{
- return ptrace (request, pid, arg3, arg4);
-}
-
-void
-kill_inferior ()
-{
- if (remote_debugging)
- return;
- if (inferior_pid == 0)
- return;
- ptrace (8, inferior_pid, 0, 0);
- wait (0);
- inferior_died ();
-}
-
-/* This is used when GDB is exiting. It gives less chance of error.*/
-
-void
-kill_inferior_fast ()
-{
- if (remote_debugging)
- return;
- if (inferior_pid == 0)
- return;
- ptrace (8, inferior_pid, 0, 0);
- wait (0);
-}
-
-/* Simulate single-step ptrace call for sun4. Code written by Gary
- Beihl (beihl@@mcc.com). */
-
-/*
- * Duplicated from breakpoint.c because (at least for now) this is a
- * machine dependent routine.
- */
-static char break_insn[] = BREAKPOINT;
-
-/* From infrun.c */
-extern int stop_after_trap, stop_after_attach;
-
-static CORE_ADDR next_pc, npc4, target;
-static int brknpc4, brktrg;
-typedef char binsn_quantum[sizeof break_insn];
-static binsn_quantum break_mem[3];
-
-/* Non-zero if we just simulated a single-step ptrace call. This is
- needed because we cannot remove the breakpoints in the inferior
- process until after the `wait' in `wait_for_inferior'. Used for
- sun4. */
-
-int one_stepped;
-
-void
-single_step (signal)
- int signal;
-{
- branch_type br, isannulled();
- CORE_ADDR pc;
-
- next_pc = read_register (NPC_REGNUM);
- npc4 = next_pc + 4; /* branch not taken */
-
- if (!one_stepped)
- {
- /* Always set breakpoint for NPC. */
- read_memory (next_pc, break_mem[0], sizeof break_insn);
- write_memory (next_pc, break_insn, sizeof break_insn);
- /* printf ("set break at %x\n",next_pc); */
-
- pc = read_register (PC_REGNUM);
- br = isannulled (pc, &target);
- brknpc4 = brktrg = 0;
-
- if (br == bicca)
- {
- /* Conditional annulled branch will either end up at
- npc (if taken) or at npc+4 (if not taken). Trap npc+4. */
- brknpc4 = 1;
- read_memory (npc4, break_mem[1], sizeof break_insn);
- write_memory (npc4, break_insn, sizeof break_insn);
- }
- else if (br == baa && target != next_pc)
- {
- /* Unconditional annulled branch will always end up at
- the target. */
- brktrg = 1;
- read_memory (target, break_mem[2], sizeof break_insn);
- write_memory (target, break_insn, sizeof break_insn);
- }
-
- /* Let it go */
- ptrace (7, inferior_pid, 1, signal);
- one_stepped = 1;
- return;
- }
- else
- {
- /* Remove breakpoints */
- write_memory (next_pc, break_mem[0], sizeof break_insn);
-
- if (brknpc4)
- {
- write_memory (npc4, break_mem[1], sizeof break_insn);
- }
- if (brktrg)
- {
- write_memory (target, break_mem[2], sizeof break_insn);
- }
- one_stepped = 0;
- }
-}
-
-/* Resume execution of the inferior process.
- If STEP is nonzero, single-step it.
- If SIGNAL is nonzero, give it that signal. */
-
-void
-resume (step, signal)
- int step;
- int signal;
-{
- errno = 0;
- if (remote_debugging)
- remote_resume (step, signal);
- else
- {
- /* Sparc doesn't have single step on ptrace */
- if (step)
- single_step (signal);
- else
- ptrace (7, inferior_pid, 1, signal);
- if (errno)
- perror_with_name ("ptrace");
- }
-}
-
-#ifdef ATTACH_DETACH
-
-/* Start debugging the process whose number is PID. */
-
-int
-attach (pid)
- int pid;
-{
- errno = 0;
- ptrace (PTRACE_ATTACH, pid, 0, 0);
- if (errno)
- perror_with_name ("ptrace");
- attach_flag = 1;
- return pid;
-}
-
-/* Stop debugging the process whose number is PID
- and continue it with signal number SIGNAL.
- SIGNAL = 0 means just continue it. */
-
-void
-detach (signal)
- int signal;
-{
- errno = 0;
- ptrace (PTRACE_DETACH, inferior_pid, 1, signal);
- if (errno)
- perror_with_name ("ptrace");
- attach_flag = 0;
-}
-#endif /* ATTACH_DETACH */
-
-void
-fetch_inferior_registers ()
-{
- struct regs inferior_registers;
- struct fp_status inferior_fp_registers;
- extern char registers[];
- int cwp;
- struct rwindow local_and_ins;
-
- if (remote_debugging)
- remote_fetch_registers (registers);
- else
- {
- ptrace (PTRACE_GETREGS, inferior_pid, &inferior_registers);
- ptrace (PTRACE_GETFPREGS, inferior_pid, &inferior_fp_registers);
-
- registers[REGISTER_BYTE (0)] = 0;
- bcopy (&inferior_registers.r_g1, &registers[REGISTER_BYTE (1)], 15 * 4);
- bcopy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
- sizeof inferior_fp_registers.fpu_fr);
- *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
- *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
- *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc;
- *(int *)&registers[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y;
-/* *(int *)&registers[REGISTER_BYTE (RP_REGNUM)] =
- inferior_registers.r_o7 + 8;
- bcopy (&inferior_fp_registers.Fpu_fsr,
- &registers[REGISTER_BYTE (FPS_REGNUM)],
- sizeof (FPU_FSR_TYPE)); */
-
- read_inferior_memory (inferior_registers.r_sp,
- &registers[REGISTER_BYTE (16)],
- 16*4);
- }
-}
-
-/* Store our register values back into the inferior.
- If REGNO is -1, do this for all registers.
- Otherwise, REGNO specifies which register (so we can save time). */
-
-void
-store_inferior_registers (regno)
- int regno;
-{
- struct regs inferior_registers;
- struct fp_status inferior_fp_registers;
- extern char registers[];
-
- if (remote_debugging)
- remote_store_registers (registers);
- else
- {
- int in_regs = 1, in_fpregs = 1, in_fparegs, in_cpregs = 1;
-
- if (regno >= 0)
- if (FP0_REGNUM <= regno && regno <= FP0_REGNUM + 32)
- in_regs = 0;
- else
- in_fpregs = 0;
-
- if (in_regs)
- {
- bcopy (&registers[REGISTER_BYTE (1)],
- &inferior_registers.r_g1, 15 * 4);
-
- inferior_registers.r_ps =
- *(int *)&registers[REGISTER_BYTE (PS_REGNUM)];
- inferior_registers.r_pc =
- *(int *)&registers[REGISTER_BYTE (PC_REGNUM)];
- inferior_registers.r_npc =
- *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)];
- inferior_registers.r_y =
- *(int *)&registers[REGISTER_BYTE (Y_REGNUM)];
-
- write_inferior_memory (*(int *)&registers[REGISTER_BYTE (SP_REGNUM)],
- &registers[REGISTER_BYTE (16)],
- 16*4);
- }
- if (in_fpregs)
- {
- bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)],
- &inferior_fp_registers,
- sizeof inferior_fp_registers.fpu_fr);
-
- /* bcopy (&registers[REGISTER_BYTE (FPS_REGNUM)],
- &inferior_fp_registers.Fpu_fsr,
- sizeof (FPU_FSR_TYPE));
- ****/
- }
-
- if (in_regs)
- ptrace (PTRACE_SETREGS, inferior_pid, &inferior_registers);
- if (in_fpregs)
- ptrace (PTRACE_SETFPREGS, inferior_pid, &inferior_fp_registers);
- }
-}
-
-/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
- in the NEW_SUN_PTRACE case.
- It ought to be straightforward. But it appears that writing did
- not write the data that I specified. I cannot understand where
- it got the data that it actually did write. */
-
-/* Copy LEN bytes from inferior's memory starting at MEMADDR
- to debugger memory starting at MYADDR.
- On failure (cannot read from inferior, usually because address is out
- of bounds) returns the value of errno. */
-
-int
-read_inferior_memory (memaddr, myaddr, len)
- CORE_ADDR memaddr;
- char *myaddr;
- int len;
-{
- register int i;
- /* Round starting address down to longword boundary. */
- register CORE_ADDR addr = memaddr & - sizeof (int);
- /* Round ending address up; get number of longwords that makes. */
- register int count
- = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
- /* Allocate buffer of that many longwords. */
- register int *buffer = (int *) alloca (count * sizeof (int));
- extern int errno;
-
- /* Read all the longwords */
- for (i = 0; i < count; i++, addr += sizeof (int))
- {
- errno = 0;
- if (remote_debugging)
- buffer[i] = remote_fetch_word (addr);
- else
- buffer[i] = ptrace (1, inferior_pid, addr, 0);
- if (errno)
- return errno;
- }
-
- /* Copy appropriate bytes out of the buffer. */
- bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
- return 0;
-}
-
-/* Copy LEN bytes of data from debugger memory at MYADDR
- to inferior's memory at MEMADDR.
- On failure (cannot write the inferior)
- returns the value of errno. */
-
-int
-write_inferior_memory (memaddr, myaddr, len)
- CORE_ADDR memaddr;
- char *myaddr;
- int len;
-{
- register int i;
- /* Round starting address down to longword boundary. */
- register CORE_ADDR addr = memaddr & - sizeof (int);
- /* Round ending address up; get number of longwords that makes. */
- register int count
- = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
- /* Allocate buffer of that many longwords. */
- register int *buffer = (int *) alloca (count * sizeof (int));
- extern int errno;
-
- /* Fill start and end extra bytes of buffer with existing memory data. */
-
- if (remote_debugging)
- buffer[0] = remote_fetch_word (addr);
- else
- buffer[0] = ptrace (1, inferior_pid, addr, 0);
-
- if (count > 1)
- {
- if (remote_debugging)
- buffer[count - 1]
- = remote_fetch_word (addr + (count - 1) * sizeof (int));
- else
- buffer[count - 1]
- = ptrace (1, inferior_pid,
- addr + (count - 1) * sizeof (int), 0);
- }
-
- /* Copy data to be written over corresponding part of buffer */
-
- bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
-
- /* Write the entire buffer. */
-
- for (i = 0; i < count; i++, addr += sizeof (int))
- {
- errno = 0;
- if (remote_debugging)
- remote_store_word (addr, buffer[i]);
- else
- ptrace (4, inferior_pid, addr, buffer[i]);
- if (errno)
- return errno;
- }
-
- return 0;
-}
-
-
-/* Machine-dependent code which would otherwise be in core.c */
-/* Work with core dump and executable files, for GDB. */
-
-/* Recognize COFF format systems because a.out.h defines AOUTHDR. */
-#ifdef AOUTHDR
-#define COFF_FORMAT
-#endif
-
-#ifndef N_TXTADDR
-#define N_TXTADDR(hdr) 0
-#endif /* no N_TXTADDR */
-
-#ifndef N_DATADDR
-#define N_DATADDR(hdr) hdr.a_text
-#endif /* no N_DATADDR */
-
-/* Make COFF and non-COFF names for things a little more compatible
- to reduce conditionals later. */
-
-#ifdef COFF_FORMAT
-#define a_magic magic
-#endif
-
-#ifndef COFF_FORMAT
-#define AOUTHDR struct exec
-#endif
-
-extern char *sys_siglist[];
-
-/* Hook for `exec_file_command' command to call. */
-
-extern void (*exec_file_display_hook) ();
-
-#ifdef COFF_FORMAT
-/* various coff data structures */
-
-extern FILHDR file_hdr;
-extern SCNHDR text_hdr;
-extern SCNHDR data_hdr;
-
-#endif /* not COFF_FORMAT */
-
-/* a.out header saved in core file. */
-
-extern AOUTHDR core_aouthdr;
-
-/* a.out header of exec file. */
-
-extern AOUTHDR exec_aouthdr;
-
-extern void validate_files ();
-
-void
-core_file_command (filename, from_tty)
- char *filename;
- int from_tty;
-{
- int val;
- extern char registers[];
-
- /* Discard all vestiges of any previous core file
- and mark data and stack spaces as empty. */
-
- if (corefile)
- free (corefile);
- corefile = 0;
-
- if (corechan >= 0)
- close (corechan);
- corechan = -1;
-
- data_start = 0;
- data_end = 0;
- stack_start = STACK_END_ADDR;
- stack_end = STACK_END_ADDR;
-
- /* Now, if a new core file was specified, open it and digest it. */
-
- if (filename)
- {
- if (have_inferior_p ())
- error ("To look at a core file, you must kill the inferior with \"kill\".");
- corechan = open (filename, O_RDONLY, 0);
- if (corechan < 0)
- perror_with_name (filename);
-
- {
- struct core corestr;
-
- val = myread (corechan, &corestr, sizeof corestr);
- if (val < 0)
- perror_with_name (filename);
- if (corestr.c_magic != CORE_MAGIC)
- error ("\"%s\" does not appear to be a core dump file (magic 0x%x, expected 0x%x)",
- filename, corestr.c_magic, (int) CORE_MAGIC);
- else if (sizeof (struct core) != corestr.c_len)
- error ("\"%s\" has an invalid struct core length (%d, expected %d)",
- filename, corestr.c_len, (int) sizeof (struct core));
-
- /* Note that data_start and data_end don't depend on the exec file */
- data_start = N_DATADDR (corestr.c_aouthdr);
- data_end = data_start + corestr.c_dsize;
- stack_start = stack_end - corestr.c_ssize;
- data_offset = sizeof corestr;
- stack_offset = sizeof corestr + corestr.c_dsize;
-
- /* G0 *always* holds 0. */
- *(int *)&registers[REGISTER_BYTE (0)] = 0;
- /* The globals and output registers. */
-
- bcopy (&corestr.c_regs.r_g1, ((int *) registers) + 1, 15 * 4);
- *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = corestr.c_regs.r_ps;
- *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = corestr.c_regs.r_pc;
- *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)] = corestr.c_regs.r_npc;
- *(int *)&registers[REGISTER_BYTE (Y_REGNUM)] = corestr.c_regs.r_y;
-
- /* My best guess at where to get the locals and input
- registers is exactly where they usually are, right above
- the stack pointer. If the core dump was caused by a bus
- writing off the stack pointer (as is possible) then this
- won't work, but it's worth the try. */
- {
- int sp;
-
- sp = *(int *)&registers[REGISTER_BYTE (SP_REGNUM)];
- lseek (corechan, sp - stack_start + stack_offset, L_SET);
- if (16 * 4 != myread (corechan,
- &registers[REGISTER_BYTE (16)],
- 16 * 4))
- /* fprintf so user can still use gdb */
- fprintf (stderr, "Couldn't read input and local registers from core file\n");
- }
-
- bcopy (corestr.c_fpu.fpu_regs,
- &registers[REGISTER_BYTE (FP0_REGNUM)],
- sizeof corestr.c_fpu.fpu_regs);
-#ifdef FPU
- bcopy (&corestr.c_fpu.fpu_fsr,
- &registers[REGISTER_BYTE (FPS_REGNUM)],
- sizeof (FPU_FSR_TYPE));
-#endif
-
- bcopy (&corestr.c_aouthdr, &core_aouthdr, sizeof (struct exec));
-
- printf ("Core file is from \"%s\".\n", corestr.c_cmdname);
- if (corestr.c_signo > 0)
- printf ("Program terminated with signal %d, %s.\n",
- corestr.c_signo,
- corestr.c_signo < NSIG
- ? sys_siglist[corestr.c_signo]
- : "(undocumented)");
- }
- if (filename[0] == '/')
- corefile = savestring (filename, strlen (filename));
- else
- {
- corefile = concat (current_directory, "/", filename);
- }
-
- set_current_frame ( create_new_frame (read_register (FP_REGNUM),
- read_pc ()));
- select_frame (get_current_frame (), 0);
- validate_files ();
- }
- else if (from_tty)
- printf ("No core file now.\n");
-}
-
-void
-exec_file_command (filename, from_tty)
- char *filename;
- int from_tty;
-{
- int val;
-
- /* Eliminate all traces of old exec file.
- Mark text segment as empty. */
-
- if (execfile)
- free (execfile);
- execfile = 0;
- text_start = 0;
- text_end = 0;
- exec_data_start = 0;
- exec_data_end = 0;
- if (execchan >= 0)
- close (execchan);
- execchan = -1;
-
- /* Now open and digest the file the user requested, if any. */
-
- if (filename)
- {
- execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
- &execfile);
- if (execchan < 0)
- perror_with_name (filename);
-
-#ifdef COFF_FORMAT
- {
- int aout_hdrsize;
- int num_sections;
-
- if (read_file_hdr (execchan, &file_hdr) < 0)
- error ("\"%s\": not in executable format.", execfile);
-
- aout_hdrsize = file_hdr.f_opthdr;
- num_sections = file_hdr.f_nscns;
-
- if (read_aout_hdr (execchan, &exec_aouthdr, aout_hdrsize) < 0)
- error ("\"%s\": can't read optional aouthdr", execfile);
-
- if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections) < 0)
- error ("\"%s\": can't read text section header", execfile);
-
- if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0)
- error ("\"%s\": can't read data section header", execfile);
-
- text_start = exec_aouthdr.text_start;
- text_end = text_start + exec_aouthdr.tsize;
- text_offset = text_hdr.s_scnptr;
- exec_data_start = exec_aouthdr.data_start;
- exec_data_end = exec_data_start + exec_aouthdr.dsize;
- exec_data_offset = data_hdr.s_scnptr;
- exec_mtime = file_hdr.f_timdat;
- }
-#else /* not COFF_FORMAT */
- {
- struct stat st_exec;
- val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR));
-
- if (val < 0)
- perror_with_name (filename);
-
- text_start = N_TXTADDR (exec_aouthdr);
- exec_data_start = N_DATADDR (exec_aouthdr);
- text_offset = N_TXTOFF (exec_aouthdr);
- exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
-
- text_end = text_start + exec_aouthdr.a_text;
- exec_data_end = exec_data_start + exec_aouthdr.a_data;
-
- fstat (execchan, &st_exec);
- exec_mtime = st_exec.st_mtime;
- }
-#endif /* not COFF_FORMAT */
-
- validate_files ();
- }
- else if (from_tty)
- printf ("No exec file now.\n");
-
- /* Tell display code (if any) about the changed file name. */
- if (exec_file_display_hook)
- (*exec_file_display_hook) (filename);
-}
-
-/*
- * Find the pc saved in frame FRAME.
- */
-CORE_ADDR
-frame_saved_pc (frame)
- FRAME frame;
-{
- CORE_ADDR prev_pc;
-
- /* If it's at the bottom, the return value's stored in i7/rp */
- if (get_current_frame () == frame)
- prev_pc = GET_RWINDOW_REG (read_register (SP_REGNUM), rw_in[7]);
- else
- /* Wouldn't this always work? This would allow this routine to
- be completely a macro. */
- prev_pc = GET_RWINDOW_REG (frame->bottom, rw_in[7]);
-
- return PC_ADJUST (prev_pc);
-}
-
-/*
- * Since an individual frame in the frame cache is defined by two
- * arguments (a frame pointer and a stack pointer), we need two
- * arguments to get info for an arbitrary stack frame. This routine
- * takes two arguments and makes the cached frames look as if these
- * two arguments defined a frame on the cache. This allows the rest
- * of info frame to extract the important arguments without
- * difficulty.
- */
-FRAME
-setup_arbitrary_frame (frame, stack)
- FRAME_ADDR frame, stack;
-{
- struct frame_info *fci;
- FRAME fid = create_new_frame (frame, 0);
-
- if (!fid)
- fatal ("internal: create_new_frame returned invalid frame id");
-
- fid->bottom = stack;
-
- return fid;
-}
-
-/* This code was written by Gary Beihl (beihl@@mcc.com).
- It was modified by Michael Tiemann (tiemann@@corto.inria.fr). */
-
-struct command_line *get_breakpoint_commands ();
-
-/*
- * This routine appears to be passed a size by which to increase the
- * stack. It then executes a save instruction in the inferior to
- * increase the stack by this amount. Only the register window system
- * should be affected by this; the program counter & etc. will not be.
- *
- * This instructions used for this purpose are:
- *
- * sethi %hi(0x0),g1 *
- * add g1,0x1ee0,g1 *
- * save sp,g1,sp
- * sethi %hi(0x0),g1 *
- * add g1,0x1ee0,g1 *
- * t g0,0x1,o0
- * sethi %hi(0x0),g0 (nop)
- *
- * I presume that these set g1 to be the negative of the size, do a
- * save (putting the stack pointer at sp - size) and restore the
- * original contents of g1. A * indicates that the actual value of
- * the instruction is modified below.
- */
-static int save_insn_opcodes[] = {
- 0x03000000, 0x82007ee0, 0x9de38001, 0x03000000,
- 0x82007ee0, 0x91d02001, 0x01000000 };
-
-/* Neither do_save_insn or do_restore_insn save stack configuration
- (since the stack is in an indeterminate state through the call to
- each of them); that responsibility of the routine which calls them. */
-
-void
-do_save_insn (size)
- int size;
-{
- int g1 = read_register (1);
- CORE_ADDR sp = read_register (SP_REGNUM);
- CORE_ADDR pc = read_register (PC_REGNUM);
- CORE_ADDR npc = read_register (NPC_REGNUM);
- CORE_ADDR fake_pc = sp - sizeof (save_insn_opcodes);
- struct inferior_status inf_status;
-
- save_inferior_status (&inf_status, 0); /* Don't restore stack info */
- /*
- * See above.
- */
- save_insn_opcodes[0] = 0x03000000 | ((-size >> 10) & 0x3fffff);
- save_insn_opcodes[1] = 0x82006000 | (-size & 0x3ff);
- save_insn_opcodes[3] = 0x03000000 | ((g1 >> 10) & 0x3fffff);
- save_insn_opcodes[4] = 0x82006000 | (g1 & 0x3ff);
- write_memory (fake_pc, save_insn_opcodes, sizeof (save_insn_opcodes));
-
- clear_proceed_status ();
- stop_after_trap = 1;
- proceed (fake_pc, 0, 0);
-
- write_register (PC_REGNUM, pc);
- write_register (NPC_REGNUM, npc);
- restore_inferior_status (&inf_status);
-}
-
-/*
- * This routine takes a program counter value. It restores the
- * register window system to the frame above the current one, and sets
- * the pc and npc to the correct values.
- */
-
-/* The following insns translate to:
-
- restore
- t g0,0x1,o0
- sethi %hi(0x0), g0 */
-
-static int restore_insn_opcodes[] = { 0x81e80000, 0x91d02001, 0x01000000 };
-
-void
-do_restore_insn (pc)
- CORE_ADDR pc;
-{
- CORE_ADDR sp = read_register (SP_REGNUM);
- CORE_ADDR npc = pc + 4;
- CORE_ADDR fake_pc = sp - sizeof (restore_insn_opcodes);
- struct inferior_status inf_status;
-
- save_inferior_status (&inf_status, 0); /* Don't restore stack info */
-
- if (!pc)
- abort();
-
- write_memory (fake_pc, restore_insn_opcodes, sizeof (restore_insn_opcodes));
-
- clear_proceed_status ();
- stop_after_trap = 1;
- proceed (fake_pc, 0, 0);
-
- write_register (PC_REGNUM, pc);
- write_register (NPC_REGNUM, npc);
- restore_inferior_status (&inf_status);
-}
-
-/*
- * This routine should be more specific in it's actions; making sure
- * that it uses the same register in the initial prologue section.
- */
-CORE_ADDR
-skip_prologue (pc)
- CORE_ADDR pc;
-{
- union
- {
- union insn_fmt insn;
- int i;
- } x;
- int dest = -1;
-
- x.i = read_memory_integer (pc, 4);
-
- /* Recognize sethi insn. Record destination. */
- if (x.insn.sethi.op == 0
- && x.insn.sethi.op2 == 4)
- {
- dest = x.insn.sethi.rd;
- pc += 4;
- x.i = read_memory_integer (pc, 4);
- }
-
- /* Recognizes an add immediate value to register to either %g1 or
- the destination register recorded above. Actually, this might
- well recognize several different arithmetic operations.*/
- if (x.insn.arith_imm.op == 2
- && x.insn.arith_imm.i == 1
- && (x.insn.arith_imm.rd == 1
- || x.insn.arith_imm.rd == dest))
- {
- pc += 4;
- x.i = read_memory_integer (pc, 4);
- }
-
- /* This recognizes any SAVE insn. But why do the XOR and then
- the compare? That's identical to comparing against 60 (as long
- as there isn't any sign extension). */
- if (x.insn.arith.op == 2
- && (x.insn.arith.op3 ^ 32) == 28)
- {
- pc += 4;
- x.i = read_memory_integer (pc, 4);
- }
-
- /* Now we need to recognize stores into the frame from the input
- registers. This recognizes all non alternate stores of input
- register, into a location offset from the frame pointer. */
- while (x.insn.arith_imm.op == 3
- && (x.insn.arith_imm.op3 & 0x3c) == 4 /* Store, non-alt */
- && (x.insn.arith_imm.rd & 0x18) == 0x18 /* Input register */
- && x.insn.arith_imm.i == 1 /* Immediate mode */
- && x.insn.arith_imm.rs1 == 30 /* Off of frame pointer */
- && x.insn.arith_imm.simm >= 0x44 /* Into reserved */
- && x.insn.arith_imm.simm < 0x5b) /* stack space. */
- {
- pc += 4;
- x.i = read_memory_integer (pc, 4);
- }
- return pc;
-}
-
-/*
- * Check instruction at "addr" to see if it is an annulled branch.
- * All other instructions will go to NPC or will trap.
- *
- * Set *target if we find a candidate branch; set to zero if not.
- */
-
-branch_type
-isannulled (addr, target)
- CORE_ADDR addr, *target;
-{
- union insn_fmt instr;
- branch_type val = not_branch;
- long offset; /* Must be signed for sign-extend */
-
- *target = 0;
- instr.intval = read_memory_integer (addr, 4);
- /* printf("intval = %x\n",instr.intval); */
- switch (instr.op1.op1)
- {
- case 0: /* Format 2 */
- switch(instr.op2.op2)
- {
- case 2: case 6: case 7: /* Bcc, FBcc, CBcc */
- if (instr.branch.cond == 8)
- val = instr.branch.a ? baa : ba;
- else
- val = instr.branch.a ? bicca : bicc;
- /* 22 bits, sign extended */
- offset = 4 * ((int) (instr.branch.disp << 10) >> 10);
- *target = addr + offset;
- break;
- }
- break;
- }
- /*printf("isannulled ret: %d\n",val); */
- return val;
-}
-@
-
-
-1.2
-log
-@ * Use gdbcore.h rather than a bunch of externs.
- * Avoid dependency on "exec file" when figuring out data_start and data_end
-of core file.
-@
-text
-@d97 2
-a98 2
-static CORE_ADDR next_pc, pc8, target;
-static int brkpc8, brktrg;
-d113 2
-a114 1
- branch_type br, isabranch();
-d117 1
-a117 1
- pc8 = read_register (PC_REGNUM) + 8; /* branch not taken */
-d124 1
-d126 3
-a128 3
- /* printf ("set break at %x\n",next_pc); */
- br = isabranch (pc8 - 8, &target);
- brkpc8 = brktrg = 0;
-d130 7
-a136 6
- if (br == bicca && pc8 != next_pc)
- {
- /* Handle branches with care */
- brkpc8 = 1;
- read_memory (pc8, break_mem[1], sizeof break_insn);
- write_memory (pc8, break_insn, sizeof break_insn);
-d140 2
-d157 1
-a157 1
- if (brkpc8)
-d159 1
-a159 1
- write_memory (pc8, break_mem[1], sizeof break_insn);
-d895 6
-a900 1
-/* Set *target if we find a branch. */
-d903 1
-a903 1
-isabranch (addr, target)
-d918 1
-a918 1
- case 2: case 6: /* BICC & FBCC */
-d930 1
-a930 1
- /*printf("isabranch ret: %d\n",val); */
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d29 1
-a453 49
-/* File names of core file and executable file. */
-
-extern char *corefile;
-extern char *execfile;
-
-/* Descriptors on which core file and executable file are open.
- Note that the execchan is closed when an inferior is created
- and reopened if the inferior dies or is killed. */
-
-extern int corechan;
-extern int execchan;
-
-/* Last modification time of executable file.
- Also used in source.c to compare against mtime of a source file. */
-
-extern int exec_mtime;
-
-/* Virtual addresses of bounds of the two areas of memory in the core file. */
-
-extern CORE_ADDR data_start;
-extern CORE_ADDR data_end;
-extern CORE_ADDR stack_start;
-extern CORE_ADDR stack_end;
-
-/* Virtual addresses of bounds of two areas of memory in the exec file.
- Note that the data area in the exec file is used only when there is no core file. */
-
-extern CORE_ADDR text_start;
-extern CORE_ADDR text_end;
-
-extern CORE_ADDR exec_data_start;
-extern CORE_ADDR exec_data_end;
-
-/* Address in executable file of start of text area data. */
-
-extern int text_offset;
-
-/* Address in executable file of start of data area data. */
-
-extern int exec_data_offset;
-
-/* Address in core file of start of data area data. */
-
-extern int data_offset;
-
-/* Address in core file of start of stack area data. */
-
-extern int stack_offset;
-
-d520 2
-a521 1
- data_start = exec_data_start;
-a601 2
- data_start = 0;
- data_end -= exec_data_start;
-a644 2
- data_start = exec_data_start;
- data_end += exec_data_start;
-a661 2
- data_start = exec_data_start;
- data_end += exec_data_start;
-@