1 | /* Memory management for dlerror messages. |
2 | Copyright (C) 2021-2023 Free Software Foundation, Inc. |
3 | This file is part of the GNU C Library. |
4 | |
5 | The GNU C Library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Lesser General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, see |
17 | <https://www.gnu.org/licenses/>. */ |
18 | |
19 | #ifndef _DLERROR_H |
20 | #define _DLERROR_H |
21 | |
22 | #include <dlfcn.h> |
23 | #include <ldsodefs.h> |
24 | #include <stdbool.h> |
25 | #include <stdint.h> |
26 | #include <stdlib.h> |
27 | |
28 | /* Source of the errstring member in struct dl_action_result, for |
29 | finding the right deallocation routine. */ |
30 | enum dl_action_result_errstring_source |
31 | { |
32 | dl_action_result_errstring_constant, /* String literal, no deallocation. */ |
33 | dl_action_result_errstring_rtld, /* libc in the primary namespace. */ |
34 | dl_action_result_errstring_local, /* libc in the current namespace. */ |
35 | }; |
36 | |
37 | struct dl_action_result |
38 | { |
39 | int errcode; |
40 | char errstring_source; |
41 | bool returned; |
42 | const char *objname; |
43 | char *errstring; |
44 | }; |
45 | |
46 | /* Used to free the errstring member of struct dl_action_result in the |
47 | dl_action_result_errstring_rtld case. */ |
48 | static inline void |
49 | dl_error_free (void *ptr) |
50 | { |
51 | #ifdef SHARED |
52 | /* In the shared case, ld.so may use a different malloc than this |
53 | namespace. */ |
54 | GLRO (dl_error_free (ptr)); |
55 | #else |
56 | /* Call the implementation directly. It still has to check for |
57 | pointers which cannot be freed, so do not call free directly |
58 | here. */ |
59 | _dl_error_free (ptr); |
60 | #endif |
61 | } |
62 | |
63 | /* Deallocate RESULT->errstring, leaving *RESULT itself allocated. */ |
64 | static inline void |
65 | dl_action_result_errstring_free (struct dl_action_result *result) |
66 | { |
67 | switch (result->errstring_source) |
68 | { |
69 | case dl_action_result_errstring_constant: |
70 | break; |
71 | case dl_action_result_errstring_rtld: |
72 | dl_error_free (result->errstring); |
73 | break; |
74 | case dl_action_result_errstring_local: |
75 | free (result->errstring); |
76 | break; |
77 | } |
78 | } |
79 | |
80 | /* Stand-in for an error result object whose allocation failed. No |
81 | precise message can be reported for this, but an error must still |
82 | be signaled. */ |
83 | static struct dl_action_result *const dl_action_result_malloc_failed |
84 | __attribute__ ((unused)) = (struct dl_action_result *) (intptr_t) -1; |
85 | |
86 | /* Thread-local variable for storing dlfcn failures for subsequent |
87 | reporting via dlerror. */ |
88 | extern __thread struct dl_action_result *__libc_dlerror_result |
89 | attribute_tls_model_ie; |
90 | |
91 | #endif /* _DLERROR_H */ |
92 | |