Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/nathanw_sa]: src/gnu/dist/toolchain/gdb When removing a single-step brea...



details:   https://anonhg.NetBSD.org/src/rev/8288d58741dd
branches:  nathanw_sa
changeset: 505546:8288d58741dd
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Fri Jan 18 06:15:33 2002 +0000

description:
When removing a single-step breakpoint, fix-up the PC, since GDB does
not do for us in this case.

This fixes all sorts of random lossage with the new Alpha GDB, which,
as far as I can tell, works just fine now.

diffstat:

 gnu/dist/toolchain/gdb/alpha-tdep.c |  1567 +++++++++++++++++++++++++++++++++++
 1 files changed, 1567 insertions(+), 0 deletions(-)

diffs (truncated from 1571 to 300 lines):

diff -r 4da18d914e3f -r 8288d58741dd gnu/dist/toolchain/gdb/alpha-tdep.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/gnu/dist/toolchain/gdb/alpha-tdep.c       Fri Jan 18 06:15:33 2002 +0000
@@ -0,0 +1,1567 @@
+/* Target-dependent code for the ALPHA architecture, for GDB, the GNU Debugger.
+   Copyright 1993, 94, 95, 96, 97, 1998 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 "frame.h"
+#include "inferior.h"
+#include "symtab.h"
+#include "value.h"
+#include "gdbcmd.h"
+#include "gdbcore.h"
+#include "dis-asm.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdb_string.h"
+
+/* FIXME: Some of this code should perhaps be merged with mips-tdep.c.  */
+
+/* Prototypes for local functions. */
+
+static alpha_extra_func_info_t push_sigtramp_desc PARAMS ((CORE_ADDR low_addr));
+
+static CORE_ADDR read_next_frame_reg PARAMS ((struct frame_info *, int));
+
+static CORE_ADDR heuristic_proc_start PARAMS ((CORE_ADDR));
+
+static alpha_extra_func_info_t heuristic_proc_desc PARAMS ((CORE_ADDR,
+                                                           CORE_ADDR,
+                                                     struct frame_info *));
+
+static alpha_extra_func_info_t find_proc_desc PARAMS ((CORE_ADDR,
+                                                      struct frame_info *));
+
+#if 0
+static int alpha_in_lenient_prologue PARAMS ((CORE_ADDR, CORE_ADDR));
+#endif
+
+static void reinit_frame_cache_sfunc PARAMS ((char *, int,
+                                             struct cmd_list_element *));
+
+static CORE_ADDR after_prologue PARAMS ((CORE_ADDR pc,
+                                        alpha_extra_func_info_t proc_desc));
+
+static int alpha_in_prologue PARAMS ((CORE_ADDR pc,
+                                     alpha_extra_func_info_t proc_desc));
+
+static int alpha_about_to_return PARAMS ((CORE_ADDR pc));
+
+void _initialize_alpha_tdep PARAMS ((void));
+
+/* Heuristic_proc_start may hunt through the text section for a long
+   time across a 2400 baud serial line.  Allows the user to limit this
+   search.  */
+static unsigned int heuristic_fence_post = 0;
+/* *INDENT-OFF* */
+/* Layout of a stack frame on the alpha:
+
+                |                              |
+ pdr members:  |  7th ... nth arg,             |
+                |  `pushed' by caller.         |
+                |                              |
+----------------|-------------------------------|<--  old_sp == vfp
+   ^  ^  ^  ^  |                               |
+   |  |  |  |  |                               |
+   |  |localoff        |  Copies of 1st .. 6th         |
+   |  |  |  |  |  argument if necessary.       |
+   |  |  |  v  |                               |
+   |  |  |  ---        |-------------------------------|<-- FRAME_LOCALS_ADDRESS
+   |  |  |      |                              |
+   |  |  |      |  Locals and temporaries.     |
+   |  |  |      |                              |
+   |  |  |      |-------------------------------|
+   |  |  |      |                              |
+   |-fregoffset        |  Saved float registers.       |
+   |  |  |      |  F9                          |
+   |  |  |      |   .                          |
+   |  |  |      |   .                          |
+   |  |  |      |  F2                          |
+   |  |  v      |                              |
+   |  |  -------|-------------------------------|
+   |  |         |                              |
+   |  |         |  Saved registers.            |
+   |  |         |  S6                          |
+   |-regoffset |   .                           |
+   |  |         |   .                          |
+   |  |         |  S0                          |
+   |  |         |  pdr.pcreg                   |
+   |  v         |                              |
+   |  ----------|-------------------------------|
+   |            |                              |
+ frameoffset    |  Argument build area, gets   |
+   |            |  7th ... nth arg for any     |
+   |            |  called procedure.           |
+   v            |                              |
+   -------------|-------------------------------|<-- sp
+                |                              |
+*/
+/* *INDENT-ON* */
+
+
+
+#define PROC_LOW_ADDR(proc) ((proc)->pdr.adr)  /* least address */
+/* These next two fields are kind of being hijacked.  I wonder if
+   iline is too small for the values it needs to hold, if GDB is
+   running on a 32-bit host.  */
+#define PROC_HIGH_ADDR(proc) ((proc)->pdr.iline)       /* upper address bound */
+#define PROC_DUMMY_FRAME(proc) ((proc)->pdr.cbLineOffset)      /*CALL_DUMMY frame */
+#define PROC_FRAME_OFFSET(proc) ((proc)->pdr.frameoffset)
+#define PROC_FRAME_REG(proc) ((proc)->pdr.framereg)
+#define PROC_REG_MASK(proc) ((proc)->pdr.regmask)
+#define PROC_FREG_MASK(proc) ((proc)->pdr.fregmask)
+#define PROC_REG_OFFSET(proc) ((proc)->pdr.regoffset)
+#define PROC_FREG_OFFSET(proc) ((proc)->pdr.fregoffset)
+#define PROC_PC_REG(proc) ((proc)->pdr.pcreg)
+#define PROC_LOCALOFF(proc) ((proc)->pdr.localoff)
+#define PROC_SYMBOL(proc) (*(struct symbol**)&(proc)->pdr.isym)
+#define _PROC_MAGIC_ 0x0F0F0F0F
+#define PROC_DESC_IS_DUMMY(proc) ((proc)->pdr.isym == _PROC_MAGIC_)
+#define SET_PROC_DESC_IS_DUMMY(proc) ((proc)->pdr.isym = _PROC_MAGIC_)
+
+struct linked_proc_info
+  {
+    struct alpha_extra_func_info info;
+    struct linked_proc_info *next;
+  }
+ *linked_proc_desc_table = NULL;
+
+
+/* Under GNU/Linux, signal handler invocations can be identified by the
+   designated code sequence that is used to return from a signal
+   handler.  In particular, the return address of a signal handler
+   points to the following sequence (the first instruction is quadword
+   aligned):
+
+   bis $30,$30,$16
+   addq $31,0x67,$0
+   call_pal callsys
+
+   Each instruction has a unique encoding, so we simply attempt to
+   match the instruction the pc is pointing to with any of the above
+   instructions.  If there is a hit, we know the offset to the start
+   of the designated sequence and can then check whether we really are
+   executing in a designated sequence.  If not, -1 is returned,
+   otherwise the offset from the start of the desingated sequence is
+   returned.
+
+   There is a slight chance of false hits: code could jump into the
+   middle of the designated sequence, in which case there is no
+   guarantee that we are in the middle of a sigreturn syscall.  Don't
+   think this will be a problem in praxis, though.
+ */
+
+#ifndef TM_LINUXALPHA_H
+/* HACK: Provide a prototype when compiling this file for non
+   linuxalpha targets. */
+long alpha_linux_sigtramp_offset PARAMS ((CORE_ADDR pc));
+#endif
+long
+alpha_linux_sigtramp_offset (pc)
+     CORE_ADDR pc;
+{
+  unsigned int i[3], w;
+  long off;
+
+  if (read_memory_nobpt (pc, (char *) &w, 4) != 0)
+    return -1;
+
+  off = -1;
+  switch (w)
+    {
+    case 0x47de0410:
+      off = 0;
+      break;                   /* bis $30,$30,$16 */
+    case 0x43ecf400:
+      off = 4;
+      break;                   /* addq $31,0x67,$0 */
+    case 0x00000083:
+      off = 8;
+      break;                   /* call_pal callsys */
+    default:
+      return -1;
+    }
+  pc -= off;
+  if (pc & 0x7)
+    {
+      /* designated sequence is not quadword aligned */
+      return -1;
+    }
+
+  if (read_memory_nobpt (pc, (char *) i, sizeof (i)) != 0)
+    return -1;
+
+  if (i[0] == 0x47de0410 && i[1] == 0x43ecf400 && i[2] == 0x00000083)
+    return off;
+
+  return -1;
+}
+
+
+/* Under OSF/1, the __sigtramp routine is frameless and has a frame
+   size of zero, but we are able to backtrace through it.  */
+CORE_ADDR
+alpha_osf_skip_sigtramp_frame (frame, pc)
+     struct frame_info *frame;
+     CORE_ADDR pc;
+{
+  char *name;
+  find_pc_partial_function (pc, &name, (CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
+  if (IN_SIGTRAMP (pc, name))
+    return frame->frame;
+  else
+    return 0;
+}
+
+
+/* Dynamically create a signal-handler caller procedure descriptor for
+   the signal-handler return code starting at address LOW_ADDR.  The
+   descriptor is added to the linked_proc_desc_table.  */
+
+static alpha_extra_func_info_t
+push_sigtramp_desc (low_addr)
+     CORE_ADDR low_addr;
+{
+  struct linked_proc_info *link;
+  alpha_extra_func_info_t proc_desc;
+
+  link = (struct linked_proc_info *)
+    xmalloc (sizeof (struct linked_proc_info));
+  link->next = linked_proc_desc_table;
+  linked_proc_desc_table = link;
+
+  proc_desc = &link->info;
+
+  proc_desc->numargs = 0;
+  PROC_LOW_ADDR (proc_desc) = low_addr;
+  PROC_HIGH_ADDR (proc_desc) = low_addr + 3 * 4;
+  PROC_DUMMY_FRAME (proc_desc) = 0;
+  PROC_FRAME_OFFSET (proc_desc) = 0x298;       /* sizeof(struct sigcontext_struct) */
+  PROC_FRAME_REG (proc_desc) = SP_REGNUM;
+  PROC_REG_MASK (proc_desc) = 0xffff;
+  PROC_FREG_MASK (proc_desc) = 0xffff;
+  PROC_PC_REG (proc_desc) = 26;
+  PROC_LOCALOFF (proc_desc) = 0;
+  SET_PROC_DESC_IS_DYN_SIGTRAMP (proc_desc);
+  return (proc_desc);
+}
+
+
+/* Guaranteed to set frame->saved_regs to some values (it never leaves it
+   NULL).  */
+
+void
+alpha_find_saved_regs (frame)
+     struct frame_info *frame;
+{
+  int ireg;
+  CORE_ADDR reg_position;
+  unsigned long mask;
+  alpha_extra_func_info_t proc_desc;
+  int returnreg;
+
+  frame_saved_regs_zalloc (frame);
+
+  /* If it is the frame for __sigtramp, the saved registers are located
+     in a sigcontext structure somewhere on the stack. __sigtramp
+     passes a pointer to the sigcontext structure on the stack.
+     If the stack layout for __sigtramp changes, or if sigcontext offsets
+     change, we might have to update this code.  */
+#ifndef SIGFRAME_PC_OFF
+#define SIGFRAME_PC_OFF                (2 * 8)
+#define SIGFRAME_REGSAVE_OFF   (4 * 8)
+#define SIGFRAME_FPREGSAVE_OFF (SIGFRAME_REGSAVE_OFF + 32 * 8 + 8)
+#endif
+  if (frame->signal_handler_caller)
+    {
+      CORE_ADDR sigcontext_addr;
+
+      sigcontext_addr = SIGCONTEXT_ADDR (frame);
+      for (ireg = 0; ireg < 32; ireg++)
+       {



Home | Main Index | Thread Index | Old Index