X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Falpha-mdebug-tdep.c;h=7f0ac8ae127182c9b206e16fd32fcb7f49e5d6b4;hb=8a6200ba863f207d93467312431d107f50f0e2ab;hp=008956111084280c194d60f77f31f701f512d97d;hpb=0cd9ab92e5269fb69a286539a19c0d2ef49ad01c;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/alpha-mdebug-tdep.c b/gdb/alpha-mdebug-tdep.c index 0089561110..7f0ac8ae12 100644 --- a/gdb/alpha-mdebug-tdep.c +++ b/gdb/alpha-mdebug-tdep.c @@ -1,6 +1,5 @@ /* Target-dependent mdebug code for the ALPHA architecture. - Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - 2003, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 1993-2017 Free Software Foundation, Inc. This file is part of GDB. @@ -24,8 +23,6 @@ #include "symtab.h" #include "gdbcore.h" #include "block.h" -#include "gdb_assert.h" -#include "gdb_string.h" #include "trad-frame.h" #include "alpha-tdep.h" @@ -94,10 +91,10 @@ static struct mdebug_extra_func_info * find_proc_desc (CORE_ADDR pc) { - struct block *b = block_for_pc (pc); + const struct block *b = block_for_pc (pc); struct mdebug_extra_func_info *proc_desc = NULL; struct symbol *sym = NULL; - char *sh_name = NULL; + const char *sh_name = NULL; if (b) { @@ -110,12 +107,13 @@ find_proc_desc (CORE_ADDR pc) symbol reading. */ sym = NULL; else - sym = lookup_symbol (MDEBUG_EFI_SYMBOL_NAME, b, LABEL_DOMAIN, 0); + sym = lookup_symbol (MDEBUG_EFI_SYMBOL_NAME, b, LABEL_DOMAIN, + 0).symbol; } if (sym) { - proc_desc = (struct mdebug_extra_func_info *) SYMBOL_VALUE (sym); + proc_desc = (struct mdebug_extra_func_info *) SYMBOL_VALUE_BYTES (sym); /* Correct incorrect setjmp procedure descriptor from the library to make backtrace through setjmp work. */ @@ -136,18 +134,27 @@ find_proc_desc (CORE_ADDR pc) return proc_desc; } +/* Return a non-zero result if the function is frameless; zero otherwise. */ + +static int +alpha_mdebug_frameless (struct mdebug_extra_func_info *proc_desc) +{ + return (PROC_FRAME_REG (proc_desc) == ALPHA_SP_REGNUM + && PROC_FRAME_OFFSET (proc_desc) == 0); +} + /* This returns the PC of the first inst after the prologue. If we can't find the prologue, then return 0. */ static CORE_ADDR -alpha_mdebug_after_prologue (CORE_ADDR pc, struct mdebug_extra_func_info *proc_desc) +alpha_mdebug_after_prologue (CORE_ADDR pc, + struct mdebug_extra_func_info *proc_desc) { if (proc_desc) { /* If function is frameless, then we need to do it the hard way. I - strongly suspect that frameless always means prologueless... */ - if (PROC_FRAME_REG (proc_desc) == ALPHA_SP_REGNUM - && PROC_FRAME_OFFSET (proc_desc) == 0) + strongly suspect that frameless always means prologueless... */ + if (alpha_mdebug_frameless (proc_desc)) return 0; } @@ -158,7 +165,8 @@ alpha_mdebug_after_prologue (CORE_ADDR pc, struct mdebug_extra_func_info *proc_d if we are definitively *not* in a function prologue. */ static int -alpha_mdebug_in_prologue (CORE_ADDR pc, struct mdebug_extra_func_info *proc_desc) +alpha_mdebug_in_prologue (CORE_ADDR pc, + struct mdebug_extra_func_info *proc_desc) { CORE_ADDR after_prologue_pc = alpha_mdebug_after_prologue (pc, proc_desc); return (after_prologue_pc == 0 || pc < after_prologue_pc); @@ -189,11 +197,11 @@ alpha_mdebug_frame_unwind_cache (struct frame_info *this_frame, int ireg, returnreg; if (*this_prologue_cache) - return *this_prologue_cache; + return (struct alpha_mdebug_unwind_cache *) *this_prologue_cache; info = FRAME_OBSTACK_ZALLOC (struct alpha_mdebug_unwind_cache); *this_prologue_cache = info; - pc = get_frame_pc (this_frame); + pc = get_frame_address_in_block (this_frame); /* ??? We don't seem to be able to cache the lookup of the PDR from alpha_mdebug_frame_p. It'd be nice if we could change @@ -219,7 +227,7 @@ alpha_mdebug_frame_unwind_cache (struct frame_info *this_frame, register number. */ if (mask & (1 << returnreg)) { - /* Clear bit for RA so we don't save it again later. */ + /* Clear bit for RA so we don't save it again later. */ mask &= ~(1 << returnreg); info->saved_regs[returnreg].addr = reg_position; @@ -283,6 +291,20 @@ alpha_mdebug_frame_prev_register (struct frame_info *this_frame, return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum); } +/* Return a non-zero result if the size of the stack frame exceeds the + maximum debuggable frame size (512 Kbytes); zero otherwise. */ + +static int +alpha_mdebug_max_frame_size_exceeded (struct mdebug_extra_func_info *proc_desc) +{ + /* If frame offset is null, we can be in two cases: either the + function is frameless (the stack frame is null) or its + frame exceeds the maximum debuggable frame size (512 Kbytes). */ + + return (PROC_FRAME_OFFSET (proc_desc) == 0 + && !alpha_mdebug_frameless (proc_desc)); +} + static int alpha_mdebug_frame_sniffer (const struct frame_unwind *self, struct frame_info *this_frame, @@ -302,11 +324,17 @@ alpha_mdebug_frame_sniffer (const struct frame_unwind *self, if (alpha_mdebug_in_prologue (pc, proc_desc)) return 0; + /* If the maximum debuggable frame size has been exceeded, the + proc desc is bogus. Fall back on the heuristic unwinder. */ + if (alpha_mdebug_max_frame_size_exceeded (proc_desc)) + return 0; + return 1; } static const struct frame_unwind alpha_mdebug_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, alpha_mdebug_frame_this_id, alpha_mdebug_frame_prev_register, NULL, @@ -362,6 +390,11 @@ alpha_mdebug_frame_base_sniffer (struct frame_info *this_frame) if (proc_desc == NULL) return NULL; + /* If the maximum debuggable frame size has been exceeded, the + proc desc is bogus. Fall back on the heuristic unwinder. */ + if (alpha_mdebug_max_frame_size_exceeded (proc_desc)) + return 0; + return &alpha_mdebug_frame_base; } @@ -369,8 +402,6 @@ alpha_mdebug_frame_base_sniffer (struct frame_info *this_frame) void alpha_mdebug_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - frame_unwind_append_unwinder (gdbarch, &alpha_mdebug_frame_unwind); frame_base_append_sniffer (gdbarch, alpha_mdebug_frame_base_sniffer); }