1 1.1 christos /* Public API to SFrame. 2 1.1 christos 3 1.1.1.2 christos Copyright (C) 2022-2024 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos This file is part of libsframe. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 1.1 christos 20 1.1 christos #ifndef _SFRAME_API_H 21 1.1 christos #define _SFRAME_API_H 22 1.1 christos 23 1.1 christos #include <sframe.h> 24 1.1 christos #include <stdbool.h> 25 1.1 christos 26 1.1 christos #ifdef __cplusplus 27 1.1 christos extern "C" 28 1.1 christos { 29 1.1 christos #endif 30 1.1 christos 31 1.1 christos typedef struct sframe_decoder_ctx sframe_decoder_ctx; 32 1.1 christos typedef struct sframe_encoder_ctx sframe_encoder_ctx; 33 1.1 christos 34 1.1.1.2 christos #define MAX_NUM_STACK_OFFSETS 3 35 1.1.1.2 christos 36 1.1.1.2 christos #define MAX_OFFSET_BYTES \ 37 1.1.1.2 christos ((SFRAME_FRE_OFFSET_4B * 2 * MAX_NUM_STACK_OFFSETS)) 38 1.1 christos 39 1.1 christos /* User interfacing SFrame Row Entry. 40 1.1 christos An abstraction provided by libsframe so the consumer is decoupled from 41 1.1 christos the binary format representation of the same. 42 1.1 christos 43 1.1 christos The members are best ordered such that they are aligned at their natural 44 1.1 christos boundaries. This helps avoid usage of undesirable misaligned memory 45 1.1 christos accesses. See PR libsframe/29856. */ 46 1.1 christos 47 1.1 christos typedef struct sframe_frame_row_entry 48 1.1 christos { 49 1.1 christos uint32_t fre_start_addr; 50 1.1 christos unsigned char fre_offsets[MAX_OFFSET_BYTES]; 51 1.1 christos unsigned char fre_info; 52 1.1 christos } sframe_frame_row_entry; 53 1.1 christos 54 1.1 christos #define SFRAME_ERR ((int) -1) 55 1.1 christos 56 1.1 christos /* This macro holds information about all the available SFrame 57 1.1 christos errors. It is used to form both an enum holding all the error 58 1.1 christos constants, and also the error strings themselves. To use, define 59 1.1 christos _SFRAME_FIRST and _SFRAME_ITEM to expand as you like, then 60 1.1 christos mention the macro name. See the enum after this for an example. */ 61 1.1 christos #define _SFRAME_ERRORS \ 62 1.1 christos _SFRAME_FIRST (SFRAME_ERR_VERSION_INVAL, "SFrame version not supported.") \ 63 1.1 christos _SFRAME_ITEM (SFRAME_ERR_NOMEM, "Out of Memory.") \ 64 1.1 christos _SFRAME_ITEM (SFRAME_ERR_INVAL, "Corrupt SFrame.") \ 65 1.1 christos _SFRAME_ITEM (SFRAME_ERR_BUF_INVAL, "Buffer does not contain SFrame data.") \ 66 1.1 christos _SFRAME_ITEM (SFRAME_ERR_DCTX_INVAL, "Corrupt SFrame decoder.") \ 67 1.1 christos _SFRAME_ITEM (SFRAME_ERR_ECTX_INVAL, "Corrupt SFrame encoder.") \ 68 1.1 christos _SFRAME_ITEM (SFRAME_ERR_FDE_INVAL, "Corrput FDE.") \ 69 1.1 christos _SFRAME_ITEM (SFRAME_ERR_FRE_INVAL, "Corrupt FRE.") \ 70 1.1 christos _SFRAME_ITEM (SFRAME_ERR_FDE_NOTFOUND,"FDE not found.") \ 71 1.1 christos _SFRAME_ITEM (SFRAME_ERR_FDE_NOTSORTED, "FDEs not sorted.") \ 72 1.1 christos _SFRAME_ITEM (SFRAME_ERR_FRE_NOTFOUND,"FRE not found.") \ 73 1.1 christos _SFRAME_ITEM (SFRAME_ERR_FREOFFSET_NOPRESENT,"FRE offset not present.") 74 1.1 christos 75 1.1 christos #define SFRAME_ERR_BASE 2000 /* Base value for libsframe errnos. */ 76 1.1 christos 77 1.1 christos enum 78 1.1 christos { 79 1.1 christos #define _SFRAME_FIRST(NAME, STR) NAME = SFRAME_ERR_BASE 80 1.1 christos #define _SFRAME_ITEM(NAME, STR) , NAME 81 1.1 christos _SFRAME_ERRORS 82 1.1 christos #undef _SFRAME_ITEM 83 1.1 christos #undef _SFRAME_FIRST 84 1.1 christos }; 85 1.1 christos 86 1.1 christos /* Count of SFrame errors. */ 87 1.1 christos #define SFRAME_ERR_NERR (SFRAME_ERR_FREOFFSET_NOPRESENT - SFRAME_ERR_BASE + 1) 88 1.1 christos 89 1.1 christos /* Get the error message string. */ 90 1.1 christos 91 1.1 christos extern const char * 92 1.1 christos sframe_errmsg (int error); 93 1.1 christos 94 1.1 christos /* Create an FDE function info bye given an FRE_TYPE and an FDE_TYPE. */ 95 1.1 christos 96 1.1 christos extern unsigned char 97 1.1.1.2 christos sframe_fde_create_func_info (uint32_t fre_type, uint32_t fde_type); 98 1.1 christos 99 1.1 christos /* Gather the FRE type given the function size. */ 100 1.1 christos 101 1.1.1.2 christos extern uint32_t 102 1.1.1.2 christos sframe_calc_fre_type (size_t func_size); 103 1.1 christos 104 1.1 christos /* The SFrame Decoder. */ 105 1.1 christos 106 1.1 christos /* Decode the specified SFrame buffer CF_BUF of size CF_SIZE and return the 107 1.1 christos new SFrame decoder context. Sets ERRP for the caller if any error. */ 108 1.1 christos extern sframe_decoder_ctx * 109 1.1 christos sframe_decode (const char *cf_buf, size_t cf_size, int *errp); 110 1.1 christos 111 1.1 christos /* Free the decoder context. */ 112 1.1 christos extern void 113 1.1 christos sframe_decoder_free (sframe_decoder_ctx **dctx); 114 1.1 christos 115 1.1 christos /* Get the size of the SFrame header from the decoder context DCTX. */ 116 1.1 christos extern unsigned int 117 1.1 christos sframe_decoder_get_hdr_size (sframe_decoder_ctx *dctx); 118 1.1 christos 119 1.1 christos /* Get the SFrame's abi/arch info. */ 120 1.1.1.2 christos extern uint8_t 121 1.1 christos sframe_decoder_get_abi_arch (sframe_decoder_ctx *dctx); 122 1.1 christos 123 1.1.1.2 christos /* Get the format version from the SFrame decoder context DCTX. */ 124 1.1.1.2 christos extern uint8_t 125 1.1.1.2 christos sframe_decoder_get_version (sframe_decoder_ctx *dctx); 126 1.1.1.2 christos 127 1.1 christos /* Return the number of function descriptor entries in the SFrame decoder 128 1.1 christos DCTX. */ 129 1.1.1.2 christos extern uint32_t 130 1.1 christos sframe_decoder_get_num_fidx (sframe_decoder_ctx *dctx); 131 1.1 christos 132 1.1 christos /* Get the fixed FP offset from the decoder context DCTX. */ 133 1.1 christos extern int8_t 134 1.1 christos sframe_decoder_get_fixed_fp_offset (sframe_decoder_ctx *dctx); 135 1.1 christos 136 1.1 christos /* Get the fixed RA offset from the decoder context DCTX. */ 137 1.1 christos extern int8_t 138 1.1 christos sframe_decoder_get_fixed_ra_offset (sframe_decoder_ctx *dctx); 139 1.1 christos 140 1.1.1.2 christos /* Find the function descriptor entry which contains the specified address. 141 1.1.1.2 christos 142 1.1.1.2 christos Note: This function is deprecated and will be removed from future release 143 1.1.1.2 christos X+2 of the library. */ 144 1.1.1.2 christos extern void * 145 1.1.1.2 christos sframe_get_funcdesc_with_addr (sframe_decoder_ctx *dctx, int32_t addr, 146 1.1.1.2 christos int *errp); 147 1.1 christos 148 1.1 christos /* Find the SFrame Frame Row Entry which contains the PC. Returns 149 1.1 christos SFRAME_ERR if failure. */ 150 1.1 christos 151 1.1 christos extern int 152 1.1 christos sframe_find_fre (sframe_decoder_ctx *ctx, int32_t pc, 153 1.1 christos sframe_frame_row_entry *frep); 154 1.1 christos 155 1.1 christos /* Get the FRE_IDX'th FRE of the function at FUNC_IDX'th function 156 1.1 christos index entry in the SFrame decoder CTX. Returns error code as 157 1.1 christos applicable. */ 158 1.1 christos extern int 159 1.1 christos sframe_decoder_get_fre (sframe_decoder_ctx *ctx, 160 1.1 christos unsigned int func_idx, 161 1.1 christos unsigned int fre_idx, 162 1.1 christos sframe_frame_row_entry *fre); 163 1.1 christos 164 1.1 christos /* Get the data (NUM_FRES, FUNC_START_ADDRESS) from the function 165 1.1 christos descriptor entry at index I'th in the decoder CTX. If failed, 166 1.1 christos return error code. */ 167 1.1 christos extern int 168 1.1 christos sframe_decoder_get_funcdesc (sframe_decoder_ctx *ctx, 169 1.1 christos unsigned int i, 170 1.1 christos uint32_t *num_fres, 171 1.1 christos uint32_t *func_size, 172 1.1 christos int32_t *func_start_address, 173 1.1 christos unsigned char *func_info); 174 1.1 christos 175 1.1.1.2 christos /* Get the data (NUM_FRES, FUNC_SIZE, FUNC_START_ADDRESS, FUNC_INFO, 176 1.1.1.2 christos REP_BLOCK_SIZE) from the function descriptor entry at index I'th 177 1.1.1.2 christos in the decoder CTX. If failed, return error code. 178 1.1.1.2 christos This API is only available from SFRAME_VERSION_2. */ 179 1.1.1.2 christos extern int 180 1.1.1.2 christos sframe_decoder_get_funcdesc_v2 (sframe_decoder_ctx *ctx, 181 1.1.1.2 christos unsigned int i, 182 1.1.1.2 christos uint32_t *num_fres, 183 1.1.1.2 christos uint32_t *func_size, 184 1.1.1.2 christos int32_t *func_start_address, 185 1.1.1.2 christos unsigned char *func_info, 186 1.1.1.2 christos uint8_t *rep_block_size); 187 1.1.1.2 christos 188 1.1 christos /* SFrame textual dump. */ 189 1.1 christos extern void 190 1.1 christos dump_sframe (sframe_decoder_ctx *decoder, uint64_t addr); 191 1.1 christos 192 1.1 christos /* Get the base reg id from the FRE info. Sets errp if fails. */ 193 1.1.1.2 christos extern uint8_t 194 1.1 christos sframe_fre_get_base_reg_id (sframe_frame_row_entry *fre, int *errp); 195 1.1 christos 196 1.1 christos /* Get the CFA offset from the FRE. If the offset is invalid, sets errp. */ 197 1.1 christos extern int32_t 198 1.1 christos sframe_fre_get_cfa_offset (sframe_decoder_ctx *dtcx, 199 1.1 christos sframe_frame_row_entry *fre, int *errp); 200 1.1 christos 201 1.1 christos /* Get the FP offset from the FRE. If the offset is invalid, sets errp. */ 202 1.1 christos extern int32_t 203 1.1 christos sframe_fre_get_fp_offset (sframe_decoder_ctx *dctx, 204 1.1 christos sframe_frame_row_entry *fre, int *errp); 205 1.1 christos 206 1.1 christos /* Get the RA offset from the FRE. If the offset is invalid, sets errp. */ 207 1.1 christos extern int32_t 208 1.1 christos sframe_fre_get_ra_offset (sframe_decoder_ctx *dctx, 209 1.1 christos sframe_frame_row_entry *fre, int *errp); 210 1.1 christos 211 1.1 christos /* Get whether the RA is mangled. */ 212 1.1 christos 213 1.1 christos extern bool 214 1.1 christos sframe_fre_get_ra_mangled_p (sframe_decoder_ctx *dctx, 215 1.1 christos sframe_frame_row_entry *fre, int *errp); 216 1.1 christos 217 1.1 christos /* The SFrame Encoder. */ 218 1.1 christos 219 1.1 christos /* Create an encoder context with the given SFrame format version VER, FLAGS 220 1.1 christos and ABI information. Sets errp if failure. */ 221 1.1 christos extern sframe_encoder_ctx * 222 1.1.1.2 christos sframe_encode (uint8_t ver, uint8_t flags, uint8_t abi_arch, 223 1.1 christos int8_t fixed_fp_offset, int8_t fixed_ra_offset, int *errp); 224 1.1 christos 225 1.1 christos /* Free the encoder context. */ 226 1.1 christos extern void 227 1.1 christos sframe_encoder_free (sframe_encoder_ctx **encoder); 228 1.1 christos 229 1.1 christos /* Get the size of the SFrame header from the encoder ctx ENCODER. */ 230 1.1 christos extern unsigned int 231 1.1 christos sframe_encoder_get_hdr_size (sframe_encoder_ctx *encoder); 232 1.1 christos 233 1.1 christos /* Get the abi/arch info from the SFrame encoder context CTX. */ 234 1.1.1.2 christos extern uint8_t 235 1.1 christos sframe_encoder_get_abi_arch (sframe_encoder_ctx *encoder); 236 1.1 christos 237 1.1.1.2 christos /* Get the format version from the SFrame encoder context ENCODER. */ 238 1.1.1.2 christos extern uint8_t 239 1.1.1.2 christos sframe_encoder_get_version (sframe_encoder_ctx *encoder); 240 1.1.1.2 christos 241 1.1 christos /* Return the number of function descriptor entries in the SFrame encoder 242 1.1 christos ENCODER. */ 243 1.1.1.2 christos extern uint32_t 244 1.1 christos sframe_encoder_get_num_fidx (sframe_encoder_ctx *encoder); 245 1.1 christos 246 1.1 christos /* Add an FRE to function at FUNC_IDX'th function descriptor index entry in 247 1.1 christos the encoder context. */ 248 1.1 christos extern int 249 1.1 christos sframe_encoder_add_fre (sframe_encoder_ctx *encoder, 250 1.1 christos unsigned int func_idx, 251 1.1 christos sframe_frame_row_entry *frep); 252 1.1 christos 253 1.1 christos /* Add a new function descriptor entry with START_ADDR, FUNC_SIZE and NUM_FRES 254 1.1 christos to the encoder. */ 255 1.1 christos extern int 256 1.1 christos sframe_encoder_add_funcdesc (sframe_encoder_ctx *encoder, 257 1.1 christos int32_t start_addr, 258 1.1 christos uint32_t func_size, 259 1.1 christos unsigned char func_info, 260 1.1 christos uint32_t num_fres); 261 1.1 christos 262 1.1.1.2 christos /* Add a new function descriptor entry with START_ADDR, FUNC_SIZE, FUNC_INFO 263 1.1.1.2 christos and REP_BLOCK_SIZE to the encoder. */ 264 1.1.1.2 christos extern int 265 1.1.1.2 christos sframe_encoder_add_funcdesc_v2 (sframe_encoder_ctx *encoder, 266 1.1.1.2 christos int32_t start_addr, 267 1.1.1.2 christos uint32_t func_size, 268 1.1.1.2 christos unsigned char func_info, 269 1.1.1.2 christos uint8_t rep_block_size, 270 1.1.1.2 christos uint32_t num_fres); 271 1.1.1.2 christos 272 1.1 christos /* Serialize the contents of the encoder and return the buffer. ENCODED_SIZE 273 1.1 christos is updated to the size of the buffer. Sets ERRP if failure. */ 274 1.1 christos extern char * 275 1.1 christos sframe_encoder_write (sframe_encoder_ctx *encoder, 276 1.1 christos size_t *encoded_size, int *errp); 277 1.1 christos 278 1.1 christos #ifdef __cplusplus 279 1.1 christos } 280 1.1 christos #endif 281 1.1 christos 282 1.1 christos #endif /* _SFRAME_API_H */ 283