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