1313#include <stdint.h>
1414#include <toolchain.h>
1515#include <sys/util.h>
16-
17- #ifdef CONFIG_CBPRINTF_STATIC_PACKAGE_CHECK_ALIGNMENT
1816#include <sys/__assert.h>
19- #endif
2017
2118/*
2219 * Special alignment cases
@@ -357,6 +354,22 @@ union z_cbprintf_hdr {
357354#define Z_CBPRINTF_SUPPRESS_SIZEOF_ARRAY_DECAY
358355#endif
359356
357+ /* Allocation to avoid using VLA and alloca. Alloc frees space when leaving
358+ * a function which can lead to increased stack usage if logging is used
359+ * multiple times. VLA is not always available.
360+ */
361+ #define Z_CBPRINTF_ON_STACK_ALLOC (_name , _len ) \
362+ uint8_t _name##_buf4[4]; \
363+ uint8_t _name##_buf8[8]; \
364+ uint8_t _name##_buf12[12]; \
365+ uint8_t _name##_buf16[16]; \
366+ uint8_t _name##_buf32[32]; \
367+ _name = (_len) <= 4 ? _name##_buf4 : \
368+ ((_len) <= 8 ? _name##_buf8 : \
369+ ((_len) <= 12 ? _name##_buf12 : \
370+ ((_len) <= 16 ? _name##_buf16 : \
371+ _name##_buf32)))
372+
360373/** @brief Statically package a formatted string with arguments.
361374 *
362375 * @param buf buffer. If null then only length is calculated.
@@ -400,9 +413,11 @@ do { \
400413 /* Variable holds count of non const string pointers. */ \
401414 uint8_t _rws_cnt = _cros_en ? \
402415 Z_CBPRINTF_PCHAR_COUNT (_flags , __VA_ARGS__ ) : _alls_cnt - _fros_cnt ; \
403- uint8_t _ros_cnt = 1 + _alls_cnt - _rws_cnt ; \
404- uint8_t _ros_pos_buf [_ros_pos_en ? _ros_cnt : 0 ]; \
405- uint8_t _rws_buffer [_rws_cnt ]; \
416+ uint8_t _ros_cnt = _ros_pos_en ? (1 + _alls_cnt - _rws_cnt ) : 0 ; \
417+ uint8_t * _ros_pos_buf ; \
418+ Z_CBPRINTF_ON_STACK_ALLOC (_ros_pos_buf , _ros_cnt ); \
419+ uint8_t * _rws_buffer ; \
420+ Z_CBPRINTF_ON_STACK_ALLOC (_rws_buffer , _rws_cnt ); \
406421 size_t _pmax = (buf != NULL ) ? _inlen : INT32_MAX ; \
407422 int _pkg_len = 0 ; \
408423 int _total_len = 0 ; \
@@ -425,17 +440,15 @@ do { \
425440 FOR_EACH_IDX (Z_CBPRINTF_PACK_ARG , (;), __VA_ARGS__ );\
426441 _total_len = _pkg_len ; \
427442 /* Append string indexes to the package. */ \
428- if (_ros_pos_en ) { \
429- _total_len += sizeof (_ros_pos_buf ); \
430- } \
431- _total_len += sizeof (_rws_buffer ); \
443+ _total_len += _ros_cnt ; \
444+ _total_len += _rws_cnt ; \
432445 if (_pbuf ) { \
433446 /* Append string locations. */ \
434447 uint8_t * _pbuf_loc = & _pbuf [_pkg_len ]; \
435- for (size_t i = 0 ; i < sizeof ( _ros_pos_buf ) ; i ++ ) { \
448+ for (size_t i = 0 ; i < _ros_cnt ; i ++ ) { \
436449 * _pbuf_loc ++ = _ros_pos_buf [i ]; \
437450 } \
438- for (size_t i = 0 ; i < sizeof ( _rws_buffer ) ; i ++ ) { \
451+ for (size_t i = 0 ; i < _rws_cnt ; i ++ ) { \
439452 * _pbuf_loc ++ = _rws_buffer [i ]; \
440453 } \
441454 } \
@@ -447,8 +460,8 @@ do { \
447460 .desc = { \
448461 .len = (uint8_t )(_pkg_len / sizeof (int )), \
449462 .str_cnt = 0 , \
450- .ro_str_cnt = ( uint8_t ) sizeof ( _ros_pos_buf ) , \
451- .rw_str_cnt = ( uint8_t ) sizeof ( _rws_buffer ) , \
463+ .ro_str_cnt = _ros_cnt , \
464+ .rw_str_cnt = _rws_cnt , \
452465 } \
453466 }; \
454467 * _len_loc = hdr ; \
0 commit comments