[PATCH] firmware: payload: test: Relocate GOT entries before calling C code

Anup Patel anup at brainfault.org
Mon Sep 28 06:34:15 PDT 2026


On Fri, Aug 21, 2026 at 3:43 PM Alvin Chang <alvinga at andestech.com> wrote:
>
> The test payload is linked as a PIE but, unlike fw_base.S, its startup
> code never processed its own dynamic relocations. Nothing in the payload
> needed a GOT so far, so this went unnoticed.
>
> CONFIG_STACK_PROTECTOR_ALL=y changes that. GCC derives the
> __stack_chk_guard reference from an artificial declaration with default
> visibility, so under -fPIE it always loads the guard address through the
> GOT. The linker zeroes that entry and records an R_RISCV_RELATIVE
> relocation instead, which nobody applies. test_main() then reads the
> canary from a NULL pointer before the first sbi_ecall_console_puts(), so
> the payload hangs silently right after the OpenSBI boot banner. The other
> two configurations emit no canary in the payload, leaving .rela.dyn
> empty, which is why only this one breaks.
>
> Keep .rela.dyn in the payload image and apply the R_RISCV_RELATIVE
> entries at the top of _start, reusing the code from fw_base.S. The loop
> is skipped when .rela.dyn is empty.
>
> Fixes: edfbc1285dd9 ("firmware: Initial compiler built-in stack protector support")
> Reported-by: Anup Patel <anup at brainfault.org>
> Signed-off-by: Alvin Chang <alvinga at andestech.com>

LGTM.

Reviewed-by: Anup Patel <anup at brainfault.org>

Applied this patch to the riscv/opensbi repo.

Thanks,
Anup

> ---
>  firmware/payloads/test.elf.ldS |  6 ++++++
>  firmware/payloads/test_head.S  | 30 ++++++++++++++++++++++++++++++
>  2 files changed, 36 insertions(+)
>
> diff --git a/firmware/payloads/test.elf.ldS b/firmware/payloads/test.elf.ldS
> index 2328a1b7..6632c132 100644
> --- a/firmware/payloads/test.elf.ldS
> +++ b/firmware/payloads/test.elf.ldS
> @@ -47,6 +47,12 @@ SECTIONS
>                 PROVIDE(_rodata_end = .);
>         }
>
> +       .rela.dyn : {
> +               PROVIDE(__rela_dyn_start = .);
> +               *(.rela*)
> +               PROVIDE(__rela_dyn_end = .);
> +       }
> +
>         /* End of the read-only data sections */
>
>         . = ALIGN(0x1000); /* Ensure next section is page aligned */
> diff --git a/firmware/payloads/test_head.S b/firmware/payloads/test_head.S
> index e4fcaaca..09d0ad18 100644
> --- a/firmware/payloads/test_head.S
> +++ b/firmware/payloads/test_head.S
> @@ -7,6 +7,7 @@
>   *   Anup Patel <anup.patel at wdc.com>
>   */
>
> +#include <sbi/riscv_elf.h>
>  #include <sbi/riscv_encoding.h>
>  #define __ASM_STR(x)   x
>
> @@ -24,6 +25,13 @@
>  #define REG_S          __REG_SEL(sd, sw)
>  #define REG_ADDW       __REG_SEL(addw, add)
>
> +/* Link time address of _payload_start, see test.elf.ldS */
> +#ifdef FW_PAYLOAD_OFFSET
> +#define PAYLOAD_LINK_START     (FW_TEXT_START + FW_PAYLOAD_OFFSET)
> +#else
> +#define PAYLOAD_LINK_START     0
> +#endif
> +
>         .section .entry, "ax", %progbits
>         .align 3
>         .globl _start
> @@ -45,6 +53,28 @@ _sc_fail:
>  #endif
>         bnez    a3, _start_hang
>
> +       /* relocate the global table content */
> +       li      t0, PAYLOAD_LINK_START  /* link start */
> +       lla     t1, _payload_start      /* load start */
> +       sub     t2, t1, t0              /* load offset */
> +       lla     t0, __rela_dyn_start
> +       lla     t1, __rela_dyn_end
> +       beq     t0, t1, _relocate_done
> +2:
> +       REG_L   t5, __SIZEOF_LONG__(t0) /* t5 <-- relocation info:type */
> +       li      t3, R_RISCV_RELATIVE    /* reloc type R_RISCV_RELATIVE */
> +       bne     t5, t3, 3f
> +       REG_L   t3, 0(t0)
> +       REG_L   t5, (__SIZEOF_LONG__ * 2)(t0)   /* t5 <-- addend */
> +       add     t5, t5, t2
> +       add     t3, t3, t2
> +       REG_S   t5, 0(t3)               /* store runtime address to the GOT entry */
> +
> +3:
> +       addi    t0, t0, (__SIZEOF_LONG__ * 3)
> +       blt     t0, t1, 2b
> +_relocate_done:
> +
>         /* Save a0 and a1 */
>         lla     a3, _boot_a0
>         REG_S   a0, 0(a3)
> --
> 2.43.0
>



More information about the opensbi mailing list