linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: Linus Torvalds <torvalds@transmeta.com>
Cc: Kernel Mailing List <linux-kernel@vger.kernel.org>,
	<linuxppc-dev@lists.linuxppc.org>,
	Alan Cox <alan@lxorguk.ukuu.org.uk>, <paulus@samba.org>,
	<cort@fsmlabs.com>
Subject: [PATCH] binfmt_elf.c fix with PPC update
Date: Wed, 11 Apr 2001 22:51:40 +0200	[thread overview]
Message-ID: <20010411205140.17398@mailhost.mipsys.com> (raw)

Hi Linus !

Enclosed is a (not big ;) patch against 2.4.4pre1 that does a few
inter-dependant things, one beeing a bug fix for everybody, the other
is a mix of bug fix & cleanup on PPC:

 - binfmt_elf.c : fix DLINFO_ITEMS so that final alignement on the
   stack takes into account the AT_NULL entry (or it won't align).

   Remove hackish PPC addition (now re-done properly). Add a simple
   way (via 2 macros) for include/asm-xxx/elf.h to add platform
   specific entries to it while keeping the alignement right.

 - Remove shove_aux_table() in arch/ppc/kernel/process.c. That routine
   used to lookup the aux table on the stack and move it up to align
   it to a 16 bytes boundary (ABI). Now done via the ARCH_DLINFO in
   include/asm-ppc/elf.h

 - Re-implement the alignement mecanism properly, taking into account
   a pair glibc bugs we had until now (not doing so results in breaking
   existing userland binaries).

 - Add 3 new aux table entries for PPC containing some cache line size
   information. Those are part of our PPC SysV ABI, and were never
   properly implemented, possibly because of conflict in the AT_xxxx
   numbers assigned to them. This was now "fixed" and the next glibc
   release will understand them. Those informations are necessary for
   glibc to properly handle various brands of PPC CPUs when doing
   cache invalidates or using cache trick to speed up copy operations.

The patch has been tested on PPC, glibc is ready for it, and it's
simple enough not to damage other archs. Next are coming the PPC
AT_HWCAP infos, still beeing worked on.

Feel free to comment, not agree, whatever, I'd be glad however if you
could explain me if you don't want to merge that now as our glibc
maintainer is waiting for it ;)

Regards,
Ben.

--- linuxppc_2_4_orig/fs/binfmt_elf.c	Wed Apr 11 20:18:59 2001
+++ linuxppc_2_4/fs/binfmt_elf.c	Wed Apr 11 18:38:47 2001
@@ -36,7 +36,7 @@
 #include <asm/param.h>
 #include <asm/pgalloc.h>
 
-#define DLINFO_ITEMS 13
+#define DLINFO_ITEMS 14
 
 #include <linux/elf.h>
 
@@ -135,12 +135,13 @@
 
 	/*
 	 * Force 16 byte _final_ alignment here for generality.
-	 * Leave an extra 16 bytes free so that on the PowerPC we
-	 * can move the aux table up to start on a 16-byte boundary.
 	 */
-	sp = (elf_addr_t *)((~15UL & (unsigned long)(u_platform)) - 16UL);
+	sp = (elf_addr_t *)(~15UL & (unsigned long)(u_platform));
 	csp = sp;
 	csp -= DLINFO_ITEMS*2 + (k_platform ? 2 : 0);
+#ifdef DLINFO_ARCH_ITEMS
+	csp -= DLINFO_ARCH_ITEMS*2;
+#endif
 	csp -= envc+1;
 	csp -= argc+1;
 	csp -= (!ibcs ? 3 : 1);	/* argc itself */
@@ -174,6 +175,13 @@
 	NEW_AUX_ENT(10, AT_EUID, (elf_addr_t) current->euid);
 	NEW_AUX_ENT(11, AT_GID, (elf_addr_t) current->gid);
 	NEW_AUX_ENT(12, AT_EGID, (elf_addr_t) current->egid);
+#ifdef ARCH_DLINFO
+	/* 
+	 * ARCH_DLINFO must come last so platform specific code can enforce
+	 * special alignment requirements on the AUXV if necessary (eg. PPC).
+	 */
+	ARCH_DLINFO;
+#endif
 #undef NEW_AUX_ENT
 
 	sp -= envc+1;
