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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [gdb/] [sparc64-linux-tdep.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
/* Target-dependent code for GNU/Linux UltraSPARC.
/* Target-dependent code for GNU/Linux UltraSPARC.
 
 
   Copyright (C) 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
   Copyright (C) 2003, 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 "frame.h"
#include "frame.h"
#include "frame-unwind.h"
#include "frame-unwind.h"
#include "dwarf2-frame.h"
#include "dwarf2-frame.h"
#include "regset.h"
#include "regset.h"
#include "regcache.h"
#include "regcache.h"
#include "gdbarch.h"
#include "gdbarch.h"
#include "gdbcore.h"
#include "gdbcore.h"
#include "osabi.h"
#include "osabi.h"
#include "solib-svr4.h"
#include "solib-svr4.h"
#include "symtab.h"
#include "symtab.h"
#include "trad-frame.h"
#include "trad-frame.h"
#include "tramp-frame.h"
#include "tramp-frame.h"
 
 
#include "sparc64-tdep.h"
#include "sparc64-tdep.h"
 
 
/* Signal trampoline support.  */
/* Signal trampoline support.  */
 
 
static void sparc64_linux_sigframe_init (const struct tramp_frame *self,
static void sparc64_linux_sigframe_init (const struct tramp_frame *self,
                                         struct frame_info *next_frame,
                                         struct frame_info *next_frame,
                                         struct trad_frame_cache *this_cache,
                                         struct trad_frame_cache *this_cache,
                                         CORE_ADDR func);
                                         CORE_ADDR func);
 
 
/* See sparc-linux-tdep.c for details.  Note that 64-bit binaries only
/* See sparc-linux-tdep.c for details.  Note that 64-bit binaries only
   use RT signals.  */
   use RT signals.  */
 
 
static const struct tramp_frame sparc64_linux_rt_sigframe =
static const struct tramp_frame sparc64_linux_rt_sigframe =
{
{
  SIGTRAMP_FRAME,
  SIGTRAMP_FRAME,
  4,
  4,
  {
  {
    { 0x82102065, -1 },         /* mov __NR_rt_sigreturn, %g1 */
    { 0x82102065, -1 },         /* mov __NR_rt_sigreturn, %g1 */
    { 0x91d0206d, -1 },         /* ta  0x6d */
    { 0x91d0206d, -1 },         /* ta  0x6d */
    { TRAMP_SENTINEL_INSN, -1 }
    { TRAMP_SENTINEL_INSN, -1 }
  },
  },
  sparc64_linux_sigframe_init
  sparc64_linux_sigframe_init
};
};
 
 
static void
static void
sparc64_linux_sigframe_init (const struct tramp_frame *self,
sparc64_linux_sigframe_init (const struct tramp_frame *self,
                             struct frame_info *next_frame,
                             struct frame_info *next_frame,
                             struct trad_frame_cache *this_cache,
                             struct trad_frame_cache *this_cache,
                             CORE_ADDR func)
                             CORE_ADDR func)
{
{
  CORE_ADDR base, addr, sp_addr;
  CORE_ADDR base, addr, sp_addr;
  int regnum;
  int regnum;
 
 
  base = frame_unwind_register_unsigned (next_frame, SPARC_O1_REGNUM);
  base = frame_unwind_register_unsigned (next_frame, SPARC_O1_REGNUM);
  base += 128;
  base += 128;
 
 
  /* Offsets from <bits/sigcontext.h>.  */
  /* Offsets from <bits/sigcontext.h>.  */
 
 
  /* Since %g0 is always zero, keep the identity encoding.  */
  /* Since %g0 is always zero, keep the identity encoding.  */
  addr = base + 8;
  addr = base + 8;
  sp_addr = base + ((SPARC_SP_REGNUM - SPARC_G0_REGNUM) * 8);
  sp_addr = base + ((SPARC_SP_REGNUM - SPARC_G0_REGNUM) * 8);
  for (regnum = SPARC_G1_REGNUM; regnum <= SPARC_O7_REGNUM; regnum++)
  for (regnum = SPARC_G1_REGNUM; regnum <= SPARC_O7_REGNUM; regnum++)
    {
    {
      trad_frame_set_reg_addr (this_cache, regnum, addr);
      trad_frame_set_reg_addr (this_cache, regnum, addr);
      addr += 8;
      addr += 8;
    }
    }
 
 
  trad_frame_set_reg_addr (this_cache, SPARC64_STATE_REGNUM, addr + 0);
  trad_frame_set_reg_addr (this_cache, SPARC64_STATE_REGNUM, addr + 0);
  trad_frame_set_reg_addr (this_cache, SPARC64_PC_REGNUM, addr + 8);
  trad_frame_set_reg_addr (this_cache, SPARC64_PC_REGNUM, addr + 8);
  trad_frame_set_reg_addr (this_cache, SPARC64_NPC_REGNUM, addr + 16);
  trad_frame_set_reg_addr (this_cache, SPARC64_NPC_REGNUM, addr + 16);
  trad_frame_set_reg_addr (this_cache, SPARC64_Y_REGNUM, addr + 24);
  trad_frame_set_reg_addr (this_cache, SPARC64_Y_REGNUM, addr + 24);
  trad_frame_set_reg_addr (this_cache, SPARC64_FPRS_REGNUM, addr + 28);
  trad_frame_set_reg_addr (this_cache, SPARC64_FPRS_REGNUM, addr + 28);
 
 
  base = frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM);
  base = frame_unwind_register_unsigned (next_frame, SPARC_SP_REGNUM);
  if (base & 1)
  if (base & 1)
    base += BIAS;
    base += BIAS;
 
 
  addr = get_frame_memory_unsigned (next_frame, sp_addr, 8);
  addr = get_frame_memory_unsigned (next_frame, sp_addr, 8);
  if (addr & 1)
  if (addr & 1)
    addr += BIAS;
    addr += BIAS;
 
 
  for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
  for (regnum = SPARC_L0_REGNUM; regnum <= SPARC_I7_REGNUM; regnum++)
    {
    {
      trad_frame_set_reg_addr (this_cache, regnum, addr);
      trad_frame_set_reg_addr (this_cache, regnum, addr);
      addr += 8;
      addr += 8;
    }
    }
  trad_frame_set_id (this_cache, frame_id_build (base, func));
  trad_frame_set_id (this_cache, frame_id_build (base, func));
}
}


