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