--- linuxppc_2_4_orig/arch/ppc/kernel/process.c	Mon Apr  2 19:25:35 2001
+++ linuxppc_2_4/arch/ppc/kernel/process.c	Wed Apr 11 18:40:51 2001
@@ -378,45 +378,6 @@
 }
 
 /*
- * XXX ld.so expects the auxiliary table to start on
- * a 16-byte boundary, so we have to find it and
- * move it up. :-(
- */
-static inline void shove_aux_table(unsigned long sp)
-{
-	int argc;
-	char *p;
-	unsigned long e;
-	unsigned long aux_start, offset;
-
-	if (__get_user(argc, (int *)sp))
-		return;
-	sp += sizeof(int) + (argc + 1) * sizeof(char *);
-	/* skip over the environment pointers */
-	do {
-		if (__get_user(p, (char **)sp))
-			return;
-		sp += sizeof(char *);
-	} while (p != NULL);
-	aux_start = sp;
-	/* skip to the end of the auxiliary table */
-	do {
-		if (__get_user(e, (unsigned long *)sp))
-			return;
-		sp += 2 * sizeof(unsigned long);
-	} while (e != AT_NULL);
-	offset = ((aux_start + 15) & ~15) - aux_start;
-	if (offset != 0) {
-		do {
-			sp -= sizeof(unsigned long);
-			if (__get_user(e, (unsigned long *)sp)
-			    || __put_user(e, (unsigned long *)(sp + offset)))
-				return;
-		} while (sp > aux_start);
-	}
-}
-
-/*
  * Set up a thread for executing a new program
  */
 void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp)
@@ -425,7 +386,6 @@
 	regs->nip = nip;
 	regs->gpr[1] = sp;
 	regs->msr = MSR_USER;
-	shove_aux_table(sp);
 	if (last_task_used_math == current)
 		last_task_used_math = 0;
 	if (last_task_used_altivec == current)
--- linuxppc_2_4_orig/include/asm-ppc/elf.h	Mon Apr  2 19:24:39 2001
+++ linuxppc_2_4/include/asm-ppc/elf.h	Wed Apr 11 21:25:00 2001
@@ -74,20 +74,46 @@
  * We need to put in some extra aux table entries to tell glibc what
  * the cache block size is, so it can use the dcbz instruction safely.
  */
-#define AT_DCACHEBSIZE		17
-#define AT_ICACHEBSIZE		18
-#define AT_UCACHEBSIZE		19
+#define AT_DCACHEBSIZE		19
+#define AT_ICACHEBSIZE		20
+#define AT_UCACHEBSIZE		21
+/* A special ignored type value for PPC, for glibc compatibility.  */
+#define AT_IGNOREPPC		22
 
 extern int dcache_bsize;
 extern int icache_bsize;
 extern int ucache_bsize;
 
-#define DLINFO_EXTRA_ITEMS	3
-#define EXTRA_DLINFO		do {			\
-	NEW_AUX_ENT(0, AT_DCACHEBSIZE, dcache_bsize);	\
-	NEW_AUX_ENT(1, AT_ICACHEBSIZE, icache_bsize);	\
-	NEW_AUX_ENT(2, AT_UCACHEBSIZE, ucache_bsize);	\
-} while (0)
+/*
+ * The requirements here are:
+ * - keep the final alignment of sp (sp & 0xf)
+ * - make sure the 32-bit value at the first 16 byte aligned position of
+ *   AUXV is greater than 16 for glibc compatibility.
+ *   AT_IGNOREPPC is used for that.
+ * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
+ *   even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
+ */
+#define DLINFO_ARCH_ITEMS	3
+#define ARCH_DLINFO							\
+do {									\
+	sp -= DLINFO_ARCH_ITEMS * 2;					\
+	NEW_AUX_ENT(0, AT_DCACHEBSIZE, dcache_bsize);			\
+	NEW_AUX_ENT(1, AT_ICACHEBSIZE, icache_bsize);			\
+	NEW_AUX_ENT(2, AT_UCACHEBSIZE, ucache_bsize);			\
+	/*								\
+	 * Keep the final alignment of sp.				\
+	 */								\
+	if (DLINFO_ARCH_ITEMS & 1) {					\
+		sp -= 2;						\
+		NEW_AUX_ENT(0, AT_IGNOREPPC, AT_IGNOREPPC);		\
+	}								\
+	/*								\
+	 * Now handle glibc compatibility.				\
+	 */								\
+	sp -= 2*2;							\
+	NEW_AUX_ENT(0, AT_IGNOREPPC, AT_IGNOREPPC);			\
+	NEW_AUX_ENT(1, AT_IGNOREPPC, AT_IGNOREPPC);			\
+ } while (0)
 
 #endif /* __KERNEL__ */
 #endif




                 reply	other threads:[~2001-04-11 19:52 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20010411205140.17398@mailhost.mipsys.com \
    --to=benh@kernel.crashing.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=cort@fsmlabs.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@lists.linuxppc.org \
    --cc=paulus@samba.org \
    --cc=torvalds@transmeta.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).