/* Return the address of a system call's alternative return
/* Return the address of a system call's alternative return
   address.  */
   address.  */
 
 
static CORE_ADDR
static CORE_ADDR
sparc64_linux_step_trap (struct frame_info *frame, unsigned long insn)
sparc64_linux_step_trap (struct frame_info *frame, unsigned long insn)
{
{
  if (insn == 0x91d0206d)
  if (insn == 0x91d0206d)
    {
    {
      ULONGEST sp = get_frame_register_unsigned (frame, SPARC_SP_REGNUM);
      ULONGEST sp = get_frame_register_unsigned (frame, SPARC_SP_REGNUM);
      if (sp & 1)
      if (sp & 1)
        sp += BIAS;
        sp += BIAS;
 
 
      /* The kernel puts the sigreturn registers on the stack,
      /* The kernel puts the sigreturn registers on the stack,
         and this is where the signal unwinding state is take from
         and this is where the signal unwinding state is take from
         when returning from a signal.
         when returning from a signal.
 
 
         A siginfo_t sits 192 bytes from the base of the stack.  This
         A siginfo_t sits 192 bytes from the base of the stack.  This
         siginfo_t is 128 bytes, and is followed by the sigreturn
         siginfo_t is 128 bytes, and is followed by the sigreturn
         register save area.  The saved PC sits at a 136 byte offset
         register save area.  The saved PC sits at a 136 byte offset
         into there.  */
         into there.  */
 
 
      return read_memory_unsigned_integer (sp + 192 + 128 + 136, 8);
      return read_memory_unsigned_integer (sp + 192 + 128 + 136, 8);
    }
    }
 
 
  return 0;
  return 0;
}
}


 
 
const struct sparc_gregset sparc64_linux_core_gregset =
const struct sparc_gregset sparc64_linux_core_gregset =
{
{
  32 * 8,                       /* %tstate */
  32 * 8,                       /* %tstate */
  33 * 8,                       /* %tpc */
  33 * 8,                       /* %tpc */
  34 * 8,                       /* %tnpc */
  34 * 8,                       /* %tnpc */
  35 * 8,                       /* %y */
  35 * 8,                       /* %y */
  -1,                           /* %wim */
  -1,                           /* %wim */
  -1,                           /* %tbr */
  -1,                           /* %tbr */
  1 * 8,                        /* %g1 */
  1 * 8,                        /* %g1 */
  16 * 8,                       /* %l0 */
  16 * 8,                       /* %l0 */
  8,                            /* y size */
  8,                            /* y size */
};
};


 
 
