aboutsummaryrefslogtreecommitdiffstats
path: root/lib/memset_explicit.c
diff options
context:
space:
mode:
authorPaul Eggert2022-12-17 23:11:55 -0800
committerPaul Eggert2022-12-18 00:24:13 -0800
commitbda755bf92b5fa0dfe25da173b30e1002e95b774 (patch)
treea9aa1b5520a48c93a1702b39c1b2f22a32c46805 /lib/memset_explicit.c
parent5a344d90c53d681ed98ab03ad3e218a3c6561108 (diff)
downloademacs-bda755bf92b5fa0dfe25da173b30e1002e95b774.tar.gz
emacs-bda755bf92b5fa0dfe25da173b30e1002e95b774.zip
Update from Gnulib by running admin/merge-gnulib
Diffstat (limited to 'lib/memset_explicit.c')
-rw-r--r--lib/memset_explicit.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/lib/memset_explicit.c b/lib/memset_explicit.c
new file mode 100644
index 00000000000..eabeb3ec2b8
--- /dev/null
+++ b/lib/memset_explicit.c
@@ -0,0 +1,55 @@
1/* Erase sensitive data from memory.
2 Copyright 2022 Free Software Foundation, Inc.
3
4 This file is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2.1 of the
7 License, or (at your option) any later version.
8
9 This file is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
16
17#include <config.h>
18
19/* memset_s need this define */
20#if HAVE_MEMSET_S
21# define __STDC_WANT_LIB_EXT1__ 1
22#endif
23
24#include <string.h>
25
26/* Set S's bytes to C, where S has LEN bytes. The compiler will not
27 optimize effects away, even if S is dead after the call. */
28void *
29memset_explicit (void *s, int c, size_t len)
30{
31#if HAVE_EXPLICIT_MEMSET
32 return explicit_memset (s, c, len);
33#elif HAVE_MEMSET_S
34 (void) memset_s (s, len, c, len);
35 return s;
36#elif defined __GNUC__ && !defined __clang__
37 memset (s, c, len);
38 /* Compiler barrier. */
39 __asm__ volatile ("" ::: "memory");
40 return s;
41#elif defined __clang__
42 memset (s, c, len);
43 /* Compiler barrier. */
44 /* With asm ("" ::: "memory") LLVM analyzes uses of 's' and finds that the
45 whole thing is dead and eliminates it. Use 'g' to work around this
46 problem. See <https://bugs.llvm.org/show_bug.cgi?id=15495#c11>. */
47 __asm__ volatile ("" : : "g"(s) : "memory");
48 return s;
49#else
50 /* Invoke memset through a volatile function pointer. This defeats compiler
51 optimizations. */
52 void * (* const volatile volatile_memset) (void *, int, size_t) = memset;
53 return volatile_memset (s, c, len);
54#endif
55}