diff options
author | obrien <obrien@FreeBSD.org> | 2002-06-27 23:04:23 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2002-06-27 23:04:23 +0000 |
commit | 24c014fcd5bfe9e57a1208a57b8c0f9aa77261ec (patch) | |
tree | 3a27b96108bccb91c5b154b69c30b24950c25d89 /contrib/gdb/gdb/gdbserver/low-nbsd.c | |
parent | a9ab854862b9e8f268eb8bbbac00742895dbb2c3 (diff) | |
parent | f458c59c2304bcdacc00cd43ff1a93f184c407d0 (diff) | |
download | FreeBSD-src-24c014fcd5bfe9e57a1208a57b8c0f9aa77261ec.zip FreeBSD-src-24c014fcd5bfe9e57a1208a57b8c0f9aa77261ec.tar.gz |
This commit was generated by cvs2svn to compensate for changes in r98944,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'contrib/gdb/gdb/gdbserver/low-nbsd.c')
-rw-r--r-- | contrib/gdb/gdb/gdbserver/low-nbsd.c | 599 |
1 files changed, 599 insertions, 0 deletions
diff --git a/contrib/gdb/gdb/gdbserver/low-nbsd.c b/contrib/gdb/gdb/gdbserver/low-nbsd.c new file mode 100644 index 0000000..9046d63 --- /dev/null +++ b/contrib/gdb/gdb/gdbserver/low-nbsd.c @@ -0,0 +1,599 @@ +/* Low level interface to ptrace, for the remote server for GDB. + Copyright 1986, 1987, 1993, 2000, 2001, 2002 Free Software Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include "server.h" +#include <sys/types.h> +#include <sys/wait.h> +#include "frame.h" +#include "inferior.h" + +#include <stdio.h> +#include <errno.h> + +/***************Begin MY defs*********************/ +static char my_registers[REGISTER_BYTES]; +char *registers = my_registers; +/***************End MY defs*********************/ + +#include <sys/ptrace.h> +#include <machine/reg.h> + +#define RF(dst, src) \ + memcpy(®isters[REGISTER_BYTE(dst)], &src, sizeof(src)) + +#define RS(src, dst) \ + memcpy(&dst, ®isters[REGISTER_BYTE(src)], sizeof(dst)) + +#ifdef __i386__ +struct env387 + { + unsigned short control; + unsigned short r0; + unsigned short status; + unsigned short r1; + unsigned short tag; + unsigned short r2; + unsigned long eip; + unsigned short code_seg; + unsigned short opcode; + unsigned long operand; + unsigned short operand_seg; + unsigned short r3; + unsigned char regs[8][10]; + }; + +/* i386_register_raw_size[i] is the number of bytes of storage in the + actual machine representation for register i. */ +int i386_register_raw_size[MAX_NUM_REGS] = { + 4, 4, 4, 4, + 4, 4, 4, 4, + 4, 4, 4, 4, + 4, 4, 4, 4, + 10, 10, 10, 10, + 10, 10, 10, 10, + 4, 4, 4, 4, + 4, 4, 4, 4, + 16, 16, 16, 16, + 16, 16, 16, 16, + 4 +}; + +int i386_register_byte[MAX_NUM_REGS]; + +static void +initialize_arch (void) +{ + /* Initialize the table saying where each register starts in the + register file. */ + { + int i, offset; + + offset = 0; + for (i = 0; i < MAX_NUM_REGS; i++) + { + i386_register_byte[i] = offset; + offset += i386_register_raw_size[i]; + } + } +} +#endif /* !__i386__ */ + +#ifdef __m68k__ +static void +initialize_arch (void) +{ +} +#endif /* !__m68k__ */ + +#ifdef __ns32k__ +static void +initialize_arch (void) +{ +} +#endif /* !__ns32k__ */ + +#ifdef __powerpc__ +#include "ppc-tdep.h" + +static void +initialize_arch (void) +{ +} +#endif /* !__powerpc__ */ + + +/* Start an inferior process and returns its pid. + ALLARGS is a vector of program-name and args. */ + +int +create_inferior (char *program, char **allargs) +{ + int pid; + + pid = fork (); + if (pid < 0) + perror_with_name ("fork"); + + if (pid == 0) + { + ptrace (PT_TRACE_ME, 0, 0, 0); + + execv (program, allargs); + + fprintf (stderr, "Cannot exec %s: %s.\n", program, + errno < sys_nerr ? sys_errlist[errno] : "unknown error"); + fflush (stderr); + _exit (0177); + } + + return pid; +} + +/* Attaching is not supported. */ +int +myattach (int pid) +{ + return -1; +} + +/* Kill the inferior process. Make us have no inferior. */ + +void +kill_inferior (void) +{ + if (inferior_pid == 0) + return; + ptrace (PT_KILL, inferior_pid, 0, 0); + wait (0); + /*************inferior_died ();****VK**************/ +} + +/* Return nonzero if the given thread is still alive. */ +int +mythread_alive (int pid) +{ + return 1; +} + +/* Wait for process, returns status */ + +unsigned char +mywait (char *status) +{ + int pid; + int w; + + enable_async_io (); + pid = waitpid (inferior_pid, &w, 0); + disable_async_io (); + if (pid != inferior_pid) + perror_with_name ("wait"); + + if (WIFEXITED (w)) + { + fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w)); + *status = 'W'; + return ((unsigned char) WEXITSTATUS (w)); + } + else if (!WIFSTOPPED (w)) + { + fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w)); + *status = 'X'; + return ((unsigned char) WTERMSIG (w)); + } + + fetch_inferior_registers (0); + + *status = 'T'; + return ((unsigned char) WSTOPSIG (w)); +} + +/* Resume execution of the inferior process. + If STEP is nonzero, single-step it. + If SIGNAL is nonzero, give it that signal. */ + +void +myresume (int step, int signal) +{ + errno = 0; + ptrace (step ? PT_STEP : PT_CONTINUE, inferior_pid, + (PTRACE_ARG3_TYPE) 1, signal); + if (errno) + perror_with_name ("ptrace"); +} + + +#ifdef __i386__ +/* Fetch one or more registers from the inferior. REGNO == -1 to get + them all. We actually fetch more than requested, when convenient, + marking them as valid so we won't fetch them again. */ + +void +fetch_inferior_registers (int ignored) +{ + struct reg inferior_registers; + struct env387 inferior_fp_registers; + + ptrace (PT_GETREGS, inferior_pid, + (PTRACE_ARG3_TYPE) &inferior_registers, 0); + ptrace (PT_GETFPREGS, inferior_pid, + (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0); + + RF ( 0, inferior_registers.r_eax); + RF ( 1, inferior_registers.r_ecx); + RF ( 2, inferior_registers.r_edx); + RF ( 3, inferior_registers.r_ebx); + RF ( 4, inferior_registers.r_esp); + RF ( 5, inferior_registers.r_ebp); + RF ( 6, inferior_registers.r_esi); + RF ( 7, inferior_registers.r_edi); + RF ( 8, inferior_registers.r_eip); + RF ( 9, inferior_registers.r_eflags); + RF (10, inferior_registers.r_cs); + RF (11, inferior_registers.r_ss); + RF (12, inferior_registers.r_ds); + RF (13, inferior_registers.r_es); + RF (14, inferior_registers.r_fs); + RF (15, inferior_registers.r_gs); + + RF (FP0_REGNUM, inferior_fp_registers.regs[0]); + RF (FP0_REGNUM + 1, inferior_fp_registers.regs[1]); + RF (FP0_REGNUM + 2, inferior_fp_registers.regs[2]); + RF (FP0_REGNUM + 3, inferior_fp_registers.regs[3]); + RF (FP0_REGNUM + 4, inferior_fp_registers.regs[4]); + RF (FP0_REGNUM + 5, inferior_fp_registers.regs[5]); + RF (FP0_REGNUM + 6, inferior_fp_registers.regs[6]); + RF (FP0_REGNUM + 7, inferior_fp_registers.regs[7]); + + RF (FCTRL_REGNUM, inferior_fp_registers.control); + RF (FSTAT_REGNUM, inferior_fp_registers.status); + RF (FTAG_REGNUM, inferior_fp_registers.tag); + RF (FCS_REGNUM, inferior_fp_registers.code_seg); + RF (FCOFF_REGNUM, inferior_fp_registers.eip); + RF (FDS_REGNUM, inferior_fp_registers.operand_seg); + RF (FDOFF_REGNUM, inferior_fp_registers.operand); + RF (FOP_REGNUM, inferior_fp_registers.opcode); +} + +/* 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 (int ignored) +{ + struct reg inferior_registers; + struct env387 inferior_fp_registers; + + RS ( 0, inferior_registers.r_eax); + RS ( 1, inferior_registers.r_ecx); + RS ( 2, inferior_registers.r_edx); + RS ( 3, inferior_registers.r_ebx); + RS ( 4, inferior_registers.r_esp); + RS ( 5, inferior_registers.r_ebp); + RS ( 6, inferior_registers.r_esi); + RS ( 7, inferior_registers.r_edi); + RS ( 8, inferior_registers.r_eip); + RS ( 9, inferior_registers.r_eflags); + RS (10, inferior_registers.r_cs); + RS (11, inferior_registers.r_ss); + RS (12, inferior_registers.r_ds); + RS (13, inferior_registers.r_es); + RS (14, inferior_registers.r_fs); + RS (15, inferior_registers.r_gs); + + RS (FP0_REGNUM, inferior_fp_registers.regs[0]); + RS (FP0_REGNUM + 1, inferior_fp_registers.regs[1]); + RS (FP0_REGNUM + 2, inferior_fp_registers.regs[2]); + RS (FP0_REGNUM + 3, inferior_fp_registers.regs[3]); + RS (FP0_REGNUM + 4, inferior_fp_registers.regs[4]); + RS (FP0_REGNUM + 5, inferior_fp_registers.regs[5]); + RS (FP0_REGNUM + 6, inferior_fp_registers.regs[6]); + RS (FP0_REGNUM + 7, inferior_fp_registers.regs[7]); + + RS (FCTRL_REGNUM, inferior_fp_registers.control); + RS (FSTAT_REGNUM, inferior_fp_registers.status); + RS (FTAG_REGNUM, inferior_fp_registers.tag); + RS (FCS_REGNUM, inferior_fp_registers.code_seg); + RS (FCOFF_REGNUM, inferior_fp_registers.eip); + RS (FDS_REGNUM, inferior_fp_registers.operand_seg); + RS (FDOFF_REGNUM, inferior_fp_registers.operand); + RS (FOP_REGNUM, inferior_fp_registers.opcode); + + ptrace (PT_SETREGS, inferior_pid, + (PTRACE_ARG3_TYPE) &inferior_registers, 0); + ptrace (PT_SETFPREGS, inferior_pid, + (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0); +} +#endif /* !__i386__ */ + +#ifdef __m68k__ +/* Fetch one or more registers from the inferior. REGNO == -1 to get + them all. We actually fetch more than requested, when convenient, + marking them as valid so we won't fetch them again. */ + +void +fetch_inferior_registers (int regno) +{ + struct reg inferior_registers; + struct fpreg inferior_fp_registers; + + ptrace (PT_GETREGS, inferior_pid, + (PTRACE_ARG3_TYPE) & inferior_registers, 0); + memcpy (®isters[REGISTER_BYTE (0)], &inferior_registers, + sizeof (inferior_registers)); + + ptrace (PT_GETFPREGS, inferior_pid, + (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0); + memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers, + sizeof (inferior_fp_registers)); +} + +/* 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 (int regno) +{ + struct reg inferior_registers; + struct fpreg inferior_fp_registers; + + memcpy (&inferior_registers, ®isters[REGISTER_BYTE (0)], + sizeof (inferior_registers)); + ptrace (PT_SETREGS, inferior_pid, + (PTRACE_ARG3_TYPE) & inferior_registers, 0); + + memcpy (&inferior_fp_registers, ®isters[REGISTER_BYTE (FP0_REGNUM)], + sizeof (inferior_fp_registers)); + ptrace (PT_SETFPREGS, inferior_pid, + (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0); +} +#endif /* !__m68k__ */ + + +#ifdef __ns32k__ +/* Fetch one or more registers from the inferior. REGNO == -1 to get + them all. We actually fetch more than requested, when convenient, + marking them as valid so we won't fetch them again. */ + +void +fetch_inferior_registers (int regno) +{ + struct reg inferior_registers; + struct fpreg inferior_fpregisters; + + ptrace (PT_GETREGS, inferior_pid, + (PTRACE_ARG3_TYPE) & inferior_registers, 0); + ptrace (PT_GETFPREGS, inferior_pid, + (PTRACE_ARG3_TYPE) & inferior_fpregisters, 0); + + RF (R0_REGNUM + 0, inferior_registers.r_r0); + RF (R0_REGNUM + 1, inferior_registers.r_r1); + RF (R0_REGNUM + 2, inferior_registers.r_r2); + RF (R0_REGNUM + 3, inferior_registers.r_r3); + RF (R0_REGNUM + 4, inferior_registers.r_r4); + RF (R0_REGNUM + 5, inferior_registers.r_r5); + RF (R0_REGNUM + 6, inferior_registers.r_r6); + RF (R0_REGNUM + 7, inferior_registers.r_r7); + + RF (SP_REGNUM, inferior_registers.r_sp); + RF (FP_REGNUM, inferior_registers.r_fp); + RF (PC_REGNUM, inferior_registers.r_pc); + RF (PS_REGNUM, inferior_registers.r_psr); + + RF (FPS_REGNUM, inferior_fpregisters.r_fsr); + RF (FP0_REGNUM + 0, inferior_fpregisters.r_freg[0]); + RF (FP0_REGNUM + 2, inferior_fpregisters.r_freg[2]); + RF (FP0_REGNUM + 4, inferior_fpregisters.r_freg[4]); + RF (FP0_REGNUM + 6, inferior_fpregisters.r_freg[6]); + RF (LP0_REGNUM + 1, inferior_fpregisters.r_freg[1]); + RF (LP0_REGNUM + 3, inferior_fpregisters.r_freg[3]); + RF (LP0_REGNUM + 5, inferior_fpregisters.r_freg[5]); + RF (LP0_REGNUM + 7, inferior_fpregisters.r_freg[7]); +} + +/* 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 (int regno) +{ + struct reg inferior_registers; + struct fpreg inferior_fpregisters; + + RS (R0_REGNUM + 0, inferior_registers.r_r0); + RS (R0_REGNUM + 1, inferior_registers.r_r1); + RS (R0_REGNUM + 2, inferior_registers.r_r2); + RS (R0_REGNUM + 3, inferior_registers.r_r3); + RS (R0_REGNUM + 4, inferior_registers.r_r4); + RS (R0_REGNUM + 5, inferior_registers.r_r5); + RS (R0_REGNUM + 6, inferior_registers.r_r6); + RS (R0_REGNUM + 7, inferior_registers.r_r7); + + RS (SP_REGNUM, inferior_registers.r_sp); + RS (FP_REGNUM, inferior_registers.r_fp); + RS (PC_REGNUM, inferior_registers.r_pc); + RS (PS_REGNUM, inferior_registers.r_psr); + + RS (FPS_REGNUM, inferior_fpregisters.r_fsr); + RS (FP0_REGNUM + 0, inferior_fpregisters.r_freg[0]); + RS (FP0_REGNUM + 2, inferior_fpregisters.r_freg[2]); + RS (FP0_REGNUM + 4, inferior_fpregisters.r_freg[4]); + RS (FP0_REGNUM + 6, inferior_fpregisters.r_freg[6]); + RS (LP0_REGNUM + 1, inferior_fpregisters.r_freg[1]); + RS (LP0_REGNUM + 3, inferior_fpregisters.r_freg[3]); + RS (LP0_REGNUM + 5, inferior_fpregisters.r_freg[5]); + RS (LP0_REGNUM + 7, inferior_fpregisters.r_freg[7]); + + ptrace (PT_SETREGS, inferior_pid, + (PTRACE_ARG3_TYPE) & inferior_registers, 0); + ptrace (PT_SETFPREGS, inferior_pid, + (PTRACE_ARG3_TYPE) & inferior_fpregisters, 0); + +} +#endif /* !__ns32k__ */ + +#ifdef __powerpc__ +/* Fetch one or more registers from the inferior. REGNO == -1 to get + them all. We actually fetch more than requested, when convenient, + marking them as valid so we won't fetch them again. */ + +void +fetch_inferior_registers (int regno) +{ + struct reg inferior_registers; +#ifdef PT_GETFPREGS + struct fpreg inferior_fp_registers; +#endif + int i; + + ptrace (PT_GETREGS, inferior_pid, + (PTRACE_ARG3_TYPE) & inferior_registers, 0); + for (i = 0; i < 32; i++) + RF (i, inferior_registers.fixreg[i]); + RF (PPC_LR_REGNUM, inferior_registers.lr); + RF (PPC_CR_REGNUM, inferior_registers.cr); + RF (PPC_XER_REGNUM, inferior_registers.xer); + RF (PPC_CTR_REGNUM, inferior_registers.ctr); + RF (PC_REGNUM, inferior_registers.pc); + +#ifdef PT_GETFPREGS + ptrace (PT_GETFPREGS, inferior_pid, + (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0); + for (i = 0; i < 32; i++) + RF (FP0_REGNUM + i, inferior_fp_registers.r_regs[i]); +#endif +} + +/* 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 (int regno) +{ + struct reg inferior_registers; +#ifdef PT_SETFPREGS + struct fpreg inferior_fp_registers; +#endif + int i; + + for (i = 0; i < 32; i++) + RS (i, inferior_registers.fixreg[i]); + RS (PPC_LR_REGNUM, inferior_registers.lr); + RS (PPC_CR_REGNUM, inferior_registers.cr); + RS (PPC_XER_REGNUM, inferior_registers.xer); + RS (PPC_CTR_REGNUM, inferior_registers.ctr); + RS (PC_REGNUM, inferior_registers.pc); + ptrace (PT_SETREGS, inferior_pid, + (PTRACE_ARG3_TYPE) & inferior_registers, 0); + +#ifdef PT_SETFPREGS + for (i = 0; i < 32; i++) + RS (FP0_REGNUM + i, inferior_fp_registers.r_regs[i]); + ptrace (PT_SETFPREGS, inferior_pid, + (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0); +#endif +} +#endif /* !__powerpc__ */ + +/* 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. */ + +void +read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len) +{ + register int i; + /* Round starting address down to longword boundary. */ + register CORE_ADDR addr = memaddr & -(CORE_ADDR) 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)); + + /* Read all the longwords */ + for (i = 0; i < count; i++, addr += sizeof (int)) + { + buffer[i] = ptrace (PT_READ_D, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0); + } + + /* Copy appropriate bytes out of the buffer. */ + memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len); +} + +/* 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 (CORE_ADDR memaddr, char *myaddr, int len) +{ + register int i; + /* Round starting address down to longword boundary. */ + register CORE_ADDR addr = memaddr & -(CORE_ADDR) 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. */ + + buffer[0] = ptrace (PT_READ_D, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0); + + if (count > 1) + { + buffer[count - 1] + = ptrace (PT_READ_D, inferior_pid, + (PTRACE_ARG3_TYPE) addr + (count - 1) * sizeof (int), 0); + } + + /* Copy data to be written over corresponding part of buffer */ + + memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len); + + /* Write the entire buffer. */ + + for (i = 0; i < count; i++, addr += sizeof (int)) + { + errno = 0; + ptrace (PT_WRITE_D, inferior_pid, (PTRACE_ARG3_TYPE) addr, buffer[i]); + if (errno) + return errno; + } + + return 0; +} + +void +initialize_low (void) +{ + initialize_arch (); +} |