[5/7] libio: Remove the usage of __libc_IO_vtables

Message ID 20221115193159.173838-6-adhemerval.zanella@linaro.org
State Under Review
Delegated to: Florian Weimer
Headers
Series Fixing remaining lld issues |

Checks

Context Check Description
dj/TryBot-apply_patch success Patch applied to master at the time it was sent

Commit Message

Adhemerval Zanella Netto Nov. 15, 2022, 7:31 p.m. UTC
  The libio vtables are all moved to an array and the IO_validate_vtable
checks if the vtable is within the array, instead of using special
ELF section and linker scripts directives.

To avoid static linking namespace issues and to pulling all vtables
referenced objects, all function pointers are set to weak references.
This also leads to slight small static objects that uses printf-like
family.

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.
---
 Makerules                        |  24 --
 elf/Makefile                     |  20 +-
 include/libc-symbols.h           |  18 +-
 libio/Makefile                   |   2 +
 libio/fileops.c                  |  81 +----
 libio/iofopncook.c               |  60 +---
 libio/iopopen.c                  |  25 --
 libio/iovsprintf.c               |  26 +-
 libio/libio-macros.sym           |   7 +
 libio/libioP.h                   | 312 ++++++++++++-------
 libio/memstream.c                |  32 +-
 libio/obprintf.c                 |  34 +--
 libio/oldfileops.c               |  23 --
 libio/oldiopopen.c               |  23 --
 libio/stdio.c                    |   3 +
 libio/strfile.h                  |   5 -
 libio/strops.c                   |  24 --
 libio/tst-vtables-interposed.c   |   5 +
 libio/vsnprintf.c                |  29 +-
 libio/vswprintf.c                |  30 +-
 libio/vtables.c                  | 502 +++++++++++++++++++++++++++++++
 libio/wfileops.c                 |  79 +----
 libio/wmemstream.c               |  32 +-
 libio/wstrops.c                  |  24 --
 stdio-common/vfprintf-internal.c |  60 +---
 25 files changed, 770 insertions(+), 710 deletions(-)
 create mode 100644 libio/libio-macros.sym
  

Patch

diff --git a/Makerules b/Makerules
index 962b2cd90c..41fc8db4ba 100644
--- a/Makerules
+++ b/Makerules
@@ -544,34 +544,10 @@  $(LINK.o) -shared -static-libgcc -Wl,-O1 $(sysdep-LDFLAGS) \
 	  -L$(subst :, -L,$(rpath-link)) -Wl,-rpath-link=$(rpath-link)
 endef
 
-ifeq (yes,$(use-default-link))
 # If the linker is good enough, we can let it use its default linker script.
 # In the long term the custom linker script will be removed.
 shlib-lds =
 shlib-lds-flags =
-else
-# binutils only position loadable notes into the first page for binaries,
-# not for shared objects
-# lld --verbose does not dump a linker script.  Use -fuse-ld=bfd.
-$(common-objpfx)shlib.lds: $(common-objpfx)config.make $(..)Makerules
-	$(LINK.o) -shared -Wl,-O1 \
-		  -nostdlib -nostartfiles -fuse-ld=bfd \
-		  $(sysdep-LDFLAGS) $(rtld-LDFLAGS) $(LDFLAGS.so) \
-		  -Wl,--verbose 2>/dev/null | \
-	  sed > $@T \
-	      -e '/^=========/,/^=========/!d;/^=========/d' \
-	      -e 's@^.*\*(\.jcr).*$$@& \
-		 PROVIDE(__start___libc_IO_vtables = .);\
-		 __libc_IO_vtables : { *(__libc_IO_vtables) }\
-		 PROVIDE(__stop___libc_IO_vtables = .);\
-		 /DISCARD/ : { *(.gnu.glibc-stub.*) }@'
-	test -s $@T
-	mv -f $@T $@
-common-generated += shlib.lds
-
-shlib-lds = $(common-objpfx)shlib.lds
-shlib-lds-flags = -T $(shlib-lds)
-endif
 
 define build-shlib
 $(build-shlib-helper) -o $@ $(shlib-lds-flags) \
diff --git a/elf/Makefile b/elf/Makefile
index 6de2ca6d6c..8527e659dc 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -595,27 +595,11 @@  $(objpfx)tst-relro-ldso.out: tst-relro-symbols.py $(..)/scripts/glibcelf.py \
 $(objpfx)tst-relro-libc.out: tst-relro-symbols.py $(..)/scripts/glibcelf.py \
   $(common-objpfx)libc.so
 	$(PYTHON) tst-relro-symbols.py $(common-objpfx)libc.so \
-	    --required=_IO_cookie_jumps \
 	    --required=_IO_file_jumps \
-	    --required=_IO_file_jumps_maybe_mmap \
-	    --required=_IO_file_jumps_mmap \
-	    --required=_IO_helper_jumps \
-	    --required=_IO_mem_jumps \
-	    --required=_IO_obstack_jumps \
-	    --required=_IO_proc_jumps \
-	    --required=_IO_str_chk_jumps \
-	    --required=_IO_str_jumps \
-	    --required=_IO_strn_jumps \
 	    --required=_IO_wfile_jumps \
-	    --required=_IO_wfile_jumps_maybe_mmap \
-	    --required=_IO_wfile_jumps_mmap \
-	    --required=_IO_wmem_jumps \
-	    --required=_IO_wstr_jumps \
-	    --required=_IO_wstrn_jumps \
+	    --required=__io_vtables \
+	    --required=__io_vtables_size \
 	    --required=__libc_freeres_funcs \
-	    --optional=_IO_old_cookie_jumps \
-	    --optional=_IO_old_file_jumps \
-	    --optional=_IO_old_proc_jumps \
 	  > $@ 2>&1; $(evaluate-test)
 
 ifeq ($(run-built-tests),yes)
diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index a1d422131f..02fbfe91f0 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -243,20 +243,26 @@  for linking")
    This is only necessary when defining something in assembly, or playing
    funny alias games where the size should be other than what the compiler
    thinks it is.  */
-#ifdef __ASSEMBLER__
-# define declare_object_symbol_alias(symbol, original, size) \
+#define declare_object_symbol_alias(symbol, original, size) \
   declare_object_symbol_alias_1 (symbol, original, size)
+#ifdef __ASSEMBLER__
 # define declare_object_symbol_alias_1(symbol, original, s_size) \
    strong_alias (original, symbol) ASM_LINE_SEP \
    .type C_SYMBOL_NAME (symbol), %object ASM_LINE_SEP \
    .size C_SYMBOL_NAME (symbol), s_size ASM_LINE_SEP
 #else /* Not __ASSEMBLER__.  */
 # ifdef HAVE_ASM_SET_DIRECTIVE
