X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fmips-nat.c;h=16009c2e545173c7a91b7743f2004abc28e4ffd6;hb=ebef2de3771e8ce665b4f1952040990b8aaf7f34;hp=d7c28b5487415d12e3098a0f752f20cc382ea444;hpb=3496b7456212818953a6b39a0ea0b278ee5de913;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/mips-nat.c b/gdb/mips-nat.c index d7c28b5487..16009c2e54 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 @@ -59,29 +62,31 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ : regno >= FP0_REGNUM ? FPR_BASE + (regno - FP0_REGNUM) \ : 0) -static char zerobuf[MAX_REGISTER_RAW_SIZE] = {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; - 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, + { + *(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); } @@ -95,20 +100,21 @@ 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; char buf[80]; - if (regno == 0) - return; - if (regno > 0) { + 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)) + 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 +125,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_addr (regno, 1); - 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,18 +136,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; - jb_addr = read_register(A0_REGNUM); + 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, pc, - sizeof(CORE_ADDR))) + if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf, + TARGET_PTR_BIT / TARGET_CHAR_BIT)) return 0; - SWAP_TARGET_AND_HOST(pc, sizeof(CORE_ADDR)); + *pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT); return 1; } @@ -167,24 +159,21 @@ 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 bad_reg = -1; - register reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */ + register reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */ /* 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, @@ -193,21 +182,28 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr) core file without a upage, reg_ptr will be zero and this is all a big NOP. */ if (reg_ptr > core_reg_size) +#ifdef KERNEL_U_ADDR reg_ptr -= KERNEL_U_ADDR; +#else + error ("Old mips core file can't be processed on this machine."); +#endif 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. */ @@ -217,12 +213,10 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr) /* 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); @@ -231,3 +225,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); +}