| Message ID | 6ada697cef076eaed1971c4877c402a91ad5cb48.1777550346.git.michal.simek@amd.com |
|---|---|
| State | New |
| Delegated to: | Andes |
| Headers | show |
| Series | riscv: Disable -fpic for SPL builds | expand |
On Thu, Apr 30, 2026 at 01:59:07PM +0200, Michal Simek wrote: > When building U-Boot SPL for RISC-V with position-independent code > (-fpic), the linker fails with relocation errors like: > > relocation truncated to fit: R_RISCV_PCREL_HI20 against `symbol' > > This occurs because SPL's linker script places .bss in a separate > memory region (.bss_mem) from .text/.data (.spl_mem). With -fpic, > accessing global variables uses PC-relative GOT addressing, which > fails when the distance between code and data exceeds the 20-bit > signed offset limit of R_RISCV_PCREL_HI20. > > The main U-Boot binary requires -fpic for runtime relocation support, > but SPL runs from a fixed address and doesn't need position-independent > code. Disable -fpic for SPL builds while keeping it enabled for the > main U-Boot image. > > spl/u-boot-spl: all -1187 bss +4 data -2631 rodata +2440 text -1000 > > Signed-off-by: Michal Simek <michal.simek@amd.com> I've sent a similar patch[1] to fix issues caused by GOT addressing when building RISC-V ports with LLD, and got feedback that without -fpic CONFIG_SPL_RELOC_LOADER might break, but don't have the time to investigate it further. Maybe we should coordinate on this. I'll take a look on CONFIG_SPL_RELOC_LOADER first. Thanks, Yao Zi [1]: https://lore.kernel.org/u-boot/20251215172236.52710-2-me@ziyao.cc/
On Thu, Apr 30, 2026 at 01:59:07PM +0200, Michal Simek wrote: > When building U-Boot SPL for RISC-V with position-independent code > (-fpic), the linker fails with relocation errors like: > > relocation truncated to fit: R_RISCV_PCREL_HI20 against `symbol' > > This occurs because SPL's linker script places .bss in a separate > memory region (.bss_mem) from .text/.data (.spl_mem). With -fpic, > accessing global variables uses PC-relative GOT addressing, which > fails when the distance between code and data exceeds the 20-bit > signed offset limit of R_RISCV_PCREL_HI20. This sounds strange. R_RISCV_GOT_HI20 instead of R_RISCV_PCREL_HI20 should be used when addressing a variable through GOT in code. Thus I suspect in your case, the compiler decides to address the .bss variable PC-relatively, bypassing the GOT, possibly because it's static thus considered non-preemptible. Might you provide a reproducer for the problem so we could dig it further and confirm the root cause? Best regards, Yao Zi > The main U-Boot binary requires -fpic for runtime relocation support, > but SPL runs from a fixed address and doesn't need position-independent > code. Disable -fpic for SPL builds while keeping it enabled for the > main U-Boot image. > > spl/u-boot-spl: all -1187 bss +4 data -2631 rodata +2440 text -1000 > > Signed-off-by: Michal Simek <michal.simek@amd.com>
On 5/1/26 12:41, Yao Zi wrote: > On Thu, Apr 30, 2026 at 01:59:07PM +0200, Michal Simek wrote: >> When building U-Boot SPL for RISC-V with position-independent code >> (-fpic), the linker fails with relocation errors like: >> >> relocation truncated to fit: R_RISCV_PCREL_HI20 against `symbol' >> >> This occurs because SPL's linker script places .bss in a separate >> memory region (.bss_mem) from .text/.data (.spl_mem). With -fpic, >> accessing global variables uses PC-relative GOT addressing, which >> fails when the distance between code and data exceeds the 20-bit >> signed offset limit of R_RISCV_PCREL_HI20. >> >> The main U-Boot binary requires -fpic for runtime relocation support, >> but SPL runs from a fixed address and doesn't need position-independent >> code. Disable -fpic for SPL builds while keeping it enabled for the >> main U-Boot image. >> >> spl/u-boot-spl: all -1187 bss +4 data -2631 rodata +2440 text -1000 >> >> Signed-off-by: Michal Simek <michal.simek@amd.com> > > I've sent a similar patch[1] to fix issues caused by GOT addressing when > building RISC-V ports with LLD, and got feedback that without -fpic > CONFIG_SPL_RELOC_LOADER might break, but don't have the time to > investigate it further. > > Maybe we should coordinate on this. I'll take a look on > CONFIG_SPL_RELOC_LOADER first. Thanks for pointer. I understand Heinrich's point and no issue with it. But I expect this feature is something what should be enabled (or should be possible to disable it). We need to stay with SPL below 64k limit and relocation is adding too much overhead for nothing for us. Would be good if you can find some time to look at RELOC_LOADER and please keep me in a loop. Thanks, Michal
diff --git a/arch/riscv/config.mk b/arch/riscv/config.mk index eddd6a3b9a29..b1cfb25e7ea3 100644 --- a/arch/riscv/config.mk +++ b/arch/riscv/config.mk @@ -35,7 +35,7 @@ EFI_LDS := elf_riscv64_efi.lds PLATFORM_ELFFLAGS += -B riscv -O elf64-$(large-endian)riscv endif -PLATFORM_CPPFLAGS += -ffixed-x3 -fpic +PLATFORM_CPPFLAGS += -ffixed-x3 $(if $(CONFIG_XPL_BUILD),,-fpic) PLATFORM_RELFLAGS += -fno-common -ffunction-sections -fdata-sections LDFLAGS_u-boot += --gc-sections -static -pie
When building U-Boot SPL for RISC-V with position-independent code (-fpic), the linker fails with relocation errors like: relocation truncated to fit: R_RISCV_PCREL_HI20 against `symbol' This occurs because SPL's linker script places .bss in a separate memory region (.bss_mem) from .text/.data (.spl_mem). With -fpic, accessing global variables uses PC-relative GOT addressing, which fails when the distance between code and data exceeds the 20-bit signed offset limit of R_RISCV_PCREL_HI20. The main U-Boot binary requires -fpic for runtime relocation support, but SPL runs from a fixed address and doesn't need position-independent code. Disable -fpic for SPL builds while keeping it enabled for the main U-Boot image. spl/u-boot-spl: all -1187 bss +4 data -2631 rodata +2440 text -1000 Signed-off-by: Michal Simek <michal.simek@amd.com> --- arch/riscv/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)