Targetting ESP32 with opt-level 0, under some circumstances calling the same function twice doesn't work. It seems the function address register, in the case of my reproducible setup, a8 gets clobbered even though it's used again later.
The Rust code looks like:
// Initialize RTC RAM
xtensa_lx_rt::zero_bss(&mut _rtc_fast_bss_start, &mut _rtc_fast_bss_end); xtensa_lx_rt::zero_bss(&mut _rtc_slow_bss_start, &mut _rtc_slow_bss_end);
On the second call, it crashes.
400d805c: e22381 l32r a8, 400d08e8 <_stext+0x8c8> // correct address is loaded here
xtensa_lx_rt::zero_bss(&mut _rtc_fast_bss_start, &mut _rtc_fast_bss_end);
400d805f: 0189 s32i.n a8, a1, 0
400d8061: 0008e0 callx8 a8
400d8064: 0188 l32i.n a8, a1, 0 // a8 is clobbered here
400d8066: e221a1 l32r a10, 400d08ec <_stext+0x8cc>
400d8069: e221b1 l32r a11, 400d08f0 <_stext+0x8d0>
xtensa_lx_rt::zero_bss(&mut _rtc_slow_bss_start, &mut _rtc_slow_bss_end);
400d806c: 0008e0 callx8 a8 // callx8 jumps to garbage and crashes
400d806f: e22181 l32r a8, 400d08f4 <_stext+0x8d4> // continue with default reset handler
xtensa_lx_rt::Reset();
Seems 1.67 has exposed this bug in the LLVM backend.
workarounds
Any opt-level != 0 seems to work fine.
Targetting ESP32 with opt-level 0, under some circumstances calling the same function twice doesn't work. It seems the function address register, in the case of my reproducible setup, a8 gets clobbered even though it's used again later.
The Rust code looks like:
On the second call, it crashes.
Seems 1.67 has exposed this bug in the LLVM backend.
workarounds
Any opt-level != 0 seems to work fine.