1 /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- 2 * 3 * Copyright (c) 2014-2015 Datalight, Inc. 4 * All Rights Reserved Worldwide. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; use version 2 of the License. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty 12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 /* Businesses and individuals that for commercial or other reasons cannot 21 * comply with the terms of the GPLv2 license may obtain a commercial license 22 * before incorporating Reliance Edge into proprietary software for 23 * distribution in any form. Visit http://www.datalight.com/reliance-edge for 24 * more information. 25 */ 26 27 /** @file 28 * @brief This header contains macros which deviate from MISRA C:2012 29 */ 30 #ifndef REDDEVIATIONS_H 31 #define REDDEVIATIONS_H 32 33 34 /** @brief Append a suffix to a constant so that it is an unsigned 64-bit value. 35 * 36 * Usages of this macro deviate from MISRA C:2012 Rule 1.2 (advisory). The 37 * rule prohibits the use of language extensions. The ULL suffix became part 38 * of the C standard with C99. Since this code base adheres to C89, use of 39 * this suffix is a language extension. Reliance Edge needs to deal with 40 * 64-bit quantities, which by convention are explicitly suffixed. In at 41 * least one case, with the INODE_SIZE_MAX macro, the code needs a way to force 42 * a constant to be 64-bits even though its value is not so large that it would 43 * be automatically promoted to 64-bits. Thus the need for this macro and the 44 * deviation. In practice, the ULL suffix has proven to be a nearly universal 45 * extension among C89 compilers. 46 * 47 * As rule 19.2 is advisory, a deviation record is not required. This notice 48 * is the only record of the deviation. PC-Lint does not issue an error for 49 * this deviation so there is no error inhibition option. 50 * 51 * Usages of this macro also deviate from MISRA C:2012 Rule 20.10 (advisory). 52 * The rule prohibits use of the ## preprocessor operator. The code is not 53 * obscure, and the operator is used only once, so this is deemed to be safe. 54 * 55 * As rule 20.10 is advisory, a deviation record is not required. This notice 56 * is the only record of the deviation. 57 * 58 * Consistent use of this macro, even in non MISRA C code, is encouraged to 59 * make it easier to search for 64-bit values. 60 * 61 */ 62 #define UINT64_SUFFIX( number ) ( number ## ULL ) 63 64 65 /** @brief Append a suffix to a constant so that it is a signed 64-bit value. 66 * 67 * Usages of this macro deviate from MISRA C:2012 Rule 1.2 (advisory). See the 68 * description of UINT64_SUFFIX() for details. 69 * 70 * Usages of this macro deviate from MISRA C:2012 Rule 20.10 (advisory). See 71 * the description of UINT64_SUFFIX() for details. 72 */ 73 #define INT64_SUFFIX( number ) ( number ## LL ) 74 75 76 /** @brief Cast a pointer to a const uint8_t pointer. 77 * 78 * All usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory). 79 * Because there are no alignment requirements for a uint8_t pointer, this is 80 * safe. However, it is technically a deviation from the rule. 81 * 82 * As Rule 11.5 is advisory, a deviation record is not required. This notice 83 * and the PC-Lint error inhibition option are the only records of the 84 * deviation. 85 */ 86 #define CAST_VOID_PTR_TO_CONST_UINT8_PTR( PTR ) ( ( const uint8_t * ) ( PTR ) ) 87 88 89 /** @brief Cast a pointer to a uint8_t pointer. 90 * 91 * All usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory). 92 * Because there are no alignment requirements for a uint8_t pointer, this is 93 * safe. However, it is technically a deviation from the rule. 94 * 95 * As Rule 11.5 is advisory, a deviation record is not required. This notice 96 * and the PC-Lint error inhibition option are the only records of the 97 * deviation. 98 */ 99 #define CAST_VOID_PTR_TO_UINT8_PTR( PTR ) ( ( uint8_t * ) ( PTR ) ) 100 101 102 /** @brief Cast a pointer to a const uint32_t pointer. 103 * 104 * Usages of this macro may deviate from MISRA C:2012 Rule 11.5 (advisory). 105 * It is only used in cases where the pointer is known to be aligned, and thus 106 * it is safe to do so. 107 * 108 * As Rule 11.5 is advisory, a deviation record is not required. This notice 109 * and the PC-Lint error inhibition option are the only records of the 110 * deviation. 111 * 112 * Usages of this macro may deviate from MISRA C:2012 Rule 11.3 (required). 113 * As Rule 11.3 is required, a separate deviation record is required. 114 * 115 * Regarding the cast to (const void *): this is there to placate some 116 * compilers which emit warnings when a type with lower alignment requirements 117 * (such as const uint8_t *) is cast to a type with higher alignment 118 * requirements. In the places where this macro is used, the pointer is 119 * checked to be of sufficient alignment. 120 */ 121 #define CAST_CONST_UINT32_PTR( PTR ) ( ( const uint32_t * ) ( const void * ) ( PTR ) ) 122 123 124 /** @brief Cast a pointer to a pointer to (void **). 125 * 126 * Usages of this macro deviate from MISRA C:2012 Rule 11.3 (required). 127 * It is only used for populating a node structure pointer with a buffer 128 * pointer. Buffer pointers are 8-byte aligned, thus it is safe to do so. 129 * 130 * As Rule 11.3 is required, a separate deviation record is required. 131 */ 132 #define CAST_VOID_PTR_PTR( PTRPTR ) ( ( void ** ) ( PTRPTR ) ) 133 134 135 /** @brief Create a two-dimensional byte array which is safely aligned. 136 * 137 * Usages of this macro deviate from MISRA C:2012 Rule 19.2 (advisory). 138 * A union is required to force alignment of the block buffers, which are used 139 * to access metadata nodes, which must be safely aligned for 64-bit types. 140 * 141 * As rule 19.2 is advisory, a deviation record is not required. This notice 142 * and the PC-Lint error inhibition option are the only records of the 143 * deviation. 144 */ 145 #define ALIGNED_2D_BYTE_ARRAY( un, nam, size1, size2 ) \ 146 union \ 147 { \ 148 uint8_t nam[ size1 ][ size2 ]; \ 149 uint64_t DummyAlign; \ 150 } \ 151 un 152 153 154 /** @brief Determine whether RedMemMove() must copy memory in the forward 155 * direction, instead of in the reverse. 156 * 157 * In order to copy between overlapping memory regions, RedMemMove() must copy 158 * forward if the destination memory is lower, and backward if the destination 159 * memory is higher. Failure to do so would yield incorrect results. 160 * 161 * The only way to make this determination without gross inefficiency is to 162 * use pointer comparison. Pointer comparisons are undefined unless both 163 * pointers point within the same object or array (or one element past the end 164 * of the array); see section 6.3.8 of ANSI C89. While RedMemMove() is 165 * normally only used when memory regions overlap, which would not result in 166 * undefined behavior, it (like memmove()) is supposed to work even for non- 167 * overlapping regions, which would make this function invoke undefined 168 * behavior. Experience has shown the pointer comparisons of this sort behave 169 * intuitively on common platforms, even though the behavior is undefined. For 170 * those platforms where this is not the case, this implementation of memmove() 171 * should be replaced with an alternate one. 172 * 173 * Usages of this macro deviate from MISRA-C:2012 Rule 18.3 (required). As 174 * Rule 18.3 is required, a separate deviation record is required. 175 */ 176 #define MEMMOVE_MUST_COPY_FORWARD( dest, src ) ( ( dest ) < ( src ) ) 177 178 179 /** @brief Cast a pointer to a (const DIRENT *). 180 * 181 * Usages of this macro deviate from MISRA-C:2012 Rule 11.3 (required). 182 * It is used for populating a directory entry structure pointer with a 183 * buffer pointer. Buffer pointers are 8-byte aligned, and DIRENT only 184 * requires 4-byte alignment, thus the typecast is safe. 185 * 186 * As Rule 11.3 is required, a separate deviation record is required. 187 */ 188 #define CAST_CONST_DIRENT_PTR( PTR ) ( ( const DIRENT * ) ( PTR ) ) 189 190 191 /** @brief Determine whether a pointer is aligned. 192 * 193 * A pointer is aligned if its address is an even multiple of 194 * ::REDCONF_ALIGNMENT_SIZE. 195 * 196 * This is used in the slice-by-8 RedCrc32Update() function, which needs to 197 * know whether a pointer is aligned, since the slice-by-8 algorithm needs to 198 * access the memory in an aligned fashion, and if the pointer is not aligned, 199 * this can result in faults or suboptimal performance (depending on platform). 200 * 201 * There is no way to perform this check without deviating from MISRA C rules 202 * against casting pointers to integer types. Usage of this macro deviates 203 * from MISRA C:2012 Rule 11.4 (advisory). The main rationale the rule cites 204 * against converting pointers to integers is that the chosen integer type may 205 * not be able to represent the pointer; this is a non-issue here since we use 206 * uintptr_t. The text says the rule still applies when using uintptr_t due to 207 * concern about unaligned pointers, but that is not an issue here since the 208 * integer value of the pointer is not saved and not converted back into a 209 * pointer and dereferenced. The result of casting a pointer to a sufficiently 210 * large integer is implementation-defined, but macros similar to this one have 211 * been used by Datalight for a long time in a wide variety of environments and 212 * they have always worked as expected. 213 * 214 * As Rule 11.4 is advisory, a deviation record is not required. This notice 215 * and the PC-Lint error inhibition option are the only records of the 216 * deviation. 217 * 218 * @note PC-Lint also thinks this macro as it is used below violates Rule 11.6 219 * (required). This is a false positive, since Rule 11.6 only applies to 220 * void pointers. Below, we use it on a pointer-to-object (uint8_t *), 221 * which is covered by Rule 11.4. 222 */ 223 #define IS_ALIGNED_PTR( ptr ) ( ( ( uintptr_t ) ( ptr ) & ( REDCONF_ALIGNMENT_SIZE - 1U ) ) == 0U ) 224 225 226 #endif /* ifndef REDDEVIATIONS_H */ 227