gdb/alpha-mdebug-tdep.c - gdb

Global variables defined

Data types defined

Functions defined

Macros defined

Source code

  1. /* Target-dependent mdebug code for the ALPHA architecture.
  2.    Copyright (C) 1993-2015 Free Software Foundation, Inc.

  3.    This file is part of GDB.

  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 3 of the License, or
  7.    (at your option) any later version.

  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.

  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

  14. #include "defs.h"
  15. #include "frame.h"
  16. #include "frame-unwind.h"
  17. #include "frame-base.h"
  18. #include "symtab.h"
  19. #include "gdbcore.h"
  20. #include "block.h"
  21. #include "trad-frame.h"

  22. #include "alpha-tdep.h"
  23. #include "mdebugread.h"

  24. /* FIXME: Some of this code should perhaps be merged with mips.  */

  25. /* *INDENT-OFF* */
  26. /* Layout of a stack frame on the alpha:

  27.                 |                                |
  28. pdr members:        |  7th ... nth arg,                |
  29.                 |  `pushed' by caller.                |
  30.                 |                                |
  31. ----------------|-------------------------------|<--  old_sp == vfp
  32.    ^  ^  ^  ^        |                                |
  33.    |  |  |  |        |                                |
  34.    |  |localoff        |  Copies of 1st .. 6th                |
  35.    |  |  |  |        |  argument if necessary.        |
  36.    |  |  |  v        |                                |
  37.    |  |  |  ---        |-------------------------------|<-- LOCALS_ADDRESS
  38.    |  |  |      |                                |
  39.    |  |  |      |  Locals and temporaries.        |
  40.    |  |  |      |                                |
  41.    |  |  |      |-------------------------------|
  42.    |  |  |      |                                |
  43.    |-fregoffset        |  Saved float registers.        |
  44.    |  |  |      |  F9                                |
  45.    |  |  |      |   .                                |
  46.    |  |  |      |   .                                |
  47.    |  |  |      |  F2                                |
  48.    |  |  v      |                                |
  49.    |  |  -------|-------------------------------|
  50.    |  |         |                                |
  51.    |  |         |  Saved registers.                |
  52.    |  |         |  S6                                |
  53.    |-regoffset        |   .                                |
  54.    |  |         |   .                                |
  55.    |  |         |  S0                                |
  56.    |  |         |  pdr.pcreg                        |
  57.    |  v         |                                |
  58.    |  ----------|-------------------------------|
  59.    |            |                                |
  60. frameoffset    |  Argument build area, gets        |
  61.    |            |  7th ... nth arg for any        |
  62.    |            |  called procedure.                |
  63.    v            |                                  |
  64.    -------------|-------------------------------|<-- sp
  65.                 |                                |
  66. */
  67. /* *INDENT-ON* */

  68. #define PROC_LOW_ADDR(proc) ((proc)->pdr.adr)
  69. #define PROC_FRAME_OFFSET(proc) ((proc)->pdr.frameoffset)
  70. #define PROC_FRAME_REG(proc) ((proc)->pdr.framereg)
  71. #define PROC_REG_MASK(proc) ((proc)->pdr.regmask)
  72. #define PROC_FREG_MASK(proc) ((proc)->pdr.fregmask)
  73. #define PROC_REG_OFFSET(proc) ((proc)->pdr.regoffset)
  74. #define PROC_FREG_OFFSET(proc) ((proc)->pdr.fregoffset)
  75. #define PROC_PC_REG(proc) ((proc)->pdr.pcreg)
  76. #define PROC_LOCALOFF(proc) ((proc)->pdr.localoff)

  77. /* Locate the mdebug PDR for the given PC.  Return null if one can't
  78.    be found; you'll have to fall back to other methods in that case.  */

  79. static struct mdebug_extra_func_info *
  80. find_proc_desc (CORE_ADDR pc)
  81. {
  82.   const struct block *b = block_for_pc (pc);
  83.   struct mdebug_extra_func_info *proc_desc = NULL;
  84.   struct symbol *sym = NULL;
  85.   const char *sh_name = NULL;

  86.   if (b)
  87.     {
  88.       CORE_ADDR startaddr;
  89.       find_pc_partial_function (pc, &sh_name, &startaddr, NULL);

  90.       if (startaddr > BLOCK_START (b))
  91.         /* This is the "pathological" case referred to in a comment in
  92.            print_frame_info.  It might be better to move this check into
  93.            symbol reading.  */
  94.         sym = NULL;
  95.       else
  96.         sym = lookup_symbol (MDEBUG_EFI_SYMBOL_NAME, b, LABEL_DOMAIN, 0);
  97.     }

  98.   if (sym)
  99.     {
  100.       proc_desc = (struct mdebug_extra_func_info *) SYMBOL_VALUE_BYTES (sym);

  101.       /* Correct incorrect setjmp procedure descriptor from the library
  102.          to make backtrace through setjmp work.  */
  103.       if (proc_desc->pdr.pcreg == 0
  104.           && strcmp (sh_name, "setjmp") == 0)
  105.         {
  106.           proc_desc->pdr.pcreg = ALPHA_RA_REGNUM;
  107.           proc_desc->pdr.regmask = 0x80000000;
  108.           proc_desc->pdr.regoffset = -4;
  109.         }

  110.       /* If we never found a PDR for this function in symbol reading,
  111.          then examine prologues to find the information.  */
  112.       if (proc_desc->pdr.framereg == -1)
  113.         proc_desc = NULL;
  114.     }

  115.   return proc_desc;
  116. }

  117. /* Return a non-zero result if the function is frameless; zero otherwise.  */

  118. static int
  119. alpha_mdebug_frameless (struct mdebug_extra_func_info *proc_desc)
  120. {
  121.   return (PROC_FRAME_REG (proc_desc) == ALPHA_SP_REGNUM
  122.           && PROC_FRAME_OFFSET (proc_desc) == 0);
  123. }

  124. /* This returns the PC of the first inst after the prologue.  If we can't
  125.    find the prologue, then return 0.  */

  126. static CORE_ADDR
  127. alpha_mdebug_after_prologue (CORE_ADDR pc,
  128.                              struct mdebug_extra_func_info *proc_desc)
  129. {
  130.   if (proc_desc)
  131.     {
  132.       /* If function is frameless, then we need to do it the hard way.  I
  133.          strongly suspect that frameless always means prologueless...  */
  134.       if (alpha_mdebug_frameless (proc_desc))
  135.         return 0;
  136.     }

  137.   return alpha_after_prologue (pc);
  138. }

  139. /* Return non-zero if we *might* be in a function prologue.  Return zero
  140.    if we are definitively *not* in a function prologue.  */

  141. static int
  142. alpha_mdebug_in_prologue (CORE_ADDR pc,
  143.                           struct mdebug_extra_func_info *proc_desc)
  144. {
  145.   CORE_ADDR after_prologue_pc = alpha_mdebug_after_prologue (pc, proc_desc);
  146.   return (after_prologue_pc == 0 || pc < after_prologue_pc);
  147. }


  148. /* Frame unwinder that reads mdebug PDRs.  */

  149. struct alpha_mdebug_unwind_cache
  150. {
  151.   struct mdebug_extra_func_info *proc_desc;
  152.   CORE_ADDR vfp;
  153.   struct trad_frame_saved_reg *saved_regs;
  154. };

  155. /* Extract all of the information about the frame from PROC_DESC
  156.    and store the resulting register save locations in the structure.  */

  157. static struct alpha_mdebug_unwind_cache *
  158. alpha_mdebug_frame_unwind_cache (struct frame_info *this_frame,
  159.                                  void **this_prologue_cache)
  160. {
  161.   struct alpha_mdebug_unwind_cache *info;
  162.   struct mdebug_extra_func_info *proc_desc;
  163.   ULONGEST vfp;
  164.   CORE_ADDR pc, reg_position;
  165.   unsigned long mask;
  166.   int ireg, returnreg;

  167.   if (*this_prologue_cache)
  168.     return *this_prologue_cache;

  169.   info = FRAME_OBSTACK_ZALLOC (struct alpha_mdebug_unwind_cache);
  170.   *this_prologue_cache = info;
  171.   pc = get_frame_address_in_block (this_frame);

  172.   /* ??? We don't seem to be able to cache the lookup of the PDR
  173.      from alpha_mdebug_frame_p.  It'd be nice if we could change
  174.      the arguments to that function.  Oh well.  */
  175.   proc_desc = find_proc_desc (pc);
  176.   info->proc_desc = proc_desc;
  177.   gdb_assert (proc_desc != NULL);

  178.   info->saved_regs = trad_frame_alloc_saved_regs (this_frame);

  179.   /* The VFP of the frame is at FRAME_REG+FRAME_OFFSET.  */
  180.   vfp = get_frame_register_unsigned (this_frame, PROC_FRAME_REG (proc_desc));
  181.   vfp += PROC_FRAME_OFFSET (info->proc_desc);
  182.   info->vfp = vfp;

  183.   /* Fill in the offsets for the registers which gen_mask says were saved.  */

  184.   reg_position = vfp + PROC_REG_OFFSET (proc_desc);
  185.   mask = PROC_REG_MASK (proc_desc);
  186.   returnreg = PROC_PC_REG (proc_desc);

  187.   /* Note that RA is always saved first, regardless of its actual
  188.      register number.  */
  189.   if (mask & (1 << returnreg))
  190.     {
  191.       /* Clear bit for RA so we don't save it again later.  */
  192.       mask &= ~(1 << returnreg);

  193.       info->saved_regs[returnreg].addr = reg_position;
  194.       reg_position += 8;
  195.     }

  196.   for (ireg = 0; ireg <= 31; ++ireg)
  197.     if (mask & (1 << ireg))
  198.       {
  199.         info->saved_regs[ireg].addr = reg_position;
  200.         reg_position += 8;
  201.       }

  202.   reg_position = vfp + PROC_FREG_OFFSET (proc_desc);
  203.   mask = PROC_FREG_MASK (proc_desc);

  204.   for (ireg = 0; ireg <= 31; ++ireg)
  205.     if (mask & (1 << ireg))
  206.       {
  207.         info->saved_regs[ALPHA_FP0_REGNUM + ireg].addr = reg_position;
  208.         reg_position += 8;
  209.       }

  210.   /* The stack pointer of the previous frame is computed by popping
  211.      the current stack frame.  */
  212.   if (!trad_frame_addr_p (info->saved_regs, ALPHA_SP_REGNUM))
  213.    trad_frame_set_value (info->saved_regs, ALPHA_SP_REGNUM, vfp);

  214.   return info;
  215. }

  216. /* Given a GDB frame, determine the address of the calling function's
  217.    frame.  This will be used to create a new GDB frame struct.  */

  218. static void
  219. alpha_mdebug_frame_this_id (struct frame_info *this_frame,
  220.                             void **this_prologue_cache,
  221.                             struct frame_id *this_id)
  222. {
  223.   struct alpha_mdebug_unwind_cache *info
  224.     = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);

  225.   *this_id = frame_id_build (info->vfp, get_frame_func (this_frame));
  226. }

  227. /* Retrieve the value of REGNUM in FRAME.  Don't give up!  */

  228. static struct value *
  229. alpha_mdebug_frame_prev_register (struct frame_info *this_frame,
  230.                                   void **this_prologue_cache, int regnum)
  231. {
  232.   struct alpha_mdebug_unwind_cache *info
  233.     = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);

  234.   /* The PC of the previous frame is stored in the link register of
  235.      the current frame.  Frob regnum so that we pull the value from
  236.      the correct place.  */
  237.   if (regnum == ALPHA_PC_REGNUM)
  238.     regnum = PROC_PC_REG (info->proc_desc);

  239.   return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
  240. }

  241. /* Return a non-zero result if the size of the stack frame exceeds the
  242.    maximum debuggable frame size (512 Kbytes); zero otherwise.  */

  243. static int
  244. alpha_mdebug_max_frame_size_exceeded (struct mdebug_extra_func_info *proc_desc)
  245. {
  246.   /* If frame offset is null, we can be in two cases: either the
  247.      function is frameless (the stack frame is null) or its
  248.      frame exceeds the maximum debuggable frame size (512 Kbytes).  */

  249.   return (PROC_FRAME_OFFSET (proc_desc) == 0
  250.           && !alpha_mdebug_frameless (proc_desc));
  251. }

  252. static int
  253. alpha_mdebug_frame_sniffer (const struct frame_unwind *self,
  254.                             struct frame_info *this_frame,
  255.                             void **this_cache)
  256. {
  257.   CORE_ADDR pc = get_frame_address_in_block (this_frame);
  258.   struct mdebug_extra_func_info *proc_desc;

  259.   /* If this PC does not map to a PDR, then clearly this isn't an
  260.      mdebug frame.  */
  261.   proc_desc = find_proc_desc (pc);
  262.   if (proc_desc == NULL)
  263.     return 0;

  264.   /* If we're in the prologue, the PDR for this frame is not yet valid.
  265.      Say no here and we'll fall back on the heuristic unwinder.  */
  266.   if (alpha_mdebug_in_prologue (pc, proc_desc))
  267.     return 0;

  268.   /* If the maximum debuggable frame size has been exceeded, the
  269.      proc desc is bogus.  Fall back on the heuristic unwinder.  */
  270.   if (alpha_mdebug_max_frame_size_exceeded (proc_desc))
  271.     return 0;

  272.   return 1;
  273. }

  274. static const struct frame_unwind alpha_mdebug_frame_unwind = {
  275.   NORMAL_FRAME,
  276.   default_frame_unwind_stop_reason,
  277.   alpha_mdebug_frame_this_id,
  278.   alpha_mdebug_frame_prev_register,
  279.   NULL,
  280.   alpha_mdebug_frame_sniffer
  281. };

  282. static CORE_ADDR
  283. alpha_mdebug_frame_base_address (struct frame_info *this_frame,
  284.                                  void **this_prologue_cache)
  285. {
  286.   struct alpha_mdebug_unwind_cache *info
  287.     = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);

  288.   return info->vfp;
  289. }

  290. static CORE_ADDR
  291. alpha_mdebug_frame_locals_address (struct frame_info *this_frame,
  292.                                    void **this_prologue_cache)
  293. {
  294.   struct alpha_mdebug_unwind_cache *info
  295.     = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);

  296.   return info->vfp - PROC_LOCALOFF (info->proc_desc);
  297. }

  298. static CORE_ADDR
  299. alpha_mdebug_frame_args_address (struct frame_info *this_frame,
  300.                                  void **this_prologue_cache)
  301. {
  302.   struct alpha_mdebug_unwind_cache *info
  303.     = alpha_mdebug_frame_unwind_cache (this_frame, this_prologue_cache);

  304.   return info->vfp - ALPHA_NUM_ARG_REGS * 8;
  305. }

  306. static const struct frame_base alpha_mdebug_frame_base = {
  307.   &alpha_mdebug_frame_unwind,
  308.   alpha_mdebug_frame_base_address,
  309.   alpha_mdebug_frame_locals_address,
  310.   alpha_mdebug_frame_args_address
  311. };

  312. static const struct frame_base *
  313. alpha_mdebug_frame_base_sniffer (struct frame_info *this_frame)
  314. {
  315.   CORE_ADDR pc = get_frame_address_in_block (this_frame);
  316.   struct mdebug_extra_func_info *proc_desc;

  317.   /* If this PC does not map to a PDR, then clearly this isn't an
  318.      mdebug frame.  */
  319.   proc_desc = find_proc_desc (pc);
  320.   if (proc_desc == NULL)
  321.     return NULL;

  322.   /* If the maximum debuggable frame size has been exceeded, the
  323.      proc desc is bogus.  Fall back on the heuristic unwinder.  */
  324.   if (alpha_mdebug_max_frame_size_exceeded (proc_desc))
  325.     return 0;

  326.   return &alpha_mdebug_frame_base;
  327. }


  328. void
  329. alpha_mdebug_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
  330. {
  331.   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

  332.   frame_unwind_append_unwinder (gdbarch, &alpha_mdebug_frame_unwind);
  333.   frame_base_append_sniffer (gdbarch, alpha_mdebug_frame_base_sniffer);
  334. }