diff options
author | marcel <marcel@FreeBSD.org> | 2002-04-03 07:24:12 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2002-04-03 07:24:12 +0000 |
commit | 0dbbe50955903ed143bea85061e98780e7fb4da4 (patch) | |
tree | b6dcb5afbd5f2f972055f768371369118ac773e8 | |
parent | 8d96cdfea385d755723b1d9b0f2d33d9b3a368a5 (diff) | |
download | FreeBSD-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.c | 26 | ||||
-rw-r--r-- | sys/amd64/amd64/dump_machdep.c | 19 | ||||
-rw-r--r-- | sys/i386/i386/dump_machdep.c | 19 | ||||
-rw-r--r-- | sys/i386/i386/i386dump.c | 19 | ||||
-rw-r--r-- | sys/ia64/ia64/dump_machdep.c | 23 | ||||
-rw-r--r-- | sys/ia64/ia64/ia64dump.c | 23 | ||||
-rw-r--r-- | sys/sys/kerneldump.h | 34 |
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) { |