5f7b84
commit 09e1b0e3f6facc1af2dbcfef204f0aaa8718772b
5f7b84
Author: Florian Weimer <fweimer@redhat.com>
5f7b84
Date:   Mon May 20 21:54:57 2019 +0200
5f7b84
5f7b84
    libio: Remove codecvt vtable [BZ #24588]
5f7b84
    
5f7b84
    The codecvt vtable is not a real vtable because it also contains the
5f7b84
    conversion state data.  Furthermore, wide stream support was added to
5f7b84
    GCC 3.0, after a C++ ABI bump, so there is no compatibility
5f7b84
    requirement with libstdc++.
5f7b84
    
5f7b84
    This change removes several unmangled function pointers which could
5f7b84
    be used with a corrupted FILE object to redirect execution.  (libio
5f7b84
    vtable verification did not cover the codecvt vtable.)
5f7b84
    
5f7b84
    Reviewed-by: Yann Droneaud <ydroneaud@opteya.com>
5f7b84
    Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
5f7b84
5f7b84
diff --git a/libio/fileops.c b/libio/fileops.c
5f7b84
index d2070a856e..daa5a05877 100644
5f7b84
--- a/libio/fileops.c
5f7b84
+++ b/libio/fileops.c
5f7b84
@@ -331,9 +331,6 @@ _IO_new_file_fopen (FILE *fp, const char *filename, const char *mode,
5f7b84
 
5f7b84
 	  cc = fp->_codecvt = &fp->_wide_data->_codecvt;
5f7b84
 
5f7b84
-	  /* The functions are always the same.  */
5f7b84
-	  *cc = __libio_codecvt;
5f7b84
-
5f7b84
 	  cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
5f7b84
 	  cc->__cd_in.__cd.__steps = fcts.towc;
5f7b84
 
5f7b84
diff --git a/libio/iofgetpos.c b/libio/iofgetpos.c
5f7b84
index 8032192440..388c4a0708 100644
5f7b84
--- a/libio/iofgetpos.c
5f7b84
+++ b/libio/iofgetpos.c
5f7b84
@@ -70,8 +70,7 @@ _IO_new_fgetpos (FILE *fp, __fpos_t *posp)
5f7b84
   else
5f7b84
     {
5f7b84
       posp->__pos = pos;
5f7b84
-      if (fp->_mode > 0
5f7b84
-	  && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0)
5f7b84
+      if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0)
5f7b84
 	/* This is a stateful encoding, safe the state.  */
5f7b84
 	posp->__state = fp->_wide_data->_IO_state;
5f7b84
     }
5f7b84
diff --git a/libio/iofgetpos64.c b/libio/iofgetpos64.c
5f7b84
index 54de6a8205..6a0ba50d29 100644
5f7b84
--- a/libio/iofgetpos64.c
5f7b84
+++ b/libio/iofgetpos64.c
5f7b84
@@ -54,8 +54,7 @@ _IO_new_fgetpos64 (FILE *fp, __fpos64_t *posp)
5f7b84
   else
5f7b84
     {
5f7b84
       posp->__pos = pos;
5f7b84
-      if (fp->_mode > 0
5f7b84
-	  && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0)
5f7b84
+      if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0)
5f7b84
 	/* This is a stateful encoding, safe the state.  */
5f7b84
 	posp->__state = fp->_wide_data->_IO_state;
5f7b84
     }
5f7b84
diff --git a/libio/iofsetpos.c b/libio/iofsetpos.c
5f7b84
index d7b1abbc61..4df1aae082 100644
5f7b84
--- a/libio/iofsetpos.c
5f7b84
+++ b/libio/iofsetpos.c
5f7b84
@@ -58,8 +58,7 @@ _IO_new_fsetpos (FILE *fp, const __fpos_t *posp)
5f7b84
   else
5f7b84
     {
5f7b84
       result = 0;
5f7b84
-      if (fp->_mode > 0
5f7b84
-	  && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0)
5f7b84
+      if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0)
5f7b84
 	/* This is a stateful encoding, restore the state.  */
5f7b84
 	fp->_wide_data->_IO_state = posp->__state;
5f7b84
     }
5f7b84
diff --git a/libio/iofsetpos64.c b/libio/iofsetpos64.c
5f7b84
index d1865b728e..f382ba0dc1 100644
5f7b84
--- a/libio/iofsetpos64.c
5f7b84
+++ b/libio/iofsetpos64.c
5f7b84
@@ -48,8 +48,7 @@ _IO_new_fsetpos64 (FILE *fp, const fpos64_t *posp)
5f7b84
   else
