14b169a6bSchristos /* Public API to SFrame. 24b169a6bSchristos 3*e663ba6eSchristos Copyright (C) 2022-2024 Free Software Foundation, Inc. 44b169a6bSchristos 54b169a6bSchristos This file is part of libsframe. 64b169a6bSchristos 74b169a6bSchristos This program is free software; you can redistribute it and/or modify 84b169a6bSchristos it under the terms of the GNU General Public License as published by 94b169a6bSchristos the Free Software Foundation; either version 3 of the License, or 104b169a6bSchristos (at your option) any later version. 114b169a6bSchristos 124b169a6bSchristos This program is distributed in the hope that it will be useful, 134b169a6bSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 144b169a6bSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 154b169a6bSchristos GNU General Public License for more details. 164b169a6bSchristos 174b169a6bSchristos You should have received a copy of the GNU General Public License 184b169a6bSchristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 194b169a6bSchristos 204b169a6bSchristos #ifndef _SFRAME_API_H 214b169a6bSchristos #define _SFRAME_API_H 224b169a6bSchristos 234b169a6bSchristos #include <sframe.h> 244b169a6bSchristos #include <stdbool.h> 254b169a6bSchristos 264b169a6bSchristos #ifdef __cplusplus 274b169a6bSchristos extern "C" 284b169a6bSchristos { 294b169a6bSchristos #endif 304b169a6bSchristos 314b169a6bSchristos typedef struct sframe_decoder_ctx sframe_decoder_ctx; 324b169a6bSchristos typedef struct sframe_encoder_ctx sframe_encoder_ctx; 334b169a6bSchristos 34*e663ba6eSchristos #define MAX_NUM_STACK_OFFSETS 3 35*e663ba6eSchristos 36*e663ba6eSchristos #define MAX_OFFSET_BYTES \ 37*e663ba6eSchristos ((SFRAME_FRE_OFFSET_4B * 2 * MAX_NUM_STACK_OFFSETS)) 384b169a6bSchristos 394b169a6bSchristos /* User interfacing SFrame Row Entry. 404b169a6bSchristos An abstraction provided by libsframe so the consumer is decoupled from 414b169a6bSchristos the binary format representation of the same. 424b169a6bSchristos 434b169a6bSchristos The members are best ordered such that they are aligned at their natural 444b169a6bSchristos boundaries. This helps avoid usage of undesirable misaligned memory 454b169a6bSchristos accesses. See PR libsframe/29856. */ 464b169a6bSchristos 474b169a6bSchristos typedef struct sframe_frame_row_entry 484b169a6bSchristos { 494b169a6bSchristos uint32_t fre_start_addr; 504b169a6bSchristos unsigned char fre_offsets[MAX_OFFSET_BYTES]; 514b169a6bSchristos unsigned char fre_info; 524b169a6bSchristos } sframe_frame_row_entry; 534b169a6bSchristos 544b169a6bSchristos #define SFRAME_ERR ((int) -1) 554b169a6bSchristos 564b169a6bSchristos /* This macro holds information about all the available SFrame 574b169a6bSchristos errors. It is used to form both an enum holding all the error 584b169a6bSchristos constants, and also the error strings themselves. To use, define 594b169a6bSchristos _SFRAME_FIRST and _SFRAME_ITEM to expand as you like, then 604b169a6bSchristos mention the macro name. See the enum after this for an example. */ 614b169a6bSchristos #define _SFRAME_ERRORS \ 624b169a6bSchristos _SFRAME_FIRST (SFRAME_ERR_VERSION_INVAL, "SFrame version not supported.") \ 634b169a6bSchristos _SFRAME_ITEM (SFRAME_ERR_NOMEM, "Out of Memory.") \ 644b169a6bSchristos _SFRAME_ITEM (SFRAME_ERR_INVAL, "Corrupt SFrame.") \ 654b169a6bSchristos _SFRAME_ITEM (SFRAME_ERR_BUF_INVAL, "Buffer does not contain SFrame data.") \ 664b169a6bSchristos _SFRAME_ITEM (SFRAME_ERR_DCTX_INVAL, "Corrupt SFrame decoder.") \ 674b169a6bSchristos _SFRAME_ITEM (SFRAME_ERR_ECTX_INVAL, "Corrupt SFrame encoder.") \ 684b169a6bSchristos _SFRAME_ITEM (SFRAME_ERR_FDE_INVAL, "Corrput FDE.") \ 694b169a6bSchristos _SFRAME_ITEM (SFRAME_ERR_FRE_INVAL, "Corrupt FRE.") \ 704b169a6bSchristos _SFRAME_ITEM (SFRAME_ERR_FDE_NOTFOUND,"FDE not found.") \ 714b169a6bSchristos _SFRAME_ITEM (SFRAME_ERR_FDE_NOTSORTED, "FDEs not sorted.") \ 724b169a6bSchristos _SFRAME_ITEM (SFRAME_ERR_FRE_NOTFOUND,"FRE not found.") \ 734b169a6bSchristos _SFRAME_ITEM (SFRAME_ERR_FREOFFSET_NOPRESENT,"FRE offset not present.") 744b169a6bSchristos 754b169a6bSchristos #define SFRAME_ERR_BASE 2000 /* Base value for libsframe errnos. */ 764b169a6bSchristos 774b169a6bSchristos enum 784b169a6bSchristos { 794b169a6bSchristos #define _SFRAME_FIRST(NAME, STR) NAME = SFRAME_ERR_BASE 804b169a6bSchristos #define _SFRAME_ITEM(NAME, STR) , NAME 814b169a6bSchristos _SFRAME_ERRORS 824b169a6bSchristos #undef _SFRAME_ITEM 834b169a6bSchristos #undef _SFRAME_FIRST 844b169a6bSchristos }; 854b169a6bSchristos 864b169a6bSchristos /* Count of SFrame errors. */ 874b169a6bSchristos #define SFRAME_ERR_NERR (SFRAME_ERR_FREOFFSET_NOPRESENT - SFRAME_ERR_BASE + 1) 884b169a6bSchristos 894b169a6bSchristos /* Get the error message string. */ 904b169a6bSchristos 914b169a6bSchristos extern const char * 924b169a6bSchristos sframe_errmsg (int error); 934b169a6bSchristos 944b169a6bSchristos /* Create an FDE function info bye given an FRE_TYPE and an FDE_TYPE. */ 954b169a6bSchristos 964b169a6bSchristos extern unsigned char 97*e663ba6eSchristos sframe_fde_create_func_info (uint32_t fre_type, uint32_t fde_type); 984b169a6bSchristos 994b169a6bSchristos /* Gather the FRE type given the function size. */ 1004b169a6bSchristos 101*e663ba6eSchristos extern uint32_t 102*e663ba6eSchristos sframe_calc_fre_type (size_t func_size); 1034b169a6bSchristos 1044b169a6bSchristos /* The SFrame Decoder. */ 1054b169a6bSchristos 1064b169a6bSchristos /* Decode the specified SFrame buffer CF_BUF of size CF_SIZE and return the 1074b169a6bSchristos new SFrame decoder context. Sets ERRP for the caller if any error. */ 1084b169a6bSchristos extern sframe_decoder_ctx * 1094b169a6bSchristos sframe_decode (const char *cf_buf, size_t cf_size, int *errp); 1104b169a6bSchristos 1114b169a6bSchristos /* Free the decoder context. */ 1124b169a6bSchristos extern void 1134b169a6bSchristos sframe_decoder_free (sframe_decoder_ctx **dctx); 1144b169a6bSchristos 1154b169a6bSchristos /* Get the size of the SFrame header from the decoder context DCTX. */ 1164b169a6bSchristos extern unsigned int 1174b169a6bSchristos sframe_decoder_get_hdr_size (sframe_decoder_ctx *dctx); 1184b169a6bSchristos 1194b169a6bSchristos /* Get the SFrame's abi/arch info. */ 120*e663ba6eSchristos extern uint8_t 1214b169a6bSchristos sframe_decoder_get_abi_arch (sframe_decoder_ctx *dctx); 1224b169a6bSchristos 123*e663ba6eSchristos /* Get the format version from the SFrame decoder context DCTX. */ 124*e663ba6eSchristos extern uint8_t 125*e663ba6eSchristos sframe_decoder_get_version (sframe_decoder_ctx *dctx); 126*e663ba6eSchristos 1274b169a6bSchristos /* Return the number of function descriptor entries in the SFrame decoder 1284b169a6bSchristos DCTX. */ 129*e663ba6eSchristos extern uint32_t 1304b169a6bSchristos sframe_decoder_get_num_fidx (sframe_decoder_ctx *dctx); 1314b169a6bSchristos 1324b169a6bSchristos /* Get the fixed FP offset from the decoder context DCTX. */ 1334b169a6bSchristos extern int8_t 1344b169a6bSchristos sframe_decoder_get_fixed_fp_offset (sframe_decoder_ctx *dctx); 1354b169a6bSchristos 1364b169a6bSchristos /* Get the fixed RA offset from the decoder context DCTX. */ 1374b169a6bSchristos extern int8_t 1384b169a6bSchristos sframe_decoder_get_fixed_ra_offset (sframe_decoder_ctx *dctx); 1394b169a6bSchristos 140*e663ba6eSchristos /* Find the function descriptor entry which contains the specified address. 141*e663ba6eSchristos 142*e663ba6eSchristos Note: This function is deprecated and will be removed from future release 143*e663ba6eSchristos X+2 of the library. */ 144*e663ba6eSchristos extern void * 145*e663ba6eSchristos sframe_get_funcdesc_with_addr (sframe_decoder_ctx *dctx, int32_t addr, 146*e663ba6eSchristos int *errp); 1474b169a6bSchristos 1484b169a6bSchristos /* Find the SFrame Frame Row Entry which contains the PC. Returns 1494b169a6bSchristos SFRAME_ERR if failure. */ 1504b169a6bSchristos 1514b169a6bSchristos extern int 1524b169a6bSchristos sframe_find_fre (sframe_decoder_ctx *ctx, int32_t pc, 1534b169a6bSchristos sframe_frame_row_entry *frep); 1544b169a6bSchristos 1554b169a6bSchristos /* Get the FRE_IDX'th FRE of the function at FUNC_IDX'th function 1564b169a6bSchristos index entry in the SFrame decoder CTX. Returns error code as 1574b169a6bSchristos applicable. */ 1584b169a6bSchristos extern int 1594b169a6bSchristos sframe_decoder_get_fre (sframe_decoder_ctx *ctx, 1604b169a6bSchristos unsigned int func_idx, 1614b169a6bSchristos unsigned int fre_idx, 1624b169a6bSchristos sframe_frame_row_entry *fre); 1634b169a6bSchristos 1644b169a6bSchristos /* Get the data (NUM_FRES, FUNC_START_ADDRESS) from the function 1654b169a6bSchristos descriptor entry at index I'th in the decoder CTX. If failed, 1664b169a6bSchristos return error code. */ 1674b169a6bSchristos extern int 1684b169a6bSchristos sframe_decoder_get_funcdesc (sframe_decoder_ctx *ctx, 1694b169a6bSchristos unsigned int i, 1704b169a6bSchristos uint32_t *num_fres, 1714b169a6bSchristos uint32_t *func_size, 1724b169a6bSchristos int32_t *func_start_address, 1734b169a6bSchristos unsigned char *func_info); 1744b169a6bSchristos 175*e663ba6eSchristos /* Get the data (NUM_FRES, FUNC_SIZE, FUNC_START_ADDRESS, FUNC_INFO, 176*e663ba6eSchristos REP_BLOCK_SIZE) from the function descriptor entry at index I'th 177*e663ba6eSchristos in the decoder CTX. If failed, return error code. 178*e663ba6eSchristos This API is only available from SFRAME_VERSION_2. */ 179*e663ba6eSchristos extern int 180*e663ba6eSchristos sframe_decoder_get_funcdesc_v2 (sframe_decoder_ctx *ctx, 181*e663ba6eSchristos unsigned int i, 182*e663ba6eSchristos uint32_t *num_fres, 183*e663ba6eSchristos uint32_t *func_size, 184*e663ba6eSchristos int32_t *func_start_address, 185*e663ba6eSchristos unsigned char *func_info, 186*e663ba6eSchristos uint8_t *rep_block_size); 187*e663ba6eSchristos 1884b169a6bSchristos /* SFrame textual dump. */ 1894b169a6bSchristos extern void 1904b169a6bSchristos dump_sframe (sframe_decoder_ctx *decoder, uint64_t addr); 1914b169a6bSchristos 1924b169a6bSchristos /* Get the base reg id from the FRE info. Sets errp if fails. */ 193*e663ba6eSchristos extern uint8_t 1944b169a6bSchristos sframe_fre_get_base_reg_id (sframe_frame_row_entry *fre, int *errp); 1954b169a6bSchristos 1964b169a6bSchristos /* Get the CFA offset from the FRE. If the offset is invalid, sets errp. */ 1974b169a6bSchristos extern int32_t 1984b169a6bSchristos sframe_fre_get_cfa_offset (sframe_decoder_ctx *dtcx, 1994b169a6bSchristos sframe_frame_row_entry *fre, int *errp); 2004b169a6bSchristos 2014b169a6bSchristos /* Get the FP offset from the FRE. If the offset is invalid, sets errp. */ 2024b169a6bSchristos extern int32_t 2034b169a6bSchristos sframe_fre_get_fp_offset (sframe_decoder_ctx *dctx, 2044b169a6bSchristos sframe_frame_row_entry *fre, int *errp); 2054b169a6bSchristos 2064b169a6bSchristos /* Get the RA offset from the FRE. If the offset is invalid, sets errp. */ 2074b169a6bSchristos extern int32_t 2084b169a6bSchristos sframe_fre_get_ra_offset (sframe_decoder_ctx *dctx, 2094b169a6bSchristos sframe_frame_row_entry *fre, int *errp); 2104b169a6bSchristos 2114b169a6bSchristos /* Get whether the RA is mangled. */ 2124b169a6bSchristos 2134b169a6bSchristos extern bool 2144b169a6bSchristos sframe_fre_get_ra_mangled_p (sframe_decoder_ctx *dctx, 2154b169a6bSchristos sframe_frame_row_entry *fre, int *errp); 2164b169a6bSchristos 2174b169a6bSchristos /* The SFrame Encoder. */ 2184b169a6bSchristos 2194b169a6bSchristos /* Create an encoder context with the given SFrame format version VER, FLAGS 2204b169a6bSchristos and ABI information. Sets errp if failure. */ 2214b169a6bSchristos extern sframe_encoder_ctx * 222*e663ba6eSchristos sframe_encode (uint8_t ver, uint8_t flags, uint8_t abi_arch, 2234b169a6bSchristos int8_t fixed_fp_offset, int8_t fixed_ra_offset, int *errp); 2244b169a6bSchristos 2254b169a6bSchristos /* Free the encoder context. */ 2264b169a6bSchristos extern void 2274b169a6bSchristos sframe_encoder_free (sframe_encoder_ctx **encoder); 2284b169a6bSchristos 2294b169a6bSchristos /* Get the size of the SFrame header from the encoder ctx ENCODER. */ 2304b169a6bSchristos extern unsigned int 2314b169a6bSchristos sframe_encoder_get_hdr_size (sframe_encoder_ctx *encoder); 2324b169a6bSchristos 2334b169a6bSchristos /* Get the abi/arch info from the SFrame encoder context CTX. */ 234*e663ba6eSchristos extern uint8_t 2354b169a6bSchristos sframe_encoder_get_abi_arch (sframe_encoder_ctx *encoder); 2364b169a6bSchristos 237*e663ba6eSchristos /* Get the format version from the SFrame encoder context ENCODER. */ 238*e663ba6eSchristos extern uint8_t 239*e663ba6eSchristos sframe_encoder_get_version (sframe_encoder_ctx *encoder); 240*e663ba6eSchristos 2414b169a6bSchristos /* Return the number of function descriptor entries in the SFrame encoder 2424b169a6bSchristos ENCODER. */ 243*e663ba6eSchristos extern uint32_t 2444b169a6bSchristos sframe_encoder_get_num_fidx (sframe_encoder_ctx *encoder); 2454b169a6bSchristos 2464b169a6bSchristos /* Add an FRE to function at FUNC_IDX'th function descriptor index entry in 2474b169a6bSchristos the encoder context. */ 2484b169a6bSchristos extern int 2494b169a6bSchristos sframe_encoder_add_fre (sframe_encoder_ctx *encoder, 2504b169a6bSchristos unsigned int func_idx, 2514b169a6bSchristos sframe_frame_row_entry *frep); 2524b169a6bSchristos 2534b169a6bSchristos /* Add a new function descriptor entry with START_ADDR, FUNC_SIZE and NUM_FRES 2544b169a6bSchristos to the encoder. */ 2554b169a6bSchristos extern int 2564b169a6bSchristos sframe_encoder_add_funcdesc (sframe_encoder_ctx *encoder, 2574b169a6bSchristos int32_t start_addr, 2584b169a6bSchristos uint32_t func_size, 2594b169a6bSchristos unsigned char func_info, 2604b169a6bSchristos uint32_t num_fres); 2614b169a6bSchristos 262*e663ba6eSchristos /* Add a new function descriptor entry with START_ADDR, FUNC_SIZE, FUNC_INFO 263*e663ba6eSchristos and REP_BLOCK_SIZE to the encoder. */ 264*e663ba6eSchristos extern int 265*e663ba6eSchristos sframe_encoder_add_funcdesc_v2 (sframe_encoder_ctx *encoder, 266*e663ba6eSchristos int32_t start_addr, 267*e663ba6eSchristos uint32_t func_size, 268*e663ba6eSchristos unsigned char func_info, 269*e663ba6eSchristos uint8_t rep_block_size, 270*e663ba6eSchristos uint32_t num_fres); 271*e663ba6eSchristos 2724b169a6bSchristos /* Serialize the contents of the encoder and return the buffer. ENCODED_SIZE 2734b169a6bSchristos is updated to the size of the buffer. Sets ERRP if failure. */ 2744b169a6bSchristos extern char * 2754b169a6bSchristos sframe_encoder_write (sframe_encoder_ctx *encoder, 2764b169a6bSchristos size_t *encoded_size, int *errp); 2774b169a6bSchristos 2784b169a6bSchristos #ifdef __cplusplus 2794b169a6bSchristos } 2804b169a6bSchristos #endif 2814b169a6bSchristos 2824b169a6bSchristos #endif /* _SFRAME_API_H */ 283