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