This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFA] Add sparc-linux-tdep


"David S. Miller" wrote:
> 
> [ Assuming the Sparc OS tdep changes get approved. ]

This is OK in principal; but I note that you have cloned
some functions from i386-linux-tdep and/or arm-linux-tdep, 
and that now we have at least three duplicate versions of
these functions.

I wonder if it's time for some sort of "all-linux-nat.c"
module, where code that's needed by all native linux gdbs
can be kept?

I'll fire this question off as a new thread.

> 
> This makes use of Sparc OS tdep for Linux/Sparc.  It adds signal frame
> recognition and also dynamic linker support.  It also takes care of
> the "long double is 8 bytes" issue.
> 
> Everything that can be multi-arch'd is.  I've noted the in comments
> labelled "TODO" in sparc-linux-tdep.c which routines still cannot be
> generically multi-arch'd so that I can take care of this later.
> 
> 2002-04-20  David S. Miller  <davem@redhat.com>
> 
>         * sparc-linux-tdep.c: New file.
>         * Makefile.in (ALLDEPFILES): Add sparc-linux-tdep.c
>         (sparc-linux-tdep.o): New dependencies.
>         (sparc-tdep.o): Add sparc-tdep.h dependency
>         * config/sparc/tm-linux.h (SIGCONTEXT_PC_OFFSET): Don't define.
>         (IN_SIGTRAMP, SKIP_SOLIB_RESOLVER, SKIP_PROLOGUE_FRAMELESS_P):
>         Define.
>         (sparc_linux_skip_prologue_frameless_p,
>         sparc_linux_skip_solib_resolver, sparc_linux_in_sigtramp):
>         Declare.
>         * config/sparc/tm-sp64linux.h (tm-sysv4.h): Don't include.
>         (tm-linux.h): Include this instead.
>         (SIGCONTEXT_PC_OFFSET, GDB_PTRACE_REGS64): Don't define.
>         (IN_SIGTRAMP, SKIP_SOLIB_RESOLVER, SKIP_PROLOGUE_FRAMELESS_P):
>         Define.
>         (sparc_linux_skip_prologue_frameless_p,
>         sparc_linux_skip_solib_resolver, sparc_linux_in_sigtramp):
>         Declare.
> 
> --- sparc-linux-tdep.c.~1~      Sat Apr 20 20:55:07 2002
> +++ sparc-linux-tdep.c  Sat Apr 20 21:50:48 2002
> @@ -0,0 +1,508 @@
> +/* Target-dependent code for GNU/Linux running on Sparc's, for GDB.
> +
> +   Copyright 2002 Free Software Foundation, Inc.
> +
> +   This file is part of GDB.
> +
> +   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
> +   the Free Software Foundation; either version 2 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program; if not, write to the Free Software
> +   Foundation, Inc., 59 Temple Place - Suite 330,
> +   Boston, MA 02111-1307, USA.  */
> +
> +#include "defs.h"
> +#include "arch-utils.h"
> +#include "frame.h"
> +#include "inferior.h"
> +#include "obstack.h"
> +#include "target.h"
> +#include "value.h"
> +#include "bfd.h"
> +#include "gdb_string.h"
> +#include "regcache.h"
> +
> +#include "gdbcore.h"
> +
> +#include "elf-bfd.h"
> +
> +#include "sparc-tdep.h"
> +
> +/* For sparc_linux_skip_solib_resolver.  */
> +#include "symtab.h"
> +#include "symfile.h"
> +#include "objfiles.h"
> +
> +#include "solib-svr4.h"                /* For struct link_map_offsets.  */
> +
> +/* Recognizing signal handler frames.  */
> +
> +/* GNU/Linux has two flavors of signals.  Normal signal handlers, and
> +   "realtime" (RT) signals.  The RT signals can provide additional
> +   information to the signal handler if the SA_SIGINFO flag is set
> +   when establishing a signal handler using `sigaction'.  It is not
> +   unlikely that future versions of GNU/Linux will support SA_SIGINFO
> +   for normal signals too.  */
> +
> +/* When the sparc Linux kernel calls a signal handler and the
> +   SA_RESTORER flag isn't set, the return address points to a bit of
> +   code on the stack.  This function returns whether the PC appears to
> +   be within this bit of code.
> +
> +   The instruction sequence for normal signals is
> +       mov __NR_sigreturn, %g1         ! hex: 0x821020d8
> +       ta  0x10                        ! hex: 0x91d02010
> +
> +   Checking for the code sequence should be somewhat reliable, because
> +   the effect is to call the system call sigreturn.  This is unlikely
> +   to occur anywhere other than a signal trampoline.
> +
> +   It kind of sucks that we have to read memory from the process in
> +   order to identify a signal trampoline, but there doesn't seem to be
> +   any other way.  The IN_SIGTRAMP macro in tm-linux.h arranges to
> +   only call us if no function name could be identified, which should
> +   be the case since the code is on the stack.  */
> +
> +#define LINUX_SIGTRAMP_WORD0   (0x821020d8)    /* mov __NR_sigreturn, %g1 */
> +#define LINUX_SIGTRAMP_WORD1   (0x91d02010)    /* ta  0x10 */
> +
> +#define LINUX_SIGTRAMP_LEN     (0x8)
> +
> +/* If PC is in a sigtramp routine, return the address of the start of
> +   the routine.  Otherwise, return 0.  */
> +
> +static CORE_ADDR
> +sparc_linux_sigtramp_start (CORE_ADDR pc)
> +{
> +  unsigned int buf[LINUX_SIGTRAMP_LEN / sizeof(unsigned int)];
> +
> +  /* We only recognize a signal trampoline if PC is at the start of
> +     one of the three instructions.  We optimize for finding the PC at
> +     the start, as will be the case when the trampoline is not the
> +     first frame on the stack.  We assume that in the case where the
> +     PC is not at the start of the instruction sequence, there will be
> +     a few trailing readable bytes on the stack.  */
> +
> +  if (read_memory_nobpt (pc, (char *) buf, LINUX_SIGTRAMP_LEN) != 0)
> +    return 0;
> +
> +  if (buf[0] != LINUX_SIGTRAMP_WORD0)
> +    {
> +      if (buf[0] != LINUX_SIGTRAMP_WORD1)
> +       return 0;
> +
> +      pc -= 4;
> +
> +      if (read_memory_nobpt(pc, (char *) buf, LINUX_SIGTRAMP_LEN) != 0)
> +       return 0;
> +    }
> +
> +  if (buf[0] != LINUX_SIGTRAMP_WORD0
> +      || buf[1] != LINUX_SIGTRAMP_WORD1)
> +    return 0;
> +
> +  return pc;
> +}
> +
> +/* This function does the same for RT signals.  Here the instruction
> +   sequence is
> +       mov __NR_rt_sigreturn, %g1      ! hex: 0x82102065
> +       ta  {0x10,0x6d}                 ! hex: 0x91d02010 or 0x91d0206d
> +
> +   The effect is to call the system call rt_sigreturn.  The trap number
> +   is variable based upon whether this is a 32-bit or 64-bit sparc binary.
> +   Note that 64-bit binaries only use this RT signal return method.  */
> +
> +#define LINUX_RT_SIGTRAMP_WORD0                (0x82102065)
> +#define LINUX_RT_SIGTRAMP_WORD1_32     (0x91d02010)
> +#define LINUX_RT_SIGTRAMP_WORD1_64     (0x91d0206d)
> +
> +#define LINUX_RT_SIGTRAMP_LEN          8
> +
> +/* If PC is in a RT sigtramp routine, return the address of the start
> +   of the routine.  Otherwise, return 0.  */
> +
> +static CORE_ADDR
> +sparc_linux_rt_sigtramp_start (CORE_ADDR pc)
> +{
> +  unsigned int buf[LINUX_RT_SIGTRAMP_LEN / sizeof(unsigned int)];
> +
> +  /* We only recognize a signal trampoline if PC is at the start of
> +     one of the two instructions.  We optimize for finding the PC at
> +     the start, as will be the case when the trampoline is not the
> +     first frame on the stack.  We assume that in the case where the
> +     PC is not at the start of the instruction sequence, there will be
> +     a few trailing readable bytes on the stack.  */
> +
> +  if (read_memory_nobpt (pc, (char *) buf, LINUX_RT_SIGTRAMP_LEN) != 0)
> +    return 0;
> +
> +  if (buf[0] != LINUX_RT_SIGTRAMP_WORD0)
> +    {
> +      if (buf[0] != LINUX_RT_SIGTRAMP_WORD1_32
> +         && buf[0] != LINUX_RT_SIGTRAMP_WORD1_64)
> +       return 0;
> +
> +      pc -= 4;
> +
> +      if (read_memory_nobpt (pc, (char *) buf, LINUX_RT_SIGTRAMP_LEN) != 0)
> +       return 0;
> +    }
> +
> +  if (buf[0] != LINUX_RT_SIGTRAMP_WORD0
> +      || (buf[1] != LINUX_RT_SIGTRAMP_WORD1_32
> +         && buf[1] != LINUX_RT_SIGTRAMP_WORD1_64))
> +    return 0;
> +
> +  return pc;
> +}
> +
> +/* Return whether PC is in a GNU/Linux sigtramp routine.
> +
> +   TODO Need to generically multi-arch this. */
> +
> +int
> +sparc_linux_in_sigtramp (CORE_ADDR pc, char *name)
> +{
> +  int ret;
> +
> +  if (name)
> +    ret = (STREQ ("__sigreturn_stub", name) || STREQ ("__rt_sigreturn_stub", name));
> +  else
> +    ret = (sparc_linux_sigtramp_start (pc) != 0
> +          || sparc_linux_rt_sigtramp_start (pc) != 0);
> +
> +  return ret;
> +}
> +
> +/* Assuming FRAME is for a GNU/Linux sigtramp routine, return the
> +   PC/SP of the associated sigcontext structure.  */
> +
> +static CORE_ADDR
> +sparc_linux_sigtramp_saved_pc (struct frame_info *frame)
> +{
> +  CORE_ADDR ret;
> +  char *buf;
> +
> +  if (!frame->next)
> +    return 0;
> +
> +  buf = alloca(SPARC_INTREG_SIZE);
> +
> +  if (sparc_linux_sigtramp_start (frame->pc) != 0)
> +    {
> +      /* Stack frame is:
> +           standard 32-bit register window + slack     96 bytes
> +           siginfo_t                                   PC at offset 4  */
> +
> +      read_memory(frame->next->frame + (96 + 4), buf, SPARC_INTREG_SIZE);
> +
> +      ret = PC_ADJUST (extract_address (buf, SPARC_INTREG_SIZE));
> +
> +      return ret;
> +    }
> +
> +  if (sparc_linux_rt_sigtramp_start (frame->pc) != 0)
> +    {
> +      /* For 32-bit task, same as non-rt frame.  For 64-bit task
> +        the layout is:
> +             standard 64-bit register window + slack   192 bytes
> +             siginfo_t                                 128 bytes
> +             pt_regs                                   PC at offset 136  */
> +      if (! GDB_TARGET_IS_SPARC64)
> +       {
> +         read_memory(frame->next->frame + (96 + 4), buf, SPARC_INTREG_SIZE);
> +       }
> +      else
> +       {
> +         read_memory(frame->next->frame + (192 + 128 + 136), buf, SPARC_INTREG_SIZE);
> +       }
> +
> +      ret = PC_ADJUST (extract_address (buf, SPARC_INTREG_SIZE));
> +
> +      return ret;
> +    }
> +
> +  error ("Couldn't recognize signal trampoline.");
> +  return 0;
> +}
> +
> +extern CORE_ADDR sparc_frame_chain (struct frame_info *);
> +
> +static CORE_ADDR
> +sparc_linux_frame_chain (struct frame_info *frame)
> +{
> +  if (frame->signal_handler_caller)
> +    return frame->frame;
> +
> +  return sparc_frame_chain (frame);
> +}
> +
> +extern CORE_ADDR sparc_frame_saved_pc (struct frame_info *);
> +
> +/* Return the saved program counter for FRAME.  */
> +
> +static CORE_ADDR
> +sparc_linux_frame_saved_pc (struct frame_info *frame)
> +{
> +  CORE_ADDR ret;
> +
> +  if (frame->signal_handler_caller)
> +    ret = sparc_linux_sigtramp_saved_pc (frame);
> +  else
> +    ret = sparc_frame_saved_pc (frame);
> +
> +  return ret;
> +}
> +
> +static CORE_ADDR
> +sparc_linux_saved_pc_after_call (struct frame_info *frame)
> +{
> +  CORE_ADDR ret;
> +
> +  if (frame->signal_handler_caller)
> +    ret = sparc_linux_sigtramp_saved_pc (frame);
> +  else
> +    ret = sparc_pc_adjust (read_register (RP_REGNUM));
> +
> +  return ret;
> +}
> +
> +/* Calling functions in shared libraries.  */
> +
> +/* Find the minimal symbol named NAME, and return both the minsym
> +   struct and its objfile.  This probably ought to be in minsym.c, but
> +   everything there is trying to deal with things like C++ and
> +   SOFUN_ADDRESS_MAYBE_TURQUOISE, ...  Since this is so simple, it may
> +   be considered too special-purpose for general consumption.  */
> +
> +static struct minimal_symbol *
> +find_minsym_and_objfile (char *name, struct objfile **objfile_p)
> +{
> +  struct objfile *objfile;
> +
> +  ALL_OBJFILES (objfile)
> +    {
> +      struct minimal_symbol *msym;
> +
> +      ALL_OBJFILE_MSYMBOLS (objfile, msym)
> +       {
> +         if (SYMBOL_NAME (msym)
> +             && STREQ (SYMBOL_NAME (msym), name))
> +           {
> +             *objfile_p = objfile;
> +             return msym;
> +           }
> +       }
> +    }
> +
> +  return 0;
> +}
> +
> +static CORE_ADDR
> +skip_hurd_resolver (CORE_ADDR pc)
> +{
> +  /* The HURD dynamic linker is part of the GNU C library, so many
> +     GNU/Linux distributions use it.  (All ELF versions, as far as I
> +     know.)  An unresolved PLT entry points to "_dl_runtime_resolve",
> +     which calls "fixup" to patch the PLT, and then passes control to
> +     the function.
> +
> +     We look for the symbol `_dl_runtime_resolve', and find `fixup' in
> +     the same objfile.  If we are at the entry point of `fixup', then
> +     we set a breakpoint at the return address (at the top of the
> +     stack), and continue.
> +
> +     It's kind of gross to do all these checks every time we're
> +     called, since they don't change once the executable has gotten
> +     started.  But this is only a temporary hack --- upcoming versions
> +     of GNU/Linux will provide a portable, efficient interface for
> +     debugging programs that use shared libraries.  */
> +
> +  struct objfile *objfile;
> +  struct minimal_symbol *resolver
> +    = find_minsym_and_objfile ("_dl_runtime_resolve", &objfile);
> +
> +  if (resolver)
> +    {
> +      struct minimal_symbol *fixup
> +       = lookup_minimal_symbol ("fixup", NULL, objfile);
> +
> +      if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc)
> +       return (SAVED_PC_AFTER_CALL (get_current_frame ()));
> +
> +      fixup = lookup_minimal_symbol("profile_fixup", NULL, objfile);
> +      if (fixup && SYMBOL_VALUE_ADDRESS (fixup) == pc)
> +       return (SAVED_PC_AFTER_CALL (get_current_frame ()));
> +    }
> +
> +  return 0;
> +}
> +
> +/* See the comments for SKIP_SOLIB_RESOLVER at the top of infrun.c.
> +   This function:
> +   1) decides whether a PLT has sent us into the linker to resolve
> +      a function reference, and
> +   2) if so, tells us where to set a temporary breakpoint that will
> +      trigger when the dynamic linker is done.
> +
> +   TODO Need to generically multi-arch this thing.  */
> +
> +CORE_ADDR
> +sparc_linux_skip_solib_resolver (CORE_ADDR pc)
> +{
> +  CORE_ADDR result;
> +
> +  /* Plug in functions for other kinds of resolvers here.  */
> +  result = skip_hurd_resolver (pc);
> +  if (result)
> +    return result;
> +
> +  return 0;
> +}
> +
> +/* We need special processing here because 'fixup' in the dynamic linker
> +   looks like it is frameless, but it really does get a frame from its
> +   caller in the PLT (which does save).
> +
> +   Actually, any piece of code which has the same pettern, ie.:
> +
> +       place1:         save
> +                       call place2
> +                        nop
> +
> +       place2:         call place3
> +                        nop
> +                       jmp  %reg
> +                       restore
> +
> +       place3:         save
> +                       ...
> +                       ret
> +                        restore
> +
> +   is going to confuse SKIP_PROLOGUE_FRAMELESS_P.  It is hard to
> +   formulate a generic fix for this that would not break on sibcalls.
> +
> +   TODO Need to generically multi-arch this.  */
> +
> +CORE_ADDR
> +sparc_linux_skip_prologue_frameless_p (CORE_ADDR pc)
> +{
> +  struct objfile *objfile;
> +  struct minimal_symbol *resolver
> +    = find_minsym_and_objfile ((GDB_TARGET_IS_SPARC64 ?
> +                               "_dl_runtime_resolve_0" :
> +                               "_dl_runtime_resolve"), &objfile);
> +
> +  if (resolver)
> +    {
> +      CORE_ADDR rpc = SYMBOL_VALUE_ADDRESS (resolver);
> +      int resolver_size = 0x60;
> +
> +      /* This size includes all of the resolver instances present.
> +        For example on sparc32 it includes _dl_runtime_resolve
> +        and _dl_profile_resolve, and on sparc64 it includes
> +        _dl_runtime_resolve_0 _dl_runtime_resolve_1 and
> +        _dl_profile_resolve.  It works because they are present
> +        one right after another in the dynamic linker.  */
> +      if (GDB_TARGET_IS_SPARC64)
> +       resolver_size = 0x100;
> +
> +      if (pc >= rpc && pc < (rpc + resolver_size))
> +       return pc + 4;
> +    }
> +  return sparc_skip_prologue (pc, 1);
> +}
> +
> +/* Fetch (and possibly build) an appropriate link_map_offsets
> +   structure for native GNU/Linux Sparc targets using the struct offsets
> +   defined in link.h (but without actual reference to that file).
> +
> +   This makes it possible to access GNU/Linux Sparc shared libraries from a
> +   GDB that was built on a different host platform (for cross debugging).
> +
> +   It also is needed to handle GDB multi-arch properly.  */
> +
> +static struct link_map_offsets *
> +sparc_linux_svr4_fetch_link_map_offsets (void)
> +{
> +  static struct link_map_offsets lmo;
> +  static struct link_map_offsets *lmp = NULL;
> +
> +  if (lmp == NULL)
> +    {
> +      lmp = &lmo;
> +
> +      if (! GDB_TARGET_IS_SPARC64)
> +       {
> +         lmo.r_debug_size = 8; /* The actual size is 20 bytes, but
> +                                  this is all we need.  */
> +         lmo.r_map_offset = 4;
> +         lmo.r_map_size   = 4;
> +         lmo.link_map_size = 20;
> +         lmo.l_addr_offset = 0;
> +         lmo.l_addr_size   = 4;
> +         lmo.l_name_offset = 4;
> +         lmo.l_name_size   = 4;
> +         lmo.l_next_offset = 12;
> +         lmo.l_next_size   = 4;
> +         lmo.l_prev_offset = 16;
> +         lmo.l_prev_size   = 4;
> +       }
> +      else
> +       {
> +         lmo.r_debug_size = 16; /* The actual size is 40 bytes, but
> +                                   this is all we need.  */
> +         lmo.r_map_offset = 8;
> +         lmo.r_map_size   = 8;
> +         lmo.link_map_size = 40;
> +         lmo.l_addr_offset = 0;
> +         lmo.l_addr_size   = 8;
> +         lmo.l_name_offset = 8;
> +         lmo.l_name_size   = 8;
> +         lmo.l_next_offset = 24;
> +         lmo.l_next_size   = 8;
> +         lmo.l_prev_offset = 32;
> +         lmo.l_prev_size   = 8;
> +       }
> +    }
> +
> +  return lmp;
> +}
> +
> +static void
> +sparc_linux_gdbarch_os_init(struct gdbarch_info info, struct gdbarch *gdbarch)
> +{
> +  set_gdbarch_frame_chain (gdbarch, sparc_linux_frame_chain);
> +  set_gdbarch_frame_saved_pc (gdbarch, sparc_linux_frame_saved_pc);
> +  set_gdbarch_saved_pc_after_call (gdbarch, sparc_linux_saved_pc_after_call);
> +
> +  if (gdbarch_tdep (gdbarch)->intreg_size == 4)
> +    {
> +      /* Contrary to the v8 ABI, we use an 8-byte long double
> +        in this configuration.  */
> +      set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
> +    }
> +  else
> +    {
> +      set_gdbarch_long_double_bit (gdbarch, 16 * TARGET_CHAR_BIT);
> +    }
> +
> +  set_solib_svr4_fetch_link_map_offsets (gdbarch,
> +                                        sparc_linux_svr4_fetch_link_map_offsets);
> +}
> +
> +void
> +_initialize_sparc_linux_tdep (void)
> +{
> +  sparc_gdbarch_register_os_abi (ELFOSABI_LINUX, sparc_linux_gdbarch_os_init);
> +}
> --- Makefile.in.~2~     Sat Apr 20 20:04:36 2002
> +++ Makefile.in Sat Apr 20 21:04:24 2002
> @@ -1213,7 +1213,7 @@
>         ser-go32.c ser-pipe.c ser-tcp.c \
>         sh-tdep.c solib.c solib-svr4.c solib-sunos.c sparc-linux-nat.c \
>         sparc-nat.c \
> -       sparc-tdep.c sparcl-tdep.c sun3-nat.c \
> +       sparc-tdep.c sparcl-tdep.c sparc-linux-tdep.c sun3-nat.c \
>         symm-tdep.c symm-nat.c \
>         vax-tdep.c \
>         vx-share/xdr_ld.c vx-share/xdr_ptrace.c vx-share/xdr_rdb.c \
> @@ -2048,12 +2048,17 @@
> 
>  sparc-linux-nat.o: sparc-linux-nat.c $(defs_h) $(regcache_h)
> 
> +sparc-linux-tdep.o: sparc-linux-tdep.c $(defs_h) $(arch_utils_h) $(frame_h) \
> +       $(inferior_h) $(obstack_h) $(target_h) $(value_h) $(bfd_h) \
> +       $(gdb_string_h) $(regcache_h) $(gdbcore_h) $(symtab_h) $(symfile_h) \
> +       $(objdiles_h) $(solib_svr4_h) $(BFD_SRC)/elf-bfd.h sparc-tdep.h
> +
>  sparc-nat.o: sparc-nat.c $(bfd_h) $(defs_h) $(inferior_h) $(gdbcore_h) \
>         $(target_h) $(regcache_h)
> 
>  sparc-tdep.o: sparc-tdep.c $(floatformat_h) $(defs_h) $(gdbcore_h) \
>         $(inferior_h) $(objfiles_h) $(symfile_h) $(target_h) $(gdb_string_h) \
> -       $(arch_utils_h) $(regcache_h) $(BFD_SRC)/elf-bfd.h
> +       $(arch_utils_h) $(regcache_h) $(BFD_SRC)/elf-bfd.h sparc-tdep.h
> 
>  sparcl-tdep.o: sparcl-tdep.c $(defs_h) $(gdbcore_h) $(target_h) $(regcache_h)
> 
> --- config/sparc/tm-linux.h.~1~ Sat Apr 20 18:47:06 2002
> +++ config/sparc/tm-linux.h     Sat Apr 20 20:53:49 2002
> @@ -27,8 +27,26 @@
> 
>  #include "sparc/tm-sparc.h"
> 
> -#define SIGCONTEXT_PC_OFFSET 12
> -
>  #include "tm-linux.h"
> +
> +/* When the sparc Linux kernel calls a signal handler, the return
> +   address points to a bit of code on the stack.  These definitions
> +   are used to identify this bit of code as a signal trampoline in
> +   order to support backtracing through calls to signal handlers.  */
> +
> +#define IN_SIGTRAMP(pc, name) sparc_linux_in_sigtramp (pc, name)
> +extern int sparc_linux_in_sigtramp (CORE_ADDR, char *);
> +
> +/* When we call a function in a shared library, and the PLT sends us
> +   into the dynamic linker to find the function's real address, we
> +   need to skip over the dynamic linker call.  This function decides
> +   when to skip, and where to skip to.  See the comments for
> +   SKIP_SOLIB_RESOLVER at the top of infrun.c.  */
> +#define SKIP_SOLIB_RESOLVER sparc_linux_skip_solib_resolver
> +extern CORE_ADDR sparc_linux_skip_solib_resolver (CORE_ADDR pc);
> +
> +#undef SKIP_PROLOGUE_FRAMELESS_P
> +#define SKIP_PROLOGUE_FRAMELESS_P(PC) sparc_linux_skip_prologue_frameless_p (PC)
> +extern CORE_ADDR sparc_linux_skip_prologue_frameless_p (CORE_ADDR pc);
> 
>  #endif /* TM_SPARCLINUX_H */
> --- config/sparc/tm-sp64linux.h.~1~     Sat Apr 20 18:47:06 2002
> +++ config/sparc/tm-sp64linux.h Sat Apr 20 20:54:24 2002
> @@ -23,14 +23,31 @@ Foundation, Inc., 59 Temple Place - Suit
> 
>  #include "sparc/tm-sp64.h"
> 
> -#define SIGCONTEXT_PC_OFFSET 16  /* See asm-sparc64/sigcontext.h */
> -
>  /* We always want full V9 + Ultra VIS stuff... */
>  #undef TM_PRINT_INSN_MACH
>  #define TM_PRINT_INSN_MACH bfd_mach_sparc_v9a
> 
> -#define GDB_PTRACE_REGS64
> +#include "tm-linux.h"
> +
> +
> +/* When the sparc Linux kernel calls a signal handler, the return
> +   address points to a bit of code on the stack.  These definitions
> +   are used to identify this bit of code as a signal trampoline in
> +   order to support backtracing through calls to signal handlers.  */
> +
> +#define IN_SIGTRAMP(pc, name) sparc_linux_in_sigtramp (pc, name)
> +extern int sparc_linux_in_sigtramp (CORE_ADDR, char *);
> +
> +/* When we call a function in a shared library, and the PLT sends us
> +   into the dynamic linker to find the function's real address, we
> +   need to skip over the dynamic linker call.  This function decides
> +   when to skip, and where to skip to.  See the comments for
> +   SKIP_SOLIB_RESOLVER at the top of infrun.c.  */
> +#define SKIP_SOLIB_RESOLVER sparc_linux_skip_solib_resolver
> +extern CORE_ADDR sparc_linux_skip_solib_resolver (CORE_ADDR pc);
> 
> -#include "tm-sysv4.h"
> +#undef SKIP_PROLOGUE_FRAMELESS_P
> +#define SKIP_PROLOGUE_FRAMELESS_P(PC) sparc_linux_skip_prologue_frameless_p (PC)
> +extern CORE_ADDR sparc_linux_skip_prologue_frameless_p (CORE_ADDR pc);
> 
> -#endif TM_SPARC_LIN64_H
> +#endif /* TM_SPARC_LIN64_H */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]