This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] libio: Consolidate vtable definitions in a single file


This will allow us to efficiently validate vtable pointers.

There is some increase the size of statically linked executables.
The numbers below are for x86_64, with GCC 6 and the default flags.

Before:

   text    data     bss     dec     hex filename
 694942    7276    5816  708034   acdc2 elf/sln
 861436    7536    6760  875732   d5cd4 elf/ldconfig

After:

 695550    7276    5816  708642   ad022 elf/sln
 861916    7536    6760  876212   d5eb4 elf/ldconfig

2016-06-03  Florian Weimer  <fweimer@redhat.com>

	Consolidate libio vtables in a single file.
	* libio/vtables.c: New file.  Define jump tables with designated
	initializers instead of JUMP_INIT.
	* libio/libioP.h (JUMP_INIT, JUMP_INIT_DUMMY): Remove macros.
	(_IO_file_jumps, _IO_file_jumps_mmap, _IO_file_jumps_maybe_mmap)
	(_IO_wfile_jumps, _IO_wfile_jumps_mmap)
	(_IO_wfile_jumps_maybe_mmap, _IO_old_file_jumps)
	(_IO_streambuf_jumps, _IO_old_proc_jumps, _IO_str_jumps)
	(_IO_wstr_jumps): Remove declarations.
	(IO_VTABLE_file, IO_VTABLE_file_mmap, IO_VTABLE_file_maybe_mmap)
	(IO_VTABLE_wfile, IO_VTABLE_wfile_mmap)
	(IO_VTABLE_wfile_maybe_mmap, IO_VTABLE_mem, IO_VTABLE_wmem)
	(IO_VTABLE_proc, IO_VTABLE_str, IO_VTABLE_str_chk, IO_VTABLE_strn)
	(IO_VTABLE_wstr, IO_VTABLE_wstrn, IO_VTABLE_cookie)
	(IO_VTABLE_obstack, IO_VTABLE_printf_helper)
	(IO_VTABLE_wprintf_helper, IO_VTABLE_old_file, IO_VTABLE_old_proc)
	(IO_VTABLE_old_cookie): New enum constants.
	(_IO_vtables): New array of vtables.
	(_IO_file_sync_mmap, _IO_file_xsgetn_mmap)
	(_IO_file_xsgetn_maybe_mmap, _IO_file_seekoff_maybe_mmap)
	(_IO_wfile_underflow_mmap, _IO_wfile_underflow_maybe_mmap)
	(_IO_mem_sync, _IO_mem_finish, _IO_wmem_sync, _IO_wmem_finish)
	(_IO_str_chk_overflow, _IO_strn_overflow, _IO_wstrn_overflow)
	(_IO_cookie_read, _IO_cookie_write, _IO_cookie_seek)
	(_IO_cookie_seekoff, _IO_cookie_close, _IO_obstack_overflow)
	(_IO_obstack_xsputn, _IO_printf_helper_overflow)
	(_IO_wprintf_helper_overflow, _IO_old_cookie_seek): Declare
	functions used in vtables.
	* libio/Makefile (routines): Add vtables.
	* debug/obprintf_chk.c (_IO_obstack_jumps): Remove declaration.
	(__obstack_vprintf_chk): Use IO_VTABLE_obstack.
	* debug/vasprintf_chk.c (__vasprintf_chk): Use IO_VTABLE_str.
	* debug/vdprintf_chk.c (__vdprintf_chk): Use IO_VTABLE_wfile,
	IO_VTABLE_file.
	* debug/vsnprintf_chk.c (_IO_strn_jumps): Remove declaration.
	(___vsnprintf_chk): Use IO_VTABLE_strn.
	* debug/vsprintf_chk.c (_IO_str_chk_overflow): Export.
	(_IO_str_chk_jumps): Remove.
	(___vsprintf_chk): Use IO_VTABLE_str_chk.
	* debug/vswprintf_chk.c (__vswprintf_chk): Use IO_VTABLE_wstrn.
	* libio/fileops.c (_IO_file_setbuf_mmap): Use IO_VTABLE_file,
	IO_VTABLE_wfile, IO_VTABLE_file_mmap, IO_VTABLE_wfile_mmap.
	(mmap_remap_check): Use IO_VTABLE_file, IO_VTABLE_wfile.
	(decide_maybe_mmap): Use IO_VTABLE_file_mmap,
	IO_VTABLE_wfile_mmap, IO_VTABLE_file, IO_VTABLE_wfile.
	(_IO_file_sync_mmap, _IO_file_seekoff_maybe_mmap)
	(_IO_file_xsgetn_mmap, _IO_file_xsgetn_maybe_mmap): Export.
	(_IO_file_jumps, _IO_file_jumps_mmap, _IO_file_jumps_maybe_mmap):
	Remove.
	* libio/freopen.c (freopen): Use IO_VTABLE_old_file,
	IO_VTABLE_file, IO_VTABLE_wfile.
	* libio/libio/freopen64.c (freopen64): Use IO_VTABLE_file,
	IO_VTABLE_wfile.
	* libio/iofdopen.c (_IO_new_fdopen): Use
	IO_VTABLE_wfile_maybe_mmap, IO_VTABLE_wfile,
	IO_VTABLE_file_maybe_mmap, IO_VTABLE_file.
	* libio/iofopen.c (__fopen_maybe_mmap): Use
	IO_VTABLE_file_maybe_mmap, IO_VTABLE_wfile_maybe_mmap.
	(__fopen_internal): Use IO_VTABLE_wfile, IO_VTABLE_file.
	* libio/iofopncook.c (_IO_cookie_read, _IO_cookie_write)
	(_IO_cookie_seek, _IO_cookie_close, _IO_cookie_seekoff): Export.
	(_IO_cookie_jumps): Remove.
	(_IO_cookie_init): Use IO_VTABLE_cookie.
	(_IO_old_cookie_jumps): Remove.
	(_IO_old_fopencookie): Use IO_VTABLE_old_cookie.
	* libio/iopopen.c (_IO_proc_jumps): Remove.
	(_IO_new_popen): Use IO_VTABLE_proc.
	* libio/iovdprintf.c (_IO_vdprintf): Use IO_VTABLE_wfile,
	IO_VTABLE_file.
	* libio/iovsprintf.c (__IO_vsprintf): Use IO_VTABLE_str.
	* libio/iovsscanf.c (_IO_vsscanf): Use IO_VTABLE_str.
	* libio/iovswscanf.c (__vswscanf): Use IO_VTABLE_wstr.
	* libio/memstream.c (_IO_mem_sync, _IO_mem_finish): Export.
	(_IO_mem_jumps): Remove.
	(__open_memstream): Use IO_VTABLE_mem.
	* libio/obprintf.c (_IO_obstack_overflow, _IO_obstack_xsputn):
	Export.
	(_IO_obstack_jumps): Remove.
	(_IO_obstack_vprintf): Use IO_VTABLE_obstack.
	* libio/oldfileops.c (_IO_old_file_jumps): Remove.
	* libio/oldiofdopen.c (_IO_old_fdopen): Use IO_VTABLE_old_file.
	* libio/oldiofopen.c (_IO_old_fopen): Use IO_VTABLE_old_file.
	* libio/oldiopopen.c (_IO_old_popen): Use IO_VTABLE_old_proc.
	(_IO_old_proc_jumps): Remove.
	* libio/oldstdfiles.c (DEF_STDFILE): Use IO_VTABLE_old_file.
	* libio/stdfiles.c (DEF_STDFILE): Use IO_VTABLE_wfile,
	IO_VTABLE_file.
	* libio/strfile.h (_IO_strn_jumps, _IO_wstrn_jumps): Remove
	declarations.
	* libio/strops.c (_IO_str_jumps): Remove.
	* libio/vasprintf.c (_IO_vasprintf): Use IO_VTABLE_str.
	* libio/vsnprintf.c (_IO_strn_overflow): Export.
	(_IO_strn_jumps): Remove.
	(_IO_vsnprintf): Use IO_VTABLE_strn.
	* libio/vswprintf.c (_IO_wstrn_overflow): Export.
	(_IO_wstrn_jumps): Remove.
	(_IO_vswprintf): Use IO_VTABLE_wstrn.
	* libio/wfileops.c (_IO_wfile_underflow_mmap)
	(_IO_wfile_underflow_maybe_mmap): Export.
	(_IO_wfile_jumps, _IO_wfile_jumps_mmap)
	(_IO_wfile_jumps_maybe_mmap): Remove.
	* libio/wmemstream.c (_IO_wmem_sync, _IO_wmem_finish): Export.
	(_IO_wmem_jumps): Remove.
	(open_wmemstream): Use IO_VTABLE_wmem.
	* libio/wstrops.c (_IO_wstr_jumps): Remove.
	* stdio-common/isoc99_vsscanf.c (__isoc99_vsscanf): Use
	IO_VTABLE_str.
	* stdio-common/vfprintf.c (_IO_wprintf_helper_overflow)
	(_IO_printf_helper_overflow): Split, rename and export.
	(_IO_helper_jumps, _IO_helper_jumps): Remove.
	(buffered_vfprintf): Use IO_VTABLE_printf_helper,
	IO_VTABLE_wprintf_helper
	* stdlib/strfmon_l.c (__vstrfmon_l): Use IO_VTABLE_str.
	* wcsmbs/isoc99_vswscanf.c (__isoc99_vswscanf): Use
	IO_VTABLE_wstr.

