Home | History | Annotate | Line # | Download | only in include
      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