-#  define declare_symbol_alias_1_alias(symbol, original) \
-     ".set " __SYMBOL_PREFIX #symbol ", " __SYMBOL_PREFIX #original
+#  define declare_object_symbol_alias_1(symbol, original, size) \
+     asm (".global " __SYMBOL_PREFIX # symbol "\n" \
+	  ".type " __SYMBOL_PREFIX # symbol ", %object\n" \
+	  ".set " __SYMBOL_PREFIX #symbol ", " __SYMBOL_PREFIX original "\n" \
+	  ".size " __SYMBOL_PREFIX #symbol ", " #size "\n");
 # else
-#  define declare_symbol_alias_1_alias(symbol, original) \
-     __SYMBOL_PREFIX #symbol " = " __SYMBOL_PREFIX #original
+#  define declare_object_symbol_alias_1(symbol, original, size) \
+     asm (".global " __SYMBOL_PREFIX # symbol "\n" \
+	  ".type " __SYMBOL_PREFIX # symbol ", %object\n" \
+	  __SYMBOL_PREFIX #symbol " = " __SYMBOL_PREFIX original "\n" \
+	  ".size " __SYMBOL_PREFIX #symbol ", " #size "\n");
 # endif /* HAVE_ASM_SET_DIRECTIVE */
 #endif /* __ASSEMBLER__ */
 
diff --git a/libio/Makefile b/libio/Makefile
index 64398ab1ee..fc67aea9e2 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -51,6 +51,8 @@  routines	:=							      \
 									      \
 	libc_fatal fmemopen oldfmemopen vtables
 
+gen-as-const-headers += libio-macros.sym
+
 tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc   \
 	tst_wprintf2 tst-widetext test-fmemopen tst-ext tst-ext2 \
 	tst-fgetws tst-ungetwc1 tst-ungetwc2 tst-swscanf tst-sscanf	      \
diff --git a/libio/fileops.c b/libio/fileops.c
index 41c18be789..87027d5adb 100644
--- a/libio/fileops.c
+++ b/libio/fileops.c
@@ -815,7 +815,7 @@  _IO_new_file_sync (FILE *fp)
 }
 libc_hidden_ver (_IO_new_file_sync, _IO_file_sync)
 
-static int
+int
 _IO_file_sync_mmap (FILE *fp)
 {
   if (fp->_IO_read_ptr != fp->_IO_read_end)
@@ -1109,7 +1109,7 @@  _IO_file_seekoff_mmap (FILE *fp, off64_t offset, int dir, int mode)
   return offset;
 }
 
-static off64_t
+off64_t
 _IO_file_seekoff_maybe_mmap (FILE *fp, off64_t offset, int dir,
 			     int mode)
 {
@@ -1360,7 +1360,7 @@  _IO_file_xsgetn (FILE *fp, void *data, size_t n)
 }
 libc_hidden_def (_IO_file_xsgetn)
 
-static size_t
+size_t
 _IO_file_xsgetn_mmap (FILE *fp, void *data, size_t n)
 {
   size_t have;
@@ -1405,7 +1405,7 @@  _IO_file_xsgetn_mmap (FILE *fp, void *data, size_t n)
   return s - (char *) data;
 }
 
-static size_t
+size_t
 _IO_file_xsgetn_maybe_mmap (FILE *fp, void *data, size_t n)
 {
   /* We only get here if this is the first attempt to read something.
@@ -1428,76 +1428,3 @@  versioned_symbol (libc, _IO_new_file_seekoff, _IO_file_seekoff, GLIBC_2_1);
 versioned_symbol (libc, _IO_new_file_underflow, _IO_file_underflow, GLIBC_2_1);
 versioned_symbol (libc, _IO_new_file_write, _IO_file_write, GLIBC_2_1);
 versioned_symbol (libc, _IO_new_file_xsputn, _IO_file_xsputn, GLIBC_2_1);
-
-const struct _IO_jump_t _IO_file_jumps libio_vtable =
-{
-  JUMP_INIT_DUMMY,
-  JUMP_INIT(finish, _IO_file_finish),
-  JUMP_INIT(overflow, _IO_file_overflow),
-  JUMP_INIT(underflow, _IO_file_underflow),
-  JUMP_INIT(uflow, _IO_default_uflow),
-  JUMP_INIT(pbackfail, _IO_default_pbackfail),
-  JUMP_INIT(xsputn, _IO_file_xsputn),
-  JUMP_INIT(xsgetn, _IO_file_xsgetn),
-  JUMP_INIT(seekoff, _IO_new_file_seekoff),
-  JUMP_INIT(seekpos, _IO_default_seekpos),
-  JUMP_INIT(setbuf, _IO_new_file_setbuf),
-  JUMP_INIT(sync, _IO_new_file_sync),
-  JUMP_INIT(doallocate, _IO_file_doallocate),
-  JUMP_INIT(read, _IO_file_read),
-  JUMP_INIT(write, _IO_new_file_write),
-  JUMP_INIT(seek, _IO_file_seek),
-  JUMP_INIT(close, _IO_file_close),
-  JUMP_INIT(stat, _IO_file_stat),
-  JUMP_INIT(showmanyc, _IO_default_showmanyc),
-  JUMP_INIT(imbue, _IO_default_imbue)
-};
-libc_hidden_data_def (_IO_file_jumps)
-
-const struct _IO_jump_t _IO_file_jumps_mmap libio_vtable =
-{
-  JUMP_INIT_DUMMY,
-  JUMP_INIT(finish, _IO_file_finish),
-  JUMP_INIT(overflow, _IO_file_overflow),
-  JUMP_INIT(underflow, _IO_file_underflow_mmap),
-  JUMP_INIT(uflow, _IO_default_uflow),
-  JUMP_INIT(pbackfail, _IO_default_pbackfail),
-  JUMP_INIT(xsputn, _IO_new_file_xsputn),
-  JUMP_INIT(xsgetn, _IO_file_xsgetn_mmap),
-  JUMP_INIT(seekoff, _IO_file_seekoff_mmap),
-  JUMP_INIT(seekpos, _IO_default_seekpos),
-  JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap),
-  JUMP_INIT(sync, _IO_file_sync_mmap),
-  JUMP_INIT(doallocate, _IO_file_doallocate),
-  JUMP_INIT(read, _IO_file_read),
-  JUMP_INIT(write, _IO_new_file_write),
-  JUMP_INIT(seek, _IO_file_seek),
-  JUMP_INIT(close, _IO_file_close_mmap),
-  JUMP_INIT(stat, _IO_file_stat),
-  JUMP_INIT(showmanyc, _IO_default_showmanyc),
-  JUMP_INIT(imbue, _IO_default_imbue)
-};
-
-const struct _IO_jump_t _IO_file_jumps_maybe_mmap libio_vtable =
-{
-  JUMP_INIT_DUMMY,
-  JUMP_INIT(finish, _IO_file_finish),
-  JUMP_INIT(overflow, _IO_file_overflow),
-  JUMP_INIT(underflow, _IO_file_underflow_maybe_mmap),
-  JUMP_INIT(uflow, _IO_default_uflow),
-  JUMP_INIT(pbackfail, _IO_default_pbackfail),
-  JUMP_INIT(xsputn, _IO_new_file_xsputn),
-  JUMP_INIT(xsgetn, _IO_file_xsgetn_maybe_mmap),
-  JUMP_INIT(seekoff, _IO_file_seekoff_maybe_mmap),
-  JUMP_INIT(seekpos, _IO_default_seekpos),
-  JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap),
-  JUMP_INIT(sync, _IO_new_file_sync),
-  JUMP_INIT(doallocate, _IO_file_doallocate),
-  JUMP_INIT(read, _IO_file_read),
-  JUMP_INIT(write, _IO_new_file_write),
-  JUMP_INIT(seek, _IO_file_seek),
-  JUMP_INIT(close, _IO_file_close),
-  JUMP_INIT(stat, _IO_file_stat),
-  JUMP_INIT(showmanyc, _IO_default_showmanyc),
-  JUMP_INIT(imbue, _IO_default_imbue)
-};
diff --git a/libio/iofopncook.c b/libio/iofopncook.c
index 6c27610319..338cb31c79 100644
--- a/libio/iofopncook.c
+++ b/libio/iofopncook.c
@@ -30,7 +30,7 @@ 
 #include <shlib-compat.h>
 #include <pointer_guard.h>
 
-static ssize_t
+ssize_t
 _IO_cookie_read (FILE *fp, void *buf, ssize_t size)
 {
   struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
@@ -43,7 +43,7 @@  _IO_cookie_read (FILE *fp, void *buf, ssize_t size)
   return read_cb (cfile->__cookie, buf, size);
 }
 
-static ssize_t
+ssize_t
 _IO_cookie_write (FILE *fp, const void *buf, ssize_t size)
 {
   struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
@@ -63,7 +63,7 @@  _IO_cookie_write (FILE *fp, const void *buf, ssize_t size)
   return n;
 }
 
-static off64_t
+off64_t
 _IO_cookie_seek (FILE *fp, off64_t offset, int dir)
 {
   struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
@@ -77,7 +77,7 @@  _IO_cookie_seek (FILE *fp, off64_t offset, int dir)
 	  ? _IO_pos_BAD : offset);
 }
 
-static int
+int
 _IO_cookie_close (FILE *fp)
 {
   struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
@@ -91,7 +91,7 @@  _IO_cookie_close (FILE *fp)
 }
 
 
-static off64_t
+off64_t
 _IO_cookie_seekoff (FILE *fp, off64_t offset, int dir, int mode)
 {
   /* We must force the fileops code to always use seek to determine
@@ -100,31 +100,6 @@  _IO_cookie_seekoff (FILE *fp, off64_t offset, int dir, int mode)
   return _IO_file_seekoff (fp, offset, dir, mode);
 }
 
-
-static const struct _IO_jump_t _IO_cookie_jumps libio_vtable = {
-  JUMP_INIT_DUMMY,
-  JUMP_INIT(finish, _IO_file_finish),
-  JUMP_INIT(overflow, _IO_file_overflow),
-  JUMP_INIT(underflow, _IO_file_underflow),
-  JUMP_INIT(uflow, _IO_default_uflow),
-  JUMP_INIT(pbackfail, _IO_default_pbackfail),
-  JUMP_INIT(xsputn, _IO_file_xsputn),
-  JUMP_INIT(xsgetn, _IO_default_xsgetn),
-  JUMP_INIT(seekoff, _IO_cookie_seekoff),
-  JUMP_INIT(seekpos, _IO_default_seekpos),
-  JUMP_INIT(setbuf, _IO_file_setbuf),
-  JUMP_INIT(sync, _IO_file_sync),
-  JUMP_INIT(doallocate, _IO_file_doallocate),
-  JUMP_INIT(read, _IO_cookie_read),
-  JUMP_INIT(write, _IO_cookie_write),
-  JUMP_INIT(seek, _IO_cookie_seek),
-  JUMP_INIT(close, _IO_cookie_close),
-  JUMP_INIT(stat, _IO_default_stat),
-  JUMP_INIT(showmanyc, _IO_default_showmanyc),
-  JUMP_INIT(imbue, _IO_default_imbue),
-};
-
-
 /* Copy the callbacks from SOURCE to *TARGET, with pointer
    mangling.  */
 static void
@@ -209,7 +184,7 @@  versioned_symbol (libc, _IO_fopencookie, fopencookie, GLIBC_2_2);
 
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
 
-static off64_t
+off64_t
 attribute_compat_text_section
 _IO_old_cookie_seek (FILE *fp, off64_t offset, int dir)
 {
@@ -226,29 +201,6 @@  _IO_old_cookie_seek (FILE *fp, off64_t offset, int dir)
   return (ret == -1) ? _IO_pos_BAD : ret;
 }
 
-static const struct _IO_jump_t _IO_old_cookie_jumps libio_vtable = {
-  JUMP_INIT_DUMMY,
-  JUMP_INIT(finish, _IO_file_finish),
-  JUMP_INIT(overflow, _IO_file_overflow),
-  JUMP_INIT(underflow, _IO_file_underflow),
-  JUMP_INIT(uflow, _IO_default_uflow),
-  JUMP_INIT(pbackfail, _IO_default_pbackfail),
-  JUMP_INIT(xsputn, _IO_file_xsputn),
-  JUMP_INIT(xsgetn, _IO_default_xsgetn),
-  JUMP_INIT(seekoff, _IO_cookie_seekoff),
-  JUMP_INIT(seekpos, _IO_default_seekpos),
-  JUMP_INIT(setbuf, _IO_file_setbuf),
-  JUMP_INIT(sync, _IO_file_sync),
-  JUMP_INIT(doallocate, _IO_file_doallocate),
-  JUMP_INIT(read, _IO_cookie_read),
-  JUMP_INIT(write, _IO_cookie_write),
-  JUMP_INIT(seek, _IO_old_cookie_seek),
-  JUMP_INIT(close, _IO_cookie_close),
-  JUMP_INIT(stat, _IO_default_stat),
-  JUMP_INIT(showmanyc, _IO_default_showmanyc),
-  JUMP_INIT(imbue, _IO_default_imbue),
-};
-
 FILE *
 attribute_compat_text_section
 _IO_old_fopencookie (void *cookie, const char *mode,
diff --git a/libio/iopopen.c b/libio/iopopen.c
index 06778cf110..5ed30a817b 100644
--- a/libio/iopopen.c
+++ b/libio/iopopen.c
@@ -45,8 +45,6 @@  struct _IO_proc_file
 };
 typedef struct _IO_proc_file _IO_proc_file;
 
-static const struct _IO_jump_t _IO_proc_jumps;
-
 static struct _IO_proc_file *proc_file_chain;
 
 #ifdef _IO_MTSAFE_IO
@@ -291,29 +289,6 @@  _IO_new_proc_close (FILE *fp)
   return wstatus;
 }
 
-static const struct _IO_jump_t _IO_proc_jumps libio_vtable = {
-  JUMP_INIT_DUMMY,
-  JUMP_INIT(finish, _IO_new_file_finish),
-  JUMP_INIT(overflow, _IO_new_file_overflow),
-  JUMP_INIT(underflow, _IO_new_file_underflow),
-  JUMP_INIT(uflow, _IO_default_uflow),
-  JUMP_INIT(pbackfail, _IO_default_pbackfail),
-  JUMP_INIT(xsputn, _IO_new_file_xsputn),
-  JUMP_INIT(xsgetn, _IO_default_xsgetn),
-  JUMP_INIT(seekoff, _IO_new_file_seekoff),
-  JUMP_INIT(seekpos, _IO_default_seekpos),
-  JUMP_INIT(setbuf, _IO_new_file_setbuf),
-  JUMP_INIT(sync, _IO_new_file_sync),
-  JUMP_INIT(doallocate, _IO_file_doallocate),
-  JUMP_INIT(read, _IO_file_read),
-  JUMP_INIT(write, _IO_new_file_write),
-  JUMP_INIT(seek, _IO_file_seek),
-  JUMP_INIT(close, _IO_new_proc_close),
-  JUMP_INIT(stat, _IO_file_stat),
-  JUMP_INIT(showmanyc, _IO_default_showmanyc),
-  JUMP_INIT(imbue, _IO_default_imbue)
-};
-
 strong_alias (_IO_new_popen, __new_popen)
 versioned_symbol (libc, _IO_new_popen, _IO_popen, GLIBC_2_1);
 versioned_symbol (libc, __new_popen, popen, GLIBC_2_1);
diff --git a/libio/iovsprintf.c b/libio/iovsprintf.c
index 72c67bf27b..ca73de9313 100644
--- a/libio/iovsprintf.c
+++ b/libio/iovsprintf.c
@@ -27,7 +27,7 @@ 
 #include "libioP.h"
 #include "strfile.h"
 
-static int __THROW
+int __THROW
 _IO_str_chk_overflow (FILE *fp, int c)
 {
   /* If we get here, the user-supplied buffer would be overrun by
@@ -35,30 +35,6 @@  _IO_str_chk_overflow (FILE *fp, int c)
   __chk_fail ();
 }
 
-static const struct _IO_jump_t _IO_str_chk_jumps libio_vtable =
-{
-  JUMP_INIT_DUMMY,
-  JUMP_INIT(finish, _IO_str_finish),
-  JUMP_INIT(overflow, _IO_str_chk_overflow),
-  JUMP_INIT(underflow, _IO_str_underflow),
-  JUMP_INIT(uflow, _IO_default_uflow),
-  JUMP_INIT(pbackfail, _IO_str_pbackfail),
-  JUMP_INIT(xsputn, _IO_default_xsputn),
-  JUMP_INIT(xsgetn, _IO_default_xsgetn),
-  JUMP_INIT(seekoff, _IO_str_seekoff),
-  JUMP_INIT(seekpos, _IO_default_seekpos),
-  JUMP_INIT(setbuf, _IO_default_setbuf),
-  JUMP_INIT(sync, _IO_default_sync),
-  JUMP_INIT(doallocate, _IO_default_doallocate),
-  JUMP_INIT(read, _IO_default_read),
-  JUMP_INIT(write, _IO_default_write),
-  JUMP_INIT(seek, _IO_default_seek),
-  JUMP_INIT(close, _IO_default_close),
-  JUMP_INIT(stat, _IO_default_stat),
-  JUMP_INIT(showmanyc, _IO_default_showmanyc),
-  JUMP_INIT(imbue, _IO_default_imbue)
-};
-
 /* This function is called by regular vsprintf with maxlen set to -1,
    and by vsprintf_chk with maxlen set to the size of the output
    string.  In the former case, _IO_str_chk_overflow will never be
diff --git a/libio/libio-macros.sym b/libio/libio-macros.sym
new file mode 100644
index 0000000000..cfb5cf2841
--- /dev/null
+++ b/libio/libio-macros.sym
@@ -0,0 +1,7 @@ 
+#include <libioP.h>
+
+--
+
+IO_JUMP_T_SIZE		sizeof (struct _IO_jump_t)
+IO_FILE_JUMPS_OFFSET	sizeof (struct _IO_jump_t) * IO_FILE_JUMPS
+IO_WFILE_JUMPS_OFFSET	sizeof (struct _IO_jump_t) * IO_WFILE_JUMPS
diff --git a/libio/libioP.h b/libio/libioP.h
index 3a5498bd65..63d2145963 100644
--- a/libio/libioP.h
+++ b/libio/libioP.h
@@ -431,57 +431,105 @@  libc_hidden_proto (_IO_enable_locks)
 
 /* Default jumptable functions. */
 
-extern int _IO_default_underflow (FILE *) __THROW;
-extern int _IO_default_uflow (FILE *);
+extern int _IO_default_underflow (FILE *) __THROW weak_function;
+extern int _IO_default_uflow (FILE *) weak_function;
 libc_hidden_proto (_IO_default_uflow)
-extern wint_t _IO_wdefault_uflow (FILE *);
+extern wint_t _IO_wdefault_uflow (FILE *) weak_function;
 libc_hidden_proto (_IO_wdefault_uflow)
-extern int _IO_default_doallocate (FILE *) __THROW;
+extern int _IO_default_doallocate (FILE *) __THROW weak_function;
 libc_hidden_proto (_IO_default_doallocate)
-extern int _IO_wdefault_doallocate (FILE *) __THROW;
+extern int _IO_wdefault_doallocate (FILE *) __THROW weak_function;
 libc_hidden_proto (_IO_wdefault_doallocate)
-extern void _IO_default_finish (FILE *, int) __THROW;
+extern void _IO_default_finish (FILE *, int) __THROW weak_function;
 libc_hidden_proto (_IO_default_finish)
-extern void _IO_wdefault_finish (FILE *, int) __THROW;
+extern void _IO_wdefault_finish (FILE *, int) __THROW weak_function;
 libc_hidden_proto (_IO_wdefault_finish)
-extern int _IO_default_pbackfail (FILE *, int) __THROW;
+extern int _IO_default_pbackfail (FILE *, int) __THROW weak_function;
 libc_hidden_proto (_IO_default_pbackfail)
-extern wint_t _IO_wdefault_pbackfail (FILE *, wint_t) __THROW;
+extern wint_t _IO_wdefault_pbackfail (FILE *, wint_t) __THROW weak_function;
 libc_hidden_proto (_IO_wdefault_pbackfail)
-extern FILE* _IO_default_setbuf (FILE *, char *, ssize_t);
-extern size_t _IO_default_xsputn (FILE *, const void *, size_t);
+extern FILE* _IO_default_setbuf (FILE *, char *, ssize_t) weak_function;
+extern size_t _IO_default_xsputn (FILE *, const void *, size_t) weak_function;
 libc_hidden_proto (_IO_default_xsputn)
-extern size_t _IO_wdefault_xsputn (FILE *, const void *, size_t);
+extern size_t _IO_wdefault_xsputn (FILE *, const void *, size_t)
+     weak_function;
 libc_hidden_proto (_IO_wdefault_xsputn)
-extern size_t _IO_default_xsgetn (FILE *, void *, size_t);
+extern size_t _IO_default_xsgetn (FILE *, void *, size_t) weak_function;
 libc_hidden_proto (_IO_default_xsgetn)
-extern size_t _IO_wdefault_xsgetn (FILE *, void *, size_t);
+extern size_t _IO_wdefault_xsgetn (FILE *, void *, size_t) weak_function;
 libc_hidden_proto (_IO_wdefault_xsgetn)
 extern off64_t _IO_default_seekoff (FILE *, off64_t, int, int)
-     __THROW;
-extern off64_t _IO_default_seekpos (FILE *, off64_t, int);
-extern ssize_t _IO_default_write (FILE *, const void *, ssize_t);
-extern ssize_t _IO_default_read (FILE *, void *, ssize_t);
+     __THROW weak_function;
+extern off64_t _IO_default_seekpos (FILE *, off64_t, int) weak_function;
+extern ssize_t _IO_default_write (FILE *, const void *, ssize_t)
+     weak_function;
+extern ssize_t _IO_default_read (FILE *, void *, ssize_t) weak_function;
 extern int _IO_default_stat (FILE *, void *) __THROW;
-extern off64_t _IO_default_seek (FILE *, off64_t, int) __THROW;
-extern int _IO_default_sync (FILE *) __THROW;
+extern off64_t _IO_default_seek (FILE *, off64_t, int) __THROW weak_function;
+extern int _IO_default_sync (FILE *) __THROW weak_function;
 #define _IO_default_close ((_IO_close_t) _IO_default_sync)
-extern int _IO_default_showmanyc (FILE *) __THROW;
-extern void _IO_default_imbue (FILE *, void *) __THROW;
-
-extern const struct _IO_jump_t _IO_file_jumps;
-libc_hidden_proto (_IO_file_jumps)
-extern const struct _IO_jump_t _IO_file_jumps_mmap attribute_hidden;
-extern const struct _IO_jump_t _IO_file_jumps_maybe_mmap attribute_hidden;
-extern const struct _IO_jump_t _IO_wfile_jumps;
-libc_hidden_proto (_IO_wfile_jumps)
-extern const struct _IO_jump_t _IO_wfile_jumps_mmap attribute_hidden;
-extern const struct _IO_jump_t _IO_wfile_jumps_maybe_mmap attribute_hidden;
-extern const struct _IO_jump_t _IO_old_file_jumps attribute_hidden;
-extern const struct _IO_jump_t _IO_streambuf_jumps;
-extern const struct _IO_jump_t _IO_old_proc_jumps attribute_hidden;
-extern const struct _IO_jump_t _IO_str_jumps attribute_hidden;
-extern const struct _IO_jump_t _IO_wstr_jumps attribute_hidden;
+extern int _IO_default_showmanyc (FILE *) __THROW weak_function;
+extern void _IO_default_imbue (FILE *, void *) __THROW weak_function;
+
+enum
+{
+  IO_STR_JUMPS              = 0,
+  IO_WSTR_JUMPS             = 1,
+  IO_STRN_JUMPS             = 2,
+  IO_WSTRN_JUMPS            = 3,
+  IO_FILE_JUMPS             = 4,
+  IO_FILE_JUMPS_MMAP        = 5,
+  IO_FILE_JUMPS_MAYBE_MMAP  = 6,
+  IO_WFILE_JUMPS            = 7,
+  IO_WFILE_JUMPS_MMAP       = 8,
+  IO_WFILE_JUMPS_MAYBE_MMAP = 9,
+  IO_COOKIE_JUMPS           = 10,
+  IO_PROC_JUMPS             = 11,
+  IO_STR_CHK_JUMPS          = 12,
+  IO_OBSTACK_JUMPS          = 13,
+  IO_HELPER_JUMPS           = 14,
+  IO_WHELPER_JUMPS          = 15,
+  IO_MEM_JUMPS              = 16,
+  IO_WMEM_JUMPS             = 17,
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+  IO_OLD_FILE_JUMPS         = 18,
+  IO_OLD_PROC_JUMPS         = 19,
+#endif
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
+  IO_OLD_COOKIED_JUMPS      = 20,
+#endif
+};
+
+extern const struct _IO_jump_t __io_vtables[] attribute_hidden;
+extern const size_t __io_vtables_size attribute_hidden;
+#define _IO_str_jumps			(__io_vtables[IO_STR_JUMPS])
+#define _IO_wstr_jumps			(__io_vtables[IO_WSTR_JUMPS])
+#define _IO_strn_jumps			(__io_vtables[IO_STRN_JUMPS])
+#define _IO_wstrn_jumps			(__io_vtables[IO_WSTRN_JUMPS])
+#define _IO_file_jumps			(__io_vtables[IO_FILE_JUMPS])
+#define _IO_file_jumps_mmap		(__io_vtables[IO_FILE_JUMPS_MMAP])
+#define _IO_file_jumps_maybe_mmap	(__io_vtables[IO_FILE_JUMPS_MAYBE_MMAP])
+#define _IO_wfile_jumps			(__io_vtables[IO_WFILE_JUMPS])
+#define _IO_wfile_jumps_mmap		(__io_vtables[IO_WFILE_JUMPS_MMAP])
+#define _IO_wfile_jumps_maybe_mmap	(__io_vtables[IO_WFILE_JUMPS_MAYBE_MMAP])
+#define _IO_cookie_jumps		(__io_vtables[IO_COOKIE_JUMPS])
+#define _IO_proc_jumps			(__io_vtables[IO_PROC_JUMPS])
+#define _IO_str_chk_jumps		(__io_vtables[IO_STR_CHK_JUMPS])
+#define _IO_obstack_jumps		(__io_vtables[IO_OBSTACK_JUMPS])
+#define _IO_helper_jumps		(__io_vtables[IO_HELPER_JUMPS])
+#define _IO_whelper_jumps		(__io_vtables[IO_WHELPER_JUMPS])
+#define _IO_mem_jumps			(__io_vtables[IO_MEM_JUMPS])
+#define _IO_wmem_jumps			(__io_vtables[IO_WMEM_JUMPS])
+#define _IO_old_file_jumps		(__io_vtables[IO_OLD_FILE_JUMPS])
+#define _IO_old_proc_jumps		(__io_vtables[IO_OLD_PROC_JUMPS])
+#define _IO_old_cookie_jumps		(__io_vtables[IO_OLD_COOKIED_JUMPS])
+
+#ifdef SHARED
+# define libio_static_fn_required(name)
+#else
+# define libio_static_fn_required(name) __asm (".globl " #name);
+#endif
+
 extern int _IO_do_write (FILE *, const char *, size_t);
 libc_hidden_proto (_IO_do_write)
 extern int _IO_new_do_write (FILE *, const char *, size_t);
@@ -540,65 +588,77 @@  extern void _IO_old_init (FILE *fp, int flags) __THROW;
 
 /* Jumptable functions for files. */
 
-extern int _IO_file_doallocate (FILE *) __THROW;
+extern int _IO_file_doallocate (FILE *) __THROW weak_function;
 libc_hidden_proto (_IO_file_doallocate)
-extern FILE* _IO_file_setbuf (FILE *, char *, ssize_t);
+extern FILE* _IO_file_setbuf (FILE *, char *, ssize_t) weak_function;
 libc_hidden_proto (_IO_file_setbuf)
-extern off64_t _IO_file_seekoff (FILE *, off64_t, int, int);
+extern off64_t _IO_file_seekoff (FILE *, off64_t, int, int) weak_function;
 libc_hidden_proto (_IO_file_seekoff)
 extern off64_t _IO_file_seekoff_mmap (FILE *, off64_t, int, int)
-     __THROW;
-extern size_t _IO_file_xsputn (FILE *, const void *, size_t);
+     __THROW weak_function;
+extern size_t _IO_file_xsputn (FILE *, const void *, size_t) weak_function;
 libc_hidden_proto (_IO_file_xsputn)
-extern size_t _IO_file_xsgetn (FILE *, void *, size_t);
+extern size_t _IO_file_xsgetn (FILE *, void *, size_t) weak_function;
 libc_hidden_proto (_IO_file_xsgetn)
-extern int _IO_file_stat (FILE *, void *) __THROW;
+extern int _IO_file_stat (FILE *, void *) __THROW weak_function;
 libc_hidden_proto (_IO_file_stat)
-extern int _IO_file_close (FILE *) __THROW;
+extern int _IO_file_close (FILE *) __THROW weak_function;
 libc_hidden_proto (_IO_file_close)
-extern int _IO_file_close_mmap (FILE *) __THROW;
-extern int _IO_file_underflow (FILE *);
+extern int _IO_file_close_mmap (FILE *) __THROW weak_function;
+extern int _IO_file_underflow (FILE *) weak_function;
 libc_hidden_proto (_IO_file_underflow)
-extern int _IO_file_underflow_mmap (FILE *);
-extern int _IO_file_underflow_maybe_mmap (FILE *);
-extern int _IO_file_overflow (FILE *, int);
+extern int _IO_file_underflow_mmap (FILE *) weak_function;
+extern int _IO_file_underflow_maybe_mmap (FILE *) weak_function;
+extern int _IO_file_overflow (FILE *, int) weak_function;
 libc_hidden_proto (_IO_file_overflow)
 #define _IO_file_is_open(__fp) ((__fp)->_fileno != -1)
-extern FILE* _IO_file_attach (FILE *, int);
+extern FILE* _IO_file_attach (FILE *, int) weak_function;
 libc_hidden_proto (_IO_file_attach)
-extern FILE* _IO_file_open (FILE *, const char *, int, int, int, int);
+extern FILE* _IO_file_open (FILE *, const char *, int, int, int, int)
+     weak_function;
 libc_hidden_proto (_IO_file_open)
-extern FILE* _IO_file_fopen (FILE *, const char *, const char *, int);
+extern FILE* _IO_file_fopen (FILE *, const char *, const char *, int)
+     weak_function;
 libc_hidden_proto (_IO_file_fopen)
-extern ssize_t _IO_file_write (FILE *, const void *, ssize_t);
-extern ssize_t _IO_file_read (FILE *, void *, ssize_t);
+extern ssize_t _IO_file_write (FILE *, const void *, ssize_t) weak_function;
+extern ssize_t _IO_file_read (FILE *, void *, ssize_t) weak_function;
 libc_hidden_proto (_IO_file_read)
-extern int _IO_file_sync (FILE *);
+extern int _IO_file_sync (FILE *) weak_function;
 libc_hidden_proto (_IO_file_sync)
-extern int _IO_file_close_it (FILE *);
+extern int _IO_file_close_it (FILE *) weak_function;
 libc_hidden_proto (_IO_file_close_it)
-extern off64_t _IO_file_seek (FILE *, off64_t, int) __THROW;
+extern off64_t _IO_file_seek (FILE *, off64_t, int) __THROW weak_function;
 libc_hidden_proto (_IO_file_seek)
-extern void _IO_file_finish (FILE *, int);
+extern void _IO_file_finish (FILE *, int) weak_function;
 libc_hidden_proto (_IO_file_finish)
 
-extern FILE* _IO_new_file_attach (FILE *, int);
-extern int _IO_new_file_close_it (FILE *);
-extern void _IO_new_file_finish (FILE *, int);
+extern FILE* _IO_new_file_attach (FILE *, int) weak_function;
+extern int _IO_new_file_close_it (FILE *) weak_function;
+extern void _IO_new_file_finish (FILE *, int) weak_function;
 extern FILE* _IO_new_file_fopen (FILE *, const char *, const char *,
-				     int);
+				 int) weak_function;
 extern void _IO_no_init (FILE *, int, int, struct _IO_wide_data *,
-			 const struct _IO_jump_t *) __THROW;
+			 const struct _IO_jump_t *) __THROW weak_function;
 extern void _IO_new_file_init_internal (struct _IO_FILE_plus *)
