1 | /* libio vtable validation. |
2 | Copyright (C) 2016-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 | #include <dlfcn.h> |
20 | #include <libioP.h> |
21 | #include <stdio.h> |
22 | #include <ldsodefs.h> |
23 | #include <pointer_guard.h> |
24 | #include <libio-macros.h> |
25 | |
26 | /* Both _IO_str_* and _IO_new_file functions are pulled into every link (from |
27 | stdio initialization). */ |
28 | #ifndef SHARED |
29 | /* NB: the following directives do add pragma weak for _IO_default _* and |
30 | _IO_wdefault_* symbols to potentially avoid link failures, since they |
31 | are always used when the __io_vtables is used. */ |
32 | # pragma weak _IO_wstr_finish |
33 | # pragma weak _IO_wstr_overflow |
34 | # pragma weak _IO_wstr_pbackfail |
35 | # pragma weak _IO_wstr_seekoff |
36 | # pragma weak _IO_wstr_underflow |
37 | |
38 | # pragma weak _IO_file_close |
39 | # pragma weak _IO_file_close_mmap |
40 | # pragma weak _IO_file_doallocate |
41 | # pragma weak _IO_file_finish |
42 | # pragma weak _IO_file_overflow |
43 | # pragma weak _IO_file_read |
44 | # pragma weak _IO_file_seek |
45 | # pragma weak _IO_file_seekoff_maybe_mmap |
46 | # pragma weak _IO_file_seekoff_mmap |
47 | # pragma weak _IO_file_setbuf |
48 | # pragma weak _IO_file_setbuf_mmap |
49 | # pragma weak _IO_file_setbuf_mmap |
50 | # pragma weak _IO_file_stat |
51 | # pragma weak _IO_file_sync |
52 | # pragma weak _IO_file_sync_mmap |
53 | # pragma weak _IO_file_underflow |
54 | # pragma weak _IO_file_underflow_maybe_mmap |
55 | # pragma weak _IO_file_underflow_mmap |
56 | # pragma weak _IO_file_xsgetn |
57 | # pragma weak _IO_file_xsgetn_maybe_mmap |
58 | # pragma weak _IO_file_xsgetn_mmap |
59 | # pragma weak _IO_file_xsputn |
60 | |
61 | # pragma weak _IO_wfile_overflow |
62 | # pragma weak _IO_wfile_sync |
63 | # pragma weak _IO_wfile_underflow |
64 | # pragma weak _IO_wfile_underflow_maybe_mmap |
65 | # pragma weak _IO_wfile_underflow_mmap |
66 | # pragma weak _IO_wfile_doallocate |
67 | # pragma weak _IO_wfile_seekoff |
68 | # pragma weak _IO_wfile_xsputn |
69 | |
70 | # pragma weak _IO_new_proc_close |
71 | |
72 | # pragma weak _IO_cookie_close |
73 | # pragma weak _IO_cookie_read |
74 | # pragma weak _IO_cookie_seek |
75 | # pragma weak _IO_cookie_seekoff |
76 | # pragma weak _IO_cookie_write |
77 | |
78 | # pragma weak _IO_mem_finish |
79 | # pragma weak _IO_mem_sync |
80 | |
81 | # pragma weak _IO_wmem_finish |
82 | # pragma weak _IO_wmem_sync |
83 | |
84 | # pragma weak __printf_buffer_as_file_overflow |
85 | # pragma weak __printf_buffer_as_file_xsputn |
86 | |
87 | # pragma weak __wprintf_buffer_as_file_overflow |
88 | # pragma weak __wprintf_buffer_as_file_xsputn |
89 | #endif |
90 | |
91 | const struct _IO_jump_t __io_vtables[IO_VTABLES_LEN] attribute_relro = |
92 | { |
93 | /* _IO_str_jumps */ |
94 | [IO_STR_JUMPS] = |
95 | { |
96 | JUMP_INIT_DUMMY, |
97 | JUMP_INIT (finish, _IO_str_finish), |
98 | JUMP_INIT (overflow, _IO_str_overflow), |
99 | JUMP_INIT (underflow, _IO_str_underflow), |
100 | JUMP_INIT (uflow, _IO_default_uflow), |
101 | JUMP_INIT (pbackfail, _IO_str_pbackfail), |
102 | JUMP_INIT (xsputn, _IO_default_xsputn), |
103 | JUMP_INIT (xsgetn, _IO_default_xsgetn), |
104 | JUMP_INIT (seekoff, _IO_str_seekoff), |
105 | JUMP_INIT (seekpos, _IO_default_seekpos), |
106 | JUMP_INIT (setbuf, _IO_default_setbuf), |
107 | JUMP_INIT (sync, _IO_default_sync), |
108 | JUMP_INIT (doallocate, _IO_default_doallocate), |
109 | JUMP_INIT (read, _IO_default_read), |
110 | JUMP_INIT (write, _IO_default_write), |
111 | JUMP_INIT (seek, _IO_default_seek), |
112 | JUMP_INIT (close, _IO_default_close), |
113 | JUMP_INIT (stat, _IO_default_stat), |
114 | JUMP_INIT (showmanyc, _IO_default_showmanyc), |
115 | JUMP_INIT (imbue, _IO_default_imbue) |
116 | }, |
117 | /* _IO_wstr_jumps */ |
118 | [IO_WSTR_JUMPS] = { |
119 | JUMP_INIT_DUMMY, |
120 | JUMP_INIT (finish, _IO_wstr_finish), |
121 | JUMP_INIT (overflow, (_IO_overflow_t) _IO_wstr_overflow), |
122 | JUMP_INIT (underflow, (_IO_underflow_t) _IO_wstr_underflow), |
123 | JUMP_INIT (uflow, (_IO_underflow_t) _IO_wdefault_uflow), |
124 | JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail), |
125 | JUMP_INIT (xsputn, _IO_wdefault_xsputn), |
126 | JUMP_INIT (xsgetn, _IO_wdefault_xsgetn), |
127 | JUMP_INIT (seekoff, _IO_wstr_seekoff), |
128 | JUMP_INIT (seekpos, _IO_default_seekpos), |
129 | JUMP_INIT (setbuf, _IO_default_setbuf), |
130 | JUMP_INIT (sync, _IO_default_sync), |
131 | JUMP_INIT (doallocate, _IO_wdefault_doallocate), |
132 | JUMP_INIT (read, _IO_default_read), |
133 | JUMP_INIT (write, _IO_default_write), |
134 | JUMP_INIT (seek, _IO_default_seek), |
135 | JUMP_INIT (close, _IO_default_close), |
136 | JUMP_INIT (stat, _IO_default_stat), |
137 | JUMP_INIT (showmanyc, _IO_default_showmanyc), |
138 | JUMP_INIT (imbue, _IO_default_imbue) |
139 | }, |
140 | /* _IO_file_jumps */ |
141 | [IO_FILE_JUMPS] = { |
142 | JUMP_INIT_DUMMY, |
143 | JUMP_INIT (finish, _IO_file_finish), |
144 | JUMP_INIT (overflow, _IO_file_overflow), |
145 | JUMP_INIT (underflow, _IO_file_underflow), |
146 | JUMP_INIT (uflow, _IO_default_uflow), |
147 | JUMP_INIT (pbackfail, _IO_default_pbackfail), |
148 | JUMP_INIT (xsputn, _IO_file_xsputn), |
149 | JUMP_INIT (xsgetn, _IO_file_xsgetn), |
150 | JUMP_INIT (seekoff, _IO_new_file_seekoff), |
151 | JUMP_INIT (seekpos, _IO_default_seekpos), |
152 | JUMP_INIT (setbuf, _IO_new_file_setbuf), |
153 | JUMP_INIT (sync, _IO_new_file_sync), |
154 | JUMP_INIT (doallocate, _IO_file_doallocate), |
155 | JUMP_INIT (read, _IO_file_read), |
156 | JUMP_INIT (write, _IO_new_file_write), |
157 | JUMP_INIT (seek, _IO_file_seek), |
158 | JUMP_INIT (close, _IO_file_close), |
159 | JUMP_INIT (stat, _IO_file_stat), |
160 | JUMP_INIT (showmanyc, _IO_default_showmanyc), |
161 | JUMP_INIT (imbue, _IO_default_imbue) |
162 | }, |
163 | /* _IO_file_jumps_mmap */ |
164 | [IO_FILE_JUMPS_MMAP] = { |
165 | JUMP_INIT_DUMMY, |
166 | JUMP_INIT (finish, _IO_file_finish), |
167 | JUMP_INIT (overflow, _IO_file_overflow), |
168 | JUMP_INIT (underflow, _IO_file_underflow_mmap), |
169 | JUMP_INIT (uflow, _IO_default_uflow), |
170 | JUMP_INIT (pbackfail, _IO_default_pbackfail), |
171 | JUMP_INIT (xsputn, _IO_new_file_xsputn), |
172 | JUMP_INIT (xsgetn, _IO_file_xsgetn_mmap), |
173 | JUMP_INIT (seekoff, _IO_file_seekoff_mmap), |
174 | JUMP_INIT (seekpos, _IO_default_seekpos), |
175 | JUMP_INIT (setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap), |
176 | JUMP_INIT (sync, _IO_file_sync_mmap), |
177 | JUMP_INIT (doallocate, _IO_file_doallocate), |
178 | JUMP_INIT (read, _IO_file_read), |
179 | JUMP_INIT (write, _IO_new_file_write), |
180 | JUMP_INIT (seek, _IO_file_seek), |
181 | JUMP_INIT (close, _IO_file_close_mmap), |
182 | JUMP_INIT (stat, _IO_file_stat), |
183 | JUMP_INIT (showmanyc, _IO_default_showmanyc), |
184 | JUMP_INIT (imbue, _IO_default_imbue) |
185 | }, |
186 | /* _IO_file_jumps_maybe_mmap */ |
187 | [IO_FILE_JUMPS_MAYBE_MMAP] = { |
188 | JUMP_INIT_DUMMY, |
189 | JUMP_INIT (finish, _IO_file_finish), |
190 | JUMP_INIT (overflow, _IO_file_overflow), |
191 | JUMP_INIT (underflow, _IO_file_underflow_maybe_mmap), |
192 | JUMP_INIT (uflow, _IO_default_uflow), |
193 | JUMP_INIT (pbackfail, _IO_default_pbackfail), |
194 | JUMP_INIT (xsputn, _IO_new_file_xsputn), |
195 | JUMP_INIT (xsgetn, _IO_file_xsgetn_maybe_mmap), |
196 | JUMP_INIT (seekoff, _IO_file_seekoff_maybe_mmap), |
197 | JUMP_INIT (seekpos, _IO_default_seekpos), |
198 | JUMP_INIT (setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap), |
199 | JUMP_INIT (sync, _IO_new_file_sync), |
200 | JUMP_INIT (doallocate, _IO_file_doallocate), |
201 | JUMP_INIT (read, _IO_file_read), |
202 | JUMP_INIT (write, _IO_new_file_write), |
203 | JUMP_INIT (seek, _IO_file_seek), |
204 | JUMP_INIT (close, _IO_file_close), |
205 | JUMP_INIT (stat, _IO_file_stat), |
206 | JUMP_INIT (showmanyc, _IO_default_showmanyc), |
207 | JUMP_INIT (imbue, _IO_default_imbue) |
208 | }, |
209 | /* _IO_wfile_jumps */ |
210 | [IO_WFILE_JUMPS] = { |
211 | JUMP_INIT_DUMMY, |
212 | JUMP_INIT (finish, _IO_new_file_finish), |
213 | JUMP_INIT (overflow, (_IO_overflow_t) _IO_wfile_overflow), |
214 | JUMP_INIT (underflow, (_IO_underflow_t) _IO_wfile_underflow), |
215 | JUMP_INIT (uflow, (_IO_underflow_t) _IO_wdefault_uflow), |
216 | JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail), |
217 | JUMP_INIT (xsputn, _IO_wfile_xsputn), |
218 | JUMP_INIT (xsgetn, _IO_file_xsgetn), |
219 | JUMP_INIT (seekoff, _IO_wfile_seekoff), |
220 | JUMP_INIT (seekpos, _IO_default_seekpos), |
221 | JUMP_INIT (setbuf, _IO_new_file_setbuf), |
222 | JUMP_INIT (sync, (_IO_sync_t) _IO_wfile_sync), |
223 | JUMP_INIT (doallocate, _IO_wfile_doallocate), |
224 | JUMP_INIT (read, _IO_file_read), |
225 | JUMP_INIT (write, _IO_new_file_write), |
226 | JUMP_INIT (seek, _IO_file_seek), |
227 | JUMP_INIT (close, _IO_file_close), |
228 | JUMP_INIT (stat, _IO_file_stat), |
229 | JUMP_INIT (showmanyc, _IO_default_showmanyc), |
230 | JUMP_INIT (imbue, _IO_default_imbue) |
231 | }, |
232 | /* _IO_wfile_jumps_mmap */ |
233 | [IO_WFILE_JUMPS_MMAP] = { |
234 | JUMP_INIT_DUMMY, |
235 | JUMP_INIT (finish, _IO_new_file_finish), |
236 | JUMP_INIT (overflow, (_IO_overflow_t) _IO_wfile_overflow), |
237 | JUMP_INIT (underflow, (_IO_underflow_t) _IO_wfile_underflow_mmap), |
238 | JUMP_INIT (uflow, (_IO_underflow_t) _IO_wdefault_uflow), |
239 | JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail), |
240 | JUMP_INIT (xsputn, _IO_wfile_xsputn), |
241 | JUMP_INIT (xsgetn, _IO_file_xsgetn), |
242 | JUMP_INIT (seekoff, _IO_wfile_seekoff), |
243 | JUMP_INIT (seekpos, _IO_default_seekpos), |
244 | JUMP_INIT (setbuf, _IO_file_setbuf_mmap), |
245 | JUMP_INIT (sync, (_IO_sync_t) _IO_wfile_sync), |
246 | JUMP_INIT (doallocate, _IO_wfile_doallocate), |
247 | JUMP_INIT (read, _IO_file_read), |
248 | JUMP_INIT (write, _IO_new_file_write), |
249 | JUMP_INIT (seek, _IO_file_seek), |
250 | JUMP_INIT (close, _IO_file_close_mmap), |
251 | JUMP_INIT (stat, _IO_file_stat), |
252 | JUMP_INIT (showmanyc, _IO_default_showmanyc), |
253 | JUMP_INIT (imbue, _IO_default_imbue) |
254 | }, |
255 | /* _IO_wfile_jumps_maybe_mmap */ |
256 | [IO_WFILE_JUMPS_MAYBE_MMAP] = { |
257 | JUMP_INIT_DUMMY, |
258 | JUMP_INIT (finish, _IO_new_file_finish), |
259 | JUMP_INIT (overflow, (_IO_overflow_t) _IO_wfile_overflow), |
260 | JUMP_INIT (underflow, (_IO_underflow_t) _IO_wfile_underflow_maybe_mmap), |
261 | JUMP_INIT (uflow, (_IO_underflow_t) _IO_wdefault_uflow), |
262 | JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail), |
263 | JUMP_INIT (xsputn, _IO_wfile_xsputn), |
264 | JUMP_INIT (xsgetn, _IO_file_xsgetn), |
265 | JUMP_INIT (seekoff, _IO_wfile_seekoff), |
266 | JUMP_INIT (seekpos, _IO_default_seekpos), |
267 | JUMP_INIT (setbuf, _IO_file_setbuf_mmap), |
268 | JUMP_INIT (sync, (_IO_sync_t) _IO_wfile_sync), |
269 | JUMP_INIT (doallocate, _IO_wfile_doallocate), |
270 | JUMP_INIT (read, _IO_file_read), |
271 | JUMP_INIT (write, _IO_new_file_write), |
272 | JUMP_INIT (seek, _IO_file_seek), |
273 | JUMP_INIT (close, _IO_file_close), |
274 | JUMP_INIT (stat, _IO_file_stat), |
275 | JUMP_INIT (showmanyc, _IO_default_showmanyc), |
276 | JUMP_INIT (imbue, _IO_default_imbue) |
277 | }, |
278 | /* _IO_cookie_jumps */ |
279 | [IO_COOKIE_JUMPS] = { |
280 | JUMP_INIT_DUMMY, |
281 | JUMP_INIT (finish, _IO_file_finish), |
282 | JUMP_INIT (overflow, _IO_file_overflow), |
283 | JUMP_INIT (underflow, _IO_file_underflow), |
284 | JUMP_INIT (uflow, _IO_default_uflow), |
285 | JUMP_INIT (pbackfail, _IO_default_pbackfail), |
286 | JUMP_INIT (xsputn, _IO_file_xsputn), |
287 | JUMP_INIT (xsgetn, _IO_default_xsgetn), |
288 | JUMP_INIT (seekoff, _IO_cookie_seekoff), |
289 | JUMP_INIT (seekpos, _IO_default_seekpos), |
290 | JUMP_INIT (setbuf, _IO_file_setbuf), |
291 | JUMP_INIT (sync, _IO_file_sync), |
292 | JUMP_INIT (doallocate, _IO_file_doallocate), |
293 | JUMP_INIT (read, _IO_cookie_read), |
294 | JUMP_INIT (write, _IO_cookie_write), |
295 | JUMP_INIT (seek, _IO_cookie_seek), |
296 | JUMP_INIT (close, _IO_cookie_close), |
297 | JUMP_INIT (stat, _IO_default_stat), |
298 | JUMP_INIT (showmanyc, _IO_default_showmanyc), |
299 | JUMP_INIT (imbue, _IO_default_imbue), |
300 | }, |
301 | /* _IO_proc_jumps */ |
302 | [IO_PROC_JUMPS] = { |
303 | JUMP_INIT_DUMMY, |
304 | JUMP_INIT (finish, _IO_new_file_finish), |
305 | JUMP_INIT (overflow, _IO_new_file_overflow), |
306 | JUMP_INIT (underflow, _IO_new_file_underflow), |
307 | JUMP_INIT (uflow, _IO_default_uflow), |
308 | JUMP_INIT (pbackfail, _IO_default_pbackfail), |
309 | JUMP_INIT (xsputn, _IO_new_file_xsputn), |
310 | JUMP_INIT (xsgetn, _IO_default_xsgetn), |
311 | JUMP_INIT (seekoff, _IO_new_file_seekoff), |
312 | JUMP_INIT (seekpos, _IO_default_seekpos), |
313 | JUMP_INIT (setbuf, _IO_new_file_setbuf), |
314 | JUMP_INIT (sync, _IO_new_file_sync), |
315 | JUMP_INIT (doallocate, _IO_file_doallocate), |
316 | JUMP_INIT (read, _IO_file_read), |
317 | JUMP_INIT (write, _IO_new_file_write), |
318 | JUMP_INIT (seek, _IO_file_seek), |
319 | JUMP_INIT (close, _IO_new_proc_close), |
320 | JUMP_INIT (stat, _IO_file_stat), |
321 | JUMP_INIT (showmanyc, _IO_default_showmanyc), |
322 | JUMP_INIT (imbue, _IO_default_imbue) |
323 | }, |
324 | /* _IO_mem_jumps */ |
325 | [IO_MEM_JUMPS] = { |
326 | JUMP_INIT_DUMMY, |
327 | JUMP_INIT (finish, _IO_mem_finish), |
328 | JUMP_INIT (overflow, _IO_str_overflow), |
329 | JUMP_INIT (underflow, _IO_str_underflow), |
330 | JUMP_INIT (uflow, _IO_default_uflow), |
331 | JUMP_INIT (pbackfail, _IO_str_pbackfail), |
332 | JUMP_INIT (xsputn, _IO_default_xsputn), |
333 | JUMP_INIT (xsgetn, _IO_default_xsgetn), |
334 | JUMP_INIT (seekoff, _IO_str_seekoff), |
335 | JUMP_INIT (seekpos, _IO_default_seekpos), |
336 | JUMP_INIT (setbuf, _IO_default_setbuf), |
337 | JUMP_INIT (sync, _IO_mem_sync), |
338 | JUMP_INIT (doallocate, _IO_default_doallocate), |
339 | JUMP_INIT (read, _IO_default_read), |
340 | JUMP_INIT (write, _IO_default_write), |
341 | JUMP_INIT (seek, _IO_default_seek), |
342 | JUMP_INIT (close, _IO_default_close), |
343 | JUMP_INIT (stat, _IO_default_stat), |
344 | JUMP_INIT (showmanyc, _IO_default_showmanyc), |
345 | JUMP_INIT (imbue, _IO_default_imbue) |
346 | }, |
347 | /* _IO_wmem_jumps */ |
348 | [IO_WMEM_JUMPS] = { |
349 | JUMP_INIT_DUMMY, |
350 | JUMP_INIT (finish, _IO_wmem_finish), |
351 | JUMP_INIT (overflow, (_IO_overflow_t) _IO_wstr_overflow), |
352 | JUMP_INIT (underflow, (_IO_underflow_t) _IO_wstr_underflow), |
353 | JUMP_INIT (uflow, (_IO_underflow_t) _IO_wdefault_uflow), |
354 | JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail), |
355 | JUMP_INIT (xsputn, _IO_wdefault_xsputn), |
356 | JUMP_INIT (xsgetn, _IO_wdefault_xsgetn), |
357 | JUMP_INIT (seekoff, _IO_wstr_seekoff), |
358 | JUMP_INIT (seekpos, _IO_default_seekpos), |
359 | JUMP_INIT (setbuf, _IO_default_setbuf), |
360 | JUMP_INIT (sync, _IO_wmem_sync), |
361 | JUMP_INIT (doallocate, _IO_wdefault_doallocate), |
362 | JUMP_INIT (read, _IO_default_read), |
363 | JUMP_INIT (write, _IO_default_write), |
364 | JUMP_INIT (seek, _IO_default_seek), |
365 | JUMP_INIT (close, _IO_default_close), |
366 | JUMP_INIT (stat, _IO_default_stat), |
367 | JUMP_INIT (showmanyc, _IO_default_showmanyc), |
368 | JUMP_INIT (imbue, _IO_default_imbue) |
369 | }, |
370 | [IO_PRINTF_BUFFER_AS_FILE_JUMPS] = { |
371 | JUMP_INIT_DUMMY, |
372 | JUMP_INIT (finish, NULL), |
373 | JUMP_INIT (overflow, __printf_buffer_as_file_overflow), |
374 | JUMP_INIT (underflow, NULL), |
375 | JUMP_INIT (uflow, NULL), |
376 | JUMP_INIT (pbackfail, NULL), |
377 | JUMP_INIT (xsputn, __printf_buffer_as_file_xsputn), |
378 | JUMP_INIT (xsgetn, NULL), |
379 | JUMP_INIT (seekoff, NULL), |
380 | JUMP_INIT (seekpos, NULL), |
381 | JUMP_INIT (setbuf, NULL), |
382 | JUMP_INIT (sync, NULL), |
383 | JUMP_INIT (doallocate, NULL), |
384 | JUMP_INIT (read, NULL), |
385 | JUMP_INIT (write, NULL), |
386 | JUMP_INIT (seek, NULL), |
387 | JUMP_INIT (close, NULL), |
388 | JUMP_INIT (stat, NULL), |
389 | JUMP_INIT (showmanyc, NULL), |
390 | JUMP_INIT (imbue, NULL) |
391 | }, |
392 | [IO_WPRINTF_BUFFER_AS_FILE_JUMPS] = { |
393 | JUMP_INIT_DUMMY, |
394 | JUMP_INIT (finish, NULL), |
395 | JUMP_INIT (overflow, (_IO_overflow_t) __wprintf_buffer_as_file_overflow), |
396 | JUMP_INIT (underflow, NULL), |
397 | JUMP_INIT (uflow, NULL), |
398 | JUMP_INIT (pbackfail, NULL), |
399 | JUMP_INIT (xsputn, __wprintf_buffer_as_file_xsputn), |
400 | JUMP_INIT (xsgetn, NULL), |
401 | JUMP_INIT (seekoff, NULL), |
402 | JUMP_INIT (seekpos, NULL), |
403 | JUMP_INIT (setbuf, NULL), |
404 | JUMP_INIT (sync, NULL), |
405 | JUMP_INIT (doallocate, NULL), |
406 | JUMP_INIT (read, NULL), |
407 | JUMP_INIT (write, NULL), |
408 | JUMP_INIT (seek, NULL), |
409 | JUMP_INIT (close, NULL), |
410 | JUMP_INIT (stat, NULL), |
411 | JUMP_INIT (showmanyc, NULL), |
412 | JUMP_INIT (imbue, NULL) |
413 | }, |
414 | |
415 | #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) |
416 | /* _IO_old_file_jumps */ |
417 | [IO_OLD_FILE_JUMPS] = { |
418 | JUMP_INIT_DUMMY, |
419 | JUMP_INIT (finish, _IO_old_file_finish), |
420 | JUMP_INIT (overflow, _IO_old_file_overflow), |
421 | JUMP_INIT (underflow, _IO_old_file_underflow), |
422 | JUMP_INIT (uflow, _IO_default_uflow), |
423 | JUMP_INIT (pbackfail, _IO_default_pbackfail), |
424 | JUMP_INIT (xsputn, _IO_old_file_xsputn), |
425 | JUMP_INIT (xsgetn, _IO_default_xsgetn), |
426 | JUMP_INIT (seekoff, _IO_old_file_seekoff), |
427 | JUMP_INIT (seekpos, _IO_default_seekpos), |
428 | JUMP_INIT (setbuf, _IO_old_file_setbuf), |
429 | JUMP_INIT (sync, _IO_old_file_sync), |
430 | JUMP_INIT (doallocate, _IO_file_doallocate), |
431 | JUMP_INIT (read, _IO_file_read), |
432 | JUMP_INIT (write, _IO_old_file_write), |
433 | JUMP_INIT (seek, _IO_file_seek), |
434 | JUMP_INIT (close, _IO_file_close), |
435 | JUMP_INIT (stat, _IO_file_stat) |
436 | }, |
437 | /* _IO_old_proc_jumps */ |
438 | [IO_OLD_PROC_JUMPS] = { |
439 | JUMP_INIT_DUMMY, |
440 | JUMP_INIT (finish, _IO_old_file_finish), |
441 | JUMP_INIT (overflow, _IO_old_file_overflow), |
442 | JUMP_INIT (underflow, _IO_old_file_underflow), |
443 | JUMP_INIT (uflow, _IO_default_uflow), |
444 | JUMP_INIT (pbackfail, _IO_default_pbackfail), |
445 | JUMP_INIT (xsputn, _IO_old_file_xsputn), |
446 | JUMP_INIT (xsgetn, _IO_default_xsgetn), |
447 | JUMP_INIT (seekoff, _IO_old_file_seekoff), |
448 | JUMP_INIT (seekpos, _IO_default_seekpos), |
449 | JUMP_INIT (setbuf, _IO_old_file_setbuf), |
450 | JUMP_INIT (sync, _IO_old_file_sync), |
451 | JUMP_INIT (doallocate, _IO_file_doallocate), |
452 | JUMP_INIT (read, _IO_file_read), |
453 | JUMP_INIT (write, _IO_old_file_write), |
454 | JUMP_INIT (seek, _IO_file_seek), |
455 | JUMP_INIT (close, _IO_old_proc_close), |
456 | JUMP_INIT (stat, _IO_file_stat), |
457 | JUMP_INIT (showmanyc, _IO_default_showmanyc), |
458 | JUMP_INIT (imbue, _IO_default_imbue) |
459 | }, |
460 | #endif |
461 | |
462 | #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2) |
463 | /* _IO_old_cookie_jumps */ |
464 | [IO_OLD_COOKIED_JUMPS] = { |
465 | JUMP_INIT_DUMMY, |
466 | JUMP_INIT (finish, _IO_file_finish), |
467 | JUMP_INIT (overflow, _IO_file_overflow), |
468 | JUMP_INIT (underflow, _IO_file_underflow), |
469 | JUMP_INIT (uflow, _IO_default_uflow), |
470 | JUMP_INIT (pbackfail, _IO_default_pbackfail), |
471 | JUMP_INIT (xsputn, _IO_file_xsputn), |
472 | JUMP_INIT (xsgetn, _IO_default_xsgetn), |
473 | JUMP_INIT (seekoff, _IO_cookie_seekoff), |
474 | JUMP_INIT (seekpos, _IO_default_seekpos), |
475 | JUMP_INIT (setbuf, _IO_file_setbuf), |
476 | JUMP_INIT (sync, _IO_file_sync), |
477 | JUMP_INIT (doallocate, _IO_file_doallocate), |
478 | JUMP_INIT (read, _IO_cookie_read), |
479 | JUMP_INIT (write, _IO_cookie_write), |
480 | JUMP_INIT (seek, _IO_old_cookie_seek), |
481 | JUMP_INIT (close, _IO_cookie_close), |
482 | JUMP_INIT (stat, _IO_default_stat), |
483 | JUMP_INIT (showmanyc, _IO_default_showmanyc), |
484 | JUMP_INIT (imbue, _IO_default_imbue), |
485 | }, |
486 | #endif |
487 | }; |
488 | |
489 | #ifdef SHARED |
490 | |
491 | void (*IO_accept_foreign_vtables) (void) attribute_hidden; |
492 | |
493 | #else /* !SHARED */ |
494 | |
495 | /* Used to check whether static dlopen support is needed. */ |
496 | # pragma weak __dlopen |
497 | |
498 | #endif |
499 | |
500 | void attribute_hidden |
501 | _IO_vtable_check (void) |
502 | { |
503 | #ifdef SHARED |
504 | /* Honor the compatibility flag. */ |
505 | void (*flag) (void) = atomic_load_relaxed (&IO_accept_foreign_vtables); |
506 | PTR_DEMANGLE (flag); |
507 | if (flag == &_IO_vtable_check) |
508 | return; |
509 | |
510 | /* In case this libc copy is in a non-default namespace, we always |
511 | need to accept foreign vtables because there is always a |
512 | possibility that FILE * objects are passed across the linking |
513 | boundary. */ |
514 | { |
515 | Dl_info di; |
516 | struct link_map *l; |
517 | if (!rtld_active () |
518 | || (_dl_addr (_IO_vtable_check, &di, &l, NULL) != 0 |
519 | && l->l_ns != LM_ID_BASE)) |
520 | return; |
521 | } |
522 | |
523 | #else /* !SHARED */ |
524 | /* We cannot perform vtable validation in the static dlopen case |
525 | because FILE * handles might be passed back and forth across the |
526 | boundary. Therefore, we disable checking in this case. */ |
527 | if (__dlopen != NULL) |
528 | return; |
529 | #endif |
530 | |
531 | __libc_fatal ("Fatal error: glibc detected an invalid stdio handle\n" ); |
532 | } |
533 | |
534 | /* Some variants of libstdc++ interpose _IO_2_1_stdin_ etc. and |
535 | install their own vtables directly, without calling _IO_init or |
536 | other functions. Detect this by looking at the vtables values |
537 | during startup, and disable vtable validation in this case. */ |
538 | #ifdef SHARED |
539 | __attribute__ ((constructor)) |
540 | static void |
541 | check_stdfiles_vtables (void) |
542 | { |
543 | if (_IO_2_1_stdin_.vtable != &_IO_file_jumps |
544 | || _IO_2_1_stdout_.vtable != &_IO_file_jumps |
545 | || _IO_2_1_stderr_.vtable != &_IO_file_jumps) |
546 | IO_set_accept_foreign_vtables (&_IO_vtable_check); |
547 | } |
548 | #endif |
549 | |
550 | #define STR(s) XSTR(s) |
551 | #define XSTR(s) #s |
552 | |
553 | #undef _IO_file_jumps |
554 | #define _IO_file_jumps_alias "__io_vtables + " STR(IO_FILE_JUMPS_OFFSET) |
555 | declare_object_symbol_alias (_IO_file_jumps, _IO_file_jumps_alias, |
556 | IO_JUMP_T_SIZE) |
557 | #undef _IO_wfile_jumps |
558 | #define _IO_wfile_jumps_alias "__io_vtables + " STR(IO_WFILE_JUMPS_OFFSET) |
559 | declare_object_symbol_alias (_IO_wfile_jumps, _IO_wfile_jumps_alias, |
560 | IO_JUMP_T_SIZE) |
561 | |