summaryrefslogtreecommitdiffstats
path: root/sys/boot/common
diff options
context:
space:
mode:
authormarius <marius@FreeBSD.org>2012-03-11 13:39:19 +0000
committermarius <marius@FreeBSD.org>2012-03-11 13:39:19 +0000
commit98ea631a425fc57d13175ce5a079df40bfd4909b (patch)
treec6a3fb06f55d0e0ae871cce0cfb35d813a269490 /sys/boot/common
parent8adabb0356f0bb9d2681f2b8641d303ff20116f1 (diff)
downloadFreeBSD-src-98ea631a425fc57d13175ce5a079df40bfd4909b.zip
FreeBSD-src-98ea631a425fc57d13175ce5a079df40bfd4909b.tar.gz
Fix a bug introduced in r223938; on big-endian machines coping a 32-bit
quantum bytewise to the address of a 64-bit variable results in writing to the "wrong" 32-bit half so adjust the address accordingly. This fix is implemented in a hackish way for two reasons: o in order to be able to get it into 8.3 with zero impact on the little- endian architectures where this bug has no effect and o to avoid blowing the x86 boot2 out of the water again when compiling it with clang, which all sane versions of this fix tested do. This change fixes booting from UFS1 file systems on big-endian machines. MFC after: 3 days
Diffstat (limited to 'sys/boot/common')
-rw-r--r--sys/boot/common/ufsread.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/sys/boot/common/ufsread.c b/sys/boot/common/ufsread.c
index b767732..d87853f 100644
--- a/sys/boot/common/ufsread.c
+++ b/sys/boot/common/ufsread.c
@@ -46,6 +46,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/endian.h>
+
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h>
@@ -262,15 +264,28 @@ fsread(ino_t inode, void *buf, size_t nbyte)
}
n = (lbn - NDADDR) & (n - 1);
#if defined(UFS1_ONLY)
+#if BYTE_ORDER == BIG_ENDIAN
+ memcpy((char *)&addr + sizeof(addr) -
+ sizeof(ufs1_daddr_t), (ufs1_daddr_t *)indbuf + n,
+ sizeof(ufs1_daddr_t));
+#else
memcpy(&addr, (ufs1_daddr_t *)indbuf + n,
sizeof(ufs1_daddr_t));
+#endif
#elif defined(UFS2_ONLY)
memcpy(&addr, (ufs2_daddr_t *)indbuf + n,
sizeof(ufs2_daddr_t));
#else
if (fs.fs_magic == FS_UFS1_MAGIC)
+#if BYTE_ORDER == BIG_ENDIAN
+ memcpy((char *)&addr + sizeof(addr) -
+ sizeof(ufs1_daddr_t),
+ (ufs1_daddr_t *)indbuf + n,
+ sizeof(ufs1_daddr_t));
+#else
memcpy(&addr, (ufs1_daddr_t *)indbuf + n,
sizeof(ufs1_daddr_t));
+#endif
else
memcpy(&addr, (ufs2_daddr_t *)indbuf + n,
sizeof(ufs2_daddr_t));
OpenPOWER on IntegriCloud