diff --git a/debug/obprintf_chk.c b/debug/obprintf_chk.c
index 8469b5f..e458655 100644
--- a/debug/obprintf_chk.c
+++ b/debug/obprintf_chk.c
@@ -35,8 +35,6 @@ struct _IO_obstack_file
   struct obstack *obstack;
 };
 
-extern const struct _IO_jump_t _IO_obstack_jumps attribute_hidden;
-
 int
 __obstack_vprintf_chk (struct obstack *obstack, int flags, const char *format,
 		       va_list args)
@@ -54,7 +52,7 @@ __obstack_vprintf_chk (struct obstack *obstack, int flags, const char *format,
 #endif
 
   _IO_no_init (&new_f.ofile.file.file, _IO_USER_LOCK, -1, NULL, NULL);
-  _IO_JUMPS (&new_f.ofile.file) = &_IO_obstack_jumps;
+  _IO_JUMPS (&new_f.ofile.file) = &_IO_vtables[IO_VTABLE_obstack];
   room = obstack_room (obstack);
   size = obstack_object_size (obstack) + room;
   if (size == 0)
diff --git a/debug/vasprintf_chk.c b/debug/vasprintf_chk.c
index cb1f74a..235db0b 100644
--- a/debug/vasprintf_chk.c
+++ b/debug/vasprintf_chk.c
@@ -52,7 +52,7 @@ __vasprintf_chk (char **result_ptr, int flags, const char *format,
   sf._sbf._f._lock = NULL;
 #endif
   _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
-  _IO_JUMPS (&sf._sbf) = &_IO_str_jumps;
+  _IO_JUMPS (&sf._sbf) = &_IO_vtables[IO_VTABLE_str];
   _IO_str_init_static_internal (&sf, string, init_string_size, string);
   sf._sbf._f._flags &= ~_IO_USER_BUF;
   sf._s._allocate_buffer = (_IO_alloc_type) malloc;
diff --git a/debug/vdprintf_chk.c b/debug/vdprintf_chk.c
index 05d0bcd..6efe9ee 100644
--- a/debug/vdprintf_chk.c
+++ b/debug/vdprintf_chk.c
@@ -37,8 +37,9 @@ __vdprintf_chk (int d, int flags, const char *format, va_list arg)
 #ifdef _IO_MTSAFE_IO
   tmpfil.file._lock = NULL;
 #endif
-  _IO_no_init (&tmpfil.file, _IO_USER_LOCK, 0, &wd, &_IO_wfile_jumps);
-  _IO_JUMPS (&tmpfil) = &_IO_file_jumps;
+  _IO_no_init (&tmpfil.file, _IO_USER_LOCK, 0, &wd,
+	       &_IO_vtables[IO_VTABLE_wfile]);
+  _IO_JUMPS (&tmpfil) = &_IO_vtables[IO_VTABLE_file];
   _IO_file_init (&tmpfil);
 #if  !_IO_UNIFIED_JUMPTABLES
   tmpfil.vtable = NULL;
diff --git a/debug/vsnprintf_chk.c b/debug/vsnprintf_chk.c
index cc559d2..a682fae 100644
--- a/debug/vsnprintf_chk.c
+++ b/debug/vsnprintf_chk.c
@@ -20,8 +20,6 @@
 #include "../libio/libioP.h"
 #include "../libio/strfile.h"
 
-extern const struct _IO_jump_t _IO_strn_jumps attribute_hidden;
-
 /* Write formatted output into S, according to the format
    string FORMAT, writing no more than MAXLEN characters.  */
 /* VARARGS5 */
@@ -51,7 +49,7 @@ ___vsnprintf_chk (char *s, size_t maxlen, int flags, size_t slen,
     }
 
   _IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
-  _IO_JUMPS (&sf.f._sbf) = &_IO_strn_jumps;
+  _IO_JUMPS (&sf.f._sbf) = &_IO_vtables[IO_VTABLE_strn];
   s[0] = '\0';
 
   /* For flags > 0 (i.e. __USE_FORTIFY_LEVEL > 1) request that %n
diff --git a/debug/vsprintf_chk.c b/debug/vsprintf_chk.c
index aa1587c..71ff17c 100644
--- a/debug/vsprintf_chk.c
+++ b/debug/vsprintf_chk.c
@@ -20,10 +20,7 @@
 #include "../libio/libioP.h"
 #include "../libio/strfile.h"
 
-
-static int _IO_str_chk_overflow (_IO_FILE *fp, int c) __THROW;
-
-static int
+int
 _IO_str_chk_overflow (_IO_FILE *fp, int c)
 {
   /* When we come to here this means the user supplied buffer is
@@ -31,32 +28,6 @@ _IO_str_chk_overflow (_IO_FILE *fp, int c)
   __chk_fail ();
 }
 
-
-static const struct _IO_jump_t _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)
-};
-
-
 int
 ___vsprintf_chk (char *s, int flags, size_t slen, const char *format,
 		 va_list args)
@@ -71,7 +42,7 @@ ___vsprintf_chk (char *s, int flags, size_t slen, const char *format,
     __chk_fail ();
 
   _IO_no_init (&f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
-  _IO_JUMPS (&f._sbf) = &_IO_str_chk_jumps;
+  _IO_JUMPS (&f._sbf) = &_IO_vtables[IO_VTABLE_str_chk];
   s[0] = '\0';
   _IO_str_init_static_internal (&f, s, slen - 1, s);
 
diff --git a/debug/vswprintf_chk.c b/debug/vswprintf_chk.c
index 50bdb78..1479439 100644
--- a/debug/vswprintf_chk.c
+++ b/debug/vswprintf_chk.c
@@ -49,7 +49,8 @@ __vswprintf_chk (wchar_t *s, size_t maxlen, int flags, size_t slen,
        length of zero always makes the function fail.  */
     return -1;
 
-  _IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, 0, &wd, &_IO_wstrn_jumps);
+  _IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, 0, &wd,
+	       &_IO_vtables[IO_VTABLE_wstrn]);
   _IO_fwide (&sf.f._sbf._f, 1);
   s[0] = L'\0';
 
diff --git a/libio/Makefile b/libio/Makefile
index 4189bc4..12589f2 100644
--- a/libio/Makefile
+++ b/libio/Makefile
@@ -46,7 +46,7 @@ routines	:=							      \
 	__fbufsize __freading __fwriting __freadable __fwritable __flbf	      \
 	__fpurge __fpending __fsetlocking				      \
 									      \
-	libc_fatal fmemopen oldfmemopen
+	libc_fatal fmemopen oldfmemopen vtables
 
 tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc   \
 	tst_wprintf2 tst-widetext test-fmemopen tst-ext tst-ext2 \
diff --git a/libio/fileops.c b/libio/fileops.c
index 8e83b1c..110d7c9 100644
--- a/libio/fileops.c
+++ b/libio/fileops.c
@@ -466,8 +466,8 @@ _IO_file_setbuf_mmap (_IO_FILE *fp, char *p, _IO_ssize_t len)
   _IO_FILE *result;
 
   /* Change the function table.  */
