[Concept,08/15] riscv: efi: Exclude PLT relocations from the reloc loop

Message ID 20260212001410.1919749-9-sjg@u-boot.org
State New
Headers
Series riscv: Add EFI-application support |

Commit Message

Simon Glass Feb. 12, 2026, 12:13 a.m. UTC
  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(-)
  

Patch

diff --git a/arch/riscv/lib/reloc_riscv_efi.c b/arch/riscv/lib/reloc_riscv_efi.c
index c1039dd165d..da448bfdf96 100644
--- a/arch/riscv/lib/reloc_riscv_efi.c
+++ b/arch/riscv/lib/reloc_riscv_efi.c
@@ -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;