OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [gdb/] [mips-linux-nat.c] - Diff between revs 827 and 840

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 827 Rev 840
/* Native-dependent code for GNU/Linux on MIPS processors.
/* Native-dependent code for GNU/Linux on MIPS processors.
 
 
   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
   Free Software Foundation, Inc.
   Free Software Foundation, Inc.
 
 
   This file is part of GDB.
   This file is part of GDB.
 
 
   This program is free software; you can redistribute it and/or modify
   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
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
#include "defs.h"
#include "defs.h"
#include "inferior.h"
#include "inferior.h"
#include "mips-tdep.h"
#include "mips-tdep.h"
#include "target.h"
#include "target.h"
#include "regcache.h"
#include "regcache.h"
#include "linux-nat.h"
#include "linux-nat.h"
#include "mips-linux-tdep.h"
#include "mips-linux-tdep.h"
#include "target-descriptions.h"
#include "target-descriptions.h"
 
 
#include "gdb_proc_service.h"
#include "gdb_proc_service.h"
#include "gregset.h"
#include "gregset.h"
 
 
#include <sgidefs.h>
#include <sgidefs.h>
#include <sys/ptrace.h>
#include <sys/ptrace.h>
 
 
#include "features/mips-linux.c"
#include "features/mips-linux.c"
#include "features/mips64-linux.c"
#include "features/mips64-linux.c"
 
 
#ifndef PTRACE_GET_THREAD_AREA
#ifndef PTRACE_GET_THREAD_AREA
#define PTRACE_GET_THREAD_AREA 25
#define PTRACE_GET_THREAD_AREA 25
#endif
#endif
 
 
/* Assume that we have PTRACE_GETREGS et al. support.  If we do not,
/* Assume that we have PTRACE_GETREGS et al. support.  If we do not,
   we'll clear this and use PTRACE_PEEKUSER instead.  */
   we'll clear this and use PTRACE_PEEKUSER instead.  */
static int have_ptrace_regsets = 1;
static int have_ptrace_regsets = 1;
 
 
/* Saved function pointers to fetch and store a single register using
/* Saved function pointers to fetch and store a single register using
   PTRACE_PEEKUSER and PTRACE_POKEUSER.  */
   PTRACE_PEEKUSER and PTRACE_POKEUSER.  */
 
 
void (*super_fetch_registers) (struct regcache *, int);
void (*super_fetch_registers) (struct regcache *, int);
void (*super_store_registers) (struct regcache *, int);
void (*super_store_registers) (struct regcache *, int);
 
 
/* Map gdb internal register number to ptrace ``address''.
/* Map gdb internal register number to ptrace ``address''.
   These ``addresses'' are normally defined in <asm/ptrace.h>.
   These ``addresses'' are normally defined in <asm/ptrace.h>.
 
 
   ptrace does not provide a way to read (or set) MIPS_PS_REGNUM,
   ptrace does not provide a way to read (or set) MIPS_PS_REGNUM,
   and there's no point in reading or setting MIPS_ZERO_REGNUM.
   and there's no point in reading or setting MIPS_ZERO_REGNUM.
   We also can not set BADVADDR, CAUSE, or FCRIR via ptrace().  */
   We also can not set BADVADDR, CAUSE, or FCRIR via ptrace().  */
 
 
