boards/rp23xx: copy .got into RAM at boot in the memmap linker scripts

The pico-sdk-derived rp23xx linker scripts place .got/.got.plt as orphan
sections after the .data output section, so the boot-time .data copy
(which runs to _edata) never copies the GOT into RAM.  Any position-
independent (-fPIC) object linked into an application then reads an
uninitialised GOT full of NULLs: the first GOT-indirected access
branches to 0 and the board hardfaults before main().  A PIC static
library (for example liboqs, whose SHA3 dispatch reads its function
pointers through the GOT) triggers this deterministically.

Fold *(.got)/*(.got.plt) into the .data{} section, before _edata, in all
three boot-mode scripts (memmap_default/copy_to_ram/no_flash) for every
rp23xx board, so the GOT is initialised in RAM by the standard startup
copy.  No effect on non-PIC images (the GOT is empty).

Reproduced and fixed on a Raspberry Pi Pico 2 W: an app linking a -fPIC
liboqs.a wedged the board on its first crypto call before the change and
runs correctly after it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Ricard Rosson <ricard@groundbits.com>
This commit is contained in:
Ricard Rosson 2026-07-11 12:26:06 +01:00 committed by Alan C. Assis
parent d8d77c249c
commit 05df45dfee
9 changed files with 90 additions and 0 deletions

View file

@ -184,6 +184,16 @@ SECTIONS
*(.data*)
*(.sdata*)
/* GOT/PLT must live INSIDE the copied .data range so a flat
* -fPIC object (e.g. a PIC static library linked into an app)
* gets an initialised GOT in RAM at boot; otherwise an orphan
* .got lands after _edata, is never copied, and every GOT-
* indirected access reads a NULL pointer (hardfault). */
. = ALIGN(4);
*(.got)
*(.got.plt)
*(.got*)
. = ALIGN(4);
*(.after_data.*)
. = ALIGN(4);

View file

@ -211,6 +211,16 @@ SECTIONS
*(.data*)
*(.sdata*)
/* GOT/PLT must live INSIDE the copied .data range so a flat
* -fPIC object (e.g. a PIC static library linked into an app)
* gets an initialised GOT in RAM at boot; otherwise an orphan
* .got lands after _edata, is never copied, and every GOT-
* indirected access reads a NULL pointer (hardfault). */
. = ALIGN(4);
*(.got)
*(.got.plt)
*(.got*)
. = ALIGN(4);
*(.after_data.*)
. = ALIGN(4);

View file

@ -133,6 +133,16 @@ SECTIONS
*(.data*)
*(.sdata*)
/* GOT/PLT must live INSIDE the copied .data range so a flat
* -fPIC object (e.g. a PIC static library linked into an app)
* gets an initialised GOT in RAM at boot; otherwise an orphan
* .got lands after _edata, is never copied, and every GOT-
* indirected access reads a NULL pointer (hardfault). */
. = ALIGN(4);
*(.got)
*(.got.plt)
*(.got*)
. = ALIGN(4);
*(.after_data.*)
. = ALIGN(4);

View file

@ -184,6 +184,16 @@ SECTIONS
*(.data*)
*(.sdata*)
/* GOT/PLT must live INSIDE the copied .data range so a flat
* -fPIC object (e.g. a PIC static library linked into an app)
* gets an initialised GOT in RAM at boot; otherwise an orphan
* .got lands after _edata, is never copied, and every GOT-
* indirected access reads a NULL pointer (hardfault). */
. = ALIGN(4);
*(.got)
*(.got.plt)
*(.got*)
. = ALIGN(4);
*(.after_data.*)
. = ALIGN(4);

View file

@ -211,6 +211,16 @@ SECTIONS
*(.data*)
*(.sdata*)
/* GOT/PLT must live INSIDE the copied .data range so a flat
* -fPIC object (e.g. a PIC static library linked into an app)
* gets an initialised GOT in RAM at boot; otherwise an orphan
* .got lands after _edata, is never copied, and every GOT-
* indirected access reads a NULL pointer (hardfault). */
. = ALIGN(4);
*(.got)
*(.got.plt)
*(.got*)
. = ALIGN(4);
*(.after_data.*)
. = ALIGN(4);

View file

@ -133,6 +133,16 @@ SECTIONS
*(.data*)
*(.sdata*)
/* GOT/PLT must live INSIDE the copied .data range so a flat
* -fPIC object (e.g. a PIC static library linked into an app)
* gets an initialised GOT in RAM at boot; otherwise an orphan
* .got lands after _edata, is never copied, and every GOT-
* indirected access reads a NULL pointer (hardfault). */
. = ALIGN(4);
*(.got)
*(.got.plt)
*(.got*)
. = ALIGN(4);
*(.after_data.*)
. = ALIGN(4);

View file

@ -184,6 +184,16 @@ SECTIONS
*(.data*)
*(.sdata*)
/* GOT/PLT must live INSIDE the copied .data range so a flat
* -fPIC object (e.g. a PIC static library linked into an app)
* gets an initialised GOT in RAM at boot; otherwise an orphan
* .got lands after _edata, is never copied, and every GOT-
* indirected access reads a NULL pointer (hardfault). */
. = ALIGN(4);
*(.got)
*(.got.plt)
*(.got*)
. = ALIGN(4);
*(.after_data.*)
. = ALIGN(4);

View file

@ -211,6 +211,16 @@ SECTIONS
*(.data*)
*(.sdata*)
/* GOT/PLT must live INSIDE the copied .data range so a flat
* -fPIC object (e.g. a PIC static library linked into an app)
* gets an initialised GOT in RAM at boot; otherwise an orphan
* .got lands after _edata, is never copied, and every GOT-
* indirected access reads a NULL pointer (hardfault). */
. = ALIGN(4);
*(.got)
*(.got.plt)
*(.got*)
. = ALIGN(4);
*(.after_data.*)
. = ALIGN(4);

View file

@ -133,6 +133,16 @@ SECTIONS
*(.data*)
*(.sdata*)
/* GOT/PLT must live INSIDE the copied .data range so a flat
* -fPIC object (e.g. a PIC static library linked into an app)
* gets an initialised GOT in RAM at boot; otherwise an orphan
* .got lands after _edata, is never copied, and every GOT-
* indirected access reads a NULL pointer (hardfault). */
. = ALIGN(4);
*(.got)
*(.got.plt)
*(.got*)
. = ALIGN(4);
*(.after_data.*)
. = ALIGN(4);