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