5f7b84
     {
5f7b84
       result = 0;
5f7b84
-      if (fp->_mode > 0
5f7b84
-	  && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0)
5f7b84
+      if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0)
5f7b84
 	/* This is a stateful encoding, safe the state.  */
5f7b84
 	fp->_wide_data->_IO_state = posp->__state;
5f7b84
     }
5f7b84
diff --git a/libio/iofwide.c b/libio/iofwide.c
5f7b84
index 247cfde3d0..80cb2d5074 100644
5f7b84
--- a/libio/iofwide.c
5f7b84
+++ b/libio/iofwide.c
5f7b84
@@ -39,44 +39,6 @@
5f7b84
 #include <sysdep.h>
5f7b84
 
5f7b84
 
5f7b84
-/* Prototypes of libio's codecvt functions.  */
5f7b84
-static enum __codecvt_result do_out (struct _IO_codecvt *codecvt,
5f7b84
-				     __mbstate_t *statep,
5f7b84
-				     const wchar_t *from_start,
5f7b84
-				     const wchar_t *from_end,
5f7b84
-				     const wchar_t **from_stop, char *to_start,
5f7b84
-				     char *to_end, char **to_stop);
5f7b84
-static enum __codecvt_result do_unshift (struct _IO_codecvt *codecvt,
5f7b84
-					 __mbstate_t *statep, char *to_start,
5f7b84
-					 char *to_end, char **to_stop);
5f7b84
-static enum __codecvt_result do_in (struct _IO_codecvt *codecvt,
5f7b84
-				    __mbstate_t *statep,
5f7b84
-				    const char *from_start,
5f7b84
-				    const char *from_end,
5f7b84
-				    const char **from_stop, wchar_t *to_start,
5f7b84
-				    wchar_t *to_end, wchar_t **to_stop);
5f7b84
-static int do_encoding (struct _IO_codecvt *codecvt);
5f7b84
-static int do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
5f7b84
-		      const char *from_start,
5f7b84
-		      const char *from_end, size_t max);
5f7b84
-static int do_max_length (struct _IO_codecvt *codecvt);
5f7b84
-static int do_always_noconv (struct _IO_codecvt *codecvt);
5f7b84
-
5f7b84
-
5f7b84
-/* The functions used in `codecvt' for libio are always the same.  */
5f7b84
-const struct _IO_codecvt __libio_codecvt =
5f7b84
-{
5f7b84
-  .__codecvt_destr = NULL,		/* Destructor, never used.  */
5f7b84
-  .__codecvt_do_out = do_out,
5f7b84
-  .__codecvt_do_unshift = do_unshift,
5f7b84
-  .__codecvt_do_in = do_in,
5f7b84
-  .__codecvt_do_encoding = do_encoding,
5f7b84
-  .__codecvt_do_always_noconv = do_always_noconv,
5f7b84
-  .__codecvt_do_length = do_length,
5f7b84
-  .__codecvt_do_max_length = do_max_length
5f7b84
-};
5f7b84
-
5f7b84
-
5f7b84
 /* Return orientation of stream.  If mode is nonzero try to change
5f7b84
    the orientation first.  */
5f7b84
 #undef _IO_fwide
5f7b84
@@ -118,9 +80,6 @@ _IO_fwide (FILE *fp, int mode)
5f7b84
 	assert (fcts.towc_nsteps == 1);
5f7b84
 	assert (fcts.tomb_nsteps == 1);
5f7b84
 
5f7b84
-	/* The functions are always the same.  */
5f7b84
-	*cc = __libio_codecvt;
5f7b84
-
5f7b84
 	cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
5f7b84
 	cc->__cd_in.__cd.__steps = fcts.towc;
5f7b84
 
5f7b84
@@ -150,11 +109,11 @@ _IO_fwide (FILE *fp, int mode)
5f7b84
 }
5f7b84
 
5f7b84
 
