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