static void
static void
sparc64_linux_supply_core_gregset (const struct regset *regset,
sparc64_linux_supply_core_gregset (const struct regset *regset,
                                   struct regcache *regcache,
                                   struct regcache *regcache,
                                   int regnum, const void *gregs, size_t len)
                                   int regnum, const void *gregs, size_t len)
{
{
  sparc64_supply_gregset (&sparc64_linux_core_gregset, regcache, regnum, gregs);
  sparc64_supply_gregset (&sparc64_linux_core_gregset, regcache, regnum, gregs);
}
}
 
 
static void
static void
sparc64_linux_collect_core_gregset (const struct regset *regset,
sparc64_linux_collect_core_gregset (const struct regset *regset,
                                    const struct regcache *regcache,
                                    const struct regcache *regcache,
                                    int regnum, void *gregs, size_t len)
                                    int regnum, void *gregs, size_t len)
{
{
  sparc64_collect_gregset (&sparc64_linux_core_gregset, regcache, regnum, gregs);
  sparc64_collect_gregset (&sparc64_linux_core_gregset, regcache, regnum, gregs);
}
}
 
 
static void
static void
sparc64_linux_supply_core_fpregset (const struct regset *regset,
sparc64_linux_supply_core_fpregset (const struct regset *regset,
                                    struct regcache *regcache,
                                    struct regcache *regcache,
                                    int regnum, const void *fpregs, size_t len)
                                    int regnum, const void *fpregs, size_t len)
{
{
  sparc64_supply_fpregset (regcache, regnum, fpregs);
  sparc64_supply_fpregset (regcache, regnum, fpregs);
}
}
 
 
static void
static void
sparc64_linux_collect_core_fpregset (const struct regset *regset,
sparc64_linux_collect_core_fpregset (const struct regset *regset,
                                     const struct regcache *regcache,
                                     const struct regcache *regcache,
                                     int regnum, void *fpregs, size_t len)
                                     int regnum, void *fpregs, size_t len)
{
{
  sparc64_collect_fpregset (regcache, regnum, fpregs);
  sparc64_collect_fpregset (regcache, regnum, fpregs);
}
}
 
 


 
 
static void
static void
sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
 
  tdep->gregset = regset_alloc (gdbarch, sparc64_linux_supply_core_gregset,
  tdep->gregset = regset_alloc (gdbarch, sparc64_linux_supply_core_gregset,
                                sparc64_linux_collect_core_gregset);
                                sparc64_linux_collect_core_gregset);
  tdep->sizeof_gregset = 288;
  tdep->sizeof_gregset = 288;
 
 
  tdep->fpregset = regset_alloc (gdbarch, sparc64_linux_supply_core_fpregset,
  tdep->fpregset = regset_alloc (gdbarch, sparc64_linux_supply_core_fpregset,
                                 sparc64_linux_collect_core_fpregset);
                                 sparc64_linux_collect_core_fpregset);
  tdep->sizeof_fpregset = 280;
  tdep->sizeof_fpregset = 280;
 
 
  tramp_frame_prepend_unwinder (gdbarch, &sparc64_linux_rt_sigframe);
  tramp_frame_prepend_unwinder (gdbarch, &sparc64_linux_rt_sigframe);
 
 
  /* Hook in the DWARF CFI frame unwinder.  */
  /* Hook in the DWARF CFI frame unwinder.  */
  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
 
 
  sparc64_init_abi (info, gdbarch);
  sparc64_init_abi (info, gdbarch);
 
 
  /* GNU/Linux has SVR4-style shared libraries...  */
  /* GNU/Linux has SVR4-style shared libraries...  */
  set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
  set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
  set_solib_svr4_fetch_link_map_offsets
  set_solib_svr4_fetch_link_map_offsets
    (gdbarch, svr4_lp64_fetch_link_map_offsets);
    (gdbarch, svr4_lp64_fetch_link_map_offsets);
 
 
  /* ...which means that we need some special handling when doing
  /* ...which means that we need some special handling when doing
     prologue analysis.  */
     prologue analysis.  */
  tdep->plt_entry_size = 16;
  tdep->plt_entry_size = 16;
 
 
  /* Enable TLS support.  */
  /* Enable TLS support.  */
  set_gdbarch_fetch_tls_load_module_address (gdbarch,
  set_gdbarch_fetch_tls_load_module_address (gdbarch,
                                             svr4_fetch_objfile_link_map);
                                             svr4_fetch_objfile_link_map);
 
 
  /* Make sure we can single-step over signal return system calls.  */
  /* Make sure we can single-step over signal return system calls.  */
  tdep->step_trap = sparc64_linux_step_trap;
  tdep->step_trap = sparc64_linux_step_trap;
}
}


 
 
/* Provide a prototype to silence -Wmissing-prototypes.  */
/* Provide a prototype to silence -Wmissing-prototypes.  */
extern void _initialize_sparc64_linux_tdep (void);
extern void _initialize_sparc64_linux_tdep (void);
 
 
void
void
_initialize_sparc64_linux_tdep (void)
_initialize_sparc64_linux_tdep (void)
{
{
  gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
  gdbarch_register_osabi (bfd_arch_sparc, bfd_mach_sparc_v9,
                          GDB_OSABI_LINUX, sparc64_linux_init_abi);
                          GDB_OSABI_LINUX, sparc64_linux_init_abi);
}
}
 
 

powered by: WebSVN 2.1.0

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