static CORE_ADDR
static CORE_ADDR
mips_linux_register_addr (struct gdbarch *gdbarch, int regno, int store)
mips_linux_register_addr (struct gdbarch *gdbarch, int regno, int store)
{
{
  CORE_ADDR regaddr;
  CORE_ADDR regaddr;
 
 
  if (regno < 0 || regno >= gdbarch_num_regs (gdbarch))
  if (regno < 0 || regno >= gdbarch_num_regs (gdbarch))
    error (_("Bogon register number %d."), regno);
    error (_("Bogon register number %d."), regno);
 
 
  if (regno > MIPS_ZERO_REGNUM && regno < MIPS_ZERO_REGNUM + 32)
  if (regno > MIPS_ZERO_REGNUM && regno < MIPS_ZERO_REGNUM + 32)
    regaddr = regno;
    regaddr = regno;
  else if ((regno >= mips_regnum (gdbarch)->fp0)
  else if ((regno >= mips_regnum (gdbarch)->fp0)
           && (regno < mips_regnum (gdbarch)->fp0 + 32))
           && (regno < mips_regnum (gdbarch)->fp0 + 32))
    regaddr = FPR_BASE + (regno - mips_regnum (gdbarch)->fp0);
    regaddr = FPR_BASE + (regno - mips_regnum (gdbarch)->fp0);
  else if (regno == mips_regnum (gdbarch)->pc)
  else if (regno == mips_regnum (gdbarch)->pc)
    regaddr = PC;
    regaddr = PC;
  else if (regno == mips_regnum (gdbarch)->cause)
  else if (regno == mips_regnum (gdbarch)->cause)
    regaddr = store? (CORE_ADDR) -1 : CAUSE;
    regaddr = store? (CORE_ADDR) -1 : CAUSE;
  else if (regno == mips_regnum (gdbarch)->badvaddr)
  else if (regno == mips_regnum (gdbarch)->badvaddr)
    regaddr = store? (CORE_ADDR) -1 : BADVADDR;
    regaddr = store? (CORE_ADDR) -1 : BADVADDR;
  else if (regno == mips_regnum (gdbarch)->lo)
  else if (regno == mips_regnum (gdbarch)->lo)
    regaddr = MMLO;
    regaddr = MMLO;
  else if (regno == mips_regnum (gdbarch)->hi)
  else if (regno == mips_regnum (gdbarch)->hi)
    regaddr = MMHI;
    regaddr = MMHI;
  else if (regno == mips_regnum (gdbarch)->fp_control_status)
  else if (regno == mips_regnum (gdbarch)->fp_control_status)
    regaddr = FPC_CSR;
    regaddr = FPC_CSR;
  else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
  else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
    regaddr = store? (CORE_ADDR) -1 : FPC_EIR;
    regaddr = store? (CORE_ADDR) -1 : FPC_EIR;
  else if (mips_linux_restart_reg_p (gdbarch) && regno == MIPS_RESTART_REGNUM)
  else if (mips_linux_restart_reg_p (gdbarch) && regno == MIPS_RESTART_REGNUM)
    regaddr = 0;
    regaddr = 0;
  else
  else
    regaddr = (CORE_ADDR) -1;
    regaddr = (CORE_ADDR) -1;
 
 
  return regaddr;
  return regaddr;
}
}
 
 
static CORE_ADDR
static CORE_ADDR
mips64_linux_register_addr (struct gdbarch *gdbarch, int regno, int store)
mips64_linux_register_addr (struct gdbarch *gdbarch, int regno, int store)
{
{
  CORE_ADDR regaddr;
  CORE_ADDR regaddr;
 
 
  if (regno < 0 || regno >= gdbarch_num_regs (gdbarch))
  if (regno < 0 || regno >= gdbarch_num_regs (gdbarch))
    error (_("Bogon register number %d."), regno);
    error (_("Bogon register number %d."), regno);
 
 
  if (regno > MIPS_ZERO_REGNUM && regno < MIPS_ZERO_REGNUM + 32)
  if (regno > MIPS_ZERO_REGNUM && regno < MIPS_ZERO_REGNUM + 32)
    regaddr = regno;
    regaddr = regno;
  else if ((regno >= mips_regnum (gdbarch)->fp0)
  else if ((regno >= mips_regnum (gdbarch)->fp0)
           && (regno < mips_regnum (gdbarch)->fp0 + 32))
           && (regno < mips_regnum (gdbarch)->fp0 + 32))
    regaddr = MIPS64_FPR_BASE + (regno - gdbarch_fp0_regnum (gdbarch));
    regaddr = MIPS64_FPR_BASE + (regno - gdbarch_fp0_regnum (gdbarch));
  else if (regno == mips_regnum (gdbarch)->pc)
  else if (regno == mips_regnum (gdbarch)->pc)
    regaddr = MIPS64_PC;
    regaddr = MIPS64_PC;
  else if (regno == mips_regnum (gdbarch)->cause)
  else if (regno == mips_regnum (gdbarch)->cause)
    regaddr = store? (CORE_ADDR) -1 : MIPS64_CAUSE;
    regaddr = store? (CORE_ADDR) -1 : MIPS64_CAUSE;
  else if (regno == mips_regnum (gdbarch)->badvaddr)
  else if (regno == mips_regnum (gdbarch)->badvaddr)
    regaddr = store? (CORE_ADDR) -1 : MIPS64_BADVADDR;
    regaddr = store? (CORE_ADDR) -1 : MIPS64_BADVADDR;
  else if (regno == mips_regnum (gdbarch)->lo)
  else if (regno == mips_regnum (gdbarch)->lo)
    regaddr = MIPS64_MMLO;
    regaddr = MIPS64_MMLO;
  else if (regno == mips_regnum (gdbarch)->hi)
  else if (regno == mips_regnum (gdbarch)->hi)
    regaddr = MIPS64_MMHI;
    regaddr = MIPS64_MMHI;
  else if (regno == mips_regnum (gdbarch)->fp_control_status)
  else if (regno == mips_regnum (gdbarch)->fp_control_status)
    regaddr = MIPS64_FPC_CSR;
    regaddr = MIPS64_FPC_CSR;
  else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
  else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
    regaddr = store? (CORE_ADDR) -1 : MIPS64_FPC_EIR;
    regaddr = store? (CORE_ADDR) -1 : MIPS64_FPC_EIR;
  else if (mips_linux_restart_reg_p (gdbarch) && regno == MIPS_RESTART_REGNUM)
  else if (mips_linux_restart_reg_p (gdbarch) && regno == MIPS_RESTART_REGNUM)
    regaddr = 0;
    regaddr = 0;
  else
  else
    regaddr = (CORE_ADDR) -1;
    regaddr = (CORE_ADDR) -1;
 
 
  return regaddr;
  return regaddr;
}
}
 
 
/* Fetch the thread-local storage pointer for libthread_db.  */
/* Fetch the thread-local storage pointer for libthread_db.  */
 
 
ps_err_e
ps_err_e
ps_get_thread_area (const struct ps_prochandle *ph,
ps_get_thread_area (const struct ps_prochandle *ph,
                    lwpid_t lwpid, int idx, void **base)
                    lwpid_t lwpid, int idx, void **base)
{
{
  if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
  if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
    return PS_ERR;
    return PS_ERR;
 
 
  /* IDX is the bias from the thread pointer to the beginning of the
  /* IDX is the bias from the thread pointer to the beginning of the
     thread descriptor.  It has to be subtracted due to implementation
     thread descriptor.  It has to be subtracted due to implementation
     quirks in libthread_db.  */
     quirks in libthread_db.  */
  *base = (void *) ((char *)*base - idx);
  *base = (void *) ((char *)*base - idx);
 
 
  return PS_OK;
  return PS_OK;
}
}
 
 
/* Wrapper functions.  These are only used by libthread_db.  */
/* Wrapper functions.  These are only used by libthread_db.  */
 
 
void
void
supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
supply_gregset (struct regcache *regcache, const gdb_gregset_t *gregsetp)
{
{
  if (mips_isa_regsize (get_regcache_arch (regcache)) == 4)
  if (mips_isa_regsize (get_regcache_arch (regcache)) == 4)
    mips_supply_gregset (regcache, (const mips_elf_gregset_t *) gregsetp);
    mips_supply_gregset (regcache, (const mips_elf_gregset_t *) gregsetp);
  else
  else
    mips64_supply_gregset (regcache, (const mips64_elf_gregset_t *) gregsetp);
    mips64_supply_gregset (regcache, (const mips64_elf_gregset_t *) gregsetp);
}
}
 
 
void
void
fill_gregset (const struct regcache *regcache,
fill_gregset (const struct regcache *regcache,
              gdb_gregset_t *gregsetp, int regno)
              gdb_gregset_t *gregsetp, int regno)
{
{
  if (mips_isa_regsize (get_regcache_arch (regcache)) == 4)
  if (mips_isa_regsize (get_regcache_arch (regcache)) == 4)
    mips_fill_gregset (regcache, (mips_elf_gregset_t *) gregsetp, regno);
    mips_fill_gregset (regcache, (mips_elf_gregset_t *) gregsetp, regno);
  else
  else
    mips64_fill_gregset (regcache, (mips64_elf_gregset_t *) gregsetp, regno);
    mips64_fill_gregset (regcache, (mips64_elf_gregset_t *) gregsetp, regno);
}
}
 
 
void
void
supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregsetp)
{
{
  if (mips_isa_regsize (get_regcache_arch (regcache)) == 4)
  if (mips_isa_regsize (get_regcache_arch (regcache)) == 4)
    mips_supply_fpregset (regcache, (const mips_elf_fpregset_t *) fpregsetp);
    mips_supply_fpregset (regcache, (const mips_elf_fpregset_t *) fpregsetp);
  else
  else
    mips64_supply_fpregset (regcache, (const mips64_elf_fpregset_t *) fpregsetp);
    mips64_supply_fpregset (regcache, (const mips64_elf_fpregset_t *) fpregsetp);
}
}
 
 
void
void
fill_fpregset (const struct regcache *regcache,
fill_fpregset (const struct regcache *regcache,
               gdb_fpregset_t *fpregsetp, int regno)
               gdb_fpregset_t *fpregsetp, int regno)
{
{
  if (mips_isa_regsize (get_regcache_arch (regcache)) == 4)
  if (mips_isa_regsize (get_regcache_arch (regcache)) == 4)
    mips_fill_fpregset (regcache, (mips_elf_fpregset_t *) fpregsetp, regno);
    mips_fill_fpregset (regcache, (mips_elf_fpregset_t *) fpregsetp, regno);
  else
  else
    mips64_fill_fpregset (regcache, (mips64_elf_fpregset_t *) fpregsetp, regno);
    mips64_fill_fpregset (regcache, (mips64_elf_fpregset_t *) fpregsetp, regno);
}
}
 
 
 
 
/* Fetch REGNO (or all registers if REGNO == -1) from the target
/* Fetch REGNO (or all registers if REGNO == -1) from the target
   using PTRACE_GETREGS et al.  */
   using PTRACE_GETREGS et al.  */
 
 
