Index: tools/disklabel/Makefile =================================================================== RCS file: /cvsroot/src/tools/disklabel/Makefile,v retrieving revision 1.2 diff -u -r1.2 Makefile --- tools/disklabel/Makefile 9 Dec 2006 20:13:13 -0000 1.2 +++ tools/disklabel/Makefile 28 Nov 2009 12:52:43 -0000 @@ -2,7 +2,17 @@ HOSTPROGNAME= nbdisklabel-${MAKEWRAPPERMACHINE} HOST_SRCDIR= sbin/disklabel -HOST_SRCS= getcap.c disklabel.c +HOST_SRCS= getcap.c disklabel.c bswap.c + +NOMAN= # defined + +.include + +.if ${TARGET_ENDIANNESS} == "1234" +CPPFLAGS+= -DTARGET_BYTE_ORDER=LITTLE_ENDIAN +.elif ${TARGET_ENDIANNESS} == "4321" +CPPFLAGS+= -DTARGET_BYTE_ORDER=BIG_ENDIAN +.endif .include "${.CURDIR}/../Makefile.disklabel" .include "${.CURDIR}/../Makefile.host" Index: sbin/disklabel/dkcksum.c =================================================================== RCS file: /cvsroot/src/sbin/disklabel/dkcksum.c,v retrieving revision 1.12 diff -u -r1.12 dkcksum.c --- sbin/disklabel/dkcksum.c 24 Oct 2009 18:15:45 -0000 1.12 +++ sbin/disklabel/dkcksum.c 28 Nov 2009 12:52:43 -0000 @@ -53,12 +53,19 @@ uint16_t dkcksum(struct disklabel *lp) { + + return dkcksum_sized(lp, lp->d_npartitions); +} + +uint16_t +dkcksum_sized(struct disklabel *lp, size_t npartitions) +{ uint16_t *start, *end; uint16_t sum; sum = 0; start = (uint16_t *)lp; - end = (uint16_t *)&lp->d_partitions[lp->d_npartitions]; + end = (uint16_t *)&lp->d_partitions[npartitions]; while (start < end) sum ^= *start++; return sum; Index: sbin/disklabel/dkcksum.h =================================================================== RCS file: /cvsroot/src/sbin/disklabel/dkcksum.h,v retrieving revision 1.4 diff -u -r1.4 dkcksum.h --- sbin/disklabel/dkcksum.h 24 Oct 2009 18:15:45 -0000 1.4 +++ sbin/disklabel/dkcksum.h 28 Nov 2009 12:52:43 -0000 @@ -1,3 +1,4 @@ /* $NetBSD: dkcksum.h,v 1.4 2009/10/24 18:15:45 tsutsui Exp $ */ uint16_t dkcksum(struct disklabel *); +uint16_t dkcksum_sized(struct disklabel *, size_t); Index: sbin/disklabel/main.c =================================================================== RCS file: /cvsroot/src/sbin/disklabel/main.c,v retrieving revision 1.21 diff -u -r1.21 main.c --- sbin/disklabel/main.c 28 Nov 2009 12:14:53 -0000 1.21 +++ sbin/disklabel/main.c 28 Nov 2009 12:52:44 -0000 @@ -117,6 +117,7 @@ #include "pathnames.h" #include "extern.h" #include "dkcksum.h" +#include "bswap.h" /* * Disklabel: read and write disklabels. @@ -688,12 +689,12 @@ static int readlabel_mbr(int f, u_int sector) { - struct disklabel *lp; + struct disklabel *disk_lp; - lp = find_label(f, sector); - if (lp == NULL) + disk_lp = find_label(f, sector); + if (disk_lp == NULL) return 1; - lab = *lp; + targettohlabel(&lab, disk_lp); return 0; } @@ -900,7 +901,7 @@ static struct disklabel * find_label(int f, u_int sector) { - struct disklabel *lp; + struct disklabel *disk_lp, hlp; int i, offset; const char *is_deleted; @@ -919,29 +920,30 @@ /* Check expected offset first */ for (offset = LABEL_OFFSET, i = -4;; offset = i += 4) { is_deleted = ""; - lp = (void *)(bootarea + offset); + disk_lp = (void *)(bootarea + offset); if (i == LABEL_OFFSET) continue; - if ((char *)(lp + 1) > bootarea + bootarea_len) + if ((char *)(disk_lp + 1) > bootarea + bootarea_len) break; - if (lp->d_magic2 != lp->d_magic) + if (disk_lp->d_magic2 != disk_lp->d_magic) continue; - if (read_all && (lp->d_magic == DISKMAGIC_DELETED || - lp->d_magic == DISKMAGIC_DELETED_REV)) { - lp->d_magic ^= ~0u; - lp->d_magic2 ^= ~0u; + if (read_all && (disk_lp->d_magic == DISKMAGIC_DELETED || + disk_lp->d_magic == DISKMAGIC_DELETED_REV)) { + disk_lp->d_magic ^= ~0u; + disk_lp->d_magic2 ^= ~0u; is_deleted = "deleted "; } - if (lp->d_magic != DISKMAGIC) { + if (target32toh(disk_lp->d_magic) != DISKMAGIC) { /* XXX: Do something about byte-swapped labels ? */ - if (lp->d_magic == DISKMAGIC_REV && - lp->d_magic2 == DISKMAGIC_REV) + if (target32toh(disk_lp->d_magic) == DISKMAGIC_REV && + target32toh(disk_lp->d_magic2) == DISKMAGIC_REV) warnx("ignoring %sbyteswapped label" " at offset %u from sector %u", is_deleted, offset, sector); continue; } - if (lp->d_npartitions > MAXPARTITIONS || dkcksum(lp) != 0) { + if (target16toh(disk_lp->d_npartitions) > MAXPARTITIONS || + dkcksum_target(disk_lp) != 0) { if (verbose > 0) warnx("corrupt label found at offset %u in " "sector %u", offset, sector); @@ -951,19 +953,21 @@ warnx("%slabel found at offset %u from sector %u", is_deleted, offset, sector); if (!read_all) - return lp; + return disk_lp; /* To print all the labels we have to do it here */ /* XXX: maybe we should compare them? */ + targettohlabel(&hlp, disk_lp); printf("# %ssector %u offset %u bytes\n", is_deleted, sector, offset); if (tflag) - makedisktab(stdout, lp); + makedisktab(stdout, &hlp); else { - showinfo(stdout, lp, specname); - showpartitions(stdout, lp, Cflag); + showinfo(stdout, &hlp, specname); + showpartitions(stdout, &hlp, Cflag); } - checklabel(lp); + checklabel(&hlp); + htotargetlabel(disk_lp, &hlp); /* Remember we've found a label */ read_all = 2; } @@ -1033,7 +1037,7 @@ "to create label", label_sector); } - *disk_lp = lab; + htotargetlabel(disk_lp, &lab); write_bootarea(f, label_sector); return 1; } @@ -1069,7 +1073,7 @@ if (filecore_partition_offset != 0) { disk_lp = find_label(f, filecore_partition_offset); if (disk_lp != NULL) { - lab = *disk_lp; + targettohlabel(&lab, disk_lp); return 0; } } @@ -1079,7 +1083,7 @@ disk_lp = find_label(f, 0); if (disk_lp != NULL) { - lab = *disk_lp; + targettohlabel(&lab, disk_lp); return 0; } --- /dev/null 2009-11-28 13:17:33.000000000 +0900 +++ sbin/disklabel/bswap.c 2009-11-27 20:19:55.000000000 +0900 @@ -0,0 +1,177 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2009 Izumi Tsutsui. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 1982, 1986, 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91 + */ + +#if HAVE_NBTOOL_CONFIG_H +#include "nbtool_config.h" +#endif + +#include +#if HAVE_NBTOOL_CONFIG_H +#include +#else +#include +#endif /* HAVE_NBTOOL_CONFIG_H */ + +#include "bswap.h" +#include "dkcksum.h" + +#if TARGET_BYTE_ORDER != BYTE_ORDER +static void bswaplabel(struct disklabel *nlp, struct disklabel *olp); + +void +bswaplabel(struct disklabel *nlp, struct disklabel *olp) +{ + int i; + + nlp->d_magic = bswap32(olp->d_magic); + nlp->d_type = bswap16(olp->d_type); + nlp->d_subtype = bswap16(olp->d_subtype); + + /* no need to swap char strings */ + memcpy(nlp->d_typename, olp->d_typename, sizeof(nlp->d_typename)); + + /* XXX What should we do for d_un (an union of char and pointers) ? */ + memcpy(nlp->d_packname, olp->d_packname, sizeof(nlp->d_packname)); + + nlp->d_secsize = bswap32(olp->d_secsize); + nlp->d_nsectors = bswap32(olp->d_nsectors); + nlp->d_ntracks = bswap32(olp->d_ntracks); + nlp->d_ncylinders = bswap32(olp->d_ncylinders); + nlp->d_secpercyl = bswap32(olp->d_secpercyl); + nlp->d_secperunit = bswap32(olp->d_secperunit); + + nlp->d_sparespertrack = bswap16(olp->d_sparespertrack); + nlp->d_sparespercyl = bswap16(olp->d_sparespercyl); + + nlp->d_acylinders = bswap32(olp->d_acylinders); + + nlp->d_rpm = bswap16(olp->d_rpm); + nlp->d_interleave = bswap16(olp->d_interleave); + nlp->d_trackskew = bswap16(olp->d_trackskew); + nlp->d_cylskew = bswap16(olp->d_cylskew); + nlp->d_headswitch = bswap32(olp->d_headswitch); + nlp->d_trkseek = bswap32(olp->d_trkseek); + nlp->d_flags = bswap32(olp->d_flags); + + for (i = 0; i < NDDATA; i++) + nlp->d_drivedata[i] = bswap32(olp->d_drivedata[i]); + + for (i = 0; i < NSPARE; i++) + nlp->d_spare[i] = bswap32(olp->d_spare[i]); + + nlp->d_magic2 = bswap32(olp->d_magic2); + nlp->d_checksum = bswap16(olp->d_checksum); + + /* filesystem and partition information: */ + nlp->d_npartitions = bswap16(olp->d_npartitions); + nlp->d_bbsize = bswap32(olp->d_bbsize); + nlp->d_sbsize = bswap32(olp->d_sbsize); + + for (i = 0; i < MAXPARTITIONS; i++) { + nlp->d_partitions[i].p_size = + bswap32(olp->d_partitions[i].p_size); + nlp->d_partitions[i].p_offset = + bswap32(olp->d_partitions[i].p_offset); + nlp->d_partitions[i].p_fsize = + bswap32(olp->d_partitions[i].p_fsize); + /* p_fstype and p_frag is uint8_t, so no need to swap */ + nlp->d_partitions[i].p_fstype = olp->d_partitions[i].p_fstype; + nlp->d_partitions[i].p_frag = olp->d_partitions[i].p_frag; + nlp->d_partitions[i].p_cpg = + bswap16(olp->d_partitions[i].p_cpg); + } +} + +void +targettohlabel(struct disklabel *hlp, struct disklabel *tlp) +{ + + bswaplabel(hlp, tlp); + /* update checksum in host endian */ + hlp->d_checksum = 0; + hlp->d_checksum = dkcksum(hlp); +} + +void +htotargetlabel(struct disklabel *tlp, struct disklabel *hlp) +{ + + bswaplabel(tlp, hlp); + /* update checksum in target endian */ + tlp->d_checksum = 0; + tlp->d_checksum = dkcksum_re(tlp); +} + +uint16_t +dkcksum_re(struct disklabel *lp) +{ + uint16_t npartitions; + + /* we can assume lp is reversed, but check it again for sanity */ + if (lp->d_magic == DISKMAGIC) + npartitions = lp->d_npartitions; + else if (bswap32(lp->d_magic) == DISKMAGIC) + npartitions = bswap16(lp->d_npartitions); + else + npartitions = 0; + + if (npartitions > MAXPARTITIONS) + npartitions = 0; + + return dkcksum_sized(lp, npartitions); +} +#endif --- /dev/null 2009-11-28 13:17:33.000000000 +0900 +++ sbin/disklabel/bswap.h 2009-10-27 01:41:55.000000000 +0900 @@ -0,0 +1,64 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2009 Izumi Tsutsui. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#if HAVE_NBTOOL_CONFIG_H +#ifndef BYTE_ORDER +#ifdef WORDS_BIGENDIAN +#define BYTE_ORDER BIG_ENDIAN +#else +#define BYTE_ORDER LITTLE_ENDIAN +#endif +#endif +#endif + +#ifndef TARGET_BYTE_ORDER +#define TARGET_BYTE_ORDER BYTE_ORDER +#endif + +#if TARGET_BYTE_ORDER != BYTE_ORDER +#define htotarget16(x) bswap16(x) +#define target16toh(x) bswap16(x) +#define htotarget32(x) bswap32(x) +#define target32toh(x) bswap32(x) +#define dkcksum_target(lp) dkcksum_re(lp) + +void htotargetlabel(struct disklabel *, struct disklabel *); +void targettohlabel(struct disklabel *, struct disklabel *); +uint16_t dkcksum_re(struct disklabel *); + +#else +#define htotarget16(x) (x) +#define target16toh(x) (x) +#define htotarget32(x) (x) +#define target32toh(x) (x) +#define dkcksum_target(lp) dkcksum(lp) +#define htotargetlabel(tlp, hlp) \ + do {*(tlp) = *(hlp);} while (/* CONSTCOND */0) +#define targettohlabel(hlp, tlp) \ + do {*(hlp) = *(tlp);} while (/* CONSTCOND */0) +#endif