-  __THROW attribute_hidden;
-extern FILE* _IO_new_file_setbuf (FILE *, char *, ssize_t);
-extern FILE* _IO_file_setbuf_mmap (FILE *, char *, ssize_t);
-extern int _IO_new_file_sync (FILE *);
-extern int _IO_new_file_underflow (FILE *);
-extern int _IO_new_file_overflow (FILE *, int);
-extern off64_t _IO_new_file_seekoff (FILE *, off64_t, int, int);
-extern ssize_t _IO_new_file_write (FILE *, const void *, ssize_t);
-extern size_t _IO_new_file_xsputn (FILE *, const void *, size_t);
+  __THROW attribute_hidden weak_function;
+extern FILE* _IO_new_file_setbuf (FILE *, char *, ssize_t) weak_function;
+extern FILE* _IO_file_setbuf_mmap (FILE *, char *, ssize_t) weak_function;
+extern int _IO_new_file_sync (FILE *) weak_function;
+extern int _IO_file_sync_mmap (FILE *) attribute_hidden weak_function;
+extern size_t  _IO_file_xsgetn_maybe_mmap (FILE *fp, void *data, size_t n)
+  attribute_hidden weak_function;
+extern size_t _IO_file_xsgetn_mmap (FILE *fp, void *data, size_t n)
+  attribute_hidden weak_function;
+extern off64_t _IO_file_seekoff_maybe_mmap (FILE *fp, off64_t offset, int dir,
+					    int mode)
+     attribute_hidden weak_function;
+extern int _IO_new_file_underflow (FILE *) weak_function;
+extern int _IO_new_file_overflow (FILE *, int) weak_function;
+extern off64_t _IO_new_file_seekoff (FILE *, off64_t, int, int) weak_function;
+extern ssize_t _IO_new_file_write (FILE *, const void *, ssize_t)
+     weak_function;
+extern size_t _IO_new_file_xsputn (FILE *, const void *, size_t)
+     weak_function;
 
 extern FILE* _IO_old_file_setbuf (FILE *, char *, ssize_t);
 extern off64_t _IO_old_file_seekoff (FILE *, off64_t, int, int);
