xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/dwarf2/frame.h (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
17d62b00eSchristos /* Frame unwinder for frames with DWARF Call Frame Information.
27d62b00eSchristos 
3*6881a400Schristos    Copyright (C) 2003-2023 Free Software Foundation, Inc.
47d62b00eSchristos 
57d62b00eSchristos    Contributed by Mark Kettenis.
67d62b00eSchristos 
77d62b00eSchristos    This file is part of GDB.
87d62b00eSchristos 
97d62b00eSchristos    This program is free software; you can redistribute it and/or modify
107d62b00eSchristos    it under the terms of the GNU General Public License as published by
117d62b00eSchristos    the Free Software Foundation; either version 3 of the License, or
127d62b00eSchristos    (at your option) any later version.
137d62b00eSchristos 
147d62b00eSchristos    This program is distributed in the hope that it will be useful,
157d62b00eSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
167d62b00eSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
177d62b00eSchristos    GNU General Public License for more details.
187d62b00eSchristos 
197d62b00eSchristos    You should have received a copy of the GNU General Public License
207d62b00eSchristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
217d62b00eSchristos 
227d62b00eSchristos #ifndef DWARF2_FRAME_H
237d62b00eSchristos #define DWARF2_FRAME_H 1
247d62b00eSchristos 
257d62b00eSchristos struct gdbarch;
26*6881a400Schristos class frame_info_ptr;
277d62b00eSchristos struct dwarf2_per_cu_data;
287d62b00eSchristos struct agent_expr;
297d62b00eSchristos struct axs_value;
307d62b00eSchristos 
317d62b00eSchristos /* Register rule.  */
327d62b00eSchristos 
337d62b00eSchristos enum dwarf2_frame_reg_rule
347d62b00eSchristos {
357d62b00eSchristos   /* Make certain that 0 maps onto the correct enum value; the
367d62b00eSchristos      corresponding structure is being initialized using memset zero.
377d62b00eSchristos      This indicates that CFI didn't provide any information at all
387d62b00eSchristos      about a register, leaving how to obtain its value totally
397d62b00eSchristos      unspecified.  */
407d62b00eSchristos   DWARF2_FRAME_REG_UNSPECIFIED = 0,
417d62b00eSchristos 
427d62b00eSchristos   /* The term "undefined" comes from the DWARF2 CFI spec which this
437d62b00eSchristos      code is modeling; it indicates that the register's value is
447d62b00eSchristos      "undefined".  GCC uses the less formal term "unsaved".  Its
457d62b00eSchristos      definition is a combination of REG_UNDEFINED and REG_UNSPECIFIED.
467d62b00eSchristos      The failure to differentiate the two helps explain a few problems
477d62b00eSchristos      with the CFI generated by GCC.  */
487d62b00eSchristos   DWARF2_FRAME_REG_UNDEFINED,
497d62b00eSchristos   DWARF2_FRAME_REG_SAVED_OFFSET,
507d62b00eSchristos   DWARF2_FRAME_REG_SAVED_REG,
517d62b00eSchristos   DWARF2_FRAME_REG_SAVED_EXP,
527d62b00eSchristos   DWARF2_FRAME_REG_SAME_VALUE,
537d62b00eSchristos 
547d62b00eSchristos   /* These are defined in Dwarf3.  */
557d62b00eSchristos   DWARF2_FRAME_REG_SAVED_VAL_OFFSET,
567d62b00eSchristos   DWARF2_FRAME_REG_SAVED_VAL_EXP,
577d62b00eSchristos 
587d62b00eSchristos   /* These aren't defined by the DWARF2 CFI specification, but are
597d62b00eSchristos      used internally by GDB.  */
607d62b00eSchristos   DWARF2_FRAME_REG_FN,		/* Call a registered function.  */
617d62b00eSchristos   DWARF2_FRAME_REG_RA,		/* Return Address.  */
627d62b00eSchristos   DWARF2_FRAME_REG_RA_OFFSET,	/* Return Address with offset.  */
637d62b00eSchristos   DWARF2_FRAME_REG_CFA,		/* Call Frame Address.  */
647d62b00eSchristos   DWARF2_FRAME_REG_CFA_OFFSET	/* Call Frame Address with offset.  */
657d62b00eSchristos };
667d62b00eSchristos 
677d62b00eSchristos /* Register state.  */
687d62b00eSchristos 
69*6881a400Schristos typedef struct value *(*fn_prev_register) (frame_info_ptr this_frame,
70*6881a400Schristos 					   void **this_cache, int regnum);
71*6881a400Schristos 
727d62b00eSchristos struct dwarf2_frame_state_reg
737d62b00eSchristos {
747d62b00eSchristos   /* Each register save state can be described in terms of a CFA slot,
757d62b00eSchristos      another register, or a location expression.  */
767d62b00eSchristos   union {
777d62b00eSchristos     LONGEST offset;
787d62b00eSchristos     ULONGEST reg;
797d62b00eSchristos     struct
807d62b00eSchristos     {
817d62b00eSchristos       const gdb_byte *start;
827d62b00eSchristos       ULONGEST len;
837d62b00eSchristos     } exp;
84*6881a400Schristos     fn_prev_register fn;
857d62b00eSchristos   } loc;
867d62b00eSchristos   enum dwarf2_frame_reg_rule how;
877d62b00eSchristos };
887d62b00eSchristos 
897d62b00eSchristos enum cfa_how_kind
907d62b00eSchristos {
917d62b00eSchristos   CFA_UNSET,
927d62b00eSchristos   CFA_REG_OFFSET,
937d62b00eSchristos   CFA_EXP
947d62b00eSchristos };
957d62b00eSchristos 
967d62b00eSchristos struct dwarf2_frame_state_reg_info
977d62b00eSchristos {
987d62b00eSchristos   dwarf2_frame_state_reg_info () = default;
997d62b00eSchristos   ~dwarf2_frame_state_reg_info ()
1007d62b00eSchristos   {
1017d62b00eSchristos     delete prev;
1027d62b00eSchristos   }
1037d62b00eSchristos 
1047d62b00eSchristos   /* Copy constructor.  */
1057d62b00eSchristos   dwarf2_frame_state_reg_info (const dwarf2_frame_state_reg_info &src)
1067d62b00eSchristos     : reg (src.reg), cfa_offset (src.cfa_offset),
1077d62b00eSchristos       cfa_reg (src.cfa_reg), cfa_how (src.cfa_how), cfa_exp (src.cfa_exp),
1087d62b00eSchristos       prev (src.prev)
1097d62b00eSchristos   {
1107d62b00eSchristos   }
1117d62b00eSchristos 
1127d62b00eSchristos   /* Assignment operator for both move-assignment and copy-assignment.  */
1137d62b00eSchristos   dwarf2_frame_state_reg_info&
1147d62b00eSchristos   operator= (dwarf2_frame_state_reg_info rhs)
1157d62b00eSchristos   {
1167d62b00eSchristos     swap (*this, rhs);
1177d62b00eSchristos     return *this;
1187d62b00eSchristos   }
1197d62b00eSchristos 
1207d62b00eSchristos   /* Move constructor.  */
1217d62b00eSchristos   dwarf2_frame_state_reg_info (dwarf2_frame_state_reg_info &&rhs) noexcept
1227d62b00eSchristos     : reg (std::move (rhs.reg)), cfa_offset (rhs.cfa_offset),
1237d62b00eSchristos       cfa_reg (rhs.cfa_reg), cfa_how (rhs.cfa_how), cfa_exp (rhs.cfa_exp),
1247d62b00eSchristos       prev (rhs.prev)
1257d62b00eSchristos   {
1267d62b00eSchristos     rhs.prev = nullptr;
1277d62b00eSchristos   }
1287d62b00eSchristos 
1297d62b00eSchristos   /* If necessary, enlarge the register set to hold NUM_REGS_REQUESTED
1307d62b00eSchristos      registers.  */
1317d62b00eSchristos   void alloc_regs (int num_regs_requested)
1327d62b00eSchristos   {
1337d62b00eSchristos     gdb_assert (num_regs_requested > 0);
1347d62b00eSchristos 
1357d62b00eSchristos     if (num_regs_requested <= reg.size ())
1367d62b00eSchristos       return;
1377d62b00eSchristos 
1387d62b00eSchristos     reg.resize (num_regs_requested);
1397d62b00eSchristos   }
1407d62b00eSchristos 
1417d62b00eSchristos   std::vector<struct dwarf2_frame_state_reg> reg;
1427d62b00eSchristos 
1437d62b00eSchristos   LONGEST cfa_offset = 0;
1447d62b00eSchristos   ULONGEST cfa_reg = 0;
1457d62b00eSchristos   enum cfa_how_kind cfa_how = CFA_UNSET;
1467d62b00eSchristos   const gdb_byte *cfa_exp = NULL;
1477d62b00eSchristos 
1487d62b00eSchristos   /* Used to implement DW_CFA_remember_state.  */
1497d62b00eSchristos   struct dwarf2_frame_state_reg_info *prev = NULL;
1507d62b00eSchristos 
1517d62b00eSchristos private:
1527d62b00eSchristos   friend void swap (dwarf2_frame_state_reg_info& lhs,
1537d62b00eSchristos 		    dwarf2_frame_state_reg_info& rhs)
1547d62b00eSchristos   {
1557d62b00eSchristos     using std::swap;
1567d62b00eSchristos 
1577d62b00eSchristos     swap (lhs.reg, rhs.reg);
1587d62b00eSchristos     swap (lhs.cfa_offset, rhs.cfa_offset);
1597d62b00eSchristos     swap (lhs.cfa_reg, rhs.cfa_reg);
1607d62b00eSchristos     swap (lhs.cfa_how, rhs.cfa_how);
1617d62b00eSchristos     swap (lhs.cfa_exp, rhs.cfa_exp);
1627d62b00eSchristos     swap (lhs.prev, rhs.prev);
1637d62b00eSchristos   }
1647d62b00eSchristos };
1657d62b00eSchristos 
1667d62b00eSchristos struct dwarf2_cie;
1677d62b00eSchristos 
1687d62b00eSchristos /* Structure describing a frame state.  */
1697d62b00eSchristos 
1707d62b00eSchristos struct dwarf2_frame_state
1717d62b00eSchristos {
1727d62b00eSchristos   dwarf2_frame_state (CORE_ADDR pc, struct dwarf2_cie *cie);
1737d62b00eSchristos 
1747d62b00eSchristos   /* Each register save state can be described in terms of a CFA slot,
1757d62b00eSchristos      another register, or a location expression.  */
1767d62b00eSchristos   struct dwarf2_frame_state_reg_info regs {};
1777d62b00eSchristos 
1787d62b00eSchristos   /* The PC described by the current frame state.  */
1797d62b00eSchristos   CORE_ADDR pc;
1807d62b00eSchristos 
1817d62b00eSchristos   /* Initial register set from the CIE.
1827d62b00eSchristos      Used to implement DW_CFA_restore.  */
1837d62b00eSchristos   struct dwarf2_frame_state_reg_info initial {};
1847d62b00eSchristos 
1857d62b00eSchristos   /* The information we care about from the CIE.  */
1867d62b00eSchristos   const LONGEST data_align;
1877d62b00eSchristos   const ULONGEST code_align;
1887d62b00eSchristos   const ULONGEST retaddr_column;
1897d62b00eSchristos 
1907d62b00eSchristos   /* Flags for known producer quirks.  */
1917d62b00eSchristos 
1927d62b00eSchristos   /* The ARM compilers, in DWARF2 mode, assume that DW_CFA_def_cfa
1937d62b00eSchristos      and DW_CFA_def_cfa_offset takes a factored offset.  */
1947d62b00eSchristos   bool armcc_cfa_offsets_sf = false;
1957d62b00eSchristos 
1967d62b00eSchristos   /* The ARM compilers, in DWARF2 or DWARF3 mode, may assume that
1977d62b00eSchristos      the CFA is defined as REG - OFFSET rather than REG + OFFSET.  */
1987d62b00eSchristos   bool armcc_cfa_offsets_reversed = false;
1997d62b00eSchristos };
2007d62b00eSchristos 
2017d62b00eSchristos /* When this is true the DWARF frame unwinders can be used if they are
2027d62b00eSchristos    registered with the gdbarch.  Not all architectures can or do use the
2037d62b00eSchristos    DWARF unwinders.  Setting this to true on a target that does not
2047d62b00eSchristos    otherwise support the DWARF unwinders has no effect.  */
2057d62b00eSchristos extern bool dwarf2_frame_unwinders_enabled_p;
2067d62b00eSchristos 
2077d62b00eSchristos /* Set the architecture-specific register state initialization
2087d62b00eSchristos    function for GDBARCH to INIT_REG.  */
2097d62b00eSchristos 
2107d62b00eSchristos extern void dwarf2_frame_set_init_reg (struct gdbarch *gdbarch,
2117d62b00eSchristos 				       void (*init_reg) (struct gdbarch *, int,
2127d62b00eSchristos 					     struct dwarf2_frame_state_reg *,
213*6881a400Schristos 					     frame_info_ptr));
2147d62b00eSchristos 
2157d62b00eSchristos /* Set the architecture-specific signal trampoline recognition
2167d62b00eSchristos    function for GDBARCH to SIGNAL_FRAME_P.  */
2177d62b00eSchristos 
2187d62b00eSchristos extern void
2197d62b00eSchristos   dwarf2_frame_set_signal_frame_p (struct gdbarch *gdbarch,
2207d62b00eSchristos 				   int (*signal_frame_p) (struct gdbarch *,
221*6881a400Schristos 							  frame_info_ptr));
2227d62b00eSchristos 
2237d62b00eSchristos /* Set the architecture-specific adjustment of .eh_frame and .debug_frame
2247d62b00eSchristos    register numbers.  */
2257d62b00eSchristos 
2267d62b00eSchristos extern void
2277d62b00eSchristos   dwarf2_frame_set_adjust_regnum (struct gdbarch *gdbarch,
2287d62b00eSchristos 				  int (*adjust_regnum) (struct gdbarch *,
2297d62b00eSchristos 							int, int));
2307d62b00eSchristos 
2317d62b00eSchristos /* Append the DWARF-2 frame unwinders to GDBARCH's list.  */
2327d62b00eSchristos 
2337d62b00eSchristos void dwarf2_append_unwinders (struct gdbarch *gdbarch);
2347d62b00eSchristos 
2357d62b00eSchristos /* Return the frame base methods for the function that contains PC, or
2367d62b00eSchristos    NULL if it can't be handled by the DWARF CFI frame unwinder.  */
2377d62b00eSchristos 
2387d62b00eSchristos extern const struct frame_base *
239*6881a400Schristos   dwarf2_frame_base_sniffer (frame_info_ptr this_frame);
2407d62b00eSchristos 
2417d62b00eSchristos /* Compute the DWARF CFA for a frame.  */
2427d62b00eSchristos 
243*6881a400Schristos CORE_ADDR dwarf2_frame_cfa (frame_info_ptr this_frame);
2447d62b00eSchristos 
2457d62b00eSchristos /* Find the CFA information for PC.
2467d62b00eSchristos 
2477d62b00eSchristos    Return 1 if a register is used for the CFA, or 0 if another
2487d62b00eSchristos    expression is used.  Throw an exception on error.
2497d62b00eSchristos 
2507d62b00eSchristos    GDBARCH is the architecture to use.
2517d62b00eSchristos    DATA is the per-CU data.
2527d62b00eSchristos 
2537d62b00eSchristos    REGNUM_OUT is an out parameter that is set to the register number.
2547d62b00eSchristos    OFFSET_OUT is the offset to use from this register.
2557d62b00eSchristos    These are only filled in when 1 is returned.
2567d62b00eSchristos 
2577d62b00eSchristos    TEXT_OFFSET_OUT, CFA_START_OUT, and CFA_END_OUT describe the CFA
2587d62b00eSchristos    in other cases.  These are only used when 0 is returned.  */
2597d62b00eSchristos 
2607d62b00eSchristos extern int dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
2617d62b00eSchristos 				  struct dwarf2_per_cu_data *data,
2627d62b00eSchristos 				  int *regnum_out, LONGEST *offset_out,
2637d62b00eSchristos 				  CORE_ADDR *text_offset_out,
2647d62b00eSchristos 				  const gdb_byte **cfa_start_out,
2657d62b00eSchristos 				  const gdb_byte **cfa_end_out);
2667d62b00eSchristos 
267*6881a400Schristos 
268*6881a400Schristos /* Allocate a new instance of the function unique data.
269*6881a400Schristos 
270*6881a400Schristos    The main purpose of this custom function data object is to allow caching the
271*6881a400Schristos    value of expensive lookups in the prev_register implementation.
272*6881a400Schristos 
273*6881a400Schristos    THIS_FRAME is the frame that the custom data object should be associated
274*6881a400Schristos    with.
275*6881a400Schristos    THIS_CACHE is the dwarf2 cache object to store the pointer on.
276*6881a400Schristos    COOKIE is the key for the prev_function implementation.
277*6881a400Schristos    SIZE is the size of the custom data object to allocate.  */
278*6881a400Schristos 
279*6881a400Schristos extern void *dwarf2_frame_allocate_fn_data (frame_info_ptr this_frame,
280*6881a400Schristos 					    void **this_cache,
281*6881a400Schristos 					    fn_prev_register cookie,
282*6881a400Schristos 					    unsigned long size);
283*6881a400Schristos 
284*6881a400Schristos /* Retrieve the function unique data for this frame or NULL if none exists.
285*6881a400Schristos 
286*6881a400Schristos    The main purpose of this custom function data object is to allow caching the
287*6881a400Schristos    value of expensive lookups in the prev_register implementation.
288*6881a400Schristos 
289*6881a400Schristos    THIS_FRAME is the frame that the custom data object should be associated
290*6881a400Schristos    with.
291*6881a400Schristos    THIS_CACHE is the dwarf2 cache object to store the pointer on.
292*6881a400Schristos    COOKIE is the key for the prev_function implementation.  */
293*6881a400Schristos 
294*6881a400Schristos extern void *dwarf2_frame_get_fn_data (frame_info_ptr this_frame,
295*6881a400Schristos 				       void **this_cache,
296*6881a400Schristos 				       fn_prev_register cookie);
297*6881a400Schristos 
2987d62b00eSchristos #endif /* dwarf2-frame.h */
299