1 /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3- 1 /* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */ 2 /* 2 /* 3 * Copyright (c) Yann Collet, Facebook, Inc. 3 * Copyright (c) Yann Collet, Facebook, Inc. 4 * All rights reserved. 4 * All rights reserved. 5 * 5 * 6 * This source code is licensed under both the 6 * This source code is licensed under both the BSD-style license (found in the 7 * LICENSE file in the root directory of this 7 * LICENSE file in the root directory of this source tree) and the GPLv2 (found 8 * in the COPYING file in the root directory o 8 * in the COPYING file in the root directory of this source tree). 9 * You may select, at your option, one of the 9 * You may select, at your option, one of the above-listed licenses. 10 */ 10 */ 11 11 12 #ifndef MEM_H_MODULE 12 #ifndef MEM_H_MODULE 13 #define MEM_H_MODULE 13 #define MEM_H_MODULE 14 14 15 /*-**************************************** 15 /*-**************************************** 16 * Dependencies 16 * Dependencies 17 ******************************************/ 17 ******************************************/ 18 #include <linux/unaligned.h> /* get_unaligned !! 18 #include <asm/unaligned.h> /* get_unaligned, put_unaligned* */ 19 #include <linux/compiler.h> /* inline */ 19 #include <linux/compiler.h> /* inline */ 20 #include <linux/swab.h> /* swab32, swab64 */ 20 #include <linux/swab.h> /* swab32, swab64 */ 21 #include <linux/types.h> /* size_t, ptrdiff_t 21 #include <linux/types.h> /* size_t, ptrdiff_t */ 22 #include "debug.h" /* DEBUG_STATIC_ASSERT */ 22 #include "debug.h" /* DEBUG_STATIC_ASSERT */ 23 23 24 /*-**************************************** 24 /*-**************************************** 25 * Compiler specifics 25 * Compiler specifics 26 ******************************************/ 26 ******************************************/ 27 #define MEM_STATIC static inline 27 #define MEM_STATIC static inline 28 28 29 /*-******************************************* 29 /*-************************************************************** 30 * Basic Types 30 * Basic Types 31 ********************************************** 31 *****************************************************************/ 32 typedef uint8_t BYTE; 32 typedef uint8_t BYTE; 33 typedef uint8_t U8; << 34 typedef int8_t S8; << 35 typedef uint16_t U16; 33 typedef uint16_t U16; 36 typedef int16_t S16; 34 typedef int16_t S16; 37 typedef uint32_t U32; 35 typedef uint32_t U32; 38 typedef int32_t S32; 36 typedef int32_t S32; 39 typedef uint64_t U64; 37 typedef uint64_t U64; 40 typedef int64_t S64; 38 typedef int64_t S64; 41 39 42 /*-******************************************* 40 /*-************************************************************** 43 * Memory I/O API 41 * Memory I/O API 44 ********************************************** 42 *****************************************************************/ 45 /*=== Static platform detection ===*/ 43 /*=== Static platform detection ===*/ 46 MEM_STATIC unsigned MEM_32bits(void); 44 MEM_STATIC unsigned MEM_32bits(void); 47 MEM_STATIC unsigned MEM_64bits(void); 45 MEM_STATIC unsigned MEM_64bits(void); 48 MEM_STATIC unsigned MEM_isLittleEndian(void); 46 MEM_STATIC unsigned MEM_isLittleEndian(void); 49 47 50 /*=== Native unaligned read/write ===*/ 48 /*=== Native unaligned read/write ===*/ 51 MEM_STATIC U16 MEM_read16(const void* memPtr); 49 MEM_STATIC U16 MEM_read16(const void* memPtr); 52 MEM_STATIC U32 MEM_read32(const void* memPtr); 50 MEM_STATIC U32 MEM_read32(const void* memPtr); 53 MEM_STATIC U64 MEM_read64(const void* memPtr); 51 MEM_STATIC U64 MEM_read64(const void* memPtr); 54 MEM_STATIC size_t MEM_readST(const void* memPt 52 MEM_STATIC size_t MEM_readST(const void* memPtr); 55 53 56 MEM_STATIC void MEM_write16(void* memPtr, U16 54 MEM_STATIC void MEM_write16(void* memPtr, U16 value); 57 MEM_STATIC void MEM_write32(void* memPtr, U32 55 MEM_STATIC void MEM_write32(void* memPtr, U32 value); 58 MEM_STATIC void MEM_write64(void* memPtr, U64 56 MEM_STATIC void MEM_write64(void* memPtr, U64 value); 59 57 60 /*=== Little endian unaligned read/write ===*/ 58 /*=== Little endian unaligned read/write ===*/ 61 MEM_STATIC U16 MEM_readLE16(const void* memPtr 59 MEM_STATIC U16 MEM_readLE16(const void* memPtr); 62 MEM_STATIC U32 MEM_readLE24(const void* memPtr 60 MEM_STATIC U32 MEM_readLE24(const void* memPtr); 63 MEM_STATIC U32 MEM_readLE32(const void* memPtr 61 MEM_STATIC U32 MEM_readLE32(const void* memPtr); 64 MEM_STATIC U64 MEM_readLE64(const void* memPtr 62 MEM_STATIC U64 MEM_readLE64(const void* memPtr); 65 MEM_STATIC size_t MEM_readLEST(const void* mem 63 MEM_STATIC size_t MEM_readLEST(const void* memPtr); 66 64 67 MEM_STATIC void MEM_writeLE16(void* memPtr, U1 65 MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val); 68 MEM_STATIC void MEM_writeLE24(void* memPtr, U3 66 MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val); 69 MEM_STATIC void MEM_writeLE32(void* memPtr, U3 67 MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32); 70 MEM_STATIC void MEM_writeLE64(void* memPtr, U6 68 MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64); 71 MEM_STATIC void MEM_writeLEST(void* memPtr, si 69 MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val); 72 70 73 /*=== Big endian unaligned read/write ===*/ 71 /*=== Big endian unaligned read/write ===*/ 74 MEM_STATIC U32 MEM_readBE32(const void* memPtr 72 MEM_STATIC U32 MEM_readBE32(const void* memPtr); 75 MEM_STATIC U64 MEM_readBE64(const void* memPtr 73 MEM_STATIC U64 MEM_readBE64(const void* memPtr); 76 MEM_STATIC size_t MEM_readBEST(const void* mem 74 MEM_STATIC size_t MEM_readBEST(const void* memPtr); 77 75 78 MEM_STATIC void MEM_writeBE32(void* memPtr, U3 76 MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32); 79 MEM_STATIC void MEM_writeBE64(void* memPtr, U6 77 MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64); 80 MEM_STATIC void MEM_writeBEST(void* memPtr, si 78 MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val); 81 79 82 /*=== Byteswap ===*/ 80 /*=== Byteswap ===*/ 83 MEM_STATIC U32 MEM_swap32(U32 in); 81 MEM_STATIC U32 MEM_swap32(U32 in); 84 MEM_STATIC U64 MEM_swap64(U64 in); 82 MEM_STATIC U64 MEM_swap64(U64 in); 85 MEM_STATIC size_t MEM_swapST(size_t in); 83 MEM_STATIC size_t MEM_swapST(size_t in); 86 84 87 /*-******************************************* 85 /*-************************************************************** 88 * Memory I/O Implementation 86 * Memory I/O Implementation 89 ********************************************** 87 *****************************************************************/ 90 MEM_STATIC unsigned MEM_32bits(void) 88 MEM_STATIC unsigned MEM_32bits(void) 91 { 89 { 92 return sizeof(size_t) == 4; 90 return sizeof(size_t) == 4; 93 } 91 } 94 92 95 MEM_STATIC unsigned MEM_64bits(void) 93 MEM_STATIC unsigned MEM_64bits(void) 96 { 94 { 97 return sizeof(size_t) == 8; 95 return sizeof(size_t) == 8; 98 } 96 } 99 97 100 #if defined(__LITTLE_ENDIAN) 98 #if defined(__LITTLE_ENDIAN) 101 #define MEM_LITTLE_ENDIAN 1 99 #define MEM_LITTLE_ENDIAN 1 102 #else 100 #else 103 #define MEM_LITTLE_ENDIAN 0 101 #define MEM_LITTLE_ENDIAN 0 104 #endif 102 #endif 105 103 106 MEM_STATIC unsigned MEM_isLittleEndian(void) 104 MEM_STATIC unsigned MEM_isLittleEndian(void) 107 { 105 { 108 return MEM_LITTLE_ENDIAN; 106 return MEM_LITTLE_ENDIAN; 109 } 107 } 110 108 111 MEM_STATIC U16 MEM_read16(const void *memPtr) 109 MEM_STATIC U16 MEM_read16(const void *memPtr) 112 { 110 { 113 return get_unaligned((const U16 *)memPtr); 111 return get_unaligned((const U16 *)memPtr); 114 } 112 } 115 113 116 MEM_STATIC U32 MEM_read32(const void *memPtr) 114 MEM_STATIC U32 MEM_read32(const void *memPtr) 117 { 115 { 118 return get_unaligned((const U32 *)memPtr); 116 return get_unaligned((const U32 *)memPtr); 119 } 117 } 120 118 121 MEM_STATIC U64 MEM_read64(const void *memPtr) 119 MEM_STATIC U64 MEM_read64(const void *memPtr) 122 { 120 { 123 return get_unaligned((const U64 *)memPtr); 121 return get_unaligned((const U64 *)memPtr); 124 } 122 } 125 123 126 MEM_STATIC size_t MEM_readST(const void *memPt 124 MEM_STATIC size_t MEM_readST(const void *memPtr) 127 { 125 { 128 return get_unaligned((const size_t *)memPt 126 return get_unaligned((const size_t *)memPtr); 129 } 127 } 130 128 131 MEM_STATIC void MEM_write16(void *memPtr, U16 129 MEM_STATIC void MEM_write16(void *memPtr, U16 value) 132 { 130 { 133 put_unaligned(value, (U16 *)memPtr); 131 put_unaligned(value, (U16 *)memPtr); 134 } 132 } 135 133 136 MEM_STATIC void MEM_write32(void *memPtr, U32 134 MEM_STATIC void MEM_write32(void *memPtr, U32 value) 137 { 135 { 138 put_unaligned(value, (U32 *)memPtr); 136 put_unaligned(value, (U32 *)memPtr); 139 } 137 } 140 138 141 MEM_STATIC void MEM_write64(void *memPtr, U64 139 MEM_STATIC void MEM_write64(void *memPtr, U64 value) 142 { 140 { 143 put_unaligned(value, (U64 *)memPtr); 141 put_unaligned(value, (U64 *)memPtr); 144 } 142 } 145 143 146 /*=== Little endian r/w ===*/ 144 /*=== Little endian r/w ===*/ 147 145 148 MEM_STATIC U16 MEM_readLE16(const void *memPtr 146 MEM_STATIC U16 MEM_readLE16(const void *memPtr) 149 { 147 { 150 return get_unaligned_le16(memPtr); 148 return get_unaligned_le16(memPtr); 151 } 149 } 152 150 153 MEM_STATIC void MEM_writeLE16(void *memPtr, U1 151 MEM_STATIC void MEM_writeLE16(void *memPtr, U16 val) 154 { 152 { 155 put_unaligned_le16(val, memPtr); 153 put_unaligned_le16(val, memPtr); 156 } 154 } 157 155 158 MEM_STATIC U32 MEM_readLE24(const void *memPtr 156 MEM_STATIC U32 MEM_readLE24(const void *memPtr) 159 { 157 { 160 return MEM_readLE16(memPtr) + (((const BYT 158 return MEM_readLE16(memPtr) + (((const BYTE *)memPtr)[2] << 16); 161 } 159 } 162 160 163 MEM_STATIC void MEM_writeLE24(void *memPtr, U3 161 MEM_STATIC void MEM_writeLE24(void *memPtr, U32 val) 164 { 162 { 165 MEM_writeLE16(memPtr, (U16)val); 163 MEM_writeLE16(memPtr, (U16)val); 166 ((BYTE *)memPtr)[2] = (BYTE)(val >> 16 164 ((BYTE *)memPtr)[2] = (BYTE)(val >> 16); 167 } 165 } 168 166 169 MEM_STATIC U32 MEM_readLE32(const void *memPtr 167 MEM_STATIC U32 MEM_readLE32(const void *memPtr) 170 { 168 { 171 return get_unaligned_le32(memPtr); 169 return get_unaligned_le32(memPtr); 172 } 170 } 173 171 174 MEM_STATIC void MEM_writeLE32(void *memPtr, U3 172 MEM_STATIC void MEM_writeLE32(void *memPtr, U32 val32) 175 { 173 { 176 put_unaligned_le32(val32, memPtr); 174 put_unaligned_le32(val32, memPtr); 177 } 175 } 178 176 179 MEM_STATIC U64 MEM_readLE64(const void *memPtr 177 MEM_STATIC U64 MEM_readLE64(const void *memPtr) 180 { 178 { 181 return get_unaligned_le64(memPtr); 179 return get_unaligned_le64(memPtr); 182 } 180 } 183 181 184 MEM_STATIC void MEM_writeLE64(void *memPtr, U6 182 MEM_STATIC void MEM_writeLE64(void *memPtr, U64 val64) 185 { 183 { 186 put_unaligned_le64(val64, memPtr); 184 put_unaligned_le64(val64, memPtr); 187 } 185 } 188 186 189 MEM_STATIC size_t MEM_readLEST(const void *mem 187 MEM_STATIC size_t MEM_readLEST(const void *memPtr) 190 { 188 { 191 if (MEM_32bits()) 189 if (MEM_32bits()) 192 return (size_t)MEM_readLE32(me 190 return (size_t)MEM_readLE32(memPtr); 193 else 191 else 194 return (size_t)MEM_readLE64(me 192 return (size_t)MEM_readLE64(memPtr); 195 } 193 } 196 194 197 MEM_STATIC void MEM_writeLEST(void *memPtr, si 195 MEM_STATIC void MEM_writeLEST(void *memPtr, size_t val) 198 { 196 { 199 if (MEM_32bits()) 197 if (MEM_32bits()) 200 MEM_writeLE32(memPtr, (U32)val 198 MEM_writeLE32(memPtr, (U32)val); 201 else 199 else 202 MEM_writeLE64(memPtr, (U64)val 200 MEM_writeLE64(memPtr, (U64)val); 203 } 201 } 204 202 205 /*=== Big endian r/w ===*/ 203 /*=== Big endian r/w ===*/ 206 204 207 MEM_STATIC U32 MEM_readBE32(const void *memPtr 205 MEM_STATIC U32 MEM_readBE32(const void *memPtr) 208 { 206 { 209 return get_unaligned_be32(memPtr); 207 return get_unaligned_be32(memPtr); 210 } 208 } 211 209 212 MEM_STATIC void MEM_writeBE32(void *memPtr, U3 210 MEM_STATIC void MEM_writeBE32(void *memPtr, U32 val32) 213 { 211 { 214 put_unaligned_be32(val32, memPtr); 212 put_unaligned_be32(val32, memPtr); 215 } 213 } 216 214 217 MEM_STATIC U64 MEM_readBE64(const void *memPtr 215 MEM_STATIC U64 MEM_readBE64(const void *memPtr) 218 { 216 { 219 return get_unaligned_be64(memPtr); 217 return get_unaligned_be64(memPtr); 220 } 218 } 221 219 222 MEM_STATIC void MEM_writeBE64(void *memPtr, U6 220 MEM_STATIC void MEM_writeBE64(void *memPtr, U64 val64) 223 { 221 { 224 put_unaligned_be64(val64, memPtr); 222 put_unaligned_be64(val64, memPtr); 225 } 223 } 226 224 227 MEM_STATIC size_t MEM_readBEST(const void *mem 225 MEM_STATIC size_t MEM_readBEST(const void *memPtr) 228 { 226 { 229 if (MEM_32bits()) 227 if (MEM_32bits()) 230 return (size_t)MEM_readBE32(me 228 return (size_t)MEM_readBE32(memPtr); 231 else 229 else 232 return (size_t)MEM_readBE64(me 230 return (size_t)MEM_readBE64(memPtr); 233 } 231 } 234 232 235 MEM_STATIC void MEM_writeBEST(void *memPtr, si 233 MEM_STATIC void MEM_writeBEST(void *memPtr, size_t val) 236 { 234 { 237 if (MEM_32bits()) 235 if (MEM_32bits()) 238 MEM_writeBE32(memPtr, (U32)val 236 MEM_writeBE32(memPtr, (U32)val); 239 else 237 else 240 MEM_writeBE64(memPtr, (U64)val 238 MEM_writeBE64(memPtr, (U64)val); 241 } 239 } 242 240 243 MEM_STATIC U32 MEM_swap32(U32 in) 241 MEM_STATIC U32 MEM_swap32(U32 in) 244 { 242 { 245 return swab32(in); 243 return swab32(in); 246 } 244 } 247 245 248 MEM_STATIC U64 MEM_swap64(U64 in) 246 MEM_STATIC U64 MEM_swap64(U64 in) 249 { 247 { 250 return swab64(in); 248 return swab64(in); 251 } 249 } 252 250 253 MEM_STATIC size_t MEM_swapST(size_t in) 251 MEM_STATIC size_t MEM_swapST(size_t in) 254 { 252 { 255 if (MEM_32bits()) 253 if (MEM_32bits()) 256 return (size_t)MEM_swap32((U32)in); 254 return (size_t)MEM_swap32((U32)in); 257 else 255 else 258 return (size_t)MEM_swap64((U64)in); 256 return (size_t)MEM_swap64((U64)in); 259 } 257 } 260 258 261 #endif /* MEM_H_MODULE */ 259 #endif /* MEM_H_MODULE */ 262 260
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.