@@ -614,54 +674,97 @@  extern int _IO_old_file_sync (FILE *);
 extern int _IO_old_file_close_it (FILE *);
 extern void _IO_old_file_finish (FILE *, int);
 
-extern int _IO_wfile_doallocate (FILE *) __THROW;
-extern size_t _IO_wfile_xsputn (FILE *, const void *, size_t);
+extern int _IO_wfile_doallocate (FILE *) __THROW weak_function;
+extern size_t _IO_wfile_xsputn (FILE *, const void *, size_t) weak_function;
 libc_hidden_proto (_IO_wfile_xsputn)
-extern FILE* _IO_wfile_setbuf (FILE *, wchar_t *, ssize_t);
-extern wint_t _IO_wfile_sync (FILE *);
+extern FILE* _IO_wfile_setbuf (FILE *, wchar_t *, ssize_t) weak_function;
+extern wint_t _IO_wfile_sync (FILE *) weak_function;
 libc_hidden_proto (_IO_wfile_sync)
-extern wint_t _IO_wfile_underflow (FILE *);
+extern wint_t _IO_wfile_underflow (FILE *) weak_function;
 libc_hidden_proto (_IO_wfile_underflow)
-extern wint_t _IO_wfile_overflow (FILE *, wint_t);
+extern wint_t _IO_wfile_overflow (FILE *, wint_t) weak_function;
 libc_hidden_proto (_IO_wfile_overflow)
-extern off64_t _IO_wfile_seekoff (FILE *, off64_t, int, int);
+extern off64_t _IO_wfile_seekoff (FILE *, off64_t, int, int) weak_function;
 libc_hidden_proto (_IO_wfile_seekoff)
+extern wint_t _IO_wfile_underflow_maybe_mmap (FILE *fp)
+     attribute_hidden weak_function;
+extern wint_t _IO_wfile_underflow_mmap (FILE *fp)
+     attribute_hidden weak_function;
 
 /* Jumptable functions for proc_files. */
 extern FILE* _IO_proc_open (FILE *, const char *, const char *)
-     __THROW;
+     __THROW weak_function;
 extern FILE* _IO_new_proc_open (FILE *, const char *, const char *)
-     __THROW;
-extern FILE* _IO_old_proc_open (FILE *, const char *, const char *);
-extern int _IO_proc_close (FILE *) __THROW;
-extern int _IO_new_proc_close (FILE *) __THROW;
-extern int _IO_old_proc_close (FILE *);
+     __THROW weak_function;
+extern FILE* _IO_old_proc_open (FILE *, const char *, const char *)
+     weak_function;
+extern int _IO_proc_close (FILE *) __THROW weak_function;
+extern int _IO_new_proc_close (FILE *) __THROW weak_function;
+extern int _IO_old_proc_close (FILE *) weak_function;
 
 /* Jumptable functions for strfiles. */
-extern int _IO_str_underflow (FILE *) __THROW;
+extern int _IO_str_underflow (FILE *) __THROW weak_function weak_function;
 libc_hidden_proto (_IO_str_underflow)
-extern int _IO_str_overflow (FILE *, int) __THROW;
+extern int _IO_str_overflow (FILE *, int) __THROW weak_function;
 libc_hidden_proto (_IO_str_overflow)
-extern int _IO_str_pbackfail (FILE *, int) __THROW;
+extern int _IO_str_pbackfail (FILE *, int) __THROW weak_function;
 libc_hidden_proto (_IO_str_pbackfail)
-extern off64_t _IO_str_seekoff (FILE *, off64_t, int, int) __THROW;
+extern off64_t _IO_str_seekoff (FILE *, off64_t, int, int) __THROW
+  weak_function;
 libc_hidden_proto (_IO_str_seekoff)
-extern void _IO_str_finish (FILE *, int) __THROW;
+extern void _IO_str_finish (FILE *, int) __THROW weak_function;
+extern int _IO_str_chk_overflow (FILE *fp, int c) __THROW
+  attribute_hidden weak_function;
+
+/* Jumptable functions for fopencookie.  */
+extern ssize_t _IO_cookie_read (FILE *fp, void *buf, ssize_t size)
+  attribute_hidden weak_function;
+extern ssize_t _IO_cookie_write (FILE *fp, const void *buf, ssize_t size)
+  attribute_hidden weak_function;
+extern off64_t _IO_cookie_seek (FILE *fp, off64_t offset, int dir)
+  attribute_hidden weak_function;
+extern int _IO_cookie_close (FILE *fp) attribute_hidden;
+extern off64_t _IO_cookie_seekoff (FILE *fp, off64_t offset, int dir, int mode)
+  attribute_hidden weak_function;
+extern off64_t _IO_old_cookie_seek (FILE *fp, off64_t offset, int dir)
+  attribute_hidden weak_function;
+
+/* Jumptable functions for obstack.  */
+extern int __IO_obstack_overflow (FILE *fp, int c) attribute_hidden
+  weak_function;
+extern size_t __IO_obstack_xsputn (FILE *fp, const void *data, size_t n)
+  attribute_hidden weak_function;
+extern wint_t _IO_wstrn_overflow (FILE *fp, wint_t c) __THROW
+  attribute_hidden weak_function;
+
+/* Jumptable functions for open_{w}memstream.  */
+extern int _IO_mem_sync (FILE* fp) __THROW attribute_hidden weak_function;
+extern void _IO_mem_finish (FILE* fp, int) __THROW attribute_hidden
+  weak_function;
+extern int _IO_wmem_sync (FILE* fp) __THROW attribute_hidden weak_function;
+extern void _IO_wmem_finish (FILE* fp, int) __THROW attribute_hidden
+  weak_function;
 
 /* Other strfile functions */
 struct _IO_strfile_;
-extern ssize_t _IO_str_count (FILE *) __THROW;
+extern ssize_t _IO_str_count (FILE *) __THROW weak_function;
+extern int _IO_strn_overflow (FILE *fp, int c) __THROW attribute_hidden
+  weak_function;
 
 /* And the wide character versions.  */
 extern void _IO_wstr_init_static (FILE *, wchar_t *, size_t, wchar_t *)
      __THROW;
-extern ssize_t _IO_wstr_count (FILE *) __THROW;
-extern wint_t _IO_wstr_overflow (FILE *, wint_t) __THROW;
-extern wint_t _IO_wstr_underflow (FILE *) __THROW;
+extern ssize_t _IO_wstr_count (FILE *) __THROW weak_function;
+extern wint_t _IO_wstr_overflow (FILE *, wint_t) __THROW weak_function;
+extern wint_t _IO_wstr_underflow (FILE *) __THROW weak_function;
 extern off64_t _IO_wstr_seekoff (FILE *, off64_t, int, int)
-     __THROW;
-extern wint_t _IO_wstr_pbackfail (FILE *, wint_t) __THROW;
-extern void _IO_wstr_finish (FILE *, int) __THROW;
+     __THROW weak_function;
+extern wint_t _IO_wstr_pbackfail (FILE *, wint_t) __THROW weak_function;
+extern void _IO_wstr_finish (FILE *, int) __THROW weak_function;
+
+/* Helper functions.  */
+int _IO_helper_overflow (FILE *s, int c) weak_function;
+int _IO_whelper_overflow (FILE *s, int c) weak_function;
 
 /* Internal versions of v*printf that take an additional flags
    parameter.  */
@@ -892,14 +995,6 @@  _IO_acquire_lock_fct (FILE **p)
   } while (0)
 #endif
 
-/* Collect all vtables in a special section for vtable verification.
-   These symbols cover the extent of this section.  */
-symbol_set_declare (__libc_IO_vtables)
-
-/* libio vtables need to carry this attribute so that they pass
-   validation.  */
-#define libio_vtable __attribute__ ((section ("__libc_IO_vtables")))
-
 #ifdef SHARED
 /* If equal to &_IO_vtable_check (with pointer guard protection),
    unknown vtable pointers are valid.  This function pointer is solely
@@ -934,12 +1029,9 @@  void _IO_vtable_check (void) attribute_hidden;
 static inline const struct _IO_jump_t *
 IO_validate_vtable (const struct _IO_jump_t *vtable)
 {
-  /* Fast path: The vtable pointer is within the __libc_IO_vtables
-     section.  */
-  uintptr_t section_length = __stop___libc_IO_vtables - __start___libc_IO_vtables;
   uintptr_t ptr = (uintptr_t) vtable;
-  uintptr_t offset = ptr - (uintptr_t) __start___libc_IO_vtables;
-  if (__glibc_unlikely (offset >= section_length))
+  uintptr_t offset = ptr - (uintptr_t) &__io_vtables;
+  if (__glibc_unlikely (offset >= __io_vtables_size))
     /* The vtable pointer is not in the expected section.  Use the
        slow path, which will terminate the process if necessary.  */
     _IO_vtable_check ();
diff --git a/libio/memstream.c b/libio/memstream.c
index 1ae8cd9544..b5b5254a34 100644
--- a/libio/memstream.c
+++ b/libio/memstream.c
@@ -29,34 +29,6 @@  struct _IO_FILE_memstream
 };
 
 
-static int _IO_mem_sync (FILE* fp) __THROW;
-static void _IO_mem_finish (FILE* fp, int) __THROW;
-
-
-static const struct _IO_jump_t _IO_mem_jumps libio_vtable =
-{
-  JUMP_INIT_DUMMY,
-  JUMP_INIT (finish, _IO_mem_finish),
-  JUMP_INIT (overflow, _IO_str_overflow),
-  JUMP_INIT (underflow, _IO_str_underflow),
-  JUMP_INIT (uflow, _IO_default_uflow),
-  JUMP_INIT (pbackfail, _IO_str_pbackfail),
-  JUMP_INIT (xsputn, _IO_default_xsputn),
-  JUMP_INIT (xsgetn, _IO_default_xsgetn),
-  JUMP_INIT (seekoff, _IO_str_seekoff),
-  JUMP_INIT (seekpos, _IO_default_seekpos),
-  JUMP_INIT (setbuf, _IO_default_setbuf),
-  JUMP_INIT (sync, _IO_mem_sync),
-  JUMP_INIT (doallocate, _IO_default_doallocate),
-  JUMP_INIT (read, _IO_default_read),
-  JUMP_INIT (write, _IO_default_write),
-  JUMP_INIT (seek, _IO_default_seek),
-  JUMP_INIT (close, _IO_default_close),
-  JUMP_INIT (stat, _IO_default_stat),
-  JUMP_INIT(showmanyc, _IO_default_showmanyc),
-  JUMP_INIT(imbue, _IO_default_imbue)
-};
-
 /* Open a stream that writes into a malloc'd buffer that is expanded as
    necessary.  *BUFLOC and *SIZELOC are updated with the buffer's location
    and the number of characters written on fflush or fclose.  */
@@ -105,7 +77,7 @@  libc_hidden_def (__open_memstream)
 weak_alias (__open_memstream, open_memstream)
 
 
-static int
+int
 _IO_mem_sync (FILE *fp)
 {
   struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp;
@@ -123,7 +95,7 @@  _IO_mem_sync (FILE *fp)
 }
 
 
-static void
+void
 _IO_mem_finish (FILE *fp, int dummy)
 {
   struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp;
diff --git a/libio/obprintf.c b/libio/obprintf.c
index c220be9adc..1b3f074826 100644
--- a/libio/obprintf.c
+++ b/libio/obprintf.c
@@ -35,8 +35,8 @@  struct _IO_obstack_file
 };
 
 
-static int
-_IO_obstack_overflow (FILE *fp, int c)
+int
+__IO_obstack_overflow (FILE *fp, int c)
 {
   struct obstack *obstack = ((struct _IO_obstack_file *) fp)->obstack;
   int size;
@@ -58,8 +58,8 @@  _IO_obstack_overflow (FILE *fp, int c)
 }
 
 
-static size_t
-_IO_obstack_xsputn (FILE *fp, const void *data, size_t n)
+size_t
+__IO_obstack_xsputn (FILE *fp, const void *data, size_t n)
 {
   struct obstack *obstack = ((struct _IO_obstack_file *) fp)->obstack;
 
@@ -89,32 +89,6 @@  _IO_obstack_xsputn (FILE *fp, const void *data, size_t n)
 }
 
 
-/* the jump table.  */
-const struct _IO_jump_t _IO_obstack_jumps libio_vtable attribute_hidden =
-{
-  JUMP_INIT_DUMMY,
-  JUMP_INIT(finish, NULL),
-  JUMP_INIT(overflow, _IO_obstack_overflow),
-  JUMP_INIT(underflow, NULL),
-  JUMP_INIT(uflow, NULL),
-  JUMP_INIT(pbackfail, NULL),
-  JUMP_INIT(xsputn, _IO_obstack_xsputn),
-  JUMP_INIT(xsgetn, NULL),
-  JUMP_INIT(seekoff, NULL),
-  JUMP_INIT(seekpos, NULL),
-  JUMP_INIT(setbuf, NULL),
-  JUMP_INIT(sync, NULL),
-  JUMP_INIT(doallocate, NULL),
-  JUMP_INIT(read, NULL),
-  JUMP_INIT(write, NULL),
-  JUMP_INIT(seek, NULL),
-  JUMP_INIT(close, NULL),
-  JUMP_INIT(stat, NULL),
-  JUMP_INIT(showmanyc, NULL),
-  JUMP_INIT(imbue, NULL)
-};
-
-
 int
 __obstack_vprintf_internal (struct obstack *obstack, const char *format,
 			    va_list args, unsigned int mode_flags)
