1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <libintl.h>
21: #include <setjmp.h>
22: #include <stdbool.h>
23: #include <stdlib.h>
24: #include <string.h>
25: #include <unistd.h>
26: #include <ldsodefs.h>
27:
28:
29:
30: struct catch
31: {
32: const char *objname;
33: const char *errstring;
34: bool malloced;
35:
36: jmp_buf env;
37: };
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50: static const char _dl_out_of_memory[] = "out of memory";
51:
52:
53:
54:
55:
56:
57:
58:
59:
60: static receiver_fct receiver;
61:
62: #ifdef _LIBC_REENTRANT
63: # define CATCH_HOOK (*(struct catch **) (*GL(dl_error_catch_tsd)) ())
64: #else
65: static struct catch *catch_hook;
66: # define CATCH_HOOK catch_hook
67: #endif
68:
69: void
70: internal_function
71: _dl_signal_error (int errcode, const char *objname, const char *occation,
72: const char *errstring)
73: {
74: struct catch *lcatch;
75:
76: if (! errstring)
77: errstring = N_("DYNAMIC LINKER BUG!!!");
78:
79: lcatch = CATCH_HOOK;
80: if (objname == NULL)
81: objname = "";
82: if (lcatch != NULL)
83: {
84:
85:
86:
87: size_t len_objname = strlen (objname) + 1;
88: size_t len_errstring = strlen (errstring) + 1;
89:
90: lcatch->errstring = (char *) malloc (len_objname + len_errstring);
91: if (lcatch->errstring != NULL)
92: {
93:
94: lcatch->objname = memcpy (__mempcpy ((char *) lcatch->errstring,
95: errstring, len_errstring),
96: objname, len_objname);
97:
98:
99:
100: #ifdef SHARED
101: lcatch->malloced = (GL(dl_ns)[LM_ID_BASE]._ns_loaded != NULL
102: && (GL(dl_ns)[LM_ID_BASE]._ns_loaded->l_relocated
103: != 0));
104: #else
105: lcatch->malloced = true;
106: #endif
107: }
108: else
109: {
110:
111: lcatch->objname = "";
112: lcatch->errstring = _dl_out_of_memory;
113: lcatch->malloced = false;
114: }
115:
116: __longjmp (lcatch->env[0].__jmpbuf, errcode ?: -1);
117: }
118: else
119: {
120:
121: char buffer[1024];
122: _dl_fatal_printf ("%s: %s: %s%s%s%s%s\n",
123: rtld_progname ?: "<program name unknown>",
124: occation ?: N_("error while loading shared libraries"),
125: objname, *objname ? ": " : "",
126: errstring, errcode ? ": " : "",
127: (errcode
128: ? __strerror_r (errcode, buffer, sizeof buffer)
129: : ""));
130: }
131: }
132:
133:
134: void
135: internal_function
136: _dl_signal_cerror (int errcode, const char *objname, const char *occation,
137: const char *errstring)
138: {
139: if (__builtin_expect (GLRO(dl_debug_mask)
140: & ~(DL_DEBUG_STATISTICS|DL_DEBUG_PRELINK), 0))
141: _dl_debug_printf ("%s: error: %s: %s (%s)\n", objname, occation,
142: errstring, receiver ? "continued" : "fatal");
143:
144: if (receiver)
145: {
146:
147:
148:
149: (*receiver) (errcode, objname, errstring);
150: }
151: else
152: _dl_signal_error (errcode, objname, occation, errstring);
153: }
154:
155:
156: int
157: internal_function
158: _dl_catch_error (const char **objname, const char **errstring,
159: bool *mallocedp, void (*operate) (void *), void *args)
160: {
161: int errcode;
162: struct catch *volatile old;
163: struct catch c;
164:
165:
166:
167:
168:
169: c.errstring = NULL;
170:
171: struct catch **const catchp = &CATCH_HOOK;
172: old = *catchp;
173:
174: errcode = __sigsetjmp (c.env, 0);
175: if (__builtin_expect (errcode, 0) == 0)
176: {
177: *catchp = &c;
178: (*operate) (args);
179: *catchp = old;
180: *objname = NULL;
181: *errstring = NULL;
182: *mallocedp = false;
183: return 0;
184: }
185:
186:
187: *catchp = old;
188: *objname = c.objname;
189: *errstring = c.errstring;
190: *mallocedp = c.malloced;
191: return errcode == -1 ? 0 : errcode;
192: }
193:
194:
195: void
196: internal_function
197: _dl_receive_error (receiver_fct fct, void (*operate) (void *), void *args)
198: {
199: struct catch **const catchp = &CATCH_HOOK;
200: struct catch *old_catch;
201: receiver_fct old_receiver;
202:
203: old_catch = *catchp;
204: old_receiver = receiver;
205:
206:
207: *catchp = NULL;
208: receiver = fct;
209:
210: (*operate) (args);
211:
212: *catchp = old_catch;
213: receiver = old_receiver;
214: }