1 1.1 christos /* Public API to SFrame. 2 1.1 christos 3 1.1.1.2 christos Copyright (C) 2022-2025 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 christos #define MAX_NUM_STACK_OFFSETS 3 35 1.1 christos 36 1.1 christos #define MAX_OFFSET_BYTES \ 37 1.1 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 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 christos extern uint32_t 102 1.1 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 christos extern uint8_t 121 1.1 christos sframe_decoder_get_abi_arch (sframe_decoder_ctx *dctx); 122 1.1 christos 123 1.1 christos /* Get the format version from the SFrame decoder context DCTX. */ 124 1.1 christos extern uint8_t 125 1.1 christos sframe_decoder_get_version (sframe_decoder_ctx *dctx); 126 1.1 christos 127 1.1.1.2 christos /* Get the section flags from the SFrame decoder context DCTX. */ 128 1.1.1.2 christos extern uint8_t 129 1.1.1.2 christos sframe_decoder_get_flags (sframe_decoder_ctx *dctx); 130 1.1.1.2 christos 131 1.1.1.2 christos /* Get the offset of the sfde_func_start_address field (from the start of the 132 1.1.1.2 christos on-disk layout of the SFrame section) of the FDE at FUNC_IDX in the decoder 133 1.1.1.2 christos context DCTX. 134 1.1.1.2 christos 135 1.1.1.2 christos If FUNC_IDX is more than the number of SFrame FDEs in the section, sets 136 1.1.1.2 christos error code in ERRP, but returns the (hypothetical) offset. This is useful 137 1.1.1.2 christos for the linker when arranging input FDEs into the output section to be 138 1.1.1.2 christos emitted. */ 139 1.1.1.2 christos uint32_t 140 1.1.1.2 christos sframe_decoder_get_offsetof_fde_start_addr (sframe_decoder_ctx *dctx, 141 1.1.1.2 christos uint32_t func_idx, int *errp); 142 1.1.1.2 christos 143 1.1 christos /* Return the number of function descriptor entries in the SFrame decoder 144 1.1 christos DCTX. */ 145 1.1 christos extern uint32_t 146 1.1 christos sframe_decoder_get_num_fidx (sframe_decoder_ctx *dctx); 147 1.1 christos 148 1.1 christos /* Get the fixed FP offset from the decoder context DCTX. */ 149 1.1 christos extern int8_t 150 1.1 christos sframe_decoder_get_fixed_fp_offset (sframe_decoder_ctx *dctx); 151 1.1 christos 152 1.1 christos /* Get the fixed RA offset from the decoder context DCTX. */ 153 1.1 christos extern int8_t 154 1.1 christos sframe_decoder_get_fixed_ra_offset (sframe_decoder_ctx *dctx); 155 1.1 christos 156 1.1 christos /* Find the SFrame Frame Row Entry which contains the PC. Returns 157 1.1 christos SFRAME_ERR if failure. */ 158 1.1 christos 159 1.1 christos extern int 160 1.1 christos sframe_find_fre (sframe_decoder_ctx *ctx, int32_t pc, 161 1.1 christos sframe_frame_row_entry *frep); 162 1.1 christos 163 1.1 christos /* Get the FRE_IDX'th FRE of the function at FUNC_IDX'th function 164 1.1 christos index entry in the SFrame decoder CTX. Returns error code as 165 1.1 christos applicable. */ 166 1.1 christos extern int 167 1.1 christos sframe_decoder_get_fre (sframe_decoder_ctx *ctx, 168 1.1 christos unsigned int func_idx, 169 1.1 christos unsigned int fre_idx, 170 1.1 christos sframe_frame_row_entry *fre); 171 1.1 christos 172 1.1 christos /* Get the data (NUM_FRES, FUNC_START_ADDRESS) from the function 173 1.1 christos descriptor entry at index I'th in the decoder CTX. If failed, 174 1.1 christos return error code. */ 175 1.1 christos extern int 176 1.1 christos sframe_decoder_get_funcdesc (sframe_decoder_ctx *ctx, 177 1.1 christos unsigned int i, 178 1.1 christos uint32_t *num_fres, 179 1.1 christos uint32_t *func_size, 180 1.1 christos int32_t *func_start_address, 181 1.1 christos unsigned char *func_info); 182 1.1 christos 183 1.1 christos /* Get the data (NUM_FRES, FUNC_SIZE, FUNC_START_ADDRESS, FUNC_INFO, 184 1.1 christos REP_BLOCK_SIZE) from the function descriptor entry at index I'th 185 1.1 christos in the decoder CTX. If failed, return error code. 186 1.1 christos This API is only available from SFRAME_VERSION_2. */ 187 1.1 christos extern int 188 1.1 christos sframe_decoder_get_funcdesc_v2 (sframe_decoder_ctx *ctx, 189 1.1 christos unsigned int i, 190 1.1 christos uint32_t *num_fres, 191 1.1 christos uint32_t *func_size, 192 1.1 christos int32_t *func_start_address, 193 1.1 christos unsigned char *func_info, 194 1.1 christos uint8_t *rep_block_size); 195 1.1 christos 196 1.1 christos /* SFrame textual dump. */ 197 1.1 christos extern void 198 1.1 christos dump_sframe (sframe_decoder_ctx *decoder, uint64_t addr); 199 1.1 christos 200 1.1 christos /* Get the base reg id from the FRE info. Sets errp if fails. */ 201 1.1 christos extern uint8_t 202 1.1 christos sframe_fre_get_base_reg_id (sframe_frame_row_entry *fre, int *errp); 203 1.1 christos 204 1.1 christos /* Get the CFA offset from the FRE. If the offset is invalid, sets errp. */ 205 1.1 christos extern int32_t 206 1.1 christos sframe_fre_get_cfa_offset (sframe_decoder_ctx *dtcx, 207 1.1 christos sframe_frame_row_entry *fre, int *errp); 208 1.1 christos 209 1.1.1.2 christos /* Get the FP offset from the FRE. If the offset is invalid, sets errp. 210 1.1.1.2 christos 211 1.1.1.2 christos For s390x the offset may be an encoded register number, indicated by 212 1.1.1.2 christos LSB set to one, which is only valid in the topmost frame. */ 213 1.1 christos extern int32_t 214 1.1 christos sframe_fre_get_fp_offset (sframe_decoder_ctx *dctx, 215 1.1 christos sframe_frame_row_entry *fre, int *errp); 216 1.1 christos 217 1.1.1.2 christos /* Get the RA offset from the FRE. If the offset is invalid, sets errp. 218 1.1.1.2 christos 219 1.1.1.2 christos For s390x an RA offset value of SFRAME_FRE_RA_OFFSET_INVALID indicates 220 1.1.1.2 christos that the RA is not saved, which is only valid in the topmost frame. 221 1.1.1.2 christos For s390x the offset may be an encoded register number, indicated by 222 1.1.1.2 christos LSB set to one, which is only valid in the topmost frame. */ 223 1.1 christos extern int32_t 224 1.1 christos sframe_fre_get_ra_offset (sframe_decoder_ctx *dctx, 225 1.1 christos sframe_frame_row_entry *fre, int *errp); 226 1.1 christos 227 1.1 christos /* Get whether the RA is mangled. */ 228 1.1 christos 229 1.1 christos extern bool 230 1.1 christos sframe_fre_get_ra_mangled_p (sframe_decoder_ctx *dctx, 231 1.1 christos sframe_frame_row_entry *fre, int *errp); 232 1.1 christos 233 1.1 christos /* The SFrame Encoder. */ 234 1.1 christos 235 1.1 christos /* Create an encoder context with the given SFrame format version VER, FLAGS 236 1.1 christos and ABI information. Sets errp if failure. */ 237 1.1 christos extern sframe_encoder_ctx * 238 1.1 christos sframe_encode (uint8_t ver, uint8_t flags, uint8_t abi_arch, 239 1.1 christos int8_t fixed_fp_offset, int8_t fixed_ra_offset, int *errp); 240 1.1 christos 241 1.1 christos /* Free the encoder context. */ 242 1.1 christos extern void 243 1.1 christos sframe_encoder_free (sframe_encoder_ctx **encoder); 244 1.1 christos 245 1.1 christos /* Get the size of the SFrame header from the encoder ctx ENCODER. */ 246 1.1 christos extern unsigned int 247 1.1 christos sframe_encoder_get_hdr_size (sframe_encoder_ctx *encoder); 248 1.1 christos 249 1.1 christos /* Get the abi/arch info from the SFrame encoder context CTX. */ 250 1.1 christos extern uint8_t 251 1.1 christos sframe_encoder_get_abi_arch (sframe_encoder_ctx *encoder); 252 1.1 christos 253 1.1 christos /* Get the format version from the SFrame encoder context ENCODER. */ 254 1.1 christos extern uint8_t 255 1.1 christos sframe_encoder_get_version (sframe_encoder_ctx *encoder); 256 1.1 christos 257 1.1.1.2 christos /* Get the section flags from the SFrame encoder context ENCODER. */ 258 1.1.1.2 christos extern uint8_t 259 1.1.1.2 christos sframe_encoder_get_flags (sframe_encoder_ctx *encoder); 260 1.1.1.2 christos 261 1.1.1.2 christos /* Get the offset of the sfde_func_start_address field (from the start of the 262 1.1.1.2 christos on-disk layout of the SFrame section) of the FDE at FUNC_IDX in the encoder 263 1.1.1.2 christos context ENCODER. 264 1.1.1.2 christos 265 1.1.1.2 christos If FUNC_IDX is more than the number of SFrame FDEs in the section, sets 266 1.1.1.2 christos error code in ERRP, but returns the (hypothetical) offset. This is useful 267 1.1.1.2 christos for the linker when arranging input FDEs into the output section to be 268 1.1.1.2 christos emitted. */ 269 1.1.1.2 christos uint32_t 270 1.1.1.2 christos sframe_encoder_get_offsetof_fde_start_addr (sframe_encoder_ctx *encoder, 271 1.1.1.2 christos uint32_t func_idx, int *errp); 272 1.1.1.2 christos 273 1.1 christos /* Return the number of function descriptor entries in the SFrame encoder 274 1.1 christos ENCODER. */ 275 1.1 christos extern uint32_t 276 1.1 christos sframe_encoder_get_num_fidx (sframe_encoder_ctx *encoder); 277 1.1 christos 278 1.1 christos /* Add an FRE to function at FUNC_IDX'th function descriptor index entry in 279 1.1 christos the encoder context. */ 280 1.1 christos extern int 281 1.1 christos sframe_encoder_add_fre (sframe_encoder_ctx *encoder, 282 1.1 christos unsigned int func_idx, 283 1.1 christos sframe_frame_row_entry *frep); 284 1.1 christos 285 1.1 christos /* Add a new function descriptor entry with START_ADDR, FUNC_SIZE and NUM_FRES 286 1.1 christos to the encoder. */ 287 1.1 christos extern int 288 1.1 christos sframe_encoder_add_funcdesc (sframe_encoder_ctx *encoder, 289 1.1 christos int32_t start_addr, 290 1.1 christos uint32_t func_size, 291 1.1 christos unsigned char func_info, 292 1.1 christos uint32_t num_fres); 293 1.1 christos 294 1.1 christos /* Add a new function descriptor entry with START_ADDR, FUNC_SIZE, FUNC_INFO 295 1.1 christos and REP_BLOCK_SIZE to the encoder. */ 296 1.1 christos extern int 297 1.1 christos sframe_encoder_add_funcdesc_v2 (sframe_encoder_ctx *encoder, 298 1.1 christos int32_t start_addr, 299 1.1 christos uint32_t func_size, 300 1.1 christos unsigned char func_info, 301 1.1 christos uint8_t rep_block_size, 302 1.1 christos uint32_t num_fres); 303 1.1 christos 304 1.1 christos /* Serialize the contents of the encoder and return the buffer. ENCODED_SIZE 305 1.1 christos is updated to the size of the buffer. Sets ERRP if failure. */ 306 1.1 christos extern char * 307 1.1 christos sframe_encoder_write (sframe_encoder_ctx *encoder, 308 1.1 christos size_t *encoded_size, int *errp); 309 1.1 christos 310 1.1 christos #ifdef __cplusplus 311 1.1 christos } 312 1.1 christos #endif 313 1.1 christos 314 1.1 christos #endif /* _SFRAME_API_H */ 315