-  _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
-  fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
+  _IO_JUMPS_FILE_plus (fp) = &_IO_vtables[IO_VTABLE_file];
+  fp->_wide_data->_wide_vtable = &_IO_vtables[IO_VTABLE_wfile];
 
   /* And perform the normal operation.  */
   result = _IO_new_file_setbuf (fp, p, len);
@@ -475,8 +475,8 @@ _IO_file_setbuf_mmap (_IO_FILE *fp, char *p, _IO_ssize_t len)
   /* If the call failed, restore to using mmap.  */
   if (result == NULL)
     {
-      _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps_mmap;
-      fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
+      _IO_JUMPS_FILE_plus (fp) = &_IO_vtables[IO_VTABLE_file_mmap];
+      fp->_wide_data->_wide_vtable = &_IO_vtables[IO_VTABLE_wfile_mmap];
     }
 
   return result;
@@ -703,10 +703,10 @@ mmap_remap_check (_IO_FILE *fp)
       fp->_IO_buf_base = fp->_IO_buf_end = NULL;
       _IO_setg (fp, NULL, NULL, NULL);
       if (fp->_mode <= 0)
-	_IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
+	_IO_JUMPS_FILE_plus (fp) = &_IO_vtables[IO_VTABLE_file];
       else
-	_IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps;
-      fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
+	_IO_JUMPS_FILE_plus (fp) = &_IO_vtables[IO_VTABLE_wfile];
+      fp->_wide_data->_wide_vtable = &_IO_vtables[IO_VTABLE_wfile];
 
       return 1;
     }
@@ -773,10 +773,10 @@ decide_maybe_mmap (_IO_FILE *fp)
 	      fp->_offset = st.st_size;
 
 	      if (fp->_mode <= 0)
-		_IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps_mmap;
+		_IO_JUMPS_FILE_plus (fp) = &_IO_vtables[IO_VTABLE_file_mmap];
 	      else
-		_IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps_mmap;
-	      fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
+		_IO_JUMPS_FILE_plus (fp) = &_IO_vtables[IO_VTABLE_wfile_mmap];
+	      fp->_wide_data->_wide_vtable = &_IO_vtables[IO_VTABLE_wfile_mmap];
 
 	      return;
 	    }
@@ -786,10 +786,10 @@ decide_maybe_mmap (_IO_FILE *fp)
   /* We couldn't use mmap, so revert to the vanilla file operations.  */
 
   if (fp->_mode <= 0)
-    _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
+    _IO_JUMPS_FILE_plus (fp) = &_IO_vtables[IO_VTABLE_file];
   else
-    _IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps;
-  fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
+    _IO_JUMPS_FILE_plus (fp) = &_IO_vtables[IO_VTABLE_wfile];
+  fp->_wide_data->_wide_vtable = &_IO_vtables[IO_VTABLE_wfile];
 }
 
 int
@@ -897,7 +897,7 @@ _IO_new_file_sync (_IO_FILE *fp)
 }
 libc_hidden_ver (_IO_new_file_sync, _IO_file_sync)
 
-static int
+int
 _IO_file_sync_mmap (_IO_FILE *fp)
 {
   if (fp->_IO_read_ptr != fp->_IO_read_end)
@@ -1192,7 +1192,7 @@ _IO_file_seekoff_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode)
   return offset;
 }
 
-static _IO_off64_t
+_IO_off64_t
 _IO_file_seekoff_maybe_mmap (_IO_FILE *fp, _IO_off64_t offset, int dir,
 			     int mode)
 {
@@ -1453,7 +1453,7 @@ _IO_file_xsgetn (_IO_FILE *fp, void *data, _IO_size_t n)
 }
 libc_hidden_def (_IO_file_xsgetn)
 
-static _IO_size_t
+_IO_size_t
 _IO_file_xsgetn_mmap (_IO_FILE *fp, void *data, _IO_size_t n)
 {
   _IO_size_t have;
@@ -1508,7 +1508,7 @@ _IO_file_xsgetn_mmap (_IO_FILE *fp, void *data, _IO_size_t n)
   return s - (char *) data;
 }
 
-static _IO_size_t
+_IO_size_t
 _IO_file_xsgetn_maybe_mmap (_IO_FILE *fp, void *data, _IO_size_t n)
 {
   /* We only get here if this is the first attempt to read something.
@@ -1533,76 +1533,3 @@ 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);
 #endif
-
-const struct _IO_jump_t _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)
-};
-libc_hidden_data_def (_IO_file_jumps)
-
-const struct _IO_jump_t _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)
-};
-
-const struct _IO_jump_t _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)
-};
diff --git a/libio/freopen.c b/libio/freopen.c
index 8a2a417..d7d1e71 100644
--- a/libio/freopen.c
+++ b/libio/freopen.c
@@ -56,16 +56,16 @@ freopen (const char *filename, const char *mode, FILE *fp)
 	 to the old libio may be passed into shared C library and wind
 	 up here. */
       _IO_old_file_close_it (fp);
-      _IO_JUMPS_FILE_plus (fp) = &_IO_old_file_jumps;
+      _IO_JUMPS_FILE_plus (fp) = &_IO_vtables[IO_VTABLE_old_file];
       result = _IO_old_file_fopen (fp, gfilename, mode);
     }
   else
 #endif
     {
       _IO_file_close_it (fp);
-      _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
+      _IO_JUMPS_FILE_plus (fp) = &_IO_vtables[IO_VTABLE_file];
       if (_IO_vtable_offset (fp) == 0 && fp->_wide_data != NULL)
-	fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
+	fp->_wide_data->_wide_vtable = &_IO_vtables[IO_VTABLE_wfile];
       result = _IO_file_fopen (fp, gfilename, mode, 1);
       if (result != NULL)
 	result = __fopen_maybe_mmap (result);
diff --git a/libio/freopen64.c b/libio/freopen64.c
index ba85c3e..760ebc9 100644
--- a/libio/freopen64.c
+++ b/libio/freopen64.c
@@ -47,9 +47,9 @@ freopen64 (const char *filename, const char *mode, FILE *fp)
 			   ? fd_to_filename (fd) : filename);
   fp->_flags2 |= _IO_FLAGS2_NOCLOSE;
   _IO_file_close_it (fp);
-  _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps;
+  _IO_JUMPS_FILE_plus (fp) = &_IO_vtables[IO_VTABLE_file];
   if (_IO_vtable_offset (fp) == 0 && fp->_wide_data != NULL)
-    fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
+    fp->_wide_data->_wide_vtable = &_IO_vtables[IO_VTABLE_wfile];
   result = _IO_file_fopen (fp, gfilename, mode, 0);
   fp->_flags2 &= ~_IO_FLAGS2_NOCLOSE;
   if (result != NULL)
diff --git a/libio/iofdopen.c b/libio/iofdopen.c
index e00f337..2bcd21a 100644
--- a/libio/iofdopen.c
+++ b/libio/iofdopen.c
@@ -145,14 +145,15 @@ _IO_new_fdopen (int fd, const char *mode)
   _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd,
 #ifdef _G_HAVE_MMAP
 	       (use_mmap && (read_write & _IO_NO_WRITES))
-	       ? &_IO_wfile_jumps_maybe_mmap :
+	       ? &_IO_vtables[IO_VTABLE_wfile_maybe_mmap] :
 #endif
-	       &_IO_wfile_jumps);
+	       &_IO_vtables[IO_VTABLE_wfile]);
   _IO_JUMPS (&new_f->fp) =
 #ifdef _G_HAVE_MMAP
-    (use_mmap && (read_write & _IO_NO_WRITES)) ? &_IO_file_jumps_maybe_mmap :
+    (use_mmap && (read_write & _IO_NO_WRITES))
+      ? &_IO_vtables[IO_VTABLE_file_maybe_mmap] :
 #endif
-      &_IO_file_jumps;
+      &_IO_vtables[IO_VTABLE_file];
   _IO_file_init (&new_f->fp);
 #if  !_IO_UNIFIED_JUMPTABLES
   new_f->fp.vtable = NULL;
diff --git a/libio/iofopen.c b/libio/iofopen.c
index 13e3910..3510e8d 100644
--- a/libio/iofopen.c
+++ b/libio/iofopen.c
@@ -46,10 +46,10 @@ __fopen_maybe_mmap (_IO_FILE *fp)
 	 vanilla file operations and reset the jump table accordingly.  */
 
       if (fp->_mode <= 0)
