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