summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2002-04-03 07:24:12 +0000
committermarcel <marcel@FreeBSD.org>2002-04-03 07:24:12 +0000
commit0dbbe50955903ed143bea85061e98780e7fb4da4 (patch)
treeb6dcb5afbd5f2f972055f768371369118ac773e8
parent8d96cdfea385d755723b1d9b0f2d33d9b3a368a5 (diff)
downloadFreeBSD-src-0dbbe50955903ed143bea85061e98780e7fb4da4.zip
FreeBSD-src-0dbbe50955903ed143bea85061e98780e7fb4da4.tar.gz
Make the kernel dump header endianness invariant by always dumping
in dump byte order (=network byte order). Swap blocksize and dumptime to avoid extraneous padding on 64-bit architectures. Use CTASSERT instead of runtime checks to make sure the header is 512 bytes large. Various style(9) fixes. Reviewed by: phk, bde, mike
-rw-r--r--sbin/savecore/savecore.c26
-rw-r--r--sys/amd64/amd64/dump_machdep.c19
-rw-r--r--sys/i386/i386/dump_machdep.c19
-rw-r--r--sys/i386/i386/i386dump.c19
-rw-r--r--sys/ia64/ia64/dump_machdep.c23
-rw-r--r--sys/ia64/ia64/ia64dump.c23
-rw-r--r--sys/sys/kerneldump.h34
7 files changed, 86 insertions, 77 deletions
diff --git a/sbin/savecore/savecore.c b/sbin/savecore/savecore.c
index 846aaac..078bb3a 100644
--- a/sbin/savecore/savecore.c
+++ b/sbin/savecore/savecore.c
@@ -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 @@ DoFile(const char *devname)
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 @@ DoFile(const char *devname)
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);
diff --git a/sys/amd64/amd64/dump_machdep.c b/sys/amd64/amd64/dump_machdep.c
index b914af1..09db68b 100644
--- a/sys/amd64/amd64/dump_machdep.c
+++ b/sys/amd64/amd64/dump_machdep.c
@@ -44,6 +44,8 @@
#include <vm/pmap.h>
#include <machine/md_var.h>
+CTASSERT(sizeof(struct kerneldumpheader) == 512);
+
static struct kerneldumpheader kdh;
void
@@ -57,21 +59,14 @@ dumpsys(struct dumperinfo *di)
printf("Dumping %u MB\n", Maxmem / (1024*1024 / PAGE_SIZE));
- if (sizeof kdh != 512) {
- printf(
- "Compiled struct kerneldumpheader is %d, not %d bytes\n",
- sizeof kdh, 512);
- return;
- }
-
/* 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)
diff --git a/sys/i386/i386/dump_machdep.c b/sys/i386/i386/dump_machdep.c
index b914af1..09db68b 100644
--- a/sys/i386/i386/dump_machdep.c
+++ b/sys/i386/i386/dump_machdep.c
@@ -44,6 +44,8 @@
#include <vm/pmap.h>
#include <machine/md_var.h>
+CTASSERT(sizeof(struct kerneldumpheader) == 512);
+
static struct kerneldumpheader kdh;
void
@@ -57,21 +59,14 @@ dumpsys(struct dumperinfo *di)
printf("Dumping %u MB\n", Maxmem / (1024*1024 / PAGE_SIZE));
- if (sizeof kdh != 512) {
- printf(
- "Compiled struct kerneldumpheader is %d, not %d bytes\n",
- sizeof kdh, 512);
- return;
- }
-
/* 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)
diff --git a/sys/i386/i386/i386dump.c b/sys/i386/i386/i386dump.c
index b914af1..09db68b 100644
--- a/sys/i386/i386/i386dump.c
+++ b/sys/i386/i386/i386dump.c
@@ -44,6 +44,8 @@
#include <vm/pmap.h>
#include <machine/md_var.h>
+CTASSERT(sizeof(struct kerneldumpheader) == 512);
+
static struct kerneldumpheader kdh;
void
@@ -57,21 +59,14 @@ dumpsys(struct dumperinfo *di)
printf("Dumping %u MB\n", Maxmem / (1024*1024 / PAGE_SIZE));
- if (sizeof kdh != 512) {
- printf(
- "Compiled struct kerneldumpheader is %d, not %d bytes\n",
- sizeof kdh, 512);
- return;
- }
-
/* 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)
diff --git a/sys/ia64/ia64/dump_machdep.c b/sys/ia64/ia64/dump_machdep.c
index d49265d..a86754e 100644
--- a/sys/ia64/ia64/dump_machdep.c
+++ b/sys/ia64/ia64/dump_machdep.c
@@ -38,6 +38,8 @@
#include <machine/elf.h>
#include <machine/md_var.h>
+CTASSERT(sizeof(struct kerneldumpheader) == 512);
+
#define MD_ALIGN(x) (((off_t)(x) + EFI_PAGE_MASK) & ~EFI_PAGE_MASK)
typedef int callback_t(EFI_MEMORY_DESCRIPTOR*, int, void*);
@@ -55,21 +57,14 @@ mkdumpheader(struct kerneldumpheader *kdh, uint32_t archver, uint64_t dumplen,
uint32_t blksz)
{
- if (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)
@@ -217,7 +212,11 @@ dumpsys(struct dumperinfo *di)
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;
diff --git a/sys/ia64/ia64/ia64dump.c b/sys/ia64/ia64/ia64dump.c
index d49265d..a86754e 100644
--- a/sys/ia64/ia64/ia64dump.c
+++ b/sys/ia64/ia64/ia64dump.c
@@ -38,6 +38,8 @@
#include <machine/elf.h>
#include <machine/md_var.h>
+CTASSERT(sizeof(struct kerneldumpheader) == 512);
+
#define MD_ALIGN(x) (((off_t)(x) + EFI_PAGE_MASK) & ~EFI_PAGE_MASK)
typedef int callback_t(EFI_MEMORY_DESCRIPTOR*, int, void*);
@@ -55,21 +57,14 @@ mkdumpheader(struct kerneldumpheader *kdh, uint32_t archver, uint64_t dumplen,
uint32_t blksz)
{
- if (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)
@@ -217,7 +212,11 @@ dumpsys(struct dumperinfo *di)
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;
diff --git a/sys/sys/kerneldump.h b/sys/sys/kerneldump.h
index c803984..b6c4caf 100644
--- a/sys/sys/kerneldump.h
+++ b/sys/sys/kerneldump.h
@@ -38,24 +38,46 @@
#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)
+#elif BYTE_ORDER == BIG_ENDIAN
+#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"
+#define KERNELDUMPMAGIC "FreeBSD Kernel Dump"
char architecture[12];
uint32_t version;
-# define KERNELDUMPVERSION 1
+#define KERNELDUMPVERSION 1
uint32_t architectureversion;
-# define KERNELDUMP_I386_VERSION 1
-# define KERNELDUMP_IA64_VERSION 1
- uint64_t dumplength; /* excl headers */
- uint32_t blocksize;
+#define KERNELDUMP_I386_VERSION 1
+#define KERNELDUMP_IA64_VERSION 1
+ uint64_t dumplength; /* excl headers */
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)
{
OpenPOWER on IntegriCloud