Repository navigation
Conversation
The linker script CubeMX writes has no .got output section, while the syscalls.c and sysmem.c it generates write errno. In the picolibc of ST Arm Clang errno is thread-local and takes a GOT entry; ld.lld puts that orphan section in RAM with its load address equal to its run address, so the .bin spans Flash up to RAM (about 384 MiB) and the startup copy of .data does not write the linked value into the entry. libxr stm32 cmake, and therefore libxr stm32 setup, now adds a .got output section directly after .fini_array, in the memory region of .fini_array, to every linker script in the project root that has none. It has to follow .fini_array directly: ld.lld keeps the init/fini arrays and the GOT in one RELRO range, and with another output section in between an STARM_NEWLIB link fails with ".got is not contiguous with other relro sections". An existing .got elsewhere only gets a warning and stays as the user wrote it. Line endings and encoding stay as the file has them, and a second run changes nothing.
|
| line_end = code.find("\n", index) | ||
| line_end = len(code) if line_end < 0 else line_end | ||
| return line_end, code[index + 1 : line_end].strip() |
There was a problem hiding this comment.
If .fini_array has its >FLASH clause on the line after }, this code inserts .got between them. The original >FLASH then belongs to .got, leaving .fini_array without its explicit region. Without (READONLY), .fini_array can move to RAM and break the ST Arm Clang link because the arrays and .got no longer sit together. Find the end of the full section, including its region clause, before inserting.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/libxr/stm32_linker_script.py
Line: 89-91
Comment:
**Flash placement moves**
If `.fini_array` has its `>FLASH` clause on the line after `}`, this code inserts `.got` between them. The original `>FLASH` then belongs to `.got`, leaving `.fini_array` without its explicit region. Without `(READONLY)`, `.fini_array` can move to RAM and break the ST Arm Clang link because the arrays and `.got` no longer sit together. Find the end of the full section, including its region clause, before inserting.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.| line_end, region = closing | ||
| block = GOT_SECTION.format(indent=sections[fini].group("indent"), region=region) | ||
| placed = text[:line_end] + "\n\n" + block.rstrip("\n") + text[line_end:] | ||
| path.write_bytes(placed.replace("\n", eol).encode("utf-8", errors="surrogateescape")) |
There was a problem hiding this comment.
If a script contains both LF and CRLF line endings, this write converts every line to CRLF. That changes untouched lines despite the promise to preserve line endings, adding noise to diffs and making merges harder. Preserve the original text around the insertion and apply the chosen ending only to the new block.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/libxr/stm32_linker_script.py
Line: 150
Comment:
**Untouched line endings change**
If a script contains both LF and CRLF line endings, this write converts every line to CRLF. That changes untouched lines despite the promise to preserve line endings, adding noise to diffs and making merges harder. Preserve the original text around the insertion and apply the chosen ending only to the new block.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
Summary
libxr stm32 cmake(and solibxr stm32 setup) now places the GOT of STM32 projects in Flash: every linker script in the project root that has no.gotoutput section gets one directly after.fini_array, in the memory region of.fini_array.Why
The linker script STM32CubeMX 6.18.1 writes has no
.gotoutput section, while thesyscalls.candsysmem.cit generates writeerrno. In the picolibc of ST Arm Clang (STARM_PICOLIBC, the profile CubeMX selects)errnois thread-local and takes one GOT entry. ld.lld puts the orphan.gotin RAM with its load address equal to its run address:.binspans Flash up to RAM (402,653,276 bytes for an STM32F407 project);.datafills the entry from past the end of the load image, so it does not hold the linked TLS offset.The section has to follow
.fini_arraydirectly. ld.lld keeps the init/fini arrays and the GOT in one RELRO range; with another output section in between (a CCM section, for example), anSTARM_NEWLIBlink fails with.got is not contiguous with other relro sections.Behavior
.gotoutput section: one is inserted after.fini_array, with a comment explaining the placement..gotthat does not directly follow.fini_array: a warning; the user's section stays..fini_array, or unbalanced braces: a warning; nothing is changed..gotthat appears only in comments or as an input rule inside.datadoes not count as an output section.New log line of
libxr stm32 setup:Changes
src/libxr/stm32_linker_script.py:place_got()andplace_got_in_project().src/libxr/generator_stm32_cmake.py:integrate()callsplace_got_in_project()after restoringstarm-clang.cmake.tests/test_stm32_linker_script.py: 9 tests.README.md: a paragraph in "CMake and Toolchains" and the new line in thelibxr stm32 setupexample (real output on a fresh CubeMX STM32F103RC project).Verification
python -m unittest discover -s tests: 637 tests pass (the 5 clang-format tests skip without clang-format 21.1.8);ruff format --checkandruff check(0.16.9) are clean.libxr stm32 cmake, built in Release with GCC 14.2 and ST Arm Clang 21.1.1 (STARM_HYBRID,STARM_NEWLIB,STARM_PICOLIBC): all four link. WithSTARM_PICOLIBCthe.bingoes from 402,653,276 to 118,104 bytes, and.gotsits in Flash holding the linked value0x8..gotafter.fini_arraystay byte-identical; a script with.gotafter a CCM section gets the warning.