| /* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- | |
| Copyright (c) 2014-2015 Datalight, Inc. | |
| All Rights Reserved Worldwide. | |
| This program is free software; you can redistribute it and/or modify | |
| it under the terms of the GNU General Public License as published by | |
| the Free Software Foundation; use version 2 of the License. | |
| This program is distributed in the hope that it will be useful, | |
| but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty | |
| of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| GNU General Public License for more details. | |
| You should have received a copy of the GNU General Public License along | |
| with this program; if not, write to the Free Software Foundation, Inc., | |
| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
| */ | |
| /* Businesses and individuals that for commercial or other reasons cannot | |
| comply with the terms of the GPLv2 license may obtain a commercial license | |
| before incorporating Reliance Edge into proprietary software for | |
| distribution in any form. Visit http://www.datalight.com/reliance-edge for | |
| more information. | |
| */ | |
| /** @file | |
| @brief This header contains macros which deviate from MISRA C:2012 | |
| */ | |
| #ifndef REDDEVIATIONS_H | |
| #define REDDEVIATIONS_H | |
| /** @brief Append a suffix to a constant so that it is an unsigned 64-bit value. | |
| Usages of this macro deviate from MISRA C:2012 Rule 1.2 (advisory). The | |
| rule prohibits the use of language extensions. The ULL suffix became part | |
| of the C standard with C99. Since this code base adheres to C89, use of | |
| this suffix is a language extension. Reliance Edge needs to deal with | |
| 64-bit quantities, which by convention are explicitly suffixed. In at | |
| least one case, with the INODE_SIZE_MAX macro, the code needs a way to force | |
| a constant to be 64-bits even though its value is not so large that it would | |
| be automatically promoted to 64-bits. Thus the need for this macro and the | |
| deviation. In practice, the ULL suffix has proven to be a nearly universal | |
| extension among C89 compilers. | |
| As rule 19.2 is advisory, a deviation record is not required. This notice | |
| is the only record of the deviation. PC-Lint does not issue an error for | |
| this deviation so there is no error inhibition option. | |
| Usages of this macro also deviate from MISRA C:2012 Rule 20.10 (advisory). | |
| The rule prohibits use of the ## preprocessor operator. The code is not | |
| obscure, and the operator is used only once, so this is deemed to be safe. | |
| As rule 20.10 is advisory, a deviation record is not required. This notice | |
| is the only record of the deviation. | |
| Consistent use of this macro, even in non MISRA C code, is encouraged to | |
| make it easier to search for 64-bit values. | |
| */ | |
| #define UINT64_SUFFIX(number) (number##ULL) | |
| /** @brief Append a suffix to a constant so that it is a signed 64-bit value. | |
| Usages of this macro deviate from MISRA C:2012 Rule 1.2 (advisory). See the | |
| description of UINT64_SUFFIX() for details. | |
| Usages of this macro deviate from MISRA C:2012 Rule 20.10 (advisory). See | |
| the description of UINT64_SUFFIX() for details. | |
| */ | |
| #define INT64_SUFFIX(number) (number##LL) | |
| /** @brief Cast a pointer to a const uint8_t pointer. | |
| All usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory). | |
| Because there are no alignment requirements for a uint8_t pointer, this is | |
| safe. However, it is technically a deviation from the rule. | |
| As Rule 11.5 is advisory, a deviation record is not required. This notice | |
| and the PC-Lint error inhibition option are the only records of the | |
| deviation. | |
| */ | |
| #define CAST_VOID_PTR_TO_CONST_UINT8_PTR(PTR) ((const uint8_t *)(PTR)) | |
| /** @brief Cast a pointer to a uint8_t pointer. | |
| All usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory). | |
| Because there are no alignment requirements for a uint8_t pointer, this is | |
| safe. However, it is technically a deviation from the rule. | |
| As Rule 11.5 is advisory, a deviation record is not required. This notice | |
| and the PC-Lint error inhibition option are the only records of the | |
| deviation. | |
| */ | |
| #define CAST_VOID_PTR_TO_UINT8_PTR(PTR) ((uint8_t *)(PTR)) | |
| /** @brief Cast a pointer to a const uint32_t pointer. | |
| Usages of this macro may deviate from MISRA C:2012 Rule 11.5 (advisory). | |
| It is only used in cases where the pointer is known to be aligned, and thus | |
| it is safe to do so. | |
| As Rule 11.5 is advisory, a deviation record is not required. This notice | |
| and the PC-Lint error inhibition option are the only records of the | |
| deviation. | |
| Usages of this macro may deviate from MISRA C:2012 Rule 11.3 (required). | |
| As Rule 11.3 is required, a separate deviation record is required. | |
| Regarding the cast to (const void *): this is there to placate some | |
| compilers which emit warnings when a type with lower alignment requirements | |
| (such as const uint8_t *) is cast to a type with higher alignment | |
| requirements. In the places where this macro is used, the pointer is | |
| checked to be of sufficient alignment. | |
| */ | |
| #define CAST_CONST_UINT32_PTR(PTR) ((const uint32_t *)(const void *)(PTR)) | |
| /** @brief Cast a pointer to a pointer to (void **). | |
| Usages of this macro deviate from MISRA C:2012 Rule 11.3 (required). | |
| It is only used for populating a node structure pointer with a buffer | |
| pointer. Buffer pointers are 8-byte aligned, thus it is safe to do so. | |
| As Rule 11.3 is required, a separate deviation record is required. | |
| */ | |
| #define CAST_VOID_PTR_PTR(PTRPTR) ((void **)(PTRPTR)) | |
| /** @brief Create a two-dimensional byte array which is safely aligned. | |
| Usages of this macro deviate from MISRA C:2012 Rule 19.2 (advisory). | |
| A union is required to force alignment of the block buffers, which are used | |
| to access metadata nodes, which must be safely aligned for 64-bit types. | |
| As rule 19.2 is advisory, a deviation record is not required. This notice | |
| and the PC-Lint error inhibition option are the only records of the | |
| deviation. | |
| */ | |
| #define ALIGNED_2D_BYTE_ARRAY(un, nam, size1, size2) \ | |
| union \ | |
| { \ | |
| uint8_t nam[size1][size2]; \ | |
| uint64_t DummyAlign; \ | |
| } un | |
| /** @brief Determine whether RedMemMove() must copy memory in the forward | |
| direction, instead of in the reverse. | |
| In order to copy between overlapping memory regions, RedMemMove() must copy | |
| forward if the destination memory is lower, and backward if the destination | |
| memory is higher. Failure to do so would yield incorrect results. | |
| The only way to make this determination without gross inefficiency is to | |
| use pointer comparison. Pointer comparisons are undefined unless both | |
| pointers point within the same object or array (or one element past the end | |
| of the array); see section 6.3.8 of ANSI C89. While RedMemMove() is | |
| normally only used when memory regions overlap, which would not result in | |
| undefined behavior, it (like memmove()) is supposed to work even for non- | |
| overlapping regions, which would make this function invoke undefined | |
| behavior. Experience has shown the pointer comparisons of this sort behave | |
| intuitively on common platforms, even though the behavior is undefined. For | |
| those platforms where this is not the case, this implementation of memmove() | |
| should be replaced with an alternate one. | |
| Usages of this macro deviate from MISRA-C:2012 Rule 18.3 (required). As | |
| Rule 18.3 is required, a separate deviation record is required. | |
| */ | |
| #define MEMMOVE_MUST_COPY_FORWARD(dest, src) ((dest) < (src)) | |
| /** @brief Cast a pointer to a (const DIRENT *). | |
| Usages of this macro deviate from MISRA-C:2012 Rule 11.3 (required). | |
| It is used for populating a directory entry structure pointer with a | |
| buffer pointer. Buffer pointers are 8-byte aligned, and DIRENT only | |
| requires 4-byte alignment, thus the typecast is safe. | |
| As Rule 11.3 is required, a separate deviation record is required. | |
| */ | |
| #define CAST_CONST_DIRENT_PTR(PTR) ((const DIRENT *)(PTR)) | |
| /** @brief Determine whether a pointer is aligned. | |
| A pointer is aligned if its address is an even multiple of | |
| ::REDCONF_ALIGNMENT_SIZE. | |
| This is used in the slice-by-8 RedCrc32Update() function, which needs to | |
| know whether a pointer is aligned, since the slice-by-8 algorithm needs to | |
| access the memory in an aligned fashion, and if the pointer is not aligned, | |
| this can result in faults or suboptimal performance (depending on platform). | |
| There is no way to perform this check without deviating from MISRA C rules | |
| against casting pointers to integer types. Usage of this macro deviates | |
| from MISRA C:2012 Rule 11.4 (advisory). The main rationale the rule cites | |
| against converting pointers to integers is that the chosen integer type may | |
| not be able to represent the pointer; this is a non-issue here since we use | |
| uintptr_t. The text says the rule still applies when using uintptr_t due to | |
| concern about unaligned pointers, but that is not an issue here since the | |
| integer value of the pointer is not saved and not converted back into a | |
| pointer and dereferenced. The result of casting a pointer to a sufficiently | |
| large integer is implementation-defined, but macros similar to this one have | |
| been used by Datalight for a long time in a wide variety of environments and | |
| they have always worked as expected. | |
| As Rule 11.4 is advisory, a deviation record is not required. This notice | |
| and the PC-Lint error inhibition option are the only records of the | |
| deviation. | |
| @note PC-Lint also thinks this macro as it is used below violates Rule 11.6 | |
| (required). This is a false positive, since Rule 11.6 only applies to | |
| void pointers. Below, we use it on a pointer-to-object (uint8_t *), | |
| which is covered by Rule 11.4. | |
| */ | |
| #define IS_ALIGNED_PTR(ptr) (((uintptr_t)(ptr) & (REDCONF_ALIGNMENT_SIZE - 1U)) == 0U) | |
| #endif | |