Home | History | Annotate | Line # | Download | only in gdb
alpha-mdebug-tdep.c revision 1.3
      1  1.1  christos /* Target-dependent mdebug code for the ALPHA architecture.
      2  1.3  christos    Copyright (C) 1993-2015 Free Software Foundation, Inc.
      3  1.1  christos 
      4  1.1  christos    This file is part of GDB.
      5  1.1  christos 
      6  1.1  christos    This program is free software; you can redistribute it and/or modify
      7  1.1  christos    it under the terms of the GNU General Public License as published by
      8  1.1  christos    the Free Software Foundation; either version 3 of the License, or
      9  1.1  christos    (at your option) any later version.
     10  1.1  christos 
     11  1.1  christos    This program is distributed in the hope that it will be useful,
     12  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14  1.1  christos    GNU General Public License for more details.
     15  1.1  christos 
     16  1.1  christos    You should have received a copy of the GNU General Public License
     17  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     18  1.1  christos 
     19  1.1  christos #include "defs.h"
     20  1.1  christos #include "frame.h"
     21  1.1  christos #include "frame-unwind.h"
     22  1.1  christos #include "frame-base.h"
     23  1.1  christos #include "symtab.h"
     24  1.1  christos #include "gdbcore.h"
     25  1.1  christos #include "block.h"
     26  1.1  christos #include "trad-frame.h"
     27  1.1  christos 
     28  1.1  christos #include "alpha-tdep.h"
     29  1.1  christos #include "mdebugread.h"
     30  1.1  christos 
     31  1.1  christos /* FIXME: Some of this code should perhaps be merged with mips.  */
     32  1.1  christos 
     33  1.1  christos /* *INDENT-OFF* */
     34  1.1  christos /* Layout of a stack frame on the alpha:
     35  1.1  christos 
     36  1.1  christos                 |				|
     37  1.1  christos  pdr members:	|  7th ... nth arg,		|
     38  1.1  christos                 |  `pushed' by caller.		|
     39  1.1  christos                 |				|
     40  1.1  christos ----------------|-------------------------------|<--  old_sp == vfp
     41  1.1  christos    ^  ^  ^  ^	|				|
     42  1.1  christos    |  |  |  |	|				|
     43  1.1  christos    |  |localoff	|  Copies of 1st .. 6th		|
     44  1.1  christos    |  |  |  |	|  argument if necessary.	|
     45  1.1  christos    |  |  |  v	|				|
     46  1.1  christos    |  |  |  ---	|-------------------------------|<-- LOCALS_ADDRESS
     47  1.1  christos    |  |  |      |				|
     48  1.1  christos    |  |  |      |  Locals and temporaries.	|
     49  1.1  christos    |  |  |      |				|
     50  1.1  christos    |  |  |      |-------------------------------|
     51  1.1  christos    |  |  |      |				|
     52  1.1  christos    |-fregoffset	|  Saved float registers.	|
     53  1.1  christos    |  |  |      |  F9				|
     54  1.1  christos    |  |  |      |   .				|
     55  1.1  christos    |  |  |      |   .				|
     56  1.1  christos    |  |  |      |  F2				|
     57  1.1  christos    |  |  v      |				|
     58  1.1  christos    |  |  -------|-------------------------------|
     59  1.1  christos    |  |         |				|
     60  1.1  christos    |  |         |  Saved registers.		|
     61  1.1  christos    |  |         |  S6				|
     62  1.1  christos    |-regoffset	|   .				|
     63  1.1  christos    |  |         |   .				|
     64  1.1  christos    |  |         |  S0				|
     65  1.1  christos    |  |         |  pdr.pcreg			|
     66  1.1  christos    |  v         |				|
     67  1.1  christos    |  ----------|-------------------------------|
     68  1.1  christos    |            |				|
     69  1.1  christos  frameoffset    |  Argument build area, gets	|
     70  1.1  christos    |            |  7th ... nth arg for any	|
     71  1.1  christos    |            |  called procedure.		|
     72  1.1  christos    v            |  				|
     73  1.1  christos    -------------|-------------------------------|<-- sp
     74  1.1  christos                 |				|
     75  1.1  christos */
     76  1.1  christos /* *INDENT-ON* */
     77  1.1  christos 
     78  1.1  christos #define PROC_LOW_ADDR(proc) ((proc)->pdr.adr)
     79  1.1  christos #define PROC_FRAME_OFFSET(proc) ((proc)->pdr.frameoffset)
     80  1.1  christos #define PROC_FRAME_REG(proc) ((proc)->pdr.framereg)
     81  1.1  christos #define PROC_REG_MASK(proc) ((proc)->pdr.regmask)
     82  1.1  christos #define PROC_FREG_MASK(proc) ((proc)->pdr.fregmask)
     83  1.1  christos #define PROC_REG_OFFSET(proc) ((proc)->pdr.regoffset)
     84  1.1  christos #define PROC_FREG_OFFSET(proc) ((proc)->pdr.fregoffset)
     85  1.1  christos #define PROC_PC_REG(proc) ((proc)->pdr.pcreg)
     86  1.1  christos #define PROC_LOCALOFF(proc) ((proc)->pdr.localoff)
     87  1.1  christos 
     88  1.1  christos /* Locate the mdebug PDR for the given PC.  Return null if one can't
     90  1.1  christos    be found; you'll have to fall back to other methods in that case.  */
     91  1.1  christos 
     92  1.1  christos static struct mdebug_extra_func_info *
     93  1.1  christos find_proc_desc (CORE_ADDR pc)
     94  1.3  christos {
     95  1.1  christos   const struct block *b = block_for_pc (pc);
     96  1.1  christos   struct mdebug_extra_func_info *proc_desc = NULL;
     97  1.1  christos   struct symbol *sym = NULL;
     98  1.1  christos   const char *sh_name = NULL;
     99  1.1  christos 
    100  1.1  christos   if (b)
    101  1.1  christos     {
    102  1.1  christos       CORE_ADDR startaddr;
    103  1.1  christos       find_pc_partial_function (pc, &sh_name, &startaddr, NULL);
    104  1.1  christos 
    105  1.1  christos       if (startaddr > BLOCK_START (b))
    106  1.1  christos 	/* This is the "pathological" case referred to in a comment in
    107  1.1  christos 	   print_frame_info.  It might be better to move this check into
    108  1.1  christos 	   symbol reading.  */
    109  1.1  christos 	sym = NULL;
    110  1.1  christos       else
    111  1.1  christos 	sym = lookup_symbol (MDEBUG_EFI_SYMBOL_NAME, b, LABEL_DOMAIN, 0);
    112  1.1  christos     }
    113  1.1  christos 
    114  1.1  christos   if (sym)
    115  1.1  christos     {
    116  1.1  christos       proc_desc = (struct mdebug_extra_func_info *) SYMBOL_VALUE_BYTES (sym);
    117  1.1  christos 
    118  1.1  christos       /* Correct incorrect setjmp procedure descriptor from the library
    119  1.1  christos          to make backtrace through setjmp work.  */
    120  1.1  christos       if (proc_desc->pdr.pcreg == 0
    121  1.1  christos 	  && strcmp (sh_name, "setjmp") == 0)
    122  1.1  christos 	{
    123  1.1  christos 	  proc_desc->pdr.pcreg = ALPHA_RA_REGNUM;
    124  1.1  christos 	  proc_desc->pdr.regmask = 0x80000000;
    125  1.1  christos 	  proc_desc->pdr.regoffset = -4;
    126  1.1  christos 	}
    127  1.1  christos 
    128  1.1  christos       /* If we never found a PDR for this function in symbol reading,
    129  1.1  christos 	 then examine prologues to find the information.  */
    130  1.1  christos       if (proc_desc->pdr.framereg == -1)
    131  1.1  christos 	proc_desc = NULL;
    132  1.1  christos     }
    133  1.1  christos 
    134  1.1  christos   return proc_desc;
    135  1.1  christos }
    136  1.1  christos 
    137  1.1  christos /* Return a non-zero result if the function is frameless; zero otherwise.  */
    138  1.1  christos 
    139  1.1  christos static int
    140  1.1  christos alpha_mdebug_frameless (struct mdebug_extra_func_info *proc_desc)
    141  1.1  christos {
    142  1.1  christos   return (PROC_FRAME_REG (proc_desc) == ALPHA_SP_REGNUM
    143  1.1  christos 	  && PROC_FRAME_OFFSET (proc_desc) == 0);
    144  1.1  christos }
    145  1.1  christos 
    146  1.1  christos /* This returns the PC of the first inst after the prologue.  If we can't
    147  1.1  christos    find the prologue, then return 0.  */
    148  1.1  christos 
    149  1.1  christos static CORE_ADDR
    150  1.1  christos alpha_mdebug_after_prologue (CORE_ADDR pc,
    151  1.1  christos 			     struct mdebug_extra_func_info *proc_desc)
    152  1.1  christos {
    153  1.1  christos   if (proc_desc)
    154  1.1  christos     {
    155  1.1  christos       /* If function is frameless, then we need to do it the hard way.  I
    156  1.1  christos          strongly suspect that frameless always means prologueless...  */
    157  1.1  christos       if (alpha_mdebug_frameless (proc_desc))
    158  1.1  christos 	return 0;
    159  1.1  christos     }
    160  1.1  christos 
    161  1.1  christos   return alpha_after_prologue (pc);
    162  1.1  christos }
    163  1.1  christos 
    164  1.1  christos /* Return non-zero if we *might* be in a function prologue.  Return zero
    165  1.1  christos    if we are definitively *not* in a function prologue.  */
    166  1.1  christos 
    167  1.1  christos static int
    168  1.1  christos alpha_mdebug_in_prologue (CORE_ADDR pc,
    169  1.1  christos 			  struct mdebug_extra_func_info *proc_desc)
    170  1.1  christos {
    171  1.1  christos   CORE_ADDR after_prologue_pc = alpha_mdebug_after_prologue (pc, proc_desc);
    172  1.1  christos   return (after_prologue_pc == 0 || pc < after_prologue_pc);
    173  1.1  christos }
    174  1.1  christos 
    175  1.1  christos 
    176  1.1  christos /* Frame unwinder that reads mdebug PDRs.  */
    178  1.1  christos 
    179  1.1  christos struct alpha_mdebug_unwind_cache
    180  1.1  christos {
    181  1.1  christos   struct mdebug_extra_func_info *proc_desc;
    182  1.1  christos   CORE_ADDR vfp;
    183  1.1  christos   struct trad_frame_saved_reg *saved_regs;
    184  1.1  christos };
    185  1.1  christos 
    186  1.1  christos /* Extract all of the information about the frame from PROC_DESC
    187  1.1  christos    and store the resulting register save locations in the structure.  */
    188  1.1  christos 
    189  1.1  christos static struct alpha_mdebug_unwind_cache *
    190  1.1  christos alpha_mdebug_frame_unwind_cache (struct frame_info *this_frame,
    191  1.1  christos 				 void **this_prologue_cache)
    192  1.1  christos {
    193  1.1  christos   struct alpha_mdebug_unwind_cache *info;
    194  1.1  christos   struct mdebug_extra_func_info *proc_desc;
    195  1.1  christos   ULONGEST vfp;
    196  1.1  christos   CORE_ADDR pc, reg_position;
    197  1.1  christos   unsigned long mask;
    198  1.1  christos   int ireg, returnreg;
    199  1.1  christos 
    200  1.1  christos   if (*this_prologue_cache)
    201  1.1  christos     return *this_prologue_cache;
    202  1.1  christos 
    203  1.1  christos   info = FRAME_OBSTACK_ZALLOC (struct alpha_mdebug_unwind_cache);
    204  1.1  christos   *this_prologue_cache = info;
    205  1.1  christos   pc = get_frame_address_in_block (this_frame);
    206  1.1  christos 
    207  1.1  christos   /* ??? We don't seem to be able to cache the lookup of the PDR
    208  1.1  christos      from alpha_mdebug_frame_p.  It'd be nice if we could change
    209  1.1  christos      the arguments to that function.  Oh well.  */
    210  1.1  christos   proc_desc = find_proc_desc (pc);
    211  1.1  christos   info->proc_desc = proc_desc;
    212  1.1  christos   gdb_assert (proc_desc != NULL);
    213  1.1  christos 
    214  1.1  christos   info->saved_regs = trad_frame_alloc_saved_regs (this_frame);
    215  1.1  christos 
    216  1.1  christos   /* The VFP of the frame is at FRAME_REG+FRAME_OFFSET.  */
    217  1.1  christos   vfp = get_frame_register_unsigned (this_frame, PROC_FRAME_REG (proc_desc));
    218  1.1  christos   vfp += PROC_FRAME_OFFSET (info->proc_desc);
    219  1.1  christos   info->vfp = vfp;
    220  1.1  christos 
    221  1.1  christos   /* Fill in the offsets for the registers which gen_mask says were saved.  */
    222  1.1  christos 
    223  1.1  christos   reg_position = vfp + PROC_REG_OFFSET (proc_desc);
    224  1.1  christos   mask = PROC_REG_MASK (proc_desc);
    225  1.1  christos   returnreg = PROC_PC_REG (proc_desc);
    226  1.1  christos 
    227  1.1  christos   /* Note that RA is always saved first, regardless of its actual
    228  1.1  christos      register number.  */
    229  1.1  christos   if (mask & (1 << returnreg))
    230  1.1  christos     {
    231  1.1  christos       /* Clear bit for RA so we don't save it again later.  */
    232  1.1  christos       mask &= ~(1 << returnreg);
    233  1.1  christos 
    234  1.1  christos       info->saved_regs[returnreg].addr = reg_position;
    235  1.1  christos       reg_position += 8;
    236  1.1  christos     }
    237  1.1  christos 
    238  1.1  christos   for (ireg = 0; ireg <= 31; ++ireg)
    239  1.1  christos     if (mask & (1 << ireg))
    240  1.1  christos       {
    241  1.1  christos 	info->saved_regs[ireg].addr = reg_position;
    242  1.1  christos 	reg_position += 8;
    243  1.1  christos       }
    244  1.1  christos 
    245  1.1  christos   reg_position = vfp + PROC_FREG_OFFSET (proc_desc);
    246  1.1  christos   mask = PROC_FREG_MASK (proc_desc);
    247  1.1  christos 
    248  1.1  christos   for (ireg = 0; ireg <= 31; ++ireg)
    249  1.1  christos     if (mask & (1 << ireg))
    250  1.1  christos       {
    251  1.1  christos 	info->saved_regs[ALPHA_FP0_REGNUM + ireg].addr = reg_position;
    252  1.1  christos 	reg_position += 8;
    253  1.1  christos       }
    254  1.1  christos 
    255  1.1  christos   /* The stack pointer of the previous frame is computed by popping
    256  1.1  christos      the current stack frame.  */
    257  1.1  christos   if (!trad_frame_addr_p (info->saved_regs, ALPHA_SP_REGNUM))
    258  1.1  christos    trad_frame_set_value (info->saved_regs, ALPHA_SP_REGNUM, vfp);
    259  1.1  christos 
    260  1.1  christos   return info;
    261  1.1  christos }
    262  1.1  christos 
    263  1.1  christos /* Given a GDB frame, determine the address of the calling function's
    264  1.1  christos    frame.  This will be used to create a new GDB frame struct.  */
    265  1.1  christos 
    266  1.1  christos static void
    267  1.1  christos alpha_mdebug_frame_this_id (struct frame_info *this_frame,
    268  1.1  christos 			    void **this_prologue_cache,
    269  1.1  christos 			    struct frame_id *this_id)
    270  1.1  christos {
    271  1.1  christos   struct alpha_mdebug_unwind_cache *info
    272  1.1  christos     = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);
    273  1.1  christos 
    274  1.1  christos   *this_id = frame_id_build (info->vfp, get_frame_func (this_frame));
    275  1.1  christos }
    276  1.1  christos 
    277  1.1  christos /* Retrieve the value of REGNUM in FRAME.  Don't give up!  */
    278  1.1  christos 
    279  1.1  christos static struct value *
    280  1.1  christos alpha_mdebug_frame_prev_register (struct frame_info *this_frame,
    281  1.1  christos 				  void **this_prologue_cache, int regnum)
    282  1.1  christos {
    283  1.1  christos   struct alpha_mdebug_unwind_cache *info
    284  1.1  christos     = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);
    285  1.1  christos 
    286  1.1  christos   /* The PC of the previous frame is stored in the link register of
    287  1.1  christos      the current frame.  Frob regnum so that we pull the value from
    288  1.1  christos      the correct place.  */
    289  1.1  christos   if (regnum == ALPHA_PC_REGNUM)
    290  1.1  christos     regnum = PROC_PC_REG (info->proc_desc);
    291  1.1  christos 
    292  1.1  christos   return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
    293  1.1  christos }
    294  1.1  christos 
    295  1.1  christos /* Return a non-zero result if the size of the stack frame exceeds the
    296  1.1  christos    maximum debuggable frame size (512 Kbytes); zero otherwise.  */
    297  1.1  christos 
    298  1.1  christos static int
    299  1.1  christos alpha_mdebug_max_frame_size_exceeded (struct mdebug_extra_func_info *proc_desc)
    300  1.1  christos {
    301  1.1  christos   /* If frame offset is null, we can be in two cases: either the
    302  1.1  christos      function is frameless (the stack frame is null) or its
    303  1.1  christos      frame exceeds the maximum debuggable frame size (512 Kbytes).  */
    304  1.1  christos 
    305  1.1  christos   return (PROC_FRAME_OFFSET (proc_desc) == 0
    306  1.1  christos 	  && !alpha_mdebug_frameless (proc_desc));
    307  1.1  christos }
    308  1.1  christos 
    309  1.1  christos static int
    310  1.1  christos alpha_mdebug_frame_sniffer (const struct frame_unwind *self,
    311  1.1  christos                             struct frame_info *this_frame,
    312  1.1  christos                             void **this_cache)
    313  1.1  christos {
    314  1.1  christos   CORE_ADDR pc = get_frame_address_in_block (this_frame);
    315  1.1  christos   struct mdebug_extra_func_info *proc_desc;
    316  1.1  christos 
    317  1.1  christos   /* If this PC does not map to a PDR, then clearly this isn't an
    318  1.1  christos      mdebug frame.  */
    319  1.1  christos   proc_desc = find_proc_desc (pc);
    320  1.1  christos   if (proc_desc == NULL)
    321  1.1  christos     return 0;
    322  1.1  christos 
    323  1.1  christos   /* If we're in the prologue, the PDR for this frame is not yet valid.
    324  1.1  christos      Say no here and we'll fall back on the heuristic unwinder.  */
    325  1.1  christos   if (alpha_mdebug_in_prologue (pc, proc_desc))
    326  1.1  christos     return 0;
    327  1.1  christos 
    328  1.1  christos   /* If the maximum debuggable frame size has been exceeded, the
    329  1.1  christos      proc desc is bogus.  Fall back on the heuristic unwinder.  */
    330  1.1  christos   if (alpha_mdebug_max_frame_size_exceeded (proc_desc))
    331  1.1  christos     return 0;
    332  1.1  christos 
    333  1.1  christos   return 1;
    334  1.1  christos }
    335  1.1  christos 
    336  1.1  christos static const struct frame_unwind alpha_mdebug_frame_unwind = {
    337  1.1  christos   NORMAL_FRAME,
    338  1.1  christos   default_frame_unwind_stop_reason,
    339  1.1  christos   alpha_mdebug_frame_this_id,
    340  1.1  christos   alpha_mdebug_frame_prev_register,
    341  1.1  christos   NULL,
    342  1.1  christos   alpha_mdebug_frame_sniffer
    343  1.1  christos };
    344  1.1  christos 
    345  1.1  christos static CORE_ADDR
    346  1.1  christos alpha_mdebug_frame_base_address (struct frame_info *this_frame,
    347  1.1  christos 				 void **this_prologue_cache)
    348  1.1  christos {
    349  1.1  christos   struct alpha_mdebug_unwind_cache *info
    350  1.1  christos     = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);
    351  1.1  christos 
    352  1.1  christos   return info->vfp;
    353  1.1  christos }
    354  1.1  christos 
    355  1.1  christos static CORE_ADDR
    356  1.1  christos alpha_mdebug_frame_locals_address (struct frame_info *this_frame,
    357  1.1  christos 				   void **this_prologue_cache)
    358  1.1  christos {
    359  1.1  christos   struct alpha_mdebug_unwind_cache *info
    360  1.1  christos     = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);
    361  1.1  christos 
    362  1.1  christos   return info->vfp - PROC_LOCALOFF (info->proc_desc);
    363  1.1  christos }
    364  1.1  christos 
    365  1.1  christos static CORE_ADDR
    366  1.1  christos alpha_mdebug_frame_args_address (struct frame_info *this_frame,
    367  1.1  christos 				 void **this_prologue_cache)
    368  1.1  christos {
    369  1.1  christos   struct alpha_mdebug_unwind_cache *info
    370  1.1  christos     = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);
    371  1.1  christos 
    372  1.1  christos   return info->vfp - ALPHA_NUM_ARG_REGS * 8;
    373  1.1  christos }
    374  1.1  christos 
    375  1.1  christos static const struct frame_base alpha_mdebug_frame_base = {
    376  1.1  christos   &alpha_mdebug_frame_unwind,
    377  1.1  christos   alpha_mdebug_frame_base_address,
    378  1.1  christos   alpha_mdebug_frame_locals_address,
    379  1.1  christos   alpha_mdebug_frame_args_address
    380  1.1  christos };
    381  1.1  christos 
    382  1.1  christos static const struct frame_base *
    383  1.1  christos alpha_mdebug_frame_base_sniffer (struct frame_info *this_frame)
    384  1.1  christos {
    385  1.1  christos   CORE_ADDR pc = get_frame_address_in_block (this_frame);
    386  1.1  christos   struct mdebug_extra_func_info *proc_desc;
    387  1.1  christos 
    388  1.1  christos   /* If this PC does not map to a PDR, then clearly this isn't an
    389  1.1  christos      mdebug frame.  */
    390  1.1  christos   proc_desc = find_proc_desc (pc);
    391  1.1  christos   if (proc_desc == NULL)
    392  1.1  christos     return NULL;
    393  1.1  christos 
    394  1.1  christos   /* If the maximum debuggable frame size has been exceeded, the
    395  1.1  christos      proc desc is bogus.  Fall back on the heuristic unwinder.  */
    396  1.1  christos   if (alpha_mdebug_max_frame_size_exceeded (proc_desc))
    397  1.1  christos     return 0;
    398  1.1  christos 
    399  1.1  christos   return &alpha_mdebug_frame_base;
    400  1.1  christos }
    401  1.1  christos 
    402  1.1  christos 
    403  1.1  christos void
    405  1.1  christos alpha_mdebug_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
    406  1.1  christos {
    407  1.1  christos   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
    408  1.1  christos 
    409                  frame_unwind_append_unwinder (gdbarch, &alpha_mdebug_frame_unwind);
    410                  frame_base_append_sniffer (gdbarch, alpha_mdebug_frame_base_sniffer);
    411                }
    412