static void
static void
mips64_linux_regsets_fetch_registers (struct regcache *regcache, int regno)
mips64_linux_regsets_fetch_registers (struct regcache *regcache, int regno)
{
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  int is_fp;
  int is_fp;
  int tid;
  int tid;
 
 
  if (regno >= mips_regnum (gdbarch)->fp0
  if (regno >= mips_regnum (gdbarch)->fp0
      && regno <= mips_regnum (gdbarch)->fp0 + 32)
      && regno <= mips_regnum (gdbarch)->fp0 + 32)
    is_fp = 1;
    is_fp = 1;
  else if (regno == mips_regnum (gdbarch)->fp_control_status)
  else if (regno == mips_regnum (gdbarch)->fp_control_status)
    is_fp = 1;
    is_fp = 1;
  else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
  else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
    is_fp = 1;
    is_fp = 1;
  else
  else
    is_fp = 0;
    is_fp = 0;
 
 
  tid = ptid_get_lwp (inferior_ptid);
  tid = ptid_get_lwp (inferior_ptid);
  if (tid == 0)
  if (tid == 0)
    tid = ptid_get_pid (inferior_ptid);
    tid = ptid_get_pid (inferior_ptid);
 
 
  if (regno == -1 || !is_fp)
  if (regno == -1 || !is_fp)
    {
    {
      mips64_elf_gregset_t regs;
      mips64_elf_gregset_t regs;
 
 
      if (ptrace (PTRACE_GETREGS, tid, 0L, (PTRACE_TYPE_ARG3) &regs) == -1)
      if (ptrace (PTRACE_GETREGS, tid, 0L, (PTRACE_TYPE_ARG3) &regs) == -1)
        {
        {
          if (errno == EIO)
          if (errno == EIO)
            {
            {
              have_ptrace_regsets = 0;
              have_ptrace_regsets = 0;
              return;
              return;
            }
            }
          perror_with_name (_("Couldn't get registers"));
          perror_with_name (_("Couldn't get registers"));
        }
        }
 
 
      mips64_supply_gregset (regcache,
      mips64_supply_gregset (regcache,
                             (const mips64_elf_gregset_t *) &regs);
                             (const mips64_elf_gregset_t *) &regs);
    }
    }
 
 
  if (regno == -1 || is_fp)
  if (regno == -1 || is_fp)
    {
    {
      mips64_elf_fpregset_t fp_regs;
      mips64_elf_fpregset_t fp_regs;
 
 
      if (ptrace (PTRACE_GETFPREGS, tid, 0L,
      if (ptrace (PTRACE_GETFPREGS, tid, 0L,
                  (PTRACE_TYPE_ARG3) &fp_regs) == -1)
                  (PTRACE_TYPE_ARG3) &fp_regs) == -1)
        {
        {
          if (errno == EIO)
          if (errno == EIO)
            {
            {
              have_ptrace_regsets = 0;
              have_ptrace_regsets = 0;
              return;
              return;
            }
            }
          perror_with_name (_("Couldn't get FP registers"));
          perror_with_name (_("Couldn't get FP registers"));
        }
        }
 
 
      mips64_supply_fpregset (regcache,
      mips64_supply_fpregset (regcache,
                              (const mips64_elf_fpregset_t *) &fp_regs);
                              (const mips64_elf_fpregset_t *) &fp_regs);
    }
    }
}
}
 
 
/* Store REGNO (or all registers if REGNO == -1) to the target
/* Store REGNO (or all registers if REGNO == -1) to the target
   using PTRACE_SETREGS et al.  */
   using PTRACE_SETREGS et al.  */
 
 