5f7b84
-static enum __codecvt_result
5f7b84
-do_out (struct _IO_codecvt *codecvt, __mbstate_t *statep,
5f7b84
-	const wchar_t *from_start, const wchar_t *from_end,
5f7b84
-	const wchar_t **from_stop, char *to_start, char *to_end,
5f7b84
-	char **to_stop)
5f7b84
+enum __codecvt_result
5f7b84
+__libio_codecvt_out (struct _IO_codecvt *codecvt, __mbstate_t *statep,
5f7b84
+		     const wchar_t *from_start, const wchar_t *from_end,
5f7b84
+		     const wchar_t **from_stop, char *to_start, char *to_end,
5f7b84
+		     char **to_stop)
5f7b84
 {
5f7b84
   enum __codecvt_result result;
5f7b84
 
5f7b84
@@ -202,57 +161,11 @@ do_out (struct _IO_codecvt *codecvt, __mbstate_t *statep,
5f7b84
 }
5f7b84
 
5f7b84
 
5f7b84
-static enum __codecvt_result
5f7b84
-do_unshift (struct _IO_codecvt *codecvt, __mbstate_t *statep,
5f7b84
-	    char *to_start, char *to_end, char **to_stop)
5f7b84
-{
5f7b84
-  enum __codecvt_result result;
5f7b84
-
5f7b84
-  struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps;
5f7b84
-  int status;
5f7b84
-  size_t dummy;
5f7b84
-
5f7b84
-  codecvt->__cd_out.__cd.__data[0].__outbuf = (unsigned char *) to_start;
5f7b84
-  codecvt->__cd_out.__cd.__data[0].__outbufend = (unsigned char *) to_end;
5f7b84
-  codecvt->__cd_out.__cd.__data[0].__statep = statep;
5f7b84
-
5f7b84
-  __gconv_fct fct = gs->__fct;
5f7b84
-#ifdef PTR_DEMANGLE
5f7b84
-  if (gs->__shlib_handle != NULL)
5f7b84
-    PTR_DEMANGLE (fct);
5f7b84
-#endif
5f7b84
-
5f7b84
-  status = DL_CALL_FCT (fct,
5f7b84
-			(gs, codecvt->__cd_out.__cd.__data, NULL, NULL,
5f7b84
-			 NULL, &dummy, 1, 0));
5f7b84
-
5f7b84
-  *to_stop = (char *) codecvt->__cd_out.__cd.__data[0].__outbuf;
5f7b84
-
5f7b84
-  switch (status)
5f7b84
-    {
5f7b84
-    case __GCONV_OK:
5f7b84
-    case __GCONV_EMPTY_INPUT:
5f7b84
-      result = __codecvt_ok;
5f7b84
-      break;
5f7b84
-
5f7b84
-    case __GCONV_FULL_OUTPUT:
5f7b84
-    case __GCONV_INCOMPLETE_INPUT:
5f7b84
-      result = __codecvt_partial;
5f7b84
-      break;
5f7b84
-
5f7b84
-    default:
5f7b84
-      result = __codecvt_error;
5f7b84
-      break;
5f7b84
-    }
5f7b84
-
5f7b84
-  return result;
5f7b84
-}
5f7b84
-
5f7b84
-
5f7b84
-static enum __codecvt_result
5f7b84
-do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep,
5f7b84
-       const char *from_start, const char *from_end, const char **from_stop,
5f7b84
-       wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop)
5f7b84
+enum __codecvt_result
5f7b84
+__libio_codecvt_in (struct _IO_codecvt *codecvt, __mbstate_t *statep,
5f7b84
+		    const char *from_start, const char *from_end,
5f7b84
+		    const char **from_stop,
5f7b84
+		    wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop)
5f7b84
 {
5f7b84
   enum __codecvt_result result;
5f7b84
 
5f7b84
@@ -300,8 +213,8 @@ do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep,
5f7b84
 }
5f7b84
 
5f7b84
 
5f7b84
-static int
5f7b84
-do_encoding (struct _IO_codecvt *codecvt)
5f7b84
+int
5f7b84
+__libio_codecvt_encoding (struct _IO_codecvt *codecvt)
5f7b84
 {
5f7b84
   /* See whether the encoding is stateful.  */
5f7b84
   if (codecvt->__cd_in.__cd.__steps[0].__stateful)
5f7b84
@@ -317,16 +230,10 @@ do_encoding (struct _IO_codecvt *codecvt)
5f7b84
 }
5f7b84
 
5f7b84
 
