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>