static void
static void
mips64_linux_regsets_store_registers (const struct regcache *regcache, int regno)
mips64_linux_regsets_store_registers (const struct regcache *regcache, int regno)
{
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  int is_fp;
  int is_fp;
  int tid;
  int tid;
 
 
  if (regno >= mips_regnum (gdbarch)->fp0
  if (regno >= mips_regnum (gdbarch)->fp0
      && regno <= mips_regnum (gdbarch)->fp0 + 32)
      && regno <= mips_regnum (gdbarch)->fp0 + 32)
    is_fp = 1;
    is_fp = 1;
  else if (regno == mips_regnum (gdbarch)->fp_control_status)
  else if (regno == mips_regnum (gdbarch)->fp_control_status)
    is_fp = 1;
    is_fp = 1;
  else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
  else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
    is_fp = 1;
    is_fp = 1;
  else
  else
    is_fp = 0;
    is_fp = 0;
 
 
  tid = ptid_get_lwp (inferior_ptid);
  tid = ptid_get_lwp (inferior_ptid);
  if (tid == 0)
  if (tid == 0)
    tid = ptid_get_pid (inferior_ptid);
    tid = ptid_get_pid (inferior_ptid);
 
 
  if (regno == -1 || !is_fp)
  if (regno == -1 || !is_fp)
    {
    {
      mips64_elf_gregset_t regs;
      mips64_elf_gregset_t regs;
 
 
      if (ptrace (PTRACE_GETREGS, tid, 0L, (PTRACE_TYPE_ARG3) &regs) == -1)
      if (ptrace (PTRACE_GETREGS, tid, 0L, (PTRACE_TYPE_ARG3) &regs) == -1)
        perror_with_name (_("Couldn't get registers"));
        perror_with_name (_("Couldn't get registers"));
 
 
      mips64_fill_gregset (regcache, &regs, regno);
      mips64_fill_gregset (regcache, &regs, regno);
 
 
      if (ptrace (PTRACE_SETREGS, tid, 0L, (PTRACE_TYPE_ARG3) &regs) == -1)
      if (ptrace (PTRACE_SETREGS, tid, 0L, (PTRACE_TYPE_ARG3) &regs) == -1)
        perror_with_name (_("Couldn't set registers"));
        perror_with_name (_("Couldn't set registers"));
    }
    }
 
 
  if (regno == -1 || is_fp)
  if (regno == -1 || is_fp)
    {
    {
      mips64_elf_fpregset_t fp_regs;
      mips64_elf_fpregset_t fp_regs;
 
 
      if (ptrace (PTRACE_GETFPREGS, tid, 0L,
      if (ptrace (PTRACE_GETFPREGS, tid, 0L,
                  (PTRACE_TYPE_ARG3) &fp_regs) == -1)
                  (PTRACE_TYPE_ARG3) &fp_regs) == -1)
        perror_with_name (_("Couldn't get FP registers"));
        perror_with_name (_("Couldn't get FP registers"));
 
 
      mips64_fill_fpregset (regcache, &fp_regs, regno);
      mips64_fill_fpregset (regcache, &fp_regs, regno);
 
 
      if (ptrace (PTRACE_SETFPREGS, tid, 0L,
      if (ptrace (PTRACE_SETFPREGS, tid, 0L,
                  (PTRACE_TYPE_ARG3) &fp_regs) == -1)
                  (PTRACE_TYPE_ARG3) &fp_regs) == -1)
        perror_with_name (_("Couldn't set FP registers"));
        perror_with_name (_("Couldn't set FP registers"));
    }
    }
}
}
 
 
/* Fetch REGNO (or all registers if REGNO == -1) from the target
/* Fetch REGNO (or all registers if REGNO == -1) from the target
   using any working method.  */
   using any working method.  */
 
 
