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 | |
92 | const 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 | |
494 | void (*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 | |
503 | void 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)) |
543 | static void |
544 | check_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) |
558 | declare_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) |
562 | declare_object_symbol_alias (_IO_wfile_jumps, _IO_wfile_jumps_alias, |
563 | IO_JUMP_T_SIZE) |
564 | |