diff options
| author | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2024-10-31 16:27:12 +0100 |
|---|---|---|
| committer | Lorenz Kästle <12514511+RincewindsHat@users.noreply.github.com> | 2024-10-31 16:27:12 +0100 |
| commit | 5be04ec2ceb1df77afbca4fcbf9e92a712612d6f (patch) | |
| tree | 2b2e1c71dffae827c8e45cd4cccc375093d03486 /gl/malloca.c | |
| parent | 6d1d1dac32841d5ca6ee51bb09b30a6c604b17e2 (diff) | |
| download | monitoring-plugins-5be04ec2ceb1df77afbca4fcbf9e92a712612d6f.tar.gz | |
Sync with the latest Gnulib code (d4ec02b3cc)
Diffstat (limited to 'gl/malloca.c')
| -rw-r--r-- | gl/malloca.c | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/gl/malloca.c b/gl/malloca.c index f055b1e5..e75c72df 100644 --- a/gl/malloca.c +++ b/gl/malloca.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Safe automatic memory allocation. | 1 | /* Safe automatic memory allocation. |
| 2 | Copyright (C) 2003, 2006-2007, 2009-2023 Free Software Foundation, Inc. | 2 | Copyright (C) 2003, 2006-2007, 2009-2024 Free Software Foundation, Inc. |
| 3 | Written by Bruno Haible <bruno@clisp.org>, 2003, 2018. | 3 | Written by Bruno Haible <bruno@clisp.org>, 2003, 2018. |
| 4 | 4 | ||
| 5 | This file is free software: you can redistribute it and/or modify | 5 | This file is free software: you can redistribute it and/or modify |
| @@ -22,6 +22,9 @@ | |||
| 22 | #include "malloca.h" | 22 | #include "malloca.h" |
| 23 | 23 | ||
| 24 | #include <stdckdint.h> | 24 | #include <stdckdint.h> |
| 25 | #if defined __CHERI_PURE_CAPABILITY__ | ||
| 26 | # include <cheri.h> | ||
| 27 | #endif | ||
| 25 | 28 | ||
| 26 | #include "idx.h" | 29 | #include "idx.h" |
| 27 | 30 | ||
| @@ -36,10 +39,15 @@ | |||
| 36 | allocation. | 39 | allocation. |
| 37 | - NULL comes from a failed heap allocation. */ | 40 | - NULL comes from a failed heap allocation. */ |
| 38 | 41 | ||
| 42 | #if defined __CHERI_PURE_CAPABILITY__ | ||
| 43 | /* Type for holding the original malloc() result. */ | ||
| 44 | typedef uintptr_t small_t; | ||
| 45 | #else | ||
| 39 | /* Type for holding very small pointer differences. */ | 46 | /* Type for holding very small pointer differences. */ |
| 40 | typedef unsigned char small_t; | 47 | typedef unsigned char small_t; |
| 41 | /* Verify that it is wide enough. */ | 48 | /* Verify that it is wide enough. */ |
| 42 | static_assert (2 * sa_alignment_max - 1 <= (small_t) -1); | 49 | static_assert (2 * sa_alignment_max - 1 <= (small_t) -1); |
| 50 | #endif | ||
| 43 | 51 | ||
| 44 | void * | 52 | void * |
| 45 | mmalloca (size_t n) | 53 | mmalloca (size_t n) |
| @@ -56,20 +64,28 @@ mmalloca (size_t n) | |||
| 56 | 64 | ||
| 57 | if (mem != NULL) | 65 | if (mem != NULL) |
| 58 | { | 66 | { |
| 59 | uintptr_t umem = (uintptr_t)mem, umemplus; | 67 | uintptr_t umem = (uintptr_t) mem; |
| 60 | /* The ckd_add avoids signed integer overflow on | 68 | /* The ckd_add avoids signed integer overflow on |
| 61 | theoretical platforms where UINTPTR_MAX <= INT_MAX. */ | 69 | theoretical platforms where UINTPTR_MAX <= INT_MAX. */ |
| 70 | uintptr_t umemplus; | ||
| 62 | ckd_add (&umemplus, umem, sizeof (small_t) + sa_alignment_max - 1); | 71 | ckd_add (&umemplus, umem, sizeof (small_t) + sa_alignment_max - 1); |
| 63 | idx_t offset = ((umemplus & ~alignment2_mask) | 72 | idx_t offset = (umemplus - umemplus % (2 * sa_alignment_max) |
| 64 | + sa_alignment_max - umem); | 73 | + sa_alignment_max - umem); |
| 65 | void *vp = mem + offset; | 74 | void *p = mem + offset; |
| 66 | small_t *p = vp; | ||
| 67 | /* Here p >= mem + sizeof (small_t), | 75 | /* Here p >= mem + sizeof (small_t), |
| 68 | and p <= mem + sizeof (small_t) + 2 * sa_alignment_max - 1 | 76 | and p <= mem + sizeof (small_t) + 2 * sa_alignment_max - 1 |
| 69 | hence p + n <= mem + nplus. | 77 | hence p + n <= mem + nplus. |
| 70 | So, the memory range [p, p+n) lies in the allocated memory range | 78 | So, the memory range [p, p+n) lies in the allocated memory range |
| 71 | [mem, mem + nplus). */ | 79 | [mem, mem + nplus). */ |
| 72 | p[-1] = offset; | 80 | small_t *sp = p; |
| 81 | # if defined __CHERI_PURE_CAPABILITY__ | ||
| 82 | sp[-1] = umem; | ||
| 83 | p = (char *) cheri_bounds_set ((char *) p - sizeof (small_t), | ||
| 84 | sizeof (small_t) + n) | ||
| 85 | + sizeof (small_t); | ||
| 86 | # else | ||
| 87 | sp[-1] = offset; | ||
| 88 | # endif | ||
| 73 | /* p ≡ sa_alignment_max mod 2*sa_alignment_max. */ | 89 | /* p ≡ sa_alignment_max mod 2*sa_alignment_max. */ |
| 74 | return p; | 90 | return p; |
| 75 | } | 91 | } |
| @@ -90,15 +106,22 @@ void | |||
| 90 | freea (void *p) | 106 | freea (void *p) |
| 91 | { | 107 | { |
| 92 | /* Check argument. */ | 108 | /* Check argument. */ |
| 93 | if ((uintptr_t) p & (sa_alignment_max - 1)) | 109 | uintptr_t u = (uintptr_t) p; |
| 110 | if (u & (sa_alignment_max - 1)) | ||
| 94 | { | 111 | { |
| 95 | /* p was not the result of a malloca() call. Invalid argument. */ | 112 | /* p was not the result of a malloca() call. Invalid argument. */ |
| 96 | abort (); | 113 | abort (); |
| 97 | } | 114 | } |
| 98 | /* Determine whether p was a non-NULL pointer returned by mmalloca(). */ | 115 | /* Determine whether p was a non-NULL pointer returned by mmalloca(). */ |
| 99 | if ((uintptr_t) p & sa_alignment_max) | 116 | if (u & sa_alignment_max) |
| 100 | { | 117 | { |
| 101 | void *mem = (char *) p - ((small_t *) p)[-1]; | 118 | char *cp = p; |
| 119 | small_t *sp = p; | ||
| 120 | # if defined __CHERI_PURE_CAPABILITY__ | ||
| 121 | void *mem = sp[-1]; | ||
| 122 | # else | ||
| 123 | void *mem = cp - sp[-1]; | ||
| 124 | # endif | ||
| 102 | free (mem); | 125 | free (mem); |
| 103 | } | 126 | } |
| 104 | } | 127 | } |