static void
static void
mips64_linux_fetch_registers (struct regcache *regcache, int regnum)
mips64_linux_fetch_registers (struct regcache *regcache, int regnum)
{
{
  /* Unless we already know that PTRACE_GETREGS does not work, try it.  */
  /* Unless we already know that PTRACE_GETREGS does not work, try it.  */
  if (have_ptrace_regsets)
  if (have_ptrace_regsets)
    mips64_linux_regsets_fetch_registers (regcache, regnum);
    mips64_linux_regsets_fetch_registers (regcache, regnum);
 
 
  /* If we know, or just found out, that PTRACE_GETREGS does not work, fall
  /* If we know, or just found out, that PTRACE_GETREGS does not work, fall
     back to PTRACE_PEEKUSER.  */
     back to PTRACE_PEEKUSER.  */
  if (!have_ptrace_regsets)
  if (!have_ptrace_regsets)
    super_fetch_registers (regcache, regnum);
    super_fetch_registers (regcache, regnum);
}
}
 
 
/* Store REGNO (or all registers if REGNO == -1) to the target
/* Store REGNO (or all registers if REGNO == -1) to the target
   using any working method.  */
   using any working method.  */
 
 
static void
static void
mips64_linux_store_registers (struct regcache *regcache, int regnum)
mips64_linux_store_registers (struct regcache *regcache, int regnum)
{
{
  /* Unless we already know that PTRACE_GETREGS does not work, try it.  */
  /* Unless we already know that PTRACE_GETREGS does not work, try it.  */
  if (have_ptrace_regsets)
  if (have_ptrace_regsets)
    mips64_linux_regsets_store_registers (regcache, regnum);
    mips64_linux_regsets_store_registers (regcache, regnum);
 
 
  /* If we know, or just found out, that PTRACE_GETREGS does not work, fall
  /* If we know, or just found out, that PTRACE_GETREGS does not work, fall
     back to PTRACE_PEEKUSER.  */
     back to PTRACE_PEEKUSER.  */
  if (!have_ptrace_regsets)
  if (!have_ptrace_regsets)
    super_store_registers (regcache, regnum);
    super_store_registers (regcache, regnum);
}
}
 
 
/* Return the address in the core dump or inferior of register
/* Return the address in the core dump or inferior of register
   REGNO.  */
   REGNO.  */
 
 
