git: b2b3d2a962eb - main - rtld-elf: move powerpc-specific auxv compat code into arch hook

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Fri, 21 Nov 2025 13:33:59 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=b2b3d2a962eb00005641546fbe672b95e5d0672a

commit b2b3d2a962eb00005641546fbe672b95e5d0672a
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-11-18 11:06:04 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-11-21 13:33:17 +0000

    rtld-elf: move powerpc-specific auxv compat code into arch hook
    
    Tested by:      Timothy Pearson (tpearson_raptorengineering.com)
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D53801
---
 libexec/rtld-elf/aarch64/rtld_machdep.h   |  2 ++
 libexec/rtld-elf/amd64/rtld_machdep.h     |  2 ++
 libexec/rtld-elf/arm/rtld_machdep.h       |  2 ++
 libexec/rtld-elf/i386/rtld_machdep.h      |  2 ++
 libexec/rtld-elf/powerpc/reloc.c          | 26 ++++++++++++++++++++++++++
 libexec/rtld-elf/powerpc/rtld_machdep.h   |  2 ++
 libexec/rtld-elf/powerpc64/reloc.c        | 26 ++++++++++++++++++++++++++
 libexec/rtld-elf/powerpc64/rtld_machdep.h |  2 ++
 libexec/rtld-elf/riscv/rtld_machdep.h     |  2 ++
 libexec/rtld-elf/rtld.c                   | 25 +------------------------
 10 files changed, 67 insertions(+), 24 deletions(-)

diff --git a/libexec/rtld-elf/aarch64/rtld_machdep.h b/libexec/rtld-elf/aarch64/rtld_machdep.h
index 3cc1339fcad4..d689ae354c49 100644
--- a/libexec/rtld-elf/aarch64/rtld_machdep.h
+++ b/libexec/rtld-elf/aarch64/rtld_machdep.h
@@ -52,6 +52,8 @@ bool arch_digest_dynamic(struct Struct_Obj_Entry *obj, const Elf_Dyn *dynp);
 
 bool arch_digest_note(struct Struct_Obj_Entry *obj, const Elf_Note *note);
 
+#define	arch_fix_auxv(a, ai)		do {} while (0)
+
 Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
     const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
     const Elf_Rel *rel);
diff --git a/libexec/rtld-elf/amd64/rtld_machdep.h b/libexec/rtld-elf/amd64/rtld_machdep.h
index 1797d13c847d..2ee63d566bed 100644
--- a/libexec/rtld-elf/amd64/rtld_machdep.h
+++ b/libexec/rtld-elf/amd64/rtld_machdep.h
@@ -47,6 +47,8 @@ Elf_Dyn *rtld_dynamic_addr(void);
 /* No architecture specific notes */
 #define	arch_digest_note(obj, note)	false
 
+#define	arch_fix_auxv(a, ai)		do {} while (0)
+
 Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
     const struct Struct_Obj_Entry *obj, const struct Struct_Obj_Entry *refobj,
     const Elf_Rel *rel);
diff --git a/libexec/rtld-elf/arm/rtld_machdep.h b/libexec/rtld-elf/arm/rtld_machdep.h
index f59b30028a3b..88fa18a0c07a 100644
--- a/libexec/rtld-elf/arm/rtld_machdep.h
+++ b/libexec/rtld-elf/arm/rtld_machdep.h
@@ -47,6 +47,8 @@ struct Struct_Obj_Entry;
 /* No architecture specific notes */
 #define	arch_digest_note(obj, note)	false
 
+#define	arch_fix_auxv(a, ai)		do {} while (0)
+
 Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
     const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
     const Elf_Rel *rel);
diff --git a/libexec/rtld-elf/i386/rtld_machdep.h b/libexec/rtld-elf/i386/rtld_machdep.h
index 581f1dfb002d..079991f913d6 100644
--- a/libexec/rtld-elf/i386/rtld_machdep.h
+++ b/libexec/rtld-elf/i386/rtld_machdep.h
@@ -60,6 +60,8 @@ Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
 #define call_init_pointer(obj, target) \
 	(((InitArrFunc)(target))(main_argc, main_argv, environ))
 
