github.com/goccy/go-jit@v0.0.0-20200514131505-ff78d45cf6af/internal/ccall/include/jit/jit-walk.h (about)

     1  /*
     2   * jit-walk.h - Functions for walking stack frames.
     3   *
     4   * Copyright (C) 2004  Southern Storm Software, Pty Ltd.
     5   *
     6   * The libjit library is free software: you can redistribute it and/or
     7   * modify it under the terms of the GNU Lesser General Public License
     8   * as published by the Free Software Foundation, either version 2.1 of
     9   * the License, or (at your option) any later version.
    10   *
    11   * The libjit library is distributed in the hope that it will be useful,
    12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    14   * Lesser General Public License for more details.
    15   *
    16   * You should have received a copy of the GNU Lesser General Public
    17   * License along with the libjit library.  If not, see
    18   * <http://www.gnu.org/licenses/>.
    19   */
    20  
    21  #ifndef	_JIT_WALK_H
    22  #define	_JIT_WALK_H
    23  
    24  #include <jit/jit-arch.h>
    25  
    26  #ifdef	__cplusplus
    27  extern	"C" {
    28  #endif
    29  
    30  /*
    31   * Get the frame address for a frame which is "n" levels up the stack.
    32   * A level value of zero indicates the current frame.
    33   */
    34  void *_jit_get_frame_address(void *start, unsigned int n);
    35  #if defined(__GNUC__)
    36  # define jit_get_frame_address(n)	\
    37  	(_jit_get_frame_address(jit_get_current_frame(), (n)))
    38  #else
    39  # define jit_get_frame_address(n)	(_jit_get_frame_address(0, (n)))
    40  #endif
    41  
    42  /*
    43   * Get the frame address for the current frame.  May be more efficient
    44   * than using "jit_get_frame_address(0)".
    45   *
    46   * Note: some gcc vestions have broken __builtin_frame_address() so use
    47   * _JIT_ARCH_GET_CURRENT_FRAME() if available. 
    48   */
    49  #if defined(__GNUC__)
    50  # define JIT_FAST_GET_CURRENT_FRAME	1
    51  # if defined(_JIT_ARCH_GET_CURRENT_FRAME)
    52  #  define jit_get_current_frame()			\
    53  	({						\
    54  		void *address;				\
    55  		_JIT_ARCH_GET_CURRENT_FRAME(address);	\
    56  		address;				\
    57  	})
    58  # else
    59  #  define jit_get_current_frame()	(__builtin_frame_address(0))
    60  # endif
    61  #else
    62  # define JIT_FAST_GET_CURRENT_FRAME	0
    63  # define jit_get_current_frame()	(jit_get_frame_address(0))
    64  #endif
    65  
    66  /*
    67   * Get the next frame up the stack from a specified frame.
    68   * Returns NULL if it isn't possible to retrieve the next frame.
    69   */
    70  void *_jit_get_next_frame_address(void *frame);
    71  #if defined(__GNUC__) && defined(_JIT_ARCH_GET_NEXT_FRAME)
    72  # define jit_get_next_frame_address(frame)			\
    73  	({							\
    74  		void *address;					\
    75  		_JIT_ARCH_GET_NEXT_FRAME(address, (frame));	\
    76  		address;					\
    77  	})
    78  #else
    79  # define jit_get_next_frame_address(frame)	\
    80  	(_jit_get_next_frame_address(frame))
    81  #endif
    82  
    83  /*
    84   * Get the return address for a specific frame.
    85   */
    86  void *_jit_get_return_address(void *frame, void *frame0, void *return0);
    87  #if defined(__GNUC__)
    88  # if defined(_JIT_ARCH_GET_RETURN_ADDRESS)
    89  #  define jit_get_return_address(frame)				\
    90  	({							\
    91  		void *address;					\
    92  		_JIT_ARCH_GET_RETURN_ADDRESS(address, (frame));	\
    93  		address;					\
    94  	})
    95  # else
    96  #  define jit_get_return_address(frame)			\
    97  	(_jit_get_return_address			\
    98  		((frame),				\
    99  		 __builtin_frame_address(0),		\
   100  		 __builtin_return_address(0)))
   101  # endif
   102  #else
   103  # define jit_get_return_address(frame)	\
   104  	(_jit_get_return_address((frame), 0, 0))
   105  #endif
   106  
   107  /*
   108   * Get the return address for the current frame.  May be more efficient
   109   * than using "jit_get_return_address(0)".
   110   */
   111  #if defined(__GNUC__)
   112  # if defined(_JIT_ARCH_GET_CURRENT_RETURN)
   113  #  define jit_get_current_return()			\
   114  	({						\
   115  		void *address;				\
   116  		_JIT_ARCH_GET_CURRENT_RETURN(address);	\
   117  		address;				\
   118  	})
   119  # else
   120  #  define jit_get_current_return()	(__builtin_return_address(0))
   121  # endif
   122  #else
   123  # define jit_get_current_return()	\
   124  	(jit_get_return_address(jit_get_current_frame()))
   125  #endif
   126  
   127  /*
   128   * Declare a stack crawl mark variable.  The address of this variable
   129   * can be passed to "jit_frame_contains_crawl_mark" to determine
   130   * if a frame contains the mark.
   131   */
   132  typedef struct { void * volatile mark; } jit_crawl_mark_t;
   133  #define	jit_declare_crawl_mark(name)	jit_crawl_mark_t name = {0}
   134  
   135  /*
   136   * Determine if the stack frame just above "frame" contains a
   137   * particular crawl mark.
   138   */
   139  int jit_frame_contains_crawl_mark(void *frame, jit_crawl_mark_t *mark);
   140  
   141  #ifdef	__cplusplus
   142  };
   143  #endif
   144  
   145  #endif /* _JIT_WALK_H */