1 /* Copyright (C) 1997-2022 Free Software Foundation, Inc. 2 This file is part of the GNU C Library. 3 4 The GNU C Library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Lesser General Public 6 License as published by the Free Software Foundation; either 7 version 2.1 of the License, or (at your option) any later version. 8 9 The GNU C Library 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 GNU 12 Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public 15 License along with the GNU C Library; if not, see 16 <https://www.gnu.org/licenses/>. */ 17 18 #include <atomic.h> 19 #include <stdlib.h> 20 #include <set-hooks.h> 21 #include <libc-internal.h> 22 #include <unwind-link.h> 23 #include <dlfcn/dlerror.h> 24 #include <ldsodefs.h> 25 26 #include "../nss/nsswitch.h" 27 #include "../libio/libioP.h" 28 29 DEFINE_HOOK (__libc_subfreeres, (void)); 30 31 symbol_set_define (__libc_freeres_ptrs); 32 33 extern void __libpthread_freeres (void) 34 #if PTHREAD_IN_LIBC && defined SHARED 35 /* It is possible to call __libpthread_freeres directly in shared 36 builds with an integrated libpthread. */ 37 attribute_hidden 38 #else 39 __attribute__ ((weak)) 40 #endif 41 ; 42 43 void __libc_freeres_fn_section __libc_freeres(void)44__libc_freeres (void) 45 { 46 /* This function might be called from different places. So better 47 protect for multiple executions since these are fatal. */ 48 static long int already_called; 49 50 if (!atomic_compare_and_exchange_bool_acq (&already_called, 1, 0)) 51 { 52 void *const *p; 53 54 call_function_static_weak (__nss_module_freeres); 55 call_function_static_weak (__nss_action_freeres); 56 call_function_static_weak (__nss_database_freeres); 57 58 _IO_cleanup (); 59 60 /* We run the resource freeing after IO cleanup. */ 61 RUN_HOOK (__libc_subfreeres, ()); 62 63 call_function_static_weak (__libpthread_freeres); 64 65 #ifdef SHARED 66 __libc_unwind_link_freeres (); 67 #endif 68 69 call_function_static_weak (__libc_dlerror_result_free); 70 71 #ifdef SHARED 72 GLRO (dl_libc_freeres) (); 73 #endif 74 75 for (p = symbol_set_first_element (__libc_freeres_ptrs); 76 !symbol_set_end_p (__libc_freeres_ptrs, p); ++p) 77 free (*p); 78 } 79 } 80 libc_hidden_def (__libc_freeres) 81