# HG changeset patch # Parent 03101b4a14f5627be99e79dbe73554aa1e46f5b7 # Parent 1f8233a193bf122c5d083b424744e97441b97d41 Port libvtv to Solaris diff --git a/gcc/config/sol2.h b/gcc/config/sol2.h --- a/gcc/config/sol2.h +++ b/gcc/config/sol2.h @@ -150,6 +150,10 @@ along with GCC; see the file COPYING3. #define MD_EXEC_PREFIX "/usr/ccs/bin/" #endif +/* Enable constructor priorities if the configured linker supports it. */ +#undef SUPPORTS_INIT_PRIORITY +#define SUPPORTS_INIT_PRIORITY HAVE_INITFINI_ARRAY_SUPPORT + #undef STARTFILE_ARCH_SPEC #define STARTFILE_ARCH_SPEC "%{ansi:values-Xc.o%s} \ %{!ansi:values-Xa.o%s}" @@ -162,6 +166,22 @@ along with GCC; see the file COPYING3. #define STARTFILE_CRTBEGIN_SPEC "crtbegin.o%s" #endif +#if SUPPORTS_INIT_PRIORITY +#define STARTFILE_VTV_SPEC \ + "%{fvtable-verify=none:%s; \ + fvtable-verify=preinit:vtv_start_preinit.o%s; \ + fvtable-verify=std:vtv_start.o%s}" + +#define ENDFILE_VTV_SPEC \ + "%{fvtable-verify=none:%s; \ + fvtable-verify=preinit:vtv_end_preinit.o%s; \ + fvtable-verify=std:vtv_end.o%s}" +#else +#define STARTFILE_VTV_SPEC \ + "%{fvtable-verify:%e-fvtable-verify is not supported in this configuration}" +#define ENDFILE_VTV_SPEC "" +#endif + /* We don't use the standard svr4 STARTFILE_SPEC because it's wrong for us. */ #undef STARTFILE_SPEC #ifdef HAVE_SOLARIS_CRTS @@ -172,13 +192,15 @@ along with GCC; see the file COPYING3. %{p:%e-p is not supported; \ pg:crtpg.o%s gmon.o%s; \ :crtp.o%s}}} \ - crti.o%s %(startfile_arch) %(startfile_crtbegin)" + crti.o%s %(startfile_arch) %(startfile_crtbegin) \ + %(startfile_vtv)" #else #define STARTFILE_SPEC "%{!shared:%{!symbolic: \ %{p:mcrt1.o%s; \ pg:gcrt1.o%s gmon.o%s; \ :crt1.o%s}}} \ - crti.o%s %(startfile_arch) %(startfile_crtbegin)" + crti.o%s %(startfile_arch) %(startfile_crtbegin) \ + %(startfile_vtv)" #endif #if defined(HAVE_LD_PIE) && defined(HAVE_SOLARIS_CRTS) @@ -192,7 +214,7 @@ along with GCC; see the file COPYING3. #undef ENDFILE_SPEC #define ENDFILE_SPEC \ "%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \ - %(endfile_arch) %(endfile_crtend) crtn.o%s" + %(endfile_arch) %(endfile_vtv) %(endfile_crtend) crtn.o%s" #undef LINK_ARCH32_SPEC_BASE #define LINK_ARCH32_SPEC_BASE \ @@ -267,12 +289,14 @@ along with GCC; see the file COPYING3. #define SUBTARGET_EXTRA_SPECS \ { "startfile_arch", STARTFILE_ARCH_SPEC }, \ { "startfile_crtbegin", STARTFILE_CRTBEGIN_SPEC }, \ + { "startfile_vtv", STARTFILE_VTV_SPEC }, \ { "link_arch32", LINK_ARCH32_SPEC }, \ { "link_arch64", LINK_ARCH64_SPEC }, \ { "link_arch_default", LINK_ARCH_DEFAULT_SPEC }, \ { "link_arch", LINK_ARCH_SPEC }, \ { "endfile_arch", ENDFILE_ARCH_SPEC }, \ - { "endfile_crtend", ENDFILE_CRTEND_SPEC }, \ + { "endfile_crtend", ENDFILE_CRTEND_SPEC }, \ + { "endfile_vtv", ENDFILE_VTV_SPEC }, \ SUBTARGET_CPU_EXTRA_SPECS /* C++11 programs need -lrt for nanosleep. */ @@ -398,10 +422,6 @@ along with GCC; see the file COPYING3. #define NO_DBX_BNSYM_ENSYM 1 #endif -/* Enable constructor priorities if the configured linker supports it. */ -#undef SUPPORTS_INIT_PRIORITY -#define SUPPORTS_INIT_PRIORITY HAVE_INITFINI_ARRAY_SUPPORT - /* Solaris has an implementation of __enable_execute_stack. */ #define HAVE_ENABLE_EXECUTE_STACK diff --git a/gcc/gcc.c b/gcc/gcc.c --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -1011,9 +1011,9 @@ proper position among the other output f %{flto} %{fno-lto} %{flto=*} %l " LINK_PIE_SPEC \ "%{fuse-ld=*:-fuse-ld=%*} " LINK_COMPRESS_DEBUG_SPEC \ "%X %{o*} %{e*} %{N} %{n} %{r}\ - %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}} " VTABLE_VERIFICATION_SPEC " \ - %{static:} %{L*} %(mfwrap) %(link_libgcc) " SANITIZER_EARLY_SPEC " %o\ - " CHKP_SPEC " \ + %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}} \ + %{static:} %{L*} %(mfwrap) %(link_libgcc) " \ + VTABLE_VERIFICATION_SPEC " " SANITIZER_EARLY_SPEC " %o " CHKP_SPEC " \ %{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*} 1):\ %:include(libgomp.spec)%(link_gomp)}\ %{fcilkplus:%:include(libcilkrts.spec)%(link_cilkrts)}\ diff --git a/include/vtv-change-permission.h b/include/vtv-change-permission.h --- a/include/vtv-change-permission.h +++ b/include/vtv-change-permission.h @@ -46,8 +46,12 @@ extern void __VLTChangePermission (int); /* TODO - Replace '4096' below with correct big page size. */ #define VTV_PAGE_SIZE 4096 #else +#if defined(__sun__) && defined(__svr4__) && defined(__sparc__) +#define VTV_PAGE_SIZE 8192 +#else #define VTV_PAGE_SIZE 4096 #endif +#endif diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in --- a/libgcc/Makefile.in +++ b/libgcc/Makefile.in @@ -1006,17 +1006,22 @@ endif ifeq ($(enable_vtable_verify),yes) # These are used in vtable verification; see comments in source files for # more details. + +# Override -finhibit-size-directive to avoid mismatch between libgcc and libvtv +# compilations. +VTV_CFLAGS = $(CRTSTUFF_T_CFLAGS_S) -fno-inhibit-size-directive + vtv_start$(objext): $(srcdir)/vtv_start.c - $(crt_compile) $(CRTSTUFF_T_CFLAGS_S) -c $(srcdir)/vtv_start.c + $(crt_compile) $(VTV_CFLAGS) -c $(srcdir)/vtv_start.c vtv_end$(objext): $(srcdir)/vtv_end.c - $(crt_compile) $(CRTSTUFF_T_CFLAGS_S) -c $(srcdir)/vtv_end.c + $(crt_compile) $(VTV_CFLAGS) -c $(srcdir)/vtv_end.c vtv_start_preinit$(objext): $(srcdir)/vtv_start_preinit.c - $(crt_compile) $(CRTSTUFF_T_CFLAGS_S) -c $(srcdir)/vtv_start_preinit.c + $(crt_compile) $(VTV_CFLAGS) -c $(srcdir)/vtv_start_preinit.c vtv_end_preinit$(objext): $(srcdir)/vtv_end_preinit.c - $(crt_compile) $(CRTSTUFF_T_CFLAGS_S) -c $(srcdir)/vtv_end_preinit.c + $(crt_compile) $(VTV_CFLAGS) -c $(srcdir)/vtv_end_preinit.c endif ifeq ($(CUSTOM_CRTIN),) diff --git a/libgcc/config.host b/libgcc/config.host --- a/libgcc/config.host +++ b/libgcc/config.host @@ -294,6 +294,9 @@ case ${host} in ;; esac fi + if test x$enable_vtable_verify = xyes; then + extra_parts="$extra_parts vtv_start.o vtv_end.o vtv_start_preinit.o vtv_end_preinit.o" + fi ;; *-*-uclinux*) extra_parts="crtbegin.o crtend.o" diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -2424,6 +2424,10 @@ AC_DEFUN([GLIBCXX_ENABLE_VTABLE_VERIFY], VTV_CXXFLAGS="-fvtable-verify=std -Wl,-u,_vtable_map_vars_start -Wl,-u,_vtable_map_vars_end" VTV_CXXLINKFLAGS="-L${toplevel_builddir}/libvtv/.libs -Wl,-rpath,${toplevel_builddir}/libvtv/.libs" ;; + solaris2*) + VTV_CXXFLAGS="-fvtable-verify=std -Wl,-u_vtable_map_vars_start,-u_vtable_map_vars_end" + VTV_CXXLINKFLAGS="-L${toplevel_builddir}/libvtv/.libs -Wl,-R -Wl,${toplevel_builddir}/libvtv/.libs" + ;; *) VTV_CXXFLAGS="-fvtable-verify=std -Wl,-u_vtable_map_vars_start,-u_vtable_map_vars_end" VTV_CXXLINKFLAGS="-L${toplevel_builddir}/libvtv/.libs -Wl,--rpath -Wl,${toplevel_builddir}/libvtv/.libs" 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 --- 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 -fvtable-verify=none" { target *-*-linux* *-*-gnu* } } +// { dg-options "-g -O2 -pthread -ldl -x c -fvtable-verify=none" { target *-*-linux* *-*-gnu* *-*-solaris2.1[2-9]* } } // Copyright (C) 2005-2015 Free Software Foundation, Inc. // diff --git a/libvtv/Makefile.am b/libvtv/Makefile.am --- a/libvtv/Makefile.am +++ b/libvtv/Makefile.am @@ -76,11 +76,14 @@ vtv_end.c: rm -f $@ $(LN_S) $(toplevel_srcdir)/libgcc/vtv_end.c $@ -if VTV_CYGMIN +if VTV_NO_OBSTACK obstack.c: rm -f $@ $(LN_S) $(toplevel_srcdir)/libiberty/obstack.c $@ - + > config.h +endif + +if VTV_CYGMIN vtv_stubs.cc: rm -f $@ $(LN_S) $(toplevel_srcdir)/libstdc++-v3/libsupc++/vtv_stubs.cc $@ @@ -93,11 +96,12 @@ if VTV_CYGMIN endif if ENABLE_VTABLE_VERIFY + libvtv_la_SOURCES = $(vtv_sources) +if VTV_NO_OBSTACK + libvtv_la_SOURCES += obstack.c +endif if VTV_CYGMIN - libvtv_la_SOURCES = $(vtv_sources) obstack.c libvtv_stubs_la_SOURCES = $(vtv_stubs_sources) -else - libvtv_la_SOURCES = $(vtv_sources) endif libvtv_include_HEADERS = $(vtv_headers) else diff --git a/libvtv/configure.ac b/libvtv/configure.ac --- a/libvtv/configure.ac +++ b/libvtv/configure.ac @@ -27,6 +27,8 @@ target_alias=${target_alias-$host_alias} AC_SUBST(target_alias) GCC_LIBSTDCXX_RAW_CXX_FLAGS +AC_USE_SYSTEM_EXTENSIONS + # Use same top-level configure hooks in libgcc/libstdc++/libvtv. AC_MSG_CHECKING([for --enable-vtable-verify]) AC_ARG_ENABLE(vtable-verify, @@ -43,6 +45,21 @@ AC_MSG_RESULT($enable_vtable_verify) unset VTV_SUPPORTED AC_MSG_CHECKING([for host support for vtable verification]) . ${srcdir}/configure.tgt +case ${host} in + *-*-solaris2*) + # libvtv requires init priority support, which depends on the linker + # used on Solaris. + AC_CACHE_CHECK(for init priority support, libvtv_cv_init_priority, [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, + [[void ip (void) __attribute__ ((constructor (1)));]])], + [libgcc_cv_init_priority=yes],[libgcc_cv_init_priority=no])]) + if test x$libvtv_cv_init_priority = xno; then + VTV_SUPPORTED=no + fi + # FIXME: Maybe check for dl_iterate_phdr, too? Should be covered by + # configure.tgt restricting to libvtv to Solaris 11+. + ;; +esac AC_MSG_RESULT($VTV_SUPPORTED) # Decide if it's usable. @@ -97,6 +114,8 @@ AC_CHECK_FUNCS([__secure_getenv]) AC_GNU_SOURCE AC_CHECK_FUNCS([secure_getenv]) +AC_CHECK_FUNCS([getexecname __fortify_fail]) + # Check for programs. m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS]) m4_define([_AC_ARG_VAR_PRECIOUS],[]) @@ -167,4 +186,7 @@ esac AM_CONDITIONAL(VTV_CYGMIN, test $vtv_cygmin = yes) +AC_CHECK_FUNCS([_obstack_begin]) +AM_CONDITIONAL(VTV_NO_OBSTACK, test $ac_cv_func__obstack_begin = no) + AC_OUTPUT diff --git a/libvtv/configure.tgt b/libvtv/configure.tgt --- a/libvtv/configure.tgt +++ b/libvtv/configure.tgt @@ -23,6 +23,12 @@ VTV_SUPPORTED=no case "${target}" in *-*-*android*) ;; + *-*-solaris2.1[1-9]*) + # Vtable verification requires constructor priority support and + # dl_iterate_phdr. The former requires a dynamic check in + # configure.ac, the latter is fully present in Solaris 11 only. + VTV_SUPPORTED=yes + ;; x86_64-*-linux* | i?86-*-linux*) VTV_SUPPORTED=yes ;; diff --git a/libvtv/vtv_rts.cc b/libvtv/vtv_rts.cc --- a/libvtv/vtv_rts.cc +++ b/libvtv/vtv_rts.cc @@ -150,13 +150,11 @@ #include "vtv-change-permission.h" -#if defined (__CYGWIN__) || defined (__MINGW32__) -// porting: fix link error to libc -void __fortify_fail (const char * msg){ - OutputDebugString(msg); - abort(); -} -#else +#ifdef HAVE_GETEXECNAME +const char *program_invocation_name; +#endif + +#ifdef HAVE___FORTIFY_FAIL extern "C" { /* __fortify_fail is a function in glibc that calls __libc_message, @@ -173,6 +171,20 @@ extern "C" { extern void __fortify_fail (const char *) __attribute__((noreturn)); } /* extern "C" */ +#else +#if defined (__CYGWIN__) || defined (__MINGW32__) +// porting: fix link error to libc +void __fortify_fail (const char * msg){ + OutputDebugString(msg); + abort(); +} +#else +// FIXME: Provide backtrace via libbacktrace? +void __fortify_fail (const char *msg) { + write (2, msg, strlen (msg)); + abort (); +} +#endif #endif /* The following variables are used only for debugging and performance @@ -573,6 +585,9 @@ read_section_offset_and_length (struct d /* Get the name of the main executable. This may or may not include arguments passed to the program. Find the first space, assume it is the start of the argument list, and change it to a '\0'. */ +#ifdef HAVE_GETEXECNAME + program_invocation_name = getexecname (); +#endif snprintf (program_name, sizeof (program_name), program_invocation_name); /* Check to see if we already have the data for this file. */ @@ -663,7 +678,10 @@ read_section_offset_and_length (struct d size. */ *sect_offset = sect_hdr.sh_addr; if (!is_libvtv) - *sect_len = sect_hdr.sh_size - VTV_PAGE_SIZE; + { + VTV_ASSERT (sect_hdr.sh_size - VTV_PAGE_SIZE >= 0); + *sect_len = sect_hdr.sh_size - VTV_PAGE_SIZE; + } else *sect_len = sect_hdr.sh_size; found = true; @@ -784,7 +802,7 @@ iterate_modules (void *data) if (debug_functions) { snprintf (buffer, sizeof (buffer), - "Failed called to mprotect for %s error: ", + "Failed call to mprotect for %s error: ", (*mprotect_flags & PROT_WRITE) ? "READ/WRITE" : "READ-ONLY"); log_memory_protection_data (buffer); @@ -804,9 +822,8 @@ iterate_modules (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 + 4096 - 1) / 4096; + num_pages_protected += (map_sect_len + VTV_PAGE_SIZE - 1) + / VTV_PAGE_SIZE; continue; } } @@ -853,6 +870,9 @@ dl_iterate_phdr_callback (struct dl_phdr /* Get the name of the main executable. This may or may not include arguments passed to the program. Find the first space, assume it is the start of the argument list, and change it to a '\0'. */ +#ifdef HAVE_GETEXECNAME + program_invocation_name = getexecname (); +#endif snprintf (program_name, sizeof (program_name), program_invocation_name); read_section_offset_and_length (info, map_sect_name, *mprotect_flags, @@ -896,7 +916,7 @@ dl_iterate_phdr_callback (struct dl_phdr if (debug_functions) { snprintf (buffer, sizeof (buffer), - "Failed called to mprotect for %s error: ", + "Failed call to mprotect for %s error: ", (*mprotect_flags & PROT_WRITE) ? "READ/WRITE" : "READ-ONLY"); log_memory_protection_data (buffer); @@ -916,8 +936,7 @@ dl_iterate_phdr_callback (struct dl_phdr } } 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 + 4096 - 1) / 4096; + num_pages_protected += (map_sect_len + VTV_PAGE_SIZE - 1) / VTV_PAGE_SIZE; } return 0; @@ -1054,9 +1073,9 @@ void if (debug_functions) { if (perm == __VLTP_READ_WRITE) - fprintf (stdout, "Changing VLT permisisons to Read-Write.\n"); + fprintf (stdout, "Changing VLT permissions to Read-Write.\n"); else if (perm == __VLTP_READ_ONLY) - fprintf (stdout, "Changing VLT permissions to Read-only.\n"); + fprintf (stdout, "Changing VLT permissions to Read-Only.\n"); else fprintf (stdout, "Unrecognized permissions value: %d\n", perm);