-	_IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps_maybe_mmap;
+	_IO_JUMPS_FILE_plus (fp) = &_IO_vtables[IO_VTABLE_file_maybe_mmap];
       else
-	_IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps_maybe_mmap;
-      fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_maybe_mmap;
+	_IO_JUMPS_FILE_plus (fp) = &_IO_vtables[IO_VTABLE_wfile_maybe_mmap];
+      fp->_wide_data->_wide_vtable = &_IO_vtables[IO_VTABLE_wfile_maybe_mmap];
     }
 #endif
   return fp;
@@ -74,11 +74,12 @@ __fopen_internal (const char *filename, const char *mode, int is32)
   new_f->fp.file._lock = &new_f->lock;
 #endif
 #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
-  _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd, &_IO_wfile_jumps);
+  _IO_no_init (&new_f->fp.file, 0, 0, &new_f->wd,
+	       &_IO_vtables[IO_VTABLE_wfile]);
 #else
   _IO_no_init (&new_f->fp.file, 1, 0, NULL, NULL);
 #endif
-  _IO_JUMPS (&new_f->fp) = &_IO_file_jumps;
+  _IO_JUMPS (&new_f->fp) = &_IO_vtables[IO_VTABLE_file];
   _IO_file_init (&new_f->fp);
 #if  !_IO_UNIFIED_JUMPTABLES
   new_f->fp.vtable = NULL;
diff --git a/libio/iofopncook.c b/libio/iofopncook.c
index 9eda7c1..62d79ec 100644
--- a/libio/iofopncook.c
+++ b/libio/iofopncook.c
@@ -29,17 +29,7 @@
 #include <stdlib.h>
 #include <shlib-compat.h>
 
-/* Prototyped for local functions.  */
-static _IO_ssize_t _IO_cookie_read (_IO_FILE* fp, void* buf,
-				    _IO_ssize_t size);
-static _IO_ssize_t _IO_cookie_write (_IO_FILE* fp,
-				     const void* buf, _IO_ssize_t size);
-static _IO_off64_t _IO_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir);
-static _IO_off64_t _IO_cookie_seekoff (_IO_FILE *fp, _IO_off64_t offset,
-				       int dir, int mode);
-static int _IO_cookie_close (_IO_FILE* fp);
-
-static _IO_ssize_t
+_IO_ssize_t
 _IO_cookie_read (_IO_FILE *fp, void *buf, _IO_ssize_t size)
 {
   struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
@@ -50,7 +40,7 @@ _IO_cookie_read (_IO_FILE *fp, void *buf, _IO_ssize_t size)
   return cfile->__io_functions.read (cfile->__cookie, buf, size);
 }
 
-static _IO_ssize_t
+_IO_ssize_t
 _IO_cookie_write (_IO_FILE *fp, const void *buf, _IO_ssize_t size)
 {
   struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
@@ -68,7 +58,7 @@ _IO_cookie_write (_IO_FILE *fp, const void *buf, _IO_ssize_t size)
   return n;
 }
 
-static _IO_off64_t
+_IO_off64_t
 _IO_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir)
 {
   struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
@@ -80,7 +70,7 @@ _IO_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir)
 	  ? _IO_pos_BAD : offset);
 }
 
-static int
+int
 _IO_cookie_close (_IO_FILE *fp)
 {
   struct _IO_cookie_file *cfile = (struct _IO_cookie_file *) fp;
@@ -92,7 +82,7 @@ _IO_cookie_close (_IO_FILE *fp)
 }
 
 
