blob: e74f7dac36d6939ab83d21556319995662e5eaf1 [file] [log] [blame]
upstream has merged a diff fix for glibc-2.24 and newer, so we can drop this after glibc-2.23:
https://sourceware.org/git/?p=glibc.git;a=commit;h=db3476aff19b75c4fdefbe65fcd5f0a90588ba51
Description: use PTR_MANGLE/PTR_DEMANGLE for FILE vtables. This adds inline
functions to run the PTR_MANGLE at vtable assignment time and PTR_DEMANGLE
at vtable dereference time so that the FILE structure's stored vtable
pointer is not in the clear on the heap. To make sure nothing accidentally
uses _IO_JUMPS or _IO_WIDE_JUMPS directly, the macros have been renamed to
include the _RAW suffix.
Author: Kees Cook <keescook@chromium.org>
2015-08-12 Kees Cook <keescook@chromium.org>
* libio/libioP.h: Create inline helpers to run the PTR_MANGLE and
PTR_DEMANGLE routines on vtable pointers. Create _IO_JUMPS_SET and
_IO_WIDE_JUMPS_SET macros to use the new inline helpers. Update the
_IO_JUMPS_FUNC and _IO_WIDE_JUMPS_FUNC to use the new inline helpers.
* debug/obprintf_chk.c: Replace direct vtable assignment with macro.
* debug/vasprintf_chk.c: Likewise.
* debug/vdprintf_chk.c: Likewise.
* debug/vsnprintf_chk.c: Likewise.
* debug/vsprintf_chk.c: Likewise.
* libio/fileops.c: Likewise.
* libio/freopen.c: Likewise.
* libio/freopen64.c: Likewise.
* libio/genops.c: Likewise.
* libio/iofdopen.c: Likewise.
* libio/iofopen.c: Likewise.
* libio/iofopncook.c: Likewise.
* libio/iofwide.c: Likewise.
* libio/iopopen.c: Likewise.
* libio/iovdprintf.c: Likewise.
* libio/iovsprintf.c: Likewise.
* libio/iovsscanf.c: Likewise.
* libio/memstream.c: Likewise.
* libio/obprintf.c: Likewise.
* libio/oldiofdopen.c: Likewise.
* libio/oldiofopen.c: Likewise.
* libio/oldiopopen.c: Likewise.
* libio/vasprintf.c: Likewise.
* libio/vsnprintf.c: Likewise.
* stdio-common/isoc99_vsscanf.c: Likewise.
* stdio-common/vfprintf.c: Likewise.
* stdlib/strfmon_l.c: Likewise.
* misc/init-misc.c: Mangle predefined stdio FILE vtables at startup.
---
debug/obprintf_chk.c | 2 +-
debug/vasprintf_chk.c | 2 +-
debug/vdprintf_chk.c | 2 +-
debug/vsnprintf_chk.c | 2 +-
debug/vsprintf_chk.c | 2 +-
libio/fileops.c | 28 +++++++++----------
libio/freopen.c | 6 ++---
libio/freopen64.c | 4 +--
libio/genops.c | 2 +-
libio/iofdopen.c | 4 +--
libio/iofopen.c | 8 +++---
libio/iofopncook.c | 4 +--
libio/iofwide.c | 2 +-
libio/iopopen.c | 2 +-
libio/iovdprintf.c | 2 +-
libio/iovsprintf.c | 2 +-
libio/iovsscanf.c | 2 +-
libio/libioP.h | 62 ++++++++++++++++++++++++++++++-------------
libio/memstream.c | 2 +-
libio/obprintf.c | 2 +-
libio/oldiofdopen.c | 2 +-
libio/oldiofopen.c | 2 +-
libio/oldiopopen.c | 2 +-
libio/vasprintf.c | 2 +-
libio/vsnprintf.c | 2 +-
misc/init-misc.c | 13 +++++++++
stdio-common/isoc99_vsscanf.c | 2 +-
stdio-common/vfprintf.c | 2 +-
stdlib/strfmon_l.c | 2 +-
29 files changed, 104 insertions(+), 67 deletions(-)
diff --git a/debug/obprintf_chk.c b/debug/obprintf_chk.c
index c49d1e9..203b403 100644
--- a/debug/obprintf_chk.c
+++ b/debug/obprintf_chk.c
@@ -54,7 +54,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_SET (&new_f.ofile.file, &_IO_obstack_jumps);
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 8ecb9e8..4779836 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_SET (&sf._sbf, &_IO_str_jumps);
_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 bf43ed8..eb86c0b 100644
--- a/debug/vdprintf_chk.c
+++ b/debug/vdprintf_chk.c
@@ -38,7 +38,7 @@ __vdprintf_chk (int d, int flags, const char *format, va_list arg)
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_JUMPS_SET (&tmpfil, &_IO_file_jumps);
_IO_file_init (&tmpfil);
#if !_IO_UNIFIED_JUMPTABLES
tmpfil.vtable = NULL;
diff --git a/debug/vsnprintf_chk.c b/debug/vsnprintf_chk.c
index c6cb383..5b09121 100644
--- a/debug/vsnprintf_chk.c
+++ b/debug/vsnprintf_chk.c
@@ -51,7 +51,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_SET (&sf.f._sbf, &_IO_strn_jumps);
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 1ec67b5..3805788 100644
--- a/debug/vsprintf_chk.c
+++ b/debug/vsprintf_chk.c
@@ -73,7 +73,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_SET (&f._sbf, &_IO_str_chk_jumps);
s[0] = '\0';
_IO_str_init_static_internal (&f, s, slen - 1, s);
diff --git a/libio/fileops.c b/libio/fileops.c
index cbcd6f5..1bfe883 100644
--- a/libio/fileops.c
+++ b/libio/fileops.c
@@ -414,7 +414,7 @@ _IO_new_file_fopen (_IO_FILE *fp, const char *filename, const char *mode,
&result->_wide_data->_IO_state;
/* From now on use the wide character callback functions. */
- _IO_JUMPS_FILE_plus (fp) = fp->_wide_data->_wide_vtable;
+ _IO_JUMPS_FILE_plus_SET (fp, _IO_WIDE_JUMPS_FUNC (fp));
/* Set the mode now. */
result->_mode = 1;
@@ -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_SET (fp, &_IO_file_jumps);
+ _IO_WIDE_JUMPS_SET (fp, &_IO_wfile_jumps);
/* 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_SET (fp, &_IO_file_jumps_mmap);
+ _IO_WIDE_JUMPS_SET (fp, &_IO_wfile_jumps_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_SET (fp, &_IO_file_jumps);
else
- _IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps;
- fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
+ _IO_JUMPS_FILE_plus_SET (fp, &_IO_wfile_jumps);
+ _IO_WIDE_JUMPS_SET (fp, &_IO_wfile_jumps);
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_SET (fp, &_IO_file_jumps_mmap);
else
- _IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps_mmap;
- fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap;
+ _IO_JUMPS_FILE_plus_SET (fp, &_IO_wfile_jumps_mmap);
+ _IO_WIDE_JUMPS_SET (fp, &_IO_wfile_jumps_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_SET (fp, &_IO_file_jumps);
else
- _IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps;
- fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
+ _IO_JUMPS_FILE_plus_SET (fp, &_IO_wfile_jumps);
+ _IO_WIDE_JUMPS_SET (fp, &_IO_wfile_jumps);
}
int
diff --git a/libio/freopen.c b/libio/freopen.c
index 035fa1f..a9203fd 100644
--- a/libio/freopen.c
+++ b/libio/freopen.c
@@ -59,16 +59,16 @@ freopen (filename, mode, 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_SET (fp, &_IO_old_file_jumps);
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_SET (fp, &_IO_file_jumps);
if (_IO_vtable_offset (fp) == 0 && fp->_wide_data != NULL)
- fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
+ _IO_WIDE_JUMPS_SET (fp, &_IO_wfile_jumps);
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 fc6ccb1..eb883d6 100644
--- a/libio/freopen64.c
+++ b/libio/freopen64.c
@@ -50,9 +50,9 @@ freopen64 (filename, mode, 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_SET (fp, &_IO_file_jumps);
if (_IO_vtable_offset (fp) == 0 && fp->_wide_data != NULL)
- fp->_wide_data->_wide_vtable = &_IO_wfile_jumps;
+ _IO_WIDE_JUMPS_SET (fp, &_IO_wfile_jumps);
result = _IO_file_fopen (fp, gfilename, mode, 0);
fp->_flags2 &= ~_IO_FLAGS2_NOCLOSE;
if (result != NULL)
diff --git a/libio/genops.c b/libio/genops.c
index 45c9d41..acf7b79 100644
--- a/libio/genops.c
+++ b/libio/genops.c
@@ -662,7 +662,7 @@ _IO_no_init (fp, flags, orientation, wd, jmp)
fp->_wide_data->_IO_backup_base = NULL;
fp->_wide_data->_IO_save_end = NULL;
- fp->_wide_data->_wide_vtable = jmp;
+ _IO_WIDE_JUMPS_SET (fp, jmp);
}
else
/* Cause predictable crash when a wide function is called on a byte
diff --git a/libio/iofdopen.c b/libio/iofdopen.c
index e7d84ae..d272568 100644
--- a/libio/iofdopen.c
+++ b/libio/iofdopen.c
@@ -150,11 +150,11 @@ _IO_new_fdopen (fd, mode)
? &_IO_wfile_jumps_maybe_mmap :
#endif
&_IO_wfile_jumps);
- _IO_JUMPS (&new_f->fp) =
+ _IO_JUMPS_SET (&new_f->fp,
#ifdef _G_HAVE_MMAP
(use_mmap && (read_write & _IO_NO_WRITES)) ? &_IO_file_jumps_maybe_mmap :
#endif
- &_IO_file_jumps;
+ &_IO_file_jumps);
_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 be2bbb6..2d9fc41 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_SET (fp, &_IO_file_jumps_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_SET (fp, &_IO_wfile_jumps_maybe_mmap);
+ _IO_WIDE_JUMPS_SET (fp, &_IO_wfile_jumps_maybe_mmap);
}
#endif
return fp;
@@ -78,7 +78,7 @@ __fopen_internal (const char *filename, const char *mode, int is32)
#else
_IO_no_init (&new_f->fp.file, 1, 0, NULL, NULL);
#endif
- _IO_JUMPS (&new_f->fp) = &_IO_file_jumps;
+ _IO_JUMPS_SET (&new_f->fp, &_IO_file_jumps);
_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 978a7fa..76285a5 100644
--- a/libio/iofopncook.c
+++ b/libio/iofopncook.c
@@ -145,7 +145,7 @@ _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_SET (&cfile->__fp, &_IO_cookie_jumps);
cfile->__cookie = cookie;
cfile->__io_functions = io_functions;
@@ -270,7 +270,7 @@ _IO_old_fopencookie (cookie, mode, io_functions)
ret = _IO_fopencookie (cookie, mode, io_functions);
if (ret != NULL)
- _IO_JUMPS_FILE_plus (ret) = &_IO_old_cookie_jumps;
+ _IO_JUMPS_FILE_plus_SET (ret, &_IO_old_cookie_jumps);
return ret;
}
diff --git a/libio/iofwide.c b/libio/iofwide.c
index 0c175d1..8d1c39a 100644
--- a/libio/iofwide.c
+++ b/libio/iofwide.c
@@ -184,7 +184,7 @@ _IO_fwide (fp, mode)
#endif
/* From now on use the wide character callback functions. */
- _IO_JUMPS_FILE_plus (fp) = fp->_wide_data->_wide_vtable;
+ _IO_JUMPS_FILE_plus_SET (fp, _IO_WIDE_JUMPS_FUNC (fp));
}
/* Set the mode now. */
diff --git a/libio/iopopen.c b/libio/iopopen.c
index 53da776..b19e62f 100644
--- a/libio/iopopen.c
+++ b/libio/iopopen.c
@@ -293,7 +293,7 @@ _IO_new_popen (command, mode)
#endif
fp = &new_f->fpx.file.file;
_IO_init (fp, 0);
- _IO_JUMPS (&new_f->fpx.file) = &_IO_proc_jumps;
+ _IO_JUMPS_SET (&new_f->fpx.file, &_IO_proc_jumps);
_IO_new_file_init (&new_f->fpx.file);
#if !_IO_UNIFIED_JUMPTABLES
new_f->fpx.file.vtable = NULL;
diff --git a/libio/iovdprintf.c b/libio/iovdprintf.c
index 116912a..e449443 100644
--- a/libio/iovdprintf.c
+++ b/libio/iovdprintf.c
@@ -41,7 +41,7 @@ _IO_vdprintf (d, format, arg)
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_JUMPS_SET (&tmpfil, &_IO_file_jumps);
_IO_file_init (&tmpfil);
#if !_IO_UNIFIED_JUMPTABLES
tmpfil.vtable = NULL;
diff --git a/libio/iovsprintf.c b/libio/iovsprintf.c
index b6cc6b3..e624b29 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_SET (&sf._sbf, &_IO_str_jumps);
_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 c4fbd1b..35330e2 100644
--- a/libio/iovsscanf.c
+++ b/libio/iovsscanf.c
@@ -39,7 +39,7 @@ _IO_vsscanf (string, format, 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_SET (&sf._sbf, &_IO_str_jumps);
_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/libioP.h b/libio/libioP.h
index b1ca774..ddcd2c9 100644
--- a/libio/libioP.h
+++ b/libio/libioP.h
@@ -70,17 +70,16 @@ extern "C" {
/* THE JUMPTABLE FUNCTIONS.
- * The _IO_FILE type is used to implement the FILE type in GNU libc,
- * as well as the streambuf class in GNU iostreams for C++.
- * These are all the same, just used differently.
- * An _IO_FILE (or FILE) object is allows followed by a pointer to
- * a jump table (of pointers to functions). The pointer is accessed
- * with the _IO_JUMPS macro. The jump table has an eccentric format,
- * so as to be compatible with the layout of a C++ virtual function table.
- * (as implemented by g++). When a pointer to a streambuf object is
- * coerced to an (_IO_FILE*), then _IO_JUMPS on the result just
- * happens to point to the virtual function table of the streambuf.
- * Thus the _IO_JUMPS function table used for C stdio/libio does
+ * The _IO_FILE type is used to implement the FILE type in GNU libc, as well
+ * as the streambuf class in GNU iostreams for C++. These are all the same,
+ * just used differently. An _IO_FILE (or FILE) object is allows followed by
+ * a pointer to a jump table (of pointers to functions). The pointer is
+ * accessed with the _IO_JUMPS_SET and _IO_JUMPS_FUNC macros. The jump table
+ * has an eccentric format, so as to be compatible with the layout of a C++
+ * virtual function table. (as implemented by g++). When a pointer to a
+ * streambuf object is coerced to an (_IO_FILE*), then _IO_JUMPS on the
+ * result just happens to point to the virtual function table of the
+ * streambuf. Thus the _IO_JUMPS function table used for C stdio/libio does
* double duty as the virtual function table for C++ streambuf.
*
* The entries in the _IO_JUMPS function table (and hence also the
@@ -106,6 +105,14 @@ extern "C" {
# define _IO_JUMPS_OFFSET 0
#endif
+static inline void
+__mangle_vtable(const struct _IO_jump_t **vtable, const struct _IO_jump_t *table)
+{
+ struct _IO_jump_t *ptr = (struct _IO_jump_t *)table;
+ PTR_MANGLE (ptr);
+ *vtable = ptr;
+}
+
/* Type of MEMBER in struct type TYPE. */
#define _IO_MEMBER_TYPE(TYPE, MEMBER) __typeof__ (((TYPE){}).MEMBER)
@@ -115,24 +122,41 @@ extern "C" {
(*(_IO_MEMBER_TYPE (TYPE, MEMBER) *)(((char *) (THIS)) \
+ offsetof(TYPE, MEMBER)))
-#define _IO_JUMPS(THIS) (THIS)->vtable
-#define _IO_JUMPS_FILE_plus(THIS) \
+#define _IO_JUMPS_RAW(THIS) (THIS)->vtable
+#define _IO_JUMPS_SET(THIS, TABLE) \
+ __mangle_vtable (&_IO_JUMPS_RAW (THIS), (TABLE))
+
+#define _IO_JUMPS_FILE_plus_RAW(THIS) \
_IO_CAST_FIELD_ACCESS ((THIS), struct _IO_FILE_plus, vtable)
-#define _IO_WIDE_JUMPS(THIS) \
+#define _IO_JUMPS_FILE_plus_SET(THIS, TABLE) \
+ __mangle_vtable (&_IO_JUMPS_FILE_plus_RAW (THIS), (TABLE))
+
+#define _IO_WIDE_JUMPS_RAW(THIS) \
_IO_CAST_FIELD_ACCESS ((THIS), struct _IO_FILE, _wide_data)->_wide_vtable
+#define _IO_WIDE_JUMPS_SET(THIS, TABLE) \
+ __mangle_vtable (&_IO_WIDE_JUMPS_RAW (THIS), (TABLE))
+
#define _IO_CHECK_WIDE(THIS) \
(_IO_CAST_FIELD_ACCESS ((THIS), struct _IO_FILE, _wide_data) != NULL)
+static inline const struct _IO_jump_t *
+__demangle_vtable(const struct _IO_jump_t *vtable)
+{
+ struct _IO_jump_t *ptr = (struct _IO_jump_t *)vtable;
+ PTR_DEMANGLE (ptr);
+ return (const struct _IO_jump_t *)ptr;
+}
+
#if _IO_JUMPS_OFFSET
-# define _IO_JUMPS_FUNC(THIS) \
- (*(struct _IO_jump_t **) ((void *) &_IO_JUMPS_FILE_plus (THIS) \
- + (THIS)->_vtable_offset))
+# define _IO_JUMPS_FUNC(THIS) __demangle_vtable (\
+ (*(struct _IO_jump_t **) ((void *) &_IO_JUMPS_FILE_plus_RAW (THIS) \
+ + (THIS)->_vtable_offset)))
# define _IO_vtable_offset(THIS) (THIS)->_vtable_offset
#else
-# define _IO_JUMPS_FUNC(THIS) _IO_JUMPS_FILE_plus (THIS)
+# define _IO_JUMPS_FUNC(THIS) __demangle_vtable (_IO_JUMPS_FILE_plus_RAW (THIS))
# define _IO_vtable_offset(THIS) 0
#endif
-#define _IO_WIDE_JUMPS_FUNC(THIS) _IO_WIDE_JUMPS(THIS)
+#define _IO_WIDE_JUMPS_FUNC(THIS) __demangle_vtable (_IO_WIDE_JUMPS_RAW (THIS))
#define JUMP_FIELD(TYPE, NAME) TYPE NAME
#define JUMP0(FUNC, THIS) (_IO_JUMPS_FUNC(THIS)->FUNC) (THIS)
#define JUMP1(FUNC, THIS, X1) (_IO_JUMPS_FUNC(THIS)->FUNC) (THIS, X1)
diff --git a/libio/memstream.c b/libio/memstream.c
index 84742d1..640740e 100644
--- a/libio/memstream.c
+++ b/libio/memstream.c
@@ -89,7 +89,7 @@ __open_memstream (bufloc, 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_SET (&new_f->fp._sf._sbf, &_IO_mem_jumps);
_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;
diff --git a/libio/obprintf.c b/libio/obprintf.c
index d61de6a..b166362 100644
--- a/libio/obprintf.c
+++ b/libio/obprintf.c
@@ -132,7 +132,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_SET (&new_f.ofile.file, &_IO_obstack_jumps);
room = obstack_room (obstack);
size = obstack_object_size (obstack) + room;
if (size == 0)
diff --git a/libio/oldiofdopen.c b/libio/oldiofdopen.c
index e068ec7..5a571b5 100644
--- a/libio/oldiofdopen.c
+++ b/libio/oldiofdopen.c
@@ -113,7 +113,7 @@ _IO_old_fdopen (fd, 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_SET (&new_f->fp, &_IO_old_file_jumps);
_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 a90a601..0b27b00 100644
--- a/libio/oldiofopen.c
+++ b/libio/oldiofopen.c
@@ -52,7 +52,7 @@ _IO_old_fopen (filename, 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_SET (&new_f->fp, &_IO_old_file_jumps);
_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 fb4c7b8..9d0b817 100644
--- a/libio/oldiopopen.c
+++ b/libio/oldiopopen.c
@@ -215,7 +215,7 @@ _IO_old_popen (command, 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_SET (&new_f->fpx.file, &_IO_old_proc_jumps);
_IO_old_file_init ((struct _IO_FILE_plus *) &new_f->fpx.file);
#if !_IO_UNIFIED_JUMPTABLES
new_f->fpx.file.vtable = NULL;
diff --git a/libio/vasprintf.c b/libio/vasprintf.c
index 7f9c105..96e1d73 100644
--- a/libio/vasprintf.c
+++ b/libio/vasprintf.c
@@ -54,7 +54,7 @@ _IO_vasprintf (result_ptr, format, 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_SET (&sf._sbf, &_IO_str_jumps);
_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 e2752d8..66f03cf 100644
--- a/libio/vsnprintf.c
+++ b/libio/vsnprintf.c
@@ -113,7 +113,7 @@ _IO_vsnprintf (string, maxlen, format, args)
}
_IO_no_init (&sf.f._sbf._f, _IO_USER_LOCK, -1, NULL, NULL);
- _IO_JUMPS (&sf.f._sbf) = &_IO_strn_jumps;
+ _IO_JUMPS_SET (&sf.f._sbf, &_IO_strn_jumps);
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/misc/init-misc.c b/misc/init-misc.c
index 9254f02..bcf26a2 100644
--- a/misc/init-misc.c
+++ b/misc/init-misc.c
@@ -16,7 +16,11 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+#include "libioP.h"
+
#include <string.h>
+#include <stdio.h>
+#include <sysdep.h>
#include <libc-internal.h>
char *__progname_full = (char *) "";
@@ -37,4 +41,13 @@ __init_misc (int argc, char **argv, char **envp)
__progname = p + 1;
__progname_full = argv[0];
}
+
+ PTR_MANGLE (_IO_JUMPS_FILE_plus_RAW (stdin));
+ PTR_MANGLE (_IO_WIDE_JUMPS_RAW (stdin));
+
+ PTR_MANGLE (_IO_JUMPS_FILE_plus_RAW (stdout));
+ PTR_MANGLE (_IO_WIDE_JUMPS_RAW (stdout));
+
+ PTR_MANGLE (_IO_JUMPS_FILE_plus_RAW (stderr));
+ PTR_MANGLE (_IO_WIDE_JUMPS_RAW (stderr));
}
diff --git a/stdio-common/isoc99_vsscanf.c b/stdio-common/isoc99_vsscanf.c
index dadd125..513e065 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_SET (&sf._sbf, &_IO_str_jumps);
_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 5e408d2..5940887 100644
--- a/stdio-common/vfprintf.c
+++ b/stdio-common/vfprintf.c
@@ -2343,7 +2343,7 @@ 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;
+ _IO_JUMPS_SET (&helper._f, (struct _IO_jump_t *) &_IO_helper_jumps);
/* Now print to helper instead. */
#ifndef COMPILE_WPRINTF
diff --git a/stdlib/strfmon_l.c b/stdlib/strfmon_l.c
index 3fae78b..ba734da 100644
--- a/stdlib/strfmon_l.c
+++ b/stdlib/strfmon_l.c
@@ -516,7 +516,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_SET (&f._sbf, &_IO_str_jumps);
_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. */
--
1.9.1