static CORE_ADDR
static CORE_ADDR
mips_linux_register_u_offset (struct gdbarch *gdbarch, int regno, int store_p)
mips_linux_register_u_offset (struct gdbarch *gdbarch, int regno, int store_p)
{
{
  if (mips_abi_regsize (gdbarch) == 8)
  if (mips_abi_regsize (gdbarch) == 8)
    return mips64_linux_register_addr (gdbarch, regno, store_p);
    return mips64_linux_register_addr (gdbarch, regno, store_p);
  else
  else
    return mips_linux_register_addr (gdbarch, regno, store_p);
    return mips_linux_register_addr (gdbarch, regno, store_p);
}
}
 
 
static const struct target_desc *
static const struct target_desc *
mips_linux_read_description (struct target_ops *ops)
mips_linux_read_description (struct target_ops *ops)
{
{
  /* Report that target registers are a size we know for sure
  /* Report that target registers are a size we know for sure
     that we can get from ptrace.  */
     that we can get from ptrace.  */
  if (_MIPS_SIM == _ABIO32)
  if (_MIPS_SIM == _ABIO32)
    return tdesc_mips_linux;
    return tdesc_mips_linux;
  else
  else
    return tdesc_mips64_linux;
    return tdesc_mips64_linux;
}
}
 
 
void _initialize_mips_linux_nat (void);
void _initialize_mips_linux_nat (void);
 
 
void
void
_initialize_mips_linux_nat (void)
_initialize_mips_linux_nat (void)
{
{
  struct target_ops *t = linux_trad_target (mips_linux_register_u_offset);
  struct target_ops *t = linux_trad_target (mips_linux_register_u_offset);
 
 
  super_fetch_registers = t->to_fetch_registers;
  super_fetch_registers = t->to_fetch_registers;
  super_store_registers = t->to_store_registers;
  super_store_registers = t->to_store_registers;
 
 
  t->to_fetch_registers = mips64_linux_fetch_registers;
  t->to_fetch_registers = mips64_linux_fetch_registers;
  t->to_store_registers = mips64_linux_store_registers;
  t->to_store_registers = mips64_linux_store_registers;
 
 
  t->to_read_description = mips_linux_read_description;
  t->to_read_description = mips_linux_read_description;
 
 
  linux_nat_add_target (t);
  linux_nat_add_target (t);
 
 
  /* Initialize the standard target descriptions.  */
  /* Initialize the standard target descriptions.  */
  initialize_tdesc_mips_linux ();
  initialize_tdesc_mips_linux ();
  initialize_tdesc_mips64_linux ();
  initialize_tdesc_mips64_linux ();
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.