5f7b84
-static int
5f7b84
-do_always_noconv (struct _IO_codecvt *codecvt)
5f7b84
-{
5f7b84
-  return 0;
5f7b84
-}
5f7b84
-
5f7b84
-
5f7b84
-static int
5f7b84
-do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
5f7b84
-	   const char *from_start, const char *from_end, size_t max)
5f7b84
+int
5f7b84
+__libio_codecvt_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
5f7b84
+			const char *from_start, const char *from_end,
5f7b84
+			size_t max)
5f7b84
 {
5f7b84
   int result;
5f7b84
   const unsigned char *cp = (const unsigned char *) from_start;
5f7b84
@@ -353,10 +260,3 @@ do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
5f7b84
 
5f7b84
   return result;
5f7b84
 }
5f7b84
-
5f7b84
-
5f7b84
-static int
5f7b84
-do_max_length (struct _IO_codecvt *codecvt)
5f7b84
-{
5f7b84
-  return codecvt->__cd_in.__cd.__steps[0].__max_needed_from;
5f7b84
-}
5f7b84
diff --git a/libio/libio.h b/libio/libio.h
5f7b84
index c38095ff77..b985c386a2 100644
5f7b84
--- a/libio/libio.h
5f7b84
+++ b/libio/libio.h
5f7b84
@@ -116,40 +116,8 @@ struct _IO_marker {
5f7b84
   int _pos;
5f7b84
 };
5f7b84
 
5f7b84
-/* This is the structure from the libstdc++ codecvt class.  */
5f7b84
-enum __codecvt_result
5f7b84
-{
5f7b84
-  __codecvt_ok,
5f7b84
-  __codecvt_partial,
5f7b84
-  __codecvt_error,
5f7b84
-  __codecvt_noconv
5f7b84
-};
5f7b84
-
5f7b84
-/* The order of the elements in the following struct must match the order
5f7b84
-   of the virtual functions in the libstdc++ codecvt class.  */
5f7b84
 struct _IO_codecvt
5f7b84
 {
5f7b84
-  void (*__codecvt_destr) (struct _IO_codecvt *);
5f7b84
-  enum __codecvt_result (*__codecvt_do_out) (struct _IO_codecvt *,
5f7b84
-					     __mbstate_t *,
5f7b84
-					     const wchar_t *,
5f7b84
-					     const wchar_t *,
5f7b84
-					     const wchar_t **, char *,
5f7b84
-					     char *, char **);
5f7b84
-  enum __codecvt_result (*__codecvt_do_unshift) (struct _IO_codecvt *,
5f7b84
-						 __mbstate_t *, char *,
5f7b84
-						 char *, char **);
5f7b84
-  enum __codecvt_result (*__codecvt_do_in) (struct _IO_codecvt *,
5f7b84
-					    __mbstate_t *,
5f7b84
-					    const char *, const char *,
5f7b84
-					    const char **, wchar_t *,
5f7b84
-					    wchar_t *, wchar_t **);
5f7b84
-  int (*__codecvt_do_encoding) (struct _IO_codecvt *);
5f7b84
-  int (*__codecvt_do_always_noconv) (struct _IO_codecvt *);
5f7b84
-  int (*__codecvt_do_length) (struct _IO_codecvt *, __mbstate_t *,
5f7b84
-			      const char *, const char *, size_t);
5f7b84
-  int (*__codecvt_do_max_length) (struct _IO_codecvt *);
5f7b84
-
5f7b84
   _IO_iconv_t __cd_in;
5f7b84
   _IO_iconv_t __cd_out;
5f7b84
 };
5f7b84
diff --git a/libio/libioP.h b/libio/libioP.h
5f7b84
index 7bdec86a62..66afaa8968 100644
5f7b84
--- a/libio/libioP.h
5f7b84
+++ b/libio/libioP.h
5f7b84
@@ -476,7 +476,6 @@ extern const struct _IO_jump_t _IO_streambuf_jumps;
5f7b84
 extern const struct _IO_jump_t _IO_old_proc_jumps attribute_hidden;
5f7b84
 extern const struct _IO_jump_t _IO_str_jumps attribute_hidden;
5f7b84
 extern const struct _IO_jump_t _IO_wstr_jumps attribute_hidden;
5f7b84
-extern const struct _IO_codecvt __libio_codecvt attribute_hidden;
5f7b84
 extern int _IO_do_write (FILE *, const char *, size_t);
5f7b84
 libc_hidden_proto (_IO_do_write)
5f7b84
 extern int _IO_new_do_write (FILE *, const char *, size_t);
5f7b84
@@ -932,4 +931,32 @@ IO_validate_vtable (const struct _IO_jump_t *vtable)
5f7b84
   return vtable;
