pico-sdk icon indicating copy to clipboard operation
pico-sdk copied to clipboard

Linker warning when compiling with GCC 12

Open ooxi opened this issue 1 year ago • 1 comments

When compiling a minimal example with GCC 12.2 I'm getting the following linker warning:

[1/5] Performing build step for 'ELF2UF2Build'
ninja: no work to do.
[5/5] Linking CXX executable hello_world.elf
/usr/lib/gcc/arm-none-eabi/12.2.0/../../../../arm-none-eabi/bin/ld: warning: hello_world.elf has a LOAD segment with RWX permissions
/usr/lib/gcc/arm-none-eabi/12.2.0/../../../../arm-none-eabi/bin/ld: warning: hello_world.elf has a LOAD segment with RWX permissions

This is confusing for novices. Unfortunately my linker script foo is not sufficient enough to propose a fix.

GCC 12.2 is shipped by Fedora 36, the current stable release. You can see the linker warning with full compile output in my GitHub Actions build

ooxi avatar Sep 19 '22 17:09 ooxi

This is technically a new warning in Binutils 2.39 rather than GCC, but distros tend to update Binutils and GCC together.

The new warnings can be disabled by linking with -Wl,--no-warn-rwx-segments, which can be done in cmake with

# in pico-sdk/src/rp2_common/pico_standard_link/CMakeLists.txt
target_link_options(pico_standard_link INTERFACE "LINKER:--no-warn-rwx-segments")

# or for a specific executable in a local CMakeLists.txt
target_link_options(hello_world PRIVATE "LINKER:--no-warn-rwx-segments")

I presume that the new flag isn't available in older versions of GNU ld so I don't know the best way for pico-sdk to fix this for everyone without doing some sort of complex linker version checking, since cmake doesn't have an equivalent of CMAKE_C_COMPILER_VERSION for the linker itself.

I tried removing the 'x' from 'rwx' in the memory sections of mmap_default.ld but that didn't seem to have any effect, the first two program segments are still rwx according to readelf and the warning still fires. Possibly related to use of volatile, c.f. https://stackoverflow.com/questions/73429929/gnu-linker-elf-has-a-load-segment-with-rwx-permissions-embedded-arm-project

aswild avatar Sep 29 '22 04:09 aswild

Confirmed with mingw-w64-x86_64-arm-none-eabi-binutils 2.39-1. This occurs when mingw64-arm-none-eabi remains at version 10.1.0 (on windows). The global fix above in ../pico_standard_link/CMakeLists.txt works like a champ.

drankinatty avatar Oct 16 '22 19:10 drankinatty

see https://www.redhat.com/en/blog/linkers-warnings-about-executable-stacks-and-segments

kilograham avatar Oct 21 '22 14:10 kilograham

I don't know much about this stuff, but, just using the blink example, you can see the problem...

readelf -lW blink.elf

Elf file type is EXEC (Executable file) Entry point 0x100001e9 There are 3 program headers, starting at offset 52

Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x001000 0x10000000 0x10000000 0x01c1c 0x01c1c RWE 0x1000 LOAD 0x0030c0 0x200000c0 0x10001c1c 0x0016c 0x0016c RWE 0x1000 LOAD 0x000230 0x20000230 0x20000230 0x00000 0x003c8 RW 0x1000

Section to Segment mapping: Segment Sections... 00 .boot2 .text .rodata .binary_info 01 .data 02 .bss

I think the first is writeable due to binary_info. The __bi_decl macro defines a writable pointer, so quite easy to fix.

Change struct _binary_info_core * name = bi to struct _binary_info_core * const name = bi

The other issue is we put "time_critical" code in the data segment to get it into ram?

peterharperuk avatar Nov 23 '22 11:11 peterharperuk

merged into develop

kilograham avatar Jan 17 '23 22:01 kilograham