-static _IO_off64_t
+_IO_off64_t
 _IO_cookie_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode)
 {
   /* We must force the fileops code to always use seek to determine
@@ -102,36 +92,12 @@ _IO_cookie_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode)
 }
 
 
-static const struct _IO_jump_t _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),
-};
-
-
 void
 _IO_cookie_init (struct _IO_cookie_file *cfile, int read_write,
 		 void *cookie, _IO_cookie_io_functions_t io_functions)
 {
   _IO_init (&cfile->__fp.file, 0);
-  _IO_JUMPS (&cfile->__fp) = &_IO_cookie_jumps;
+  _IO_JUMPS (&cfile->__fp) = &_IO_vtables[IO_VTABLE_cookie];
 
   cfile->__cookie = cookie;
   cfile->__io_functions = io_functions;
@@ -195,12 +161,10 @@ versioned_symbol (libc, _IO_fopencookie, fopencookie, GLIBC_2_2);
 
 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_2)
 
-static _IO_off64_t _IO_old_cookie_seek (_IO_FILE *fp, _IO_off64_t offset,
-					int dir);
 _IO_FILE * _IO_old_fopencookie (void *cookie, const char *mode,
 				_IO_cookie_io_functions_t io_functions);
 
-static _IO_off64_t
+_IO_off64_t
 attribute_compat_text_section
 _IO_old_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir)
 {
@@ -217,29 +181,6 @@ _IO_old_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir)
   return (ret == -1) ? _IO_pos_BAD : ret;
 }
 
-static const struct _IO_jump_t _IO_old_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_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),
-};
-
 _IO_FILE *
 attribute_compat_text_section
 _IO_old_fopencookie (void *cookie, const char *mode,
@@ -249,7 +190,7 @@ _IO_old_fopencookie (void *cookie, const char *mode,
 
   ret = _IO_fopencookie (cookie, mode, io_functions);
   if (ret != NULL)
-    _IO_JUMPS_FILE_plus (ret) = &_IO_old_cookie_jumps;
+    _IO_JUMPS_FILE_plus (ret) = &_IO_vtables[IO_VTABLE_old_cookie];
 
   return ret;
 }
diff --git a/libio/iopopen.c b/libio/iopopen.c
index 9ddde23..671e398 100644
--- a/libio/iopopen.c
+++ b/libio/iopopen.c
@@ -91,8 +91,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
@@ -288,7 +286,7 @@ _IO_new_popen (const char *command, const char *mode)
 #endif
   fp = &new_f->fpx.file.file;
   _IO_init (fp, 0);
-  _IO_JUMPS (&new_f->fpx.file) = &_IO_proc_jumps;
+  _IO_JUMPS (&new_f->fpx.file) = &_IO_vtables[IO_VTABLE_proc];
   _IO_new_file_init (&new_f->fpx.file);
 #if  !_IO_UNIFIED_JUMPTABLES
   new_f->fpx.file.vtable = NULL;
@@ -344,29 +342,6 @@ _IO_new_proc_close (_IO_FILE *fp)
   return wstatus;
 }
 
-static const struct _IO_jump_t _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)
-};
-
 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/iovdprintf.c b/libio/iovdprintf.c
index 8ca55fc..7f0fdd3 100644
--- a/libio/iovdprintf.c
+++ b/libio/iovdprintf.c
@@ -37,8 +37,9 @@ _IO_vdprintf (int d, const char *format, _IO_va_list arg)
 #ifdef _IO_MTSAFE_IO
   tmpfil.file._lock = NULL;
 #endif
-  _IO_no_init (&tmpfil.file, _IO_USER_LOCK, 0, &wd, &_IO_wfile_jumps);
-  _IO_JUMPS (&tmpfil) = &_IO_file_jumps;
+  _IO_no_init (&tmpfil.file, _IO_USER_LOCK, 0, &wd,
+	       &_IO_vtables[IO_VTABLE_wfile]);
+  _IO_JUMPS (&tmpfil) = &_IO_vtables[IO_VTABLE_file];
   _IO_file_init (&tmpfil);
 #if  !_IO_UNIFIED_JUMPTABLES
   tmpfil.vtable = NULL;
diff --git a/libio/iovsprintf.c b/libio/iovsprintf.c
index 712d178..f1dec0d 100644
--- a/libio/iovsprintf.c
+++ b/libio/iovsprintf.c
@@ -37,7 +37,7 @@ __IO_vsprintf (char *string, const char *format, _IO_va_list args)
   sf._sbf._f._lock = NULL;
 #endif
   _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
-  _IO_JUMPS (&sf._sbf) = &_IO_str_jumps;
+  _IO_JUMPS (&sf._sbf) = &_IO_vtables[IO_VTABLE_str];
   _IO_str_init_static_internal (&sf, string, -1, string);
   ret = _IO_vfprintf (&sf._sbf._f, format, args);
   _IO_putc_unlocked ('\0', &sf._sbf._f);
diff --git a/libio/iovsscanf.c b/libio/iovsscanf.c
index 18d9aaa..11b16dd 100644
--- a/libio/iovsscanf.c
+++ b/libio/iovsscanf.c
@@ -36,7 +36,7 @@ _IO_vsscanf (const char *string, const char *format, _IO_va_list args)
   sf._sbf._f._lock = NULL;
 #endif
   _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
-  _IO_JUMPS (&sf._sbf) = &_IO_str_jumps;
+  _IO_JUMPS (&sf._sbf) = &_IO_vtables[IO_VTABLE_str];
   _IO_str_init_static_internal (&sf, (char*)string, 0, NULL);
   ret = _IO_vfscanf (&sf._sbf._f, format, args, NULL);
   return ret;
diff --git a/libio/iovswscanf.c b/libio/iovswscanf.c
index ff36069..2839b9d 100644
--- a/libio/iovswscanf.c
+++ b/libio/iovswscanf.c
@@ -37,7 +37,8 @@ __vswscanf (const wchar_t *string, const wchar_t *format, _IO_va_list args)
 #ifdef _IO_MTSAFE_IO
   sf._sbf._f._lock = NULL;
 #endif
-  _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, 0, &wd, &_IO_wstr_jumps);
+  _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, 0, &wd,
+               &_IO_vtables[IO_VTABLE_wstr]);
   _IO_fwide (&sf._sbf._f, 1);
   _IO_wstr_init_static (&sf._sbf._f, (wchar_t *)string, 0, NULL);
   ret = _IO_vfwscanf ((_IO_FILE *) &sf._sbf, format, args, NULL);
diff --git a/libio/libioP.h b/libio/libioP.h
index 8706af2..5322a84 100644
--- a/libio/libioP.h
+++ b/libio/libioP.h
@@ -138,8 +138,6 @@ extern "C" {
 #define JUMP1(FUNC, THIS, X1) (_IO_JUMPS_FUNC(THIS)->FUNC) (THIS, X1)
 #define JUMP2(FUNC, THIS, X1, X2) (_IO_JUMPS_FUNC(THIS)->FUNC) (THIS, X1, X2)
 #define JUMP3(FUNC, THIS, X1,X2,X3) (_IO_JUMPS_FUNC(THIS)->FUNC) (THIS, X1,X2, X3)
-#define JUMP_INIT(NAME, VALUE) VALUE
-#define JUMP_INIT_DUMMY JUMP_INIT(dummy, 0), JUMP_INIT (dummy2, 0)
 
 #define WJUMP0(FUNC, THIS) (_IO_WIDE_JUMPS_FUNC(THIS)->FUNC) (THIS)
 #define WJUMP1(FUNC, THIS, X1) (_IO_WIDE_JUMPS_FUNC(THIS)->FUNC) (THIS, X1)
@@ -485,19 +483,6 @@ extern int _IO_default_sync (_IO_FILE *) __THROW;
 extern int _IO_default_showmanyc (_IO_FILE *) __THROW;
 extern void _IO_default_imbue (_IO_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 const struct _IO_codecvt __libio_codecvt attribute_hidden;
 extern int _IO_do_write (_IO_FILE *, const char *, _IO_size_t);
 libc_hidden_proto (_IO_do_write)
@@ -890,3 +875,87 @@ _IO_acquire_lock_clear_flags2_fct (_IO_FILE **p)
                                           | _IO_FLAGS2_SCANF_STD);	      \
   } while (0)
 #endif
+
+/* Index into array of jump tables _IO_vtables.  */
+enum
+{
+  IO_VTABLE_file,
+  IO_VTABLE_file_mmap,
+  IO_VTABLE_file_maybe_mmap,
+  IO_VTABLE_wfile,
+  IO_VTABLE_wfile_mmap,
+  IO_VTABLE_wfile_maybe_mmap,
+  IO_VTABLE_mem,
+  IO_VTABLE_wmem,
+  IO_VTABLE_proc,
+  IO_VTABLE_str,
+  IO_VTABLE_str_chk,
+  IO_VTABLE_strn,
+  IO_VTABLE_wstr,
+  IO_VTABLE_wstrn,
+  IO_VTABLE_cookie,
+  IO_VTABLE_obstack,
+
+  /* Used in the implementation of vprintf.   */
+  IO_VTABLE_printf_helper,
+  IO_VTABLE_wprintf_helper,
+
+  /* Obsolete vtables. */
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+  IO_VTABLE_old_file,
+  IO_VTABLE_old_proc,
+  IO_VTABLE_old_cookie,
+#endif
+
+  /* Number of vtable array elements.  */
+  IO_VTABLE_COUNT
+};
+
+extern const struct _IO_jump_t _IO_vtables[IO_VTABLE_COUNT] attribute_hidden;
+
+/* Prototypes for functions used in vtables.  */
+
+int _IO_file_sync_mmap (_IO_FILE *fp) attribute_hidden;
+_IO_size_t _IO_file_xsgetn_mmap (_IO_FILE *fp, void *data, _IO_size_t n)
+  attribute_hidden;
+_IO_size_t _IO_file_xsgetn_maybe_mmap (_IO_FILE *fp, void *data, _IO_size_t n)
+  attribute_hidden;
+_IO_off64_t _IO_file_seekoff_maybe_mmap
+ (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) attribute_hidden;
+
+wint_t _IO_wfile_underflow_mmap (_IO_FILE *fp) attribute_hidden;
+wint_t _IO_wfile_underflow_maybe_mmap (_IO_FILE *fp) attribute_hidden;
+
+int _IO_mem_sync (_IO_FILE* fp) attribute_hidden;
+void _IO_mem_finish (_IO_FILE* fp, int) attribute_hidden;
+
+int _IO_wmem_sync (_IO_FILE* fp) attribute_hidden;
+void _IO_wmem_finish (_IO_FILE* fp, int) attribute_hidden;
+
+int _IO_str_chk_overflow (_IO_FILE *fp, int c) attribute_hidden;
+
+int _IO_strn_overflow (_IO_FILE *fp, int c) attribute_hidden;
+
+wint_t _IO_wstrn_overflow (_IO_FILE *fp, wint_t c) attribute_hidden;
+
+_IO_ssize_t _IO_cookie_read (_IO_FILE* fp, void* buf, _IO_ssize_t size)
+  attribute_hidden;
+_IO_ssize_t _IO_cookie_write (_IO_FILE* fp, const void* buf, _IO_ssize_t size)
+  attribute_hidden;
+_IO_off64_t _IO_cookie_seek (_IO_FILE *fp, _IO_off64_t offset, int dir)
+  attribute_hidden;
+_IO_off64_t _IO_cookie_seekoff (_IO_FILE *fp, _IO_off64_t offset,
+				int dir, int mode) attribute_hidden;
+int _IO_cookie_close (_IO_FILE* fp) attribute_hidden;
+
+int _IO_obstack_overflow (_IO_FILE *fp, int c) attribute_hidden;
+_IO_size_t _IO_obstack_xsputn (_IO_FILE *fp, const void *data, _IO_size_t n)
+  attribute_hidden;
+
+int _IO_printf_helper_overflow (_IO_FILE *s, int c) attribute_hidden;
+int _IO_wprintf_helper_overflow (_IO_FILE *s, int c) attribute_hidden;
+
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+_IO_off64_t _IO_old_cookie_seek (_IO_FILE *fp, _IO_off64_t offset,
+				 int dir) attribute_hidden;
+#endif
diff --git a/libio/memstream.c b/libio/memstream.c
index 7fa5245..42034fe 100644
--- a/libio/memstream.c
+++ b/libio/memstream.c
@@ -29,34 +29,6 @@ struct _IO_FILE_memstream
 };
 
 
-static int _IO_mem_sync (_IO_FILE* fp) __THROW;
-static void _IO_mem_finish (_IO_FILE* fp, int) __THROW;
-
-
-static const struct _IO_jump_t _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)
-};
-
 /* 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.  */
