119370Spst/* Extract registers from a "standard" core file, for GDB. 298948Sobrien Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 398948Sobrien 1999, 2000, 2001 Free Software Foundation, Inc. 419370Spst 598948Sobrien This file is part of GDB. 619370Spst 798948Sobrien This program is free software; you can redistribute it and/or modify 898948Sobrien it under the terms of the GNU General Public License as published by 998948Sobrien the Free Software Foundation; either version 2 of the License, or 1098948Sobrien (at your option) any later version. 1119370Spst 1298948Sobrien This program is distributed in the hope that it will be useful, 1398948Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1498948Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1598948Sobrien GNU General Public License for more details. 1619370Spst 1798948Sobrien You should have received a copy of the GNU General Public License 1898948Sobrien along with this program; if not, write to the Free Software 1998948Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 2098948Sobrien Boston, MA 02111-1307, USA. */ 2119370Spst 2219370Spst/* Typically used on systems that have a.out format executables. 2319370Spst corefile.c is supposed to contain the more machine-independent 2419370Spst aspects of reading registers from core files, while this file is 2519370Spst more machine specific. */ 2619370Spst 2719370Spst#include "defs.h" 2846289Sdfr 2946289Sdfr#ifdef HAVE_PTRACE_H 3098948Sobrien#include <ptrace.h> 3146289Sdfr#else 3298948Sobrien#ifdef HAVE_SYS_PTRACE_H 3398948Sobrien#include <sys/ptrace.h> 3446289Sdfr#endif 3598948Sobrien#endif 3646289Sdfr 3719370Spst#include <sys/types.h> 3819370Spst#include <sys/param.h> 3919370Spst#include "gdbcore.h" 4098948Sobrien#include "value.h" /* For supply_register. */ 4198948Sobrien#include "regcache.h" 4219370Spst 4319370Spst/* These are needed on various systems to expand REGISTER_U_ADDR. */ 4419370Spst#ifndef USG 4598948Sobrien#include "gdb_dirent.h" 4619370Spst#include <sys/file.h> 4719370Spst#include "gdb_stat.h" 4819370Spst#include <sys/user.h> 4919370Spst#endif 5019370Spst 5119370Spst#ifndef CORE_REGISTER_ADDR 5219370Spst#define CORE_REGISTER_ADDR(regno, regptr) register_addr(regno, regptr) 5319370Spst#endif /* CORE_REGISTER_ADDR */ 5419370Spst 5519370Spst#ifdef NEED_SYS_CORE_H 5619370Spst#include <sys/core.h> 5719370Spst#endif 5819370Spst 5998948Sobrienstatic void fetch_core_registers (char *, unsigned, int, CORE_ADDR); 6046289Sdfr 6198948Sobrienvoid _initialize_core_aout (void); 6246289Sdfr 6319370Spst/* Extract the register values out of the core file and store 6419370Spst them where `read_register' will find them. 6519370Spst 6619370Spst CORE_REG_SECT points to the register values themselves, read into memory. 6719370Spst CORE_REG_SIZE is the size of that area. 6819370Spst WHICH says which set of registers we are handling (0 = int, 2 = float 6998948Sobrien on machines where they are discontiguous). 7019370Spst REG_ADDR is the offset from u.u_ar0 to the register values relative to 7198948Sobrien core_reg_sect. This is used with old-fashioned core files to 7298948Sobrien locate the registers in a large upage-plus-stack ".reg" section. 7398948Sobrien Original upage address X is at location core_reg_sect+x+reg_addr. 7419370Spst */ 7519370Spst 7619370Spststatic void 7798948Sobrienfetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, 7898948Sobrien CORE_ADDR reg_addr) 7919370Spst{ 8046289Sdfr int regno; 8146289Sdfr CORE_ADDR addr; 8219370Spst int bad_reg = -1; 8398948Sobrien CORE_ADDR reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */ 8498948Sobrien int numregs = NUM_REGS; 8519370Spst 8619370Spst /* If u.u_ar0 was an absolute address in the core file, relativize it now, 8719370Spst so we can use it as an offset into core_reg_sect. When we're done, 8819370Spst "register 0" will be at core_reg_sect+reg_ptr, and we can use 8919370Spst CORE_REGISTER_ADDR to offset to the other registers. If this is a modern 9019370Spst core file without a upage, reg_ptr will be zero and this is all a big 9119370Spst NOP. */ 9221738Sgj if (reg_ptr > core_reg_size) 9319370Spst reg_ptr -= KERNEL_U_ADDR; 9419370Spst 9519370Spst for (regno = 0; regno < numregs; regno++) 9619370Spst { 9719370Spst addr = CORE_REGISTER_ADDR (regno, reg_ptr); 9846289Sdfr if (addr >= core_reg_size 9946289Sdfr && bad_reg < 0) 10046289Sdfr bad_reg = regno; 10198948Sobrien else 10298948Sobrien supply_register (regno, core_reg_sect + addr); 10319370Spst } 10446289Sdfr 10519370Spst if (bad_reg >= 0) 10646289Sdfr error ("Register %s not found in core file.", REGISTER_NAME (bad_reg)); 10719370Spst} 10819370Spst 10919370Spst 11019370Spst#ifdef REGISTER_U_ADDR 11119370Spst 11219370Spst/* Return the address in the core dump or inferior of register REGNO. 11319370Spst BLOCKEND is the address of the end of the user structure. */ 11419370Spst 11546289SdfrCORE_ADDR 11698948Sobrienregister_addr (int regno, CORE_ADDR blockend) 11719370Spst{ 11821738Sgj CORE_ADDR addr; 11919370Spst 12098948Sobrien if (regno < 0 || regno >= NUM_REGS) 12119370Spst error ("Invalid register number %d.", regno); 12219370Spst 12319370Spst REGISTER_U_ADDR (addr, blockend, regno); 12419370Spst 12519370Spst return addr; 12619370Spst} 12719370Spst 12819370Spst#endif /* REGISTER_U_ADDR */ 12998948Sobrien 13019370Spst 13119370Spst/* Register that we are able to handle aout (trad-core) file formats. */ 13219370Spst 13319370Spststatic struct core_fns aout_core_fns = 13419370Spst{ 13598948Sobrien bfd_target_unknown_flavour, /* core_flavour */ 13698948Sobrien default_check_format, /* check_format */ 13798948Sobrien default_core_sniffer, /* core_sniffer */ 13898948Sobrien fetch_core_registers, /* core_read_registers */ 13998948Sobrien NULL /* next */ 14019370Spst}; 14119370Spst 14219370Spstvoid 14398948Sobrien_initialize_core_aout (void) 14419370Spst{ 14519370Spst add_core_fns (&aout_core_fns); 14619370Spst} 147