X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fmips-nat.c;h=626f770f18df86a7ae1cae8736efa3d82e3f7e15;hb=2ca62865245d3e3da0acde89222d1a091512880a;hp=5e34f920a11c1c8f32e5105247366a11d5ae21d1;hpb=34df79fc9d631a7cacdb2f9a9e12d5e3f8c6dd1c;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/mips-nat.c b/gdb/mips-nat.c index 5e34f920a1..626f770f18 100644 --- a/gdb/mips-nat.c +++ b/gdb/mips-nat.c @@ -1,27 +1,30 @@ /* Low level DECstation interface to ptrace, for GDB when running native. - Copyright 1988, 1989, 1991, 1992 Free Software Foundation, Inc. + Copyright 1988, 1989, 1991, 1992, 1993, 1995, 1996, 1999, 2000, 2001 + Free Software Foundation, Inc. Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin. -This file is part of GDB. + 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 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. + 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + 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 "defs.h" #include "inferior.h" #include "gdbcore.h" +#include "regcache.h" #include #include #include @@ -48,46 +51,50 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Map gdb internal register number to ptrace ``address''. These ``addresses'' are defined in DECstation */ -#define REGISTER_PTRACE_ADDR(regno) \ - (regno < 32 ? GPR_BASE + regno \ - : regno == PC_REGNUM ? PC \ - : regno == CAUSE_REGNUM ? CAUSE \ - : regno == HI_REGNUM ? MMHI \ - : regno == LO_REGNUM ? MMLO \ - : regno == FCRCS_REGNUM ? FPC_CSR \ - : regno == FCRIR_REGNUM ? FPC_EIR \ - : regno >= FP0_REGNUM ? FPR_BASE + (regno - FP0_REGNUM) \ - : 0) +static int +register_ptrace_addr (int regno) +{ + return (regno < 32 ? GPR_BASE + regno + : regno == mips_regnum (current_gdbarch)->pc ? PC + : regno == mips_regnum (current_gdbarch)->cause ? CAUSE + : regno == mips_regnum (current_gdbarch)->hi ? MMHI + : regno == mips_regnum (current_gdbarch)->lo ? MMLO + : regno == mips_regnum (current_gdbarch)->fp_control_status ? FPC_CSR + : regno == mips_regnum (current_gdbarch)->fp_implementation_revision ? FPC_EIR + : regno >= FP0_REGNUM ? FPR_BASE + (regno - FP0_REGNUM) + : 0); +} -static char zerobuf[MAX_REGISTER_RAW_SIZE] = {0}; +static void fetch_core_registers (char *, unsigned, int, CORE_ADDR); /* Get all registers from the inferior */ void -fetch_inferior_registers (regno) - int regno; +fetch_inferior_registers (int regno) { - register unsigned int regaddr; - char buf[MAX_REGISTER_RAW_SIZE]; - register int i; + unsigned int regaddr; + char buf[MAX_REGISTER_SIZE]; + int i; + char zerobuf[MAX_REGISTER_SIZE]; + memset (zerobuf, 0, MAX_REGISTER_SIZE); - registers_fetched (); + deprecated_registers_fetched (); for (regno = 1; regno < NUM_REGS; regno++) { - regaddr = REGISTER_PTRACE_ADDR (regno); - for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) - { - *(int *) &buf[i] = ptrace (PT_READ_U, inferior_pid, + regaddr = register_ptrace_addr (regno); + for (i = 0; i < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (int)) + { + *(int *) &buf[i] = ptrace (PT_READ_U, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr, 0); - regaddr += sizeof (int); - } + regaddr += sizeof (int); + } supply_register (regno, buf); } supply_register (ZERO_REGNUM, zerobuf); /* Frame ptr reg must appear to be 0; it is faked by stack handling code. */ - supply_register (FP_REGNUM, zerobuf); + supply_register (DEPRECATED_FP_REGNUM, zerobuf); } /* Store our register values back into the inferior. @@ -95,20 +102,23 @@ fetch_inferior_registers (regno) Otherwise, REGNO specifies which register (so we can save time). */ void -store_inferior_registers (regno) - int regno; +store_inferior_registers (int regno) { - register unsigned int regaddr; + unsigned int regaddr; char buf[80]; - if (regno == 0) - return; - if (regno > 0) { - regaddr = REGISTER_PTRACE_ADDR (regno); + if (regno == ZERO_REGNUM || regno == PS_REGNUM + || regno == mips_regnum (current_gdbarch)->badvaddr + || regno == mips_regnum (current_gdbarch)->cause + || regno == mips_regnum (current_gdbarch)->fp_implementation_revision + || regno == DEPRECATED_FP_REGNUM + || (regno >= FIRST_EMBED_REGNUM && regno <= LAST_EMBED_REGNUM)) + return; + regaddr = register_ptrace_addr (regno); errno = 0; - ptrace (PT_WRITE_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, + ptrace (PT_WRITE_U, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr, read_register (regno)); if (errno != 0) { @@ -119,22 +129,7 @@ store_inferior_registers (regno) else { for (regno = 0; regno < NUM_REGS; regno++) - { - if (regno == ZERO_REGNUM || regno == PS_REGNUM - || regno == BADVADDR_REGNUM || regno == CAUSE_REGNUM - || regno == FCRIR_REGNUM || regno == FP_REGNUM - || (regno >= FIRST_EMBED_REGNUM && regno <= LAST_EMBED_REGNUM)) - continue; - regaddr = REGISTER_PTRACE_ADDR (regno); - errno = 0; - ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, - read_register (regno)); - if (errno != 0) - { - sprintf (buf, "writing all regs, number %d", regno); - perror_with_name (buf); - } - } + store_inferior_registers (regno); } } @@ -145,19 +140,19 @@ store_inferior_registers (regno) This routine returns true on success. */ int -get_longjmp_target(pc) - CORE_ADDR *pc; +get_longjmp_target (CORE_ADDR *pc) { CORE_ADDR jb_addr; - char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT]; + char *buf; + buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT); jb_addr = read_register (A0_REGNUM); if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf, TARGET_PTR_BIT / TARGET_CHAR_BIT)) return 0; - *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); + *pc = extract_unsigned_integer (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); return 1; } @@ -168,24 +163,25 @@ get_longjmp_target(pc) CORE_REG_SECT points to the register values themselves, read into memory. CORE_REG_SIZE is the size of that area. WHICH says which set of registers we are handling (0 = int, 2 = float - on machines where they are discontiguous). + on machines where they are discontiguous). REG_ADDR is the offset from u.u_ar0 to the register values relative to - core_reg_sect. This is used with old-fashioned core files to - locate the registers in a large upage-plus-stack ".reg" section. - Original upage address X is at location core_reg_sect+x+reg_addr. + core_reg_sect. This is used with old-fashioned core files to + locate the registers in a large upage-plus-stack ".reg" section. + Original upage address X is at location core_reg_sect+x+reg_addr. */ -void -fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr) - char *core_reg_sect; - unsigned core_reg_size; - int which; - unsigned reg_addr; +static void +fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, + CORE_ADDR reg_addr) { - register int regno; - register unsigned int addr; + int regno; + unsigned int addr; int bad_reg = -1; - register reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */ + reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */ + + char zerobuf[MAX_REGISTER_SIZE]; + memset (zerobuf, 0, MAX_REGISTER_SIZE); + /* If u.u_ar0 was an absolute address in the core file, relativize it now, so we can use it as an offset into core_reg_sect. When we're done, @@ -203,31 +199,32 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr) for (regno = 0; regno < NUM_REGS; regno++) { addr = register_addr (regno, reg_ptr); - if (addr >= core_reg_size) { - if (bad_reg < 0) - bad_reg = regno; - } else { - supply_register (regno, core_reg_sect + addr); - } + if (addr >= core_reg_size) + { + if (bad_reg < 0) + bad_reg = regno; + } + else + { + supply_register (regno, core_reg_sect + addr); + } } if (bad_reg >= 0) { - error ("Register %s not found in core file.", reg_names[bad_reg]); + error ("Register %s not found in core file.", REGISTER_NAME (bad_reg)); } supply_register (ZERO_REGNUM, zerobuf); /* Frame ptr reg must appear to be 0; it is faked by stack handling code. */ - supply_register (FP_REGNUM, zerobuf); + supply_register (DEPRECATED_FP_REGNUM, zerobuf); } /* Return the address in the core dump or inferior of register REGNO. BLOCKEND is the address of the end of the user structure. */ -unsigned int -register_addr (regno, blockend) - int regno; - int blockend; +CORE_ADDR +register_addr (int regno, CORE_ADDR blockend) { - int addr; + CORE_ADDR addr; if (regno < 0 || regno >= NUM_REGS) error ("Invalid register number %d.", regno); @@ -236,3 +233,22 @@ register_addr (regno, blockend) return addr; } + + +/* Register that we are able to handle mips core file formats. + FIXME: is this really bfd_target_unknown_flavour? */ + +static struct core_fns mips_core_fns = +{ + bfd_target_unknown_flavour, /* core_flavour */ + default_check_format, /* check_format */ + default_core_sniffer, /* core_sniffer */ + fetch_core_registers, /* core_read_registers */ + NULL /* next */ +}; + +void +_initialize_core_mips (void) +{ + add_core_fns (&mips_core_fns); +}