Module Name:    src
Committed By:   tsutsui
Date:           Tue Jan  5 15:45:26 UTC 2010

Modified Files:
        src/sbin/disklabel: dkcksum.c dkcksum.h main.c
        src/tools/disklabel: Makefile
Added Files:
        src/sbin/disklabel: bswap.c bswap.h

Log Message:
Add necessary byteswap ops for tools disklabel(8) used with -F option
(treating a target disk as a regular file and suppressing ioctl(2)s)
on reading/writing disklabel in a target file.
This allows cross build enviroment creating bootable disk images
for targets in different endian.
No functional changes to native (non-tools) disklabel(8) command.

Closes PR toolchain/42357.


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/sbin/disklabel/bswap.c src/sbin/disklabel/bswap.h
cvs rdiff -u -r1.12 -r1.13 src/sbin/disklabel/dkcksum.c
cvs rdiff -u -r1.4 -r1.5 src/sbin/disklabel/dkcksum.h
cvs rdiff -u -r1.21 -r1.22 src/sbin/disklabel/main.c
cvs rdiff -u -r1.2 -r1.3 src/tools/disklabel/Makefile

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sbin/disklabel/dkcksum.c
diff -u src/sbin/disklabel/dkcksum.c:1.12 src/sbin/disklabel/dkcksum.c:1.13
--- src/sbin/disklabel/dkcksum.c:1.12	Sat Oct 24 18:15:45 2009
+++ src/sbin/disklabel/dkcksum.c	Tue Jan  5 15:45:26 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: dkcksum.c,v 1.12 2009/10/24 18:15:45 tsutsui Exp $	*/
+/*	$NetBSD: dkcksum.c,v 1.13 2010/01/05 15:45:26 tsutsui Exp $	*/
 
 /*-
  * Copyright (c) 1991, 1993
@@ -38,7 +38,7 @@
 #if 0
 static char sccsid[] = "@(#)dkcksum.c	8.1 (Berkeley) 6/5/93";
 #else
-__RCSID("$NetBSD: dkcksum.c,v 1.12 2009/10/24 18:15:45 tsutsui Exp $");
+__RCSID("$NetBSD: dkcksum.c,v 1.13 2010/01/05 15:45:26 tsutsui Exp $");
 #endif
 #endif /* not lint */
 
@@ -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: src/sbin/disklabel/dkcksum.h
diff -u src/sbin/disklabel/dkcksum.h:1.4 src/sbin/disklabel/dkcksum.h:1.5
--- src/sbin/disklabel/dkcksum.h:1.4	Sat Oct 24 18:15:45 2009
+++ src/sbin/disklabel/dkcksum.h	Tue Jan  5 15:45:26 2010
@@ -1,3 +1,4 @@
-/*	$NetBSD: dkcksum.h,v 1.4 2009/10/24 18:15:45 tsutsui Exp $	*/
+/*	$NetBSD: dkcksum.h,v 1.5 2010/01/05 15:45:26 tsutsui Exp $	*/
 
 uint16_t	dkcksum(struct disklabel *);
+uint16_t	dkcksum_sized(struct disklabel *, size_t);

Index: src/sbin/disklabel/main.c
diff -u src/sbin/disklabel/main.c:1.21 src/sbin/disklabel/main.c:1.22
--- src/sbin/disklabel/main.c:1.21	Sat Nov 28 12:14:53 2009
+++ src/sbin/disklabel/main.c	Tue Jan  5 15:45:26 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: main.c,v 1.21 2009/11/28 12:14:53 tsutsui Exp $	*/
+/*	$NetBSD: main.c,v 1.22 2010/01/05 15:45:26 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 2006 The NetBSD Foundation, Inc.
@@ -76,7 +76,7 @@
 static char sccsid[] = "@(#)disklabel.c	8.4 (Berkeley) 5/4/95";
 /* from static char sccsid[] = "@(#)disklabel.c	1.2 (Symmetric) 11/28/85"; */
 #else
-__RCSID("$NetBSD: main.c,v 1.21 2009/11/28 12:14:53 tsutsui Exp $");
+__RCSID("$NetBSD: main.c,v 1.22 2010/01/05 15:45:26 tsutsui Exp $");
 #endif
 #endif	/* not lint */
 
@@ -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;
 	}
 

Index: src/tools/disklabel/Makefile
diff -u src/tools/disklabel/Makefile:1.2 src/tools/disklabel/Makefile:1.3
--- src/tools/disklabel/Makefile:1.2	Sat Dec  9 20:13:13 2006
+++ src/tools/disklabel/Makefile	Tue Jan  5 15:45:26 2010
@@ -1,8 +1,18 @@
-#	$NetBSD: Makefile,v 1.2 2006/12/09 20:13:13 dyoung Exp $
+#	$NetBSD: Makefile,v 1.3 2010/01/05 15:45:26 tsutsui Exp $
 
 HOSTPROGNAME=	nbdisklabel-${MAKEWRAPPERMACHINE}
 HOST_SRCDIR=	sbin/disklabel
-HOST_SRCS=	getcap.c disklabel.c
+HOST_SRCS=	getcap.c disklabel.c bswap.c
+
+NOMAN=	# defined
+
+.include <bsd.endian.mk>
+
+.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"

Added files:

Index: src/sbin/disklabel/bswap.c
diff -u /dev/null src/sbin/disklabel/bswap.c:1.1
--- /dev/null	Tue Jan  5 15:45:26 2010
+++ src/sbin/disklabel/bswap.c	Tue Jan  5 15:45:26 2010
@@ -0,0 +1,177 @@
+/*	$NetBSD: bswap.c,v 1.1 2010/01/05 15:45:26 tsutsui Exp $	*/
+
+/*-
+ * 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 <sys/types.h>
+#if HAVE_NBTOOL_CONFIG_H
+#include <nbinclude/sys/disklabel.h>
+#else
+#include <sys/disklabel.h>
+#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
Index: src/sbin/disklabel/bswap.h
diff -u /dev/null src/sbin/disklabel/bswap.h:1.1
--- /dev/null	Tue Jan  5 15:45:26 2010
+++ src/sbin/disklabel/bswap.h	Tue Jan  5 15:45:26 2010
@@ -0,0 +1,64 @@
+/*	$NetBSD: bswap.h,v 1.1 2010/01/05 15:45:26 tsutsui Exp $	*/
+
+/*-
+ * 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 <sys/types.h>
+
+#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

Reply via email to