Skip to content

Commit ca217fe

Browse files
nordic-krchnashif
authored andcommitted
lib: os: cbprintf: Avoid using VLA
Some configurations does not support VLA (e.g. CONFIG_MISRA_SANE). Replace with a trick were fixed size array is used. Note that this code is resolved at compile time so code size and stack usage should be the same. Signed-off-by: Krzysztof Chruscinski <[email protected]>
1 parent 89a3b4e commit ca217fe

File tree

1 file changed

+27
-14
lines changed

1 file changed

+27
-14
lines changed

include/sys/cbprintf_internal.h

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@
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

Comments
 (0)