@@ -87,7 +59,7 @@ __open_memstream (char **bufloc, _IO_size_t *sizeloc)
       return NULL;
     }
   _IO_init (&new_f->fp._sf._sbf._f, 0);
-  _IO_JUMPS_FILE_plus (&new_f->fp._sf._sbf) = &_IO_mem_jumps;
+  _IO_JUMPS_FILE_plus (&new_f->fp._sf._sbf) = &_IO_vtables[IO_VTABLE_mem];
   _IO_str_init_static_internal (&new_f->fp._sf, buf, _IO_BUFSIZ, buf);
   new_f->fp._sf._sbf._f._flags &= ~_IO_USER_BUF;
   new_f->fp._sf._s._allocate_buffer = (_IO_alloc_type) malloc;
@@ -101,8 +73,7 @@ __open_memstream (char **bufloc, _IO_size_t *sizeloc)
 libc_hidden_def (__open_memstream)
 weak_alias (__open_memstream, open_memstream)
 
-
-static int
+int
 _IO_mem_sync (_IO_FILE *fp)
 {
   struct _IO_FILE_memstream *mp = (struct _IO_FILE_memstream *) fp;
@@ -121,8 +92,7 @@ _IO_mem_sync (_IO_FILE *fp)
   return 0;
 }
 
-
-static void
+void
 _IO_mem_finish (_IO_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 aa17b46..104dd61 100644
--- a/libio/obprintf.c
+++ b/libio/obprintf.c
@@ -36,7 +36,7 @@ struct _IO_obstack_file
 };
 
 
-static int
+int
 _IO_obstack_overflow (_IO_FILE *fp, int c)
 {
   struct obstack *obstack = ((struct _IO_obstack_file *) fp)->obstack;
@@ -59,7 +59,7 @@ _IO_obstack_overflow (_IO_FILE *fp, int c)
 }
 
 
-static _IO_size_t
+_IO_size_t
 _IO_obstack_xsputn (_IO_FILE *fp, const void *data, _IO_size_t n)
 {
   struct obstack *obstack = ((struct _IO_obstack_file *) fp)->obstack;
@@ -89,33 +89,6 @@ _IO_obstack_xsputn (_IO_FILE *fp, const void *data, _IO_size_t n)
   return n;
 }
 
-
-/* the jump table.  */
-const struct _IO_jump_t _IO_obstack_jumps 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
 _IO_obstack_vprintf (struct obstack *obstack, const char *format, va_list args)
 {
@@ -132,7 +105,7 @@ _IO_obstack_vprintf (struct obstack *obstack, const char *format, va_list args)
 #endif
 
   _IO_no_init (&new_f.ofile.file.file, _IO_USER_LOCK, -1, NULL, NULL);
-  _IO_JUMPS (&new_f.ofile.file) = &_IO_obstack_jumps;
+  _IO_JUMPS (&new_f.ofile.file) = &_IO_vtables[IO_VTABLE_obstack];
   room = obstack_room (obstack);
   size = obstack_object_size (obstack) + room;
   if (size == 0)
diff --git a/libio/oldfileops.c b/libio/oldfileops.c
index 4f3bdfe..3916d3b 100644
--- a/libio/oldfileops.c
+++ b/libio/oldfileops.c
@@ -744,29 +744,6 @@ _IO_old_file_xsputn (_IO_FILE *f, const void *data, _IO_size_t n)
   return n - to_do;
 }
 
-
-const struct _IO_jump_t _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)
-};
-
 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/oldiofdopen.c b/libio/oldiofdopen.c
index 33406ff..e7cf76d 100644
--- a/libio/oldiofdopen.c
+++ b/libio/oldiofdopen.c
@@ -111,7 +111,7 @@ _IO_old_fdopen (int fd, const char *mode)
   new_f->fp.file._file._lock = &new_f->lock;
 #endif
   _IO_old_init (&new_f->fp.file._file, 0);
-  _IO_JUMPS_FILE_plus (&new_f->fp) = &_IO_old_file_jumps;
+  _IO_JUMPS_FILE_plus (&new_f->fp) = &_IO_vtables[IO_VTABLE_old_file];
   _IO_old_file_init ((struct _IO_FILE_plus *) &new_f->fp);
 #if  !_IO_UNIFIED_JUMPTABLES
   new_f->fp.vtable = NULL;
diff --git a/libio/oldiofopen.c b/libio/oldiofopen.c
index cc7c342..4db8f90 100644
--- a/libio/oldiofopen.c
+++ b/libio/oldiofopen.c
@@ -50,7 +50,7 @@ _IO_old_fopen (const char *filename, const char *mode)
   new_f->fp.file._file._lock = &new_f->lock;
 #endif
   _IO_old_init (&new_f->fp.file._file, 0);
-  _IO_JUMPS_FILE_plus (&new_f->fp) = &_IO_old_file_jumps;
+  _IO_JUMPS_FILE_plus (&new_f->fp) = &_IO_vtables[IO_VTABLE_old_file];
   _IO_old_file_init ((struct _IO_FILE_plus *) &new_f->fp);
 #if  !_IO_UNIFIED_JUMPTABLES
   new_f->fp.vtable = NULL;
diff --git a/libio/oldiopopen.c b/libio/oldiopopen.c
index ea75b4f..2d8b9d4 100644
--- a/libio/oldiopopen.c
+++ b/libio/oldiopopen.c
@@ -210,7 +210,7 @@ _IO_old_popen (const char *command, const char *mode)
 #endif
   fp = &new_f->fpx.file.file._file;
   _IO_old_init (fp, 0);
-  _IO_JUMPS_FILE_plus (&new_f->fpx.file) = &_IO_old_proc_jumps;
+  _IO_JUMPS_FILE_plus (&new_f->fpx.file) = &_IO_vtables[IO_VTABLE_old_proc];
   _IO_old_file_init ((struct _IO_FILE_plus *) &new_f->fpx.file);
 #if  !_IO_UNIFIED_JUMPTABLES
   new_f->fpx.file.vtable = NULL;
@@ -267,29 +267,6 @@ _IO_old_proc_close (_IO_FILE *fp)
   return wstatus;
 }
 
-const struct _IO_jump_t _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)
-};
-
 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/oldstdfiles.c b/libio/oldstdfiles.c
index 609b7d9..b3845c7 100644
--- a/libio/oldstdfiles.c
+++ b/libio/oldstdfiles.c
@@ -40,11 +40,13 @@
 #define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
   static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \
   struct _IO_FILE_plus NAME \
-    = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), &_IO_old_file_jumps};
+    = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), \
+       &_IO_vtables[IO_VTABLE_old_file]};
 #else
 #define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
   struct _IO_FILE_plus NAME \
-    = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), &_IO_old_file_jumps};
+    = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), \
+       &_IO_vtables[IO_VTABLE_old_file]};
 #endif
 
 DEF_STDFILE(_IO_stdin_, 0, 0, _IO_NO_WRITES);
diff --git a/libio/stdfiles.c b/libio/stdfiles.c
index 1f583ed..a4bafd6 100644
--- a/libio/stdfiles.c
+++ b/libio/stdfiles.c
@@ -38,30 +38,30 @@
 #  define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
   static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \
   static struct _IO_wide_data _IO_wide_data_##FD \
-    = { ._wide_vtable = &_IO_wfile_jumps }; \
+    = { ._wide_vtable = &_IO_vtables[IO_VTABLE_wfile] }; \
   struct _IO_FILE_plus NAME \
     = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, &_IO_wide_data_##FD), \
-       &_IO_file_jumps};
+       &_IO_vtables[IO_VTABLE_file]};
 # else
 #  define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
   static _IO_lock_t _IO_stdfile_##FD##_lock = _IO_lock_initializer; \
   struct _IO_FILE_plus NAME \
     = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), \
-       &_IO_file_jumps};
+       &_IO_vtables[IO_VTABLE_file]};
 # endif
 #else
 # if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
 #  define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
   static struct _IO_wide_data _IO_wide_data_##FD \
-    = { ._wide_vtable = &_IO_wfile_jumps }; \
+    = { ._wide_vtable = &_IO_vtables[IO_VTABLE_wfile] }; \
   struct _IO_FILE_plus NAME \
     = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, &_IO_wide_data_##FD), \
