Regression in OpenOCD 0.11.0 and 0.12.0

@roboter discovered a regression in OpenOCD 0.11.0 and 0.12.0. Some .elf files can be flashed with OpenOCD 0.10.0 while versions 0.11.0 and 0.12.0 are unable to flash the same .elf file.

Below I’ll explain everything you need to know, to reproduce the problem.


1. System and OpenOCD builds

I’m working on a Windows 11 laptop. The OpenOCDs I’m using are all downloaded from Liviu Ionescu’s xPack project:

When I refer to OpenOCD 0.10.0, 0.11.0 and 0.12.0, I actualy mean this:

  • OpenOCD 0.10.0
    Downloaded as: xpack-openocd-0.10.0-15-win32-x64.zip
    The --version output is:

    xPack OpenOCD, x86_64 Open On-Chip Debugger 0.10.0+dev (2020-10-13-17:29)
    
  • OpenOCD 0.11.0
    Downloaded as: xpack-openocd-0.11.0-5-win32-x64.zip
    The --version output is:

    xPack OpenOCD x86_64 Open On-Chip Debugger 0.11.0+dev (2022-09-01-17:58)
    
  • OpenOCD 0.12.0
    Downloaded as: xpack-openocd-0.12.0-1-win32-x64.zip
    The --version output is:

     xPack Open On-Chip Debugger 0.12.0-01004-g9ea7f3d64-dirty (2023-01-30-15:04)
    

2. Demonstration of the problem

The target board is a NUCLEO-F303K8, which has a STM32F303K8 chip onboard:

@roboter has prepared two projects for this demonstration:

  • f303-working: This project works with all the OpenOCD versions - up to and including OpenOCD 0.12.0
  • f303-failing: This project works with OpenOCD 0.10.0, but not with OpenOCD 0.11.0 and 0.12.0.

Both projects are Embeetle projects. However, I’ll explain here how to flash the project’s binaries without Embeetle involved.

  • f303-working

    For the f303-working project, just download the .elf file from this source: https://new.embeetle/downloads/misc/openocd_problem/f303-working.elf

    Next, you need the openocd_probe.cfg and openocd_chip.cfg files. They’re very simple:

    # openocd_probe.cfg
    source [find interface/stlink.cfg]
    transport select hla_swd
    
    # openocd_chip.cfg
    source [find target/stm32f3x.cfg]
    reset_config srst_only
    

    Put the f303-working.elf, openocd_probe.cfg and openocd_chip.cfg files all in the same folder. Then issue the following command:

    $ openocd -f openocd_probe.cfg -f openocd_chip.cfg -c "program {f303-working.elf} verify reset; shutdown;"
    

    As you will notice, this f303-working.elf firmware can be flashed with both OpenOCD 0.10.0, 0.11.0 and 0.12.0. The output is:

    xPack Open On-Chip Debugger 0.12.0-01004-g9ea7f3d64-dirty (2023-01-30-15:04)
    Licensed under GNU GPL v2
    For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
    hla_swd
    Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
    srst_only separate srst_nogate srst_open_drain connect_deassert_srst
    
    Info : clock speed 1000 kHz
    Info : STLINK V2J25M14 (API v2) VID:PID 0483:374B
    Info : Target voltage: 3.249572
    Info : [stm32f3x.cpu] Cortex-M4 r0p1 processor detected
    Info : [stm32f3x.cpu] target has 6 breakpoints, 4 watchpoints
    Info : starting gdb server for stm32f3x.cpu on 3333
    Info : Listening on port 3333 for gdb connections
    [stm32f3x.cpu] halted due to breakpoint, current mode: Thread 
    xPSR: 0x61000000 pc: 0x2000003a msp: 0xfffffffc
    Info : Unable to match requested speed 1000 kHz, using 950 kHz
    Info : Unable to match requested speed 1000 kHz, using 950 kHz
    [stm32f3x.cpu] halted due to debug-request, current mode: Thread 
    xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc
    Info : Unable to match requested speed 8000 kHz, using 4000 kHz
    Info : Unable to match requested speed 8000 kHz, using 4000 kHz
    ** Programming Started **
    Info : device id = 0x10016438
    Info : flash size = 64 KiB
    Warn : Adding extra erase range, 0x080014a0 .. 0x080017ff
    ** Programming Finished **
    ** Verify Started **
    ** Verified OK **
    ** Resetting Target **
    Info : Unable to match requested speed 1000 kHz, using 950 kHz
    Info : Unable to match requested speed 1000 kHz, using 950 kHz
    shutdown command invoked
    

  • f303-failing

    For the f303-failing project, just replace the f303-working.elf file with the f303-failing.elf file from this source: https://new.embeetle/downloads/misc/openocd_problem/f303-failing.elf

    Everthing else remains the same. With OpenOCD 0.10.0, the output is also the same (flashing works). But with OpenOCD 0.11.0 and 0.12.0, you’ll get the following output:

    xPack OpenOCD x86_64 Open On-Chip Debugger 0.11.0+dev (2022-09-01-17:58)
    Licensed under GNU GPL v2
    For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
    hla_swd
    Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
    srst_only separate srst_nogate srst_open_drain connect_deassert_srst
    
    Info : clock speed 1000 kHz
    Info : STLINK V2J25M14 (API v2) VID:PID 0483:374B
    Info : Target voltage: 3.249572
    Info : [stm32f3x.cpu] Cortex-M4 r0p1 processor detected
    Info : [stm32f3x.cpu] target has 6 breakpoints, 4 watchpoints
    Info : starting gdb server for stm32f3x.cpu on 3333
    Info : Listening on port 3333 for gdb connections
    Info : Unable to match requested speed 1000 kHz, using 950 kHz
    Info : Unable to match requested speed 1000 kHz, using 950 kHz
    target halted due to debug-request, current mode: Thread 
    xPSR: 0x01000000 pc: 0x08001384 msp: 0x20003000
    Info : Unable to match requested speed 8000 kHz, using 4000 kHz
    Info : Unable to match requested speed 8000 kHz, using 4000 kHz
    ** Programming Started **
    Info : device id = 0x10016438
    Info : flash size = 64 KiB
    Warn : Adding extra erase range, 0x08003198 .. 0x080037ff
    Error: error writing to flash at address 0x08000000 at offset 0x00000000
    embedded:startup.tcl:1435: Error: ** Programming Failed **
    in procedure 'program' 
    in procedure 'program_error' called at file "embedded:startup.tcl", line 1500
    at file "embedded:startup.tcl", line 1435
    