diff --git a/libio/oldfileops.c b/libio/oldfileops.c
index ea3b864447..371c7479c6 100644
--- a/libio/oldfileops.c
+++ b/libio/oldfileops.c
@@ -716,29 +716,6 @@  _IO_old_file_xsputn (FILE *f, const void *data, size_t n)
   return n - to_do;
 }
 
-
-const struct _IO_jump_t _IO_old_file_jumps libio_vtable =
-{
-  JUMP_INIT_DUMMY,
-  JUMP_INIT(finish, _IO_old_file_finish),
-  JUMP_INIT(overflow, _IO_old_file_overflow),
-  JUMP_INIT(underflow, _IO_old_file_underflow),
-  JUMP_INIT(uflow, _IO_default_uflow),
-  JUMP_INIT(pbackfail, _IO_default_pbackfail),
-  JUMP_INIT(xsputn, _IO_old_file_xsputn),
-  JUMP_INIT(xsgetn, _IO_default_xsgetn),
-  JUMP_INIT(seekoff, _IO_old_file_seekoff),
-  JUMP_INIT(seekpos, _IO_default_seekpos),
-  JUMP_INIT(setbuf, _IO_old_file_setbuf),
-  JUMP_INIT(sync, _IO_old_file_sync),
-  JUMP_INIT(doallocate, _IO_file_doallocate),
-  JUMP_INIT(read, _IO_file_read),
-  JUMP_INIT(write, _IO_old_file_write),
-  JUMP_INIT(seek, _IO_file_seek),
-  JUMP_INIT(close, _IO_file_close),
-  JUMP_INIT(stat, _IO_file_stat)
-};
-
 compat_symbol (libc, _IO_old_do_write, _IO_do_write, GLIBC_2_0);
 compat_symbol (libc, _IO_old_file_attach, _IO_file_attach, GLIBC_2_0);
 compat_symbol (libc, _IO_old_file_close_it, _IO_file_close_it, GLIBC_2_0);
diff --git a/libio/oldiopopen.c b/libio/oldiopopen.c
index f9149413e8..206a0f3858 100644
--- a/libio/oldiopopen.c
+++ b/libio/oldiopopen.c
@@ -208,29 +208,6 @@  _IO_old_proc_close (FILE *fp)
   return wstatus;
 }
 
-const struct _IO_jump_t _IO_old_proc_jumps libio_vtable = {
-  JUMP_INIT_DUMMY,
-  JUMP_INIT(finish, _IO_old_file_finish),
-  JUMP_INIT(overflow, _IO_old_file_overflow),
-  JUMP_INIT(underflow, _IO_old_file_underflow),
-  JUMP_INIT(uflow, _IO_default_uflow),
-  JUMP_INIT(pbackfail, _IO_default_pbackfail),
-  JUMP_INIT(xsputn, _IO_old_file_xsputn),
-  JUMP_INIT(xsgetn, _IO_default_xsgetn),
-  JUMP_INIT(seekoff, _IO_old_file_seekoff),
-  JUMP_INIT(seekpos, _IO_default_seekpos),
-  JUMP_INIT(setbuf, _IO_old_file_setbuf),
-  JUMP_INIT(sync, _IO_old_file_sync),
-  JUMP_INIT(doallocate, _IO_file_doallocate),
-  JUMP_INIT(read, _IO_file_read),
-  JUMP_INIT(write, _IO_old_file_write),
-  JUMP_INIT(seek, _IO_file_seek),
-  JUMP_INIT(close, _IO_old_proc_close),
-  JUMP_INIT(stat, _IO_file_stat),
-  JUMP_INIT(showmanyc, _IO_default_showmanyc),
-  JUMP_INIT(imbue, _IO_default_imbue)
-};
-
 strong_alias (_IO_old_popen, __old_popen)
 compat_symbol (libc, _IO_old_popen, _IO_popen, GLIBC_2_0);
 compat_symbol (libc, __old_popen, popen, GLIBC_2_0);
diff --git a/libio/stdio.c b/libio/stdio.c
index e65ee86b24..356d41d277 100644
--- a/libio/stdio.c
+++ b/libio/stdio.c
@@ -33,3 +33,6 @@ 
 FILE *stdin = (FILE *) &_IO_2_1_stdin_;
 FILE *stdout = (FILE *) &_IO_2_1_stdout_;
 FILE *stderr = (FILE *) &_IO_2_1_stderr_;
+
+libio_static_fn_required (_IO_file_open);
+libio_static_fn_required (_IO_file_doallocate);
diff --git a/libio/strfile.h b/libio/strfile.h
index fa44ebc7e7..f2ce1ff6f3 100644
--- a/libio/strfile.h
+++ b/libio/strfile.h
@@ -70,9 +70,6 @@  typedef struct
   char overflow_buf[64];
 } _IO_strnfile;
 
-extern const struct _IO_jump_t _IO_strn_jumps attribute_hidden;
-
-
 typedef struct
 {
   _IO_strfile f;
@@ -81,8 +78,6 @@  typedef struct
   wchar_t overflow_buf[64];
 } _IO_wstrnfile;
 
-extern const struct _IO_jump_t _IO_wstrn_jumps attribute_hidden;
-
 /* Initialize an _IO_strfile SF to read from narrow string STRING, and
    return the corresponding FILE object.  It is not necessary to fclose
    the FILE when it is no longer needed.  */
diff --git a/libio/strops.c b/libio/strops.c
index 1cd0bf6c3d..4e2243b8d9 100644
--- a/libio/strops.c
+++ b/libio/strops.c
@@ -352,27 +352,3 @@  _IO_str_finish (FILE *fp, int dummy)
 
   _IO_default_finish (fp, 0);
 }
-
-const struct _IO_jump_t _IO_str_jumps libio_vtable =
-{
-  JUMP_INIT_DUMMY,
-  JUMP_INIT(finish, _IO_str_finish),
-  JUMP_INIT(overflow, _IO_str_overflow),
-  JUMP_INIT(underflow, _IO_str_underflow),
-  JUMP_INIT(uflow, _IO_default_uflow),
-  JUMP_INIT(pbackfail, _IO_str_pbackfail),
-  JUMP_INIT(xsputn, _IO_default_xsputn),
-  JUMP_INIT(xsgetn, _IO_default_xsgetn),
-  JUMP_INIT(seekoff, _IO_str_seekoff),
-  JUMP_INIT(seekpos, _IO_default_seekpos),
-  JUMP_INIT(setbuf, _IO_default_setbuf),
-  JUMP_INIT(sync, _IO_default_sync),
-  JUMP_INIT(doallocate, _IO_default_doallocate),
-  JUMP_INIT(read, _IO_default_read),
-  JUMP_INIT(write, _IO_default_write),
-  JUMP_INIT(seek, _IO_default_seek),
-  JUMP_INIT(close, _IO_default_close),
-  JUMP_INIT(stat, _IO_default_stat),
-  JUMP_INIT(showmanyc, _IO_default_showmanyc),
-  JUMP_INIT(imbue, _IO_default_imbue)
-};
diff --git a/libio/tst-vtables-interposed.c b/libio/tst-vtables-interposed.c
index 9d03fa0ec2..66f79dddb5 100644
--- a/libio/tst-vtables-interposed.c
+++ b/libio/tst-vtables-interposed.c
@@ -21,7 +21,12 @@ 
 /* Provide an interposed definition of the standard file handles with
    our own vtable.  stdout/stdin/stderr will not work as a result, but
    a succesful test does not print anything, so this is fine.  */
+#include "libioP.h"
+#undef _IO_file_jumps
 #define _IO_file_jumps jumps
+#undef _IO_wfile_jumps
+extern const struct _IO_jump_t _IO_wfile_jumps;
+#define _IO_wfile_jumps _IO_wfile_jumps
 #include "stdfiles.c"
 
 static int
diff --git a/libio/vsnprintf.c b/libio/vsnprintf.c
index 8dae66761d..dd0280f60b 100644
--- a/libio/vsnprintf.c
+++ b/libio/vsnprintf.c
@@ -27,9 +27,7 @@ 
 #include "libioP.h"
 #include "strfile.h"
 
