public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Joris van Rantwijk <jorispubl@xs4all.nl>
To: "H. Peter Anvin" <hpa@zytor.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: Inflation of vmlinux by linker on x86_64
Date: Fri, 26 Sep 2008 23:55:37 +0200	[thread overview]
Message-ID: <20080926215537.GA31124@xs4all.nl> (raw)
In-Reply-To: <48DD40EF.4000107@zytor.com>

On Fri, Sep 26, 2008 at 01:07:11PM -0700, H. Peter Anvin wrote:
> In this case, I think the easiest thing to do is to provide an optimized 
> memmove and not making it a static function.  I have a reasonably 
> optimized memmove in 32-bit assembly at:
> http://git.kernel.org/?p=boot/syslinux/syslinux.git;a=blob;f=com32/lib/memmove.S;hb=HEAD

Ok.  Right now, I'd like to focus on the semantics, preferably without
bringing in new assembler code.  I renamed memcpy to memmove and
dropped "static".  We can always replace it with optimized code
as a separate patch.

There is still the question whether linking vmlinux with -n (turn off
file offset alignment) works on all architectures.  I suspect not.

Joris.

diff -urN linux-2.6.27-rc7/Makefile linux-2.6.27-rc7j/Makefile
--- linux-2.6.27-rc7/Makefile	2008-09-26 23:01:41.000000000 +0200
+++ linux-2.6.27-rc7j/Makefile	2008-09-26 12:21:34.000000000 +0200
@@ -577,7 +577,7 @@
 LDFLAGS_BUILD_ID = $(patsubst -Wl$(comma)%,%,\
 			      $(call ld-option, -Wl$(comma)--build-id,))
 LDFLAGS_MODULE += $(LDFLAGS_BUILD_ID)
-LDFLAGS_vmlinux += $(LDFLAGS_BUILD_ID)
+LDFLAGS_vmlinux += $(LDFLAGS_BUILD_ID) -n
 
 # Default kernel image to build when no specific target is given.
 # KBUILD_IMAGE may be overruled on the command line or
diff -urN linux-2.6.27-rc7/arch/x86/boot/compressed/misc.c linux-2.6.27-rc7j/arch/x86/boot/compressed/misc.c
--- linux-2.6.27-rc7/arch/x86/boot/compressed/misc.c	2008-09-26 23:01:41.000000000 +0200
+++ linux-2.6.27-rc7j/arch/x86/boot/compressed/misc.c	2008-09-26 23:02:14.000000000 +0200
@@ -27,6 +27,7 @@
 #include <linux/linkage.h>
 #include <linux/screen_info.h>
 #include <linux/elf.h>
+#include <linux/types.h>
 #include <asm/io.h>
 #include <asm/page.h>
 #include <asm/boot.h>
@@ -122,6 +123,7 @@
 
 #undef memset
 #undef memcpy
+#define memcpy		memmove
 #define memzero(s, n)	memset((s), 0, (n))
 
 typedef unsigned char	uch;
@@ -195,7 +197,7 @@
 static long bytes_out;
 
 static void *memset(void *s, int c, unsigned n);
-static void *memcpy(void *dest, const void *src, unsigned n);
+void *memmove(void *dest, const void *src, size_t n);
 
 static void __putstr(int, const char *);
 #define putstr(__x)  __putstr(0, __x)
@@ -281,13 +283,18 @@
 	return s;
 }
 
-static void *memcpy(void *dest, const void *src, unsigned n)
+/* memmove can not be static due to a declaration in asm-x86/string_32.h */
+void *memmove(void *dest, const void *src, size_t n)
 {
-	int i;
+	size_t i;
 	const char *s = src;
 	char *d = dest;
 
-	for (i = 0; i < n; i++) d[i] = s[i];
+	if (dest <= src) {
+		for (i = 0; i < n; i++) d[i] = s[i];
+	} else {
+		for (i = n; i > 0; i--) d[i-1] = s[i-1];
+	}
 	return dest;
 }
 
@@ -343,8 +350,8 @@
 	Elf32_Ehdr ehdr;
 	Elf32_Phdr *phdrs, *phdr;
 #endif
-	void *dest;
-	int i;
+	void *dest, *src;
+	int i, direction;
 
 	memcpy(&ehdr, output, sizeof(ehdr));
 	if (ehdr.e_ident[EI_MAG0] != ELFMAG0 ||
@@ -364,7 +371,17 @@
 
 	memcpy(phdrs, output + ehdr.e_phoff, sizeof(*phdrs) * ehdr.e_phnum);
 
-	for (i = 0; i < ehdr.e_phnum; i++) {
+	/* Go two times through the list of program headers;
+	 * first forward, then backward.
+	 */
+	for (i = 0, direction = 1; i >= 0; i += direction) {
+
+		if (i >= ehdr.e_phnum) {
+			/* reached the end; turn back */
+			direction = -1;
+			continue;
+		}
+
 		phdr = &phdrs[i];
 
 		switch (phdr->p_type) {
@@ -375,9 +392,14 @@
 #else
 			dest = (void *)(phdr->p_paddr);
 #endif
-			memcpy(dest,
-			       output + phdr->p_offset,
-			       phdr->p_filesz);
+			src = output + phdr->p_offset;
+
+			/* order the copying to avoid overwriting */
+			if ((direction == 1  && dest <= src) ||
+			    (direction == -1 && dest > src)) {
+				memmove(dest, src, phdr->p_filesz);
+			}
+
 			break;
 		default: /* Ignore other PT_* */ break;
 		}

  reply	other threads:[~2008-09-26 21:55 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-26 12:42 Inflation of vmlinux by linker on x86_64 Joris van Rantwijk
2008-09-26 18:52 ` H. Peter Anvin
2008-09-26 19:50   ` Joris van Rantwijk
2008-09-26 20:07     ` H. Peter Anvin
2008-09-26 21:55       ` Joris van Rantwijk [this message]
2008-09-26 21:57         ` H. Peter Anvin

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=20080926215537.GA31124@xs4all.nl \
    --to=jorispubl@xs4all.nl \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    /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