1 /*
   2  * endians.h - Definitions related to handling of byte ordering. Part of the
   3  *             Linux-NTFS project.
   4  *
   5  * Copyright (c) 2000-2005 Anton Altaparmakov
   6  * Copyright (c)      2007 Yura Pakhuchiy
   7  *
   8  * This program/include file is free software; you can redistribute it and/or
   9  * modify it under the terms of the GNU General Public License as published
  10  * by the Free Software Foundation; either version 2 of the License, or
  11  * (at your option) any later version.
  12  *
  13  * This program/include file is distributed in the hope that it will be
  14  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  15  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16  * GNU General Public License for more details.
  17  *
  18  * You should have received a copy of the GNU General Public License
  19  * along with this program (in the main directory of the Linux-NTFS
  20  * distribution in the file COPYING); if not, write to the Free Software
  21  * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  22  */
  23 
  24 #ifndef _NTFS_ENDIANS_H
  25 #define _NTFS_ENDIANS_H
  26 
  27 #ifdef HAVE_CONFIG_H
  28 #include "config.h"
  29 #endif
  30 
  31 /*
  32  * Notes:
  33  *      We define the conversion functions including typecasts since the
  34  * defaults don't necessarily perform appropriate typecasts.
  35  *      Also, using our own functions means that we can change them if it
  36  * turns out that we do need to use the unaligned access macros on
  37  * architectures requiring aligned memory accesses...
  38  */
  39 
  40 #ifdef HAVE_ENDIAN_H
  41 #include <endian.h>
  42 #endif
  43 #ifdef HAVE_SYS_ENDIAN_H
  44 #include <sys/endian.h>
  45 #endif
  46 #ifdef HAVE_MACHINE_ENDIAN_H
  47 #include <machine/endian.h>
  48 #endif
  49 #ifdef HAVE_SYS_BYTEORDER_H
  50 #include <sys/byteorder.h>
  51 #endif
  52 #ifdef HAVE_SYS_PARAM_H
  53 #include <sys/param.h>
  54 #endif
  55 
  56 #ifndef __BYTE_ORDER
  57 #       if defined(_BYTE_ORDER)
  58 #               define __BYTE_ORDER _BYTE_ORDER
  59 #               define __LITTLE_ENDIAN _LITTLE_ENDIAN
  60 #               define __BIG_ENDIAN _BIG_ENDIAN
  61 #       elif defined(BYTE_ORDER)
  62 #               define __BYTE_ORDER BYTE_ORDER
  63 #               define __LITTLE_ENDIAN LITTLE_ENDIAN
  64 #               define __BIG_ENDIAN BIG_ENDIAN
  65 #       elif defined(__BYTE_ORDER__)
  66 #               define __BYTE_ORDER __BYTE_ORDER__
  67 #               define __LITTLE_ENDIAN __LITTLE_ENDIAN__
  68 #               define __BIG_ENDIAN __BIG_ENDIAN__
  69 #       elif (defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)) || \
  70                         defined(WORDS_LITTLEENDIAN)
  71 #               define __BYTE_ORDER 1
  72 #               define __LITTLE_ENDIAN 1
  73 #               define __BIG_ENDIAN 0
  74 #       elif (!defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)) || \
  75                         defined(WORDS_BIGENDIAN)
  76 #               define __BYTE_ORDER 0
  77 #               define __LITTLE_ENDIAN 1
  78 #               define __BIG_ENDIAN 0
  79 #       else
  80 #               error "__BYTE_ORDER is not defined."
  81 #       endif
  82 #endif
  83 
  84 #define __ntfs_bswap_constant_16(x)             \
  85           (u16)((((u16)(x) & 0xff00) >> 8) |  \
  86                 (((u16)(x) & 0x00ff) << 8))
  87 
  88 #define __ntfs_bswap_constant_32(x)                     \
  89           (u32)((((u32)(x) & 0xff000000u) >> 24) |    \
  90                 (((u32)(x) & 0x00ff0000u) >>  8) |    \
  91                 (((u32)(x) & 0x0000ff00u) <<  8) |    \
  92                 (((u32)(x) & 0x000000ffu) << 24))
  93 
  94 #define __ntfs_bswap_constant_64(x)                             \
  95           (u64)((((u64)(x) & 0xff00000000000000ull) >> 56) |  \
  96                 (((u64)(x) & 0x00ff000000000000ull) >> 40) |  \
  97                 (((u64)(x) & 0x0000ff0000000000ull) >> 24) |  \
  98                 (((u64)(x) & 0x000000ff00000000ull) >>  8) |  \
  99                 (((u64)(x) & 0x00000000ff000000ull) <<  8) |  \
 100                 (((u64)(x) & 0x0000000000ff0000ull) << 24) |  \
 101                 (((u64)(x) & 0x000000000000ff00ull) << 40) |  \
 102                 (((u64)(x) & 0x00000000000000ffull) << 56))
 103 
 104 #ifdef HAVE_BYTESWAP_H
 105 #       include <byteswap.h>
 106 #else
 107 #       define bswap_16(x) __ntfs_bswap_constant_16(x)
 108 #       define bswap_32(x) __ntfs_bswap_constant_32(x)
 109 #       define bswap_64(x) __ntfs_bswap_constant_64(x)
 110 #endif
 111 
 112 #if defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN)
 113 
 114 #define __le16_to_cpu(x) ((__force u16)(x))
 115 #define __le32_to_cpu(x) ((__force u32)(x))
 116 #define __le64_to_cpu(x) ((__force u64)(x))
 117 
 118 #define __cpu_to_le16(x) ((__force le16)(x))
 119 #define __cpu_to_le32(x) ((__force le32)(x))
 120 #define __cpu_to_le64(x) ((__force le64)(x))
 121 
 122 #define __constant_le16_to_cpu(x) ((__force u16)(x))
 123 #define __constant_le32_to_cpu(x) ((__force u32)(x))
 124 #define __constant_le64_to_cpu(x) ((__force u64)(x))
 125 
 126 #define __constant_cpu_to_le16(x) ((__force le16)(x))
 127 #define __constant_cpu_to_le32(x) ((__force le32)(x))
 128 #define __constant_cpu_to_le64(x) ((__force le64)(x))
 129 
 130 #elif defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN)
 131 
 132 #define __le16_to_cpu(x) bswap_16((__force u16)(x))
 133 #define __le32_to_cpu(x) bswap_32((__force u16)(x))
 134 #define __le64_to_cpu(x) bswap_64((__force u16)(x))
 135 
 136 #define __cpu_to_le16(x) (__force le16)bswap_16((__force u16)(x))
 137 #define __cpu_to_le32(x) (__force le32)bswap_32((__force u32)(x))
 138 #define __cpu_to_le64(x) (__force le64)bswap_64((__force u64)(x))
 139 
 140 #define __constant_le16_to_cpu(x) __ntfs_bswap_constant_16((__force u16)(x))
 141 #define __constant_le32_to_cpu(x) __ntfs_bswap_constant_32((__force u32)(x))
 142 #define __constant_le64_to_cpu(x) __ntfs_bswap_constant_64((__force u64)(x))
 143 
 144 #define __constant_cpu_to_le16(x) \
 145         (__force le16)__ntfs_bswap_constant_16((__force u16)(x))
 146 #define __constant_cpu_to_le32(x) \
 147         (__force le32)__ntfs_bswap_constant_32((__force u32)(x))
 148 #define __constant_cpu_to_le64(x) \
 149         (__force le64)__ntfs_bswap_constant_64((__force u64)(x))
 150 
 151 #else
 152 
 153 #error "You must define __BYTE_ORDER to be __LITTLE_ENDIAN or __BIG_ENDIAN."
 154 
 155 #endif
 156 
 157 /* Unsigned from LE to CPU conversion. */
 158 
 159 #define le16_to_cpu(x)          (u16)__le16_to_cpu((le16)(x))
 160 #define le32_to_cpu(x)          (u32)__le32_to_cpu((le32)(x))
 161 #define le64_to_cpu(x)          (u64)__le64_to_cpu((le64)(x))
 162 
 163 #define le16_to_cpup(x)         (u16)__le16_to_cpu(*(const le16*)(x))
 164 #define le32_to_cpup(x)         (u32)__le32_to_cpu(*(const le32*)(x))
 165 #define le64_to_cpup(x)         (u64)__le64_to_cpu(*(const le64*)(x))
 166 
 167 /* Signed from LE to CPU conversion. */
 168 
 169 #define sle16_to_cpu(x)         (s16)__le16_to_cpu((sle16)(x))
 170 #define sle32_to_cpu(x)         (s32)__le32_to_cpu((sle32)(x))
 171 #define sle64_to_cpu(x)         (s64)__le64_to_cpu((sle64)(x))
 172 
 173 #define sle16_to_cpup(x)        (s16)__le16_to_cpu(*(const sle16*)(x))
 174 #define sle32_to_cpup(x)        (s32)__le32_to_cpu(*(const sle32*)(x))
 175 #define sle64_to_cpup(x)        (s64)__le64_to_cpu(*(const sle64*)(x))
 176 
 177 /* Unsigned from CPU to LE conversion. */
 178 
 179 #define cpu_to_le16(x)          (le16)__cpu_to_le16((u16)(x))
 180 #define cpu_to_le32(x)          (le32)__cpu_to_le32((u32)(x))
 181 #define cpu_to_le64(x)          (le64)__cpu_to_le64((u64)(x))
 182 
 183 #define cpu_to_le16p(x)         (le16)__cpu_to_le16(*(const u16*)(x))
 184 #define cpu_to_le32p(x)         (le32)__cpu_to_le32(*(const u32*)(x))
 185 #define cpu_to_le64p(x)         (le64)__cpu_to_le64(*(const u64*)(x))
 186 
 187 /* Signed from CPU to LE conversion. */
 188 
 189 #define cpu_to_sle16(x)         (__force sle16)__cpu_to_le16((s16)(x))
 190 #define cpu_to_sle32(x)         (__force sle32)__cpu_to_le32((s32)(x))
 191 #define cpu_to_sle64(x)         (__force sle64)__cpu_to_le64((s64)(x))
 192 
 193 #define cpu_to_sle16p(x)        (__force sle16)__cpu_to_le16(*(const s16*)(x))
 194 #define cpu_to_sle32p(x)        (__force sle32)__cpu_to_le32(*(const s32*)(x))
 195 #define cpu_to_sle64p(x)        (__force sle64)__cpu_to_le64(*(const s64*)(x))
 196 
 197 /* Constant endianness conversion defines. */
 198 
 199 #define const_le16_to_cpu(x)    (u16)__constant_le16_to_cpu((le16)(x))
 200 #define const_le32_to_cpu(x)    (u32)__constant_le32_to_cpu((le32)(x))
 201 #define const_le64_to_cpu(x)    (u64)__constant_le64_to_cpu((le64)(x))
 202 
 203 #define const_cpu_to_le16(x)    (le16)__constant_cpu_to_le16((u16)(x))
 204 #define const_cpu_to_le32(x)    (le32)__constant_cpu_to_le32((u32)(x))
 205 #define const_cpu_to_le64(x)    (le64)__constant_cpu_to_le64((u64)(x))
 206 
 207 #ifdef __CHECKER__
 208 static void ntfs_endian_self_test(void)
 209 {
 210         /* Should not generate warnings. */
 211         (le16)cpu_to_le16((u16)1);
 212         (le32)cpu_to_le32((u32)1);
 213         (le64)cpu_to_le64((u64)1);
 214         (sle16)cpu_to_sle16((s16)1);
 215         (sle32)cpu_to_sle32((s32)1);
 216         (sle64)cpu_to_sle64((s64)1);
 217         (u16)le16_to_cpu((__force le16)1);
 218         (u32)le32_to_cpu((__force le32)1);
 219         (u64)le64_to_cpu((__force le64)1);
 220         (s16)sle16_to_cpu((__force sle16)1);
 221         (s32)sle32_to_cpu((__force sle32)1);
 222         (s64)sle64_to_cpu((__force sle64)1);
 223         (le16)const_cpu_to_le16((u16)1);
 224         (le32)const_cpu_to_le32((u32)1);
 225         (le64)const_cpu_to_le64((u64)1);
 226         (u16)const_le16_to_cpu((__force le16)1);
 227         (u32)const_le32_to_cpu((__force le32)1);
 228         (u64)const_le64_to_cpu((__force le64)1);
 229 
 230         /*
 231          * TODO: Need some how to test that warnings are actually generated,
 232          * but without flooding output with them and vice-versa print warning
 233          * in case if some one warning is not triggered, but should.  (Yura)
 234          *
 235          * I think it can only be done in  a ./configure like script / shell
 236          * script that will compile known good  and known bad code and pipe the
 237          * output from sparse to a file, then  grep the file for the wanted
 238          * warnings/lack thereof and then it would  say "Tests: PASS " or
 239          * "Tests: FAILED" or whatever.  And you can then  hook that into a
 240          * "make test" make target or similar so it is only  done when one
 241          * wants to do it...  (Anton)
 242          *
 243          * Also we can look on sparse self test script.  (Yura)
 244          */
 245 }
 246 #endif
 247 
 248 #endif /* defined _NTFS_ENDIANS_H */