-static int _IO_strn_overflow (FILE *fp, int c) __THROW;
-
-static int
+int
 _IO_strn_overflow (FILE *fp, int c)
 {
   /* When we come to here this means the user supplied buffer is
@@ -64,31 +62,6 @@  _IO_strn_overflow (FILE *fp, int c)
 }
 
 
-const struct _IO_jump_t _IO_strn_jumps libio_vtable attribute_hidden =
-{
-  JUMP_INIT_DUMMY,
-  JUMP_INIT(finish, _IO_str_finish),
-  JUMP_INIT(overflow, _IO_strn_overflow),
-  JUMP_INIT(underflow, _IO_str_underflow),
-  JUMP_INIT(uflow, _IO_default_uflow),
-  JUMP_INIT(pbackfail, _IO_str_pbackfail),
-  JUMP_INIT(xsputn, _IO_default_xsputn),
-  JUMP_INIT(xsgetn, _IO_default_xsgetn),
-  JUMP_INIT(seekoff, _IO_str_seekoff),
-  JUMP_INIT(seekpos, _IO_default_seekpos),
-  JUMP_INIT(setbuf, _IO_default_setbuf),
-  JUMP_INIT(sync, _IO_default_sync),
-  JUMP_INIT(doallocate, _IO_default_doallocate),
-  JUMP_INIT(read, _IO_default_read),
-  JUMP_INIT(write, _IO_default_write),
-  JUMP_INIT(seek, _IO_default_seek),
-  JUMP_INIT(close, _IO_default_close),
-  JUMP_INIT(stat, _IO_default_stat),
-  JUMP_INIT(showmanyc, _IO_default_showmanyc),
-  JUMP_INIT(imbue, _IO_default_imbue)
-};
-
-
 int
 __vsnprintf_internal (char *string, size_t maxlen, const char *format,
 		      va_list args, unsigned int mode_flags)
diff --git a/libio/vswprintf.c b/libio/vswprintf.c
index 5a9ccdff3e..2b31aa411c 100644
--- a/libio/vswprintf.c
+++ b/libio/vswprintf.c
@@ -27,10 +27,7 @@ 
 #include "libioP.h"
 #include "strfile.h"
 
-
-static wint_t _IO_wstrn_overflow (FILE *fp, wint_t c) __THROW;
-
-static wint_t
+wint_t
 _IO_wstrn_overflow (FILE *fp, wint_t c)
 {
   /* When we come to here this means the user supplied buffer is
@@ -63,31 +60,6 @@  _IO_wstrn_overflow (FILE *fp, wint_t c)
 }
 
 
-const struct _IO_jump_t _IO_wstrn_jumps libio_vtable attribute_hidden =
-{
-  JUMP_INIT_DUMMY,
-  JUMP_INIT(finish, _IO_wstr_finish),
-  JUMP_INIT(overflow, (_IO_overflow_t) _IO_wstrn_overflow),
-  JUMP_INIT(underflow, (_IO_underflow_t) _IO_wstr_underflow),
-  JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow),
-  JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail),
-  JUMP_INIT(xsputn, _IO_wdefault_xsputn),
-  JUMP_INIT(xsgetn, _IO_wdefault_xsgetn),
-  JUMP_INIT(seekoff, _IO_wstr_seekoff),
-  JUMP_INIT(seekpos, _IO_default_seekpos),
-  JUMP_INIT(setbuf, _IO_default_setbuf),
-  JUMP_INIT(sync, _IO_default_sync),
-  JUMP_INIT(doallocate, _IO_wdefault_doallocate),
-  JUMP_INIT(read, _IO_default_read),
-  JUMP_INIT(write, _IO_default_write),
-  JUMP_INIT(seek, _IO_default_seek),
-  JUMP_INIT(close, _IO_default_close),
-  JUMP_INIT(stat, _IO_default_stat),
-  JUMP_INIT(showmanyc, _IO_default_showmanyc),
-  JUMP_INIT(imbue, _IO_default_imbue)
-};
-
-
 int
 __vswprintf_internal (wchar_t *string, size_t maxlen, const wchar_t *format,
 		      va_list args, unsigned int mode_flags)
diff --git a/libio/vtables.c b/libio/vtables.c
index e3809c28ce..7c66cf8c19 100644
--- a/libio/vtables.c
+++ b/libio/vtables.c
@@ -21,6 +21,496 @@ 
 #include <stdio.h>
 #include <ldsodefs.h>
 #include <pointer_guard.h>
+#include <libio-macros.h>
+
+const struct _IO_jump_t __io_vtables[] attribute_relro =
+{
+  /* _IO_str_jumps  */
+  [IO_STR_JUMPS] =
+  {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT(finish, _IO_str_finish),
+    JUMP_INIT(overflow, _IO_str_overflow),
+    JUMP_INIT(underflow, _IO_str_underflow),
+    JUMP_INIT(uflow, _IO_default_uflow),
+    JUMP_INIT(pbackfail, _IO_str_pbackfail),
+    JUMP_INIT(xsputn, _IO_default_xsputn),
+    JUMP_INIT(xsgetn, _IO_default_xsgetn),
+    JUMP_INIT(seekoff, _IO_str_seekoff),
+    JUMP_INIT(seekpos, _IO_default_seekpos),
+    JUMP_INIT(setbuf, _IO_default_setbuf),
+    JUMP_INIT(sync, _IO_default_sync),
+    JUMP_INIT(doallocate, _IO_default_doallocate),
+    JUMP_INIT(read, _IO_default_read),
+    JUMP_INIT(write, _IO_default_write),
+    JUMP_INIT(seek, _IO_default_seek),
+    JUMP_INIT(close, _IO_default_close),
+    JUMP_INIT(stat, _IO_default_stat),
+    JUMP_INIT(showmanyc, _IO_default_showmanyc),
+    JUMP_INIT(imbue, _IO_default_imbue)
+  },
+  /* _IO_wstr_jumps  */
+  [IO_WSTR_JUMPS] = {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT(finish, _IO_wstr_finish),
+    JUMP_INIT(overflow, (_IO_overflow_t) _IO_wstr_overflow),
+    JUMP_INIT(underflow, (_IO_underflow_t) _IO_wstr_underflow),
+    JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow),
+    JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail),
+    JUMP_INIT(xsputn, _IO_wdefault_xsputn),
+    JUMP_INIT(xsgetn, _IO_wdefault_xsgetn),
+    JUMP_INIT(seekoff, _IO_wstr_seekoff),
+    JUMP_INIT(seekpos, _IO_default_seekpos),
+    JUMP_INIT(setbuf, _IO_default_setbuf),
+    JUMP_INIT(sync, _IO_default_sync),
+    JUMP_INIT(doallocate, _IO_wdefault_doallocate),
+    JUMP_INIT(read, _IO_default_read),
+    JUMP_INIT(write, _IO_default_write),
+    JUMP_INIT(seek, _IO_default_seek),
+    JUMP_INIT(close, _IO_default_close),
+    JUMP_INIT(stat, _IO_default_stat),
+    JUMP_INIT(showmanyc, _IO_default_showmanyc),
+    JUMP_INIT(imbue, _IO_default_imbue)
+  },
+  /* _IO_strn_jumps  */
+  [IO_STRN_JUMPS] = {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT(finish, _IO_str_finish),
+    JUMP_INIT(overflow, _IO_strn_overflow),
+    JUMP_INIT(underflow, _IO_str_underflow),
+    JUMP_INIT(uflow, _IO_default_uflow),
+    JUMP_INIT(pbackfail, _IO_str_pbackfail),
+    JUMP_INIT(xsputn, _IO_default_xsputn),
+    JUMP_INIT(xsgetn, _IO_default_xsgetn),
+    JUMP_INIT(seekoff, _IO_str_seekoff),
+    JUMP_INIT(seekpos, _IO_default_seekpos),
+    JUMP_INIT(setbuf, _IO_default_setbuf),
+    JUMP_INIT(sync, _IO_default_sync),
+    JUMP_INIT(doallocate, _IO_default_doallocate),
+    JUMP_INIT(read, _IO_default_read),
+    JUMP_INIT(write, _IO_default_write),
+    JUMP_INIT(seek, _IO_default_seek),
+    JUMP_INIT(close, _IO_default_close),
+    JUMP_INIT(stat, _IO_default_stat),
+    JUMP_INIT(showmanyc, _IO_default_showmanyc),
+    JUMP_INIT(imbue, _IO_default_imbue)
+  },
+  /* _IO_wstrn_jumps  */
+  [IO_WSTRN_JUMPS] = {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT(finish, _IO_wstr_finish),
+    JUMP_INIT(overflow, (_IO_overflow_t) _IO_wstrn_overflow),
+    JUMP_INIT(underflow, (_IO_underflow_t) _IO_wstr_underflow),
+    JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow),
+    JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail),
+    JUMP_INIT(xsputn, _IO_wdefault_xsputn),
+    JUMP_INIT(xsgetn, _IO_wdefault_xsgetn),
+    JUMP_INIT(seekoff, _IO_wstr_seekoff),
+    JUMP_INIT(seekpos, _IO_default_seekpos),
+    JUMP_INIT(setbuf, _IO_default_setbuf),
+    JUMP_INIT(sync, _IO_default_sync),
+    JUMP_INIT(doallocate, _IO_wdefault_doallocate),
+    JUMP_INIT(read, _IO_default_read),
+    JUMP_INIT(write, _IO_default_write),
+    JUMP_INIT(seek, _IO_default_seek),
+    JUMP_INIT(close, _IO_default_close),
+    JUMP_INIT(stat, _IO_default_stat),
+    JUMP_INIT(showmanyc, _IO_default_showmanyc),
+    JUMP_INIT(imbue, _IO_default_imbue)
+  },
+  /* _IO_file_jumps  */
+  [IO_FILE_JUMPS] = {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT(finish, _IO_file_finish),
+    JUMP_INIT(overflow, _IO_file_overflow),
+    JUMP_INIT(underflow, _IO_file_underflow),
+    JUMP_INIT(uflow, _IO_default_uflow),
+    JUMP_INIT(pbackfail, _IO_default_pbackfail),
+    JUMP_INIT(xsputn, _IO_file_xsputn),
+    JUMP_INIT(xsgetn, _IO_file_xsgetn),
+    JUMP_INIT(seekoff, _IO_new_file_seekoff),
+    JUMP_INIT(seekpos, _IO_default_seekpos),
+    JUMP_INIT(setbuf, _IO_new_file_setbuf),
+    JUMP_INIT(sync, _IO_new_file_sync),
+    JUMP_INIT(doallocate, _IO_file_doallocate),
+    JUMP_INIT(read, _IO_file_read),
+    JUMP_INIT(write, _IO_new_file_write),
+    JUMP_INIT(seek, _IO_file_seek),
+    JUMP_INIT(close, _IO_file_close),
+    JUMP_INIT(stat, _IO_file_stat),
+    JUMP_INIT(showmanyc, _IO_default_showmanyc),
+    JUMP_INIT(imbue, _IO_default_imbue)
+  },
+  /* _IO_file_jumps_mmap  */
+  [IO_FILE_JUMPS_MMAP] = {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT(finish, _IO_file_finish),
+    JUMP_INIT(overflow, _IO_file_overflow),
+    JUMP_INIT(underflow, _IO_file_underflow_mmap),
+    JUMP_INIT(uflow, _IO_default_uflow),
+    JUMP_INIT(pbackfail, _IO_default_pbackfail),
+    JUMP_INIT(xsputn, _IO_new_file_xsputn),
+    JUMP_INIT(xsgetn, _IO_file_xsgetn_mmap),
+    JUMP_INIT(seekoff, _IO_file_seekoff_mmap),
+    JUMP_INIT(seekpos, _IO_default_seekpos),
+    JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap),
+    JUMP_INIT(sync, _IO_file_sync_mmap),
+    JUMP_INIT(doallocate, _IO_file_doallocate),
+    JUMP_INIT(read, _IO_file_read),
+    JUMP_INIT(write, _IO_new_file_write),
+    JUMP_INIT(seek, _IO_file_seek),
+    JUMP_INIT(close, _IO_file_close_mmap),
+    JUMP_INIT(stat, _IO_file_stat),
+    JUMP_INIT(showmanyc, _IO_default_showmanyc),
+    JUMP_INIT(imbue, _IO_default_imbue)
+  },
+  /* _IO_file_jumps_maybe_mmap  */
+  [IO_FILE_JUMPS_MAYBE_MMAP] = {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT(finish, _IO_file_finish),
+    JUMP_INIT(overflow, _IO_file_overflow),
+    JUMP_INIT(underflow, _IO_file_underflow_maybe_mmap),
+    JUMP_INIT(uflow, _IO_default_uflow),
+    JUMP_INIT(pbackfail, _IO_default_pbackfail),
+    JUMP_INIT(xsputn, _IO_new_file_xsputn),
+    JUMP_INIT(xsgetn, _IO_file_xsgetn_maybe_mmap),
+    JUMP_INIT(seekoff, _IO_file_seekoff_maybe_mmap),
+    JUMP_INIT(seekpos, _IO_default_seekpos),
+    JUMP_INIT(setbuf, (_IO_setbuf_t) _IO_file_setbuf_mmap),
+    JUMP_INIT(sync, _IO_new_file_sync),
+    JUMP_INIT(doallocate, _IO_file_doallocate),
+    JUMP_INIT(read, _IO_file_read),
+    JUMP_INIT(write, _IO_new_file_write),
+    JUMP_INIT(seek, _IO_file_seek),
+    JUMP_INIT(close, _IO_file_close),
+    JUMP_INIT(stat, _IO_file_stat),
+    JUMP_INIT(showmanyc, _IO_default_showmanyc),
+    JUMP_INIT(imbue, _IO_default_imbue)
+  },
+  /* _IO_wfile_jumps  */
+  [IO_WFILE_JUMPS] = {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT(finish, _IO_new_file_finish),
+    JUMP_INIT(overflow, (_IO_overflow_t) _IO_wfile_overflow),
+    JUMP_INIT(underflow, (_IO_underflow_t) _IO_wfile_underflow),
+    JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow),
+    JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail),
+    JUMP_INIT(xsputn, _IO_wfile_xsputn),
+    JUMP_INIT(xsgetn, _IO_file_xsgetn),
+    JUMP_INIT(seekoff, _IO_wfile_seekoff),
+    JUMP_INIT(seekpos, _IO_default_seekpos),
+    JUMP_INIT(setbuf, _IO_new_file_setbuf),
+    JUMP_INIT(sync, (_IO_sync_t) _IO_wfile_sync),
+    JUMP_INIT(doallocate, _IO_wfile_doallocate),
+    JUMP_INIT(read, _IO_file_read),
+    JUMP_INIT(write, _IO_new_file_write),
+    JUMP_INIT(seek, _IO_file_seek),
+    JUMP_INIT(close, _IO_file_close),
+    JUMP_INIT(stat, _IO_file_stat),
+    JUMP_INIT(showmanyc, _IO_default_showmanyc),
+    JUMP_INIT(imbue, _IO_default_imbue)
+  },
+  /* _IO_wfile_jumps_mmap  */
+  [IO_WFILE_JUMPS_MMAP] = {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT(finish, _IO_new_file_finish),
+    JUMP_INIT(overflow, (_IO_overflow_t) _IO_wfile_overflow),
+    JUMP_INIT(underflow, (_IO_underflow_t) _IO_wfile_underflow_mmap),
+    JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow),
+    JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail),
+    JUMP_INIT(xsputn, _IO_wfile_xsputn),
+    JUMP_INIT(xsgetn, _IO_file_xsgetn),
+    JUMP_INIT(seekoff, _IO_wfile_seekoff),
+    JUMP_INIT(seekpos, _IO_default_seekpos),
+    JUMP_INIT(setbuf, _IO_file_setbuf_mmap),
+    JUMP_INIT(sync, (_IO_sync_t) _IO_wfile_sync),
+    JUMP_INIT(doallocate, _IO_wfile_doallocate),
+    JUMP_INIT(read, _IO_file_read),
+    JUMP_INIT(write, _IO_new_file_write),
+    JUMP_INIT(seek, _IO_file_seek),
+    JUMP_INIT(close, _IO_file_close_mmap),
+    JUMP_INIT(stat, _IO_file_stat),
+    JUMP_INIT(showmanyc, _IO_default_showmanyc),
+    JUMP_INIT(imbue, _IO_default_imbue)
+  },
+  /* _IO_wfile_jumps_maybe_mmap  */
+  [IO_WFILE_JUMPS_MAYBE_MMAP] = {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT(finish, _IO_new_file_finish),
+    JUMP_INIT(overflow, (_IO_overflow_t) _IO_wfile_overflow),
+    JUMP_INIT(underflow, (_IO_underflow_t) _IO_wfile_underflow_maybe_mmap),
+    JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow),
+    JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail),
+    JUMP_INIT(xsputn, _IO_wfile_xsputn),
+    JUMP_INIT(xsgetn, _IO_file_xsgetn),
+    JUMP_INIT(seekoff, _IO_wfile_seekoff),
+    JUMP_INIT(seekpos, _IO_default_seekpos),
+    JUMP_INIT(setbuf, _IO_file_setbuf_mmap),
+    JUMP_INIT(sync, (_IO_sync_t) _IO_wfile_sync),
+    JUMP_INIT(doallocate, _IO_wfile_doallocate),
+    JUMP_INIT(read, _IO_file_read),
+    JUMP_INIT(write, _IO_new_file_write),
+    JUMP_INIT(seek, _IO_file_seek),
+    JUMP_INIT(close, _IO_file_close),
+    JUMP_INIT(stat, _IO_file_stat),
+    JUMP_INIT(showmanyc, _IO_default_showmanyc),
+    JUMP_INIT(imbue, _IO_default_imbue)
+  },
+  /* _IO_cookie_jumps  */
+  [IO_COOKIE_JUMPS] = {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT(finish, _IO_file_finish),
+    JUMP_INIT(overflow, _IO_file_overflow),
+    JUMP_INIT(underflow, _IO_file_underflow),
+    JUMP_INIT(uflow, _IO_default_uflow),
+    JUMP_INIT(pbackfail, _IO_default_pbackfail),
+    JUMP_INIT(xsputn, _IO_file_xsputn),
+    JUMP_INIT(xsgetn, _IO_default_xsgetn),
+    JUMP_INIT(seekoff, _IO_cookie_seekoff),
+    JUMP_INIT(seekpos, _IO_default_seekpos),
+    JUMP_INIT(setbuf, _IO_file_setbuf),
+    JUMP_INIT(sync, _IO_file_sync),
+    JUMP_INIT(doallocate, _IO_file_doallocate),
+    JUMP_INIT(read, _IO_cookie_read),
+    JUMP_INIT(write, _IO_cookie_write),
+    JUMP_INIT(seek, _IO_cookie_seek),
+    JUMP_INIT(close, _IO_cookie_close),
+    JUMP_INIT(stat, _IO_default_stat),
+    JUMP_INIT(showmanyc, _IO_default_showmanyc),
+    JUMP_INIT(imbue, _IO_default_imbue),
+  },
+  /* _IO_proc_jumps  */
+  [IO_PROC_JUMPS] = {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT(finish, _IO_new_file_finish),
+    JUMP_INIT(overflow, _IO_new_file_overflow),
+    JUMP_INIT(underflow, _IO_new_file_underflow),
+    JUMP_INIT(uflow, _IO_default_uflow),
+    JUMP_INIT(pbackfail, _IO_default_pbackfail),
+    JUMP_INIT(xsputn, _IO_new_file_xsputn),
+    JUMP_INIT(xsgetn, _IO_default_xsgetn),
+    JUMP_INIT(seekoff, _IO_new_file_seekoff),
+    JUMP_INIT(seekpos, _IO_default_seekpos),
+    JUMP_INIT(setbuf, _IO_new_file_setbuf),
+    JUMP_INIT(sync, _IO_new_file_sync),
+    JUMP_INIT(doallocate, _IO_file_doallocate),
+    JUMP_INIT(read, _IO_file_read),
+    JUMP_INIT(write, _IO_new_file_write),
+    JUMP_INIT(seek, _IO_file_seek),
+    JUMP_INIT(close, _IO_new_proc_close),
+    JUMP_INIT(stat, _IO_file_stat),
+    JUMP_INIT(showmanyc, _IO_default_showmanyc),
+    JUMP_INIT(imbue, _IO_default_imbue)
+  },
+  /* _IO_str_chk_jumps  */
+  [IO_STR_CHK_JUMPS] = {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT(finish, _IO_str_finish),
+    JUMP_INIT(overflow, _IO_str_chk_overflow),
+    JUMP_INIT(underflow, _IO_str_underflow),
+    JUMP_INIT(uflow, _IO_default_uflow),
+    JUMP_INIT(pbackfail, _IO_str_pbackfail),
+    JUMP_INIT(xsputn, _IO_default_xsputn),
+    JUMP_INIT(xsgetn, _IO_default_xsgetn),
+    JUMP_INIT(seekoff, _IO_str_seekoff),
+    JUMP_INIT(seekpos, _IO_default_seekpos),
+    JUMP_INIT(setbuf, _IO_default_setbuf),
+    JUMP_INIT(sync, _IO_default_sync),
+    JUMP_INIT(doallocate, _IO_default_doallocate),
+    JUMP_INIT(read, _IO_default_read),
+    JUMP_INIT(write, _IO_default_write),
+    JUMP_INIT(seek, _IO_default_seek),
+    JUMP_INIT(close, _IO_default_close),
+    JUMP_INIT(stat, _IO_default_stat),
+    JUMP_INIT(showmanyc, _IO_default_showmanyc),
+    JUMP_INIT(imbue, _IO_default_imbue)
+  },
+  /* _IO_obstack_jumps  */
+  [IO_OBSTACK_JUMPS] = {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT(finish, NULL),
+    JUMP_INIT(overflow, __IO_obstack_overflow),
+    JUMP_INIT(underflow, NULL),
+    JUMP_INIT(uflow, NULL),
+    JUMP_INIT(pbackfail, NULL),
+    JUMP_INIT(xsputn, __IO_obstack_xsputn),
+    JUMP_INIT(xsgetn, NULL),
+    JUMP_INIT(seekoff, NULL),
+    JUMP_INIT(seekpos, NULL),
+    JUMP_INIT(setbuf, NULL),
+    JUMP_INIT(sync, NULL),
+    JUMP_INIT(doallocate, NULL),
+    JUMP_INIT(read, NULL),
+    JUMP_INIT(write, NULL),
+    JUMP_INIT(seek, NULL),
+    JUMP_INIT(close, NULL),
+    JUMP_INIT(stat, NULL),
+    JUMP_INIT(showmanyc, NULL),
+    JUMP_INIT(imbue, NULL)
+  },
+  /* _IO_helper_jumps  */
+  [IO_HELPER_JUMPS] = {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT (finish, _IO_wdefault_finish),
+    JUMP_INIT (overflow, _IO_helper_overflow),
+    JUMP_INIT (underflow, _IO_default_underflow),
+    JUMP_INIT (uflow, _IO_default_uflow),
+    JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail),
+    JUMP_INIT (xsputn, _IO_wdefault_xsputn),
+    JUMP_INIT (xsgetn, _IO_wdefault_xsgetn),
+    JUMP_INIT (seekoff, _IO_default_seekoff),
+    JUMP_INIT (seekpos, _IO_default_seekpos),
+    JUMP_INIT (setbuf, _IO_default_setbuf),
+    JUMP_INIT (sync, _IO_default_sync),
+    JUMP_INIT (doallocate, _IO_wdefault_doallocate),
+    JUMP_INIT (read, _IO_default_read),
+    JUMP_INIT (write, _IO_default_write),
+    JUMP_INIT (seek, _IO_default_seek),
+    JUMP_INIT (close, _IO_default_close),
+    JUMP_INIT (stat, _IO_default_stat)
+  },
+  /* _IO_whelper_jumps  */
+  [IO_WHELPER_JUMPS] = {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT (finish, _IO_default_finish),
+    JUMP_INIT (overflow, _IO_whelper_overflow),
+    JUMP_INIT (underflow, _IO_default_underflow),
+    JUMP_INIT (uflow, _IO_default_uflow),
+    JUMP_INIT (pbackfail, _IO_default_pbackfail),
+    JUMP_INIT (xsputn, _IO_default_xsputn),
+    JUMP_INIT (xsgetn, _IO_default_xsgetn),
+    JUMP_INIT (seekoff, _IO_default_seekoff),
+    JUMP_INIT (seekpos, _IO_default_seekpos),
+    JUMP_INIT (setbuf, _IO_default_setbuf),
+    JUMP_INIT (sync, _IO_default_sync),
+    JUMP_INIT (doallocate, _IO_default_doallocate),
+    JUMP_INIT (read, _IO_default_read),
+    JUMP_INIT (write, _IO_default_write),
+    JUMP_INIT (seek, _IO_default_seek),
+    JUMP_INIT (close, _IO_default_close),
+    JUMP_INIT (stat, _IO_default_stat)
+  },
+  /* _IO_mem_jumps  */
+  [IO_MEM_JUMPS] = {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT (finish, _IO_mem_finish),
+    JUMP_INIT (overflow, _IO_str_overflow),
+    JUMP_INIT (underflow, _IO_str_underflow),
+    JUMP_INIT (uflow, _IO_default_uflow),
+    JUMP_INIT (pbackfail, _IO_str_pbackfail),
+    JUMP_INIT (xsputn, _IO_default_xsputn),
+    JUMP_INIT (xsgetn, _IO_default_xsgetn),
+    JUMP_INIT (seekoff, _IO_str_seekoff),
+    JUMP_INIT (seekpos, _IO_default_seekpos),
+    JUMP_INIT (setbuf, _IO_default_setbuf),
+    JUMP_INIT (sync, _IO_mem_sync),
+    JUMP_INIT (doallocate, _IO_default_doallocate),
+    JUMP_INIT (read, _IO_default_read),
+    JUMP_INIT (write, _IO_default_write),
+    JUMP_INIT (seek, _IO_default_seek),
+    JUMP_INIT (close, _IO_default_close),
+    JUMP_INIT (stat, _IO_default_stat),
+    JUMP_INIT(showmanyc, _IO_default_showmanyc),
+    JUMP_INIT(imbue, _IO_default_imbue)
+  },
+  /* _IO_wmem_jumps  */
+  [IO_WMEM_JUMPS] = {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT (finish, _IO_wmem_finish),
+    JUMP_INIT (overflow, (_IO_overflow_t) _IO_wstr_overflow),
+    JUMP_INIT (underflow, (_IO_underflow_t) _IO_wstr_underflow),
+    JUMP_INIT (uflow, (_IO_underflow_t) _IO_wdefault_uflow),
+    JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail),
+    JUMP_INIT (xsputn, _IO_wdefault_xsputn),
+    JUMP_INIT (xsgetn, _IO_wdefault_xsgetn),
+    JUMP_INIT (seekoff, _IO_wstr_seekoff),
+    JUMP_INIT (seekpos, _IO_default_seekpos),
+    JUMP_INIT (setbuf, _IO_default_setbuf),
+    JUMP_INIT (sync, _IO_wmem_sync),
+    JUMP_INIT (doallocate, _IO_wdefault_doallocate),
+    JUMP_INIT (read, _IO_default_read),
+    JUMP_INIT (write, _IO_default_write),
+    JUMP_INIT (seek, _IO_default_seek),
+    JUMP_INIT (close, _IO_default_close),
+    JUMP_INIT (stat, _IO_default_stat),
+    JUMP_INIT (showmanyc, _IO_default_showmanyc),
+    JUMP_INIT (imbue, _IO_default_imbue)
+  },
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+  /* _IO_old_file_jumps  */
+  [IO_OLD_FILE_JUMPS] {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT(finish, _IO_old_file_finish),
+    JUMP_INIT(overflow, _IO_old_file_overflow),
+    JUMP_INIT(underflow, _IO_old_file_underflow),
+    JUMP_INIT(uflow, _IO_default_uflow),
+    JUMP_INIT(pbackfail, _IO_default_pbackfail),
+    JUMP_INIT(xsputn, _IO_old_file_xsputn),
+    JUMP_INIT(xsgetn, _IO_default_xsgetn),
+    JUMP_INIT(seekoff, _IO_old_file_seekoff),
+    JUMP_INIT(seekpos, _IO_default_seekpos),
+    JUMP_INIT(setbuf, _IO_old_file_setbuf),
+    JUMP_INIT(sync, _IO_old_file_sync),
+    JUMP_INIT(doallocate, _IO_file_doallocate),
+    JUMP_INIT(read, _IO_file_read),
+    JUMP_INIT(write, _IO_old_file_write),
+    JUMP_INIT(seek, _IO_file_seek),
+    JUMP_INIT(close, _IO_file_close),
+    JUMP_INIT(stat, _IO_file_stat)
+  },
+  /*  _IO_old_proc_jumps  */
+  [IO_OLD_PROC_JUMPS] {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT(finish, _IO_old_file_finish),
+    JUMP_INIT(overflow, _IO_old_file_overflow),
+    JUMP_INIT(underflow, _IO_old_file_underflow),
+    JUMP_INIT(uflow, _IO_default_uflow),
+    JUMP_INIT(pbackfail, _IO_default_pbackfail),
+    JUMP_INIT(xsputn, _IO_old_file_xsputn),
+    JUMP_INIT(xsgetn, _IO_default_xsgetn),
+    JUMP_INIT(seekoff, _IO_old_file_seekoff),
+    JUMP_INIT(seekpos, _IO_default_seekpos),
+    JUMP_INIT(setbuf, _IO_old_file_setbuf),
+    JUMP_INIT(sync, _IO_old_file_sync),
+    JUMP_INIT(doallocate, _IO_file_doallocate),
+    JUMP_INIT(read, _IO_file_read),
+    JUMP_INIT(write, _IO_old_file_write),
+    JUMP_INIT(seek, _IO_file_seek),
+    JUMP_INIT(close, _IO_old_proc_close),
+    JUMP_INIT(stat, _IO_file_stat),
+    JUMP_INIT(showmanyc, _IO_default_showmanyc),
+    JUMP_INIT(imbue, _IO_default_imbue)
+  },
+#endif
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
+  /* _IO_old_cookie_jumps  */
+  [IO_OLD_COOKIED_JUMPS] = {
+    JUMP_INIT_DUMMY,
+    JUMP_INIT(finish, _IO_file_finish),
+    JUMP_INIT(overflow, _IO_file_overflow),
+    JUMP_INIT(underflow, _IO_file_underflow),
+    JUMP_INIT(uflow, _IO_default_uflow),
+    JUMP_INIT(pbackfail, _IO_default_pbackfail),
+    JUMP_INIT(xsputn, _IO_file_xsputn),
+    JUMP_INIT(xsgetn, _IO_default_xsgetn),
+    JUMP_INIT(seekoff, _IO_cookie_seekoff),
+    JUMP_INIT(seekpos, _IO_default_seekpos),
+    JUMP_INIT(setbuf, _IO_file_setbuf),
+    JUMP_INIT(sync, _IO_file_sync),
+    JUMP_INIT(doallocate, _IO_file_doallocate),
+    JUMP_INIT(read, _IO_cookie_read),
+    JUMP_INIT(write, _IO_cookie_write),
+    JUMP_INIT(seek, _IO_old_cookie_seek),
+    JUMP_INIT(close, _IO_cookie_close),
+    JUMP_INIT(stat, _IO_default_stat),
+    JUMP_INIT(showmanyc, _IO_default_showmanyc),
+    JUMP_INIT(imbue, _IO_default_imbue),
+  },
+#endif
+};
+const size_t __io_vtables_size attribute_relro = sizeof (__io_vtables);
 
 #ifdef SHARED
 