-       &_IO_file_jumps};
+       &_IO_vtables[IO_VTABLE_file]};
 # else
 #  define DEF_STDFILE(NAME, FD, CHAIN, FLAGS) \
   struct _IO_FILE_plus NAME \
     = {FILEBUF_LITERAL(CHAIN, FLAGS, FD, NULL), \
-       &_IO_file_jumps};
+       &_IO_vtables[IO_VTABLE_file]};
 # endif
 #endif
 
diff --git a/libio/strfile.h b/libio/strfile.h
index f7ada8e..bd588d1 100644
--- a/libio/strfile.h
+++ b/libio/strfile.h
@@ -71,9 +71,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,5 +78,3 @@ typedef struct
      provided by the user.  */
   wchar_t overflow_buf[64];
 } _IO_wstrnfile;
-
-extern const struct _IO_jump_t _IO_wstrn_jumps attribute_hidden;
diff --git a/libio/strops.c b/libio/strops.c
index 0932d4c..8b68bff 100644
--- a/libio/strops.c
+++ b/libio/strops.c
@@ -322,27 +322,3 @@ _IO_str_finish (_IO_FILE *fp, int dummy)
 
   _IO_default_finish (fp, 0);
 }
-
-const struct _IO_jump_t _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)
-};
diff --git a/libio/vasprintf.c b/libio/vasprintf.c
index 7460f1e..f7517e6 100644
--- a/libio/vasprintf.c
+++ b/libio/vasprintf.c
@@ -51,7 +51,7 @@ _IO_vasprintf (char **result_ptr, const char *format, _IO_va_list args)
   sf._sbf._f._lock = NULL;
 #endif
   _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
-  _IO_JUMPS (&sf._sbf) = &_IO_str_jumps;
+  _IO_JUMPS (&sf._sbf) = &_IO_vtables[IO_VTABLE_str];
   _IO_str_init_static_internal (&sf, string, init_string_size, string);
   sf._sbf._f._flags &= ~_IO_USER_BUF;
   sf._s._allocate_buffer = (_IO_alloc_type) malloc;
diff --git a/libio/vsnprintf.c b/libio/vsnprintf.c
index f1063a1..4cad77d 100644
--- a/libio/vsnprintf.c
+++ b/libio/vsnprintf.c
@@ -27,9 +27,7 @@
 #include "libioP.h"
 #include "strfile.h"
 
-static int _IO_strn_overflow (_IO_FILE *fp, int c) __THROW;
-
-static int
+int
 _IO_strn_overflow (_IO_FILE *fp, int c)
 {
   /* When we come to here this means the user supplied buffer is
@@ -63,32 +61,6 @@ _IO_strn_overflow (_IO_FILE *fp, int c)
   return c;
 }
 
-
-const struct _IO_jump_t _IO_strn_jumps 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
 _IO_vsnprintf (char *string, _IO_size_t maxlen, const char *format,
 	       _IO_va_list args)
@@ -108,7 +80,7 @@ _IO_vsnprintf (char *string, _IO_size_t maxlen, const char *format,
     }
 
   _IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
-  _IO_JUMPS (&sf.f._sbf) = &_IO_strn_jumps;
+  _IO_JUMPS (&sf.f._sbf) = &_IO_vtables[IO_VTABLE_strn];
   string[0] = '\0';
   _IO_str_init_static_internal (&sf.f, string, maxlen - 1, string);
   ret = _IO_vfprintf (&sf.f._sbf._f, format, args);
diff --git a/libio/vswprintf.c b/libio/vswprintf.c
index b90441a..91e24db 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 (_IO_FILE *fp, wint_t c) __THROW;
-
-static wint_t
+wint_t
 _IO_wstrn_overflow (_IO_FILE *fp, wint_t c)
 {
   /* When we come to here this means the user supplied buffer is
@@ -62,32 +59,6 @@ _IO_wstrn_overflow (_IO_FILE *fp, wint_t c)
   return c;
 }
 
-
-const struct _IO_jump_t _IO_wstrn_jumps 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
 _IO_vswprintf (wchar_t *string, _IO_size_t maxlen, const wchar_t *format,
 	       _IO_va_list args)
@@ -104,7 +75,8 @@ _IO_vswprintf (wchar_t *string, _IO_size_t maxlen, const wchar_t *format,
        length of zero always makes the function fail.  */
     return -1;
 
-  _IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, 0, &wd, &_IO_wstrn_jumps);
+  _IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, 0, &wd,
+	       &_IO_vtables[IO_VTABLE_wstrn]);
   _IO_fwide (&sf.f._sbf._f, 1);
   string[0] = L'\0';
   _IO_wstr_init_static (&sf.f._sbf._f, string, maxlen - 1, string);
diff --git a/libio/vtables.c b/libio/vtables.c
new file mode 100644
index 0000000..fb5ee61
--- /dev/null
+++ b/libio/vtables.c
@@ -0,0 +1,574 @@
+/* Central definition of libio jump tables.
+   Copyright (C) 1995-2016 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.
+
+   As a special exception, if you link the code in this file with
+   files compiled with a GNU compiler to produce an executable,
+   that does not cause the resulting executable to be covered by
+   the GNU Lesser General Public License.  This exception does not
+   however invalidate any other reasons why the executable file
+   might be covered by the GNU Lesser General Public License.
+   This exception applies to code released by its copyright holders
+   in files containing the exception.  */
+
+#include "libioP.h"
+
+/* When linking statically, do not pull in the funcationality we do
+   not need.  This also avoids linknamespace issues.  The list of
+   symbols needs to be curated carefully, so that required symbols
+   only referenced through the vtable are always pulled in.  */
+#ifndef SHARED
+# pragma weak _IO_cookie_close
+# pragma weak _IO_cookie_read
+# pragma weak _IO_cookie_seek
+# pragma weak _IO_cookie_seekoff
+# pragma weak _IO_cookie_write
+# pragma weak _IO_mem_finish
+# pragma weak _IO_mem_sync
+# pragma weak _IO_new_proc_close
+# pragma weak _IO_obstack_overflow
+# pragma weak _IO_obstack_xsputn
+# pragma weak _IO_old_cookie_seek
+# pragma weak _IO_old_proc_close
+# pragma weak _IO_printf_helper_overflow
+# pragma weak _IO_wmem_finish
+# pragma weak _IO_wmem_sync
+# pragma weak _IO_wprintf_helper_overflow
+#endif
+
+/* We keep all jump tables in an array, so that we can verify jump
+   table pointers easily.  */
+
+#define JUMP_INIT(name, value) .__##name = value
+
+const struct _IO_jump_t _IO_vtables[] =
+  {
+    [IO_VTABLE_file] =
+    {
+      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_VTABLE_file_mmap] =
+    {
+      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_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_VTABLE_file_maybe_mmap] =
+    {
+      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_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_VTABLE_wfile] =
+    {
+      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_VTABLE_wfile_mmap] =
+    {
+      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_VTABLE_wfile_maybe_mmap] =
+    {
+      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_VTABLE_mem] =
+    {
+      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_VTABLE_wmem] =
+    {
+      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)
+    },
+
+    [IO_VTABLE_proc] =
+    {
+      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_VTABLE_str] =
+    {
+      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_VTABLE_str_chk] =
+    {
+      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_VTABLE_strn] =
+    {
+      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_VTABLE_wstr] =
+    {
+      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_VTABLE_wstrn] =
+    {
+      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_VTABLE_cookie] =
+    {
+      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_VTABLE_obstack] =
+    {
+      JUMP_INIT (overflow, _IO_obstack_overflow),
+      JUMP_INIT (xsputn, _IO_obstack_xsputn),
+    },
+
+    [IO_VTABLE_printf_helper] =
+    {
+      JUMP_INIT (finish, _IO_default_finish),
+      JUMP_INIT (overflow, _IO_printf_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),
+    },
+
+    [IO_VTABLE_wprintf_helper] =
+    {
+      JUMP_INIT (finish, _IO_wdefault_finish),
+      JUMP_INIT (overflow, _IO_wprintf_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),
+    },
+
+    /* Obsolete vtables.  */
+#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+    [IO_VTABLE_old_file] =
+    {
+      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_VTABLE_old_proc] =
+    {
+      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)
+    },
+
+    [IO_VTABLE_old_cookie] =
+    {
+      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
+  };
+
+
+/* These symbols need to be exported for backwards compatibility.
+   They are no longer used by glibc itself.  */
+
+#ifdef SHARED
+const struct _IO_jump_t _IO_file_jumps =
+{
+  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)
+};
+
+const struct _IO_jump_t _IO_wfile_jumps =
+{
+  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)
+};
+#endif
diff --git a/libio/wfileops.c b/libio/wfileops.c
index df1fbda..13cded4 100644
--- a/libio/wfileops.c
+++ b/libio/wfileops.c
@@ -349,7 +349,7 @@ _IO_wfile_underflow (_IO_FILE *fp)
 libc_hidden_def (_IO_wfile_underflow)
 
 
