/* This test file is part of GDB, the GNU debugger. Copyright 2021-2022 Free Software Foundation, Inc. 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; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but 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, see . */ #include #include #include #include /* Return true if address P is ALIGNMENT-byte aligned. */ static int is_aligned (void *p, size_t alignment) { size_t mask = (alignment - 1); return ((uintptr_t)p & mask) == 0; } /* Allocate SIZE memory with ALIGNMENT, and return it. If FREE_POINTER, return in it the corresponding pointer to be passed to free. Do the alignment precisely, in other words, if an alignment of 4 is requested, make sure the pointer is 4-byte aligned, but not 8-byte aligned. In other words, make sure the pointer is not overaligned. The benefit of using precise alignment is that accidentally specifying a too low alignment will not be compensated by accidental overalignment. */ static void * precise_aligned_alloc (size_t alignment, size_t size, void **free_pointer) { /* Allocate extra to compensate for "p += alignment". */ size_t alloc_size = size + alignment; /* Align extra, to be able to do precise align. */ void *p = aligned_alloc (alignment * 2, alloc_size); assert (p != NULL); void *p_orig = p; void *p_end = p + alloc_size; /* Make p precisely aligned. */ p += alignment; /* Verify p is without bounds, and points to large enough area. */ assert (p >= p_orig); assert (p + size <= p_end); /* Verify required alignment. */ assert (is_aligned (p, alignment)); /* Verify required alignment is precise. */ assert (! is_aligned (p, 2 * alignment)); if (free_pointer != NULL) *free_pointer = p_orig; return p; } /* Duplicate data SRC of size SIZE to a newly allocated, precisely aligned location with alignment ALIGNMENT. */ static void * precise_aligned_dup (size_t alignment, size_t size, void **free_pointer, void *src) { void *p = precise_aligned_alloc (alignment, size, free_pointer); memcpy (p, src, size); return p; }