@@ -82,3 +572,15 @@  check_stdfiles_vtables (void)
     IO_set_accept_foreign_vtables (&_IO_vtable_check);
 }
 #endif
+
+#define STR(s)  XSTR(s)
+#define XSTR(s) #s
+
+#undef _IO_file_jumps
+#define _IO_file_jumps_alias  "__io_vtables + " STR(IO_FILE_JUMPS_OFFSET)
+declare_object_symbol_alias (_IO_file_jumps, _IO_file_jumps_alias,
+			     IO_JUMP_T_SIZE)
+#undef _IO_wfile_jumps
+#define _IO_wfile_jumps_alias  "__io_vtables + " STR(IO_WFILE_JUMPS_OFFSET)
+declare_object_symbol_alias (_IO_wfile_jumps, _IO_wfile_jumps_alias,
+			     IO_JUMP_T_SIZE)
diff --git a/libio/wfileops.c b/libio/wfileops.c
index b59a98881f..f92d9b42eb 100644
--- a/libio/wfileops.c
+++ b/libio/wfileops.c
@@ -328,7 +328,7 @@  _IO_wfile_underflow (FILE *fp)
 libc_hidden_def (_IO_wfile_underflow)
 
 
-static wint_t
+wint_t
 _IO_wfile_underflow_mmap (FILE *fp)
 {
   struct _IO_codecvt *cd;
@@ -389,7 +389,7 @@  _IO_wfile_underflow_mmap (FILE *fp)
   return WEOF;
 }
 