3. Resources

You can download the entire Embeetle projects here:

Aside from the .elf file, you can also find the .bin, .hex and .map files here:

I’ve run OpenOCD 0.12.0 on both projects with the -d flag to obtain debug output:

Liviu Ionescu responded this by mail:

This approach is a bit unusual; since you have a binary that can be flashed with all versions and one that fails with the latest two versions, assuming that all other things are the same, the natural question that comes to my mind is what differs between the two binaries?

Did you inspect the size and layout of the sections in the elf files and check if they are valid for your device? readelf or objdump may provide some help.

Another thing to try would be to flash the failing binary with the STM tools, and watch for errors/warnings messages, perhaps you can get some hints on what might be wrong.

The fact that your binary was fine with 0.10.0 and fails with the newer releases does not automatically imply a regression, it can also be explained by a problem with your binary and an extra validation test that was added in recent OpenOCDs, not accompanied by a helpful error message.

Only if you have the confirmation that the binaries are valid and can be flashed with a professional tool, (either provided by the silicon vendor or by some acknowledged third party like SEGGER), you can expect someone to consider a bug in OpenOCD.

Liviu

As a reply to Liviu’s concerns:

@roboter tried to flash the binary with the official STM flashtool. It worked. In other words: the binary is okay. The problem is on OpenOCD’s side.

Paul Fertser replied the following on the OpenOCD developers mailing list:

[Paul Fertser] I suspect a bug in this version of STLINK firmware (as it’s not like
the failing operation is writing to the wrong place or the wrong size,
the target has enough RAM). Have you tried upgrading it to the latest?

Thanks Paul for this note. @roboter just updated the STLINK firmware to the latest version. Unfortunately, this didn’t help.

[Paul Fertser] Have you tried using stlink-dap.cfg instead?

@roboter tried that today. Unfortunately, no success.