-static wint_t
+wint_t
 _IO_wfile_underflow_mmap (_IO_FILE *fp)
 {
   struct _IO_codecvt *cd;
@@ -410,7 +410,7 @@ _IO_wfile_underflow_mmap (_IO_FILE *fp)
   return WEOF;
 }
 
-static wint_t
+wint_t
 _IO_wfile_underflow_maybe_mmap (_IO_FILE *fp)
 {
   /* This is the first read attempt.  Doing the underflow will choose mmap
@@ -1040,78 +1040,3 @@ _IO_wfile_xsputn (_IO_FILE *f, const void *data, _IO_size_t n)
   return n - to_do;
 }
 libc_hidden_def (_IO_wfile_xsputn)
-
-
-const struct _IO_jump_t _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)
-};
-libc_hidden_data_def (_IO_wfile_jumps)
-
-
-const struct _IO_jump_t _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)
-};
-
-const struct _IO_jump_t _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)
-};
diff --git a/libio/wmemstream.c b/libio/wmemstream.c
index 1bdbae9..2e0b505 100644
--- a/libio/wmemstream.c
+++ b/libio/wmemstream.c
@@ -30,34 +30,6 @@ struct _IO_FILE_wmemstream
 };
 
 
-static int _IO_wmem_sync (_IO_FILE* fp) __THROW;
-static void _IO_wmem_finish (_IO_FILE* fp, int) __THROW;
-
-
-static const struct _IO_jump_t _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)
-};
-
 /* 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.  */
@@ -87,7 +59,8 @@ open_wmemstream (wchar_t **bufloc, _IO_size_t *sizeloc)
       free (new_f);
       return NULL;
     }
-  _IO_no_init (&new_f->fp._sf._sbf._f, 0, 0, &new_f->wd, &_IO_wmem_jumps);
+  _IO_no_init (&new_f->fp._sf._sbf._f, 0, 0, &new_f->wd,
+	       &_IO_vtables[IO_VTABLE_wmem]);
   _IO_fwide (&new_f->fp._sf._sbf._f, 1);
   _IO_wstr_init_static (&new_f->fp._sf._sbf._f, buf,
 			_IO_BUFSIZ / sizeof (wchar_t), buf);
@@ -101,8 +74,7 @@ open_wmemstream (wchar_t **bufloc, _IO_size_t *sizeloc)
   return (_IO_FILE *) &new_f->fp._sf._sbf;
 }
 
-
-static int
+int
 _IO_wmem_sync (_IO_FILE *fp)
 {
   struct _IO_FILE_wmemstream *mp = (struct _IO_FILE_wmemstream *) fp;
@@ -123,7 +95,7 @@ _IO_wmem_sync (_IO_FILE *fp)
 }
 
 
-static void
+void
 _IO_wmem_finish (_IO_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 8d0e1cb..6651615 100644
--- a/libio/wstrops.c
+++ b/libio/wstrops.c
@@ -331,27 +331,3 @@ _IO_wstr_finish (_IO_FILE *fp, int dummy)
 
   _IO_wdefault_finish (fp, 0);
 }
-
-const struct _IO_jump_t _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)
-};
diff --git a/stdio-common/isoc99_vsscanf.c b/stdio-common/isoc99_vsscanf.c
index 720f122..abb9e1d 100644
--- a/stdio-common/isoc99_vsscanf.c
+++ b/stdio-common/isoc99_vsscanf.c
@@ -37,7 +37,7 @@ __isoc99_vsscanf (const char *string, const char *format, _IO_va_list args)
   sf._sbf._f._lock = NULL;
 #endif
   _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
-  _IO_JUMPS (&sf._sbf) = &_IO_str_jumps;
+  _IO_JUMPS (&sf._sbf) = &_IO_vtables[IO_VTABLE_str];
   _IO_str_init_static_internal (&sf, (char*)string, 0, NULL);
   sf._sbf._f._flags2 |= _IO_FLAGS2_SCANF_STD;
   ret = _IO_vfscanf (&sf._sbf._f, format, args, NULL);
diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c
index f24020a..09da13c 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -2207,11 +2207,11 @@ struct helper_file
 #endif
   };
 
-static int
-_IO_helper_overflow (_IO_FILE *s, int c)
+#ifdef COMPILE_WPRINTF
+int
+_IO_wprintf_helper_overflow (_IO_FILE *s, int c)
 {
   _IO_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)
     {
@@ -2224,7 +2224,13 @@ _IO_helper_overflow (_IO_FILE *s, int c)
 		  used - written);
       s->_wide_data->_IO_write_ptr -= written;
     }
+  return PUTC (c, s);
+}
 #else
+int
+_IO_printf_helper_overflow (_IO_FILE *s, int c)
+{
+  _IO_FILE *target = ((struct helper_file*) s)->_put_stream;
   int used = s->_IO_write_ptr - s->_IO_write_base;
   if (used)
     {
@@ -2235,54 +2241,8 @@ _IO_helper_overflow (_IO_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 =
-{
-  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 =
-{
-  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
@@ -2318,7 +2278,11 @@ buffered_vfprintf (_IO_FILE *s, const CHAR_T *format,
   hp->_lock = NULL;
 #endif
   hp->_flags2 = s->_flags2;
-  _IO_JUMPS (&helper._f) = (struct _IO_jump_t *) &_IO_helper_jumps;
+#ifndef COMPILE_WPRINTF
+  _IO_JUMPS (&helper._f) = &_IO_vtables[IO_VTABLE_printf_helper];
+#else
+  _IO_JUMPS (&helper._f) = &_IO_vtables[IO_VTABLE_wprintf_helper];
+#endif
 
   /* Now print to helper instead.  */
 #ifndef COMPILE_WPRINTF
diff --git a/stdlib/strfmon_l.c b/stdlib/strfmon_l.c
index 5851a5b..d96f230 100644
--- a/stdlib/strfmon_l.c
+++ b/stdlib/strfmon_l.c
@@ -513,7 +513,7 @@ __vstrfmon_l (char *s, size_t maxsize, __locale_t loc, const char *format,
       f._sbf._f._lock = NULL;
 #endif
       _IO_init (&f._sbf._f, 0);
-      _IO_JUMPS (&f._sbf) = &_IO_str_jumps;
+      _IO_JUMPS (&f._sbf) = &_IO_vtables[IO_VTABLE_str];
       _IO_str_init_static_internal (&f, dest, (s + maxsize) - dest, dest);
       /* We clear the last available byte so we can find out whether
 	 the numeric representation is too long.  */
diff --git a/wcsmbs/isoc99_vswscanf.c b/wcsmbs/isoc99_vswscanf.c
index b7effb0..763891e 100644
--- a/wcsmbs/isoc99_vswscanf.c
+++ b/wcsmbs/isoc99_vswscanf.c
@@ -38,7 +38,8 @@ __isoc99_vswscanf (const wchar_t *string, const wchar_t *format,
 #ifdef _IO_MTSAFE_IO
   sf._sbf._f._lock = NULL;
 #endif
-  _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, 0, &wd, &_IO_wstr_jumps);
+  _IO_no_init (&sf._sbf._f, _IO_USER_LOCK, 0, &wd,
+	       &_IO_vtables[IO_VTABLE_wstr]);
   _IO_fwide (&sf._sbf._f, 1);
   _IO_wstr_init_static (&sf._sbf._f, (wchar_t *)string, 0, NULL);
   sf._sbf._f._flags2 |= _IO_FLAGS2_SCANF_STD;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]