(root)/
coreutils-9.4/
lib/
memset_explicit.c
       1  /* Erase sensitive data from memory.
       2     Copyright 2022-2023 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.  */
      28  void *
      29  memset_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  }