| /* Public API to SFrame. |
| |
| Copyright (C) 2022-2024 Free Software Foundation, Inc. |
| |
| This file is part of libsframe. |
| |
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 3 of the License, or |
| (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| |
| #ifndef _SFRAME_API_H |
| #define _SFRAME_API_H |
| |
| #include <sframe.h> |
| #include <stdbool.h> |
| |
| #ifdef __cplusplus |
| extern "C" |
| { |
| #endif |
| |
| typedef struct sframe_decoder_ctx sframe_decoder_ctx; |
| typedef struct sframe_encoder_ctx sframe_encoder_ctx; |
| |
| #define MAX_NUM_STACK_OFFSETS 3 |
| |
| #define MAX_OFFSET_BYTES \ |
| ((SFRAME_FRE_OFFSET_4B * 2 * MAX_NUM_STACK_OFFSETS)) |
| |
| /* User interfacing SFrame Row Entry. |
| An abstraction provided by libsframe so the consumer is decoupled from |
| the binary format representation of the same. |
| |
| The members are best ordered such that they are aligned at their natural |
| boundaries. This helps avoid usage of undesirable misaligned memory |
| accesses. See PR libsframe/29856. */ |
| |
| typedef struct sframe_frame_row_entry |
| { |
| uint32_t fre_start_addr; |
| unsigned char fre_offsets[MAX_OFFSET_BYTES]; |
| unsigned char fre_info; |
| } sframe_frame_row_entry; |
| |
| #define SFRAME_ERR ((int) -1) |
| |
| /* This macro holds information about all the available SFrame |
| errors. It is used to form both an enum holding all the error |
| constants, and also the error strings themselves. To use, define |
| _SFRAME_FIRST and _SFRAME_ITEM to expand as you like, then |
| mention the macro name. See the enum after this for an example. */ |
| #define _SFRAME_ERRORS \ |
| _SFRAME_FIRST (SFRAME_ERR_VERSION_INVAL, "SFrame version not supported.") \ |
| _SFRAME_ITEM (SFRAME_ERR_NOMEM, "Out of Memory.") \ |
| _SFRAME_ITEM (SFRAME_ERR_INVAL, "Corrupt SFrame.") \ |
| _SFRAME_ITEM (SFRAME_ERR_BUF_INVAL, "Buffer does not contain SFrame data.") \ |
| _SFRAME_ITEM (SFRAME_ERR_DCTX_INVAL, "Corrupt SFrame decoder.") \ |
| _SFRAME_ITEM (SFRAME_ERR_ECTX_INVAL, "Corrupt SFrame encoder.") \ |
| _SFRAME_ITEM (SFRAME_ERR_FDE_INVAL, "Corrput FDE.") \ |
| _SFRAME_ITEM (SFRAME_ERR_FRE_INVAL, "Corrupt FRE.") \ |
| _SFRAME_ITEM (SFRAME_ERR_FDE_NOTFOUND,"FDE not found.") \ |
| _SFRAME_ITEM (SFRAME_ERR_FDE_NOTSORTED, "FDEs not sorted.") \ |
| _SFRAME_ITEM (SFRAME_ERR_FRE_NOTFOUND,"FRE not found.") \ |
| _SFRAME_ITEM (SFRAME_ERR_FREOFFSET_NOPRESENT,"FRE offset not present.") |
| |
| #define SFRAME_ERR_BASE 2000 /* Base value for libsframe errnos. */ |
| |
| enum |
| { |
| #define _SFRAME_FIRST(NAME, STR) NAME = SFRAME_ERR_BASE |
| #define _SFRAME_ITEM(NAME, STR) , NAME |
| _SFRAME_ERRORS |
| #undef _SFRAME_ITEM |
| #undef _SFRAME_FIRST |
| }; |
| |
| /* Count of SFrame errors. */ |
| #define SFRAME_ERR_NERR (SFRAME_ERR_FREOFFSET_NOPRESENT - SFRAME_ERR_BASE + 1) |
| |
| /* Get the error message string. */ |
| |
| extern const char * |
| sframe_errmsg (int error); |
| |
| /* Create an FDE function info bye given an FRE_TYPE and an FDE_TYPE. */ |
| |
| extern unsigned char |
| sframe_fde_create_func_info (uint32_t fre_type, uint32_t fde_type); |
| |
| /* Gather the FRE type given the function size. */ |
| |
| extern uint32_t |
| sframe_calc_fre_type (size_t func_size); |
| |
| /* The SFrame Decoder. */ |
| |
| /* Decode the specified SFrame buffer CF_BUF of size CF_SIZE and return the |
| new SFrame decoder context. Sets ERRP for the caller if any error. */ |
| extern sframe_decoder_ctx * |
| sframe_decode (const char *cf_buf, size_t cf_size, int *errp); |
| |
| /* Free the decoder context. */ |
| extern void |
| sframe_decoder_free (sframe_decoder_ctx **dctx); |
| |
| /* Get the size of the SFrame header from the decoder context DCTX. */ |
| extern unsigned int |
| sframe_decoder_get_hdr_size (sframe_decoder_ctx *dctx); |
| |
| /* Get the SFrame's abi/arch info. */ |
| extern uint8_t |
| sframe_decoder_get_abi_arch (sframe_decoder_ctx *dctx); |
| |
| /* Get the format version from the SFrame decoder context DCTX. */ |
| extern uint8_t |
| sframe_decoder_get_version (sframe_decoder_ctx *dctx); |
| |
| /* Return the number of function descriptor entries in the SFrame decoder |
| DCTX. */ |
| extern uint32_t |
| sframe_decoder_get_num_fidx (sframe_decoder_ctx *dctx); |
| |
| /* Get the fixed FP offset from the decoder context DCTX. */ |
| extern int8_t |
| sframe_decoder_get_fixed_fp_offset (sframe_decoder_ctx *dctx); |
| |
| /* Get the fixed RA offset from the decoder context DCTX. */ |
| extern int8_t |
| sframe_decoder_get_fixed_ra_offset (sframe_decoder_ctx *dctx); |
| |
| /* Find the function descriptor entry which contains the specified address. |
| |
| Note: This function is deprecated and will be removed from future release |
| X+2 of the library. */ |
| extern void * |
| sframe_get_funcdesc_with_addr (sframe_decoder_ctx *dctx, int32_t addr, |
| int *errp); |
| |
| /* Find the SFrame Frame Row Entry which contains the PC. Returns |
| SFRAME_ERR if failure. */ |
| |
| extern int |
| sframe_find_fre (sframe_decoder_ctx *ctx, int32_t pc, |
| sframe_frame_row_entry *frep); |
| |
| /* Get the FRE_IDX'th FRE of the function at FUNC_IDX'th function |
| index entry in the SFrame decoder CTX. Returns error code as |
| applicable. */ |
| extern int |
| sframe_decoder_get_fre (sframe_decoder_ctx *ctx, |
| unsigned int func_idx, |
| unsigned int fre_idx, |
| sframe_frame_row_entry *fre); |
| |
| /* Get the data (NUM_FRES, FUNC_START_ADDRESS) from the function |
| descriptor entry at index I'th in the decoder CTX. If failed, |
| return error code. */ |
| extern int |
| sframe_decoder_get_funcdesc (sframe_decoder_ctx *ctx, |
| unsigned int i, |
| uint32_t *num_fres, |
| uint32_t *func_size, |
| int32_t *func_start_address, |
| unsigned char *func_info); |
| |
| /* Get the data (NUM_FRES, FUNC_SIZE, FUNC_START_ADDRESS, FUNC_INFO, |
| REP_BLOCK_SIZE) from the function descriptor entry at index I'th |
| in the decoder CTX. If failed, return error code. |
| This API is only available from SFRAME_VERSION_2. */ |
| extern int |
| sframe_decoder_get_funcdesc_v2 (sframe_decoder_ctx *ctx, |
| unsigned int i, |
| uint32_t *num_fres, |
| uint32_t *func_size, |
| int32_t *func_start_address, |
| unsigned char *func_info, |
| uint8_t *rep_block_size); |
| |
| /* SFrame textual dump. */ |
| extern void |
| dump_sframe (sframe_decoder_ctx *decoder, uint64_t addr); |
| |
| /* Get the base reg id from the FRE info. Sets errp if fails. */ |
| extern uint8_t |
| sframe_fre_get_base_reg_id (sframe_frame_row_entry *fre, int *errp); |
| |
| /* Get the CFA offset from the FRE. If the offset is invalid, sets errp. */ |
| extern int32_t |
| sframe_fre_get_cfa_offset (sframe_decoder_ctx *dtcx, |
| sframe_frame_row_entry *fre, int *errp); |
| |
| /* Get the FP offset from the FRE. If the offset is invalid, sets errp. */ |
| extern int32_t |
| sframe_fre_get_fp_offset (sframe_decoder_ctx *dctx, |
| sframe_frame_row_entry *fre, int *errp); |
| |
| /* Get the RA offset from the FRE. If the offset is invalid, sets errp. */ |
| extern int32_t |
| sframe_fre_get_ra_offset (sframe_decoder_ctx *dctx, |
| sframe_frame_row_entry *fre, int *errp); |
| |
| /* Get whether the RA is mangled. */ |
| |
| extern bool |
| sframe_fre_get_ra_mangled_p (sframe_decoder_ctx *dctx, |
| sframe_frame_row_entry *fre, int *errp); |
| |
| /* The SFrame Encoder. */ |
| |
| /* Create an encoder context with the given SFrame format version VER, FLAGS |
| and ABI information. Sets errp if failure. */ |
| extern sframe_encoder_ctx * |
| sframe_encode (uint8_t ver, uint8_t flags, uint8_t abi_arch, |
| int8_t fixed_fp_offset, int8_t fixed_ra_offset, int *errp); |
| |
| /* Free the encoder context. */ |
| extern void |
| sframe_encoder_free (sframe_encoder_ctx **encoder); |
| |
| /* Get the size of the SFrame header from the encoder ctx ENCODER. */ |
| extern unsigned int |
| sframe_encoder_get_hdr_size (sframe_encoder_ctx *encoder); |
| |
| /* Get the abi/arch info from the SFrame encoder context CTX. */ |
| extern uint8_t |
| sframe_encoder_get_abi_arch (sframe_encoder_ctx *encoder); |
| |
| /* Get the format version from the SFrame encoder context ENCODER. */ |
| extern uint8_t |
| sframe_encoder_get_version (sframe_encoder_ctx *encoder); |
| |
| /* Return the number of function descriptor entries in the SFrame encoder |
| ENCODER. */ |
| extern uint32_t |
| sframe_encoder_get_num_fidx (sframe_encoder_ctx *encoder); |
| |
| /* Add an FRE to function at FUNC_IDX'th function descriptor index entry in |
| the encoder context. */ |
| extern int |
| sframe_encoder_add_fre (sframe_encoder_ctx *encoder, |
| unsigned int func_idx, |
| sframe_frame_row_entry *frep); |
| |
| /* Add a new function descriptor entry with START_ADDR, FUNC_SIZE and NUM_FRES |
| to the encoder. */ |
| extern int |
| sframe_encoder_add_funcdesc (sframe_encoder_ctx *encoder, |
| int32_t start_addr, |
| uint32_t func_size, |
| unsigned char func_info, |
| uint32_t num_fres); |
| |
| /* Add a new function descriptor entry with START_ADDR, FUNC_SIZE, FUNC_INFO |
| and REP_BLOCK_SIZE to the encoder. */ |
| extern int |
| sframe_encoder_add_funcdesc_v2 (sframe_encoder_ctx *encoder, |
| int32_t start_addr, |
| uint32_t func_size, |
| unsigned char func_info, |
| uint8_t rep_block_size, |
| uint32_t num_fres); |
| |
| /* Serialize the contents of the encoder and return the buffer. ENCODED_SIZE |
| is updated to the size of the buffer. Sets ERRP if failure. */ |
| extern char * |
| sframe_encoder_write (sframe_encoder_ctx *encoder, |
| size_t *encoded_size, int *errp); |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* _SFRAME_API_H */ |