diff mbox

Port libvtv to Solaris

Message ID ydd610rd7b3.fsf@lokon.CeBiTec.Uni-Bielefeld.DE
State New
Headers show

Commit Message

Rainer Orth Nov. 24, 2015, 10:24 a.m. UTC
Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:

> Now that init priority support on Solaris is on mainline, porting libvtv
> proved to be relatively easy, though it discovered a couple of quirks on
> a non-gld non-x86 platform.

This patch has now remained unreviewed for a week.  With both Jeff and
Richi fine with it going into mainline even this late, it would be nice
if Caroline could find the time to review it.

Linux/x86_64 testing found one minor issue, explained below.  I'm
attaching the updated patch.

> A considerable part of the patch lives in Solaris-specific files and
> thus doesn't need approval, though some changes require explanation:
>
> * In gcc.c (LINK_COMMAND_SPEC), VTABLE_VERIFICATION_SPEC was before
>   %{L*}.  The spec includes -lvtv.  Solaris ld, other than GNU ld, heeds
>   the relative order of -L and -l switches, so the libvtv testcases
>   wouldn't link manually, but did inside a testsuite run where
>   LD_LIBRARY_PATH points ld at the correct directory.
>
> * Solaris/SPARC uses an 8 kB page size, so a couple of cases where uses
>   of VTV_PAGE_SIZE had been replaced with hardcoded values of 4096 had
>   to be reverted.
>
> * Inside libgcc, the vtv_*.c files are compiled with
>   -finhibit-size-directive, whereas in libvtv that flag is absent.  This
>   caused all testcases to fail due to a linker warning:
>
> FAIL: libvtv.cc/bb_tests.cc -O0 -fvtable-verify=std (test for excess errors)
> Excess errors:
> ld: warning: symbol '_vtable_map_vars_end' has differing sizes:
>         (file /var/gcc/gcc-6.0.0-20151111/12-gcc-vtv/sparc-sun-solaris2.12/./libvtv/.libs/libvtv.so value=0x1000; file /var/gcc/gcc-6.0.0-20151111/12-gcc-vtv/gcc/vtv_end.o value=0x0);
>         /var/gcc/gcc-6.0.0-20151111/12-gcc-vtv/gcc/vtv_end.o definition taken
>
> * Like Cygwin, Solaris has no obstack functions in libc, so I'm now
>   using a common conditional for that.
>
> * libvtv requires constructor priority support and dl_iterate_phdr.  The
>   former needs either a recent (Solaris 12 only so far) ld or gld, the
>   latter came in Solaris 11 only.
>
> * Unlike glibc systems, Solaris has no __fortify_fail in libc; some of
>   this can probably provided using libbacktrace, which I haven't yet
>   done.
>
> * It also lacks program_invocation_name, but the functionality can be
>   provided via getexecname() instead.
>
> * On Solaris 12/SPARC with Solaris as, the .vtable_map_vars section
>   wouldn't be pagesize aligned (I'm still looking how to fix this; it
>   works out of the box for .bss), so the section length calclated in
>   read_section_offset_and_length would be negative, leading to all sorts
>   of havoc.  For the moment, I'm using gas instead to avoid this.
>
> * The patch also fixes a number of typos noticed during testing.
>
> With those changes, I get almost clean libvtv test results on
> i386-pc-solaris2.12 (as/ld and gas/gld) and sparc-sun-solaris2.12
> (gas/ld):
>
> * i386-pc-solaris2.12:
>
> 		=== libvtv tests ===
>
>
> Running target unix
>
> 		=== libvtv Summary for unix ===
>
> # of expected passes		176
>
> Running target unix/-m64
> WARNING: program timed out.
> FAIL: libvtv.mt.cc/register_set_pair_inserts_mt.cc -O0 -fvtable-verify=std -lpthread execution test
> WARNING: program timed out.
> FAIL: libvtv.mt.cc/register_set_pair_inserts_mt.cc -O2 -fvtable-verify=std -lpthread execution test
>
> 		=== libvtv Summary for unix/-m64 ===
>
> # of expected passes		174
> # of unexpected failures	2
>
> 		=== libvtv Summary ===
>
> # of expected passes		350
> # of unexpected failures	2
>
> * sparc-sun-solaris2.12:
>
> 		=== libvtv tests ===
>
>
> Running target unix
> WARNING: program timed out.
> FAIL: libvtv.mt.cc/register_set_pair_inserts_mt.cc -O0 -fvtable-verify=std -lpthread execution test
> WARNING: program timed out.
> FAIL: libvtv.mt.cc/register_set_pair_mt.cc -O0 -fvtable-verify=std -lpthread execution test
> WARNING: program timed out.
> FAIL: libvtv.mt.cc/register_set_pair_inserts_mt.cc -O2 -fvtable-verify=std -lpthread execution test
> WARNING: program timed out.
> FAIL: libvtv.mt.cc/register_set_pair_mt.cc -O2 -fvtable-verify=std -lpthread execution test
>
> 		=== libvtv Summary for unix ===
>
> # of expected passes		172
> # of unexpected failures	4
>
> Running target unix/-m64
> WARNING: program timed out.
> FAIL: libvtv.mt.cc/register_set_pair_inserts_mt.cc -O0 -fvtable-verify=std -lpthread execution test
> WARNING: program timed out.
> FAIL: libvtv.mt.cc/register_set_pair_mt.cc -O0 -fvtable-verify=std -lpthread execution test
> WARNING: program timed out.
> FAIL: libvtv.mt.cc/register_set_pair_inserts_mt.cc -O2 -fvtable-verify=std -lpthread execution test
> WARNING: program timed out.
> FAIL: libvtv.mt.cc/register_set_pair_mt.cc -O2 -fvtable-verify=std -lpthread execution test
>
> 		=== libvtv Summary for unix/-m64 ===
>
> # of expected passes		172
> # of unexpected failures	4
>
> 		=== libvtv Summary ===
>
> # of expected passes		344
> # of unexpected failures	8
>
> I'm still investigating what causes those timeouts, it seems to be a
> scalability issue in libc.
>
> While I realize that we are past stage1, maybe the fact that this patch
> is for an off-by-default feature and well localized still could allow it
> into mainline at this point?