5f7b84
 }
5f7b84
 
5f7b84
+/* Character set conversion.  */
5f7b84
+
5f7b84
+enum __codecvt_result
5f7b84
+{
5f7b84
+  __codecvt_ok,
5f7b84
+  __codecvt_partial,
5f7b84
+  __codecvt_error,
5f7b84
+  __codecvt_noconv
5f7b84
+};
5f7b84
+
5f7b84
+enum __codecvt_result __libio_codecvt_out (struct _IO_codecvt *,
5f7b84
+					   __mbstate_t *,
5f7b84
+					   const wchar_t *,
5f7b84
+					   const wchar_t *,
5f7b84
+					   const wchar_t **, char *,
5f7b84
+					   char *, char **)
5f7b84
+  attribute_hidden;
5f7b84
+enum __codecvt_result __libio_codecvt_in (struct _IO_codecvt *,
5f7b84
+					  __mbstate_t *,
5f7b84
+					  const char *, const char *,
5f7b84
+					  const char **, wchar_t *,
5f7b84
+					  wchar_t *, wchar_t **)
5f7b84
+  attribute_hidden;
5f7b84
+int __libio_codecvt_encoding (struct _IO_codecvt *) attribute_hidden;
5f7b84
+int __libio_codecvt_length (struct _IO_codecvt *, __mbstate_t *,
5f7b84
+			    const char *, const char *, size_t)
5f7b84
+  attribute_hidden;
5f7b84
+
5f7b84
 #endif /* libioP.h.  */
5f7b84
diff --git a/libio/wfileops.c b/libio/wfileops.c
5f7b84
index 69fbb62a02..f1863db638 100644
5f7b84
--- a/libio/wfileops.c
5f7b84
+++ b/libio/wfileops.c
5f7b84
@@ -72,11 +72,11 @@ _IO_wdo_write (FILE *fp, const wchar_t *data, size_t to_do)
5f7b84
 	    }
5f7b84
 
5f7b84
 	  /* Now convert from the internal format into the external buffer.  */
5f7b84
-	  result = (*cc->__codecvt_do_out) (cc, &fp->_wide_data->_IO_state,
5f7b84
-					    data, data + to_do, &new_data,
5f7b84
-					    write_ptr,
5f7b84
-					    buf_end,
5f7b84
-					    &write_ptr);
5f7b84
+	  result = __libio_codecvt_out (cc, &fp->_wide_data->_IO_state,
5f7b84
+					data, data + to_do, &new_data,
5f7b84
+					write_ptr,
5f7b84
+					buf_end,
5f7b84
+					&write_ptr);
5f7b84
 
5f7b84
 	  /* Write out what we produced so far.  */
5f7b84
 	  if (_IO_new_do_write (fp, write_base, write_ptr - write_base) == EOF)
5f7b84
@@ -140,12 +140,12 @@ _IO_wfile_underflow (FILE *fp)
5f7b84
       fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
5f7b84
       fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr =
5f7b84
 	fp->_wide_data->_IO_buf_base;
5f7b84
-      status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state,
5f7b84
-				       fp->_IO_read_ptr, fp->_IO_read_end,
5f7b84
-				       &read_stop,
5f7b84
-				       fp->_wide_data->_IO_read_ptr,
5f7b84
-				       fp->_wide_data->_IO_buf_end,
5f7b84
-				       &fp->_wide_data->_IO_read_end);
5f7b84
+      status = __libio_codecvt_in (cd, &fp->_wide_data->_IO_state,
5f7b84
+				   fp->_IO_read_ptr, fp->_IO_read_end,
5f7b84
+				   &read_stop,
5f7b84
+				   fp->_wide_data->_IO_read_ptr,
5f7b84
+				   fp->_wide_data->_IO_buf_end,
5f7b84
+				   &fp->_wide_data->_IO_read_end);
5f7b84
 
5f7b84
       fp->_IO_read_base = fp->_IO_read_ptr;
5f7b84
       fp->_IO_read_ptr = (char *) read_stop;
5f7b84
@@ -266,11 +266,11 @@ _IO_wfile_underflow (FILE *fp)
5f7b84
       naccbuf += to_copy;
5f7b84
       from = accbuf;
5f7b84
     }
