src: use __builtin_align_down, if available
In _test_malloc, we manually align a pointer to MALLOC_ALIGNMENT using `& ~(MALLOC_ALIGNMENT - 1)`. However, this has two problems: 1. We're casting the pointer to `size_t`, which isn't guaranteed to hold a pointer. Instead, we should cast to `uintptr_t`. 2. Modifying a pointer as a integer is undefined behavior, and on some platforms (e.g. CHERI), this does not work. C++11 has std::align that does this for us, but unfortunately, there isn't a way to do this in ISO C that is guaranteed to work, except for in Clang v10+, which has a builtin extension called __builtin_align_down that can align pointers safely for us. See: https://clang.llvm.org/docs/LanguageExtensions.html#alignment-builtins on-behalf-of: @nqminds <info@nqminds.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
parent
426784f405
commit
0559ef6e8e
|
@ -1,5 +1,6 @@
|
|||
include(CheckIncludeFile)
|
||||
include(CheckSymbolExists)
|
||||
include(CheckCSourceCompiles)
|
||||
include(CheckFunctionExists)
|
||||
include(CheckLibraryExists)
|
||||
include(CheckTypeSize)
|
||||
|
@ -89,6 +90,8 @@ check_function_exists(signal HAVE_SIGNAL)
|
|||
check_function_exists(strsignal HAVE_STRSIGNAL)
|
||||
check_function_exists(strcmp HAVE_STRCMP)
|
||||
check_function_exists(clock_gettime HAVE_CLOCK_GETTIME)
|
||||
# Supported by Clang v10+
|
||||
check_c_source_compiles("int main(void) { int a = 1; return __builtin_align_down(&a, 8);}" HAVE_BUILTIN_ALIGN_DOWN)
|
||||
|
||||
if (WIN32)
|
||||
check_function_exists(_vsnprintf_s HAVE__VSNPRINTF_S)
|
||||
|
|
16
src/cmocka.c
16
src/cmocka.c
|
@ -2327,9 +2327,16 @@ static void vcm_free_error(char *err_msg)
|
|||
libc_free(err_msg);
|
||||
}
|
||||
|
||||
/* Rounds the given pointer down to a multiple of the given alignment. */
|
||||
#ifdef HAVE_BUILTIN_ALIGN_DOWN
|
||||
#define ALIGN_DOWN(x, a) (__builtin_align_down((x), (a)))
|
||||
#else
|
||||
#define ALIGN_DOWN(x, a) ((uintptr_t)(x) & ~((a)-1))
|
||||
#endif
|
||||
|
||||
/* Use the real malloc in this function. */
|
||||
#undef malloc
|
||||
void* _test_malloc(const size_t size, const char* file, const int line) {
|
||||
void* _test_malloc(const size_t size, const char *file, const int line) {
|
||||
char *ptr = NULL;
|
||||
MallocBlockInfo block_info;
|
||||
ListNode * const block_list = get_allocated_blocks_list();
|
||||
|
@ -2344,9 +2351,10 @@ void* _test_malloc(const size_t size, const char* file, const int line) {
|
|||
assert_non_null(block);
|
||||
|
||||
/* Calculate the returned address. */
|
||||
ptr = (char*)(((size_t)block + MALLOC_GUARD_SIZE +
|
||||
sizeof(struct MallocBlockInfoData) +
|
||||
MALLOC_ALIGNMENT) & ~(MALLOC_ALIGNMENT - 1));
|
||||
ptr = (char *)(ALIGN_DOWN((block + MALLOC_GUARD_SIZE +
|
||||
sizeof(struct MallocBlockInfoData) +
|
||||
MALLOC_ALIGNMENT),
|
||||
MALLOC_ALIGNMENT));
|
||||
|
||||
/* Initialize the guard blocks. */
|
||||
memset(ptr - MALLOC_GUARD_SIZE, MALLOC_GUARD_PATTERN, MALLOC_GUARD_SIZE);
|
||||
|
|
Loading…
Reference in New Issue