| 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> |
| |
| diff -uNrp glibc-2.19/debug/obprintf_chk.c glibc-2.19/debug/obprintf_chk.c |
| --- a/glibc-2.19/debug/obprintf_chk.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/debug/obprintf_chk.c 2012-01-05 12:08:38.135675971 -0800 |
| @@ -56,7 +56,7 @@ __obstack_vprintf_chk (struct obstack *o |
| #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 -uNrp glibc-2.19/debug/vasprintf_chk.c glibc-2.19/debug/vasprintf_chk.c |
| --- a/glibc-2.19/debug/vasprintf_chk.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/debug/vasprintf_chk.c 2012-01-05 12:08:38.135675971 -0800 |
| @@ -54,7 +54,7 @@ __vasprintf_chk (char **result_ptr, int |
| 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 -uNrp glibc-2.19/debug/vdprintf_chk.c glibc-2.19/debug/vdprintf_chk.c |
| --- a/glibc-2.19/debug/vdprintf_chk.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/debug/vdprintf_chk.c 2012-01-05 12:08:38.135675971 -0800 |
| @@ -40,7 +40,7 @@ __vdprintf_chk (int d, int flags, const |
| 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 -uNrp glibc-2.19/debug/vsnprintf_chk.c glibc-2.19/debug/vsnprintf_chk.c |
| --- a/glibc-2.19/debug/vsnprintf_chk.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/debug/vsnprintf_chk.c 2012-01-05 12:08:38.135675971 -0800 |
| @@ -53,7 +53,7 @@ ___vsnprintf_chk (char *s, size_t maxlen |
| } |
| |
| _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 -uNrp glibc-2.19/debug/vsprintf_chk.c glibc-2.19/debug/vsprintf_chk.c |
| --- a/glibc-2.19/debug/vsprintf_chk.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/debug/vsprintf_chk.c 2012-01-05 12:08:38.135675971 -0800 |
| @@ -75,7 +75,7 @@ ___vsprintf_chk (char *s, int flags, siz |
| __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 -uNrp glibc-2.19/libio/fileops.c glibc-2.19/libio/fileops.c |
| --- a/glibc-2.19/libio/fileops.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/libio/fileops.c 2012-01-05 12:08:38.139676023 -0800 |
| @@ -464,8 +464,8 @@ _IO_file_setbuf_mmap (fp, p, len) |
| _IO_FILE *result; |
| |
| /* Change the function table. */ |
| - _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps; |
| - fp->_wide_data->_wide_vtable = &_IO_wfile_jumps; |
| + _IO_JUMPS_SET ((struct _IO_FILE_plus *) 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); |
| @@ -473,8 +473,8 @@ _IO_file_setbuf_mmap (fp, p, len) |
| /* If the call failed, restore to using mmap. */ |
| if (result == NULL) |
| { |
| - _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps_mmap; |
| - fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap; |
| + _IO_JUMPS_SET ((struct _IO_FILE_plus *) fp, &_IO_file_jumps_mmap); |
| + _IO_WIDE_JUMPS_SET (fp, &_IO_wfile_jumps_mmap); |
| } |
| |
| return result; |
| @@ -713,10 +713,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 ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps; |
| + _IO_JUMPS_SET ((struct _IO_FILE_plus *) fp, &_IO_file_jumps); |
| else |
| - _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps; |
| - fp->_wide_data->_wide_vtable = &_IO_wfile_jumps; |
| + _IO_JUMPS_SET ((struct _IO_FILE_plus *) fp, &_IO_wfile_jumps); |
| + _IO_WIDE_JUMPS_SET (fp, &_IO_wfile_jumps); |
| |
| return 1; |
| } |
| @@ -793,10 +793,10 @@ decide_maybe_mmap (_IO_FILE *fp) |
| fp->_offset = st.st_size; |
| |
| if (fp->_mode <= 0) |
| - _IO_JUMPS ((struct _IO_FILE_plus *)fp) = &_IO_file_jumps_mmap; |
| + _IO_JUMPS_SET ((struct _IO_FILE_plus *)fp, &_IO_file_jumps_mmap); |
| else |
| - _IO_JUMPS ((struct _IO_FILE_plus *)fp) = &_IO_wfile_jumps_mmap; |
| - fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap; |
| + _IO_JUMPS_SET ((struct _IO_FILE_plus *)fp, &_IO_wfile_jumps_mmap); |
| + _IO_WIDE_JUMPS_SET (fp, &_IO_wfile_jumps_mmap); |
| |
| return; |
| } |
| @@ -806,10 +806,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 ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps; |
| + _IO_JUMPS_SET ((struct _IO_FILE_plus *) fp, &_IO_file_jumps); |
| else |
| - _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps; |
| - fp->_wide_data->_wide_vtable = &_IO_wfile_jumps; |
| + _IO_JUMPS_SET ((struct _IO_FILE_plus *) fp, &_IO_wfile_jumps); |
| + _IO_WIDE_JUMPS_SET (fp, &_IO_wfile_jumps); |
| } |
| |
| int |
| diff -uNrp glibc-2.19/libio/freopen64.c glibc-2.19/libio/freopen64.c |
| --- a/glibc-2.19/libio/freopen64.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/libio/freopen64.c 2012-01-05 12:09:59.188744539 -0800 |
| @@ -51,9 +51,9 @@ freopen64 (filename, mode, fp) |
| ? fd_to_filename (fd) : filename); |
| fp->_flags2 |= _IO_FLAGS2_NOCLOSE; |
| _IO_file_close_it (fp); |
| - _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps; |
| + _IO_JUMPS_SET ((struct _IO_FILE_plus *) 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 -uNrp glibc-2.19/libio/freopen.c glibc-2.19/libio/freopen.c |
| --- a/glibc-2.19/libio/freopen.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/libio/freopen.c 2012-01-05 12:11:29.601936735 -0800 |
| @@ -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 ((struct _IO_FILE_plus *) fp) = &_IO_old_file_jumps; |
| + _IO_JUMPS_SET ((struct _IO_FILE_plus *) fp, &_IO_old_file_jumps); |
| result = _IO_old_file_fopen (fp, gfilename, mode); |
| } |
| else |
| #endif |
| { |
| _IO_file_close_it (fp); |
| - _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps; |
| + _IO_JUMPS_SET ((struct _IO_FILE_plus *) 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 -uNrp glibc-2.19/libio/genops.c glibc-2.19/libio/genops.c |
| --- a/glibc-2.19/libio/genops.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/libio/genops.c 2012-01-05 12:08:38.139676023 -0800 |
| @@ -664,7 +664,7 @@ _IO_no_init (fp, flags, orientation, wd, |
| 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); |
| } |
| #endif |
| fp->_freeres_list = NULL; |
| diff -uNrp glibc-2.19/libio/iofdopen.c glibc-2.19/libio/iofdopen.c |
| --- a/glibc-2.19/libio/iofdopen.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/libio/iofdopen.c 2012-01-05 12:08:38.139676023 -0800 |
| @@ -154,11 +154,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 -uNrp glibc-2.19/libio/iofopen.c glibc-2.19/libio/iofopen.c |
| --- a/glibc-2.19/libio/iofopen.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/libio/iofopen.c 2012-01-05 12:08:38.139676023 -0800 |
| @@ -50,10 +50,10 @@ __fopen_maybe_mmap (fp) |
| vanilla file operations and reset the jump table accordingly. */ |
| |
| if (fp->_mode <= 0) |
| - _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_file_jumps_maybe_mmap; |
| + _IO_JUMPS_SET ((struct _IO_FILE_plus *) fp, &_IO_file_jumps_maybe_mmap); |
| else |
| - _IO_JUMPS ((struct _IO_FILE_plus *) fp) = &_IO_wfile_jumps_maybe_mmap; |
| - fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_maybe_mmap; |
| + _IO_JUMPS_SET ((struct _IO_FILE_plus *) fp, &_IO_wfile_jumps_maybe_mmap); |
| + _IO_WIDE_JUMPS_SET (fp, &_IO_wfile_jumps_maybe_mmap); |
| } |
| #endif |
| return fp; |
| @@ -85,7 +85,7 @@ __fopen_internal (filename, mode, 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 -uNrp glibc-2.19/libio/iofopncook.c glibc-2.19/libio/iofopncook.c |
| --- a/glibc-2.19/libio/iofopncook.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/libio/iofopncook.c 2012-01-05 12:08:38.139676023 -0800 |
| @@ -147,7 +147,7 @@ _IO_cookie_init (struct _IO_cookie_file |
| 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; |
| @@ -272,7 +272,7 @@ _IO_old_fopencookie (cookie, mode, io_fu |
| |
| ret = _IO_fopencookie (cookie, mode, io_functions); |
| if (ret != NULL) |
| - _IO_JUMPS ((struct _IO_FILE_plus *) ret) = &_IO_old_cookie_jumps; |
| + _IO_JUMPS_SET ((struct _IO_FILE_plus *) ret, &_IO_old_cookie_jumps); |
| |
| return ret; |
| } |
| diff -uNrp glibc-2.19/libio/iopopen.c glibc-2.19/libio/iopopen.c |
| --- a/glibc-2.19/libio/iopopen.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/libio/iopopen.c 2012-01-05 12:08:38.139676023 -0800 |
| @@ -304,7 +304,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 -uNrp glibc-2.19/libio/iovdprintf.c glibc-2.19/libio/iovdprintf.c |
| --- a/glibc-2.19/libio/iovdprintf.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/libio/iovdprintf.c 2012-01-05 12:08:38.139676023 -0800 |
| @@ -43,7 +43,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 -uNrp glibc-2.19/libio/iovsprintf.c glibc-2.19/libio/iovsprintf.c |
| --- a/glibc-2.19/libio/iovsprintf.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/libio/iovsprintf.c 2012-01-05 12:08:38.139676023 -0800 |
| @@ -38,7 +38,7 @@ __IO_vsprintf (char *string, const char |
| 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 = INTUSE(_IO_vfprintf) (&sf._sbf._f, format, args); |
| _IO_putc_unlocked ('\0', &sf._sbf._f); |
| diff -uNrp glibc-2.19/libio/iovsscanf.c glibc-2.19/libio/iovsscanf.c |
| --- a/glibc-2.19/libio/iovsscanf.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/libio/iovsscanf.c 2012-01-05 12:08:38.139676023 -0800 |
| @@ -40,7 +40,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 = INTUSE(_IO_vfscanf) (&sf._sbf._f, format, args, NULL); |
| return ret; |
| diff -uNrp glibc-2.19/libio/libioP.h glibc-2.19/libio/libioP.h |
| --- a/glibc-2.19/libio/libioP.h 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/libio/libioP.h 2012-01-05 12:13:24.243448752 -0800 |
| @@ -74,11 +74,11 @@ extern "C" { |
| * 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 |
| + * 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 a 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 |
| @@ -102,20 +102,40 @@ extern "C" { |
| # define _IO_JUMPS_OFFSET 1 |
| #endif |
| |
| -#define _IO_JUMPS(THIS) (THIS)->vtable |
| -#define _IO_WIDE_JUMPS(THIS) ((struct _IO_FILE *) (THIS))->_wide_data->_wide_vtable |
| +static inline void |
| +__mangle_vtable(const struct _IO_jump_t **vtable, const struct _IO_jump_t *table) |
| +{ |
| + struct _IO_jump_t *ptr; |
| + ptr = (struct _IO_jump_t *)table; |
| + PTR_MANGLE(ptr); |
| + *vtable = ptr; |
| +} |
| + |
| +#define _IO_JUMPS_RAW(THIS) (THIS)->vtable |
| +#define _IO_JUMPS_SET(THIS, TABLE) __mangle_vtable(&_IO_JUMPS_RAW(THIS), (TABLE)) |
| +#define _IO_WIDE_JUMPS_RAW(THIS) ((struct _IO_FILE *) (THIS))->_wide_data->_wide_vtable |
| +#define _IO_WIDE_JUMPS_SET(THIS, TABLE) __mangle_vtable(&_IO_WIDE_JUMPS_RAW(THIS), (TABLE)) |
| #define _IO_CHECK_WIDE(THIS) (((struct _IO_FILE *) (THIS))->_wide_data != NULL) |
| |
| +static inline const struct _IO_jump_t * |
| +__demangle_vtable(const struct _IO_jump_t *vtable) |
| +{ |
| + struct _IO_jump_t *ptr; |
| + 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 ((struct _IO_FILE_plus *) (THIS)) \ |
| - + (THIS)->_vtable_offset)) |
| +# define _IO_JUMPS_FUNC(THIS) __demangle_vtable (\ |
| + (*(struct _IO_jump_t **) ((void *) &_IO_JUMPS_RAW ((struct _IO_FILE_plus *) (THIS)) \ |
| + + (THIS)->_vtable_offset))) |
| # define _IO_vtable_offset(THIS) (THIS)->_vtable_offset |
| #else |
| -# define _IO_JUMPS_FUNC(THIS) _IO_JUMPS ((struct _IO_FILE_plus *) (THIS)) |
| +# define _IO_JUMPS_FUNC(THIS) __demangle_vtable (_IO_JUMPS_RAW ((struct _IO_FILE_plus *) (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 -uNrp glibc-2.19/libio/memstream.c glibc-2.19/libio/memstream.c |
| --- a/glibc-2.19/libio/memstream.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/libio/memstream.c 2012-01-05 12:08:38.139676023 -0800 |
| @@ -87,7 +87,7 @@ open_memstream (bufloc, sizeloc) |
| return NULL; |
| } |
| _IO_init (&new_f->fp._sf._sbf._f, 0); |
| - _IO_JUMPS ((struct _IO_FILE_plus *) &new_f->fp._sf._sbf) = &_IO_mem_jumps; |
| + _IO_JUMPS_SET ((struct _IO_FILE_plus *) &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 -uNrp glibc-2.19/libio/obprintf.c glibc-2.19/libio/obprintf.c |
| --- a/glibc-2.19/libio/obprintf.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/libio/obprintf.c 2012-01-05 12:08:38.139676023 -0800 |
| @@ -136,7 +136,7 @@ _IO_obstack_vprintf (struct obstack *obs |
| #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 -uNrp glibc-2.19/libio/oldiofdopen.c glibc-2.19/libio/oldiofdopen.c |
| --- a/glibc-2.19/libio/oldiofdopen.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/libio/oldiofdopen.c 2012-01-05 12:08:38.139676023 -0800 |
| @@ -117,7 +117,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 ((struct _IO_FILE_plus *) &new_f->fp) = &_IO_old_file_jumps; |
| + _IO_JUMPS_SET ((struct _IO_FILE_plus *) &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 -uNrp glibc-2.19/libio/oldiofopen.c glibc-2.19/libio/oldiofopen.c |
| --- a/glibc-2.19/libio/oldiofopen.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/libio/oldiofopen.c 2012-01-05 12:08:38.139676023 -0800 |
| @@ -56,7 +56,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 ((struct _IO_FILE_plus *) &new_f->fp) = &_IO_old_file_jumps; |
| + _IO_JUMPS_SET ((struct _IO_FILE_plus *) &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 -uNrp glibc-2.19/libio/oldiopopen.c glibc-2.19/libio/oldiopopen.c |
| --- a/glibc-2.19/libio/oldiopopen.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/libio/oldiopopen.c 2012-01-05 12:08:38.139676023 -0800 |
| @@ -225,7 +225,7 @@ _IO_old_popen (command, mode) |
| #endif |
| fp = &new_f->fpx.file.file._file; |
| _IO_old_init (fp, 0); |
| - _IO_JUMPS ((struct _IO_FILE_plus *) &new_f->fpx.file) = &_IO_old_proc_jumps; |
| + _IO_JUMPS_SET ((struct _IO_FILE_plus *) &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 -uNrp glibc-2.19/libio/vasprintf.c glibc-2.19/libio/vasprintf.c |
| --- a/glibc-2.19/libio/vasprintf.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/libio/vasprintf.c 2012-01-05 12:08:38.139676023 -0800 |
| @@ -56,7 +56,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 -uNrp glibc-2.19/libio/vsnprintf.c glibc-2.19/libio/vsnprintf.c |
| --- a/glibc-2.19/libio/vsnprintf.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/libio/vsnprintf.c 2012-01-05 12:08:38.139676023 -0800 |
| @@ -114,7 +114,7 @@ _IO_vsnprintf (string, maxlen, format, a |
| } |
| |
| _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 = INTUSE(_IO_vfprintf) (&sf.f._sbf._f, format, args); |
| diff -uNrp glibc-2.19/misc/init-misc.c glibc-2.19/misc/init-misc.c |
| --- a/glibc-2.19/misc/init-misc.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/misc/init-misc.c 2012-01-05 12:13:44.995722496 -0800 |
| @@ -17,7 +17,11 @@ |
| Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA |
| 02111-1307 USA. */ |
| |
| +#include "libioP.h" |
| + |
| #include <string.h> |
| +#include <stdio.h> |
| +#include <sysdep.h> |
| #include <libc-internal.h> |
| |
| char *__progname_full = (char *) ""; |
| @@ -38,4 +42,13 @@ __init_misc (int argc, char **argv, char |
| __progname = p + 1; |
| __progname_full = argv[0]; |
| } |
| + |
| + PTR_MANGLE (_IO_JUMPS_RAW ((struct _IO_FILE_plus *)stdin)); |
| + PTR_MANGLE (_IO_WIDE_JUMPS_RAW (stdin)); |
| + |
| + PTR_MANGLE (_IO_JUMPS_RAW ((struct _IO_FILE_plus *)stdout)); |
| + PTR_MANGLE (_IO_WIDE_JUMPS_RAW (stdout)); |
| + |
| + PTR_MANGLE (_IO_JUMPS_RAW ((struct _IO_FILE_plus *)stderr)); |
| + PTR_MANGLE (_IO_WIDE_JUMPS_RAW (stderr)); |
| } |
| diff -uNrp glibc-2.19/stdio-common/isoc99_vsscanf.c glibc-2.19/stdio-common/isoc99_vsscanf.c |
| --- a/glibc-2.19/stdio-common/isoc99_vsscanf.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/stdio-common/isoc99_vsscanf.c 2012-01-05 12:08:38.139676023 -0800 |
| @@ -38,7 +38,7 @@ __isoc99_vsscanf (const char *string, co |
| 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 = INTUSE(_IO_vfscanf) (&sf._sbf._f, format, args, NULL); |
| diff -uNrp glibc-2.19/stdio-common/vfprintf.c glibc-2.19/stdio-common/vfprintf.c |
| --- a/glibc-2.19/stdio-common/vfprintf.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/stdio-common/vfprintf.c 2012-01-05 12:08:38.139676023 -0800 |
| @@ -2224,7 +2224,7 @@ buffered_vfprintf (register _IO_FILE *s, |
| 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 -uNrp glibc-2.19/stdlib/strfmon_l.c glibc-2.19/stdlib/strfmon_l.c |
| --- a/glibc-2.19/stdlib/strfmon_l.c 2009-12-08 12:10:20.000000000 -0800 |
| +++ b/glibc-2.19/stdlib/strfmon_l.c 2012-01-05 12:08:38.143676076 -0800 |
| @@ -517,7 +517,7 @@ __vstrfmon_l (char *s, size_t maxsize, _ |
| 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. */ |
| |