Memory checker fixes and enhancements. MISRA-related fixes.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15332 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
40fbc0044c
commit
6f221b1d4b
|
@ -668,6 +668,17 @@ struct nil_os_instance {
|
|||
*/
|
||||
#define MEM_NATURAL_ALIGN PORT_NATURAL_ALIGN
|
||||
|
||||
/**
|
||||
* @brief Port-defined check on function pointers.
|
||||
*
|
||||
* @param[in] p function pointer to be checked
|
||||
*/
|
||||
#if defined(PORT_IS_VALID_FUNCTION) || defined(__DOXYGEN__)
|
||||
#define MEM_IS_VALID_FUNCTION(p) PORT_IS_VALID_FUNCTION(p)
|
||||
#else
|
||||
#define MEM_IS_VALID_FUNCTION(p) true
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Alignment mask constant.
|
||||
*
|
||||
|
|
|
@ -69,6 +69,13 @@ typedef struct {
|
|||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
extern const memory_area_t __ch_mem_writable_areas[];
|
||||
extern const memory_area_t __ch_mem_readable_areas[];
|
||||
extern const memory_area_t __ch_mem_executable_areas[];
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -77,7 +84,7 @@ extern "C" {
|
|||
const char *s,
|
||||
size_t n);
|
||||
bool chMemIsAreaContainedX(const memory_area_t areas[],
|
||||
const void *base,
|
||||
const void *p,
|
||||
size_t size);
|
||||
bool chMemIsAreaWritableX(void *p,
|
||||
size_t size,
|
||||
|
@ -85,6 +92,7 @@ extern "C" {
|
|||
bool chMemIsAreaReadableX(const void *p,
|
||||
size_t size,
|
||||
unsigned align);
|
||||
bool chMemIsAddressExecutableX(const void *p);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -100,23 +108,26 @@ extern "C" {
|
|||
*
|
||||
* @param[in] map pointer to a @p memory_area_t structure
|
||||
* @param[in] p pointer to the area to be checked
|
||||
* @param[in] size size of the area to be checked
|
||||
* @param[in] size size of the area to be checked, zero is considered
|
||||
* the whole address space
|
||||
* @return The test result.
|
||||
* @retval false if the area is entirely contained within one of the
|
||||
* @retval true if the area is entirely contained within one of the
|
||||
* specified areas.
|
||||
* @retval true if the area check failed.
|
||||
* @retval false if the area check failed.
|
||||
*
|
||||
* @xclass
|
||||
*/
|
||||
static inline bool chMemIsAreaWithinX(const memory_area_t *map,
|
||||
const void *p,
|
||||
size_t size) {
|
||||
uint8_t *base = map->base;
|
||||
uint8_t *end = base + map->size - (size_t)1;
|
||||
const uint8_t *p8 = (const uint8_t *)p;
|
||||
const uint8_t *mem_base = (const uint8_t *)map->base;
|
||||
const uint8_t *mem_end = mem_base + map->size - (size_t)1;
|
||||
const uint8_t *base = (const uint8_t *)p;
|
||||
const uint8_t *end = base + size - (size_t)1;
|
||||
|
||||
return (bool)((p8 >= base) && (p8 <= end) &&
|
||||
(size <= (size_t)(end - p8) + (size_t)1));
|
||||
chDbgAssert(mem_base <= mem_end, "invalid memory area");
|
||||
|
||||
return (bool)((base <= end) && (base >= mem_base) && (end <= mem_end));
|
||||
}
|
||||
|
||||
#if CH_CFG_USE_MEMCHECKS == FALSE
|
||||
|
@ -130,7 +141,7 @@ bool chMemIsAreaWritableX(const void *p,
|
|||
(void)size;
|
||||
(void)align;
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool chMemIsAreaReadableX(const void *p,
|
||||
|
@ -141,7 +152,14 @@ bool chMemIsAreaReadableX(const void *p,
|
|||
(void)size;
|
||||
(void)align;
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool chMemIsAddressExecutableX(const void *p) {
|
||||
|
||||
(void)p;
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
* writable areas array for the device in use.
|
||||
* @note The array is terminated by an end marker (base=-1).
|
||||
*/
|
||||
CC_WEAK memory_area_t __ch_mem_writable_areas[] = {
|
||||
CC_WEAK const memory_area_t __ch_mem_writable_areas[] = {
|
||||
{(uint8_t *)0, 0U}, /* Whole space is writable.*/
|
||||
{(uint8_t *)-1, 0U},
|
||||
};
|
||||
|
@ -53,7 +53,18 @@ CC_WEAK memory_area_t __ch_mem_writable_areas[] = {
|
|||
* readable areas array for the device in use.
|
||||
* @note The array is terminated by an end marker (base=-1).
|
||||
*/
|
||||
CC_WEAK memory_area_t __ch_mem_readable_areas[] = {
|
||||
CC_WEAK const memory_area_t __ch_mem_readable_areas[] = {
|
||||
{(uint8_t *)0, 0U}, /* Whole space is readable.*/
|
||||
{(uint8_t *)-1, 0U},
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Default executable memory areas.
|
||||
* @details By default all memory is executable, user must provide its own
|
||||
* executable areas array for the device in use.
|
||||
* @note The array is terminated by an end marker (base=-1).
|
||||
*/
|
||||
CC_WEAK const memory_area_t __ch_mem_executable_areas[] = {
|
||||
{(uint8_t *)0, 0U}, /* Whole space is readable.*/
|
||||
{(uint8_t *)-1, 0U},
|
||||
};
|
||||
|
@ -85,9 +96,9 @@ CC_WEAK memory_area_t __ch_mem_readable_areas[] = {
|
|||
* @param[in] s pointer to the string to be checked
|
||||
* @param[in] n maximum expected size of the string
|
||||
* @return The test result.
|
||||
* @retval false if the string is entirely contained within one of the
|
||||
* @retval true if the string is entirely contained within one of the
|
||||
* specified areas.
|
||||
* @retval true if the string check failed.
|
||||
* @retval false if the string check failed.
|
||||
*
|
||||
* @xclass
|
||||
*/
|
||||
|
@ -116,11 +127,12 @@ bool chMemIsStringWithinX(const memory_area_t *map, const char *s, size_t n) {
|
|||
* @param[in] map array of valid areas terminated with an end
|
||||
* marker (base=-1)
|
||||
* @param[in] p pointer to the area to be checked
|
||||
* @param[in] size size of the area to be checked
|
||||
* @param[in] size size of the area to be checked, zero is considered
|
||||
* the whole address space
|
||||
* @return The test result.
|
||||
* @retval false if the area is entirely contained within one of the
|
||||
* @retval true if the area is entirely contained within one of the
|
||||
* specified areas.
|
||||
* @retval true if the area check failed.
|
||||
* @retval false if the area check failed.
|
||||
*
|
||||
* @xclass
|
||||
*/
|
||||
|
@ -148,19 +160,18 @@ bool chMemIsAreaContainedX(const memory_area_t areas[],
|
|||
* @brief Memory writable area check.
|
||||
* @details Checks if specified pointer belongs to one of the system-defined
|
||||
* writable areas and is aligned as specified.
|
||||
* @note This function is only effective if @p CH_CFG_SYS_WRITABLE_REGIONS
|
||||
* is defined, if it is not defined then just the alignment of
|
||||
* the pointer is checked.
|
||||
* @note @p __ch_mem_writable_areas must be the name of a global
|
||||
* @p memory_area_t array terminated with an end marker (-1, 0).
|
||||
*
|
||||
* @param[in] p pointer to the area to be checked
|
||||
* @param[in] size size of the area to be checked, zero is considered
|
||||
* the whole address space
|
||||
* @param[in] align required pointer alignment to be checked, must be
|
||||
* a power of two
|
||||
* @return The test result.
|
||||
* @retval false if the area is entirely contained within one of the
|
||||
* @retval true if the area is entirely contained within one of the
|
||||
* system-defined writable areas.
|
||||
* @retval true if the area check failed.
|
||||
* @retval false if the area check failed.
|
||||
*
|
||||
* @xclass
|
||||
*/
|
||||
|
@ -171,7 +182,7 @@ bool chMemIsAreaWritableX(void *p,
|
|||
chDbgCheck((align & (align - 1U)) == 0U);
|
||||
|
||||
if (!MEM_IS_ALIGNED(p, align)) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return chMemIsAreaContainedX(__ch_mem_writable_areas, p, size);
|
||||
|
@ -181,19 +192,18 @@ bool chMemIsAreaWritableX(void *p,
|
|||
* @brief Memory readable area check.
|
||||
* @details Checks if specified pointer belongs to one of the system-defined
|
||||
* readable areas and is aligned as specified.
|
||||
* @note This function is only effective if @p CH_CFG_SYS_READABLE_REGIONS
|
||||
* is defined, if it is not defined then just the alignment of
|
||||
* the pointer is checked.
|
||||
* @note @p __ch_mem_readable_areas must be the name of a global
|
||||
* @p memory_area_t array terminated with an end marker (-1, 0).
|
||||
*
|
||||
* @param[in] p pointer to the area to be checked
|
||||
* @param[in] size size of the area to be checked, zero is considered
|
||||
* the whole address space
|
||||
* @param[in] align required pointer alignment to be checked, must be
|
||||
* a power of two
|
||||
* @return The test result.
|
||||
* @retval false if the area is entirely contained within one of the
|
||||
* @retval true if the area is entirely contained within one of the
|
||||
* system-defined readable areas.
|
||||
* @retval true if the area check failed.
|
||||
* @retval false if the area check failed.
|
||||
*
|
||||
* @xclass
|
||||
*/
|
||||
|
@ -204,12 +214,38 @@ bool chMemIsAreaReadableX(const void *p,
|
|||
chDbgCheck((align & (align - 1U)) == 0U);
|
||||
|
||||
if (!MEM_IS_ALIGNED(p, align)) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return chMemIsAreaContainedX(__ch_mem_readable_areas, p, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Memory executable area check.
|
||||
* @details Checks if specified pointer belongs to one of the system-defined
|
||||
* executable areas and is aligned properly.
|
||||
* @note @p __ch_mem_executable_areas must be the name of a global
|
||||
* @p memory_area_t array terminated with an end marker (-1, 0).
|
||||
*
|
||||
* @param[in] p pointer to the area to be checked
|
||||
* @return The test result.
|
||||
* @retval true if the address belongs to one of the
|
||||
* system-defined executable areas.
|
||||
* @retval false if the address check failed.
|
||||
*
|
||||
* @xclass
|
||||
*/
|
||||
bool chMemIsAddressExecutableX(const void *p) {
|
||||
|
||||
/*lint -save -e506 -e774 [2.1, 14.3] It can be a constant by design.*/
|
||||
if (!MEM_IS_VALID_FUNCTION(p)) {
|
||||
/*lint -restore*/
|
||||
return false;
|
||||
}
|
||||
|
||||
return chMemIsAreaContainedX(__ch_mem_executable_areas, p, 1);
|
||||
}
|
||||
|
||||
#endif /* CH_CFG_USE_MEMCHECKS == TRUE */
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -399,8 +399,6 @@ size_t chHeapStatus(memory_heap_t *heapp, size_t *totalp, size_t *largestp) {
|
|||
return n;
|
||||
}
|
||||
|
||||
#define isvalidfunction(p) true
|
||||
|
||||
/**
|
||||
* @brief Heap integrity check.
|
||||
* @details Performs an integrity check of a heap stucture.
|
||||
|
@ -423,8 +421,10 @@ bool chHeapIntegrityCheck(memory_heap_t *heapp) {
|
|||
}
|
||||
|
||||
/* Validating heap object.*/
|
||||
if ((heapp->provider != NULL) && !isvalidfunction(heapp->provider)) {
|
||||
return true;
|
||||
if (heapp->provider != NULL) {
|
||||
if (!chMemIsAddressExecutableX(heapp->provider)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Taking heap mutex.*/
|
||||
|
|
|
@ -58,14 +58,25 @@
|
|||
* @note Represents the required alignment for integer and pointer
|
||||
* data types.
|
||||
*/
|
||||
#define MEM_NATURAL_ALIGN PORT_NATURAL_ALIGN
|
||||
#define MEM_NATURAL_ALIGN PORT_NATURAL_ALIGN
|
||||
|
||||
/**
|
||||
* @brief Port-defined check on function pointers.
|
||||
*
|
||||
* @param[in] p function pointer to be checked
|
||||
*/
|
||||
#if defined(PORT_IS_VALID_FUNCTION) || defined(__DOXYGEN__)
|
||||
#define MEM_IS_VALID_FUNCTION(p) PORT_IS_VALID_FUNCTION(p)
|
||||
#else
|
||||
#define MEM_IS_VALID_FUNCTION(p) true
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Alignment mask constant.
|
||||
*
|
||||
* @param[in] a alignment, must be a power of two
|
||||
*/
|
||||
#define MEM_ALIGN_MASK(a) ((size_t)(a) - 1U)
|
||||
#define MEM_ALIGN_MASK(a) ((size_t)(a) - 1U)
|
||||
|
||||
/**
|
||||
* @brief Aligns to the previous aligned memory address.
|
||||
|
@ -95,7 +106,7 @@
|
|||
* @param[in] p variable to be aligned
|
||||
* @param[in] a alignment, must be a power of two
|
||||
*/
|
||||
#define MEM_IS_ALIGNED(p, a) (((size_t)(p) & MEM_ALIGN_MASK(a)) == 0U)
|
||||
#define MEM_IS_ALIGNED(p, a) (((size_t)(p) & MEM_ALIGN_MASK(a)) == 0U)
|
||||
|
||||
/**
|
||||
* @brief Returns whatever a constant is a valid alignment.
|
||||
|
|
|
@ -521,8 +521,11 @@ static inline sysinterval_t chTimeStampDiffX(systimestamp_t start,
|
|||
/* Time difference as a wide time stamp.*/
|
||||
diff = end - start;
|
||||
|
||||
/*lint -save -e685 [14.3] This condition becomes always true when both
|
||||
types have the same width, it is fine, this is an assertion.*/
|
||||
chDbgAssert(diff <= (systimestamp_t)((sysinterval_t)-1),
|
||||
"conversion overflow");
|
||||
/*lint -restore*/
|
||||
|
||||
/*lint -save -e9033 [10.8] This cast is required by the operation, it is
|
||||
known that the destination type can be wider.*/
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
*
|
||||
* @notapi
|
||||
*/
|
||||
NOINLINE static void trace_next(os_instance_t *oip) {
|
||||
static NOINLINE void trace_next(os_instance_t *oip) {
|
||||
|
||||
oip->trace_buffer.ptr->time = chVTGetSystemTimeX();
|
||||
#if PORT_SUPPORTS_RT == TRUE
|
||||
|
|
Loading…
Reference in New Issue