-static wint_t
+wint_t
 _IO_wfile_underflow_maybe_mmap (FILE *fp)
 {
   /* This is the first read attempt.  Doing the underflow will choose mmap
@@ -1017,78 +1017,3 @@  _IO_wfile_xsputn (FILE *f, const void *data, size_t n)
   return n - to_do;
 }
 libc_hidden_def (_IO_wfile_xsputn)
-
-
-const struct _IO_jump_t _IO_wfile_jumps libio_vtable =
-{
-  JUMP_INIT_DUMMY,
-  JUMP_INIT(finish, _IO_new_file_finish),
-  JUMP_INIT(overflow, (_IO_overflow_t) _IO_wfile_overflow),
-  JUMP_INIT(underflow, (_IO_underflow_t) _IO_wfile_underflow),
-  JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow),
-  JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail),
-  JUMP_INIT(xsputn, _IO_wfile_xsputn),
-  JUMP_INIT(xsgetn, _IO_file_xsgetn),
-  JUMP_INIT(seekoff, _IO_wfile_seekoff),
-  JUMP_INIT(seekpos, _IO_default_seekpos),
-  JUMP_INIT(setbuf, _IO_new_file_setbuf),
-  JUMP_INIT(sync, (_IO_sync_t) _IO_wfile_sync),
-  JUMP_INIT(doallocate, _IO_wfile_doallocate),
-  JUMP_INIT(read, _IO_file_read),
-  JUMP_INIT(write, _IO_new_file_write),
-  JUMP_INIT(seek, _IO_file_seek),
-  JUMP_INIT(close, _IO_file_close),
-  JUMP_INIT(stat, _IO_file_stat),
-  JUMP_INIT(showmanyc, _IO_default_showmanyc),
-  JUMP_INIT(imbue, _IO_default_imbue)
-};
-libc_hidden_data_def (_IO_wfile_jumps)
-
-
-const struct _IO_jump_t _IO_wfile_jumps_mmap libio_vtable =
-{
-  JUMP_INIT_DUMMY,
-  JUMP_INIT(finish, _IO_new_file_finish),
-  JUMP_INIT(overflow, (_IO_overflow_t) _IO_wfile_overflow),
-  JUMP_INIT(underflow, (_IO_underflow_t) _IO_wfile_underflow_mmap),
-  JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow),
-  JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail),
-  JUMP_INIT(xsputn, _IO_wfile_xsputn),
-  JUMP_INIT(xsgetn, _IO_file_xsgetn),
-  JUMP_INIT(seekoff, _IO_wfile_seekoff),
-  JUMP_INIT(seekpos, _IO_default_seekpos),
-  JUMP_INIT(setbuf, _IO_file_setbuf_mmap),
-  JUMP_INIT(sync, (_IO_sync_t) _IO_wfile_sync),
-  JUMP_INIT(doallocate, _IO_wfile_doallocate),
-  JUMP_INIT(read, _IO_file_read),
-  JUMP_INIT(write, _IO_new_file_write),
-  JUMP_INIT(seek, _IO_file_seek),
-  JUMP_INIT(close, _IO_file_close_mmap),
-  JUMP_INIT(stat, _IO_file_stat),
-  JUMP_INIT(showmanyc, _IO_default_showmanyc),
-  JUMP_INIT(imbue, _IO_default_imbue)
-};
-
-const struct _IO_jump_t _IO_wfile_jumps_maybe_mmap libio_vtable =
-{
-  JUMP_INIT_DUMMY,
-  JUMP_INIT(finish, _IO_new_file_finish),
-  JUMP_INIT(overflow, (_IO_overflow_t) _IO_wfile_overflow),
-  JUMP_INIT(underflow, (_IO_underflow_t) _IO_wfile_underflow_maybe_mmap),
-  JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow),
-  JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail),
-  JUMP_INIT(xsputn, _IO_wfile_xsputn),
-  JUMP_INIT(xsgetn, _IO_file_xsgetn),
-  JUMP_INIT(seekoff, _IO_wfile_seekoff),
-  JUMP_INIT(seekpos, _IO_default_seekpos),
-  JUMP_INIT(setbuf, _IO_file_setbuf_mmap),
-  JUMP_INIT(sync, (_IO_sync_t) _IO_wfile_sync),
-  JUMP_INIT(doallocate, _IO_wfile_doallocate),
-  JUMP_INIT(read, _IO_file_read),
-  JUMP_INIT(write, _IO_new_file_write),
-  JUMP_INIT(seek, _IO_file_seek),
-  JUMP_INIT(close, _IO_file_close),
-  JUMP_INIT(stat, _IO_file_stat),
-  JUMP_INIT(showmanyc, _IO_default_showmanyc),
-  JUMP_INIT(imbue, _IO_default_imbue)
-};
diff --git a/libio/wmemstream.c b/libio/wmemstream.c
index e7f898c7fb..50ad1bdc86 100644
--- a/libio/wmemstream.c
+++ b/libio/wmemstream.c
@@ -30,34 +30,6 @@  struct _IO_FILE_wmemstream
 };
 
 
-static int _IO_wmem_sync (FILE* fp) __THROW;
-static void _IO_wmem_finish (FILE* fp, int) __THROW;
-
-
-static const struct _IO_jump_t _IO_wmem_jumps libio_vtable =
-{
-  JUMP_INIT_DUMMY,
-  JUMP_INIT (finish, _IO_wmem_finish),
-  JUMP_INIT (overflow, (_IO_overflow_t) _IO_wstr_overflow),
-  JUMP_INIT (underflow, (_IO_underflow_t) _IO_wstr_underflow),
-  JUMP_INIT (uflow, (_IO_underflow_t) _IO_wdefault_uflow),
-  JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail),
-  JUMP_INIT (xsputn, _IO_wdefault_xsputn),
-  JUMP_INIT (xsgetn, _IO_wdefault_xsgetn),
-  JUMP_INIT (seekoff, _IO_wstr_seekoff),
-  JUMP_INIT (seekpos, _IO_default_seekpos),
-  JUMP_INIT (setbuf, _IO_default_setbuf),
-  JUMP_INIT (sync, _IO_wmem_sync),
-  JUMP_INIT (doallocate, _IO_wdefault_doallocate),
-  JUMP_INIT (read, _IO_default_read),
-  JUMP_INIT (write, _IO_default_write),
-  JUMP_INIT (seek, _IO_default_seek),
-  JUMP_INIT (close, _IO_default_close),
-  JUMP_INIT (stat, _IO_default_stat),
-  JUMP_INIT (showmanyc, _IO_default_showmanyc),
-  JUMP_INIT (imbue, _IO_default_imbue)
-};
-
 /* Open a stream that writes into a malloc'd buffer that is expanded as
    necessary.  *BUFLOC and *SIZELOC are updated with the buffer's location
    and the number of characters written on fflush or fclose.  */
@@ -105,7 +77,7 @@  open_wmemstream (wchar_t **bufloc, size_t *sizeloc)
 }
 
 
-static int
+int
 _IO_wmem_sync (FILE *fp)
 {
   struct _IO_FILE_wmemstream *mp = (struct _IO_FILE_wmemstream *) fp;
@@ -124,7 +96,7 @@  _IO_wmem_sync (FILE *fp)
 }
 
 
-static void
+void
 _IO_wmem_finish (FILE *fp, int dummy)
 {
   struct _IO_FILE_wmemstream *mp = (struct _IO_FILE_wmemstream *) fp;
diff --git a/libio/wstrops.c b/libio/wstrops.c
index 2aec314937..ac7efe9f65 100644
--- a/libio/wstrops.c
+++ b/libio/wstrops.c
@@ -361,27 +361,3 @@  _IO_wstr_finish (FILE *fp, int dummy)
 
   _IO_wdefault_finish (fp, 0);
 }
-
-const struct _IO_jump_t _IO_wstr_jumps libio_vtable =
-{
-  JUMP_INIT_DUMMY,
-  JUMP_INIT(finish, _IO_wstr_finish),
-  JUMP_INIT(overflow, (_IO_overflow_t) _IO_wstr_overflow),
-  JUMP_INIT(underflow, (_IO_underflow_t) _IO_wstr_underflow),
-  JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow),
-  JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wstr_pbackfail),
-  JUMP_INIT(xsputn, _IO_wdefault_xsputn),
-  JUMP_INIT(xsgetn, _IO_wdefault_xsgetn),
-  JUMP_INIT(seekoff, _IO_wstr_seekoff),
-  JUMP_INIT(seekpos, _IO_default_seekpos),
-  JUMP_INIT(setbuf, _IO_default_setbuf),
-  JUMP_INIT(sync, _IO_default_sync),
-  JUMP_INIT(doallocate, _IO_wdefault_doallocate),
-  JUMP_INIT(read, _IO_default_read),
-  JUMP_INIT(write, _IO_default_write),
-  JUMP_INIT(seek, _IO_default_seek),
-  JUMP_INIT(close, _IO_default_close),
-  JUMP_INIT(stat, _IO_default_stat),
-  JUMP_INIT(showmanyc, _IO_default_showmanyc),
-  JUMP_INIT(imbue, _IO_default_imbue)
-};
diff --git a/stdio-common/vfprintf-internal.c b/stdio-common/vfprintf-internal.c
index fb94961f37..da284db349 100644
--- a/stdio-common/vfprintf-internal.c
+++ b/stdio-common/vfprintf-internal.c
@@ -1633,11 +1633,11 @@  struct helper_file
 #endif
   };
 
-static int
+#ifdef COMPILE_WPRINTF
+int
 _IO_helper_overflow (FILE *s, int c)
 {
   FILE *target = ((struct helper_file*) s)->_put_stream;
-#ifdef COMPILE_WPRINTF
   int used = s->_wide_data->_IO_write_ptr - s->_wide_data->_IO_write_base;
   if (used)
     {
@@ -1649,7 +1649,13 @@  _IO_helper_overflow (FILE *s, int c)
 		  used - written);
       s->_wide_data->_IO_write_ptr -= written;
     }
+  return PUTC (c, s);
+}
 #else
+int
+_IO_whelper_overflow (FILE *s, int c)
+{
+  FILE *target = ((struct helper_file*) s)->_put_stream;
   int used = s->_IO_write_ptr - s->_IO_write_base;
   if (used)
     {
@@ -1660,54 +1666,8 @@  _IO_helper_overflow (FILE *s, int c)
 	       used - written);
       s->_IO_write_ptr -= written;
     }
-#endif
   return PUTC (c, s);
 }
-
-#ifdef COMPILE_WPRINTF
-static const struct _IO_jump_t _IO_helper_jumps libio_vtable =
-{
-  JUMP_INIT_DUMMY,
-  JUMP_INIT (finish, _IO_wdefault_finish),
-  JUMP_INIT (overflow, _IO_helper_overflow),
-  JUMP_INIT (underflow, _IO_default_underflow),
-  JUMP_INIT (uflow, _IO_default_uflow),
-  JUMP_INIT (pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail),
-  JUMP_INIT (xsputn, _IO_wdefault_xsputn),
-  JUMP_INIT (xsgetn, _IO_wdefault_xsgetn),
-  JUMP_INIT (seekoff, _IO_default_seekoff),
-  JUMP_INIT (seekpos, _IO_default_seekpos),
-  JUMP_INIT (setbuf, _IO_default_setbuf),
-  JUMP_INIT (sync, _IO_default_sync),
-  JUMP_INIT (doallocate, _IO_wdefault_doallocate),
-  JUMP_INIT (read, _IO_default_read),
-  JUMP_INIT (write, _IO_default_write),
-  JUMP_INIT (seek, _IO_default_seek),
-  JUMP_INIT (close, _IO_default_close),
-  JUMP_INIT (stat, _IO_default_stat)
-};
-#else
-static const struct _IO_jump_t _IO_helper_jumps libio_vtable =
-{
-  JUMP_INIT_DUMMY,
-  JUMP_INIT (finish, _IO_default_finish),
-  JUMP_INIT (overflow, _IO_helper_overflow),
-  JUMP_INIT (underflow, _IO_default_underflow),
-  JUMP_INIT (uflow, _IO_default_uflow),
-  JUMP_INIT (pbackfail, _IO_default_pbackfail),
-  JUMP_INIT (xsputn, _IO_default_xsputn),
-  JUMP_INIT (xsgetn, _IO_default_xsgetn),
-  JUMP_INIT (seekoff, _IO_default_seekoff),
-  JUMP_INIT (seekpos, _IO_default_seekpos),
-  JUMP_INIT (setbuf, _IO_default_setbuf),
-  JUMP_INIT (sync, _IO_default_sync),
-  JUMP_INIT (doallocate, _IO_default_doallocate),
-  JUMP_INIT (read, _IO_default_read),
-  JUMP_INIT (write, _IO_default_write),
-  JUMP_INIT (seek, _IO_default_seek),
-  JUMP_INIT (close, _IO_default_close),
-  JUMP_INIT (stat, _IO_default_stat)
-};
 #endif
 
 static int
@@ -1742,7 +1702,11 @@  buffered_vfprintf (FILE *s, const CHAR_T *format, va_list args,
   hp->_lock = NULL;
 #endif
   hp->_flags2 = s->_flags2;
+#ifdef COMPILE_WPRINTF
   _IO_JUMPS (&helper._f) = (struct _IO_jump_t *) &_IO_helper_jumps;
+#else
+  _IO_JUMPS (&helper._f) = (struct _IO_jump_t *) &_IO_whelper_jumps;
+#endif
 
   /* Now print to helper instead.  */
   result = vfprintf (hp, format, args, mode_flags);