5f7b84
-  status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state,
5f7b84
-				   from, to, &read_ptr_copy,
5f7b84
-				   fp->_wide_data->_IO_read_end,
5f7b84
-				   fp->_wide_data->_IO_buf_end,
5f7b84
-				   &fp->_wide_data->_IO_read_end);
5f7b84
+  status = __libio_codecvt_in (cd, &fp->_wide_data->_IO_state,
5f7b84
+			       from, to, &read_ptr_copy,
5f7b84
+			       fp->_wide_data->_IO_read_end,
5f7b84
+			       fp->_wide_data->_IO_buf_end,
5f7b84
+			       &fp->_wide_data->_IO_read_end);
5f7b84
 
5f7b84
   if (__glibc_unlikely (naccbuf != 0))
5f7b84
     fp->_IO_read_ptr += MAX (0, read_ptr_copy - &accbuf[naccbuf - to_copy]);
5f7b84
@@ -372,12 +372,12 @@ _IO_wfile_underflow_mmap (FILE *fp)
5f7b84
   fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
5f7b84
   fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr =
5f7b84
     fp->_wide_data->_IO_buf_base;
5f7b84
-  (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state,
5f7b84
-			  fp->_IO_read_ptr, fp->_IO_read_end,
5f7b84
-			  &read_stop,
5f7b84
-			  fp->_wide_data->_IO_read_ptr,
5f7b84
-			  fp->_wide_data->_IO_buf_end,
5f7b84
-			  &fp->_wide_data->_IO_read_end);
5f7b84
+  __libio_codecvt_in (cd, &fp->_wide_data->_IO_state,
5f7b84
+		      fp->_IO_read_ptr, fp->_IO_read_end,
5f7b84
+		      &read_stop,
5f7b84
+		      fp->_wide_data->_IO_read_ptr,
5f7b84
+		      fp->_wide_data->_IO_buf_end,
5f7b84
+		      &fp->_wide_data->_IO_read_end);
5f7b84
 
5f7b84
   fp->_IO_read_ptr = (char *) read_stop;
5f7b84
 
5f7b84
@@ -495,7 +495,7 @@ _IO_wfile_sync (FILE *fp)
5f7b84
       struct _IO_codecvt *cv = fp->_codecvt;
5f7b84
       off64_t new_pos;
5f7b84
 
5f7b84
-      int clen = (*cv->__codecvt_do_encoding) (cv);
5f7b84
+      int clen = __libio_codecvt_encoding (cv);
5f7b84
 
5f7b84
       if (clen > 0)
5f7b84
 	/* It is easy, a fixed number of input bytes are used for each
5f7b84
@@ -511,9 +511,9 @@ _IO_wfile_sync (FILE *fp)
5f7b84
 	  size_t wnread = (fp->_wide_data->_IO_read_ptr
5f7b84
 			   - fp->_wide_data->_IO_read_base);
5f7b84
 	  fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
5f7b84
-	  nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state,
5f7b84
-					      fp->_IO_read_base,
5f7b84
-					      fp->_IO_read_end, wnread);
5f7b84
+	  nread = __libio_codecvt_length (cv, &fp->_wide_data->_IO_state,
5f7b84
+					  fp->_IO_read_base,
5f7b84
+					  fp->_IO_read_end, wnread);
5f7b84
 	  fp->_IO_read_ptr = fp->_IO_read_base + nread;
5f7b84
 	  delta = -(fp->_IO_read_end - fp->_IO_read_base - nread);
5f7b84
 	}
5f7b84
@@ -548,7 +548,7 @@ adjust_wide_data (FILE *fp, bool do_convert)
5f7b84
 {
5f7b84
   struct _IO_codecvt *cv = fp->_codecvt;
5f7b84
 
5f7b84
-  int clen = (*cv->__codecvt_do_encoding) (cv);
5f7b84
+  int clen = __libio_codecvt_encoding (cv);
5f7b84
 
5f7b84
   /* Take the easy way out for constant length encodings if we don't need to
5f7b84
      convert.  */
