]> Git Repo - binutils.git/blob - gdb/testsuite/lib/precise-aligned-alloc.c
Automatic date update in version.in
[binutils.git] / gdb / testsuite / lib / precise-aligned-alloc.c
1 /* This test file is part of GDB, the GNU debugger.
2
3    Copyright 2021-2022 Free Software Foundation, Inc.
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    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
16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <stdlib.h>
20 #include <assert.h>
21 #include <string.h>
22 #include <stdint.h>
23
24 /* Return true if address P is ALIGNMENT-byte aligned.  */
25
26 static int
27 is_aligned (void *p, size_t alignment)
28 {
29   size_t mask = (alignment - 1);
30   return ((uintptr_t)p & mask) == 0;
31 }
32
33 /* Allocate SIZE memory with ALIGNMENT, and return it.  If FREE_POINTER,
34    return in it the corresponding pointer to be passed to free.
35
36    Do the alignment precisely, in other words, if an alignment of 4 is
37    requested, make sure the pointer is 4-byte aligned, but not 8-byte
38    aligned.  In other words, make sure the pointer is not overaligned.
39
40    The benefit of using precise alignment is that accidentally specifying
41    a too low alignment will not be compensated by accidental
42    overalignment.  */
43
44 static void *
45 precise_aligned_alloc (size_t alignment, size_t size, void **free_pointer)
46 {
47   /* Allocate extra to compensate for "p += alignment".  */
48   size_t alloc_size = size + alignment;
49
50   /* Align extra, to be able to do precise align.  */
51   void *p = aligned_alloc (alignment * 2, alloc_size);
52   assert (p != NULL);
53   void *p_orig = p;
54   void *p_end = p + alloc_size;
55
56   /* Make p precisely aligned.  */
57   p += alignment;
58
59   /* Verify p is without bounds, and points to large enough area.  */
60   assert (p >= p_orig);
61   assert (p + size <= p_end);
62
63   /* Verify required alignment.  */
64   assert (is_aligned (p, alignment));
65
66   /* Verify required alignment is precise.  */
67   assert (! is_aligned (p, 2 * alignment));
68
69   if (free_pointer != NULL)
70     *free_pointer = p_orig;
71
72   return p;
73 }
74
75 /* Duplicate data SRC of size SIZE to a newly allocated, precisely aligned
76    location with alignment ALIGNMENT.  */
77
78 static void *
79 precise_aligned_dup (size_t alignment, size_t size, void **free_pointer,
80                      void *src)
81 {
82   void *p = precise_aligned_alloc (alignment, size, free_pointer);
83
84   memcpy (p, src, size);
85
86   return p;
87 }
This page took 0.02879 seconds and 4 git commands to generate.