From owner-freebsd-arch Tue Apr 2 19:42:25 2002 Delivered-To: freebsd-arch@freebsd.org Received: from kayak.xcllnt.net (209-128-86-226.bayarea.net [209.128.86.226]) by hub.freebsd.org (Postfix) with ESMTP id 9AB4237B417 for ; Tue, 2 Apr 2002 19:42:08 -0800 (PST) Received: from dhcp01.pn.xcllnt.net (dhcp01.pn.xcllnt.net [192.168.4.201]) by kayak.xcllnt.net (8.11.6/8.11.4) with ESMTP id g333g8b30423 for ; Tue, 2 Apr 2002 19:42:08 -0800 (PST) (envelope-from marcel@kayak.pn.xcllnt.net) Received: from dhcp01.pn.xcllnt.net (localhost [127.0.0.1]) by dhcp01.pn.xcllnt.net (8.12.2/8.12.2) with ESMTP id g333g9Q9000976 for ; Tue, 2 Apr 2002 19:42:09 -0800 (PST) (envelope-from marcel@dhcp01.pn.xcllnt.net) Received: (from marcel@localhost) by dhcp01.pn.xcllnt.net (8.12.2/8.12.2/Submit) id g333g8Ul000975 for arch@FreeBSD.org; Tue, 2 Apr 2002 19:42:08 -0800 (PST) Date: Tue, 2 Apr 2002 19:42:08 -0800 From: Marcel Moolenaar To: arch@FreeBSD.org Subject: Please review: endian invariant kernel dump headers Message-ID: <20020403034208.GA929@dhcp01.pn.xcllnt.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="d6Gm4EdcadzBjdND" Content-Disposition: inline User-Agent: Mutt/1.3.27i Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG --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 + +#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 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