LCOV - code coverage report
Current view: top level - waltz/tls - fd_tls_serde.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 82 87 94.3 %
Date: 2025-03-20 12:08:36 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      235056 : #define FD_TLS_SERDE_BEGIN do { \
      13      235056 :   int valid = 1;                \
      14             : 
      15      235056 : #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      680820 :   ulong        _field_##IDX##_laddr = wire_laddr;                            \
      25      680820 :   ulong const  _field_##IDX##_cnt   = (FIELD_CNT);                           \
      26      680820 :   ulong const  _field_##IDX##_sz    = sizeof(FIELD_TYPE)*_field_##IDX##_cnt; \
      27      680820 :   valid &= (wire_sz    >= _field_##IDX##_sz);                                \
      28      680820 :             wire_sz    -= _field_##IDX##_sz;                                 \
      29      680820 :             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      271188 :   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      313434 :   do {                                                           \
      45      313434 :     memcpy( (FIELD), (void const *)_field_##IDX##_laddr, _field_##IDX##_sz ); \
      46      313434 :     FIELD_TYPE * _field_##IDX##_ptr = (FIELD);                   \
      47     1379865 :     for( ulong i=0; i < (FIELD_CNT); i++ ) {                     \
      48     1066431 :       *((_field_##IDX##_ptr)++) = __extension__                  \
      49     1066431 :         (FIELD_TYPE)fd_##FIELD_TYPE##_bswap( (FIELD)[i] );       \
      50     1066431 :     }                                                            \
      51      313434 :   } while(0);
      52             : 
      53             : #define FD_TLS_SERDE_ENCODE( IDX, FIELD, FIELD_TYPE, FIELD_CNT ) \
      54      331254 :   do {                                                           \
      55      331254 :     uchar * dest = (uchar *)_field_##IDX##_laddr;                \
      56      331254 :     memcpy( dest, (FIELD), _field_##IDX##_sz );                  \
      57     3956040 :     for( ulong i=0; i<(FIELD_CNT); i++ ) {                       \
      58     3624786 :       FIELD_TYPE temp;                                           \
      59     3624786 :       memcpy( &temp, dest, sizeof(FIELD_TYPE) );                 \
      60     3624786 :       temp = fd_##FIELD_TYPE##_bswap( temp );                    \
      61     3624786 :       memcpy( dest, &temp, sizeof(FIELD_TYPE) );                 \
      62     3624786 :       dest += sizeof(FIELD_TYPE);                                \
      63     3624786 :     }                                                            \
      64      331254 :   } while(0);
      65             : 
      66             : /* FD_TLS_DECODE_FIELD is a convenience macro for decoding a single
      67             :    field with known size. */
      68             : 
      69             : #define FD_TLS_DECODE_FIELD( FIELD, FIELD_TYPE )  \
      70       90459 :   FD_TLS_SERDE_BEGIN                              \
      71       90459 :   FD_TLS_SERDE_LOCATE( _, FIELD, FIELD_TYPE, 1 )  \
      72       90459 :   FD_TLS_SERDE_CHECK                              \
      73       90459 :   FD_TLS_SERDE_DECODE(  _, FIELD, FIELD_TYPE, 1 ) \
      74       90459 :   FD_TLS_SERDE_END
      75             : 
      76             : #define FD_TLS_ENCODE_FIELD( FIELD, FIELD_TYPE )  \
      77           0 :   FD_TLS_SERDE_BEGIN                              \
      78           0 :   FD_TLS_SERDE_LOCATE( _, FIELD, FIELD_TYPE, 1 )  \
      79           0 :   FD_TLS_SERDE_CHECK                              \
      80           0 :   FD_TLS_SERDE_ENCODE(  _, FIELD, FIELD_TYPE, 1 ) \
      81           0 :   FD_TLS_SERDE_END
      82             : 
      83             : /* FD_TLS_DECODE_STATIC_BATCH is a convenience macro for decoding a
      84             :    batch of static sized fields in a new decode context. */
      85             : 
      86             : #define FD_TLS_DECODE_STATIC_BATCH( fields ) \
      87       96423 :   FD_TLS_SERDE_BEGIN                         \
      88      222975 :   fields( FD_TLS_SERDE_LOCATE )              \
      89       96423 :   FD_TLS_SERDE_CHECK                         \
      90      222975 :   fields( FD_TLS_SERDE_DECODE )              \
      91       96423 :   FD_TLS_SERDE_END
      92             : 
      93             : #define FD_TLS_ENCODE_STATIC_BATCH( fields ) \
      94       48174 :   FD_TLS_SERDE_BEGIN                         \
      95      331254 :   fields( FD_TLS_SERDE_LOCATE )              \
      96       48174 :   FD_TLS_SERDE_CHECK                         \
      97      331254 :   fields( FD_TLS_SERDE_ENCODE )              \
      98       48174 :   FD_TLS_SERDE_END
      99             : 
     100             : #define FD_TLS_DECODE_LIST_BEGIN( LIST_SZ_TYPE, ALIGN )           \
     101       48216 :   do {                                                            \
     102       48216 :     LIST_SZ_TYPE list_sz;                                         \
     103       48216 :     FD_TLS_DECODE_FIELD( &list_sz, LIST_SZ_TYPE );                \
     104       48216 :     if( FD_UNLIKELY( !fd_ulong_is_aligned( list_sz, (ALIGN) ) ) ) \
     105       48216 :       return -(long)FD_TLS_ALERT_DECODE_ERROR;                    \
     106       48216 :     if( FD_UNLIKELY( list_sz > wire_sz ) )                        \
     107       48216 :       return -(long)FD_TLS_ALERT_DECODE_ERROR;                    \
     108       48216 :     ulong const list_start = wire_laddr;                          \
     109       48216 :     ulong const list_stop  = list_start + list_sz;                \
     110      138690 :     while( wire_laddr < list_stop )                               \
     111             : 
     112             : #define FD_TLS_DECODE_LIST_END                     \
     113       48216 :     if( FD_UNLIKELY( wire_laddr != list_stop ) )   \
     114       48216 :       return -(long)FD_TLS_ALERT_DECODE_ERROR;     \
     115       48216 :   } while(0);                                      \
     116             : 
     117       30111 : #define FD_TLS_SKIP_FIELD( FIELD_TYPE ) (__extension__({ \
     118       30111 :     int valid = 1;                                       \
     119       30111 :     FD_TLS_SERDE_LOCATE( , , FIELD_TYPE, 1   )           \
     120       30111 :     FD_TLS_SERDE_CHECK                                   \
     121       30111 :     (FIELD_TYPE *)fd_type_pun( (void *)_field__laddr );  \
     122       30111 :   }))
     123             : 
     124        6021 : #define FD_TLS_SKIP_FIELDS( FIELD_TYPE, CNT ) (__extension__({ \
     125        6021 :     int valid = 1;                                             \
     126        6021 :     FD_TLS_SERDE_LOCATE( , , FIELD_TYPE, (CNT)   )             \
     127        6021 :     FD_TLS_SERDE_CHECK                                         \
     128        6021 :     (FIELD_TYPE *)_field__laddr;                               \
     129        6021 :   }))
     130             : 
     131        6027 : #define FD_TLS_DECODE_SUB( FUNC, OUT ) do {                      \
     132        6027 :     long res = FUNC( (OUT), (void const *)wire_laddr, wire_sz ); \
     133        6027 :     if( FD_UNLIKELY( res<0L ) ) return res;                      \
     134        6027 :     wire_laddr += (ulong)res;                                    \
     135        6027 :     wire_sz    -= (ulong)res;                                    \
     136        6027 :   } while(0)
     137             : 
     138       24072 : #define FD_TLS_ENCODE_SUB( FUNC, IN ) (__extension__({    \
     139       24072 :     long res = FUNC( (IN), (void *)wire_laddr, wire_sz ); \
     140       24072 :     if( FD_UNLIKELY( res<0L ) ) return res;               \
     141       24072 :     wire_laddr += (ulong)res;                             \
     142       24072 :     wire_sz    -= (ulong)res;                             \
     143       24072 :     (ulong)res;                                           \
     144       24072 :   }))
     145             : 
     146             : #endif /* HEADER_src_ballet_tls_fd_tls_serde_h */

Generated by: LCOV version 1.14