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 */