+#define	arch_fix_auxv(a, ai)		do {} while (0)
+
 extern uint32_t cpu_feature;
 extern uint32_t cpu_feature2;
 extern uint32_t cpu_stdext_feature;
diff --git a/libexec/rtld-elf/powerpc/reloc.c b/libexec/rtld-elf/powerpc/reloc.c
index 8932c2c21278..a38cadfe76ba 100644
--- a/libexec/rtld-elf/powerpc/reloc.c
+++ b/libexec/rtld-elf/powerpc/reloc.c
@@ -840,3 +840,29 @@ __tls_get_addr(tls_index* ti)
 	return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset +
 	    TLS_DTV_OFFSET));
 }
+
+void
+arch_fix_auxv(Elf_Auxinfo *aux, Elf_Auxinfo *aux_info[])
+{
+	Elf_Auxinfo *aux;
+	bool old_auxv_format;
+
+	old_auxv_format = true;
+	for (auxp = aux; auxp->a_type != AT_NULL; auxp++) {
+		if (auxp->a_type == 23) /* AT_STACKPROT */
+			return;
+	}
+
+	/* Remap from old-style auxv numbers. */
+	aux_info[23] = aux_info[21]; /* AT_STACKPROT */
+	aux_info[21] = aux_info[19]; /* AT_PAGESIZESLEN */
+	aux_info[19] = aux_info[17]; /* AT_NCPUS */
+	aux_info[17] = aux_info[15]; /* AT_CANARYLEN */
+	aux_info[15] = aux_info[13]; /* AT_EXECPATH */
+	aux_info[13] = NULL;	     /* AT_GID */
+
+	aux_info[20] = aux_info[18]; /* AT_PAGESIZES */
+	aux_info[18] = aux_info[16]; /* AT_OSRELDATE */
+	aux_info[16] = aux_info[14]; /* AT_CANARY */
+	aux_info[14] = NULL;	     /* AT_EGID */
+}
diff --git a/libexec/rtld-elf/powerpc/rtld_machdep.h b/libexec/rtld-elf/powerpc/rtld_machdep.h
index ec470f238991..de6a894ac1f5 100644
--- a/libexec/rtld-elf/powerpc/rtld_machdep.h
+++ b/libexec/rtld-elf/powerpc/rtld_machdep.h
@@ -46,6 +46,8 @@ bool arch_digest_dynamic(struct Struct_Obj_Entry *, const Elf_Dyn *);
 /* No architecture specific notes */
 #define	arch_digest_note(obj, note)	false
 
+void arch_fix_auxv(Elf_Auxinfo *aux, Elf_Auxinfo *aux_info[]);
+
 Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
     const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
     const Elf_Rel *rel);
diff --git a/libexec/rtld-elf/powerpc64/reloc.c b/libexec/rtld-elf/powerpc64/reloc.c
index 9ea14f63b5c7..29c52d8fc19f 100644
--- a/libexec/rtld-elf/powerpc64/reloc.c
+++ b/libexec/rtld-elf/powerpc64/reloc.c
@@ -737,3 +737,29 @@ __tls_get_addr(tls_index* ti)
 	return (tls_get_addr_common(_tcb_get(), ti->ti_module, ti->ti_offset +
 	    TLS_DTV_OFFSET));
 }
