Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 2 Apr 2002 19:42:08 -0800
From:      Marcel Moolenaar <marcel@xcllnt.net>
To:        arch@FreeBSD.org
Subject:   Please review: endian invariant kernel dump headers
Message-ID:  <20020403034208.GA929@dhcp01.pn.xcllnt.net>

next in thread | raw e-mail | index | archive | help

--d6Gm4EdcadzBjdND
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Gang,

Please review the attached patch. The change achieves the following:

1. Dump the kernel header in dump byte order. This is the same
   as network byte order. Parity calculation is endianness
   invariant and should not use the macros.
2. The kernel dump header had a size of 520 bytes on 64-bit
   architectures due to alignment of the uint64_t following
   the uint32_t. Reordering solves that.
3. No version bump is required, because all existing headers are
   in little-endian and thus will not have the same version as
   the big-endian dumps. I did not add support in savecore to
   read version 0x01000000 headers :-)

If there are no blocking objections I like to commit this quickly
due to point 2.

Thanks,

-- 
 Marcel Moolenaar	  USPA: A-39004		 marcel@xcllnt.net

--d6Gm4EdcadzBjdND
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="dump.diff"

Index: sys/i386/i386/i386dump.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/i386dump.c,v
retrieving revision 1.1
diff -u -r1.1 i386dump.c
--- sys/i386/i386/i386dump.c	31 Mar 2002 22:36:44 -0000	1.1
+++ sys/i386/i386/i386dump.c	3 Apr 2002 03:23:18 -0000
@@ -67,11 +67,11 @@
 	/* Fill in the kernel dump header */
 	strcpy(kdh.magic, KERNELDUMPMAGIC);
 	strcpy(kdh.architecture, "i386");
-	kdh.version = KERNELDUMPVERSION;
-	kdh.architectureversion = KERNELDUMP_I386_VERSION;
-	kdh.dumplength = Maxmem * (off_t)PAGE_SIZE;
-	kdh.blocksize = di->blocksize;
-	kdh.dumptime = time_second;
+	kdh.version = htod32(KERNELDUMPVERSION);
+	kdh.architectureversion = htod32(KERNELDUMP_I386_VERSION);
+	kdh.dumplength = htod64(Maxmem * (off_t)PAGE_SIZE);
+	kdh.dumptime = htod64(time_second);
+	kdh.blocksize = htod32(di->blocksize);
 	strncpy(kdh.hostname, hostname, sizeof kdh.hostname);
 	strncpy(kdh.versionstring, version, sizeof kdh.versionstring);
 	if (panicstr != NULL)
