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

source code of glibc/libio/vtables.c