+
+void
+arch_fix_auxv(Elf_Auxinfo *aux, Elf_Auxinfo *aux_info[])
+{
+	Elf_Auxinfo *aux;
+	bool old_auxv_format;
+
+	old_auxv_format = true;
+	for (auxp = aux; auxp->a_type != AT_NULL; auxp++) {
+		if (auxp->a_type == 23) /* AT_STACKPROT */
+			return;
+	}
+
+	/* Remap from old-style auxv numbers. */
+	aux_info[23] = aux_info[21]; /* AT_STACKPROT */
+	aux_info[21] = aux_info[19]; /* AT_PAGESIZESLEN */
+	aux_info[19] = aux_info[17]; /* AT_NCPUS */
+	aux_info[17] = aux_info[15]; /* AT_CANARYLEN */
+	aux_info[15] = aux_info[13]; /* AT_EXECPATH */
+	aux_info[13] = NULL;	     /* AT_GID */
+
+	aux_info[20] = aux_info[18]; /* AT_PAGESIZES */
+	aux_info[18] = aux_info[16]; /* AT_OSRELDATE */
+	aux_info[16] = aux_info[14]; /* AT_CANARY */
+	aux_info[14] = NULL;	     /* AT_EGID */
+}
diff --git a/libexec/rtld-elf/powerpc64/rtld_machdep.h b/libexec/rtld-elf/powerpc64/rtld_machdep.h
index d628e776bae9..06eb6d884101 100644
--- a/libexec/rtld-elf/powerpc64/rtld_machdep.h
+++ b/libexec/rtld-elf/powerpc64/rtld_machdep.h
@@ -46,6 +46,8 @@ bool arch_digest_dynamic(struct Struct_Obj_Entry *, const Elf_Dyn *);
 /* No architecture specific notes */
 #define	arch_digest_note(obj, note)	false
 
+void arch_fix_auxv(Elf_Auxinfo *aux, Elf_Auxinfo *aux_info[]);
+
 Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
     const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
     const Elf_Rel *rel);
diff --git a/libexec/rtld-elf/riscv/rtld_machdep.h b/libexec/rtld-elf/riscv/rtld_machdep.h
index c6600b583612..1f4fe2e928fe 100644
--- a/libexec/rtld-elf/riscv/rtld_machdep.h
+++ b/libexec/rtld-elf/riscv/rtld_machdep.h
@@ -60,6 +60,8 @@ uint64_t set_gp(struct Struct_Obj_Entry *obj);
 /* No architecture specific notes */
 #define	arch_digest_note(obj, note)	false
 
+#define	arch_fix_auxv(a, ai)		do {} while (0)
+
 Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
     const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
     const Elf_Rel *rel);
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index d27af520c21d..bdfff7361e96 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -521,9 +521,6 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
 	char buf[MAXPATHLEN];
 	int argc, fd, i, mib[4], old_osrel, osrel, phnum, rtld_argc;
 	size_t sz;
-#ifdef __powerpc__
-	int old_auxv_format = 1;
-#endif
 	bool dir_enable, dir_ignore, direct_exec, explicit_fd, search_in_path;
 
 	/*
@@ -549,28 +546,8 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
 	for (auxp = aux; auxp->a_type != AT_NULL; auxp++) {
 		if (auxp->a_type < AT_COUNT)
 			aux_info[auxp->a_type] = auxp;
-#ifdef __powerpc__
-		if (auxp->a_type == 23) /* AT_STACKPROT */
-			old_auxv_format = 0;
-#endif
-	}
-
-#ifdef __powerpc__
-	if (old_auxv_format) {
-		/* Remap from old-style auxv numbers. */
-		aux_info[23] = aux_info[21]; /* AT_STACKPROT */
-		aux_info[21] = aux_info[19]; /* AT_PAGESIZESLEN */
-		aux_info[19] = aux_info[17]; /* AT_NCPUS */
-		aux_info[17] = aux_info[15]; /* AT_CANARYLEN */
-		aux_info[15] = aux_info[13]; /* AT_EXECPATH */
-		aux_info[13] = NULL;	     /* AT_GID */
-
-		aux_info[20] = aux_info[18]; /* AT_PAGESIZES */
-		aux_info[18] = aux_info[16]; /* AT_OSRELDATE */
-		aux_info[16] = aux_info[14]; /* AT_CANARY */
-		aux_info[14] = NULL;	     /* AT_EGID */
 	}
-#endif
+	arch_fix_auxv(aux, aux_info);
 
 	/* Initialize and relocate ourselves. */
 	assert(aux_info[AT_BASE] != NULL);