Make spacer sections allocatable (#2515)
Some checks are pending
Bazel presubmit checks / bazel-build-check (macos-latest) (push) Waiting to run
Bazel presubmit checks / bazel-build-check (ubuntu-latest) (push) Waiting to run
Bazel presubmit checks / other-bazel-checks (push) Waiting to run
Check Configs / check-configs (push) Waiting to run
CMake / build (push) Waiting to run
Build on macOS / build (push) Waiting to run
Build on Windows / build (push) Waiting to run

* Default to allocating spacer sections (stack & heap), with PICO_CRT0_ALLOCATE_SPACERS config option to disable the behaviour

* Add pico_check_linker_script function to check for compatibility of custom linker scripts

* tweak error message

---------

Co-authored-by: Graham Sanderson <graham.sanderson@raspberrypi.com>
This commit is contained in:
will-v-pi 2025-07-17 17:33:23 +01:00 committed by GitHub
parent 968289625b
commit f5e0371ad5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 45 additions and 2 deletions

View file

@ -582,10 +582,16 @@ runtime_init:
// //
// Strictly the most correct thing to do (as .stack and .heap are unreferenced) is to mark them as "a", and also KEEP, which // Strictly the most correct thing to do (as .stack and .heap are unreferenced) is to mark them as "a", and also KEEP, which
// works correctly for both GCC and Clang, however doing so may break anyone who already has custom linker scripts without // works correctly for both GCC and Clang, however doing so may break anyone who already has custom linker scripts without
// the KEEP. Therefore we will only add the "a" on Clang, but will also use KEEP to our own linker scripts. // the KEEP. Therefore we add a define of PICO_CRT0_ALLOCATE_SPACERS to switch between the old and new behaviour, so anyone
// with custom linker scripts without the KEEP can set it to 0 (or update their linker script).
// PICO_CONFIG: PICO_CRT0_ALLOCATE_SPACERS, Set spacer sections as allocatable. This makes them appear in print-memory-usage but is incompatible with linker scripts that do not KEEP the sections, type=bool, default=1, advanced=true, group=pico_crt0
#ifndef PICO_CRT0_ALLOCATE_SPACERS
#define PICO_CRT0_ALLOCATE_SPACERS 1
#endif
.macro spacer_section name .macro spacer_section name
#if PICO_ASSEMBLER_IS_CLANG #if PICO_CRT0_ALLOCATE_SPACERS
.section \name, "a" .section \name, "a"
#else #else
.section \name .section \name

View file

@ -25,11 +25,48 @@ if (NOT TARGET pico_standard_link)
set_target_properties(${TARGET} PROPERTIES ${PROP} "${_LINK_DEPENDS}") set_target_properties(${TARGET} PROPERTIES ${PROP} "${_LINK_DEPENDS}")
endfunction() endfunction()
# pico_check_linker_script(LDSCRIPT)
# \brief_nodesc\ Check the linker script for compatibility
#
# Checks the linker script for compatibility with the current SDK version,
# and if not, raises warnings and enables workarounds to maintain
# compatibility where possible.
#
# \param\ LDSCRIPT Full path to the linker script to check
function(pico_check_linker_script TARGET LDSCRIPT)
if (EXISTS ${LDSCRIPT})
file(READ ${LDSCRIPT} LDSCRIPT_CONTENTS)
else()
return()
endif()
# Check if the linker script uses KEEP to keep the .stack and .heap sections
# and if not, set PICO_CRT0_ALLOCATE_SPACERS to 0 to maintain compatibility
string(FIND "${LDSCRIPT_CONTENTS}" "KEEP(*(.stack*))" KEEP_STACK_FOUND)
string(FIND "${LDSCRIPT_CONTENTS}" "KEEP(*(.heap*))" KEEP_HEAP_FOUND)
string(FIND "${LDSCRIPT_CONTENTS}" "*(.stack*)" STACK_FOUND)
string(FIND "${LDSCRIPT_CONTENTS}" "*(.heap*)" HEAP_FOUND)
set(PICO_CRT0_ALLOCATE_SPACERS TRUE)
if ((${STACK_FOUND} GREATER -1) AND NOT (${KEEP_STACK_FOUND} GREATER -1))
message(WARNING "Linker script ${LDSCRIPT} does not KEEP the .stack section - replace `*(.stack*)` with `KEEP(*(.stack*))`")
set(PICO_CRT0_ALLOCATE_SPACERS FALSE)
endif()
if ((${HEAP_FOUND} GREATER -1) AND NOT (${KEEP_HEAP_FOUND} GREATER -1))
message(WARNING "Linker script ${LDSCRIPT} does not KEEP the .heap section - replace `*(.heap*)` with `KEEP(*(.heap*))`")
set(PICO_CRT0_ALLOCATE_SPACERS FALSE)
endif()
if (NOT ${PICO_CRT0_ALLOCATE_SPACERS})
message(WARNING "Linker script ${LDSCRIPT} is incompatible with certain Pico SDK >2.1.1 features; setting PICO_CRT0_ALLOCATE_SPACERS=0 as a workaround")
target_compile_definitions(${TARGET} PRIVATE PICO_CRT0_ALLOCATE_SPACERS=0)
endif()
endfunction()
# pico_set_linker_script(TARGET LDSCRIPT) # pico_set_linker_script(TARGET LDSCRIPT)
# \brief\ Set the linker script for the target # \brief\ Set the linker script for the target
# #
# \param\ LDSCRIPT Full path to the linker script to set # \param\ LDSCRIPT Full path to the linker script to set
function(pico_set_linker_script TARGET LDSCRIPT) function(pico_set_linker_script TARGET LDSCRIPT)
pico_check_linker_script(${TARGET} ${LDSCRIPT})
set_target_properties(${TARGET} PROPERTIES PICO_TARGET_LINKER_SCRIPT ${LDSCRIPT}) set_target_properties(${TARGET} PROPERTIES PICO_TARGET_LINKER_SCRIPT ${LDSCRIPT})
endfunction() endfunction()