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-10-27 04:40:00 Functions: 0 0 -

          Line data    Source code
       1             : #ifndef HEADER_fd_src_waltz_tls_fd_tls_serde_h
       2             : #define HEADER_fd_src_waltz_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      237555 : #define FD_TLS_SERDE_BEGIN do { \
      13      237555 :   int valid = 1;                \
      14             : 
      15      237555 : #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      688125 :   ulong        _field_##IDX##_laddr = wire_laddr;                            \
      25      688125 :   ulong const  _field_##IDX##_cnt   = (FIELD_CNT);                           \
      26      688125 :   ulong const  _field_##IDX##_sz    = sizeof(FIELD_TYPE)*_field_##IDX##_cnt; \
      27      688125 :   valid &= (wire_sz    >= _field_##IDX##_sz);                                \
      28      688125 :             wire_sz    -= _field_##IDX##_sz;                                 \
      29      688125 :             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      274029 :   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      316602 :   do {                                                           \
      45      316602 :     memcpy( (FIELD), (void const *)_field_##IDX##_laddr, _field_##IDX##_sz ); \
      46      316602 :     FIELD_TYPE * _field_##IDX##_ptr = (FIELD);                   \
      47     1392762 :     for( ulong i=0; i < (FIELD_CNT); i++ ) {                     \
      48     1076160 :       *((_field_##IDX##_ptr)++) = __extension__                  \
      49     1076160 :         (FIELD_TYPE)fd_##FIELD_TYPE##_bswap( (FIELD)[i] );       \
      50     1076160 :     }                                                            \
      51      316602 :   } while(0);
      52             : 
      53             : #define FD_TLS_SERDE_ENCODE( IDX, FIELD, FIELD_TYPE, FIELD_CNT ) \
      54      335049 :   do {                                                           \
      55      335049 :     uchar * dest = (uchar *)_field_##IDX##_laddr;                \
      56      335049 :     memcpy( dest, (FIELD), _field_##IDX##_sz );                  \
      57     3995442 :     for( ulong i=0; i<(FIELD_CNT); i++ ) {                       \
      58     3660393 :       FIELD_TYPE temp;                                           \
      59     3660393 :       memcpy( &temp, dest, sizeof(FIELD_TYPE) );                 \
      60     3660393 :       temp = fd_##FIELD_TYPE##_bswap( temp );                    \
      61     3660393 :       memcpy( dest, &temp, sizeof(FIELD_TYPE) );                 \
      62     3660393 :       dest += sizeof(FIELD_TYPE);                                \
      63     3660393 :     }                                                            \
      64      335049 :   } 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       91512 :   FD_TLS_SERDE_BEGIN                              \
      71       91512 :   FD_TLS_SERDE_LOCATE( _, FIELD, FIELD_TYPE, 1 )  \
      72       91512 :   FD_TLS_SERDE_CHECK                              \
      73       91512 :   FD_TLS_SERDE_DECODE(  _, FIELD, FIELD_TYPE, 1 ) \
      74       91512 :   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       97350 :   FD_TLS_SERDE_BEGIN                         \
      88      225090 :   fields( FD_TLS_SERDE_LOCATE )              \
      89       97350 :   FD_TLS_SERDE_CHECK                         \
      90      225090 :   fields( FD_TLS_SERDE_DECODE )              \
      91       97350 :   FD_TLS_SERDE_END
      92             : 
      93             : #define FD_TLS_ENCODE_STATIC_BATCH( fields ) \
      94       48693 :   FD_TLS_SERDE_BEGIN                         \
      95      335049 :   fields( FD_TLS_SERDE_LOCATE )              \
      96       48693 :   FD_TLS_SERDE_CHECK                         \
      97      335049 :   fields( FD_TLS_SERDE_ENCODE )              \
      98       48693 :   FD_TLS_SERDE_END
      99             : 
     100             : #define FD_TLS_DECODE_LIST_BEGIN( LIST_SZ_TYPE, ALIGN )           \
     101       48660 :   do {                                                            \
     102       48660 :     LIST_SZ_TYPE list_sz;                                         \
     103       48660 :     FD_TLS_DECODE_FIELD( &list_sz, LIST_SZ_TYPE );                \
     104       48660 :     if( FD_UNLIKELY( !fd_ulong_is_aligned( list_sz, (ALIGN) ) ) ) \
     105       48660 :       return -(long)FD_TLS_ALERT_DECODE_ERROR;                    \
     106       48660 :     if( FD_UNLIKELY( list_sz > wire_sz ) )                        \
     107       48660 :       return -(long)FD_TLS_ALERT_DECODE_ERROR;                    \
     108       48660 :     ulong const list_start = wire_laddr;                          \
     109       48660 :     ulong const list_stop  = list_start + list_sz;                \
     110      140247 :     while( wire_laddr < list_stop )                               \
     111             : 
     112             : #define FD_TLS_DECODE_LIST_END                     \
     113       48660 :     if( FD_UNLIKELY( wire_laddr != list_stop ) )   \
     114       48660 :       return -(long)FD_TLS_ALERT_DECODE_ERROR;     \
     115       48660 :   } while(0);                                      \
     116             : 
     117       30402 : #define FD_TLS_SKIP_FIELD( FIELD_TYPE ) (__extension__({ \
     118       30402 :     int valid = 1;                                       \
     119       30402 :     FD_TLS_SERDE_LOCATE( , , FIELD_TYPE, 1   )           \
     120       30402 :     FD_TLS_SERDE_CHECK                                   \
     121       30402 :     (FIELD_TYPE *)fd_type_pun( (void *)_field__laddr );  \
     122       30402 :   }))
     123             : 
     124        6072 : #define FD_TLS_SKIP_FIELDS( FIELD_TYPE, CNT ) (__extension__({ \
     125        6072 :     int valid = 1;                                             \
     126        6072 :     FD_TLS_SERDE_LOCATE( , , FIELD_TYPE, (CNT)   )             \
     127        6072 :     FD_TLS_SERDE_CHECK                                         \
     128        6072 :     (FIELD_TYPE *)_field__laddr;                               \
     129        6072 :   }))
     130             : 
     131        6084 : #define FD_TLS_DECODE_SUB( FUNC, OUT ) do {                      \
     132        6084 :     long res = FUNC( (OUT), (void const *)wire_laddr, wire_sz ); \
     133        6084 :     if( FD_UNLIKELY( res<0L ) ) return res;                      \
     134        6084 :     wire_laddr += (ulong)res;                                    \
     135        6084 :     wire_sz    -= (ulong)res;                                    \
     136        6084 :   } while(0)
     137             : 
     138       24342 : #define FD_TLS_ENCODE_SUB( FUNC, IN ) (__extension__({    \
     139       24342 :     long res = FUNC( (IN), (void *)wire_laddr, wire_sz ); \
     140       24342 :     if( FD_UNLIKELY( res<0L ) ) return res;               \
     141       24342 :     wire_laddr += (ulong)res;                             \
     142       24342 :     wire_sz    -= (ulong)res;                             \
     143       24342 :     (ulong)res;                                           \
     144       24342 :   }))
     145             : 
     146             : #endif /* HEADER_fd_src_waltz_tls_fd_tls_serde_h */

Generated by: LCOV version 1.14