LCOV - code coverage report
Current view: top level - waltz/tls - fd_tls_serde.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 80 85 94.1 %
Date: 2024-11-13 11:58:15 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef HEADER_src_ballet_tls_fd_tls_serde_h
       2             : #define HEADER_src_ballet_tls_fd_tls_serde_h
       3             : 
       4             : /* fd_tls_serde.h provides branch-minimizing (de-)serializer macros for
       5             :    internal use.  This file specifically exists for fd_tls_proto.c and
       6             :    should not be included elsewhere. */
       7             : 
       8             : /* FD_TLS_SERDE_{BEGIN,END} create and terminate a bounds checking
       9             :    context.  Internally, creates a new do/while(0) scope. */
      10             : 
      11             : #include "fd_tls_proto.h"
      12      313170 : #define FD_TLS_SERDE_BEGIN do { \
      13      313170 :   int valid = 1;                \
      14             : 
      15      313170 : #define FD_TLS_SERDE_END } while(0);
      16             : 
      17             : /* FD_TLS_SERDE_LOCATE defines a local variable pointing to the would-
      18             :    be position of the field to be decoded, which may be out-of-bounds.
      19             :    Also extends the "valid" expression to include a bounds check for
      20             :    this field.  Both the "valid" expression and this local can be fully
      21             :    constant-propagated if sz is constant. */
      22             : 
      23             : #define FD_TLS_SERDE_LOCATE( IDX, FIELD, FIELD_TYPE, FIELD_CNT )             \
      24      855021 :   ulong        _field_##IDX##_laddr = wire_laddr;                            \
      25      855021 :   ulong const  _field_##IDX##_cnt   = (FIELD_CNT);                           \
      26      855021 :   ulong const  _field_##IDX##_sz    = sizeof(FIELD_TYPE)*_field_##IDX##_cnt; \
      27      855021 :   valid &= (wire_sz    >= _field_##IDX##_sz);                                \
      28      855021 :             wire_sz    -= _field_##IDX##_sz;                                 \
      29      855021 :             wire_laddr += _field_##IDX##_sz;
      30             : 
      31             : /* FD_TLS_SERDE_CHECK performs tbe bounds checks queued by prior
      32             :    FD_TLS_SERDE_LOCATE ops. */
      33             : 
      34             : #define FD_TLS_SERDE_CHECK \
      35      349284 :   if( FD_UNLIKELY( !valid ) ) return -(long)FD_TLS_ALERT_DECODE_ERROR;
      36             : 
      37             : /* FD_TLS_SERDE_DECODE generates a non-overlapping memory copy for the
      38             :    given field.  Field should be bounds checked at this point.
      39             : 
      40             :    Note: We use __extension__ here because ISO C forbids casting a
      41             :          non-scalar type to itself.  (as is the case with tls_u24). */
      42             : 
      43             : #define FD_TLS_SERDE_DECODE( IDX, FIELD, FIELD_TYPE, FIELD_CNT ) \
      44      397524 :   do {                                                           \
      45      397524 :     memcpy( (FIELD), (void const *)_field_##IDX##_laddr, _field_##IDX##_sz ); \
      46      397524 :     FIELD_TYPE * _field_##IDX##_ptr = (FIELD);                   \
      47     1547670 :     for( ulong i=0; i < (FIELD_CNT); i++ ) {                     \
      48     1150146 :       *((_field_##IDX##_ptr)++) = __extension__                  \
      49     1150146 :         (FIELD_TYPE)fd_##FIELD_TYPE##_bswap( (FIELD)[i] );       \
      50     1150146 :     }                                                            \
      51      397524 :   } while(0);
      52             : 
      53             : #define FD_TLS_SERDE_ENCODE( IDX, FIELD, FIELD_TYPE, FIELD_CNT ) \
      54      421383 :   do {                                                           \
      55      421383 :     uchar * dest = (uchar *)_field_##IDX##_laddr;                \
      56      421383 :     memcpy( dest, (FIELD), _field_##IDX##_sz );                  \
      57      421383 :     FIELD_TYPE * ele = fd_type_pun( dest );                      \
      58     2906979 :     for( ulong i=0; i<(FIELD_CNT); i++ ) {                       \
      59     2485596 :       *ele = fd_##FIELD_TYPE##_bswap( *ele );                    \
      60     2485596 :       ele++;                                                     \
      61     2485596 :     }                                                            \
      62      421383 :   } while(0);
      63             : 
      64             : /* FD_TLS_DECODE_FIELD is a convenience macro for decoding a single
      65             :    field with known size. */
      66             : 
      67             : #define FD_TLS_DECODE_FIELD( FIELD, FIELD_TYPE )  \
      68      126516 :   FD_TLS_SERDE_BEGIN                              \
      69      126516 :   FD_TLS_SERDE_LOCATE( _, FIELD, FIELD_TYPE, 1 )  \
      70      126516 :   FD_TLS_SERDE_CHECK                              \
      71      126516 :   FD_TLS_SERDE_DECODE(  _, FIELD, FIELD_TYPE, 1 ) \
      72      126516 :   FD_TLS_SERDE_END
      73             : 
      74             : #define FD_TLS_ENCODE_FIELD( FIELD, FIELD_TYPE )  \
      75           0 :   FD_TLS_SERDE_BEGIN                              \
      76           0 :   FD_TLS_SERDE_LOCATE( _, FIELD, FIELD_TYPE, 1 )  \
      77           0 :   FD_TLS_SERDE_CHECK                              \
      78           0 :   FD_TLS_SERDE_ENCODE(  _, FIELD, FIELD_TYPE, 1 ) \
      79           0 :   FD_TLS_SERDE_END
      80             : 
      81             : /* FD_TLS_DECODE_STATIC_BATCH is a convenience macro for decoding a
      82             :    batch of static sized fields in a new decode context. */
      83             : 
      84             : #define FD_TLS_DECODE_STATIC_BATCH( fields ) \
      85      120447 :   FD_TLS_SERDE_BEGIN                         \
      86      271008 :   fields( FD_TLS_SERDE_LOCATE )              \
      87      120447 :   FD_TLS_SERDE_CHECK                         \
      88      271008 :   fields( FD_TLS_SERDE_DECODE )              \
      89      120447 :   FD_TLS_SERDE_END
      90             : 
      91             : #define FD_TLS_ENCODE_STATIC_BATCH( fields ) \
      92       66207 :   FD_TLS_SERDE_BEGIN                         \
      93      421383 :   fields( FD_TLS_SERDE_LOCATE )              \
      94       66207 :   FD_TLS_SERDE_CHECK                         \
      95      421383 :   fields( FD_TLS_SERDE_ENCODE )              \
      96       66207 :   FD_TLS_SERDE_END
      97             : 
      98             : #define FD_TLS_DECODE_LIST_BEGIN( LIST_SZ_TYPE, ALIGN )           \
      99       60228 :   do {                                                            \
     100       60228 :     LIST_SZ_TYPE list_sz;                                         \
     101       60228 :     FD_TLS_DECODE_FIELD( &list_sz, LIST_SZ_TYPE );                \
     102       60228 :     if( FD_UNLIKELY( !fd_ulong_is_aligned( list_sz, (ALIGN) ) ) ) \
     103       60228 :       return -(long)FD_TLS_ALERT_DECODE_ERROR;                    \
     104       60228 :     if( FD_UNLIKELY( list_sz > wire_sz ) )                        \
     105       60228 :       return -(long)FD_TLS_ALERT_DECODE_ERROR;                    \
     106       60228 :     ulong const list_start = wire_laddr;                          \
     107       60228 :     ulong const list_stop  = list_start + list_sz;                \
     108      198795 :     while( wire_laddr < list_stop )                               \
     109             : 
     110             : #define FD_TLS_DECODE_LIST_END                     \
     111       60228 :     if( FD_UNLIKELY( wire_laddr != list_stop ) )   \
     112       60228 :       return -(long)FD_TLS_ALERT_DECODE_ERROR;     \
     113       60228 :   } while(0);                                      \
     114             : 
     115       30096 : #define FD_TLS_SKIP_FIELD( FIELD_TYPE ) (__extension__({ \
     116       30096 :     int valid = 1;                                       \
     117       30096 :     FD_TLS_SERDE_LOCATE( , , FIELD_TYPE, 1   )           \
     118       30096 :     FD_TLS_SERDE_CHECK                                   \
     119       30096 :     (FIELD_TYPE *)fd_type_pun( (void *)_field__laddr );  \
     120       30096 :   }))
     121             : 
     122        6018 : #define FD_TLS_SKIP_FIELDS( FIELD_TYPE, CNT ) (__extension__({ \
     123        6018 :     int valid = 1;                                             \
     124        6018 :     FD_TLS_SERDE_LOCATE( , , FIELD_TYPE, (CNT)   )             \
     125        6018 :     FD_TLS_SERDE_CHECK                                         \
     126        6018 :     (FIELD_TYPE *)_field__laddr;                               \
     127        6018 :   }))
     128             : 
     129        6024 : #define FD_TLS_DECODE_SUB( FUNC, OUT ) do {                      \
     130        6024 :     long res = FUNC( (OUT), (void const *)wire_laddr, wire_sz ); \
     131        6024 :     if( FD_UNLIKELY( res<0L ) ) return res;                      \
     132        6024 :     wire_laddr += (ulong)res;                                    \
     133        6024 :     wire_sz    -= (ulong)res;                                    \
     134        6024 :   } while(0)
     135             : 
     136       24060 : #define FD_TLS_ENCODE_SUB( FUNC, IN ) (__extension__({    \
     137       24060 :     long res = FUNC( (IN), (void *)wire_laddr, wire_sz ); \
     138       24060 :     if( FD_UNLIKELY( res<0L ) ) return res;               \
     139       24060 :     wire_laddr += (ulong)res;                             \
     140       24060 :     wire_sz    -= (ulong)res;                             \
     141       24060 :     (ulong)res;                                           \
     142       24060 :   }))
     143             : 
     144             : #endif /* HEADER_src_ballet_tls_fd_tls_serde_h */

Generated by: LCOV version 1.14