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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [gdb/] [hppa-hpux-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 PA-RISC HP-UX.
/* Native-dependent code for PA-RISC HP-UX.
 
 
   Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
   Copyright (C) 2004, 2005, 2007, 2008 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 "regcache.h"
#include "regcache.h"
#include "target.h"
#include "target.h"
 
 
#include "gdb_assert.h"
#include "gdb_assert.h"
#include <sys/ptrace.h>
#include <sys/ptrace.h>
#include <machine/save_state.h>
#include <machine/save_state.h>
 
 
#ifdef HAVE_TTRACE
#ifdef HAVE_TTRACE
#include <sys/ttrace.h>
#include <sys/ttrace.h>
#endif
#endif
 
 
#include "hppa-tdep.h"
#include "hppa-tdep.h"
#include "inf-ptrace.h"
#include "inf-ptrace.h"
#include "inf-ttrace.h"
#include "inf-ttrace.h"
 
 
/* Non-zero if we should pretend not to be a runnable target.  */
/* Non-zero if we should pretend not to be a runnable target.  */
int child_suppress_run = 0;
int child_suppress_run = 0;
 
 
/* Return the offset of register REGNUM within `struct save_state'.
/* Return the offset of register REGNUM within `struct save_state'.
   The offset returns depends on the flags in the "flags" register and
   The offset returns depends on the flags in the "flags" register and
   the register size (32-bit or 64-bit).  These are taken from
   the register size (32-bit or 64-bit).  These are taken from
   REGCACHE.  */
   REGCACHE.  */
 
 
LONGEST
LONGEST
hppa_hpux_save_state_offset (struct regcache *regcache, int regnum)
hppa_hpux_save_state_offset (struct regcache *regcache, int regnum)
{
{
  LONGEST offset;
  LONGEST offset;
 
 
  if (regnum == HPPA_FLAGS_REGNUM)
  if (regnum == HPPA_FLAGS_REGNUM)
    return ssoff (ss_flags);
    return ssoff (ss_flags);
 
 
  if (HPPA_R0_REGNUM < regnum && regnum < HPPA_FP0_REGNUM)
  if (HPPA_R0_REGNUM < regnum && regnum < HPPA_FP0_REGNUM)
    {
    {
      struct gdbarch *arch = get_regcache_arch (regcache);
      struct gdbarch *arch = get_regcache_arch (regcache);
      size_t size = register_size (arch, HPPA_R1_REGNUM);
      size_t size = register_size (arch, HPPA_R1_REGNUM);
      ULONGEST flags;
      ULONGEST flags;
 
 
      gdb_assert (size == 4 || size == 8);
      gdb_assert (size == 4 || size == 8);
 
 
      regcache_cooked_read_unsigned (regcache, HPPA_FLAGS_REGNUM, &flags);
      regcache_cooked_read_unsigned (regcache, HPPA_FLAGS_REGNUM, &flags);
      if (flags & SS_WIDEREGS)
      if (flags & SS_WIDEREGS)
        offset = ssoff (ss_wide) + (8 - size) + (regnum - HPPA_R0_REGNUM) * 8;
        offset = ssoff (ss_wide) + (8 - size) + (regnum - HPPA_R0_REGNUM) * 8;
      else
      else
        offset = ssoff (ss_narrow) + (regnum - HPPA_R1_REGNUM) * 4;
        offset = ssoff (ss_narrow) + (regnum - HPPA_R1_REGNUM) * 4;
    }
    }
  else
  else
    {
    {
      struct gdbarch *arch = get_regcache_arch (regcache);
      struct gdbarch *arch = get_regcache_arch (regcache);
      size_t size = register_size (arch, HPPA_FP0_REGNUM);
      size_t size = register_size (arch, HPPA_FP0_REGNUM);
 
 
      gdb_assert (size == 4 || size == 8);
      gdb_assert (size == 4 || size == 8);
      gdb_assert (regnum >= HPPA_FP0_REGNUM);
      gdb_assert (regnum >= HPPA_FP0_REGNUM);
      offset = ssoff(ss_fpblock) + (regnum - HPPA_FP0_REGNUM) * size;
      offset = ssoff(ss_fpblock) + (regnum - HPPA_FP0_REGNUM) * size;
    }
    }
 
 
  gdb_assert (offset < sizeof (save_state_t));
  gdb_assert (offset < sizeof (save_state_t));
  return offset;
  return offset;
}
}
 
 
/* Just in case a future version of PA-RISC HP-UX won't have ptrace(2)
/* Just in case a future version of PA-RISC HP-UX won't have ptrace(2)
   at all.  */
   at all.  */
#ifndef PTRACE_TYPE_RET
#ifndef PTRACE_TYPE_RET
#define PTRACE_TYPE_RET void
#define PTRACE_TYPE_RET void
#endif
#endif
 
 
static void
static void
hppa_hpux_fetch_register (struct regcache *regcache, int regnum)
hppa_hpux_fetch_register (struct regcache *regcache, int regnum)
{
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  CORE_ADDR addr;
  CORE_ADDR addr;
  size_t size;
  size_t size;
  PTRACE_TYPE_RET *buf;
  PTRACE_TYPE_RET *buf;
  pid_t pid;
  pid_t pid;
  int i;
  int i;
 
 
  pid = ptid_get_pid (inferior_ptid);
  pid = ptid_get_pid (inferior_ptid);
 
 
  /* This isn't really an address, but ptrace thinks of it as one.  */
  /* This isn't really an address, but ptrace thinks of it as one.  */
  addr = hppa_hpux_save_state_offset (regcache, regnum);
  addr = hppa_hpux_save_state_offset (regcache, regnum);
  size = register_size (gdbarch, regnum);
  size = register_size (gdbarch, regnum);
 
 
  gdb_assert (size == 4 || size == 8);
  gdb_assert (size == 4 || size == 8);
  buf = alloca (size);
  buf = alloca (size);
 
 
#ifdef HAVE_TTRACE
#ifdef HAVE_TTRACE
  {
  {
    lwpid_t lwp = ptid_get_lwp (inferior_ptid);
    lwpid_t lwp = ptid_get_lwp (inferior_ptid);
 
 
    if (ttrace (TT_LWP_RUREGS, pid, lwp, addr, size, (uintptr_t)buf) == -1)
    if (ttrace (TT_LWP_RUREGS, pid, lwp, addr, size, (uintptr_t)buf) == -1)
      error (_("Couldn't read register %s (#%d): %s"),
      error (_("Couldn't read register %s (#%d): %s"),
             gdbarch_register_name (gdbarch, regnum),
             gdbarch_register_name (gdbarch, regnum),
             regnum, safe_strerror (errno));
             regnum, safe_strerror (errno));
  }
  }
#else
#else
  {
  {
    int i;
    int i;
 
 
    /* Read the register contents from the inferior a chuck at the time.  */
    /* Read the register contents from the inferior a chuck at the time.  */
    for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
    for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
      {
      {
        errno = 0;
        errno = 0;
        buf[i] = ptrace (PT_RUREGS, pid, (PTRACE_TYPE_ARG3) addr, 0, 0);
        buf[i] = ptrace (PT_RUREGS, pid, (PTRACE_TYPE_ARG3) addr, 0, 0);
        if (errno != 0)
        if (errno != 0)
          error (_("Couldn't read register %s (#%d): %s"),
          error (_("Couldn't read register %s (#%d): %s"),
                 gdbarch_register_name (gdbarch, regnum),
                 gdbarch_register_name (gdbarch, regnum),
                 regnum, safe_strerror (errno));
                 regnum, safe_strerror (errno));
 
 
        addr += sizeof (PTRACE_TYPE_RET);
        addr += sizeof (PTRACE_TYPE_RET);
      }
      }
  }
  }
#endif
#endif
 
 
  /* Take care with the "flags" register.  It's stored as an `int' in
  /* Take care with the "flags" register.  It's stored as an `int' in
     `struct save_state', even for 64-bit code.  */
     `struct save_state', even for 64-bit code.  */
  if (regnum == HPPA_FLAGS_REGNUM && size == 8)
  if (regnum == HPPA_FLAGS_REGNUM && size == 8)
    {
    {
      ULONGEST flags = extract_unsigned_integer ((gdb_byte *)buf, 4);
      ULONGEST flags = extract_unsigned_integer ((gdb_byte *)buf, 4);
      store_unsigned_integer ((gdb_byte *)buf, 8, flags);
      store_unsigned_integer ((gdb_byte *)buf, 8, flags);
    }
    }
 
 
  regcache_raw_supply (regcache, regnum, buf);
  regcache_raw_supply (regcache, regnum, buf);
}
}
 
 
static void
static void
hppa_hpux_fetch_inferior_registers (struct regcache *regcache, int regnum)
hppa_hpux_fetch_inferior_registers (struct regcache *regcache, int regnum)
{
{
  if (regnum == -1)
  if (regnum == -1)
    for (regnum = 0;
    for (regnum = 0;
         regnum < gdbarch_num_regs (get_regcache_arch (regcache));
         regnum < gdbarch_num_regs (get_regcache_arch (regcache));
         regnum++)
         regnum++)
      hppa_hpux_fetch_register (regcache, regnum);
      hppa_hpux_fetch_register (regcache, regnum);
  else
  else
    hppa_hpux_fetch_register (regcache, regnum);
    hppa_hpux_fetch_register (regcache, regnum);
}
}
 
 
/* Store register REGNUM into the inferior.  */
/* Store register REGNUM into the inferior.  */
 
 
static void
static void
hppa_hpux_store_register (struct regcache *regcache, int regnum)
hppa_hpux_store_register (struct regcache *regcache, int regnum)
{
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  CORE_ADDR addr;
  CORE_ADDR addr;
  size_t size;
  size_t size;
  PTRACE_TYPE_RET *buf;
  PTRACE_TYPE_RET *buf;
  pid_t pid;
  pid_t pid;
 
 
  pid = ptid_get_pid (inferior_ptid);
  pid = ptid_get_pid (inferior_ptid);
 
 
  /* This isn't really an address, but ptrace thinks of it as one.  */
  /* This isn't really an address, but ptrace thinks of it as one.  */
  addr = hppa_hpux_save_state_offset (regcache, regnum);
  addr = hppa_hpux_save_state_offset (regcache, regnum);
  size = register_size (gdbarch, regnum);
  size = register_size (gdbarch, regnum);
 
 
  gdb_assert (size == 4 || size == 8);
  gdb_assert (size == 4 || size == 8);
  buf = alloca (size);
  buf = alloca (size);
 
 
  regcache_raw_collect (regcache, regnum, buf);
  regcache_raw_collect (regcache, regnum, buf);
 
 
  /* Take care with the "flags" register.  It's stored as an `int' in
  /* Take care with the "flags" register.  It's stored as an `int' in
     `struct save_state', even for 64-bit code.  */
     `struct save_state', even for 64-bit code.  */
  if (regnum == HPPA_FLAGS_REGNUM && size == 8)
  if (regnum == HPPA_FLAGS_REGNUM && size == 8)
    {
    {
      ULONGEST flags = extract_unsigned_integer ((gdb_byte *)buf, 8);
      ULONGEST flags = extract_unsigned_integer ((gdb_byte *)buf, 8);
      store_unsigned_integer ((gdb_byte *)buf, 4, flags);
      store_unsigned_integer ((gdb_byte *)buf, 4, flags);
      size = 4;
      size = 4;
    }
    }
 
 
#ifdef HAVE_TTRACE
#ifdef HAVE_TTRACE
  {
  {
    lwpid_t lwp = ptid_get_lwp (inferior_ptid);
    lwpid_t lwp = ptid_get_lwp (inferior_ptid);
 
 
    if (ttrace (TT_LWP_WUREGS, pid, lwp, addr, size, (uintptr_t)buf) == -1)
    if (ttrace (TT_LWP_WUREGS, pid, lwp, addr, size, (uintptr_t)buf) == -1)
      error (_("Couldn't write register %s (#%d): %s"),
      error (_("Couldn't write register %s (#%d): %s"),
             gdbarch_register_name (gdbarch, regnum),
             gdbarch_register_name (gdbarch, regnum),
             regnum, safe_strerror (errno));
             regnum, safe_strerror (errno));
  }
  }
#else
#else
  {
  {
    int i;
    int i;
 
 
    /* Write the register contents into the inferior a chunk at the time.  */
    /* Write the register contents into the inferior a chunk at the time.  */
    for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
    for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
      {
      {
        errno = 0;
        errno = 0;
        ptrace (PT_WUREGS, pid, (PTRACE_TYPE_ARG3) addr, buf[i], 0);
        ptrace (PT_WUREGS, pid, (PTRACE_TYPE_ARG3) addr, buf[i], 0);
        if (errno != 0)
        if (errno != 0)
          error (_("Couldn't write register %s (#%d): %s"),
          error (_("Couldn't write register %s (#%d): %s"),
                 gdbarch_register_name (gdbarch, regnum),
                 gdbarch_register_name (gdbarch, regnum),
                 regnum, safe_strerror (errno));
                 regnum, safe_strerror (errno));
 
 
        addr += sizeof (PTRACE_TYPE_RET);
        addr += sizeof (PTRACE_TYPE_RET);
      }
      }
  }
  }
#endif
#endif
}
}
 
 
/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
   this for all registers (including the floating point registers).  */
   this for all registers (including the floating point registers).  */
 
 
static void
static void
hppa_hpux_store_inferior_registers (struct regcache *regcache, int regnum)
hppa_hpux_store_inferior_registers (struct regcache *regcache, int regnum)
{
{
  if (regnum == -1)
  if (regnum == -1)
    for (regnum = 0;
    for (regnum = 0;
         regnum < gdbarch_num_regs (get_regcache_arch (regcache));
         regnum < gdbarch_num_regs (get_regcache_arch (regcache));
         regnum++)
         regnum++)
      hppa_hpux_store_register (regcache, regnum);
      hppa_hpux_store_register (regcache, regnum);
  else
  else
    hppa_hpux_store_register (regcache, regnum);
    hppa_hpux_store_register (regcache, regnum);
}
}
 
 
static int
static int
hppa_hpux_child_can_run (void)
hppa_hpux_child_can_run (void)
{
{
  /* This variable is controlled by modules that layer their own
  /* This variable is controlled by modules that layer their own
     process structure atop that provided here.  The code in
     process structure atop that provided here.  The code in
     hpux-thread.c does this to support the HP-UX user-mode DCE
     hpux-thread.c does this to support the HP-UX user-mode DCE
     threads.  */
     threads.  */
  return !child_suppress_run;
  return !child_suppress_run;
}
}


 
 
/* Prevent warning from -Wmissing-prototypes.  */
/* Prevent warning from -Wmissing-prototypes.  */
void _initialize_hppa_hpux_nat (void);
void _initialize_hppa_hpux_nat (void);
 
 
void
void
_initialize_hppa_hpux_nat (void)
_initialize_hppa_hpux_nat (void)
{
{
  struct target_ops *t;
  struct target_ops *t;
 
 
#ifdef HAVE_TTRACE
#ifdef HAVE_TTRACE
  t = inf_ttrace_target ();
  t = inf_ttrace_target ();
#else
#else
  t = inf_ptrace_target ();
  t = inf_ptrace_target ();
#endif
#endif
 
 
  t->to_fetch_registers = hppa_hpux_fetch_inferior_registers;
  t->to_fetch_registers = hppa_hpux_fetch_inferior_registers;
  t->to_store_registers = hppa_hpux_store_inferior_registers;
  t->to_store_registers = hppa_hpux_store_inferior_registers;
  t->to_can_run = hppa_hpux_child_can_run;
  t->to_can_run = hppa_hpux_child_can_run;
 
 
  add_target (t);
  add_target (t);
}
}
 
 

powered by: WebSVN 2.1.0

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