summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Kosnik <bkoz@redhat.com>2013-07-23 15:57:28 -0700
committerBenjamin Kosnik <bkoz@redhat.com>2013-07-23 15:57:28 -0700
commit3a5e88c81fe62083d80b4d302194878c9cee4337 (patch)
tree604d042f2679b6f2f4bebd7c002993ee235d91f4
parent1d616fe497694adb9617bfa0a8ecbf4bd22f314b (diff)
downloadgcc-3a5e88c81fe62083d80b4d302194878c9cee4337.tar.gz
gcc
2013-07-15 Benjamin Kosnik <bkoz@redhat.com> * aclocal.m4: Regenerate. 2013-07-15 Caroline Tice <cmtice@google.com> * gcc.c (VTABLE_VERIFICATION_SPEC): Add comments, stub out SPECs for future library placement. * vtable-verify.c: Use flag_vtv_debug, not vtv_debug. gcc/cp 2013-07-15 Caroline Tice <cmtice@google.com> * vtable-class-hierarchy.c: Use flag_vtv_debug, not vtv_debug. libstdc++ 2013-07-15 Benjamin Kosnik <bkoz@redhat.com> * acinclude.m4 (GLIBCXX_ENABLE_VTABLE_VERIFY):Adjust VTV_CXXFLAGS to be non-linking only, VTV_CXXLINKFLAGS to have exclusively link commands. * configure: Regenerated. * libsupc++/vtv_stubs.cc: Mark declarations weak. Add stub definitions. * libsupc++/Makefile.am (vtv_sources): Conditionally compile vtv_stubs.cc based on ENABLE_VTABLE_VERIFY. (libsupc___la_SOURCES, libsupc__convenience_la_SOURCES): Same. * libsupc++/Makefile.in: Regenerate. 2013-07-15 Caroline Tice <cmtice@google.com> * testsuite/18_support/bad_exception/23591_thread-1.c: Use -fvtable-verify=none. libvtv 2013-07-15 Benjamin Kosnik <bkoz@redhat.com> * vtv_stubs.cc: Move to libsupc++. * vtv_init.cc: Move functionality to libgcc_s. * Makefile.am (vtv_stubs_sources): Remove. (libvtv_stubs_la_SOURCES): Remove. (libvtv_init_la_SOURCES): Remove. * Makefile.in: Regenerate. 2013-07-15 Caroline Tice <cmtice@google.com> * vtv_fail.h (__vtv_really_fail): Add default, noreturn, nothrow attributes. (__vtv_verify_fail, __vtv_verify_fail_debug): Add nothrow attribute. * vtv_malloc.cc (VTV_count_mmapped_pages): To __vtv_count_mmapped_pages. Add debugging hook when VTV_DEBUG defined. (VTV_malloc_protect): To __vtv_malloc_protect. (VTV_malloc_unprotect): To __vtv_malloc_unprotect. (VTV_malloc_init): To __vtv_malloc_init. (VTV_malloc): To __vtv_malloc. (VTV_free): To __vtv_free. (VTV_malloc_dump_stats): To __vtv_malloc_dump_stats. (VTV_malloc_stats): To __vtv_malloc_dump_stats. * vtv_malloc.h: Adjust for name changes as immediately above. * vtv_map.h (insert_only_hash_map): Mark get and equals member functions inline. * vtv_rts.cc: Add debug_functions, debug_init, debug_verify_vtable when VTV_DEBUG. Adjust names for interface changes. (VTV_protect_vtable_vars): To vtv_protect_vtable_vars. (log_error_message): Remove. (__vtv_verify_fail_debug): Add. (__vtv_verify_fail): Add. (vtv_fail): Add. * vtv_utils.cc (__vtv_open_log, __vtv_add_to_log) (__vtv_log_verification): Uglify to declarations. * vtv_utils.h (vtv_failures_log_fd): New. (vtv_open_log): Uglify to __vtv_open_log. (vtv_add_to_log): Uglify to __vtv_add_to_log. (__vtv_log_verification): New.
-rw-r--r--gcc/ChangeLog.vtv10
-rw-r--r--gcc/aclocal.m410
-rw-r--r--gcc/cp/ChangeLog.vtv4
-rw-r--r--gcc/cp/vtable-class-hierarchy.c20
-rw-r--r--gcc/gcc.c13
-rw-r--r--gcc/vtable-verify.c3
-rw-r--r--libstdc++-v3/ChangeLog.vtv18
-rw-r--r--libstdc++-v3/acinclude.m45
-rwxr-xr-xlibstdc++-v3/configure5
-rw-r--r--libstdc++-v3/include/Makefile.am2
-rw-r--r--libstdc++-v3/include/Makefile.in2
-rw-r--r--libstdc++-v3/libsupc++/Makefile.am9
-rw-r--r--libstdc++-v3/libsupc++/Makefile.in14
-rw-r--r--libstdc++-v3/libsupc++/vtv_stubs.cc96
-rw-r--r--libstdc++-v3/testsuite/18_support/bad_exception/23591_thread-1.c2
-rw-r--r--libvtv/ChangeLog40
-rw-r--r--libvtv/Makefile.am11
-rw-r--r--libvtv/Makefile.in33
-rw-r--r--libvtv/vtv_fail.h7
-rw-r--r--libvtv/vtv_malloc.cc41
-rw-r--r--libvtv/vtv_malloc.h16
-rw-r--r--libvtv/vtv_map.h4
-rw-r--r--libvtv/vtv_rts.cc276
-rw-r--r--libvtv/vtv_stubs.cc101
-rw-r--r--libvtv/vtv_utils.cc40
-rw-r--r--libvtv/vtv_utils.h21
26 files changed, 492 insertions, 311 deletions
diff --git a/gcc/ChangeLog.vtv b/gcc/ChangeLog.vtv
index 83c38185f44..bbd0ad2dfc7 100644
--- a/gcc/ChangeLog.vtv
+++ b/gcc/ChangeLog.vtv
@@ -1,3 +1,13 @@
+2013-07-15 Benjamin Kosnik <bkoz@redhat.com>
+
+ * aclocal.m4: Regenerate.
+
+2013-07-15 Caroline Tice <cmtice@google.com>
+
+ * gcc.c (VTABLE_VERIFICATION_SPEC): Add comments, stub out SPECs
+ for future library placement.
+ * vtable-verify.c: Use flag_vtv_debug, not vtv_debug.
+
2013-07-09 Caroline Tice <cmtice@google.com>
* config/gnu-user.h: Update SPECS to properly handle cases where
diff --git a/gcc/aclocal.m4 b/gcc/aclocal.m4
index a992c3a96ed..1f3ce9d6935 100644
--- a/gcc/aclocal.m4
+++ b/gcc/aclocal.m4
@@ -99,11 +99,6 @@ m4_define([AC_PROG_CC],
[m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
])
-m4_include([../libtool.m4])
-m4_include([../ltoptions.m4])
-m4_include([../ltsugar.m4])
-m4_include([../ltversion.m4])
-m4_include([../lt~obsolete.m4])
m4_include([../config/acx.m4])
m4_include([../config/codeset.m4])
m4_include([../config/dfp.m4])
@@ -119,4 +114,9 @@ m4_include([../config/picflag.m4])
m4_include([../config/progtest.m4])
m4_include([../config/stdint.m4])
m4_include([../config/warnings.m4])
+m4_include([../libtool.m4])
+m4_include([../ltoptions.m4])
+m4_include([../ltsugar.m4])
+m4_include([../ltversion.m4])
+m4_include([../lt~obsolete.m4])
m4_include([acinclude.m4])
diff --git a/gcc/cp/ChangeLog.vtv b/gcc/cp/ChangeLog.vtv
index ac90187a992..f4c08758b8d 100644
--- a/gcc/cp/ChangeLog.vtv
+++ b/gcc/cp/ChangeLog.vtv
@@ -1,3 +1,7 @@
+2013-07-15 Caroline Tice <cmtice@google.com>
+
+ * vtable-class-hierarchy.c: Use flag_vtv_debug, not vtv_debug.
+
2013-07-03 Benjamin Kosnik <bkoz@redhat.com>
* vtable-class-hierarchy.c (output_set_info): Remove unused variables.
diff --git a/gcc/cp/vtable-class-hierarchy.c b/gcc/cp/vtable-class-hierarchy.c
index c8d7d713eb1..61d74f2c7e0 100644
--- a/gcc/cp/vtable-class-hierarchy.c
+++ b/gcc/cp/vtable-class-hierarchy.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2012 Free Software Foundation, Inc.
+/* Copyright (C) 2012-2013 Free Software Foundation, Inc.
This file is part of GCC.
@@ -162,7 +162,7 @@ struct vtbl_map_node *vtable_find_or_create_map_decl (tree);
__VLTVerifyVtablePointerDebug which can be used in place of
__VLTVerifyVtablePointer, and which takes extra parameters and
outputs extra information, to help debug problems. The debug
- version of this function is generated and used if vtv_debug is
+ version of this function is generated and used if flag_vtv_debug is
true.
The signatures for these functions are:
@@ -180,7 +180,7 @@ vtv_build_vtable_verify_fndecl (void)
&& TREE_CODE (verify_vtbl_ptr_fndecl) != ERROR_MARK)
return;
- if (vtv_debug)
+ if (flag_vtv_debug)
{
func_type = build_function_type_list (const_ptr_type_node,
build_pointer_type (ptr_type_node),
@@ -256,7 +256,7 @@ init_functions (void)
build_pointer_type (ptr_type_node),
NULL_TREE);
- if (vtv_debug)
+ if (flag_vtv_debug)
vlt_register_set_fndecl = build_lang_decl
(FUNCTION_DECL,
get_identifier ("__VLTRegisterSetDebug"),
@@ -278,7 +278,7 @@ init_functions (void)
/* Build function decl for __VLTRegisterPair*. */
- if (vtv_debug)
+ if (flag_vtv_debug)
{
register_pairs_type = build_function_type_list (void_type_node,
build_pointer_type
@@ -771,7 +771,6 @@ insert_call_to_register_set (tree class_name, int num_args,
vec<constructor_elt, va_gc> *array_elements;
vec_alloc (array_elements, num_args);
- /* constructor_elt *celt; */
tree initial = NULL_TREE;
tree arg3 = NULL_TREE;
@@ -786,11 +785,6 @@ insert_call_to_register_set (tree class_name, int num_args,
for (k = 0; k < num_args; ++k)
{
- /*
- vec_safe_push (array_elements, celt);
- celt->index = build_int_cst (integer_type_node, k);
- celt->value = vtbl_ptr_array[k];
- */
CONSTRUCTOR_APPEND_ELT (array_elements, NULL_TREE, vtbl_ptr_array[k]);
}
@@ -825,7 +819,7 @@ insert_call_to_register_pair (tree vtable_address, int num_args, tree arg1,
if (num_args == 0)
vtable_address = build_int_cst (build_pointer_type (void_type_node), 0);
- if (vtv_debug)
+ if (flag_vtv_debug)
call_expr = build_call_expr (vlt_register_pairs_fndecl, 6, arg1, arg2,
size_hint_arg, vtable_address, str1, str2);
else
@@ -911,7 +905,7 @@ register_all_pairs (tree body)
gcc_assert (current->class_info != NULL);
- if (vtv_debug)
+ if (flag_vtv_debug)
str1 = build_string_from_id (DECL_NAME (base_ptr_var_decl));
new_type = build_pointer_type (TREE_TYPE (base_ptr_var_decl));
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 97dd57ac265..7444aab8928 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -722,11 +722,24 @@ proper position among the other output files. */
%{!pie:%{!shared:%e-fsanitize=thread linking must be done with -pie or -shared}}}}}"
#endif
+/* This is the spec to use, once the code for creating the vtable
+ verification runtime library, libvtv.so, has been created. Currently
+ the vtable verification runtime functions are in libstdc++, so we use
+ the spec just below this one. */
+/*
#ifndef VTABLE_VERIFICATION_SPEC
#define VTABLE_VERIFICATION_SPEC "\
%{!nostdlib:%{fvtable-verify=std: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}\
%{fvtable-verify=preinit: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}}"
#endif
+*/
+
+/* Once libvtv.so has been created, delete this spec and use the one above. */
+#ifndef VTABLE_VERIFICATION_SPEC
+#define VTABLE_VERIFICATION_SPEC "\
+%{!nostdlib:%{fvtable-verify=std: -u_vtable_map_vars_start -u_vtable_map_vars_end}\
+ %{fvtable-verify=preinit: -u_vtable_map_vars_start -u_vtable_map_vars_end}}"
+#endif
/* -u* was put back because both BSD and SysV seem to support it. */
/* %{static:} simply prevents an error message if the target machine
diff --git a/gcc/vtable-verify.c b/gcc/vtable-verify.c
index 749dfb33a89..e48f21f1fb2 100644
--- a/gcc/vtable-verify.c
+++ b/gcc/vtable-verify.c
@@ -157,7 +157,6 @@ along with GCC; see the file COPYING3. If not see
#include "vtable-verify.h"
-bool vtv_debug = false;
unsigned num_vtable_map_nodes = 0;
bool any_verification_calls_generated = false;
int total_num_virtual_calls = 0;
@@ -658,7 +657,7 @@ verify_bb_vtables (basic_block bb)
/* Call different routines if we are interested in
trace information to debug problems. */
- if (vtv_debug)
+ if (flag_vtv_debug)
{
int len1 = IDENTIFIER_LENGTH
(DECL_NAME (vtbl_var_decl));
diff --git a/libstdc++-v3/ChangeLog.vtv b/libstdc++-v3/ChangeLog.vtv
index 2a47069f177..5a5ffae5562 100644
--- a/libstdc++-v3/ChangeLog.vtv
+++ b/libstdc++-v3/ChangeLog.vtv
@@ -1,3 +1,21 @@
+2013-07-15 Benjamin Kosnik <bkoz@redhat.com>
+
+ * acinclude.m4 (GLIBCXX_ENABLE_VTABLE_VERIFY):Adjust VTV_CXXFLAGS
+ to be non-linking only, VTV_CXXLINKFLAGS to have exclusively link
+ commands.
+ * configure: Regenerated.
+
+ * libsupc++/vtv_stubs.cc: Mark declarations weak. Add stub definitions.
+ * libsupc++/Makefile.am (vtv_sources): Conditionally compile
+ vtv_stubs.cc based on ENABLE_VTABLE_VERIFY.
+ (libsupc___la_SOURCES, libsupc__convenience_la_SOURCES): Same.
+ * libsupc++/Makefile.in: Regenerate.
+
+2013-07-15 Caroline Tice <cmtice@google.com>
+
+ * testsuite/18_support/bad_exception/23591_thread-1.c: Use
+ -fvtable-verify=none.
+
2013-07-12 Benjamin Kosnik <bkoz@redhat.com>
* libsupc++/vterminate.cc: Add back deleted file.
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index 97c47b94a24..e149931a89e 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -2301,8 +2301,9 @@ AC_DEFUN([GLIBCXX_ENABLE_VTABLE_VERIFY], [
AC_MSG_RESULT([$enable_vtable_verify])
if test $enable_vtable_verify = yes; then
- VTV_CXXFLAGS="-fvtable-verify=std -Wl,-u_vtable_map_vars_start,-u_vtable_map_vars_end"
- VTV_CXXLINKFLAGS="-L${top_builddir}/libvtv/.libs -Wl,-lvtv"
+ VTV_CXXFLAGS="-fvtable-verify=std"
+# VTV_CXXLINKFLAGS="-L${top_builddir}/libvtv/.libs -Wl,-lvtv -Wl,-u_vtable_map_vars_start,-u_vtable_map_vars_end"
+ VTV_CXXLINKFLAGS="-Wl,-u_vtable_map_vars_start,-u_vtable_map_vars_end"
else
VTV_CXXFLAGS=
VTV_CXXLINKFLAGS=
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 595b00d5d37..1206481e9c7 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -17412,8 +17412,9 @@ $as_echo_n "checking for vtable verify support... " >&6; }
$as_echo "$enable_vtable_verify" >&6; }
if test $enable_vtable_verify = yes; then
- VTV_CXXFLAGS="-fvtable-verify=std -Wl,-u_vtable_map_vars_start,-u_vtable_map_vars_end"
- VTV_CXXLINKFLAGS="-L${top_builddir}/libvtv/.libs -Wl,-lvtv"
+ VTV_CXXFLAGS="-fvtable-verify=std"
+# VTV_CXXLINKFLAGS="-L${top_builddir}/libvtv/.libs -Wl,-lvtv -Wl,-u_vtable_map_vars_start,-u_vtable_map_vars_end"
+ VTV_CXXLINKFLAGS="-Wl,-u_vtable_map_vars_start,-u_vtable_map_vars_end"
else
VTV_CXXFLAGS=
VTV_CXXLINKFLAGS=
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 801a8858087..5a4af85f83c 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -893,7 +893,7 @@ pch_output_dirs = \
${pch1_output_builddir} ${pch2_output_builddir} ${pch3_output_builddir}
pch_output_anchors = \
${pch1_output_anchor} ${pch2_output_anchor} ${pch3_output_anchor}
-PCHFLAGS=-x c++-header -nostdinc++ $(CXXFLAGS)
+PCHFLAGS=-x c++-header -nostdinc++ $(CXXFLAGS) $(VTV_CXXFLAGS)
if GLIBCXX_BUILD_PCH
pch_build = ${pch_output}
else
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 88341183d85..2880504a266 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -1151,7 +1151,7 @@ pch_output_dirs = \
pch_output_anchors = \
${pch1_output_anchor} ${pch2_output_anchor} ${pch3_output_anchor}
-PCHFLAGS = -x c++-header -nostdinc++ $(CXXFLAGS)
+PCHFLAGS = -x c++-header -nostdinc++ $(CXXFLAGS) $(VTV_CXXFLAGS)
@GLIBCXX_BUILD_PCH_FALSE@pch_build =
@GLIBCXX_BUILD_PCH_TRUE@pch_build = ${pch_output}
diff --git a/libstdc++-v3/libsupc++/Makefile.am b/libstdc++-v3/libsupc++/Makefile.am
index 032c8a2ac5b..f0ab6026ca3 100644
--- a/libstdc++-v3/libsupc++/Makefile.am
+++ b/libstdc++-v3/libsupc++/Makefile.am
@@ -97,8 +97,13 @@ sources = \
vmi_class_type_info.cc \
vterminate.cc
-libsupc___la_SOURCES = $(sources) $(c_sources)
-libsupc__convenience_la_SOURCES = $(sources) $(c_sources)
+if ENABLE_VTABLE_VERIFY
+ vtv_sources = \
+ vtv_stubs.cc
+endif
+
+libsupc___la_SOURCES = $(sources) $(c_sources) $(vtv_sources)
+libsupc__convenience_la_SOURCES = $(sources) $(c_sources) $(vtv_sources)
cp-demangle.c:
rm -f $@
diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in
index 22accce5e64..a9f8d78eea8 100644
--- a/libstdc++-v3/libsupc++/Makefile.in
+++ b/libstdc++-v3/libsupc++/Makefile.in
@@ -105,10 +105,13 @@ am__objects_1 = array_type_info.lo atexit_arm.lo atexit_thread.lo \
pointer_type_info.lo pure.lo si_class_type_info.lo tinfo.lo \
tinfo2.lo vec.lo vmi_class_type_info.lo vterminate.lo
@GLIBCXX_HOSTED_TRUE@am__objects_2 = cp-demangle.lo
-am_libsupc___la_OBJECTS = $(am__objects_1) $(am__objects_2)
+@ENABLE_VTABLE_VERIFY_TRUE@am__objects_3 = vtv_stubs.lo
+am_libsupc___la_OBJECTS = $(am__objects_1) $(am__objects_2) \
+ $(am__objects_3)
libsupc___la_OBJECTS = $(am_libsupc___la_OBJECTS)
libsupc__convenience_la_LIBADD =
-am_libsupc__convenience_la_OBJECTS = $(am__objects_1) $(am__objects_2)
+am_libsupc__convenience_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
+ $(am__objects_3)
libsupc__convenience_la_OBJECTS = \
$(am_libsupc__convenience_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
@@ -419,8 +422,11 @@ sources = \
vmi_class_type_info.cc \
vterminate.cc
-libsupc___la_SOURCES = $(sources) $(c_sources)
-libsupc__convenience_la_SOURCES = $(sources) $(c_sources)
+@ENABLE_VTABLE_VERIFY_TRUE@vtv_sources = \
+@ENABLE_VTABLE_VERIFY_TRUE@ vtv_stubs.cc
+
+libsupc___la_SOURCES = $(sources) $(c_sources) $(vtv_sources)
+libsupc__convenience_la_SOURCES = $(sources) $(c_sources) $(vtv_sources)
# AM_CXXFLAGS needs to be in each subdirectory so that it can be
# modified in a per-library or per-sub-library way. Need to manually
diff --git a/libstdc++-v3/libsupc++/vtv_stubs.cc b/libstdc++-v3/libsupc++/vtv_stubs.cc
new file mode 100644
index 00000000000..7dbff10713f
--- /dev/null
+++ b/libstdc++-v3/libsupc++/vtv_stubs.cc
@@ -0,0 +1,96 @@
+// Copyright (C) 2012-2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ 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.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/* This is part of the vtable verification runtime library. For more
+ information about this feature, see the comments in libvtv/vtv_rts.cc. */
+
+/* The functions in this file are used to create the libvtv_stubs
+ library, as part of the vtable verification feature. When building
+ a binary without vtable verification, and linking it with a
+ (possibly pre-built third-party) library that was built with
+ verification, it is possible that vtable verification will fail due
+ to incomplete data (rather than due to corrupt vtable pointers). In
+ this case we need to give programmers a way of turning off the
+ vtable verification in their libraries. They can do so by linking
+ with the libvtv_stubs library, which (as you can see) will replace
+ the real verification functions with a set of functions that do
+ nothing (so no more verification failures/aborts). */
+
+// Declare as weak for libsupc++.
+extern "C"
+void
+__VLTChangePermission(int) __attribute__((weak));
+
+void
+__VLTRegisterSet(void**, const void*, std::size_t, std::size_t,
+ void**) __attribute__((weak));
+
+void
+__VLTRegisterPair(void**, const void*, std::size_t,
+ const void*) __attribute__((weak));
+
+const void*
+__VLTVerifyVtablePointer(void**, const void*) __attribute__((weak));
+
+void
+__VLTRegisterSetDebug(void**, const void*, std::size_t, std::size_t,
+ void**) __attribute__((weak));
+
+void
+__VLTRegisterPairDebug(void**, const void*, std::size_t, const void*,
+ const char*, const char*) __attribute__((weak));
+
+const void*
+__VLTVerifyVtablePointerDebug(void**, const void*, const char*,
+ const char*) __attribute__((weak));
+
+// Stub definitions.
+extern "C"
+void
+__VLTChangePermission(int)
+{ }
+
+void
+__VLTRegisterSet(void**, const void*, std::size_t, std::size_t, void**)
+{ }
+
+void
+__VLTRegisterPair(void**, const void*, std::size_t, const void*)
+{ }
+
+const void*
+__VLTVerifyVtablePointer(void**, const void* vtable_ptr)
+{ return vtable_ptr; }
+
+void
+__VLTRegisterSetDebug(void**, const void*, std::size_t, std::size_t, void**)
+{ }
+
+void
+__VLTRegisterPairDebug(void**, const void*, std::size_t, const void*,
+ const char*, const char*)
+{ }
+
+const void*
+__VLTVerifyVtablePointerDebug(void**, const void* vtable_ptr, const char*,
+ const char*)
+{ return vtable_ptr; }
diff --git a/libstdc++-v3/testsuite/18_support/bad_exception/23591_thread-1.c b/libstdc++-v3/testsuite/18_support/bad_exception/23591_thread-1.c
index e7cabc30bd2..0b8d1e26d3b 100644
--- a/libstdc++-v3/testsuite/18_support/bad_exception/23591_thread-1.c
+++ b/libstdc++-v3/testsuite/18_support/bad_exception/23591_thread-1.c
@@ -1,5 +1,5 @@
// { dg-require-sharedlib "" }
-// { dg-options "-g -O2 -pthread -ldl -x c" { target *-*-linux* *-*-gnu* } }
+// { dg-options "-g -O2 -pthread -ldl -x c -fvtable-verify=none" { target *-*-linux* *-*-gnu* } }
// Copyright (C) 2005-2013 Free Software Foundation, Inc.
//
diff --git a/libvtv/ChangeLog b/libvtv/ChangeLog
index 6ea35b1da73..ed13b6cce66 100644
--- a/libvtv/ChangeLog
+++ b/libvtv/ChangeLog
@@ -1,3 +1,43 @@
+2013-07-15 Benjamin Kosnik <bkoz@redhat.com>
+
+ * vtv_stubs.cc: Move to libsupc++.
+ * vtv_init.cc: Move functionality to libgcc_s.
+ * Makefile.am (vtv_stubs_sources): Remove.
+ (libvtv_stubs_la_SOURCES): Remove.
+ (libvtv_init_la_SOURCES): Remove.
+ * Makefile.in: Regenerate.
+
+2013-07-15 Caroline Tice <cmtice@google.com>
+
+ * vtv_fail.h (__vtv_really_fail): Add default, noreturn, nothrow
+ attributes.
+ (__vtv_verify_fail, __vtv_verify_fail_debug): Add nothrow attribute.
+ * vtv_malloc.cc (VTV_count_mmapped_pages): To __vtv_count_mmapped_pages.
+ Add debugging hook when VTV_DEBUG defined.
+ (VTV_malloc_protect): To __vtv_malloc_protect.
+ (VTV_malloc_unprotect): To __vtv_malloc_unprotect.
+ (VTV_malloc_init): To __vtv_malloc_init.
+ (VTV_malloc): To __vtv_malloc.
+ (VTV_free): To __vtv_free.
+ (VTV_malloc_dump_stats): To __vtv_malloc_dump_stats.
+ (VTV_malloc_stats): To __vtv_malloc_dump_stats.
+ * vtv_malloc.h: Adjust for name changes as immediately above.
+ * vtv_map.h (insert_only_hash_map): Mark get and equals member
+ functions inline.
+ * vtv_rts.cc: Add debug_functions, debug_init, debug_verify_vtable
+ when VTV_DEBUG. Adjust names for interface changes.
+ (VTV_protect_vtable_vars): To vtv_protect_vtable_vars.
+ (log_error_message): Remove.
+ (__vtv_verify_fail_debug): Add.
+ (__vtv_verify_fail): Add.
+ (vtv_fail): Add.
+ * vtv_utils.cc (__vtv_open_log, __vtv_add_to_log)
+ (__vtv_log_verification): Uglify to declarations.
+ * vtv_utils.h (vtv_failures_log_fd): New.
+ (vtv_open_log): Uglify to __vtv_open_log.
+ (vtv_add_to_log): Uglify to __vtv_add_to_log.
+ (__vtv_log_verification): New.
+
2013-07-11 Benjamin Kosnik <bkoz@adair>
* libvtv/vtv_rts.cc: Remove unused variables.
diff --git a/libvtv/Makefile.am b/libvtv/Makefile.am
index e13e8fafa94..4455016df5c 100644
--- a/libvtv/Makefile.am
+++ b/libvtv/Makefile.am
@@ -33,7 +33,7 @@ AM_CCASFLAGS = $(XCFLAGS)
AM_CXXFLAGS = $(XCFLAGS)
AM_CXXFLAGS += $(LIBSTDCXX_RAW_CXX_CXXFLAGS)
-toolexeclib_LTLIBRARIES = libvtv.la libvtv_stubs.la libvtv_init.la
+toolexeclib_LTLIBRARIES = libvtv.la
vtv_headers = \
vtv_map.h \
@@ -44,20 +44,11 @@ vtv_headers = \
vtv_rts.h
vtv_sources = \
- vtv_fail.cc \
vtv_malloc.cc \
vtv_rts.cc \
vtv_utils.cc
-vtv_stubs_sources = \
- vtv_stubs.cc
-
-vtv_init_sources = \
- vtv_init.cc
-
libvtv_la_SOURCES = $(vtv_sources)
-libvtv_stubs_la_SOURCES = $(vtv_stubs_sources)
-libvtv_init_la_SOURCES = $(vtv_init_sources)
libvtv_includedir = $(includedir)
libvtv_include_HEADERS = $(vtv_headers)
diff --git a/libvtv/Makefile.in b/libvtv/Makefile.in
index 4ec543a6df4..57013efd9f9 100644
--- a/libvtv/Makefile.in
+++ b/libvtv/Makefile.in
@@ -37,7 +37,7 @@ build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = .
-DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+DIST_COMMON = ChangeLog $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/configure $(am__configure_deps) \
$(srcdir)/../mkinstalldirs $(srcdir)/../depcomp \
$(libvtv_include_HEADERS)
@@ -84,17 +84,9 @@ am__installdirs = "$(DESTDIR)$(toolexeclibdir)" \
"$(DESTDIR)$(libvtv_includedir)"
LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
libvtv_la_LIBADD =
-am__objects_1 = vtv_fail.lo vtv_malloc.lo vtv_rts.lo vtv_utils.lo
+am__objects_1 = vtv_malloc.lo vtv_rts.lo vtv_utils.lo
am_libvtv_la_OBJECTS = $(am__objects_1)
libvtv_la_OBJECTS = $(am_libvtv_la_OBJECTS)
-libvtv_init_la_LIBADD =
-am__objects_2 = vtv_init.lo
-am_libvtv_init_la_OBJECTS = $(am__objects_2)
-libvtv_init_la_OBJECTS = $(am_libvtv_init_la_OBJECTS)
-libvtv_stubs_la_LIBADD =
-am__objects_3 = vtv_stubs.lo
-am_libvtv_stubs_la_OBJECTS = $(am__objects_3)
-libvtv_stubs_la_OBJECTS = $(am_libvtv_stubs_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/../depcomp
am__depfiles_maybe = depfiles
@@ -102,8 +94,7 @@ am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
CXXLD = $(CXX)
-SOURCES = $(libvtv_la_SOURCES) $(libvtv_init_la_SOURCES) \
- $(libvtv_stubs_la_SOURCES)
+SOURCES = $(libvtv_la_SOURCES)
MULTISRCTOP =
MULTIBUILDTOP =
MULTIDIRS =
@@ -255,7 +246,7 @@ AM_CFLAGS = $(XCFLAGS)
AM_CCASFLAGS = $(XCFLAGS)
#AM_LDFLAGS = $(XLDFLAGS) $(SECTION_LDFLAGS) $(OPT_LDFLAGS)
AM_CXXFLAGS = $(XCFLAGS) $(LIBSTDCXX_RAW_CXX_CXXFLAGS)
-toolexeclib_LTLIBRARIES = libvtv.la libvtv_stubs.la libvtv_init.la
+toolexeclib_LTLIBRARIES = libvtv.la
vtv_headers = \
vtv_map.h \
vtv_malloc.h \
@@ -265,20 +256,11 @@ vtv_headers = \
vtv_rts.h
vtv_sources = \
- vtv_fail.cc \
vtv_malloc.cc \
vtv_rts.cc \
vtv_utils.cc
-vtv_stubs_sources = \
- vtv_stubs.cc
-
-vtv_init_sources = \
- vtv_init.cc
-
libvtv_la_SOURCES = $(vtv_sources)
-libvtv_stubs_la_SOURCES = $(vtv_stubs_sources)
-libvtv_init_la_SOURCES = $(vtv_init_sources)
libvtv_includedir = $(includedir)
libvtv_include_HEADERS = $(vtv_headers)
#noinst_HEADERS = config.h
@@ -369,10 +351,6 @@ clean-toolexeclibLTLIBRARIES:
done
libvtv.la: $(libvtv_la_OBJECTS) $(libvtv_la_DEPENDENCIES)
$(CXXLINK) -rpath $(toolexeclibdir) $(libvtv_la_OBJECTS) $(libvtv_la_LIBADD) $(LIBS)
-libvtv_init.la: $(libvtv_init_la_OBJECTS) $(libvtv_init_la_DEPENDENCIES)
- $(CXXLINK) -rpath $(toolexeclibdir) $(libvtv_init_la_OBJECTS) $(libvtv_init_la_LIBADD) $(LIBS)
-libvtv_stubs.la: $(libvtv_stubs_la_OBJECTS) $(libvtv_stubs_la_DEPENDENCIES)
- $(CXXLINK) -rpath $(toolexeclibdir) $(libvtv_stubs_la_OBJECTS) $(libvtv_stubs_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -380,11 +358,8 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vtv_fail.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vtv_init.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vtv_malloc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vtv_rts.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vtv_stubs.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vtv_utils.Plo@am__quote@
.cc.o:
diff --git a/libvtv/vtv_fail.h b/libvtv/vtv_fail.h
index ff525b919a9..30741616a46 100644
--- a/libvtv/vtv_fail.h
+++ b/libvtv/vtv_fail.h
@@ -32,7 +32,8 @@
attempt to rewrite __vtv_really_fail. */
extern void
-__vtv_really_fail (const char *fail_msg) __attribute__ ((noreturn));
+__vtv_really_fail (const char *fail_msg)
+ __attribute__ ((visibility ("default"), noreturn, nothrow));
/* __vtv_verify_fail is the function that gets called if the vtable
verification code discovers a vtable pointer that it cannot verify
@@ -48,11 +49,11 @@ __vtv_really_fail (const char *fail_msg) __attribute__ ((noreturn));
extern void
__vtv_verify_fail (void **data_set_ptr, const void *vtbl_pointer)
- __attribute__((visibility ("default")));
+ __attribute__((visibility ("default"), nothrow));
extern void
__vtv_verify_fail_debug (void **data_set_ptr, const void *vtbl_pointer,
const char *debug_msg)
- __attribute__((visibility ("default")));
+ __attribute__((visibility ("default"), nothrow));
#endif /* _VTV_FAIL_H */
diff --git a/libvtv/vtv_malloc.cc b/libvtv/vtv_malloc.cc
index 90987b1026e..f4725c20268 100644
--- a/libvtv/vtv_malloc.cc
+++ b/libvtv/vtv_malloc.cc
@@ -55,20 +55,18 @@ unsigned int long long mprotect_cycles = 0;
/* Put the following variables in our ".vtable_map_vars" section so
that they are protected. They are explicitly unprotected and
- protected again by calls to VTV_unprotect and VTV_protect */
+ protected again by calls to __vtv_unprotect and __vtv_protect */
-static struct obstack VTV_obstack VTV_PROTECTED_VAR;
+static struct obstack vtv_obstack VTV_PROTECTED_VAR;
static void *current_chunk VTV_PROTECTED_VAR = 0;
static size_t current_chunk_size VTV_PROTECTED_VAR = 0;
static int malloc_initialized VTV_PROTECTED_VAR = 0;
-static bool debug_malloc = false;
-
/* The function goes through and counts all the pages we have allocated
so far. It returns the page count. */
int
-VTV_count_mmapped_pages (void)
+__vtv_count_mmapped_pages (void)
{
int count = 0;
struct _obstack_chunk * ci = (struct _obstack_chunk *) current_chunk;
@@ -130,14 +128,15 @@ change_protections_on_data_chunks (int protection_flag)
num_pages_protected += (total_size + VTV_PAGE_SIZE - 1)/ VTV_PAGE_SIZE;
}
- if (debug_malloc)
+#ifdef VTV_DEBUG
VTV_malloc_dump_stats ();
+#endif
}
/* This function makes all of our allocated pages read-only. */
void
-VTV_malloc_protect (void)
+__vtv_malloc_protect (void)
{
change_protections_on_data_chunks (PROT_READ);
}
@@ -145,7 +144,7 @@ VTV_malloc_protect (void)
/* This function makes all of our allocated pages read-write. */
void
-VTV_malloc_unprotect (void)
+__vtv_malloc_unprotect (void)
{
change_protections_on_data_chunks (PROT_READ | PROT_WRITE);
}
@@ -175,7 +174,7 @@ obstack_chunk_alloc (size_t size)
}
static void
-obstack_chunk_free (size_t)
+obstack_chunk_free (size_t size)
{
/* Do nothing. For our purposes there should be very little
de-allocation. */
@@ -185,7 +184,7 @@ obstack_chunk_free (size_t)
memory allocation scheme. */
void
-VTV_malloc_init (void)
+__vtv_malloc_init (void)
{
/* Make sure we only execute the main body of this function ONCE. */
if (malloc_initialized)
@@ -194,14 +193,14 @@ VTV_malloc_init (void)
if (VTV_PAGE_SIZE != sysconf (_SC_PAGE_SIZE))
VTV_error ();
- obstack_chunk_size (&VTV_obstack) = VTV_PAGE_SIZE;
- obstack_alignment_mask (&VTV_obstack) = sizeof (long) - 1;
+ obstack_chunk_size (&vtv_obstack) = VTV_PAGE_SIZE;
+ obstack_alignment_mask (&vtv_obstack) = sizeof (long) - 1;
/* We guarantee that the obstack alloc failed handler will never be
called because in case the allocation of the chunk fails, it will
never return */
obstack_alloc_failed_handler = NULL;
- obstack_init (&VTV_obstack);
+ obstack_init (&vtv_obstack);
malloc_initialized = 1;
}
@@ -209,16 +208,16 @@ VTV_malloc_init (void)
the requested number of bytes to be allocated/ */
void *
-VTV_malloc (size_t size)
+__vtv_malloc (size_t size)
{
- return obstack_alloc (&VTV_obstack, size);
+ return obstack_alloc (&vtv_obstack, size);
}
/* This is our external interface for memory deallocation. */
void
-VTV_free (void *)
+__vtv_free (void *)
{
/* Do nothing. We dont care about recovering unneded memory at this
time. */
@@ -228,7 +227,7 @@ VTV_free (void *)
/* This is a debugging function tat collects statistics about our
memory allocation. */
void
-VTV_malloc_stats (void)
+__vtv_malloc_stats (void)
{
int count = 0;
struct _obstack_chunk * ci = (struct _obstack_chunk *) current_chunk;
@@ -238,7 +237,7 @@ VTV_malloc_stats (void)
ci = ci->prev;
}
fprintf (stderr,
- "VTV_malloc_stats:\n Page Size = %i bytes\n "
+ "__vtv_malloc_stats:\n Page Size = %lu bytes\n "
"Number of pages = %d\n", VTV_PAGE_SIZE, count);
}
@@ -246,12 +245,12 @@ VTV_malloc_stats (void)
statistics to a log file. */
void
-VTV_malloc_dump_stats (void)
+__vtv_malloc_dump_stats (void)
{
static int fd = -1;
if (fd == -1)
- fd = vtv_open_log ("vtv_mem_protection.log");
+ fd = __vtv_open_log ("vtv_mem_protection.log");
if (fd == -1)
return;
@@ -263,5 +262,5 @@ VTV_malloc_dump_stats (void)
ci = ci->prev;
}
- vtv_add_to_log (fd, "VTV_malloc_protect protected=%d pages\n", count);
+ __vtv_add_to_log (fd, "__vtv_malloc_protect protected=%d pages\n", count);
}
diff --git a/libvtv/vtv_malloc.h b/libvtv/vtv_malloc.h
index 2abbb5cd88c..55f5fe8022b 100644
--- a/libvtv/vtv_malloc.h
+++ b/libvtv/vtv_malloc.h
@@ -86,13 +86,13 @@ extern unsigned long long regpair_cycles;
/* Function declarations. */
-extern void VTV_malloc_init (void);
-extern void *VTV_malloc (size_t size);
-extern void VTV_free (void * ptr);
-extern void VTV_malloc_protect (void);
-extern void VTV_malloc_unprotect (void);
-extern void VTV_malloc_stats (void);
-extern void VTV_malloc_dump_stats (void);
-extern int VTV_count_mmapped_pages (void);
+extern void __vtv_malloc_init (void);
+extern void *__vtv_malloc (size_t size) __attribute__ ((malloc));
+extern void __vtv_free (void * ptr);
+extern void __vtv_malloc_protect (void);
+extern void __vtv_malloc_unprotect (void);
+extern void __vtv_malloc_stats (void);
+extern void __vtv_malloc_dump_stats (void);
+extern int __vtv_count_mmapped_pages (void);
#endif /* vtv_malloc.h */
diff --git a/libvtv/vtv_map.h b/libvtv/vtv_map.h
index a2043cf1612..ec058f845f7 100644
--- a/libvtv/vtv_map.h
+++ b/libvtv/vtv_map.h
@@ -277,7 +277,7 @@ insert_only_hash_map <T, Alloc>::put_internal (
}
template <typename T, typename Alloc>
-const typename insert_only_hash_map <T, Alloc>::value_type*
+inline const typename insert_only_hash_map <T, Alloc>::value_type*
insert_only_hash_map <T, Alloc>::get (const insert_only_hash_map::key_type *k)
const
{
@@ -298,7 +298,7 @@ insert_only_hash_map <T, Alloc>::get (const insert_only_hash_map::key_type *k)
}
template <typename T, typename Alloc>
-bool
+inline bool
insert_only_hash_map <T, Alloc>::key_type::equals (
const typename insert_only_hash_map <T, Alloc>::key_type *k) const
{
diff --git a/libvtv/vtv_rts.cc b/libvtv/vtv_rts.cc
index 8d584c2f42d..cb2b8d27b10 100644
--- a/libvtv/vtv_rts.cc
+++ b/libvtv/vtv_rts.cc
@@ -112,7 +112,7 @@
"-fvtable-verify=std" must be linked with libvtv_init.so (the gcc
driver has been modified to do this). vtv_stubs.so is built from
vtv_stubs.cc. It replaces the main runtime functions
- (__VLTChangePermission, __VLTRegisterPair and
+ (__VLTChangePermissino, __VLTRegisterPair and
__VLTVerifyVtablePointer) with stub functions that do nothing. If
a programmer has a library that was built with verification, but
wishes to not have verification turned on, the programmer can link
@@ -143,7 +143,22 @@
#include "../../include/vtv-change-permission.h"
-bool vtv_debug = false;
+extern "C" {
+
+ /* __fortify_fail is a function in glibc that calls __libc_message,
+ causing it to print out a program termination error message
+ (including the name of the binary being terminated), a stack
+ trace where the error occurred, and a memory map dump. Ideally
+ we would have called __libc_message directly, but that function
+ does not appear to be accessible to functions outside glibc,
+ whereas __fortify_fail is. We call __fortify_fail from
+ __vtv_really_fail. We looked at calling __libc_fatal, which is
+ externally accessible, but it does not do the back trace and
+ memory dump. */
+
+ extern void __fortify_fail (const char *) __attribute__((noreturn));
+
+} /* extern "C" */
/* The following variables are used only for debugging and performance
tuning purposes. Therefore they do not need to be "protected".
@@ -174,12 +189,16 @@ static const int debug_functions = 0;
static const int debug_init = 0;
static const int debug_verify_vtable = 0;
+#ifdef VTV_DEBUG
+static const int debug_functions = 1;
+static const int debug_init = 1;
+static const int debug_verify_vtable = 1;
+#endif
/* Global file descriptor variables for logging, tracing and debugging. */
static int init_log_fd = -1;
static int verify_vtable_log_fd = -1;
-static int vtv_failures_log_fd = -1;
/* This holds a formatted error logging message, to be written to the
vtable verify failures log. */
@@ -193,6 +212,10 @@ static __gthread_mutex_t change_permissions_lock;
#endif
+#ifndef VTV_STATS
+#define VTV_STATS 0
+#endif
+
#if VTV_STATS
static inline unsigned long long
@@ -272,7 +295,7 @@ struct vptr_set_alloc
void *
operator() (size_t n) const
{
- return VTV_malloc (n);
+ return __vtv_malloc (n);
}
};
@@ -373,9 +396,9 @@ log_memory_protection_data (char *message)
static int log_fd = -1;
if (log_fd == -1)
- log_fd = vtv_open_log ("vtv_memory_protection_data_%d.log");
+ log_fd = __vtv_open_log ("vtv_memory_protection_data_%d.log");
- vtv_add_to_log (log_fd, "%s", message);
+ __vtv_add_to_log (log_fd, "%s", message);
}
static void
@@ -444,7 +467,6 @@ read_section_offset_and_length (struct dl_phdr_info *info,
if (fd != -1)
{
-
/* Find the section header information in the file. */
ElfW (Half) strtab_idx = ehdr_info->e_shstrndx;
ElfW (Shdr) shstrtab;
@@ -456,6 +478,14 @@ read_section_offset_and_length (struct dl_phdr_info *info,
ElfW (Shdr) sect_hdr;
+ /* This code will be needed once we have crated libvtv.so. */
+ bool is_libvtv = false;
+
+ /*
+ if (strstr (info->dlpi_name, "libvtv.so"))
+ is_libvtv = true;
+ */
+
/* Loop through all the section headers, looking for one whose
name is ".vtable_map_vars". */
@@ -480,7 +510,10 @@ read_section_offset_and_length (struct dl_phdr_info *info,
/* We found the section; get its load offset and
size. */
*sect_offset = sect_hdr.sh_addr;
- *sect_len = sect_hdr.sh_size - VTV_PAGE_SIZE;
+ if (!is_libvtv)
+ *sect_len = sect_hdr.sh_size - VTV_PAGE_SIZE;
+ else
+ *sect_len = sect_hdr.sh_size;
found = true;
}
}
@@ -516,7 +549,7 @@ read_section_offset_and_length (struct dl_phdr_info *info,
}
/* This is the callback function used by dl_iterate_phdr (which is
- called from VTV_unprotect_vtable_vars and VTV_protect_vtable_vars).
+ called from vtv_unprotect_vtable_vars and vtv_protect_vtable_vars).
It attempts to find the binary file on disk for the INFO record
that dl_iterate_phdr passes in; open the binary file, and read its
section header information. If the file contains a
@@ -527,7 +560,7 @@ read_section_offset_and_length (struct dl_phdr_info *info,
read-only or read-write, depending on what's in DATA. */
static int
-dl_iterate_phdr_callback (struct dl_phdr_info *info, size_t, void *data)
+dl_iterate_phdr_callback (struct dl_phdr_info *info, size_t unused, void *data)
{
int * mprotect_flags = (int *) data;
off_t map_sect_offset = 0;
@@ -613,7 +646,8 @@ dl_iterate_phdr_callback (struct dl_phdr_info *info, size_t, void *data)
}
}
increment_num_calls (&num_calls_to_mprotect);
- num_pages_protected += (map_sect_len + VTV_PAGE_SIZE - 1) / VTV_PAGE_SIZE;
+ /* num_pages_protected += (map_sect_len + VTV_PAGE_SIZE - 1) / VTV_PAGE_SIZE; */
+ num_pages_protected += (map_sect_len + 4096 - 1) / 4096;
}
return 0;
@@ -641,10 +675,12 @@ dl_iterate_phdr_callback (struct dl_phdr_info *info, size_t, void *data)
static void
change_protections_on_phdr_cache (int protection_flag)
{
- ElfW (Addr) low_address = (ElfW (Addr)) &(vtv_sect_info_cache);
+ char * low_address = (char *) &(vtv_sect_info_cache);
size_t cache_size = MAX_ENTRIES * sizeof (struct sect_hdr_data);
- low_address = low_address & ~(VTV_PAGE_SIZE -1);
+ low_address = (char *) ((unsigned long) low_address & ~(VTV_PAGE_SIZE - 1));
+ size_t protection_size =
+ (char *) &vtv_sect_info_cache - low_address + cache_size;
if (mprotect ((void *) low_address, cache_size, protection_flag) == -1)
VTV_error ();
@@ -655,7 +691,7 @@ change_protections_on_phdr_cache (int protection_flag)
into relro sections */
static void
-VTV_unprotect_vtable_vars (void)
+vtv_unprotect_vtable_vars (void)
{
int mprotect_flags;
@@ -669,7 +705,7 @@ VTV_unprotect_vtable_vars (void)
into relro sections */
static void
-VTV_protect_vtable_vars (void)
+vtv_protect_vtable_vars (void)
{
int mprotect_flags;
@@ -722,10 +758,10 @@ log_set_stats (void)
{
#if HASHTABLE_STATS
if (set_log_fd == -1)
- set_log_fd = vtv_open_log ("vtv_set_stats.log");
+ set_log_fd = __vtv_open_log ("vtv_set_stats.log");
- vtv_add_to_log (set_log_fd, "---\n%s\n",
- insert_only_hash_tables_stats().c_str());
+ __vtv_add_to_log (set_log_fd, "---\n%s\n",
+ insert_only_hash_tables_stats().c_str());
#endif
}
@@ -767,9 +803,9 @@ __VLTChangePermission (int perm)
module that is not the first load module. */
__gthread_mutex_lock (&change_permissions_lock);
- VTV_unprotect_vtable_vars ();
- VTV_malloc_init ();
- VTV_malloc_unprotect ();
+ vtv_unprotect_vtable_vars ();
+ __vtv_malloc_init ();
+ __vtv_malloc_unprotect ();
}
else if (perm == __VLTP_READ_ONLY)
@@ -777,8 +813,8 @@ __VLTChangePermission (int perm)
if (debug_hash)
log_set_stats();
- VTV_malloc_protect ();
- VTV_protect_vtable_vars ();
+ __vtv_malloc_protect ();
+ vtv_protect_vtable_vars ();
__gthread_mutex_unlock (&change_permissions_lock);
}
@@ -798,15 +834,15 @@ struct insert_only_hash_map_allocator
void *
alloc (size_t n) const
{
- return VTV_malloc (n);
+ return __vtv_malloc (n);
}
/* P points to the memory to be deallocated; N is the number of
bytes to deallocate. */
void
- dealloc (void *p, size_t) const
+ dealloc (void *p, size_t n) const
{
- VTV_free (p);
+ __vtv_free (p);
}
};
@@ -857,31 +893,6 @@ set_handle_handle (vtv_set_handle * ptr)
return (vtv_set_handle_handle) ((unsigned long) ptr | SET_HANDLE_HANDLE_BIT);
}
-/* Open error logging file, if not already open, and write vtable
- verification failure messages (LOG_MSG) to the log file. Also
- generate a backtrace in the log file, if GENERATE_BACKTRACE is
- set. */
-
-static void
-log_error_message (const char *log_msg, bool generate_backtrace)
-{
- if (vtv_failures_log_fd == -1)
- vtv_failures_log_fd = vtv_open_log ("vtable_verification_failures.log");
-
- if (vtv_failures_log_fd == -1)
- return;
-
- vtv_add_to_log (vtv_failures_log_fd, "%s", log_msg);
-
- if (generate_backtrace)
- {
-#define STACK_DEPTH 20
- void *callers[STACK_DEPTH];
- int actual_depth = backtrace (callers, STACK_DEPTH);
- backtrace_symbols_fd (callers, actual_depth, vtv_failures_log_fd);
- }
-}
-
static inline void
register_set_common (void **set_handle_ptr, size_t num_args,
void **vtable_ptr_array, bool debug)
@@ -933,12 +944,12 @@ register_pair_common (void **set_handle_ptr, const void *vtable_ptr,
if (debug && debug_init)
{
if (init_log_fd == -1)
- init_log_fd = vtv_open_log("vtv_init.log");
+ init_log_fd = __vtv_open_log("vtv_init.log");
- vtv_add_to_log(init_log_fd,
- "Registered %s : %s (%p) 2 level deref = %s\n",
- set_symbol_name, vtable_name, vtbl_ptr,
- is_set_handle_handle(*set_handle_ptr) ? "yes" : "no" );
+ __vtv_add_to_log(init_log_fd,
+ "Registered %s : %s (%p) 2 level deref = %s\n",
+ set_symbol_name, vtable_name, vtbl_ptr,
+ is_set_handle_handle(*set_handle_ptr) ? "yes" : "no" );
}
}
@@ -986,7 +997,7 @@ init_set_symbol_debug (void **set_handle_ptr, const void *set_symbol_key,
"*** Found non-NULL local set ptr %p missing for symbol"
" %.*s",
*handle_ptr, symbol_key_ptr->n, symbol_key_ptr->bytes);
- log_error_message (buffer, true);
+ __vtv_log_verification_failure (buffer, true);
VTV_DEBUG_ASSERT (0);
}
}
@@ -1000,7 +1011,7 @@ init_set_symbol_debug (void **set_handle_ptr, const void *set_symbol_key,
"for symbol %.*s",
*handle_ptr, *map_value_ptr,
symbol_key_ptr->n, symbol_key_ptr->bytes);
- log_error_message (buffer, true);
+ __vtv_log_verification_failure (buffer, true);
VTV_DEBUG_ASSERT (0);
}
else if (*handle_ptr == NULL)
@@ -1046,7 +1057,7 @@ init_set_symbol_debug (void **set_handle_ptr, const void *set_symbol_key,
in case the memory where this comes from gets unmapped by
dlclose. */
size_t map_key_len = symbol_key_ptr->n + sizeof (vtv_symbol_key);
- void *map_key = VTV_malloc (map_key_len);
+ void *map_key = __vtv_malloc (map_key_len);
memcpy (map_key, symbol_key_ptr, map_key_len);
@@ -1064,14 +1075,14 @@ init_set_symbol_debug (void **set_handle_ptr, const void *set_symbol_key,
if (debug_init)
{
if (init_log_fd == -1)
- init_log_fd = vtv_open_log ("vtv_init.log");
-
- vtv_add_to_log (init_log_fd,
- "Init handle:%p for symbol:%.*s hash:%u size_hint:%lu"
- "number of symbols:%lu \n",
- set_handle_ptr, symbol_key_ptr->n,
- symbol_key_ptr->bytes, symbol_key_ptr->hash, size_hint,
- vtv_symbol_unification_map->size ());
+ init_log_fd = __vtv_open_log ("vtv_init.log");
+
+ __vtv_add_to_log (init_log_fd,
+ "Init handle:%p for symbol:%.*s hash:%u size_hint:%lu"
+ "number of symbols:%lu \n",
+ set_handle_ptr, symbol_key_ptr->n,
+ symbol_key_ptr->bytes, symbol_key_ptr->hash, size_hint,
+ vtv_symbol_unification_map->size ());
}
}
@@ -1165,10 +1176,10 @@ __VLTVerifyVtablePointerDebug (void **set_handle_ptr, const void *vtable_ptr,
if (debug_verify_vtable)
{
if (verify_vtable_log_fd == -1)
- vtv_open_log ("vtv_verify_vtable.log");
- vtv_add_to_log (verify_vtable_log_fd,
- "Verified %s %s value = %p\n",
- set_symbol_name, vtable_name, vtable_ptr);
+ __vtv_open_log ("vtv_verify_vtable.log");
+ __vtv_add_to_log (verify_vtable_log_fd,
+ "Verified %s %s value = %p\n",
+ set_symbol_name, vtable_name, vtable_ptr);
}
}
else
@@ -1251,7 +1262,7 @@ init_set_symbol (void **set_handle_ptr, const void *set_symbol_key,
in case the memory where this comes from gets unmapped by
dlclose. */
size_t map_key_len = symbol_key_ptr->n + sizeof (vtv_symbol_key);
- void * map_key = VTV_malloc (map_key_len);
+ void * map_key = __vtv_malloc (map_key_len);
memcpy (map_key, symbol_key_ptr, map_key_len);
s2s::value_type * value_ptr;
@@ -1393,31 +1404,122 @@ count_all_pages (void)
page_count_2 = 0;
dl_iterate_phdr (dl_iterate_phdr_count_pages, (void *) &mprotect_flags);
- page_count_2 += VTV_count_mmapped_pages ();
+ page_count_2 += __vtv_count_mmapped_pages ();
}
void
__VLTDumpStats (void)
{
- int log_fd = vtv_open_log ("vtv-runtime-stats.log");
+ int log_fd = __vtv_open_log ("vtv-runtime-stats.log");
if (log_fd != -1)
{
count_all_pages ();
- vtv_add_to_log (log_fd,
- "Calls: mprotect (%d) regset (%d) regpair (%d)"
- " verify_vtable (%d)\n",
- num_calls_to_mprotect, num_calls_to_regset,
- num_calls_to_regpair, num_calls_to_verify_vtable);
- vtv_add_to_log (log_fd,
- "Cycles: mprotect (%lld) regset (%lld) "
- "regpair (%lld) verify_vtable (%lld)\n",
- mprotect_cycles, regset_cycles, regpair_cycles,
- verify_vtable_cycles);
- vtv_add_to_log (log_fd,
- "Pages protected (1): %d\n", num_pages_protected);
- vtv_add_to_log (log_fd, "Pages protected (2): %d\n", page_count_2);
+ __vtv_add_to_log (log_fd,
+ "Calls: mprotect (%d) regset (%d) regpair (%d)"
+ " verify_vtable (%d)\n",
+ num_calls_to_mprotect, num_calls_to_regset,
+ num_calls_to_regpair, num_calls_to_verify_vtable);
+ __vtv_add_to_log (log_fd,
+ "Cycles: mprotect (%lld) regset (%lld) "
+ "regpair (%lld) verify_vtable (%lld)\n",
+ mprotect_cycles, regset_cycles, regpair_cycles,
+ verify_vtable_cycles);
+ __vtv_add_to_log (log_fd,
+ "Pages protected (1): %d\n", num_pages_protected);
+ __vtv_add_to_log (log_fd, "Pages protected (2): %d\n", page_count_2);
close (log_fd);
}
}
+
+/* This function is called from __VLTVerifyVtablePointerDebug; it
+ sends as much debugging information as it can to the error log
+ file, then calls __vtv_verify_fail. SET_HANDLE_PTR is the pointer
+ to the set of valid vtable pointers, VTBL_PTR is the pointer that
+ was not found in the set, and DEBUG_MSG is the message to be
+ written to the log file before failing. n */
+
+void
+__vtv_verify_fail_debug (void **set_handle_ptr, const void *vtbl_ptr,
+ const char *debug_msg)
+{
+ __vtv_log_verification_failure (debug_msg, false);
+
+ /* Call the public interface in case it has been overwritten by
+ user. */
+ __vtv_verify_fail (set_handle_ptr, vtbl_ptr);
+
+ __vtv_log_verification_failure ("Returned from __vtv_verify_fail."
+ " Secondary verification succeeded.\n", false);
+}
+
+/* This function calls __fortify_fail with a FAILURE_MSG and then
+ calls abort. */
+
+void
+__vtv_really_fail (const char *failure_msg)
+{
+ __fortify_fail (failure_msg);
+
+ /* We should never get this far; __fortify_fail calls __libc_message
+ which prints out a back trace and a memory dump and then is
+ supposed to call abort, but let's play it safe anyway and call abort
+ ourselves. */
+ abort ();
+}
+
+/* This function takes an error MSG, a vtable map variable
+ (DATA_SET_PTR) and a vtable pointer (VTBL_PTR). It is called when
+ an attempt to verify VTBL_PTR with the set pointed to by
+ DATA_SET_PTR failed. It outputs a failure message with the
+ addresses involved, and calls __vtv_really_fail. */
+
+static void
+vtv_fail (const char *msg, void **data_set_ptr, const void *vtbl_ptr)
+{
+ char buffer[128];
+ int buf_len;
+ const char *format_str =
+ "*** Unable to verify vtable pointer (%p) in set (%p) *** \n";
+
+ snprintf (buffer, sizeof (buffer), format_str, vtbl_ptr,
+ is_set_handle_handle(*data_set_ptr) ?
+ ptr_from_set_handle_handle (*data_set_ptr) :
+ *data_set_ptr);
+ buf_len = strlen (buffer);
+ /* Send this to to stderr. */
+ write (2, buffer, buf_len);
+
+#ifndef VTV_NO_ABORT
+ __vtv_really_fail (msg);
+#endif
+}
+
+/* Send information about what we were trying to do when verification
+ failed to the error log, then call vtv_fail. This function can be
+ overwritten/replaced by the user, to implement a secondary
+ verification function instead. DATA_SET_PTR is the vtable map
+ variable used for the failed verification, and VTBL_PTR is the
+ vtable pointer that was not found in the set. */
+
+void
+__vtv_verify_fail (void **data_set_ptr, const void *vtbl_ptr)
+{
+ char log_msg[256];
+ snprintf (log_msg, sizeof (log_msg), "Looking for vtable %p in set %p.\n",
+ vtbl_ptr,
+ is_set_handle_handle (*data_set_ptr) ?
+ ptr_from_set_handle_handle (*data_set_ptr) :
+ *data_set_ptr);
+ __vtv_log_verification_failure (log_msg, false);
+
+ const char *format_str =
+ "*** Unable to verify vtable pointer (%p) in set (%p) *** \n";
+ snprintf (log_msg, sizeof (log_msg), format_str, vtbl_ptr, *data_set_ptr);
+ __vtv_log_verification_failure (log_msg, false);
+ __vtv_log_verification_failure (" Backtrace: \n", true);
+
+ const char *fail_msg = "Potential vtable pointer corruption detected!!\n";
+ vtv_fail (fail_msg, data_set_ptr, vtbl_ptr);
+}
diff --git a/libvtv/vtv_stubs.cc b/libvtv/vtv_stubs.cc
deleted file mode 100644
index 0076772e021..00000000000
--- a/libvtv/vtv_stubs.cc
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Copyright (C) 2012-2013
- Free Software Foundation
-
- This file is part of GCC.
-
- GCC 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.
-
- GCC 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.
-
- Under Section 7 of GPL version 3, you are granted additional
- permissions described in the GCC Runtime Library Exception, version
- 3.1, as published by the Free Software Foundation.
-
- You should have received a copy of the GNU General Public License and
- a copy of the GCC Runtime Library Exception along with this program;
- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
- <http://www.gnu.org/licenses/>. */
-
-#include "../include/vtv-change-permission.h"
-#include "vtv_rts.h"
-
-/* The is part of the vtable verification runtime library. For more
- information about this feature, see the comments in vtv_rts.cc. */
-
-/* The functions in this file are used to create the libvtv_stubs
- library, as part of the vtable verification feature. When building
- a binary without vtable verification, and linking it with a
- (possibly pre-built third-party) library that was built with
- verification, it is possible that vtable verification will fail due
- to incomplete data (rather than due to corrupt vtable pointers). In
- this case we need to give programmers a way of turning off the
- vtable verification in their libraries. They can do so by linking
- with the libvtv_stubs library, which (as you can see) will replace
- the real verification functions with a set of functions that do
- nothing (so no more verification failures/aborts). */
-
-extern "C"
-void
-__VLTChangePermission (int perm __attribute__((__unused__)))
-{
-}
-
-void
-__VLTRegisterSetDebug (void ** __attribute__((__unused__)),
- const void * __attribute__((__unused__)),
- std::size_t __attribute__((__unused__)),
- std::size_t __attribute__((__unused__)),
- void ** __attribute__((__unused__)))
-{
-}
-
-void
-__VLTRegisterPairDebug (void ** __attribute__((__unused__)),
- const void * __attribute__((__unused__)),
- std::size_t __attribute__((__unused__)),
- const void * __attribute__((__unused__)),
- const char * __attribute__((__unused__)),
- const char * __attribute__((__unused__)))
-{
-}
-
-const void *
-__VLTVerifyVtablePointerDebug
- (void **set_handle_ptr __attribute__((__unused__)),
- const void *vtable_ptr,
- const char *set_symbol_name __attribute__((__unused__)),
- const char *vtable_name __attribute__((__unused__)))
-
-{
- return vtable_ptr;
-}
-
-void
-__VLTRegisterSet (void ** __attribute__((__unused__)),
- const void * __attribute__((__unused__)),
- std::size_t __attribute__((__unused__)),
- std::size_t __attribute__((__unused__)),
- void ** __attribute__((__unused__)))
-{
-}
-
-void
-__VLTRegisterPair (void ** __attribute__((__unused__)),
- const void * __attribute__((__unused__)),
- std::size_t __attribute__((__unused__)),
- const void * __attribute__((__unused__)))
-{
-}
-
-const void *
-__VLTVerifyVtablePointer (void **set_handle_ptr __attribute__((__unused__)),
- const void *vtable_ptr)
-{
- return vtable_ptr;
-}
diff --git a/libvtv/vtv_utils.cc b/libvtv/vtv_utils.cc
index bfe91b16e08..480bfa308dc 100644
--- a/libvtv/vtv_utils.cc
+++ b/libvtv/vtv_utils.cc
@@ -32,6 +32,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
+#include <execinfo.h>
#include <unistd.h>
#include <errno.h>
@@ -40,6 +41,8 @@
/* This is the directory into which all vtable verication log files
get written. */
static const char * const logs_dir = "/tmp/vtv_logs";
+static int vtv_failures_log_fd = -1;
+
/* This function takes the NAME of a log file to open, attempts to
@@ -47,14 +50,14 @@ static const char * const logs_dir = "/tmp/vtv_logs";
decriptor. */
int
-vtv_open_log (const char *name)
+__vtv_open_log (const char *name)
{
char log_name[256];
snprintf (log_name, sizeof (log_name), "%s/%s", logs_dir, name);
mkdir (logs_dir, S_IRWXU);
int fd = open (log_name, O_WRONLY | O_APPEND | O_CREAT, S_IRWXU);
if (fd == -1)
- vtv_add_to_log (2, "Cannot open log file %s %s\n", name,
+ __vtv_add_to_log (2, "Cannot open log file %s %s\n", name,
strerror (errno));
return fd;
}
@@ -69,7 +72,7 @@ vtv_log_write (int fd, const char *str)
return 0;
if (fd != 2) /* Make sure we dont get in a loop. */
- vtv_add_to_log (2, "Error writing to log: %s\n", strerror (errno));
+ __vtv_add_to_log (2, "Error writing to log: %s\n", strerror (errno));
return -1;
}
@@ -82,7 +85,7 @@ vtv_log_write (int fd, const char *str)
to vtv_log_write. */
int
-vtv_add_to_log (int log_file, const char * format, ...)
+__vtv_add_to_log (int log_file, const char * format, ...)
{
/* We dont want to dynamically allocate this buffer. This should be
more than enough in most cases. It if isn't we are careful not to
@@ -99,9 +102,30 @@ vtv_add_to_log (int log_file, const char * format, ...)
vtv_log_write (log_file, output);
va_end (ap);
- /* fdatasync is quite expensive. Only enable if you suspect you are
- loosing log data in in a program crash? */
- /* fdatasync(log_file); */
-
return 0;
}
+
+/* Open error logging file, if not already open, and write vtable
+ verification failure messages (LOG_MSG) to the log file. Also
+ generate a backtrace in the log file, if GENERATE_BACKTRACE is
+ set. */
+
+void
+__vtv_log_verification_failure (const char *log_msg, bool generate_backtrace)
+{
+ if (vtv_failures_log_fd == -1)
+ vtv_failures_log_fd = __vtv_open_log ("vtable_verification_failures.log");
+
+ if (vtv_failures_log_fd == -1)
+ return;
+
+ __vtv_add_to_log (vtv_failures_log_fd, "%s", log_msg);
+
+ if (generate_backtrace)
+ {
+#define STACK_DEPTH 20
+ void *callers[STACK_DEPTH];
+ int actual_depth = backtrace (callers, STACK_DEPTH);
+ backtrace_symbols_fd (callers, actual_depth, vtv_failures_log_fd);
+ }
+}
diff --git a/libvtv/vtv_utils.h b/libvtv/vtv_utils.h
index 1bddc8cd9f2..65600d23354 100644
--- a/libvtv/vtv_utils.h
+++ b/libvtv/vtv_utils.h
@@ -26,10 +26,7 @@
#define _VTV_UTILS_H 1
#include <stdlib.h>
-//#include "../../include/vtv-change-permission.h"
-#include "../include/vtv-change-permission.h"
-
-extern bool vtv_debug;
+#include "../../include/vtv-change-permission.h"
static inline void
VTV_not_an_error (void)
@@ -40,10 +37,15 @@ VTV_not_an_error (void)
#define VTV_error abort
/* Assertion macros used in vtable verification runtime. */
-#define VTV_ASSERT(EXPR) (!(EXPR) ? VTV_error() : VTV_not_an_error())
-
+#define VTV_ASSERT(EXPR) \
+ if (!(EXPR)) VTV_error();
+
+#ifdef VTV_DEBUG
#define VTV_DEBUG_ASSERT(EXPR) \
- ((bool) (vtv_debug && !(EXPR)) ? VTV_error() : (void) 0)
+ ((bool) (!(EXPR)) ? VTV_error() : (void) 0)
+#else
+#define VTV_DEBUG_ASSERT(EXPR) ((void) 0)
+#endif
/* Name of the section where we put general VTV variables for protection */
#define VTV_PROTECTED_VARS_SECTION ".vtable_map_vars"
@@ -54,7 +56,8 @@ VTV_not_an_error (void)
routines and avoid calling malloc. We need this so that we dont
disturb the order of calls to dlopen. Changing the order of dlopen
calls may lead to deadlocks */
-int vtv_open_log (const char * name);
-int vtv_add_to_log (int log, const char * format, ...);
+int __vtv_open_log (const char * name);
+int __vtv_add_to_log (int log, const char * format, ...);
+void __vtv_log_verification_failure (const char *, bool);
#endif /* VTV_UTILS_H */