Closed 255 closed 4 weeks ago
Could you provide a sample ELF file which has ELFOSABI_GNU
, so that we can check that the rest of the ELF file handling still works with it?
Also, could you target this PR at the develop
branch rather than master
I created a minimal example to demonstrate the issue. I built it in Pigweed using Bazel and Clang (see http://pwrev.dev/229671).
#include "pico/stdlib.h"
struct HasNonDefaultConstructor {
HasNonDefaultConstructor() {}
};
// An inline variable with a non-default destruction causes Clang to use the
// SHF_GNU_RETAIN section flag, which changes the OS/ABI field to ELFOSABI_GNU.
// If you remove `inline` on the next line, the ELF will use ELFOSABI_NONE.
inline HasNonDefaultConstructor variable;
int main() {
gpio_init(PICO_DEFAULT_LED_PIN);
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
while (true) {
gpio_put(PICO_DEFAULT_LED_PIN, true);
sleep_ms(100);
gpio_put(PICO_DEFAULT_LED_PIN, false);
sleep_ms(100);
}
}
I uploaded two versions of the ELF, one as shown above and one with inline
removed:
minimal_example.zip.
Inspecting the ELFs, you can see that when the variable is inline
, Clang sets the GNU_RETAIN
flag for .bss
:
$ readelf -t minimal_example.elf minimal_example_without_inline.elf | grep -A2 "File:\|\.bss"
File: minimal_example.elf
There are 23 section headers, starting at offset 0x25500:
--
[12] .bss
NOBITS 200003b8 0203b4 0002d8 00 0 0 8
[00200003]: WRITE, ALLOC, GNU_RETAIN
--
File: minimal_example_without_inline.elf
There are 23 section headers, starting at offset 0x25480:
--
[12] .bss
NOBITS 200003b8 0203b4 0002d4 00 0 0 8
[00000003]: WRITE, ALLOC
Because of that, it sets the OS/ABI to GNU
(3) instead of NONE
(0) (which readelf
reports as System V
).
$ readelf -h minimal_example.elf minimal_example_without_inline.elf | grep "File:\|ABI:"
File: minimal_example.elf
OS/ABI: UNIX - GNU
File: minimal_example_without_inline.elf
OS/ABI: UNIX - System V
I flashed these binaries to a Pico using openocd
and a debug probe, and they both work as expected. Picotool 2.0.0 refuses to flash minimal_example.elf
even though it is compatible.
Thanks, those elfs look like they'll be fine with the rest of picotool - I'll merge this
RP2 ELF files typically have their EI_OSABI field set to ELFOSABI_NONE. However, when Clang uses GNU extensions, it sets EI_OSABI to ELFOSABI_GNU. The binary is still fully compatible with RP2; ELFOSABI_GNU just indicates that GNU extensions are used in the ELF.
For example, Clang uses the SHF_GNU_RETAIN section flag when compiling a C++17 inline variable with a non-default constructor. This results in an ELF with an EI_OSABI of ELFOSABI_GNU. Picotool currently rejects these ELFs, even though the binary is compatible with the device.