[Concept,08/15] riscv: efi: Exclude PLT relocations from the reloc loop
Commit Message
From: Simon Glass <simon.glass@canonical.com>
GNU ld includes DT_PLTRELSZ in DT_RELASZ, so the EFI self-relocation
code processes R_RISCV_JUMP_SLOT entries from .rela.plt alongside the
expected R_RISCV_RELATIVE entries from .rela.dyn. JUMP_SLOT entries
have a different format and cause incorrect fixups.
Subtract DT_PLTRELSZ from the total relocation size so that only
R_RISCV_RELATIVE entries are processed.
Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---
arch/riscv/lib/reloc_riscv_efi.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
@@ -52,7 +52,7 @@
efi_status_t EFIAPI _relocate(long ldbase, Elf_Dyn *dyn)
{
- long relsz = 0, relent = 0;
+ long relsz = 0, relent = 0, pltrelsz = 0;
Elf_Rela *rel = 0;
unsigned long *addr;
int i;
@@ -68,11 +68,21 @@ efi_status_t EFIAPI _relocate(long ldbase, Elf_Dyn *dyn)
case DT_RELAENT:
relent = dyn[i].d_un.d_val;
break;
+ case DT_PLTRELSZ:
+ pltrelsz = dyn[i].d_un.d_val;
+ break;
default:
break;
}
}
+ /*
+ * GNU ld includes DT_PLTRELSZ in DT_RELASZ. Subtract it so
+ * we only process R_RISCV_RELATIVE entries from .rela.dyn and
+ * do not run into R_RISCV_JUMP_SLOT entries from .rela.plt.
+ */
+ relsz -= pltrelsz;
+
if (!rel && relent == 0)
return EFI_SUCCESS;