| /* Extract registers from a "standard" core file, for GDB. | 
 |    Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, | 
 |    1999, 2000, 2001 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., 51 Franklin Street, Fifth Floor, | 
 |    Boston, MA 02110-1301, USA.  */ | 
 |  | 
 | /* Typically used on systems that have a.out format executables. | 
 |    corefile.c is supposed to contain the more machine-independent | 
 |    aspects of reading registers from core files, while this file is | 
 |    more machine specific.  */ | 
 |  | 
 | #include "defs.h" | 
 |  | 
 | #ifdef HAVE_PTRACE_H | 
 | #include <ptrace.h> | 
 | #else | 
 | #ifdef HAVE_SYS_PTRACE_H | 
 | #include <sys/ptrace.h> | 
 | #endif | 
 | #endif | 
 |  | 
 | #include <sys/types.h> | 
 | #include <sys/param.h> | 
 | #include "gdbcore.h" | 
 | #include "value.h" | 
 | #include "regcache.h" | 
 |  | 
 | /* These are needed on various systems to expand REGISTER_U_ADDR.  */ | 
 | #include "gdb_dirent.h" | 
 | #include <sys/file.h> | 
 | #include "gdb_stat.h" | 
 | #include <sys/user.h> | 
 |  | 
 | #ifndef CORE_REGISTER_ADDR | 
 | #define CORE_REGISTER_ADDR(regno, regptr) register_addr(regno, regptr) | 
 | #endif /* CORE_REGISTER_ADDR */ | 
 |  | 
 | #ifdef NEED_SYS_CORE_H | 
 | #include <sys/core.h> | 
 | #endif | 
 |  | 
 | static void fetch_core_registers (char *, unsigned, int, CORE_ADDR); | 
 |  | 
 | void _initialize_core_aout (void); | 
 |  | 
 | /* Extract the register values out of the core file and store | 
 |    them where `read_register' will find them. | 
 |  | 
 |    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). | 
 |    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. | 
 |  */ | 
 |  | 
 | static void | 
 | fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, | 
 | 		      CORE_ADDR reg_addr) | 
 | { | 
 |   int regno; | 
 |   CORE_ADDR addr; | 
 |   int bad_reg = -1; | 
 |   CORE_ADDR reg_ptr = -reg_addr;	/* Original u.u_ar0 is -reg_addr. */ | 
 |   int numregs = NUM_REGS; | 
 |  | 
 |   /* 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, | 
 |      "register 0" will be at core_reg_sect+reg_ptr, and we can use | 
 |      CORE_REGISTER_ADDR to offset to the other registers.  If this is a modern | 
 |      core file without a upage, reg_ptr will be zero and this is all a big | 
 |      NOP.  */ | 
 |   if (reg_ptr > core_reg_size) | 
 |     reg_ptr -= KERNEL_U_ADDR; | 
 |  | 
 |   for (regno = 0; regno < numregs; regno++) | 
 |     { | 
 |       addr = CORE_REGISTER_ADDR (regno, reg_ptr); | 
 |       if (addr >= core_reg_size | 
 | 	  && bad_reg < 0) | 
 | 	bad_reg = regno; | 
 |       else | 
 | 	regcache_raw_supply (current_regcache, regno, core_reg_sect + addr); | 
 |     } | 
 |  | 
 |   if (bad_reg >= 0) | 
 |     error (_("Register %s not found in core file."), REGISTER_NAME (bad_reg)); | 
 | } | 
 |  | 
 |  | 
 | #ifdef REGISTER_U_ADDR | 
 |  | 
 | /* Return the address in the core dump or inferior of register REGNO. | 
 |    BLOCKEND is the address of the end of the user structure.  */ | 
 |  | 
 | CORE_ADDR | 
 | register_addr (int regno, CORE_ADDR blockend) | 
 | { | 
 |   CORE_ADDR addr; | 
 |  | 
 |   if (regno < 0 || regno >= NUM_REGS) | 
 |     error (_("Invalid register number %d."), regno); | 
 |  | 
 |   REGISTER_U_ADDR (addr, blockend, regno); | 
 |  | 
 |   return addr; | 
 | } | 
 |  | 
 | #endif /* REGISTER_U_ADDR */ | 
 |  | 
 |  | 
 | /* Register that we are able to handle aout (trad-core) file formats.  */ | 
 |  | 
 | static struct core_fns aout_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_aout (void) | 
 | { | 
 |   deprecated_add_core_fns (&aout_core_fns); | 
 | } |