Index: sys/ia64/ia64/ia64dump.c
===================================================================
RCS file: /home/ncvs/src/sys/ia64/ia64/ia64dump.c,v
retrieving revision 1.1
diff -u -r1.1 ia64dump.c
--- sys/ia64/ia64/ia64dump.c	2 Apr 2002 10:51:32 -0000	1.1
+++ sys/ia64/ia64/ia64dump.c	3 Apr 2002 03:21:07 -0000
@@ -56,20 +56,19 @@
 {
 
 	if (sizeof(*kdh) != DEV_BSIZE) {
-		printf(
-		    "Compiled struct kerneldumpheader is %d, not %d bytes\n",
-		    sizeof(*kdh), DEV_BSIZE);
+		printf("Compiled struct kerneldumpheader is %d, "
+		    "not %d bytes\n", sizeof(*kdh), DEV_BSIZE);
 		return;
 	}
 
 	bzero(kdh, sizeof(*kdh));
 	strncpy(kdh->magic, KERNELDUMPMAGIC, sizeof(kdh->magic));
 	strncpy(kdh->architecture, MACHINE_ARCH, sizeof(kdh->architecture));
-	kdh->version = KERNELDUMPVERSION;
-	kdh->architectureversion = archver;
-	kdh->dumplength = dumplen;
-	kdh->blocksize = blksz;
-	kdh->dumptime = time_second;
+	kdh->version = htod32(KERNELDUMPVERSION);
+	kdh->architectureversion = htod32(archver);
+	kdh->dumplength = htod64(dumplen);
+	kdh->dumptime = htod64(time_second);
+	kdh->blocksize = htod32(blksz);
 	strncpy(kdh->hostname, hostname, sizeof(kdh->hostname));
 	strncpy(kdh->versionstring, version, sizeof(kdh->versionstring));
 	if (panicstr != NULL)
@@ -215,7 +214,11 @@
 	ehdr.e_ident[EI_MAG2] = ELFMAG2;
 	ehdr.e_ident[EI_MAG3] = ELFMAG3;
 	ehdr.e_ident[EI_CLASS] = ELFCLASS64;
+#if BYTE_ORDER == LITTLE_ENDIAN
 	ehdr.e_ident[EI_DATA] = ELFDATA2LSB;
+#else
+	ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
+#endif
 	ehdr.e_ident[EI_VERSION] = EV_CURRENT;
 	ehdr.e_ident[EI_OSABI] = ELFOSABI_STANDALONE;	/* XXX big picture? */
 	ehdr.e_type = ET_CORE;
Index: sys/sys/kerneldump.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/kerneldump.h,v
retrieving revision 1.2
diff -u -r1.2 kerneldump.h
--- sys/sys/kerneldump.h	2 Apr 2002 10:53:59 -0000	1.2
+++ sys/sys/kerneldump.h	3 Apr 2002 03:15:20 -0000
@@ -38,6 +38,25 @@
 #ifndef _SYS_KERNELDUMP_H
 #define _SYS_KERNELDUMP_H
 
+#include <machine/endian.h>
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define	dtoh32(x)	__bswap32(x)
+#define	dtoh64(x)	__bswap64(x)
+#define	htod32(x)	__bswap32(x)
+#define	htod64(x)	__bswap64(x)
+#else
+#define	dtoh32(x)	x
+#define	dtoh64(x)	x
+#define	htod32(x)	x
+#define	htod64(x)	x
+#endif
+
+/*
+ * All uintX_t fields are in dump byte order, which is the same as
+ * network byte order. Use the macros defined above to read or
+ * write the fields.
+ */
 struct kerneldumpheader {
 	char		magic[20];
 #	    define KERNELDUMPMAGIC "FreeBSD Kernel Dump"
@@ -48,14 +67,17 @@
 #	    define KERNELDUMP_I386_VERSION 1
 #	    define KERNELDUMP_IA64_VERSION 1
 	uint64_t	dumplength;	/* excl headers */
-	uint32_t	blocksize;
 	uint64_t	dumptime;
+	uint32_t	blocksize;
 	char		hostname[64];
 	char		versionstring[192];
 	char		panicstring[192];
 	uint32_t	parity;
 };
 
+/*
+ * Parity calculation is endian insensitive
+ */
 static __inline u_int32_t
 kerneldump_parity(struct kerneldumpheader *kdhp)
 {
Index: sbin/savecore/savecore.c
===================================================================
RCS file: /home/ncvs/src/sbin/savecore/savecore.c,v
retrieving revision 1.52
diff -u -r1.52 savecore.c
--- sbin/savecore/savecore.c	1 Apr 2002 18:23:58 -0000	1.52
+++ sbin/savecore/savecore.c	3 Apr 2002 03:15:46 -0000
@@ -48,24 +48,28 @@
 #include <sys/kerneldump.h>
 
 static void
-printheader(FILE *f, const struct kerneldumpheader *h, const char *devname, const char *md5)
+printheader(FILE *f, const struct kerneldumpheader *h, const char *devname,
+    const char *md5)
 {
+	uint64_t dumplen;
 	time_t t;
 
 	fprintf(f, "Good dump found on device %s\n", devname);
 	fprintf(f, "  Architecture: %s\n", h->architecture);
-	fprintf(f, "  Architecture version: %d\n", h->architectureversion);
-	fprintf(f, "  Dump length: %lldB (%lld MB)\n", 
-	    (long long)h->dumplength, (long long)h->dumplength / (1024 * 1024));
-	fprintf(f, "  Blocksize: %d\n", h->blocksize);
-	t = h->dumptime;
+	fprintf(f, "  Architecture version: %d\n",
+	    dtoh32(h->architectureversion));
+	dumplen = dtoh64(h->dumplength);
+	fprintf(f, "  Dump length: %lldB (%lld MB)\n", (long long)dumplen,
+	    (long long)(dumplen >> 20));
+	fprintf(f, "  Blocksize: %d\n", dtoh32(h->blocksize));
+	t = dtoh64(h->dumptime);
 	fprintf(f, "  Dumptime: %s", ctime(&t));
 	fprintf(f, "  Hostname: %s\n", h->hostname);
 	fprintf(f, "  Versionstring: %s", h->versionstring);
 	fprintf(f, "  Panicstring: %s\n", h->panicstring);
 	fprintf(f, "  MD5: %s\n", md5);
 }
-		
+
 
 static void
 DoFile(const char *devname)
@@ -109,12 +113,13 @@
 		warnx("Magic mismatch on last dump header on %s\n", devname);
 		return;
 	}
-	if (kdhl.version != KERNELDUMPVERSION) {
+	if (dtoh32(kdhl.version) != KERNELDUMPVERSION) {
 		warnx("Unknown version (%d) in last dump header on %s\n",
-		    kdhl.version, devname);
+		    dtoh32(kdhl.version), devname);
 		return;
 	}
-	firsthd = lasthd - kdhl.dumplength - sizeof kdhf;
+	dumpsize = dtoh64(kdhl.dumplength);
+	firsthd = lasthd - dumpsize - sizeof kdhf;
 	lseek(fd, firsthd, SEEK_SET);
 	error = read(fd, &kdhf, sizeof kdhf);
 	if (error != sizeof kdhf) {
@@ -146,7 +151,6 @@
 	info = fdopen(fdinfo, "w");
 	printheader(stdout, &kdhl, devname, md5);
 	printheader(info, &kdhl, devname, md5);
-	dumpsize = kdhl.dumplength;
 	printf("Saving dump to file...\n");
 	while (dumpsize > 0) {
 		wl = sizeof(buf);

--d6Gm4EdcadzBjdND--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020403034208.GA929>