In my current embedded Zig/C blinky program (98% C code), the compiled binary output has become significantly larger since the Zig 0.14.0 release.
Normally, I override the C flag with -Og
to keep the binary size reasonable, but even with this flag, the resulting program is much larger than before.
Compilation Test (Zig 0.14.0)
Programs available in my repository (Commit f0e18c5
on main branch).
Build command: zig build --release=off|safe|small
Program |
Debug (-O0 ) |
Debug (-Og ) |
Safe |
Small |
blinky |
104680 |
52312 |
6944 |
5248 |
blinky_freertos |
(error) (1) |
249688 |
28992 |
18088 |
blinky_picolibc |
80708 |
52136 |
8156 |
6532 |
Error (1) blinky_freertos
: Fails to fit in device memory.
error: ld.lld: section '.bss' will not fit in region 'RAM': overflowed by 2212 bytes
error: ld.lld: section '._user_heap_stack' will not fit in region 'RAM': overflowed by 3752 bytes
Previous Behavior (Zig 0.14.0-dev.3089)
When I wrote the picolibc topic, binary sizes were more closer between releases mode:
Mode |
newlib |
picolibc |
Debug |
29056 |
25140 |
ReleaseSafe |
29480 |
25436 |
ReleaseSmall |
26504 |
23012 |
Note: Binaries were slightly larger in ReleaseSafe
and ReleaseSmall
due to additional libc components.
Question
Could I be missing something in my build.zig
configuration since Zig 0.14.0?
It looks like extra debug data, since release modes got smaller.
Have you inspected the binaries? Maybe look at the sizes of individual sections.
It’s possible zig is not passing along -Og
anymore, or it is now using the flag that generates extra debug data (I forgot the name of the flag).
The -Og
flag is passed. Here is a log with --verbose-cc
for the blinky example:
zig build --release=off --verbose-cc
install
└─ run /opt/softs/xpack-arm-none-eabi-gcc-14.2.1-1.1/bin/arm-none-eabi-size
└─ zig build-exe blinky.elf Debug thumb-freestanding-eabihf failure
error: zig clang /blinky/Core/Src/stm32l4xx_it.c --no-default-config -fno-caret-diagnostics -target thumbv7em-unknown-unknown-eabihf -mthumb -mabi=aapcs -mfloat-abi=hard -fno-PIC -gdwarf-4 -gdwarf32 -flto=full -MD -MV -MF /blinky/.zig-cache/tmp/9dce247a5145b243-stm32l4xx_it.o.d -ffreestanding -fno-omit-frame-pointer -fno-stack-protector -fbuiltin -ffunction-sections -fdata-sections -fasynchronous-unwind-tables -nostdinc -isystem /opt/softs/zig-linux-x86_64-0.14.0/lib/include -fno-spell-checking -Xclang -target-cpu -Xclang cortex-m4 -Xclang -target-feature -Xclang -32bit -Xclang -target-feature -Xclang -8msecext -Xclang -target-feature -Xclang -aapcs-frame-chain -Xclang -target-feature -Xclang -aclass -Xclang -target-feature -Xclang -acquire-release -Xclang -target-feature -Xclang -aes -Xclang -target-feature -Xclang -atomics-32 -Xclang -target-feature -Xclang -avoid-movs-shop -Xclang -target-feature -Xclang -avoid-partial-cpsr -Xclang -target-feature -Xclang -bf16 -Xclang -target-feature -Xclang -big-endian-instructions -Xclang -target-feature -Xclang -cde -Xclang -target-feature -Xclang -cdecp0 -Xclang -target-feature -Xclang -cdecp1 -Xclang -target-feature -Xclang -cdecp2 -Xclang -target-feature -Xclang -cdecp3 -Xclang -target-feature -Xclang -cdecp4 -Xclang -target-feature -Xclang -cdecp5 -Xclang -target-feature -Xclang -cdecp6 -Xclang -target-feature -Xclang -cdecp7 -Xclang -target-feature -Xclang -cheap-predicable-cpsr -Xclang -target-feature -Xclang -clrbhb -Xclang -target-feature -Xclang -crc -Xclang -target-feature -Xclang -crypto -Xclang -target-feature -Xclang -d32 -Xclang -target-feature -Xclang +db -Xclang -target-feature -Xclang -dfb -Xclang -target-feature -Xclang -disable-postra-scheduler -Xclang -target-feature -Xclang -dont-widen-vmovs -Xclang -target-feature -Xclang -dotprod -Xclang -target-feature -Xclang +dsp -Xclang -target-feature -Xclang -execute-only -Xclang -target-feature -Xclang -expand-fp-mlx -Xclang -target-feature -Xclang -fix-cmse-cve-2021-35465 -Xclang -target-feature -Xclang -fix-cortex-a57-aes-1742098 -Xclang -target-feature -Xclang +fp16 -Xclang -target-feature -Xclang -fp16fml -Xclang -target-feature -Xclang -fp64 -Xclang -target-feature -Xclang -fp-armv8 -Xclang -target-feature -Xclang -fp-armv8d16 -Xclang -target-feature -Xclang -fp-armv8d16sp -Xclang -target-feature -Xclang -fp-armv8sp -Xclang -target-feature -Xclang -fpao -Xclang -target-feature -Xclang +fpregs -Xclang -target-feature -Xclang -fpregs16 -Xclang -target-feature -Xclang -fpregs64 -Xclang -target-feature -Xclang -fullfp16 -Xclang -target-feature -Xclang -fuse-aes -Xclang -target-feature -Xclang -fuse-literals -Xclang -target-feature -Xclang -harden-sls-blr -Xclang -target-feature -Xclang -harden-sls-nocomdat -Xclang -target-feature -Xclang -harden-sls-retbr -Xclang -target-feature -Xclang +v4t -Xclang -target-feature -Xclang +v5t -Xclang -target-feature -Xclang +v5te -Xclang -target-feature -Xclang +v6 -Xclang -target-feature -Xclang +v6k -Xclang -target-feature -Xclang +v6m -Xclang -target-feature -Xclang +v6t2 -Xclang -target-feature -Xclang +v7 -Xclang -target-feature -Xclang +v7clrex -Xclang -target-feature -Xclang -v8 -Xclang -target-feature -Xclang -v8.1a -Xclang -target-feature -Xclang -v8.1m.main -Xclang -target-feature -Xclang -v8.2a -Xclang -target-feature -Xclang -v8.3a -Xclang -target-feature -Xclang -v8.4a -Xclang -target-feature -Xclang -v8.5a -Xclang -target-feature -Xclang -v8.6a -Xclang -target-feature -Xclang -v8.7a -Xclang -target-feature -Xclang -v8.8a -Xclang -target-feature -Xclang -v8.9a -Xclang -target-feature -Xclang +v8m -Xclang -target-feature -Xclang -v8m.main -Xclang -target-feature -Xclang -v9.1a -Xclang -target-feature -Xclang -v9.2a -Xclang -target-feature -Xclang -v9.3a -Xclang -target-feature -Xclang -v9.4a -Xclang -target-feature -Xclang -v9.5a -Xclang -target-feature -Xclang -v9a -Xclang -target-feature -Xclang +hwdiv -Xclang -target-feature -Xclang -hwdiv-arm -Xclang -target-feature -Xclang -i8mm -Xclang -target-feature -Xclang -iwmmxt -Xclang -target-feature -Xclang -iwmmxt2 -Xclang -target-feature -Xclang -lob -Xclang -target-feature -Xclang -long-calls -Xclang -target-feature -Xclang +loop-align -Xclang -target-feature -Xclang +mclass -Xclang -target-feature -Xclang -mp -Xclang -target-feature -Xclang -muxed-units -Xclang -target-feature -Xclang -mve -Xclang -target-feature -Xclang -mve1beat -Xclang -target-feature -Xclang -mve2beat -Xclang -target-feature -Xclang -mve4beat -Xclang -target-feature -Xclang -mve.fp -Xclang -target-feature -Xclang -nacl-trap -Xclang -target-feature -Xclang -neon -Xclang -target-feature -Xclang -neon-fpmovs -Xclang -target-feature -Xclang -neonfp -Xclang -target-feature -Xclang +no-branch-predictor -Xclang -target-feature -Xclang -no-bti-at-return-twice -Xclang -target-feature -Xclang -no-movt -Xclang -target-feature -Xclang -no-neg-immediates -Xclang -target-feature -Xclang +noarm -Xclang -target-feature -Xclang -nonpipelined-vfp -Xclang -target-feature -Xclang -pacbti -Xclang -target-feature -Xclang -perfmon -Xclang -target-feature -Xclang -prefer-ishst -Xclang -target-feature -Xclang -prefer-vmovsr -Xclang -target-feature -Xclang -prof-unpr -Xclang -target-feature -Xclang -ras -Xclang -target-feature -Xclang -rclass -Xclang -target-feature -Xclang -read-tp-tpidrprw -Xclang -target-feature -Xclang -read-tp-tpidruro -Xclang -target-feature -Xclang -read-tp-tpidrurw -Xclang -target-feature -Xclang -reserve-r9 -Xclang -target-feature -Xclang -ret-addr-stack -Xclang -target-feature -Xclang -sb -Xclang -target-feature -Xclang -sha2 -Xclang -target-feature -Xclang -slow-fp-brcc -Xclang -target-feature -Xclang -slow-load-D-subreg -Xclang -target-feature -Xclang -slow-odd-reg -Xclang -target-feature -Xclang -slow-vdup32 -Xclang -target-feature -Xclang -slow-vgetlni32 -Xclang -target-feature -Xclang +slowfpvfmx -Xclang -target-feature -Xclang +slowfpvmlx -Xclang -target-feature -Xclang -splat-vfp-neon -Xclang -target-feature -Xclang -strict-align -Xclang -target-feature -Xclang +thumb2 -Xclang -target-feature -Xclang +thumb-mode -Xclang -target-feature -Xclang -trustzone -Xclang -target-feature -Xclang -use-mipipeliner -Xclang -target-feature -Xclang +use-misched -Xclang -target-feature -Xclang -armv4 -Xclang -target-feature -Xclang -armv4t -Xclang -target-feature -Xclang -armv5t -Xclang -target-feature -Xclang -armv5te -Xclang -target-feature -Xclang -armv5tej -Xclang -target-feature -Xclang -armv6 -Xclang -target-feature -Xclang -armv6j -Xclang -target-feature -Xclang -armv6k -Xclang -target-feature -Xclang -armv6kz -Xclang -target-feature -Xclang -armv6-m -Xclang -target-feature -Xclang -armv6s-m -Xclang -target-feature -Xclang -armv6t2 -Xclang -target-feature -Xclang -armv7-a -Xclang -target-feature -Xclang +armv7e-m -Xclang -target-feature -Xclang -armv7-m -Xclang -target-feature -Xclang -armv7-r -Xclang -target-feature -Xclang -armv7ve -Xclang -target-feature -Xclang -armv8.1-a -Xclang -target-feature -Xclang -armv8.1-m.main -Xclang -target-feature -Xclang -armv8.2-a -Xclang -target-feature -Xclang -armv8.3-a -Xclang -target-feature -Xclang -armv8.4-a -Xclang -target-feature -Xclang -armv8.5-a -Xclang -target-feature -Xclang -armv8.6-a -Xclang -target-feature -Xclang -armv8.7-a -Xclang -target-feature -Xclang -armv8.8-a -Xclang -target-feature -Xclang -armv8.9-a -Xclang -target-feature -Xclang -armv8-a -Xclang -target-feature -Xclang -armv8-m.base -Xclang -target-feature -Xclang -armv8-m.main -Xclang -target-feature -Xclang -armv8-r -Xclang -target-feature -Xclang -armv9.1-a -Xclang -target-feature -Xclang -armv9.2-a -Xclang -target-feature -Xclang -armv9.3-a -Xclang -target-feature -Xclang -armv9.4-a -Xclang -target-feature -Xclang -armv9.5-a -Xclang -target-feature -Xclang -armv9-a -Xclang -target-feature -Xclang -vfp2 -Xclang -target-feature -Xclang +vfp2sp -Xclang -target-feature -Xclang -vfp3 -Xclang -target-feature -Xclang -vfp3d16 -Xclang -target-feature -Xclang +vfp3d16sp -Xclang -target-feature -Xclang -vfp3sp -Xclang -target-feature -Xclang -vfp4 -Xclang -target-feature -Xclang -vfp4d16 -Xclang -target-feature -Xclang +vfp4d16sp -Xclang -target-feature -Xclang -vfp4sp -Xclang -target-feature -Xclang -virtualization -Xclang -target-feature -Xclang -vldn-align -Xclang -target-feature -Xclang -vmlx-forwarding -Xclang -target-feature -Xclang -vmlx-hazards -Xclang -target-feature -Xclang -wide-stride-vfp -Xclang -target-feature -Xclang -xscale -Xclang -target-feature -Xclang -zcz -fsanitize=undefined -fno-sanitize=vptr -fno-sanitize=function -D_DEBUG -O0 -isystem /opt/softs/xpack-arm-none-eabi-gcc-14.2.1-1.1/arm-none-eabi/include -I /blinky/Drivers/STM32L4xx_HAL_Driver/Inc -I /blinky/Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I /blinky/Drivers/CMSIS/Device/ST/STM32L4xx/Include -I /blinky/Drivers/CMSIS/Include -I /blinky/Core/Inc -DUSE_HAL_DRIVER= -DSTM32L476xx= -Og -std=gnu17 -Wall -Wextra -c -o /blinky/.zig-cache/tmp/9dce247a5145b243-stm32l4xx_it.o --serialize-diagnostics /blinky/.zig-cache/tmp/9dce247a5145b243-stm32l4xx_it.o.diag
...
zig clang /blinky/Core/Src/stm32l4xx_hal_msp.c --no-default-config -fno-caret-diagnostics -target thumbv7em-unknown-unknown-eabihf -mthumb -mabi=aapcs -mfloat-abi=hard -fno-PIC -gdwarf-4 -gdwarf32 -flto=full -MD -MV -MF /blinky/.zig-cache/tmp/c7054f54cc9ab453-stm32l4xx_hal_msp.o.d -ffreestanding -fno-omit-frame-pointer -fno-stack-protector -fbuiltin -ffunction-sections -fdata-sections -fasynchronous-unwind-tables -nostdinc -isystem /opt/softs/zig-linux-x86_64-0.14.0/lib/include -fno-spell-checking -Xclang -target-cpu -Xclang cortex-m4 -Xclang -target-feature -Xclang -32bit -Xclang -target-feature -Xclang -8msecext -Xclang -target-feature -Xclang -aapcs-frame-chain -Xclang -target-feature -Xclang -aclass -Xclang -target-feature -Xclang -acquire-release -Xclang -target-feature -Xclang -aes -Xclang -target-feature -Xclang -atomics-32 -Xclang -target-feature -Xclang -avoid-movs-shop -Xclang -target-feature -Xclang -avoid-partial-cpsr -Xclang -target-feature -Xclang -bf16 -Xclang -target-feature -Xclang -big-endian-instructions -Xclang -target-feature -Xclang -cde -Xclang -target-feature -Xclang -cdecp0 -Xclang -target-feature -Xclang -cdecp1 -Xclang -target-feature -Xclang -cdecp2 -Xclang -target-feature -Xclang -cdecp3 -Xclang -target-feature -Xclang -cdecp4 -Xclang -target-feature -Xclang -cdecp5 -Xclang -target-feature -Xclang -cdecp6 -Xclang -target-feature -Xclang -cdecp7 -Xclang -target-feature -Xclang -cheap-predicable-cpsr -Xclang -target-feature -Xclang -clrbhb -Xclang -target-feature -Xclang -crc -Xclang -target-feature -Xclang -crypto -Xclang -target-feature -Xclang -d32 -Xclang -target-feature -Xclang +db -Xclang -target-feature -Xclang -dfb -Xclang -target-feature -Xclang -disable-postra-scheduler -Xclang -target-feature -Xclang -dont-widen-vmovs -Xclang -target-feature -Xclang -dotprod -Xclang -target-feature -Xclang +dsp -Xclang -target-feature -Xclang -execute-only -Xclang -target-feature -Xclang -expand-fp-mlx -Xclang -target-feature -Xclang -fix-cmse-cve-2021-35465 -Xclang -target-feature -Xclang -fix-cortex-a57-aes-1742098 -Xclang -target-feature -Xclang +fp16 -Xclang -target-feature -Xclang -fp16fml -Xclang -target-feature -Xclang -fp64 -Xclang -target-feature -Xclang -fp-armv8 -Xclang -target-feature -Xclang -fp-armv8d16 -Xclang -target-feature -Xclang -fp-armv8d16sp -Xclang -target-feature -Xclang -fp-armv8sp -Xclang -target-feature -Xclang -fpao -Xclang -target-feature -Xclang +fpregs -Xclang -target-feature -Xclang -fpregs16 -Xclang -target-feature -Xclang -fpregs64 -Xclang -target-feature -Xclang -fullfp16 -Xclang -target-feature -Xclang -fuse-aes -Xclang -target-feature -Xclang -fuse-literals -Xclang -target-feature -Xclang -harden-sls-blr -Xclang -target-feature -Xclang -harden-sls-nocomdat -Xclang -target-feature -Xclang -harden-sls-retbr -Xclang -target-feature -Xclang +v4t -Xclang -target-feature -Xclang +v5t -Xclang -target-feature -Xclang +v5te -Xclang -target-feature -Xclang +v6 -Xclang -target-feature -Xclang +v6k -Xclang -target-feature -Xclang +v6m -Xclang -target-feature -Xclang +v6t2 -Xclang -target-feature -Xclang +v7 -Xclang -target-feature -Xclang +v7clrex -Xclang -target-feature -Xclang -v8 -Xclang -target-feature -Xclang -v8.1a -Xclang -target-feature -Xclang -v8.1m.main -Xclang -target-feature -Xclang -v8.2a -Xclang -target-feature -Xclang -v8.3a -Xclang -target-feature -Xclang -v8.4a -Xclang -target-feature -Xclang -v8.5a -Xclang -target-feature -Xclang -v8.6a -Xclang -target-feature -Xclang -v8.7a -Xclang -target-feature -Xclang -v8.8a -Xclang -target-feature -Xclang -v8.9a -Xclang -target-feature -Xclang +v8m -Xclang -target-feature -Xclang -v8m.main -Xclang -target-feature -Xclang -v9.1a -Xclang -target-feature -Xclang -v9.2a -Xclang -target-feature -Xclang -v9.3a -Xclang -target-feature -Xclang -v9.4a -Xclang -target-feature -Xclang -v9.5a -Xclang -target-feature -Xclang -v9a -Xclang -target-feature -Xclang +hwdiv -Xclang -target-feature -Xclang -hwdiv-arm -Xclang -target-feature -Xclang -i8mm -Xclang -target-feature -Xclang -iwmmxt -Xclang -target-feature -Xclang -iwmmxt2 -Xclang -target-feature -Xclang -lob -Xclang -target-feature -Xclang -long-calls -Xclang -target-feature -Xclang +loop-align -Xclang -target-feature -Xclang +mclass -Xclang -target-feature -Xclang -mp -Xclang -target-feature -Xclang -muxed-units -Xclang -target-feature -Xclang -mve -Xclang -target-feature -Xclang -mve1beat -Xclang -target-feature -Xclang -mve2beat -Xclang -target-feature -Xclang -mve4beat -Xclang -target-feature -Xclang -mve.fp -Xclang -target-feature -Xclang -nacl-trap -Xclang -target-feature -Xclang -neon -Xclang -target-feature -Xclang -neon-fpmovs -Xclang -target-feature -Xclang -neonfp -Xclang -target-feature -Xclang +no-branch-predictor -Xclang -target-feature -Xclang -no-bti-at-return-twice -Xclang -target-feature -Xclang -no-movt -Xclang -target-feature -Xclang -no-neg-immediates -Xclang -target-feature -Xclang +noarm -Xclang -target-feature -Xclang -nonpipelined-vfp -Xclang -target-feature -Xclang -pacbti -Xclang -target-feature -Xclang -perfmon -Xclang -target-feature -Xclang -prefer-ishst -Xclang -target-feature -Xclang -prefer-vmovsr -Xclang -target-feature -Xclang -prof-unpr -Xclang -target-feature -Xclang -ras -Xclang -target-feature -Xclang -rclass -Xclang -target-feature -Xclang -read-tp-tpidrprw -Xclang -target-feature -Xclang -read-tp-tpidruro -Xclang -target-feature -Xclang -read-tp-tpidrurw -Xclang -target-feature -Xclang -reserve-r9 -Xclang -target-feature -Xclang -ret-addr-stack -Xclang -target-feature -Xclang -sb -Xclang -target-feature -Xclang -sha2 -Xclang -target-feature -Xclang -slow-fp-brcc -Xclang -target-feature -Xclang -slow-load-D-subreg -Xclang -target-feature -Xclang -slow-odd-reg -Xclang -target-feature -Xclang -slow-vdup32 -Xclang -target-feature -Xclang -slow-vgetlni32 -Xclang -target-feature -Xclang +slowfpvfmx -Xclang -target-feature -Xclang +slowfpvmlx -Xclang -target-feature -Xclang -splat-vfp-neon -Xclang -target-feature -Xclang -strict-align -Xclang -target-feature -Xclang +thumb2 -Xclang -target-feature -Xclang +thumb-mode -Xclang -target-feature -Xclang -trustzone -Xclang -target-feature -Xclang -use-mipipeliner -Xclang -target-feature -Xclang +use-misched -Xclang -target-feature -Xclang -armv4 -Xclang -target-feature -Xclang -armv4t -Xclang -target-feature -Xclang -armv5t -Xclang -target-feature -Xclang -armv5te -Xclang -target-feature -Xclang -armv5tej -Xclang -target-feature -Xclang -armv6 -Xclang -target-feature -Xclang -armv6j -Xclang -target-feature -Xclang -armv6k -Xclang -target-feature -Xclang -armv6kz -Xclang -target-feature -Xclang -armv6-m -Xclang -target-feature -Xclang -armv6s-m -Xclang -target-feature -Xclang -armv6t2 -Xclang -target-feature -Xclang -armv7-a -Xclang -target-feature -Xclang +armv7e-m -Xclang -target-feature -Xclang -armv7-m -Xclang -target-feature -Xclang -armv7-r -Xclang -target-feature -Xclang -armv7ve -Xclang -target-feature -Xclang -armv8.1-a -Xclang -target-feature -Xclang -armv8.1-m.main -Xclang -target-feature -Xclang -armv8.2-a -Xclang -target-feature -Xclang -armv8.3-a -Xclang -target-feature -Xclang -armv8.4-a -Xclang -target-feature -Xclang -armv8.5-a -Xclang -target-feature -Xclang -armv8.6-a -Xclang -target-feature -Xclang -armv8.7-a -Xclang -target-feature -Xclang -armv8.8-a -Xclang -target-feature -Xclang -armv8.9-a -Xclang -target-feature -Xclang -armv8-a -Xclang -target-feature -Xclang -armv8-m.base -Xclang -target-feature -Xclang -armv8-m.main -Xclang -target-feature -Xclang -armv8-r -Xclang -target-feature -Xclang -armv9.1-a -Xclang -target-feature -Xclang -armv9.2-a -Xclang -target-feature -Xclang -armv9.3-a -Xclang -target-feature -Xclang -armv9.4-a -Xclang -target-feature -Xclang -armv9.5-a -Xclang -target-feature -Xclang -armv9-a -Xclang -target-feature -Xclang -vfp2 -Xclang -target-feature -Xclang +vfp2sp -Xclang -target-feature -Xclang -vfp3 -Xclang -target-feature -Xclang -vfp3d16 -Xclang -target-feature -Xclang +vfp3d16sp -Xclang -target-feature -Xclang -vfp3sp -Xclang -target-feature -Xclang -vfp4 -Xclang -target-feature -Xclang -vfp4d16 -Xclang -target-feature -Xclang +vfp4d16sp -Xclang -target-feature -Xclang -vfp4sp -Xclang -target-feature -Xclang -virtualization -Xclang -target-feature -Xclang -vldn-align -Xclang -target-feature -Xclang -vmlx-forwarding -Xclang -target-feature -Xclang -vmlx-hazards -Xclang -target-feature -Xclang -wide-stride-vfp -Xclang -target-feature -Xclang -xscale -Xclang -target-feature -Xclang -zcz -fsanitize=undefined -fno-sanitize=vptr -fno-sanitize=function -D_DEBUG -O0 -isystem /opt/softs/xpack-arm-none-eabi-gcc-14.2.1-1.1/arm-none-eabi/include -I /blinky/Drivers/STM32L4xx_HAL_Driver/Inc -I /blinky/Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I /blinky/Drivers/CMSIS/Device/ST/STM32L4xx/Include -I /blinky/Drivers/CMSIS/Include -I /blinky/Core/Inc -DUSE_HAL_DRIVER= -DSTM32L476xx= -Og -std=gnu17 -Wall -Wextra -c -o /blinky/.zig-cache/tmp/c7054f54cc9ab453-stm32l4xx_hal_msp.o --serialize-diagnostics /blinky/.zig-cache/tmp/c7054f54cc9ab453-stm32l4xx_hal_msp.o.diag
clang -x c --no-default-config -fno-caret-diagnostics -target thumbv7em-unknown-unknown-eabihf -mthumb -mabi=aapcs -mfloat-abi=hard -fno-PIC -gdwarf-4 -gdwarf32 -flto=full -MD -MV -MF /blinky/.zig-cache/o/e7da661d47b5ec8b3f3a1c319a406889/cimport.h.d -ffreestanding -fno-omit-frame-pointer -fno-stack-protector -fbuiltin -ffunction-sections -fdata-sections -fasynchronous-unwind-tables -nostdinc -isystem /opt/softs/zig-linux-x86_64-0.14.0/lib/include -fno-spell-checking -Xclang -target-cpu -Xclang cortex-m4 -Xclang -target-feature -Xclang -32bit -Xclang -target-feature -Xclang -8msecext -Xclang -target-feature -Xclang -aapcs-frame-chain -Xclang -target-feature -Xclang -aclass -Xclang -target-feature -Xclang -acquire-release -Xclang -target-feature -Xclang -aes -Xclang -target-feature -Xclang -atomics-32 -Xclang -target-feature -Xclang -avoid-movs-shop -Xclang -target-feature -Xclang -avoid-partial-cpsr -Xclang -target-feature -Xclang -bf16 -Xclang -target-feature -Xclang -big-endian-instructions -Xclang -target-feature -Xclang -cde -Xclang -target-feature -Xclang -cdecp0 -Xclang -target-feature -Xclang -cdecp1 -Xclang -target-feature -Xclang -cdecp2 -Xclang -target-feature -Xclang -cdecp3 -Xclang -target-feature -Xclang -cdecp4 -Xclang -target-feature -Xclang -cdecp5 -Xclang -target-feature -Xclang -cdecp6 -Xclang -target-feature -Xclang -cdecp7 -Xclang -target-feature -Xclang -cheap-predicable-cpsr -Xclang -target-feature -Xclang -clrbhb -Xclang -target-feature -Xclang -crc -Xclang -target-feature -Xclang -crypto -Xclang -target-feature -Xclang -d32 -Xclang -target-feature -Xclang +db -Xclang -target-feature -Xclang -dfb -Xclang -target-feature -Xclang -disable-postra-scheduler -Xclang -target-feature -Xclang -dont-widen-vmovs -Xclang -target-feature -Xclang -dotprod -Xclang -target-feature -Xclang +dsp -Xclang -target-feature -Xclang -execute-only -Xclang -target-feature -Xclang -expand-fp-mlx -Xclang -target-feature -Xclang -fix-cmse-cve-2021-35465 -Xclang -target-feature -Xclang -fix-cortex-a57-aes-1742098 -Xclang -target-feature -Xclang +fp16 -Xclang -target-feature -Xclang -fp16fml -Xclang -target-feature -Xclang -fp64 -Xclang -target-feature -Xclang -fp-armv8 -Xclang -target-feature -Xclang -fp-armv8d16 -Xclang -target-feature -Xclang -fp-armv8d16sp -Xclang -target-feature -Xclang -fp-armv8sp -Xclang -target-feature -Xclang -fpao -Xclang -target-feature -Xclang +fpregs -Xclang -target-feature -Xclang -fpregs16 -Xclang -target-feature -Xclang -fpregs64 -Xclang -target-feature -Xclang -fullfp16 -Xclang -target-feature -Xclang -fuse-aes -Xclang -target-feature -Xclang -fuse-literals -Xclang -target-feature -Xclang -harden-sls-blr -Xclang -target-feature -Xclang -harden-sls-nocomdat -Xclang -target-feature -Xclang -harden-sls-retbr -Xclang -target-feature -Xclang +v4t -Xclang -target-feature -Xclang +v5t -Xclang -target-feature -Xclang +v5te -Xclang -target-feature -Xclang +v6 -Xclang -target-feature -Xclang +v6k -Xclang -target-feature -Xclang +v6m -Xclang -target-feature -Xclang +v6t2 -Xclang -target-feature -Xclang +v7 -Xclang -target-feature -Xclang +v7clrex -Xclang -target-feature -Xclang -v8 -Xclang -target-feature -Xclang -v8.1a -Xclang -target-feature -Xclang -v8.1m.main -Xclang -target-feature -Xclang -v8.2a -Xclang -target-feature -Xclang -v8.3a -Xclang -target-feature -Xclang -v8.4a -Xclang -target-feature -Xclang -v8.5a -Xclang -target-feature -Xclang -v8.6a -Xclang -target-feature -Xclang -v8.7a -Xclang -target-feature -Xclang -v8.8a -Xclang -target-feature -Xclang -v8.9a -Xclang -target-feature -Xclang +v8m -Xclang -target-feature -Xclang -v8m.main -Xclang -target-feature -Xclang -v9.1a -Xclang -target-feature -Xclang -v9.2a -Xclang -target-feature -Xclang -v9.3a -Xclang -target-feature -Xclang -v9.4a -Xclang -target-feature -Xclang -v9.5a -Xclang -target-feature -Xclang -v9a -Xclang -target-feature -Xclang +hwdiv -Xclang -target-feature -Xclang -hwdiv-arm -Xclang -target-feature -Xclang -i8mm -Xclang -target-feature -Xclang -iwmmxt -Xclang -target-feature -Xclang -iwmmxt2 -Xclang -target-feature -Xclang -lob -Xclang -target-feature -Xclang -long-calls -Xclang -target-feature -Xclang +loop-align -Xclang -target-feature -Xclang +mclass -Xclang -target-feature -Xclang -mp -Xclang -target-feature -Xclang -muxed-units -Xclang -target-feature -Xclang -mve -Xclang -target-feature -Xclang -mve1beat -Xclang -target-feature -Xclang -mve2beat -Xclang -target-feature -Xclang -mve4beat -Xclang -target-feature -Xclang -mve.fp -Xclang -target-feature -Xclang -nacl-trap -Xclang -target-feature -Xclang -neon -Xclang -target-feature -Xclang -neon-fpmovs -Xclang -target-feature -Xclang -neonfp -Xclang -target-feature -Xclang +no-branch-predictor -Xclang -target-feature -Xclang -no-bti-at-return-twice -Xclang -target-feature -Xclang -no-movt -Xclang -target-feature -Xclang -no-neg-immediates -Xclang -target-feature -Xclang +noarm -Xclang -target-feature -Xclang -nonpipelined-vfp -Xclang -target-feature -Xclang -pacbti -Xclang -target-feature -Xclang -perfmon -Xclang -target-feature -Xclang -prefer-ishst -Xclang -target-feature -Xclang -prefer-vmovsr -Xclang -target-feature -Xclang -prof-unpr -Xclang -target-feature -Xclang -ras -Xclang -target-feature -Xclang -rclass -Xclang -target-feature -Xclang -read-tp-tpidrprw -Xclang -target-feature -Xclang -read-tp-tpidruro -Xclang -target-feature -Xclang -read-tp-tpidrurw -Xclang -target-feature -Xclang -reserve-r9 -Xclang -target-feature -Xclang -ret-addr-stack -Xclang -target-feature -Xclang -sb -Xclang -target-feature -Xclang -sha2 -Xclang -target-feature -Xclang -slow-fp-brcc -Xclang -target-feature -Xclang -slow-load-D-subreg -Xclang -target-feature -Xclang -slow-odd-reg -Xclang -target-feature -Xclang -slow-vdup32 -Xclang -target-feature -Xclang -slow-vgetlni32 -Xclang -target-feature -Xclang +slowfpvfmx -Xclang -target-feature -Xclang +slowfpvmlx -Xclang -target-feature -Xclang -splat-vfp-neon -Xclang -target-feature -Xclang -strict-align -Xclang -target-feature -Xclang +thumb2 -Xclang -target-feature -Xclang +thumb-mode -Xclang -target-feature -Xclang -trustzone -Xclang -target-feature -Xclang -use-mipipeliner -Xclang -target-feature -Xclang +use-misched -Xclang -target-feature -Xclang -armv4 -Xclang -target-feature -Xclang -armv4t -Xclang -target-feature -Xclang -armv5t -Xclang -target-feature -Xclang -armv5te -Xclang -target-feature -Xclang -armv5tej -Xclang -target-feature -Xclang -armv6 -Xclang -target-feature -Xclang -armv6j -Xclang -target-feature -Xclang -armv6k -Xclang -target-feature -Xclang -armv6kz -Xclang -target-feature -Xclang -armv6-m -Xclang -target-feature -Xclang -armv6s-m -Xclang -target-feature -Xclang -armv6t2 -Xclang -target-feature -Xclang -armv7-a -Xclang -target-feature -Xclang +armv7e-m -Xclang -target-feature -Xclang -armv7-m -Xclang -target-feature -Xclang -armv7-r -Xclang -target-feature -Xclang -armv7ve -Xclang -target-feature -Xclang -armv8.1-a -Xclang -target-feature -Xclang -armv8.1-m.main -Xclang -target-feature -Xclang -armv8.2-a -Xclang -target-feature -Xclang -armv8.3-a -Xclang -target-feature -Xclang -armv8.4-a -Xclang -target-feature -Xclang -armv8.5-a -Xclang -target-feature -Xclang -armv8.6-a -Xclang -target-feature -Xclang -armv8.7-a -Xclang -target-feature -Xclang -armv8.8-a -Xclang -target-feature -Xclang -armv8.9-a -Xclang -target-feature -Xclang -armv8-a -Xclang -target-feature -Xclang -armv8-m.base -Xclang -target-feature -Xclang -armv8-m.main -Xclang -target-feature -Xclang -armv8-r -Xclang -target-feature -Xclang -armv9.1-a -Xclang -target-feature -Xclang -armv9.2-a -Xclang -target-feature -Xclang -armv9.3-a -Xclang -target-feature -Xclang -armv9.4-a -Xclang -target-feature -Xclang -armv9.5-a -Xclang -target-feature -Xclang -armv9-a -Xclang -target-feature -Xclang -vfp2 -Xclang -target-feature -Xclang +vfp2sp -Xclang -target-feature -Xclang -vfp3 -Xclang -target-feature -Xclang -vfp3d16 -Xclang -target-feature -Xclang +vfp3d16sp -Xclang -target-feature -Xclang -vfp3sp -Xclang -target-feature -Xclang -vfp4 -Xclang -target-feature -Xclang -vfp4d16 -Xclang -target-feature -Xclang +vfp4d16sp -Xclang -target-feature -Xclang -vfp4sp -Xclang -target-feature -Xclang -virtualization -Xclang -target-feature -Xclang -vldn-align -Xclang -target-feature -Xclang -vmlx-forwarding -Xclang -target-feature -Xclang -vmlx-hazards -Xclang -target-feature -Xclang -wide-stride-vfp -Xclang -target-feature -Xclang -xscale -Xclang -target-feature -Xclang -zcz -fsanitize=undefined -fno-sanitize=vptr -fno-sanitize=function -D_DEBUG -O0 -isystem /opt/softs/xpack-arm-none-eabi-gcc-14.2.1-1.1/arm-none-eabi/include -I /blinky/Drivers/STM32L4xx_HAL_Driver/Inc -I /blinky/Drivers/STM32L4xx_HAL_Driver/Inc/Legacy -I /blinky/Drivers/CMSIS/Device/ST/STM32L4xx/Include -I /blinky/Drivers/CMSIS/Include -I /blinky/Core/Inc -DUSE_HAL_DRIVER= -DSTM32L476xx= -Xclang -detailed-preprocessing-record /blinky/.zig-cache/o/e7da661d47b5ec8b3f3a1c319a406889/cimport.h
- Sections (
arm-none-eabi-readelf -S zig-out/bin/blinky.elf
) :
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .isr_vector PROGBITS 08000000 010000 000188 00 A 0 0 1
[ 2] .text PROGBITS 08000188 010188 009318 00 AX 0 0 4
[ 3] .rodata PROGBITS 080094a0 0194a0 002e58 00 AMS 0 0 16
[ 4] .ARM.extab PROGBITS 0800c2f8 01c2f8 000220 00 A 0 0 4
[ 5] .eh_frame_hdr PROGBITS 0800c518 01c518 00000c 00 A 0 0 4
[ 6] .ARM ARM_EXIDX 0800c524 01c524 000214 00 AL 2 0 4
[ 7] .preinit_array PROGBITS 0800c738 01c738 000000 00 A 0 0 1
[ 8] .init_array INIT_ARRAY 0800c738 01c738 000008 04 WA 0 0 4
[ 9] .fini_array FINI_ARRAY 0800c740 01c740 000008 04 WA 0 0 4
[10] .data PROGBITS 20000000 020000 000508 00 WA 0 0 16
[11] .bss NOBITS 20000508 020508 00027c 00 WA 0 0 4
[12] ._user_heap_stack NOBITS 20000784 020508 000604 00 WA 0 0 1
[13] .ARM.attributes ARM_ATTRIBUTES 00000000 020508 000020 00 0 0 1
[14] .comment PROGBITS 00000000 020528 00010a 01 MS 0 0 1
[15] .debug_info PROGBITS 00000000 020632 037887 00 0 0 1
[16] .debug_abbrev PROGBITS 00000000 057eb9 000d3d 00 0 0 1
[17] .debug_aranges PROGBITS 00000000 058bf6 000028 00 0 0 1
[18] .debug_ranges PROGBITS 00000000 058c1e 00f818 00 0 0 1
[19] .debug_line PROGBITS 00000000 068436 023613 00 0 0 1
[20] .debug_loc PROGBITS 00000000 08ba49 07a0e0 00 0 0 1
[21] .debug_str PROGBITS 00000000 105b29 00eacd 01 MS 0 0 1
[22] .debug_pubnames PROGBITS 00000000 1145f6 0042ed 00 0 0 1
[23] .debug_pubtypes PROGBITS 00000000 1188e3 001688 00 0 0 1
[24] .debug_frame PROGBITS 00000000 119f6c 003e40 00 0 0 4
[25] .symtab SYMTAB 00000000 11ddac 001e50 10 27 335 4
[26] .shstrtab STRTAB 00000000 11fbfc 000136 00 0 0 1
[27] .strtab STRTAB 00000000 11fd32 001ff5 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), y (purecode), p (processor specific)
- Symbol size (
arm-none-eabi-nm -r -t dec --size-sort zig-out/bin/blinky.elf
)
00014886 t ubsan_rt.Value.format__anon_6451
00002848 r fmt.format_float.FLOAT128_POW5_SPLIT
00002848 r fmt.format_float.FLOAT128_POW5_INV_SPLIT
00001798 t fmt.format_float.mul_128_256_shift
00001718 t fmt.formatBuf__anon_6387
00001696 t fmt.format_float.writeDecimal__anon_7923
00001684 t MX_USART2_UART_Init
00001248 r .Lanon.be54888b7f04376941d55ec9b1f8fa9e.153
00001232 r .Lanon.be54888b7f04376941d55ec9b1f8fa9e.152
00001202 W __udivmoddi4
00000896 r fmt.format_float.FLOAT128_POW5_TABLE
00000856 T main
00000854 t HAL_GPIO_Init
00000646 t debug.panicExtra__anon_2354
00000536 t main.myPanic
00000468 t debug.panicExtra__anon_2397
00000444 t __ubsan_handle_shift_out_of_bounds
00000398 t debug.panicExtra__anon_2366
00000386 t debug.panicExtra__anon_2407
00000356 t debug.panicExtra__anon_6317
00000356 t debug.panicExtra__anon_2700
00000356 t debug.panicExtra__anon_2325
00000356 t debug.panicExtra__anon_2317
00000356 t debug.panicExtra__anon_2312
00000344 t debug.panicExtra__anon_2278
00000344 t debug.panicExtra__anon_2197
00000330 t debug.panicExtra__anon_2299
00000330 t debug.panicExtra__anon_2291
00000318 t debug.panicExtra__anon_2344
00000316 t debug.panicExtra__anon_2381
00000312 B __sf
00000290 t debug.panicExtra__anon_6489
00000290 t debug.panicExtra__anon_2359
00000278 t HAL_UART_Transmit
00000268 t UART_EndRxTransfer
00000252 W __extenddftf2
00000248 t fmt.formatInt__anon_7159
00000248 t debug.panicExtra__anon_2284
00000248 t debug.panicExtra__anon_2203
00000234 t HAL_RCC_GetSysClockFreq
00000234 W __aeabi_memcpy
00000220 t __ubsan_handle_type_mismatch_v1
00000214 W __extendsftf2
00000201 r __anon_7609
...
It seems that for my blinky program, float formatting and ubsan account for the largest portion of the binary.
A trade-off to reduce debug binary size is to disable the C sanitizer in each module.
.sanitize_c = if (optimization == .Debug) false else true,
Program |
Debug |
blinky |
6816 |
blinky_freertos |
34176 |
blinky_picolibc |
8044 |
But now I can do undefined behavior (like division by zero) and keep running! 
Yup, I encountered this as well and ended up tracking it down to mostly being related to the C UBSAN code added in 0.14.0
. Adding:
exe.root_module.sanitize_c = false;
To your build.zig
should hopefully remove a lot of this extra code. For freestanding systems sanitize_c = false
should probably be the default behavior, I’ll check in the Zig embedded discord if someone’s made an issue for it yet since this has been a topic of discussion there.
If I disable sanitize_c
for other release profiles like safe
, this C code will execute without trapping errors:
uint32_t a = 0;
uint32_t b = 45 / a;
char test[20];
sprintf(test,"%d",b);
However, if sanitize_c
is enabled, the code triggers an hardfault and HardFault_Handler
function is called.
However, I don’t know why my custom Panic
function isn’t called in this case. It was being called when UBSan was enabled in debug mode.
Interesting! I need to look more into the ubsan code, I honestly didn’t really think it would even work without an OS.
One thing to note is make sure you can differentiate a Zig panic from a processor hard fault. In your divide by zero case, that can cause a hard fault at the processor level depending on which processor you’re using /if you’ve configured it to hard fault on a divide by zero. But it can also cause a Zig panic before it would hit the actual instruction that would generate a processor hard fault.
Maybe step through with a debugger and see what the code path is with and without ubsan on?
I did a little digging into this behavior:
With UBsan enabled in debug mode (-Og
), I got the following assembly code:
- Debug (-Og) + sanitize_c = true : In this case, Zig calls
divRemHandler
and panics.
- Safe (-O2) + sanitize_c = true : In this case, the compiler also triggers an intentional hardfault with the
udf
instruction.
When I disable UBsan (sanitize_c = false
), the compiler simply optimizes out the code and it runs without issues.
But If I compile with -O0
, the code also runs. If I want a hardware hardfault, I need to explicitly enable it with:
SCB->CCR |= SCB_CCR_DIV_0_TRP_Msk;
- Debug (-O0) + sanitize_c = false : It will hardfault at
udiv
instruction
Nice good work! Super interesting about the undefined instruction the compiler put in in the sanitization case. I’ll have to dig more into how the UB sanitizer works exactly.