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
This commit is contained in:
parent
f69c071a7d
commit
aa66f1b694
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user