diff options
Diffstat (limited to 'libvtv/testsuite/other-tests')
-rw-r--r-- | libvtv/testsuite/other-tests/Makefile.am | 52 | ||||
-rw-r--r-- | libvtv/testsuite/other-tests/Makefile.in | 379 | ||||
-rw-r--r-- | libvtv/testsuite/other-tests/README | 8 | ||||
-rw-r--r-- | libvtv/testsuite/other-tests/dlopen.cc | 38 | ||||
-rw-r--r-- | libvtv/testsuite/other-tests/dlopen_mt.cc | 112 | ||||
-rw-r--r-- | libvtv/testsuite/other-tests/environment-fail-32.s | 514 | ||||
-rw-r--r-- | libvtv/testsuite/other-tests/environment-fail-64.s | 425 | ||||
-rw-r--r-- | libvtv/testsuite/other-tests/field-test.cc | 94 | ||||
-rw-r--r-- | libvtv/testsuite/other-tests/replace-fail.cc | 11 | ||||
-rw-r--r-- | libvtv/testsuite/other-tests/so.cc | 93 | ||||
-rw-r--r-- | libvtv/testsuite/other-tests/temp_deriv.cc | 67 | ||||
-rw-r--r-- | libvtv/testsuite/other-tests/temp_deriv2.cc | 69 | ||||
-rw-r--r-- | libvtv/testsuite/other-tests/temp_deriv3.cc | 79 |
13 files changed, 1941 insertions, 0 deletions
diff --git a/libvtv/testsuite/other-tests/Makefile.am b/libvtv/testsuite/other-tests/Makefile.am new file mode 100644 index 00000000000..56f76a79f5b --- /dev/null +++ b/libvtv/testsuite/other-tests/Makefile.am @@ -0,0 +1,52 @@ +## Makefile for the testsuite subdirectory of the VTV library. +## +## Copyright (C) 2013 Free Software Foundation, Inc. +## +## Process this file with automake to produce Makefile.in. +## +## This file is part of the Vtable Verification (VTV) Library. This +## library is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3, or (at your option) +## any later version. + +## This 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 +## General Public License for more details. + +## You should have received a copy of the GNU General Public License +## along with this library; see the file COPYING3. If not see +## <http://www.gnu.org/licenses/>. + +AUTOMAKE_OPTIONS = nostdinc + +# Runs the testsuite via a script. + +# Create subdirectories. +stamp-subdir: + if test ! -d lib64; then \ + mkdir -p lib64; \ + fi; \ + if test ! -d lib32; then \ + mkdir -p lib32; \ + fi; \ + echo `date` > stamp-subdir; + + +testing_script=${libvtv_srcdir}/scripts/run-testsuite.sh +check-script: ${testing_script} stamp-subdir + -@(chmod +x ${testing_script}; \ + ${testing_script} ${libvtv_srcdir} ${libvtv_builddir}) + +check-am: + $(MAKE) $(AM_MAKEFLAGS) check-script + +.PHONY: check-script + +# By adding these files here, automake will remove them for 'make clean' +CLEANFILES = *.out environment-fail-* stamp-* replace-fail-* + +# To remove directories. +clean-local: + rm -rf lib* diff --git a/libvtv/testsuite/other-tests/Makefile.in b/libvtv/testsuite/other-tests/Makefile.in new file mode 100644 index 00000000000..66a75e16ea6 --- /dev/null +++ b/libvtv/testsuite/other-tests/Makefile.in @@ -0,0 +1,379 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = testsuite +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \ + $(top_srcdir)/../config/depstand.m4 \ + $(top_srcdir)/../config/lead-dot.m4 \ + $(top_srcdir)/../config/libstdc++-raw-cxx.m4 \ + $(top_srcdir)/../config/multi.m4 \ + $(top_srcdir)/../config/override.m4 \ + $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \ + $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/../libtool.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCAS = @CCAS@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSTDCXX_RAW_CXX_CXXFLAGS = @LIBSTDCXX_RAW_CXX_CXXFLAGS@ +LIBSTDCXX_RAW_CXX_LDFLAGS = @LIBSTDCXX_RAW_CXX_LDFLAGS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +XCFLAGS = @XCFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +enable_shared = @enable_shared@ +enable_static = @enable_static@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +libtool_VERSION = @libtool_VERSION@ +libvtv_builddir = @libvtv_builddir@ +libvtv_srcdir = @libvtv_srcdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +multi_basedir = @multi_basedir@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_noncanonical = @target_noncanonical@ +target_os = @target_os@ +target_vendor = @target_vendor@ +toolexecdir = @toolexecdir@ +toolexeclibdir = @toolexeclibdir@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +toplevel_builddir = @toplevel_builddir@ +toplevel_srcdir = @toplevel_srcdir@ +AUTOMAKE_OPTIONS = nostdinc +testing_script = ${libvtv_srcdir}/scripts/run-testsuite.sh + +# By adding these files here, automake will remove them for 'make clean' +CLEANFILES = *.out environment-fail-* stamp-* replace-fail-* +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign testsuite/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign testsuite/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-local mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + clean-local distclean distclean-generic distclean-libtool dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am + + +# Runs the testsuite via a script. + +# Create subdirectories. +stamp-subdir: + if test ! -d lib64; then \ + mkdir -p lib64; \ + fi; \ + if test ! -d lib32; then \ + mkdir -p lib32; \ + fi; \ + echo `date` > stamp-subdir; +check-script: ${testing_script} stamp-subdir + -@(chmod +x ${testing_script}; \ + ${testing_script} ${libvtv_srcdir} ${libvtv_builddir}) + +check-am: + $(MAKE) $(AM_MAKEFLAGS) check-script + +.PHONY: check-script + +# To remove directories. +clean-local: + rm -rf lib* + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libvtv/testsuite/other-tests/README b/libvtv/testsuite/other-tests/README new file mode 100644 index 00000000000..a64047460a6 --- /dev/null +++ b/libvtv/testsuite/other-tests/README @@ -0,0 +1,8 @@ +This directory contains tests that have not yet been converted to +proper dejagnu tests. If you look at the run_testsuite script in +libvtv/scripts, you should get a fair idea as to how to run these +tests. The plan is to convert these tests into proper dejangnu tests +sometime in the near future. + + +Aug. 30, 2013
\ No newline at end of file diff --git a/libvtv/testsuite/other-tests/dlopen.cc b/libvtv/testsuite/other-tests/dlopen.cc new file mode 100644 index 00000000000..4ffbe83acf7 --- /dev/null +++ b/libvtv/testsuite/other-tests/dlopen.cc @@ -0,0 +1,38 @@ +#include <stdlib.h> +#include <dlfcn.h> +#include <stdio.h> + + + +typedef void (*voidfn)(void); + +int failures = 0; + +void +__vtv_verify_fail (void **data_set_ptr, const void *vtbl_pointer) +{ + failures++; + return; +} + + +int main() +{ + char so_name[] = "so0.so"; + void * dlhandle = dlopen(so_name, RTLD_NOW); + if (!dlhandle) + { + fprintf(stderr, "dlopen %s error: %s\n", so_name, dlerror()); + exit(1); + } + voidfn so_entry = (voidfn)dlsym(dlhandle, "so_entry_0"); + if (!so_entry) + { + fprintf(stderr, "dlopen %s dlsym error: %s\n", so_name, dlerror()); + exit(2); + } + + so_entry(); + + dlclose(dlhandle); +} diff --git a/libvtv/testsuite/other-tests/dlopen_mt.cc b/libvtv/testsuite/other-tests/dlopen_mt.cc new file mode 100644 index 00000000000..772e8a733ed --- /dev/null +++ b/libvtv/testsuite/other-tests/dlopen_mt.cc @@ -0,0 +1,112 @@ +#include <stdlib.h> +#include <dlfcn.h> +#include <stdio.h> + +#include "vtv_utils.h" +#include "vtv_rts.h" +#include "pthread.h" + +#define NUM_REPEATS 10 +#define NUM_THREADS 10 +#define NUM_SOS 100 +#define NUM_SOS_PER_THREAD (NUM_SOS/NUM_THREADS) + +typedef void (*voidfn)(void); + +int failures = 0; + +void +__vtv_verify_fail (void **data_set_ptr, const void *vtbl_pointer) +{ + failures++; + return; +} + + +void do_dlopen(int so_num) +{ + char so_name [sizeof("soxxx.so")]; + sprintf(so_name, "so%d.so", so_num); + // printf("dl-opening %s\n", so_name); + void * dlhandle = dlopen(so_name, RTLD_NOW); + if (!dlhandle) + { + fprintf(stderr, "dlopen so:%s error: %s\n", so_name, dlerror()); + exit(1); + } + char so_entry [sizeof("so_entry_xxx")]; + sprintf(so_entry, "so_entry_%d", so_num); + voidfn so_entry_fn = (voidfn)dlsym(dlhandle, so_entry); + if (!so_entry_fn) + { + fprintf(stderr, "so:%s dlsym error: %s\n", so_name, dlerror()); + exit(2); + } + + so_entry_fn(); + + dlclose(dlhandle); +} + +volatile int threads_completed_it = 0; +volatile int current_wave = -1; + +void * do_dlopens(void * ptid) +{ + for (int k = 0; k < NUM_REPEATS; k++) + { + + for (int i = 0; i < NUM_SOS_PER_THREAD; i++) + { + while (current_wave < (k*NUM_SOS_PER_THREAD + i)) /* from 0 to 99 */ + ; + + do_dlopen((NUM_SOS_PER_THREAD * *(int *)ptid) + i); + + int old_value; + do { + old_value = threads_completed_it; + } while (!__sync_bool_compare_and_swap(&threads_completed_it, old_value, old_value + 1)); + + if (old_value == (NUM_THREADS - 1)) // Only one thread will do this. + { + threads_completed_it = 0; + printf("%c%d", 13, current_wave + 1); + fflush(stdout); + current_wave++; + } + } + } + + return NULL; +} + + +int main() +{ + pthread_t thread_ids[NUM_THREADS]; + int thread_nids[NUM_THREADS]; + + for (int t = 0; t < NUM_THREADS; t++ ) + { + thread_nids[t] = t; + if (pthread_create(&thread_ids[t], NULL, do_dlopens, &thread_nids[t]) != 0) + { + printf("failed pthread_create\n"); + exit(1); + } + } + + current_wave = 0; // start the work on the other threads + + for (int t = 0; t < NUM_THREADS; t++) + if (pthread_join(thread_ids[t], NULL) != 0) + { + printf("failed pthread_join\n"); + exit(2); + } + + printf("\n"); + + return 0; +} diff --git a/libvtv/testsuite/other-tests/environment-fail-32.s b/libvtv/testsuite/other-tests/environment-fail-32.s new file mode 100644 index 00000000000..cac501652a7 --- /dev/null +++ b/libvtv/testsuite/other-tests/environment-fail-32.s @@ -0,0 +1,514 @@ + .file "environment.cc" + .section .text._ZN15EnvironmentImpl6GetVarEPKcPc,"axG",@progbits,_ZN15EnvironmentImpl6GetVarEPKcPc,comdat + .align 2 + .weak _ZN15EnvironmentImpl6GetVarEPKcPc + .type _ZN15EnvironmentImpl6GetVarEPKcPc, @function +_ZN15EnvironmentImpl6GetVarEPKcPc: +.LFB0: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + movl $1, %eax + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE0: + .size _ZN15EnvironmentImpl6GetVarEPKcPc, .-_ZN15EnvironmentImpl6GetVarEPKcPc + .text + .align 2 + .globl _ZN11EnvironmentD2Ev + .type _ZN11EnvironmentD2Ev, @function +_ZN11EnvironmentD2Ev: +.LFB2: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl 8(%ebp), %eax + movl _ZTV11Environment@GOT(%ebx), %edx + leal 8(%edx), %edx + movl %edx, (%eax) + movl $0, %eax + testl %eax, %eax + je .L3 + movl 8(%ebp), %eax + movl %eax, (%esp) + call _ZdlPv@PLT +.L3: + addl $20, %esp + popl %ebx + .cfi_restore 3 + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE2: + .size _ZN11EnvironmentD2Ev, .-_ZN11EnvironmentD2Ev + .globl _ZN11EnvironmentD1Ev + .set _ZN11EnvironmentD1Ev,_ZN11EnvironmentD2Ev + .align 2 + .globl _ZN11EnvironmentD0Ev + .type _ZN11EnvironmentD0Ev, @function +_ZN11EnvironmentD0Ev: +.LFB4: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl 8(%ebp), %eax + movl %eax, (%esp) + call _ZN11EnvironmentD1Ev@PLT + movl 8(%ebp), %eax + movl %eax, (%esp) + call _ZdlPv@PLT + addl $20, %esp + popl %ebx + .cfi_restore 3 + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE4: + .size _ZN11EnvironmentD0Ev, .-_ZN11EnvironmentD0Ev + .section .text._ZN11EnvironmentC2Ev,"axG",@progbits,_ZN11EnvironmentC5Ev,comdat + .align 2 + .weak _ZN11EnvironmentC2Ev + .type _ZN11EnvironmentC2Ev, @function +_ZN11EnvironmentC2Ev: +.LFB8: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + call __x86.get_pc_thunk.cx + addl $_GLOBAL_OFFSET_TABLE_, %ecx + movl 8(%ebp), %eax + movl _ZTV11Environment@GOT(%ecx), %edx + leal 8(%edx), %edx + movl %edx, (%eax) + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE8: + .size _ZN11EnvironmentC2Ev, .-_ZN11EnvironmentC2Ev + .weak _ZN11EnvironmentC1Ev + .set _ZN11EnvironmentC1Ev,_ZN11EnvironmentC2Ev + .section .text._ZN15EnvironmentImplC2Ev,"axG",@progbits,_ZN15EnvironmentImplC5Ev,comdat + .align 2 + .weak _ZN15EnvironmentImplC2Ev + .type _ZN15EnvironmentImplC2Ev, @function +_ZN15EnvironmentImplC2Ev: +.LFB10: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl 8(%ebp), %eax + movl %eax, (%esp) + call _ZN11EnvironmentC2Ev@PLT + movl 8(%ebp), %eax + movl _ZTV15EnvironmentImpl@GOT(%ebx), %edx + leal 8(%edx), %edx + movl %edx, (%eax) + addl $20, %esp + popl %ebx + .cfi_restore 3 + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE10: + .size _ZN15EnvironmentImplC2Ev, .-_ZN15EnvironmentImplC2Ev + .weak _ZN15EnvironmentImplC1Ev + .set _ZN15EnvironmentImplC1Ev,_ZN15EnvironmentImplC2Ev + .text + .align 2 + .globl _ZN11Environment6CreateEv + .type _ZN11Environment6CreateEv, @function +_ZN11Environment6CreateEv: +.LFB5: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %esi + pushl %ebx + subl $16, %esp + .cfi_offset 6, -12 + .cfi_offset 3, -16 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl $4, (%esp) + call _Znwj@PLT + movl %eax, %esi + movl $0, (%esi) + movl %esi, (%esp) + call _ZN15EnvironmentImplC1Ev@PLT + movl %esi, %eax + addl $16, %esp + popl %ebx + .cfi_restore 3 + popl %esi + .cfi_restore 6 + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE5: + .size _ZN11Environment6CreateEv, .-_ZN11Environment6CreateEv + .section .rodata +.LC0: + .string "%p\n" + .text + .globl main + .type main, @function +main: +.LFB12: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + andl $-16, %esp + subl $32, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl $0, 28(%esp) + call _ZN11Environment6CreateEv@PLT + movl %eax, 24(%esp) + movl 24(%esp), %eax + movl (%eax), %eax + movl %eax, 4(%esp) + leal _ZN4_VTVI11EnvironmentE12__vtable_mapE@GOTOFF(%ebx), %eax + movl %eax, (%esp) + call _Z24__VLTVerifyVtablePointerPPvPKv@PLT + addl $8, %eax + movl (%eax), %eax + movl 28(%esp), %edx + movl %edx, 8(%esp) + movl $0, 4(%esp) + movl 24(%esp), %edx + movl %edx, (%esp) + call *%eax + movl 24(%esp), %eax + movl %eax, 4(%esp) + leal .LC0@GOTOFF(%ebx), %eax + movl %eax, (%esp) + call printf@PLT + movl $0, %eax + movl -4(%ebp), %ebx + leave + .cfi_restore 5 + .cfi_restore 3 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE12: + .size main, .-main + .weak _ZTV11Environment + .section .data.rel.ro._ZTV11Environment,"awG",@progbits,_ZTV11Environment,comdat + .align 8 + .type _ZTV11Environment, @object + .size _ZTV11Environment, 20 +_ZTV11Environment: + .long 0 + .long _ZTI11Environment + .long _ZN11EnvironmentD1Ev + .long _ZN11EnvironmentD0Ev + .long __cxa_pure_virtual + .weak _ZTV15EnvironmentImpl + .section .data.rel.ro._ZTV15EnvironmentImpl,"awG",@progbits,_ZTV15EnvironmentImpl,comdat + .align 8 + .type _ZTV15EnvironmentImpl, @object + .size _ZTV15EnvironmentImpl, 20 +_ZTV15EnvironmentImpl: + .long 0 + .long _ZTI15EnvironmentImpl + .long _ZN15EnvironmentImplD1Ev + .long _ZN15EnvironmentImplD0Ev + .long _ZN15EnvironmentImpl6GetVarEPKcPc + .section .text._ZN15EnvironmentImplD2Ev,"axG",@progbits,_ZN15EnvironmentImplD5Ev,comdat + .align 2 + .weak _ZN15EnvironmentImplD2Ev + .type _ZN15EnvironmentImplD2Ev, @function +_ZN15EnvironmentImplD2Ev: +.LFB14: + .cfi_startproc + .cfi_personality 0x9b,DW.ref.__gxx_personality_v0 + .cfi_lsda 0x1b,.LLSDA14 + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl 8(%ebp), %eax + movl _ZTV15EnvironmentImpl@GOT(%ebx), %edx + leal 8(%edx), %edx + movl %edx, (%eax) + movl 8(%ebp), %eax + movl %eax, (%esp) +.LEHB0: + call _ZN11EnvironmentD2Ev@PLT +.LEHE0: + movl $0, %eax + testl %eax, %eax + je .L19 + movl 8(%ebp), %eax + movl %eax, (%esp) + call _ZdlPv@PLT + jmp .L19 +.L18: + movl %eax, (%esp) +.LEHB1: + call _Unwind_Resume@PLT +.LEHE1: +.L19: + addl $20, %esp + popl %ebx + .cfi_restore 3 + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE14: + .globl __gxx_personality_v0 + .section .gcc_except_table._ZN15EnvironmentImplD2Ev,"aG",@progbits,_ZN15EnvironmentImplD5Ev,comdat +.LLSDA14: + .byte 0xff + .byte 0xff + .byte 0x1 + .uleb128 .LLSDACSE14-.LLSDACSB14 +.LLSDACSB14: + .uleb128 .LEHB0-.LFB14 + .uleb128 .LEHE0-.LEHB0 + .uleb128 .L18-.LFB14 + .uleb128 0 + .uleb128 .LEHB1-.LFB14 + .uleb128 .LEHE1-.LEHB1 + .uleb128 0 + .uleb128 0 +.LLSDACSE14: + .section .text._ZN15EnvironmentImplD2Ev,"axG",@progbits,_ZN15EnvironmentImplD5Ev,comdat + .size _ZN15EnvironmentImplD2Ev, .-_ZN15EnvironmentImplD2Ev + .weak _ZN15EnvironmentImplD1Ev + .set _ZN15EnvironmentImplD1Ev,_ZN15EnvironmentImplD2Ev + .section .text._ZN15EnvironmentImplD0Ev,"axG",@progbits,_ZN15EnvironmentImplD0Ev,comdat + .align 2 + .weak _ZN15EnvironmentImplD0Ev + .type _ZN15EnvironmentImplD0Ev, @function +_ZN15EnvironmentImplD0Ev: +.LFB16: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $20, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + movl 8(%ebp), %eax + movl %eax, (%esp) + call _ZN15EnvironmentImplD1Ev@PLT + movl 8(%ebp), %eax + movl %eax, (%esp) + call _ZdlPv@PLT + addl $20, %esp + popl %ebx + .cfi_restore 3 + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE16: + .size _ZN15EnvironmentImplD0Ev, .-_ZN15EnvironmentImplD0Ev + .weak _ZTS15EnvironmentImpl + .section .rodata._ZTS15EnvironmentImpl,"aG",@progbits,_ZTS15EnvironmentImpl,comdat + .type _ZTS15EnvironmentImpl, @object + .size _ZTS15EnvironmentImpl, 18 +_ZTS15EnvironmentImpl: + .string "15EnvironmentImpl" + .weak _ZTI15EnvironmentImpl + .section .data.rel.ro._ZTI15EnvironmentImpl,"awG",@progbits,_ZTI15EnvironmentImpl,comdat + .align 4 + .type _ZTI15EnvironmentImpl, @object + .size _ZTI15EnvironmentImpl, 12 +_ZTI15EnvironmentImpl: + .long _ZTVN10__cxxabiv120__si_class_type_infoE+8 + .long _ZTS15EnvironmentImpl + .long _ZTI11Environment + .weak _ZTI11Environment + .section .data.rel.ro._ZTI11Environment,"awG",@progbits,_ZTI11Environment,comdat + .align 4 + .type _ZTI11Environment, @object + .size _ZTI11Environment, 8 +_ZTI11Environment: + .long _ZTVN10__cxxabiv117__class_type_infoE+8 + .long _ZTS11Environment + .weak _ZTS11Environment + .section .rodata._ZTS11Environment,"aG",@progbits,_ZTS11Environment,comdat + .type _ZTS11Environment, @object + .size _ZTS11Environment, 14 +_ZTS11Environment: + .string "11Environment" + .hidden _ZN4_VTVI11EnvironmentE12__vtable_mapE + .weak _ZN4_VTVI11EnvironmentE12__vtable_mapE + .section .vtable_map_vars,"awG",@progbits,_ZN4_VTVI11EnvironmentE12__vtable_mapE,comdat + .align 4 + .type _ZN4_VTVI11EnvironmentE12__vtable_mapE, @gnu_unique_object + .size _ZN4_VTVI11EnvironmentE12__vtable_mapE, 4 +_ZN4_VTVI11EnvironmentE12__vtable_mapE: + .zero 4 + .hidden _ZN4_VTVI15EnvironmentImplE12__vtable_mapE + .weak _ZN4_VTVI15EnvironmentImplE12__vtable_mapE + .section .vtable_map_vars,"awG",@progbits,_ZN4_VTVI15EnvironmentImplE12__vtable_mapE,comdat + .align 4 + .type _ZN4_VTVI15EnvironmentImplE12__vtable_mapE, @gnu_unique_object + .size _ZN4_VTVI15EnvironmentImplE12__vtable_mapE, 4 +_ZN4_VTVI15EnvironmentImplE12__vtable_mapE: + .zero 4 + .section .data.rel.ro,"aw",@progbits + .align 4 + .type __vptr_array_11Environment, @object + .size __vptr_array_11Environment, 8 +__vptr_array_11Environment: + .long _ZTV11Environment+8 + .long _ZTV15EnvironmentImpl+8 + .section .rodata + .align 4 +.LC1: + .string "&" + .string "" + .string "" + .ascii "\224\tl\022_ZN4_VTVI11EnvironmentE12__vtable_mapE" + .align 4 +.LC2: + .string "*" + .string "" + .string "" + .ascii "N\225\r\334_ZN4_VTVI15EnvironmentImplE12__vtable_mapE" + .text + .type _GLOBAL__sub_I.00099_environment.cc, @function +_GLOBAL__sub_I.00099_environment.cc: +.LFB17: + .cfi_startproc + pushl %ebp + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp + .cfi_def_cfa_register 5 + pushl %ebx + subl $36, %esp + .cfi_offset 3, -12 + call __x86.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx + leal __vptr_array_11Environment@GOTOFF(%ebx), %eax + movl %eax, 16(%esp) + movl $2, 12(%esp) + movl $2, 8(%esp) + leal .LC1@GOTOFF(%ebx), %eax + movl %eax, 4(%esp) + leal _ZN4_VTVI11EnvironmentE12__vtable_mapE@GOTOFF(%ebx), %eax + movl %eax, (%esp) + movl _ZTV15EnvironmentImpl@GOT(%ebx), %eax + leal 8(%eax), %eax + movl %eax, 12(%esp) + movl $1, 8(%esp) + leal .LC2@GOTOFF(%ebx), %eax + movl %eax, 4(%esp) + leal _ZN4_VTVI15EnvironmentImplE12__vtable_mapE@GOTOFF(%ebx), %eax + movl %eax, (%esp) + call _Z17__VLTRegisterPairPPvPKvjS2_@PLT + addl $36, %esp + popl %ebx + .cfi_restore 3 + popl %ebp + .cfi_restore 5 + .cfi_def_cfa 4, 4 + ret + .cfi_endproc +.LFE17: + .size _GLOBAL__sub_I.00099_environment.cc, .-_GLOBAL__sub_I.00099_environment.cc + .section .init_array.00099,"aw" + .align 4 + .long _GLOBAL__sub_I.00099_environment.cc + .section .text.__x86.get_pc_thunk.cx,"axG",@progbits,__x86.get_pc_thunk.cx,comdat + .globl __x86.get_pc_thunk.cx + .hidden __x86.get_pc_thunk.cx + .type __x86.get_pc_thunk.cx, @function +__x86.get_pc_thunk.cx: +.LFB18: + .cfi_startproc + movl (%esp), %ecx + ret + .cfi_endproc +.LFE18: + .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat + .globl __x86.get_pc_thunk.bx + .hidden __x86.get_pc_thunk.bx + .type __x86.get_pc_thunk.bx, @function +__x86.get_pc_thunk.bx: +.LFB19: + .cfi_startproc + movl (%esp), %ebx + ret + .cfi_endproc +.LFE19: + .hidden DW.ref.__gxx_personality_v0 + .weak DW.ref.__gxx_personality_v0 + .section .data.DW.ref.__gxx_personality_v0,"awG",@progbits,DW.ref.__gxx_personality_v0,comdat + .align 4 + .type DW.ref.__gxx_personality_v0, @object + .size DW.ref.__gxx_personality_v0, 4 +DW.ref.__gxx_personality_v0: + .long __gxx_personality_v0 + .ident "GCC: (GNU) 4.9.0 20130616 (experimental)" + .section .note.GNU-stack,"",@progbits diff --git a/libvtv/testsuite/other-tests/environment-fail-64.s b/libvtv/testsuite/other-tests/environment-fail-64.s new file mode 100644 index 00000000000..d75db248b07 --- /dev/null +++ b/libvtv/testsuite/other-tests/environment-fail-64.s @@ -0,0 +1,425 @@ + .file "environment.cc" + .section .text._ZN15EnvironmentImpl6GetVarEPKcPc,"axG",@progbits,_ZN15EnvironmentImpl6GetVarEPKcPc,comdat + .align 2 + .weak _ZN15EnvironmentImpl6GetVarEPKcPc + .type _ZN15EnvironmentImpl6GetVarEPKcPc, @function +_ZN15EnvironmentImpl6GetVarEPKcPc: +.LFB0: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movq %rdi, -8(%rbp) + movq %rsi, -16(%rbp) + movq %rdx, -24(%rbp) + movl $1, %eax + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size _ZN15EnvironmentImpl6GetVarEPKcPc, .-_ZN15EnvironmentImpl6GetVarEPKcPc + .text + .align 2 + .globl _ZN11EnvironmentD2Ev + .type _ZN11EnvironmentD2Ev, @function +_ZN11EnvironmentD2Ev: +.LFB2: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movq %rdi, -8(%rbp) + movq -8(%rbp), %rax + movq _ZTV11Environment@GOTPCREL(%rip), %rdx + leaq 16(%rdx), %rdx + movq %rdx, (%rax) + movl $0, %eax + testl %eax, %eax + je .L3 + movq -8(%rbp), %rax + movq %rax, %rdi + call _ZdlPv@PLT +.L3: + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE2: + .size _ZN11EnvironmentD2Ev, .-_ZN11EnvironmentD2Ev + .globl _ZN11EnvironmentD1Ev + .set _ZN11EnvironmentD1Ev,_ZN11EnvironmentD2Ev + .align 2 + .globl _ZN11EnvironmentD0Ev + .type _ZN11EnvironmentD0Ev, @function +_ZN11EnvironmentD0Ev: +.LFB4: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movq %rdi, -8(%rbp) + movq -8(%rbp), %rax + movq %rax, %rdi + call _ZN11EnvironmentD1Ev@PLT + movq -8(%rbp), %rax + movq %rax, %rdi + call _ZdlPv@PLT + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE4: + .size _ZN11EnvironmentD0Ev, .-_ZN11EnvironmentD0Ev + .section .text._ZN11EnvironmentC2Ev,"axG",@progbits,_ZN11EnvironmentC5Ev,comdat + .align 2 + .weak _ZN11EnvironmentC2Ev + .type _ZN11EnvironmentC2Ev, @function +_ZN11EnvironmentC2Ev: +.LFB8: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + movq %rdi, -8(%rbp) + movq -8(%rbp), %rax + movq _ZTV11Environment@GOTPCREL(%rip), %rdx + leaq 16(%rdx), %rdx + movq %rdx, (%rax) + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE8: + .size _ZN11EnvironmentC2Ev, .-_ZN11EnvironmentC2Ev + .weak _ZN11EnvironmentC1Ev + .set _ZN11EnvironmentC1Ev,_ZN11EnvironmentC2Ev + .section .text._ZN15EnvironmentImplC2Ev,"axG",@progbits,_ZN15EnvironmentImplC5Ev,comdat + .align 2 + .weak _ZN15EnvironmentImplC2Ev + .type _ZN15EnvironmentImplC2Ev, @function +_ZN15EnvironmentImplC2Ev: +.LFB10: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movq %rdi, -8(%rbp) + movq -8(%rbp), %rax + movq %rax, %rdi + call _ZN11EnvironmentC2Ev@PLT + movq -8(%rbp), %rax + movq _ZTV15EnvironmentImpl@GOTPCREL(%rip), %rdx + leaq 16(%rdx), %rdx + movq %rdx, (%rax) + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE10: + .size _ZN15EnvironmentImplC2Ev, .-_ZN15EnvironmentImplC2Ev + .weak _ZN15EnvironmentImplC1Ev + .set _ZN15EnvironmentImplC1Ev,_ZN15EnvironmentImplC2Ev + .text + .align 2 + .globl _ZN11Environment6CreateEv + .type _ZN11Environment6CreateEv, @function +_ZN11Environment6CreateEv: +.LFB5: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + pushq %rbx + subq $8, %rsp + .cfi_offset 3, -24 + movl $8, %edi + call _Znwm@PLT + movq %rax, %rbx + movq $0, (%rbx) + movq %rbx, %rdi + call _ZN15EnvironmentImplC1Ev@PLT + movq %rbx, %rax + addq $8, %rsp + popq %rbx + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE5: + .size _ZN11Environment6CreateEv, .-_ZN11Environment6CreateEv + .section .rodata +.LC0: + .string "%p\n" + .text + .globl main + .type main, @function +main: +.LFB12: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movq $0, -8(%rbp) + call _ZN11Environment6CreateEv@PLT + movq %rax, -16(%rbp) + movq -16(%rbp), %rax + movq (%rax), %rax + movq %rax, %rsi + leaq _ZN4_VTVI11EnvironmentE12__vtable_mapE(%rip), %rdi + call _Z24__VLTVerifyVtablePointerPPvPKv@PLT + addq $16, %rax + movq (%rax), %rax + movq -8(%rbp), %rdx + movq -16(%rbp), %rcx + movl $0, %esi + movq %rcx, %rdi + call *%rax + movq -16(%rbp), %rax + movq %rax, %rsi + leaq .LC0(%rip), %rdi + movl $0, %eax + call printf@PLT + movl $0, %eax + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE12: + .size main, .-main + .weak _ZTV11Environment + .section .data.rel.ro._ZTV11Environment,"awG",@progbits,_ZTV11Environment,comdat + .align 32 + .type _ZTV11Environment, @object + .size _ZTV11Environment, 40 +_ZTV11Environment: + .quad 0 + .quad _ZTI11Environment + .quad _ZN11EnvironmentD1Ev + .quad _ZN11EnvironmentD0Ev + .quad __cxa_pure_virtual + .weak _ZTV15EnvironmentImpl + .section .data.rel.ro._ZTV15EnvironmentImpl,"awG",@progbits,_ZTV15EnvironmentImpl,comdat + .align 32 + .type _ZTV15EnvironmentImpl, @object + .size _ZTV15EnvironmentImpl, 40 +_ZTV15EnvironmentImpl: + .quad 0 + .quad _ZTI15EnvironmentImpl + .quad _ZN15EnvironmentImplD1Ev + .quad _ZN15EnvironmentImplD0Ev + .quad _ZN15EnvironmentImpl6GetVarEPKcPc + .section .text._ZN15EnvironmentImplD2Ev,"axG",@progbits,_ZN15EnvironmentImplD5Ev,comdat + .align 2 + .weak _ZN15EnvironmentImplD2Ev + .type _ZN15EnvironmentImplD2Ev, @function +_ZN15EnvironmentImplD2Ev: +.LFB14: + .cfi_startproc + .cfi_personality 0x9b,DW.ref.__gxx_personality_v0 + .cfi_lsda 0x1b,.LLSDA14 + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movq %rdi, -8(%rbp) + movq -8(%rbp), %rax + movq _ZTV15EnvironmentImpl@GOTPCREL(%rip), %rdx + leaq 16(%rdx), %rdx + movq %rdx, (%rax) + movq -8(%rbp), %rax + movq %rax, %rdi +.LEHB0: + call _ZN11EnvironmentD2Ev@PLT +.LEHE0: + movl $0, %eax + testl %eax, %eax + je .L19 + movq -8(%rbp), %rax + movq %rax, %rdi + call _ZdlPv@PLT + jmp .L19 +.L18: + movq %rax, %rdi +.LEHB1: + call _Unwind_Resume@PLT +.LEHE1: +.L19: + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE14: + .globl __gxx_personality_v0 + .section .gcc_except_table._ZN15EnvironmentImplD2Ev,"aG",@progbits,_ZN15EnvironmentImplD5Ev,comdat +.LLSDA14: + .byte 0xff + .byte 0xff + .byte 0x1 + .uleb128 .LLSDACSE14-.LLSDACSB14 +.LLSDACSB14: + .uleb128 .LEHB0-.LFB14 + .uleb128 .LEHE0-.LEHB0 + .uleb128 .L18-.LFB14 + .uleb128 0 + .uleb128 .LEHB1-.LFB14 + .uleb128 .LEHE1-.LEHB1 + .uleb128 0 + .uleb128 0 +.LLSDACSE14: + .section .text._ZN15EnvironmentImplD2Ev,"axG",@progbits,_ZN15EnvironmentImplD5Ev,comdat + .size _ZN15EnvironmentImplD2Ev, .-_ZN15EnvironmentImplD2Ev + .weak _ZN15EnvironmentImplD1Ev + .set _ZN15EnvironmentImplD1Ev,_ZN15EnvironmentImplD2Ev + .section .text._ZN15EnvironmentImplD0Ev,"axG",@progbits,_ZN15EnvironmentImplD0Ev,comdat + .align 2 + .weak _ZN15EnvironmentImplD0Ev + .type _ZN15EnvironmentImplD0Ev, @function +_ZN15EnvironmentImplD0Ev: +.LFB16: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $16, %rsp + movq %rdi, -8(%rbp) + movq -8(%rbp), %rax + movq %rax, %rdi + call _ZN15EnvironmentImplD1Ev@PLT + movq -8(%rbp), %rax + movq %rax, %rdi + call _ZdlPv@PLT + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE16: + .size _ZN15EnvironmentImplD0Ev, .-_ZN15EnvironmentImplD0Ev + .weak _ZTS15EnvironmentImpl + .section .rodata._ZTS15EnvironmentImpl,"aG",@progbits,_ZTS15EnvironmentImpl,comdat + .align 16 + .type _ZTS15EnvironmentImpl, @object + .size _ZTS15EnvironmentImpl, 18 +_ZTS15EnvironmentImpl: + .string "15EnvironmentImpl" + .weak _ZTI15EnvironmentImpl + .section .data.rel.ro._ZTI15EnvironmentImpl,"awG",@progbits,_ZTI15EnvironmentImpl,comdat + .align 16 + .type _ZTI15EnvironmentImpl, @object + .size _ZTI15EnvironmentImpl, 24 +_ZTI15EnvironmentImpl: + .quad _ZTVN10__cxxabiv120__si_class_type_infoE+16 + .quad _ZTS15EnvironmentImpl + .quad _ZTI11Environment + .weak _ZTI11Environment + .section .data.rel.ro._ZTI11Environment,"awG",@progbits,_ZTI11Environment,comdat + .align 16 + .type _ZTI11Environment, @object + .size _ZTI11Environment, 16 +_ZTI11Environment: + .quad _ZTVN10__cxxabiv117__class_type_infoE+16 + .quad _ZTS11Environment + .weak _ZTS11Environment + .section .rodata._ZTS11Environment,"aG",@progbits,_ZTS11Environment,comdat + .type _ZTS11Environment, @object + .size _ZTS11Environment, 14 +_ZTS11Environment: + .string "11Environment" + .hidden _ZN4_VTVI11EnvironmentE12__vtable_mapE + .weak _ZN4_VTVI11EnvironmentE12__vtable_mapE + .section .vtable_map_vars,"awG",@progbits,_ZN4_VTVI11EnvironmentE12__vtable_mapE,comdat + .align 8 + .type _ZN4_VTVI11EnvironmentE12__vtable_mapE, @gnu_unique_object + .size _ZN4_VTVI11EnvironmentE12__vtable_mapE, 8 +_ZN4_VTVI11EnvironmentE12__vtable_mapE: + .zero 8 + .hidden _ZN4_VTVI15EnvironmentImplE12__vtable_mapE + .weak _ZN4_VTVI15EnvironmentImplE12__vtable_mapE + .section .vtable_map_vars,"awG",@progbits,_ZN4_VTVI15EnvironmentImplE12__vtable_mapE,comdat + .align 8 + .type _ZN4_VTVI15EnvironmentImplE12__vtable_mapE, @gnu_unique_object + .size _ZN4_VTVI15EnvironmentImplE12__vtable_mapE, 8 +_ZN4_VTVI15EnvironmentImplE12__vtable_mapE: + .zero 8 + .section .data.rel.ro,"aw",@progbits + .align 16 + .type __vptr_array_11Environment, @object + .size __vptr_array_11Environment, 16 +__vptr_array_11Environment: + .quad _ZTV11Environment+16 + .quad _ZTV15EnvironmentImpl+16 + .section .rodata + .align 8 +.LC1: + .string "&" + .string "" + .string "" + .ascii "\224\tl\022_ZN4_VTVI11EnvironmentE12__vtable_mapE" + .align 8 +.LC2: + .string "*" + .string "" + .string "" + .ascii "N\225\r\334_ZN4_VTVI15EnvironmentImplE12__vtable_mapE" + .text + .type _GLOBAL__sub_I.00099_environment.cc, @function +_GLOBAL__sub_I.00099_environment.cc: +.LFB17: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + leaq __vptr_array_11Environment(%rip), %r8 + movl $2, %ecx + movl $2, %edx + leaq .LC1(%rip), %rsi + leaq _ZN4_VTVI11EnvironmentE12__vtable_mapE(%rip), %rdi + movq _ZTV15EnvironmentImpl@GOTPCREL(%rip), %rax + leaq 16(%rax), %rcx + movl $1, %edx + leaq .LC2(%rip), %rsi + leaq _ZN4_VTVI15EnvironmentImplE12__vtable_mapE(%rip), %rdi + call _Z17__VLTRegisterPairPPvPKvmS2_@PLT + popq %rbp + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE17: + .size _GLOBAL__sub_I.00099_environment.cc, .-_GLOBAL__sub_I.00099_environment.cc + .section .init_array.00099,"aw" + .align 8 + .quad _GLOBAL__sub_I.00099_environment.cc + .hidden DW.ref.__gxx_personality_v0 + .weak DW.ref.__gxx_personality_v0 + .section .data.DW.ref.__gxx_personality_v0,"awG",@progbits,DW.ref.__gxx_personality_v0,comdat + .align 8 + .type DW.ref.__gxx_personality_v0, @object + .size DW.ref.__gxx_personality_v0, 8 +DW.ref.__gxx_personality_v0: + .quad __gxx_personality_v0 + .ident "GCC: (GNU) 4.9.0 20130616 (experimental)" + .section .note.GNU-stack,"",@progbits diff --git a/libvtv/testsuite/other-tests/field-test.cc b/libvtv/testsuite/other-tests/field-test.cc new file mode 100644 index 00000000000..b6f34bca02c --- /dev/null +++ b/libvtv/testsuite/other-tests/field-test.cc @@ -0,0 +1,94 @@ +// Compile with /home/llozano/local2/proj/vtable/gcc-root/usr/local/bin/g++ -m32 -fvtable-verify=std -fpic -rdynamic -Wl,-R,/home/llozano/local2/proj/vtable/gcc-root/usr/local/lib32:./lib32 -I/home/llozano/local2/proj/vtable/vt2/gcc-4_6-mobile-vtable-security//libstdc++-v3/libsupc++ temp_deriv.cc -O0 -ldl -lpthread -Wl,--whole-archive,-lvtv_init,--no-whole-archive,-z,relro -DTPID=0 -g +// Look at assembly with: objdump -drl a.out + +#include <dlfcn.h> +#include <assert.h> +#include <stdlib.h> + +extern "C" int printf(const char *, ...); + +static int counter = 0; + +int i = TPID; +struct base +{ + virtual void inc() { counter += i; } +}; + +struct derived: public base +{ + virtual void inc() { counter += (10*i); } +}; + +// We don't use this class. It is just here so that the +// compiler does not devirtualize calls to derived::inc() +struct derived2: public derived +{ + virtual void inc() { counter += (20*i); } +}; + +/* +static base * bp = new base(); +static derived * dp = new derived(); +static base * dbp = new derived(); +*/ + +struct my_struct { + base *bp; + derived *dp; + base *dbp; +}; + +typedef void * vtptr; + +vtptr get_vtptr(void * object_ptr) +{ + vtptr * object_vtptr_ptr = (vtptr *)object_ptr; + return *object_vtptr_ptr; +} + +void set_vptr(void * object_ptr, vtptr vtp) +{ + vtptr * object_vtptr_ptr = (vtptr *)object_ptr; + *object_vtptr_ptr = vtp; +} + +// Given 2 pointers to C++ objects (non PODs), exchange the pointers to vtable +void exchange_vtptr(void * object1_ptr, void * object2_ptr) +{ + vtptr object1_vtptr = get_vtptr(object1_ptr); + vtptr object2_vtptr = get_vtptr(object2_ptr); + set_vptr(object1_ptr, object2_vtptr); + set_vptr(object2_ptr, object1_vtptr); +} + +main() +{ + int prev_counter; + + struct my_struct *my_obj = (struct my_struct *) malloc (sizeof (struct my_struct)); + + my_obj->bp = new base(); + my_obj->dp = new derived (); + my_obj->dbp = new derived (); + + + counter = 0; + my_obj->bp->inc(); + my_obj->dp->inc(); + my_obj->dbp->inc(); + assert(counter == (TPID + 10*TPID + 10*TPID)); + + prev_counter = counter; + printf("before ex bp vptr=%x dp vptr=%x\n", get_vtptr(my_obj->bp), get_vtptr(my_obj->dp)); + exchange_vtptr(my_obj->bp, my_obj->dp); + printf("after ex bp vptr=%x dp vptr=%x\n", get_vtptr(my_obj->bp), get_vtptr(my_obj->dp)); + my_obj->bp->inc(); // This one should not abort but it is calling the wrong member + assert(counter == (prev_counter + 10*TPID)); + printf("Pass first attack! Expected!\n"); + printf("TPDI=%d counter %d\n", TPID, counter); + my_obj->dp->inc(); + printf("Pass second attack! SHOULD NOT BE HERE!\n"); + printf("TPDI=%d counter %d\n", TPID, counter); + exit(1); +} diff --git a/libvtv/testsuite/other-tests/replace-fail.cc b/libvtv/testsuite/other-tests/replace-fail.cc new file mode 100644 index 00000000000..2b4070eec77 --- /dev/null +++ b/libvtv/testsuite/other-tests/replace-fail.cc @@ -0,0 +1,11 @@ +#include <stdlib.h> +#include <stdio.h> + + +void __vtv_verify_fail (void **, void*) __attribute__((visibility ("default"))); + +void +__vtv_verify_fail (void **hash_table, const void *vtbl_ptr) +{ + fprintf (stdout, "Executing alternative failure routine.\n"); +} diff --git a/libvtv/testsuite/other-tests/so.cc b/libvtv/testsuite/other-tests/so.cc new file mode 100644 index 00000000000..3f0a346f1e8 --- /dev/null +++ b/libvtv/testsuite/other-tests/so.cc @@ -0,0 +1,93 @@ +#include <dlfcn.h> +#include <assert.h> +#include <unistd.h> +#include <vtv_fail.h> + +extern "C" int printf(const char *, ...); +extern "C" int sprintf(char *, const char*, ...); + +static int counter = 0; +extern int failures; + +template <int i> struct base +{ + virtual char * whoami() { + static char sl[100]; + sprintf(sl, "I am base %d", i); + return sl; + } + virtual void inc() { counter += i; } +}; + +template <int i> struct derived: base<i> +{ + virtual char * whoami() { + static char sl[100]; + sprintf(sl, "I am derived %d", i); + return sl; + } + virtual void inc() { counter += (10*i); } +}; + +// We don't use this class. It is just here so that the +// compiler does not devirtualize calls to derived::inc() +template <int i> struct derived2: derived<i> +{ + virtual void inc() { counter += (20*i); } +}; + +static base<TPID> * bp = new base<TPID>(); +static derived<TPID> * dp = new derived<TPID>(); +static base<TPID> * dbp = new derived<TPID>(); + + +// Given 2 pointers to C++ objects (non PODs), exchange the pointers to vtable +static void exchange_vtptr(void * object1_ptr, void * object2_ptr) +{ + void ** object1_vtptr_ptr = (void **)object1_ptr; + void ** object2_vtptr_ptr = (void **)object2_ptr; + void * object1_vtptr = *object1_vtptr_ptr; + void * object2_vtptr = *object2_vtptr_ptr; + *object1_vtptr_ptr = object2_vtptr; + *object2_vtptr_ptr = object1_vtptr; +} + +#define BUILD_NAME(NAME,ID) NAME##ID +#define EXPAND(NAME,X) BUILD_NAME(NAME,X) +extern "C" void EXPAND(so_entry_,TPID)(void) +{ + int prev_counter; + int prev_failures; + + counter = 0; + bp->inc(); + dp->inc(); + dbp->inc(); + assert(counter == (TPID + 10*TPID + 10*TPID)); + + prev_counter = counter; + exchange_vtptr(bp, dp); + bp->inc(); // This one should succeed but it is calling the wrong member + if (counter != (prev_counter + 10*TPID)) + { + printf("TPID=%d whoami=%s wrong counter value prev_counter=%d counter=%d\n", TPID, bp->whoami(), prev_counter, counter); + sleep(2); + } + assert(counter == (prev_counter + 10*TPID)); + // printf("Pass first attack!\n"); + + // This one should fail verification!. So it should jump to __vtv_verify_fail above. + prev_failures = failures; + dp->inc(); + // this code may be executed by multiple threads at the same time. So, just verify the number of failures has + // increased as opposed to check for increase by 1. + assert(failures > prev_failures); + assert(counter == (prev_counter + 10*TPID + TPID)); + // printf("TPDI=%d counter %d\n", TPID, counter); + // printf("Pass second attack!\n"); + + // restore the vtable pointers to the original state. + // This is very important. For some reason the dlclose is not "really" closing the library so when we reopen it we are + // getting the old memory state. + exchange_vtptr(bp, dp); +} diff --git a/libvtv/testsuite/other-tests/temp_deriv.cc b/libvtv/testsuite/other-tests/temp_deriv.cc new file mode 100644 index 00000000000..ca360c0bc91 --- /dev/null +++ b/libvtv/testsuite/other-tests/temp_deriv.cc @@ -0,0 +1,67 @@ +// Compile with /home/llozano/local2/proj/vtable/gcc-root/usr/local/bin/g++ -m32 -fvtable-verify=std -fpic -rdynamic -Wl,-R,/home/llozano/local2/proj/vtable/gcc-root/usr/local/lib32:./lib32 -I/home/llozano/local2/proj/vtable/vt2/gcc-4_6-mobile-vtable-security//libstdc++-v3/libsupc++ temp_deriv.cc -O0 -ldl -lpthread -Wl,--whole-archive,-lvtv_init,--no-whole-archive,-z,relro -DTPID=0 -g +// Look at assembly with: objdump -drl a.out + +#include <dlfcn.h> +#include <assert.h> + +extern "C" int printf(const char *, ...); + +static int counter = 0; + +template <int i> struct base +{ + virtual void inc() { counter += i; } +}; + +template <int i> struct derived: base<i> +{ + virtual void inc() { counter += (10*i); } +}; + +// We don't use this class. It is just here so that the +// compiler does not devirtualize calls to derived::inc() +template <int i> struct derived2: derived<i> +{ + virtual void inc() { counter += (20*i); } +}; + +static base<TPID> * bp = new base<TPID>(); +static derived<TPID> * dp = new derived<TPID>(); +static base<TPID> * dbp = new derived<TPID>(); + +// Given 2 pointers to C++ objects (non PODs), exchange the pointers to vtable +void exchange_vtptr(void * object1_ptr, void * object2_ptr) +{ + void ** object1_vtptr_ptr = (void **)object1_ptr; + void ** object2_vtptr_ptr = (void **)object2_ptr; + void * object1_vtptr = *object1_vtptr_ptr; + void * object2_vtptr = *object2_vtptr_ptr; + *object1_vtptr_ptr = object2_vtptr; + *object2_vtptr_ptr = object1_vtptr; +} + +main() +{ + int prev_counter; + + exchange_vtptr(bp, dp); + exchange_vtptr(bp, dp); + exchange_vtptr(bp, dbp); + exchange_vtptr(bp, dbp); + + counter = 0; + bp->inc(); + dp->inc(); + dbp->inc(); + assert(counter == (TPID + 10*TPID + 10*TPID)); + + prev_counter = counter; + exchange_vtptr(bp, dp); + bp->inc(); // This one should succeed but it is calling the wrong member + assert(counter == (prev_counter + 10*TPID)); + printf("Pass first attack!\n"); + dp->inc(); + printf("TPDI=%d counter %d\n", TPID, counter); + printf("Pass second attack!\n"); + +} diff --git a/libvtv/testsuite/other-tests/temp_deriv2.cc b/libvtv/testsuite/other-tests/temp_deriv2.cc new file mode 100644 index 00000000000..78b43f8b08b --- /dev/null +++ b/libvtv/testsuite/other-tests/temp_deriv2.cc @@ -0,0 +1,69 @@ +// Compile with /home/llozano/local2/proj/vtable/gcc-root/usr/local/bin/g++ -m32 -fvtable-verify=std -fpic -rdynamic -Wl,-R,/home/llozano/local2/proj/vtable/gcc-root/usr/local/lib32:./lib32 -I/home/llozano/local2/proj/vtable/vt2/gcc-4_6-mobile-vtable-security//libstdc++-v3/libsupc++ temp_deriv.cc -O0 -ldl -lpthread -Wl,--whole-archive,-lvtv_init,--no-whole-archive,-z,relro -DTPID=0 -g +// Look at assembly with: objdump -drl a.out + +#include <dlfcn.h> +#include <assert.h> + +extern "C" int printf(const char *, ...); + +static int counter = 0; + +int i = TPID; +struct base +{ + virtual void inc() { counter += i; } +}; + +struct derived: public base +{ + virtual void inc() { counter += (10*i); } +}; + +// We don't use this class. It is just here so that the +// compiler does not devirtualize calls to derived::inc() +struct derived2: public derived +{ + virtual void inc() { counter += (20*i); } +}; + +static base * bp = new base(); +static derived * dp = new derived(); +static base * dbp = new derived(); + +// Given 2 pointers to C++ objects (non PODs), exchange the pointers to vtable +void exchange_vtptr(void * object1_ptr, void * object2_ptr) +{ + typedef void * vtptr; + vtptr * object1_vtptr_ptr = (vtptr *)object1_ptr; + vtptr * object2_vtptr_ptr = (vtptr *)object2_ptr; + vtptr object1_vtptr = *object1_vtptr_ptr; + vtptr object2_vtptr = *object2_vtptr_ptr; + *object1_vtptr_ptr = object2_vtptr; + *object2_vtptr_ptr = object1_vtptr; +} + +main() +{ + int prev_counter; + + exchange_vtptr(bp, dp); + exchange_vtptr(bp, dp); + exchange_vtptr(bp, dbp); + exchange_vtptr(bp, dbp); + + counter = 0; + bp->inc(); + dp->inc(); + dbp->inc(); + assert(counter == (TPID + 10*TPID + 10*TPID)); + + prev_counter = counter; + exchange_vtptr(bp, dp); + bp->inc(); // This one should succeed but it is calling the wrong member + assert(counter == (prev_counter + 10*TPID)); + printf("Pass first attack!\n"); + dp->inc(); + printf("TPDI=%d counter %d\n", TPID, counter); + printf("Pass second attack!\n"); + +} diff --git a/libvtv/testsuite/other-tests/temp_deriv3.cc b/libvtv/testsuite/other-tests/temp_deriv3.cc new file mode 100644 index 00000000000..924c47e9628 --- /dev/null +++ b/libvtv/testsuite/other-tests/temp_deriv3.cc @@ -0,0 +1,79 @@ +// Compile with /home/llozano/local2/proj/vtable/gcc-root/usr/local/bin/g++ -m32 -fvtable-verify=std -fpic -rdynamic -Wl,-R,/home/llozano/local2/proj/vtable/gcc-root/usr/local/lib32:./lib32 -I/home/llozano/local2/proj/vtable/vt2/gcc-4_6-mobile-vtable-security//libstdc++-v3/libsupc++ temp_deriv.cc -O0 -ldl -lpthread -Wl,--whole-archive,-lvtv_init,--no-whole-archive,-z,relro -DTPID=0 -g +// Look at assembly with: objdump -drl a.out + +#include <dlfcn.h> +#include <assert.h> +#include <stdlib.h> + +extern "C" int printf(const char *, ...); + +static int counter = 0; + +int i = TPID; +struct base +{ + virtual void inc() { counter += i; } +}; + +struct derived: public base +{ + virtual void inc() { counter += (10*i); } +}; + +// We don't use this class. It is just here so that the +// compiler does not devirtualize calls to derived::inc() +struct derived2: public derived +{ + virtual void inc() { counter += (20*i); } +}; + +static base * bp = new base(); +static derived * dp = new derived(); +static base * dbp = new derived(); + +typedef void * vtptr; + +vtptr get_vtptr(void * object_ptr) +{ + vtptr * object_vtptr_ptr = (vtptr *)object_ptr; + return *object_vtptr_ptr; +} + +void set_vptr(void * object_ptr, vtptr vtp) +{ + vtptr * object_vtptr_ptr = (vtptr *)object_ptr; + *object_vtptr_ptr = vtp; +} + +// Given 2 pointers to C++ objects (non PODs), exchange the pointers to vtable +void exchange_vtptr(void * object1_ptr, void * object2_ptr) +{ + vtptr object1_vtptr = get_vtptr(object1_ptr); + vtptr object2_vtptr = get_vtptr(object2_ptr); + set_vptr(object1_ptr, object2_vtptr); + set_vptr(object2_ptr, object1_vtptr); +} + +main() +{ + int prev_counter; + + counter = 0; + bp->inc(); + dp->inc(); + dbp->inc(); + assert(counter == (TPID + 10*TPID + 10*TPID)); + + prev_counter = counter; + printf("before ex bp vptr=%x dp vptr=%x\n", get_vtptr(bp), get_vtptr(dp)); + exchange_vtptr(bp, dp); + printf("after ex bp vptr=%x dp vptr=%x\n", get_vtptr(bp), get_vtptr(dp)); + bp->inc(); // This one should not abort but it is calling the wrong member + assert(counter == (prev_counter + 10*TPID)); + printf("Pass first attack! Expected!\n"); + printf("TPDI=%d counter %d\n", TPID, counter); + dp->inc(); + printf("Pass second attack! SHOULD NOT BE HERE!\n"); + printf("TPDI=%d counter %d\n", TPID, counter); + exit(1); +} |