On x86_64-pc-linux-gnu, initial testing found all libvtv testcases
failing initially like this:

FAIL: libvtv.cc/bb_tests.cc -O0 -fvtable-verify=std (test for excess errors)
Excess errors:
vtv_end.c:(.text.startup+0x0): multiple definition of `__VLTprotect'
/var/gcc/gcc-6.0.0-20151111/3.19.8-gcc-gas-gld-vtv/x86_64-pc-linux-gnu/./libvtv/.libs/libvtv.a(vtv_end.o):/var/gcc/gcc-6.0.0-20151111/3.19.8-gcc-gas-gld-vtv/x86_64-pc-linux-gnu/libvtv/vtv_end.c:59: first defined here

It turned out that while the libvtv.so.0 and libvtv.so symlinks were
built, libvtv.so.0.0.0 proper was not.  I'd overlooked this aucotonf
warning:

ro@lokon 1503 > autoconf
configure.ac:109: warning: AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS
/vol/src/gnu/autoconf/autoconf-2.64/lib/autoconf/specific.m4:332: AC_GNU_SOURCE is expanded from...
configure.ac:109: the top level

As expected, adding the macro to configure.ac fixed both the warning and
the libvtv.so.0.0.0 build, so Linux/x86_64 results are all fine again.

Thanks.

	Rainer

2015-08-20  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	libstdc++-v3:
	* acinclude.m4 (GLIBCXX_ENABLE_VTABLE_VERIFY) <solaris2*>: Use
	-Wl,-R in VTV_CXXLINKFLAGS.
	* configure: Regenerate.

	* testsuite/18_support/bad_exception/23591_thread-1.c: Use
	-fvtable-verify=none on Solaris 12+.

	libgcc:
	* Makefile.in (VTV_CFLAGS): New variable.
	(vtv_start$(objext), vtv_end$(objext), vtv_end$(objext))
	(vtv_start_preinit$(objext), vtv_end_preinit$(objext)): Use it.
	* config.host (*-*-solaris2*): Add t-crtstuff-pic to tmake_file.
	Add vtv_start.o, vtv_end.o, vtv_start_preinit.o, vtv_end_preinit.o
	to extra_parts if $enable_vtable_verify = yes.

	libvtv:
	* configure.tgt (*-*-solaris2.[1-9]*): Declare supported.
	* configure.ac: Call AC_USE_SYSTEM_EXTENSIONS.
	<*-*-solaris2*>: Check for init priority support.
	Check for getexecname, __fortify_fail, _obstack_begin.
	(VTV_NO_OBSTACK): New conditional.
	* configure: Regenerate.
	* Makefile.am [VTV_NO_OBSTACK] (obstack.c): Use new condition.
	* Makefile.in: Regenerate.

	* vtv_rts.cc [HAVE_GETEXECNAME] (program_invocation_name): New
	variable.
	(read_section_offset_and_length) [HAVE_GETEXECNAME]: Set it.
	(dl_iterate_phdr_callback) [HAVE_GETEXECNAME]: Set it.

	(__fortify_fail): Wrap in HAVE___FORTIFY_FAIL
	[!HAVE___FORTIFY_FAIL]: Provide non-Cygwin implementation.

	(read_section_offset_and_length): Assert sh_size >= VTV_PAGE_SIZE.
	(iterate_modules): Fix typo.
	Use VTV_PAGE_SIZE.
	(dl_iterate_phdr_callback): Fix typo.
	Use VTV_PAGE_SIZE.
	(__VLTChangePermission): Fix typos.

	include:
	* vtv-change-permission.h (VTV_PAGE_SIZE) [__sun__ && __svr4__ &&
	__sparc__]: Define.

	gcc:
	* config/sol2.h (SUPPORTS_INIT_PRIORITY): Move up.
	(STARTFILE_VTV_SPEC, ENDFILE_VTV_SPEC): Define.
	(STARTFILE_SPEC): Use %(startfile_vtv).
	(ENDFILE_SPEC): Use %(endfile_vtv).
	(SUBTARGET_EXTRA_SPECS): Handle STARTFILE_VTV_SPEC,
	ENDFILE_VTV_SPEC.

	* gcc.c (LINK_COMMAND_SPEC): Move VTABLE_VERIFICATION_SPEC after %{L*}.

Comments

Caroline Tice Nov. 24, 2015, 7:44 p.m. UTC | #1
(Trying this again; the mailer daemon rejected my first message)

All of the patch looks good to me, but I can only approve the libvtv
portion (which I do).  Someone else will need to approve the rest.

-- Caroline Tice
cmtice@google.com


On Tue, Nov 24, 2015 at 2:24 AM, Rainer Orth
<ro@cebitec.uni-bielefeld.de> wrote:
> Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:
>
>> Now that init priority support on Solaris is on mainline, porting libvtv
>> proved to be relatively easy, though it discovered a couple of quirks on
>> a non-gld non-x86 platform.
>
> This patch has now remained unreviewed for a week.  With both Jeff and
> Richi fine with it going into mainline even this late, it would be nice
> if Caroline could find the time to review it.
>
> Linux/x86_64 testing found one minor issue, explained below.  I'm
> attaching the updated patch.
>
>> A considerable part of the patch lives in Solaris-specific files and
>> thus doesn't need approval, though some changes require explanation:
>>
>> * In gcc.c (LINK_COMMAND_SPEC), VTABLE_VERIFICATION_SPEC was before
>>   %{L*}.  The spec includes -lvtv.  Solaris ld, other than GNU ld, heeds
>>   the relative order of -L and -l switches, so the libvtv testcases
>>   wouldn't link manually, but did inside a testsuite run where
>>   LD_LIBRARY_PATH points ld at the correct directory.
>>
>> * Solaris/SPARC uses an 8 kB page size, so a couple of cases where uses
>>   of VTV_PAGE_SIZE had been replaced with hardcoded values of 4096 had
>>   to be reverted.
>>
>> * Inside libgcc, the vtv_*.c files are compiled with
>>   -finhibit-size-directive, whereas in libvtv that flag is absent.  This
>>   caused all testcases to fail due to a linker warning:
>>
>> FAIL: libvtv.cc/bb_tests.cc -O0 -fvtable-verify=std (test for excess errors)
>> Excess errors:
>> ld: warning: symbol '_vtable_map_vars_end' has differing sizes:
>>         (file /var/gcc/gcc-6.0.0-20151111/12-gcc-vtv/sparc-sun-solaris2.12/./libvtv/.libs/libvtv.so value=0x1000; file /var/gcc/gcc-6.0.0-20151111/12-gcc-vtv/gcc/vtv_end.o value=0x0);
>>         /var/gcc/gcc-6.0.0-20151111/12-gcc-vtv/gcc/vtv_end.o definition taken
>>
>> * Like Cygwin, Solaris has no obstack functions in libc, so I'm now
>>   using a common conditional for that.
>>
>> * libvtv requires constructor priority support and dl_iterate_phdr.  The
>>   former needs either a recent (Solaris 12 only so far) ld or gld, the
>>   latter came in Solaris 11 only.
>>
>> * Unlike glibc systems, Solaris has no __fortify_fail in libc; some of
>>   this can probably provided using libbacktrace, which I haven't yet
>>   done.
>>
>> * It also lacks program_invocation_name, but the functionality can be
>>   provided via getexecname() instead.
>>
>> * On Solaris 12/SPARC with Solaris as, the .vtable_map_vars section
>>   wouldn't be pagesize aligned (I'm still looking how to fix this; it
>>   works out of the box for .bss), so the section length calclated in
>>   read_section_offset_and_length would be negative, leading to all sorts
>>   of havoc.  For the moment, I'm using gas instead to avoid this.
>>
>> * The patch also fixes a number of typos noticed during testing.
>>
>> With those changes, I get almost clean libvtv test results on
>> i386-pc-solaris2.12 (as/ld and gas/gld) and sparc-sun-solaris2.12
>> (gas/ld):
>>
>> * i386-pc-solaris2.12:
>>
>>               === libvtv tests ===
>>
>>
>> Running target unix
>>
>>               === libvtv Summary for unix ===
>>
>> # of expected passes          176
>>
>> Running target unix/-m64
>> WARNING: program timed out.
>> FAIL: libvtv.mt.cc/register_set_pair_inserts_mt.cc -O0 -fvtable-verify=std -lpthread execution test
>> WARNING: program timed out.
>> FAIL: libvtv.mt.cc/register_set_pair_inserts_mt.cc -O2 -fvtable-verify=std -lpthread execution test
>>
>>               === libvtv Summary for unix/-m64 ===
>>
>> # of expected passes          174
>> # of unexpected failures      2
>>
>>               === libvtv Summary ===
>>
>> # of expected passes          350
>> # of unexpected failures      2
>>
>> * sparc-sun-solaris2.12:
>>
>>               === libvtv tests ===
>>
>>
>> Running target unix
>> WARNING: program timed out.
>> FAIL: libvtv.mt.cc/register_set_pair_inserts_mt.cc -O0 -fvtable-verify=std -lpthread execution test
>> WARNING: program timed out.
>> FAIL: libvtv.mt.cc/register_set_pair_mt.cc -O0 -fvtable-verify=std -lpthread execution test
>> WARNING: program timed out.
>> FAIL: libvtv.mt.cc/register_set_pair_inserts_mt.cc -O2 -fvtable-verify=std -lpthread execution test
>> WARNING: program timed out.
>> FAIL: libvtv.mt.cc/register_set_pair_mt.cc -O2 -fvtable-verify=std -lpthread execution test
>>
>>               === libvtv Summary for unix ===
>>
>> # of expected passes          172
>> # of unexpected failures      4
>>
>> Running target unix/-m64
>> WARNING: program timed out.
>> FAIL: libvtv.mt.cc/register_set_pair_inserts_mt.cc -O0 -fvtable-verify=std -lpthread execution test
>> WARNING: program timed out.
>> FAIL: libvtv.mt.cc/register_set_pair_mt.cc -O0 -fvtable-verify=std -lpthread execution test
>> WARNING: program timed out.
>> FAIL: libvtv.mt.cc/register_set_pair_inserts_mt.cc -O2 -fvtable-verify=std -lpthread execution test
>> WARNING: program timed out.
>> FAIL: libvtv.mt.cc/register_set_pair_mt.cc -O2 -fvtable-verify=std -lpthread execution test
>>
>>               === libvtv Summary for unix/-m64 ===
>>
>> # of expected passes          172
>> # of unexpected failures      4
>>
>>               === libvtv Summary ===
>>
>> # of expected passes          344
>> # of unexpected failures      8
>>
>> I'm still investigating what causes those timeouts, it seems to be a
>> scalability issue in libc.
>>
>> While I realize that we are past stage1, maybe the fact that this patch
>> is for an off-by-default feature and well localized still could allow it
>> into mainline at this point?
>
> On x86_64-pc-linux-gnu, initial testing found all libvtv testcases
> failing initially like this:
>
> FAIL: libvtv.cc/bb_tests.cc -O0 -fvtable-verify=std (test for excess errors)
> Excess errors:
> vtv_end.c:(.text.startup+0x0): multiple definition of `__VLTprotect'
> /var/gcc/gcc-6.0.0-20151111/3.19.8-gcc-gas-gld-vtv/x86_64-pc-linux-gnu/./libvtv/.libs/libvtv.a(vtv_end.o):/var/gcc/gcc-6.0.0-20151111/3.19.8-gcc-gas-gld-vtv/x86_64-pc-linux-gnu/libvtv/vtv_end.c:59: first defined here
>
> It turned out that while the libvtv.so.0 and libvtv.so symlinks were
> built, libvtv.so.0.0.0 proper was not.  I'd overlooked this aucotonf
> warning:
>
> ro@lokon 1503 > autoconf
> configure.ac:109: warning: AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS
> /vol/src/gnu/autoconf/autoconf-2.64/lib/autoconf/specific.m4:332: AC_GNU_SOURCE is expanded from...
> configure.ac:109: the top level
>
> As expected, adding the macro to configure.ac fixed both the warning and
> the libvtv.so.0.0.0 build, so Linux/x86_64 results are all fine again.
>
> Thanks.
>
>         Rainer
>
> 2015-08-20  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
>
>         libstdc++-v3:
>         * acinclude.m4 (GLIBCXX_ENABLE_VTABLE_VERIFY) <solaris2*>: Use
>         -Wl,-R in VTV_CXXLINKFLAGS.
>         * configure: Regenerate.
>
>         * testsuite/18_support/bad_exception/23591_thread-1.c: Use
>         -fvtable-verify=none on Solaris 12+.
>
>         libgcc:
>         * Makefile.in (VTV_CFLAGS): New variable.
>         (vtv_start$(objext), vtv_end$(objext), vtv_end$(objext))
>         (vtv_start_preinit$(objext), vtv_end_preinit$(objext)): Use it.
>         * config.host (*-*-solaris2*): Add t-crtstuff-pic to tmake_file.
>         Add vtv_start.o, vtv_end.o, vtv_start_preinit.o, vtv_end_preinit.o
>         to extra_parts if $enable_vtable_verify = yes.
>
>         libvtv:
>         * configure.tgt (*-*-solaris2.[1-9]*): Declare supported.
>         * configure.ac: Call AC_USE_SYSTEM_EXTENSIONS.
>         <*-*-solaris2*>: Check for init priority support.
>         Check for getexecname, __fortify_fail, _obstack_begin.
>         (VTV_NO_OBSTACK): New conditional.
>         * configure: Regenerate.
>         * Makefile.am [VTV_NO_OBSTACK] (obstack.c): Use new condition.
>         * Makefile.in: Regenerate.
>
>         * vtv_rts.cc [HAVE_GETEXECNAME] (program_invocation_name): New
>         variable.
>         (read_section_offset_and_length) [HAVE_GETEXECNAME]: Set it.
>         (dl_iterate_phdr_callback) [HAVE_GETEXECNAME]: Set it.
>
>         (__fortify_fail): Wrap in HAVE___FORTIFY_FAIL
>         [!HAVE___FORTIFY_FAIL]: Provide non-Cygwin implementation.
>
>         (read_section_offset_and_length): Assert sh_size >= VTV_PAGE_SIZE.
>         (iterate_modules): Fix typo.
>         Use VTV_PAGE_SIZE.
>         (dl_iterate_phdr_callback): Fix typo.
>         Use VTV_PAGE_SIZE.
>         (__VLTChangePermission): Fix typos.
>
>         include:
>         * vtv-change-permission.h (VTV_PAGE_SIZE) [__sun__ && __svr4__ &&
>         __sparc__]: Define.
>
>         gcc:
>         * config/sol2.h (SUPPORTS_INIT_PRIORITY): Move up.
>         (STARTFILE_VTV_SPEC, ENDFILE_VTV_SPEC): Define.
>         (STARTFILE_SPEC): Use %(startfile_vtv).
>         (ENDFILE_SPEC): Use %(endfile_vtv).
>         (SUBTARGET_EXTRA_SPECS): Handle STARTFILE_VTV_SPEC,
>         ENDFILE_VTV_SPEC.
>
>         * gcc.c (LINK_COMMAND_SPEC): Move VTABLE_VERIFICATION_SPEC after %{L*}.
>
>
>
> --
> -----------------------------------------------------------------------------
> Rainer Orth, Center for Biotechnology, Bielefeld University
>
Jeff Law Nov. 24, 2015, 11:15 p.m. UTC | #2
On 11/24/2015 03:24 AM, Rainer Orth wrote:
> Rainer Orth<ro@CeBiTec.Uni-Bielefeld.DE>  writes:
>
>> >Now that init priority support on Solaris is on mainline, porting libvtv
>> >proved to be relatively easy, though it discovered a couple of quirks on
>> >a non-gld non-x86 platform.
> This patch has now remained unreviewed for a week.  With both Jeff and
> Richi fine with it going into mainline even this late, it would be nice
> if Caroline could find the time to review it.
>
> Linux/x86_64 testing found one minor issue, explained below.  I'm
> attaching the updated patch.
>
>> >A considerable part of the patch lives in Solaris-specific files and
>> >thus doesn't need approval, though some changes require explanation:
>> >
>> >* In gcc.c (LINK_COMMAND_SPEC), VTABLE_VERIFICATION_SPEC was before
>> >   %{L*}.  The spec includes -lvtv.  Solaris ld, other than GNU ld, heeds
>> >   the relative order of -L and -l switches, so the libvtv testcases
>> >   wouldn't link manually, but did inside a testsuite run where
>> >   LD_LIBRARY_PATH points ld at the correct directory.
>> >
>> >* Solaris/SPARC uses an 8 kB page size, so a couple of cases where uses
>> >   of VTV_PAGE_SIZE had been replaced with hardcoded values of 4096 had
>> >   to be reverted.
>> >
>> >* Inside libgcc, the vtv_*.c files are compiled with
>> >   -finhibit-size-directive, whereas in libvtv that flag is absent.  This
>> >   caused all testcases to fail due to a linker warning:
>> >
>> >FAIL: libvtv.cc/bb_tests.cc -O0 -fvtable-verify=std (test for excess errors)
>> >Excess errors:
>> >ld: warning: symbol '_vtable_map_vars_end' has differing sizes:
>> >         (file/var/gcc/gcc-6.0.0-20151111/12-gcc-vtv/sparc-sun-solaris2.12/./libvtv/.libs/libvtv.so value=0x1000; file /var/gcc/gcc-6.0.0-20151111/12-gcc-vtv/gcc/vtv_end.o value=0x0);
>> >         /var/gcc/gcc-6.0.0-20151111/12-gcc-vtv/gcc/vtv_end.o definition taken
>> >
>> >* Like Cygwin, Solaris has no obstack functions in libc, so I'm now
>> >   using a common conditional for that.
>> >
>> >* libvtv requires constructor priority support and dl_iterate_phdr.  The
>> >   former needs either a recent (Solaris 12 only so far) ld or gld, the
>> >   latter came in Solaris 11 only.
>> >
>> >* Unlike glibc systems, Solaris has no __fortify_fail in libc; some of
>> >   this can probably provided using libbacktrace, which I haven't yet
>> >   done.
>> >
>> >* It also lacks program_invocation_name, but the functionality can be
>> >   provided via getexecname() instead.
>> >
>> >* On Solaris 12/SPARC with Solaris as, the .vtable_map_vars section
>> >   wouldn't be pagesize aligned (I'm still looking how to fix this; it
>> >   works out of the box for .bss), so the section length calclated in
>> >   read_section_offset_and_length would be negative, leading to all sorts
>> >   of havoc.  For the moment, I'm using gas instead to avoid this.
>> >
>> >* The patch also fixes a number of typos noticed during testing.