5f7b84
@@ -565,12 +565,12 @@ adjust_wide_data (FILE *fp, bool do_convert)
5f7b84
     {
5f7b84
 
5f7b84
       fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
5f7b84
-      status = (*cv->__codecvt_do_in) (cv, &fp->_wide_data->_IO_state,
5f7b84
-				       fp->_IO_read_base, fp->_IO_read_ptr,
5f7b84
-				       &read_stop,
5f7b84
-				       fp->_wide_data->_IO_read_base,
5f7b84
-				       fp->_wide_data->_IO_buf_end,
5f7b84
-				       &fp->_wide_data->_IO_read_end);
5f7b84
+      status = __libio_codecvt_in (cv, &fp->_wide_data->_IO_state,
5f7b84
+				   fp->_IO_read_base, fp->_IO_read_ptr,
5f7b84
+				   &read_stop,
5f7b84
+				   fp->_wide_data->_IO_read_base,
5f7b84
+				   fp->_wide_data->_IO_buf_end,
5f7b84
+				   &fp->_wide_data->_IO_read_end);
5f7b84
 
5f7b84
       /* Should we return EILSEQ?  */
5f7b84
       if (__glibc_unlikely (status == __codecvt_error))
5f7b84
@@ -648,7 +648,7 @@ do_ftell_wide (FILE *fp)
5f7b84
 	}
5f7b84
 
5f7b84
       struct _IO_codecvt *cv = fp->_codecvt;
5f7b84
-      int clen = (*cv->__codecvt_do_encoding) (cv);
5f7b84
+      int clen = __libio_codecvt_encoding (cv);
5f7b84
 
5f7b84
       if (!unflushed_writes)
5f7b84
 	{
5f7b84
@@ -663,9 +663,9 @@ do_ftell_wide (FILE *fp)
5f7b84
 
5f7b84
 	      size_t delta = wide_read_ptr - wide_read_base;
5f7b84
 	      __mbstate_t state = fp->_wide_data->_IO_last_state;
5f7b84
-	      nread = (*cv->__codecvt_do_length) (cv, &state,
5f7b84
-						  fp->_IO_read_base,
5f7b84
-						  fp->_IO_read_end, delta);
5f7b84
+	      nread = __libio_codecvt_length (cv, &state,
5f7b84
+					      fp->_IO_read_base,
5f7b84
+					      fp->_IO_read_end, delta);
5f7b84
 	      offset -= fp->_IO_read_end - fp->_IO_read_base - nread;
5f7b84
 	    }
5f7b84
 	}
5f7b84
@@ -688,9 +688,8 @@ do_ftell_wide (FILE *fp)
5f7b84
 	      enum __codecvt_result status;
5f7b84
 
5f7b84
 	      __mbstate_t state = fp->_wide_data->_IO_last_state;
5f7b84
-	      status = (*cv->__codecvt_do_out) (cv, &state,
5f7b84
-						in, in + delta, &in,
5f7b84
-						out, out + outsize, &outstop);
5f7b84
+	      status = __libio_codecvt_out (cv, &state, in, in + delta, &in,
5f7b84
+					    out, out + outsize, &outstop);
5f7b84
 
5f7b84
 	      /* We don't check for __codecvt_partial because it can be
5f7b84
 		 returned on one of two conditions: either the output
5f7b84
@@ -801,7 +800,7 @@ _IO_wfile_seekoff (FILE *fp, off64_t offset, int dir, int mode)
5f7b84
 	 find out which position in the external buffer corresponds to
5f7b84
 	 the current position in the internal buffer.  */
5f7b84
       cv = fp->_codecvt;
5f7b84
-      clen = (*cv->__codecvt_do_encoding) (cv);
5f7b84
+      clen = __libio_codecvt_encoding (cv);
5f7b84
 
5f7b84
       if (mode != 0 || !was_writing)
5f7b84
 	{
5f7b84
@@ -819,10 +818,10 @@ _IO_wfile_seekoff (FILE *fp, off64_t offset, int dir, int mode)
5f7b84
 	      delta = (fp->_wide_data->_IO_read_ptr
5f7b84
 		       - fp->_wide_data->_IO_read_base);
5f7b84
 	      fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
5f7b84
-	      nread = (*cv->__codecvt_do_length) (cv,
5f7b84
-						  &fp->_wide_data->_IO_state,
5f7b84
-						  fp->_IO_read_base,
5f7b84
-						  fp->_IO_read_end, delta);
5f7b84
+	      nread = __libio_codecvt_length (cv,
5f7b84
+					      &fp->_wide_data->_IO_state,
5f7b84
+					      fp->_IO_read_base,
5f7b84
+					      fp->_IO_read_end, delta);
5f7b84
 	      fp->_IO_read_ptr = fp->_IO_read_base + nread;
5f7b84
 	      fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr;
5f7b84
 	      offset -= fp->_IO_read_end - fp->_IO_read_base - nread;