>> >I'm still investigating what causes those timeouts, it seems to be a
>> >scalability issue in libc.
>> >
>> >While I realize that we are past stage1, maybe the fact that this patch
>> >is for an off-by-default feature and well localized still could allow it
>> >into mainline at this point?
> On x86_64-pc-linux-gnu, initial testing found all libvtv testcases
> failing initially like this:
>
> FAIL: libvtv.cc/bb_tests.cc -O0 -fvtable-verify=std (test for excess errors)
> Excess errors:
> vtv_end.c:(.text.startup+0x0): multiple definition of `__VLTprotect'
> /var/gcc/gcc-6.0.0-20151111/3.19.8-gcc-gas-gld-vtv/x86_64-pc-linux-gnu/./libvtv/.libs/libvtv.a(vtv_end.o):/var/gcc/gcc-6.0.0-20151111/3.19.8-gcc-gas-gld-vtv/x86_64-pc-linux-gnu/libvtv/vtv_end.c:59: first defined here
>
> It turned out that while the libvtv.so.0 and libvtv.so symlinks were
> built, libvtv.so.0.0.0 proper was not.  I'd overlooked this aucotonf
> warning:
>
> ro@lokon 1503 > autoconf
> configure.ac:109: warning: AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS
> /vol/src/gnu/autoconf/autoconf-2.64/lib/autoconf/specific.m4:332: AC_GNU_SOURCE is expanded from...
> configure.ac:109: the top level
>
> As expected, adding the macro to configure.ac fixed both the warning and
> the libvtv.so.0.0.0 build, so Linux/x86_64 results are all fine again.
>
> Thanks.
>
> 	Rainer
>
> 2015-08-20  Rainer Orth<ro@CeBiTec.Uni-Bielefeld.DE>
>
> 	libstdc++-v3:
> 	* acinclude.m4 (GLIBCXX_ENABLE_VTABLE_VERIFY) <solaris2*>: Use
> 	-Wl,-R in VTV_CXXLINKFLAGS.
> 	* configure: Regenerate.
>
> 	* testsuite/18_support/bad_exception/23591_thread-1.c: Use
> 	-fvtable-verify=none on Solaris 12+.
>
> 	libgcc:
> 	* Makefile.in (VTV_CFLAGS): New variable.
> 	(vtv_start$(objext), vtv_end$(objext), vtv_end$(objext))
> 	(vtv_start_preinit$(objext), vtv_end_preinit$(objext)): Use it.
> 	* config.host (*-*-solaris2*): Add t-crtstuff-pic to tmake_file.
> 	Add vtv_start.o, vtv_end.o, vtv_start_preinit.o, vtv_end_preinit.o
> 	to extra_parts if $enable_vtable_verify = yes.
>
> 	libvtv:
> 	* configure.tgt (*-*-solaris2.[1-9]*): Declare supported.
> 	* configure.ac: Call AC_USE_SYSTEM_EXTENSIONS.
> 	<*-*-solaris2*>: Check for init priority support.
> 	Check for getexecname, __fortify_fail, _obstack_begin.
> 	(VTV_NO_OBSTACK): New conditional.
> 	* configure: Regenerate.
> 	* Makefile.am [VTV_NO_OBSTACK] (obstack.c): Use new condition.
> 	* Makefile.in: Regenerate.
>
> 	* vtv_rts.cc [HAVE_GETEXECNAME] (program_invocation_name): New
> 	variable.
> 	(read_section_offset_and_length) [HAVE_GETEXECNAME]: Set it.
> 	(dl_iterate_phdr_callback) [HAVE_GETEXECNAME]: Set it.
>
> 	(__fortify_fail): Wrap in HAVE___FORTIFY_FAIL
> 	[!HAVE___FORTIFY_FAIL]: Provide non-Cygwin implementation.
>
> 	(read_section_offset_and_length): Assert sh_size >= VTV_PAGE_SIZE.
> 	(iterate_modules): Fix typo.
> 	Use VTV_PAGE_SIZE.
> 	(dl_iterate_phdr_callback): Fix typo.
> 	Use VTV_PAGE_SIZE.
> 	(__VLTChangePermission): Fix typos.
>
> 	include:
> 	* vtv-change-permission.h (VTV_PAGE_SIZE) [__sun__ && __svr4__ &&
> 	__sparc__]: Define.
>
> 	gcc:
> 	* config/sol2.h (SUPPORTS_INIT_PRIORITY): Move up.
> 	(STARTFILE_VTV_SPEC, ENDFILE_VTV_SPEC): Define.
> 	(STARTFILE_SPEC): Use %(startfile_vtv).
> 	(ENDFILE_SPEC): Use %(endfile_vtv).
> 	(SUBTARGET_EXTRA_SPECS): Handle STARTFILE_VTV_SPEC,
> 	ENDFILE_VTV_SPEC.
>
> 	* gcc.c (LINK_COMMAND_SPEC): Move VTABLE_VERIFICATION_SPEC after %{L*}.
The non-Solaris and non-libvtv bits are OK as well.  I think that covers 
everything since you own the Solaris stuff and Caroline approved the 
libvtv stuff.  Right?

Jeff
Rainer Orth Nov. 25, 2015, 10:06 a.m. UTC | #3
Hi Caroline,

> All of the patch looks good to me, but I can only approve the libvtv
> portion (which I do).  Someone else will need to approve the rest.

thanks.  Jeff did so in the meantime.

>>> * Like Cygwin, Solaris has no obstack functions in libc, so I'm now
>>>   using a common conditional for that.

Just for the record, since I forgot to explain it in the submission:

	* Makefile.am [VTV_NO_OBSTACK] (obstack.c): Use new condition.
	Create empty config.h

Between my initial libvtv port and the submission, current gnulib
obstack.[ch] got imported into libiberty.  obstack.c now unconditionally
includes <config.h>, which doesn't exist in libvtv.  Given that libvtv
isn't built by default, nobody noticed, and it would have shown up on
Cygwin only anyway.  AFAICS, it's not strictly needed, though: the only
macros tested in obstack.c not predefined by either the compiler or libc
are

ENABLE_NLS
HAVE_LIBINTL_H
_OBSTACK_ELIDE_CODE
_OBSTACK_NO_ERROR_HANDLER

Given that libvtv isn't currently localized, the NLS stuff seemed
unimportant, so I just create an empty/fake config.h.

	Rainer
Rainer Orth Nov. 25, 2015, 10:08 a.m. UTC | #4
Jeff Law <law@redhat.com> writes:

>> 2015-08-20  Rainer Orth<ro@CeBiTec.Uni-Bielefeld.DE>
>>
>> 	libstdc++-v3:
>> 	* acinclude.m4 (GLIBCXX_ENABLE_VTABLE_VERIFY) <solaris2*>: Use
>> 	-Wl,-R in VTV_CXXLINKFLAGS.
>> 	* configure: Regenerate.
>>
>> 	* testsuite/18_support/bad_exception/23591_thread-1.c: Use
>> 	-fvtable-verify=none on Solaris 12+.
>>
>> 	libgcc:
>> 	* Makefile.in (VTV_CFLAGS): New variable.
>> 	(vtv_start$(objext), vtv_end$(objext), vtv_end$(objext))
>> 	(vtv_start_preinit$(objext), vtv_end_preinit$(objext)): Use it.
>> 	* config.host (*-*-solaris2*): Add t-crtstuff-pic to tmake_file.
>> 	Add vtv_start.o, vtv_end.o, vtv_start_preinit.o, vtv_end_preinit.o
>> 	to extra_parts if $enable_vtable_verify = yes.
>>
>> 	libvtv:
>> 	* configure.tgt (*-*-solaris2.[1-9]*): Declare supported.
>> 	* configure.ac: Call AC_USE_SYSTEM_EXTENSIONS.
>> 	<*-*-solaris2*>: Check for init priority support.
>> 	Check for getexecname, __fortify_fail, _obstack_begin.
>> 	(VTV_NO_OBSTACK): New conditional.
>> 	* configure: Regenerate.
>> 	* Makefile.am [VTV_NO_OBSTACK] (obstack.c): Use new condition.
>> 	* Makefile.in: Regenerate.
>>
>> 	* vtv_rts.cc [HAVE_GETEXECNAME] (program_invocation_name): New
>> 	variable.
>> 	(read_section_offset_and_length) [HAVE_GETEXECNAME]: Set it.
>> 	(dl_iterate_phdr_callback) [HAVE_GETEXECNAME]: Set it.
>>
>> 	(__fortify_fail): Wrap in HAVE___FORTIFY_FAIL
>> 	[!HAVE___FORTIFY_FAIL]: Provide non-Cygwin implementation.
>>
>> 	(read_section_offset_and_length): Assert sh_size >= VTV_PAGE_SIZE.
>> 	(iterate_modules): Fix typo.
>> 	Use VTV_PAGE_SIZE.
>> 	(dl_iterate_phdr_callback): Fix typo.
>> 	Use VTV_PAGE_SIZE.
>> 	(__VLTChangePermission): Fix typos.
>>
>> 	include:
>> 	* vtv-change-permission.h (VTV_PAGE_SIZE) [__sun__ && __svr4__ &&
>> 	__sparc__]: Define.
>>
>> 	gcc:
>> 	* config/sol2.h (SUPPORTS_INIT_PRIORITY): Move up.
>> 	(STARTFILE_VTV_SPEC, ENDFILE_VTV_SPEC): Define.
>> 	(STARTFILE_SPEC): Use %(startfile_vtv).
>> 	(ENDFILE_SPEC): Use %(endfile_vtv).
>> 	(SUBTARGET_EXTRA_SPECS): Handle STARTFILE_VTV_SPEC,
>> 	ENDFILE_VTV_SPEC.
>>
>> 	* gcc.c (LINK_COMMAND_SPEC): Move VTABLE_VERIFICATION_SPEC after %{L*}.
> The non-Solaris and non-libvtv bits are OK as well.  I think that covers
> everything since you own the Solaris stuff and Caroline approved the libvtv
> stuff.  Right?

Yes indeed.  Thanks for all your totally amazing review work.

	Rainer
diff mbox

Patch

# 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);