Bug 50166 - .init_array/.fini_array support doesn't work on Solaris
Summary: .init_array/.fini_array support doesn't work on Solaris
Status: ASSIGNED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: ---
Assignee: Rainer Orth
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-08-23 15:44 UTC by Rainer Orth
Modified: 2012-07-02 14:08 UTC (History)
2 users (show)

See Also:
Host: i386-pc-solaris2.10
Target: i386-pc-solaris2.10
Build: i386-pc-solaris2.10
Known to work:
Known to fail:
Last reconfirmed: 2011-08-26 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Rainer Orth 2011-08-23 15:44:27 UTC
Between 20110819 and 20110823, go1 started to ICE compiling libgo.  This seems
to happen for every file, e.g.

> ./go1 /var/gcc/reghunt/trunk/libgo/go/sync/atomic/doc.go
<built-in>:0:0: internal compiler error: Segmentation Fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

Running go1 under gdb, I find this stacktrace:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1 (LWP 1)]
0x08a9747d in std::_Rb_tree_decrement (__x=0x8ea3240) at /var/gcc/reghunt/trunk/libstdc++-v3/src/tree.cc:91
(gdb) where
#0  0x08a9747d in std::_Rb_tree_decrement (__x=0x8ea3240) at /var/gcc/reghunt/trunk/libstdc++-v3/src/tree.cc:91
#1  0x08a8c640 in std::_Rb_tree_iterator<std::pair<std::string const, Named_type*> >::operator-- (this=0x8ea323c, __v=...) at /var/gcc/reghunt/10-gcc/prev-i386-pc-solaris2.10/libstdc++-v3/include/bits/stl_tree.h:203
#2  std::_Rb_tree<std::string, std::pair<std::string const, Named_type*>, std::_Select1st<std::pair<std::string const, Named_type*> >, std::less<std::string>, std::allocator<std::pair<std::string const, Named_type*> > >::_M_insert_unique (this=0x8ea323c, __v=...) at /var/gcc/reghunt/10-gcc/prev-i386-pc-solaris2.10/libstdc++-v3/include/bits/stl_tree.h:1285
#3  0x081d9370 in std::map<std::string, Named_type*, std::less<std::string>, std::allocator<std::pair<std::string const, Named_type*> > >::insert (name=0x8b3b73e <error reading variable>, is_unsigned=true, bits=8, runtime_type_kind=8) at /var/gcc/reghunt/10-gcc/prev-i386-pc-solaris2.10/libstdc++-v3/include/bits/stl_map.h:521
#4  Integer_type::create_integer_type (name=0x8b3b73e <error reading variable>, is_unsigned=true, bits=8, runtime_type_kind=8) at /var/gcc/reghunt/trunk/gcc/go/gofrontend/types.cc:1837
#5  0x081a29a6 in Gogo::Gogo (this=0x8ff9a30, backend=0x8ea2da4, int_type_size=32, pointer_size=32) at /var/gcc/reghunt/trunk/gcc/go/gofrontend/gogo.cc:44
#6  0x08190d6c in go_create_gogo (int_type_size=32, pointer_size=32) at /var/gcc/reghunt/trunk/gcc/go/gofrontend/go.cc:31
#7  0x0818d62b in go_langhook_init () at /var/gcc/reghunt/trunk/gcc/go/go-lang.c:96
#8  0x0844c797 in lang_dependent_init (argc=2, argv=0x80474c4) at /var/gcc/reghunt/trunk/gcc/toplev.c:1714
#9  do_compile (argc=2, argv=0x80474c4) at /var/gcc/reghunt/trunk/gcc/toplev.c:1872
#10 toplev_main (argc=2, argv=0x80474c4) at /var/gcc/reghunt/trunk/gcc/toplev.c:1962
#11 0x08a74eeb in main (argc=2, argv=0x80474c4) at /var/gcc/reghunt/trunk/gcc/main.c:36
(gdb) up
#1  0x08a8c640 in std::_Rb_tree_iterator<std::pair<std::string const, Named_type*> >::operator-- (this=0x8ea323c, __v=...) at /var/gcc/reghunt/10-gcc/prev-i386-pc-solaris2.10/libstdc++-v3/include/bits/stl_tree.h:203
(gdb) up
#2  std::_Rb_tree<std::string, std::pair<std::string const, Named_type*>, std::_Select1st<std::pair<std::string const, Named_type*> >, std::less<std::string>, std::allocator<std::pair<std::string const, Named_type*> > >::_M_insert_unique (this=0x8ea323c, __v=...) at /var/gcc/reghunt/10-gcc/prev-i386-pc-solaris2.10/libstdc++-v3/include/bits/stl_tree.h:1285
(gdb) up
#3  0x081d9370 in std::map<std::string, Named_type*, std::less<std::string>, std::allocator<std::pair<std::string const, Named_type*> > >::insert (name=0x8b3b73e <error reading variable>, is_unsigned=true, bits=8, runtime_type_kind=8) at /var/gcc/reghunt/10-gcc/prev-i386-pc-solaris2.10/libstdc++-v3/include/bits/stl_map.h:521
(gdb) up
#4  Integer_type::create_integer_type (name=0x8b3b73e <error reading variable>, is_unsigned=true, bits=8, runtime_type_kind=8) at /var/gcc/reghunt/trunk/gcc/go/gofrontend/types.cc:1837
(gdb) where
#0  0x08a9747d in std::_Rb_tree_decrement (__x=0x8ea3240) at /var/gcc/reghunt/trunk/libstdc++-v3/src/tree.cc:91
#1  0x08a8c640 in std::_Rb_tree_iterator<std::pair<std::string const, Named_type*> >::operator-- (this=0x8ea323c, __v=...) at /var/gcc/reghunt/10-gcc/prev-i386-pc-solaris2.10/libstdc++-v3/include/bits/stl_tree.h:203
#2  std::_Rb_tree<std::string, std::pair<std::string const, Named_type*>, std::_Select1st<std::pair<std::string const, Named_type*> >, std::less<std::string>, std::allocator<std::pair<std::string const, Named_type*> > >::_M_insert_unique (this=0x8ea323c, __v=...) at /var/gcc/reghunt/10-gcc/prev-i386-pc-solaris2.10/libstdc++-v3/include/bits/stl_tree.h:1285
#3  0x081d9370 in std::map<std::string, Named_type*, std::less<std::string>, std::allocator<std::pair<std::string const, Named_type*> > >::insert (name=0x8b3b73e <error reading variable>, is_unsigned=true, bits=8, runtime_type_kind=8) at /var/gcc/reghunt/10-gcc/prev-i386-pc-solaris2.10/libstdc++-v3/include/bits/stl_map.h:521
#4  Integer_type::create_integer_type (name=0x8b3b73e <error reading variable>, is_unsigned=true, bits=8, runtime_type_kind=8) at /var/gcc/reghunt/trunk/gcc/go/gofrontend/types.cc:1837
#5  0x081a29a6 in Gogo::Gogo (this=0x8ff9a30, backend=0x8ea2da4, int_type_size=32, pointer_size=32) at /var/gcc/reghunt/trunk/gcc/go/gofrontend/gogo.cc:44
#6  0x08190d6c in go_create_gogo (int_type_size=32, pointer_size=32) at /var/gcc/reghunt/trunk/gcc/go/gofrontend/go.cc:31
#7  0x0818d62b in go_langhook_init () at /var/gcc/reghunt/trunk/gcc/go/go-lang.c:96
#8  0x0844c797 in lang_dependent_init (argc=2, argv=0x80474c4) at /var/gcc/reghunt/trunk/gcc/toplev.c:1714
#9  do_compile (argc=2, argv=0x80474c4) at /var/gcc/reghunt/trunk/gcc/toplev.c:1872
#10 toplev_main (argc=2, argv=0x80474c4) at /var/gcc/reghunt/trunk/gcc/toplev.c:1962
#11 0x08a74eeb in main (argc=2, argv=0x80474c4) at /var/gcc/reghunt/trunk/gcc/main.c:36
Comment 1 Ian Lance Taylor 2011-08-24 17:59:14 UTC
I haven't been able to recreate this crash yet.  According to the backtrace the crash occurs the very first time a value is added to Integer_type::named_integer_types, which is a std::map.  The backtrace seems to show that the code is trying to decrement a variable set to end(), which crashes because the map is empty.  I don't know why this is happening.  With the information I have so far it does not seem to be Go related.
Comment 2 ro@CeBiTec.Uni-Bielefeld.DE 2011-08-25 13:40:57 UTC
I've just checked that it still occurs with current mainline.  I'm
running a reghunt to identify the culprit.

	Rainer
Comment 3 Rainer Orth 2011-08-26 14:23:51 UTC
The reghunt identified the culprit patch:

2011-08-20  H.J. Lu  <hongjiu.lu@intel.com>

	PR other/46770
	* config.gcc (tm_file): Add initfini-array.h if
	.init_arrary/.fini_array are supported.
[...]

The problem is that the test spuriously succeeds, but .init_array/.fini_array
support doesn't work as assumed:

If I add debug printf's to the ctors, dtors, and main, I find that only main
runs.

One problem with the test is that it fails to check that any of the destructors
have run.  Unfortunately, it doesn't even work on CentOS 5.5 with mainline
gcc, gas and gld 2.21:

ctor1007 entry: count = 0
Aborted

so I'm not completely sure how it is supposed to work.  At the very least, we
need

diff --git a/gcc/acinclude.m4 b/gcc/acinclude.m4
--- a/gcc/acinclude.m4
+++ b/gcc/acinclude.m4
@@ -477,6 +477,8 @@ void (*const dtors65535[]) ()
 int
 main ()
 {
+  if (count != 65535)
+    abort ();
   return 0;
 }
 #endif

or whatever value count is supposed to have here.

This patch at least allowed a successfull i386-pc-solaris2.11 bootstrap.

As for other issues with the testcase:

void (*const ctors65535[]) ()
  __attribute__ ((section (".ctors"), aligned (sizeof (void *))))
  = { ctor65535 };

leads to

       .section        .ctors,"a",@progbits

while using __attribute__ ((constructor) instead works.  It has

       .section        .ctors,"aw",@progbits

crtbegin.o and crtend.o already have the latter form, and Sun ld only merges
input sections if all of sh_name, sh_flags, and sh_type match.  The resulting
executable has two different .ctors sections, as can be seen with 

> elfdump -N .ctors -c initfini      

Section Header[24]:  sh_name: .ctors
    sh_addr:      0x8051084       sh_flags:   [ SHF_ALLOC ]
    sh_size:      0x4             sh_type:    [ SHT_PROGBITS ]
    sh_offset:    0x1084          sh_entsize: 0
    sh_link:      0               sh_info:    0
    sh_addralign: 0x4       

Section Header[32]:  sh_name: .ctors
    sh_addr:      0x8061260       sh_flags:   [ SHF_WRITE SHF_ALLOC ]
    sh_size:      0x8             sh_type:    [ SHT_PROGBITS ]
    sh_offset:    0x1260          sh_entsize: 0
    sh_link:      0               sh_info:    0
    sh_addralign: 0x4       

I don't know why __attribute__ ((section(".ctors)) creates a read-only section;
there seems no way to set a section's SECTION_WRITE flag.

The other problem with the testcase is the use of .ctors.<N> sections.  AFAICT
the coalescing of .ctors.<N> sections into .ctors (and similar behavior for
.dtors.<N>, .init_array.<N> and .fini_array.<N>) is a GNU ld feature or
implementation detail not called for by the ELF gABI.  Please point out where
this is specified if I'm wrong.  Certainly, Sun ld (and SGI ld for that matter)
don't do this.

  Rainer
Comment 4 Rainer Orth 2011-08-26 15:17:45 UTC
Author: ro
Date: Fri Aug 26 15:17:42 2011
New Revision: 178116

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=178116
Log:
Disable .init_array/.fini_array support on Solaris (PR target/50166)

	PR target/50166
	* acinclude.m4 (gcc_AC_INITFINI_ARRAY): Check count in main.
	* configure: Regenerate.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/acinclude.m4
    trunk/gcc/configure   (contents, props changed)
Comment 5 Ian Lance Taylor 2012-02-17 15:59:42 UTC
Can this PR be closed?  It seems to have been fixed.
Comment 6 ro@CeBiTec.Uni-Bielefeld.DE 2012-02-17 16:03:56 UTC
> --- Comment #5 from Ian Lance Taylor <ian at airs dot com> 2012-02-17 15:59:42 UTC ---
> Can this PR be closed?  It seems to have been fixed.

Not yet: support currently isn't detected, a partial patch for which is
pending:

	http://gcc.gnu.org/ml/gcc-patches/2012-02/msg00939.html

Even after that patch, it doesn't work with Sun ld (which I plan to work
on with the linker guys) and on SPARC, even with gas/gld.  I'd like to
keep the PR open until then.

	Rainer
Comment 7 Jing Yu 2012-02-22 22:04:44 UTC
Author: jingyu
Date: Wed Feb 22 22:04:39 2012
New Revision: 184493

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=184493
Log:
2012-02-21   Jing Yu  <jingyu@google.com>

	Google Ref 47894
	Backport from mainline r177933, r175181, r177963, r178116, r183299.

	2011-08-20  H.J. Lu  <hongjiu.lu@intel.com>
	PR other/46770
	* config.gcc (tm_file): Add initfini-array.h if
	.init_arrary/.fini_array are supported.
	* crtstuff.c: Don't generate .ctors nor .dtors sections if
	USE_INITFINI_ARRAY is defined.
	* output.h (default_elf_init_array_asm_out_constructor): New.
	(default_elf_fini_array_asm_out_destructor): Likewise.
	* varasm.c (elf_init_array_section): Likewise.
	(elf_fini_array_section): Likewise.
	(get_elf_initfini_array_priority_section): Likewise.
	(default_elf_init_array_asm_out_constructor): Likewise.
	(default_elf_fini_array_asm_out_destructor): Likewise.
	* config/initfini-array.h: New.
	
	2011-06-18  H.J. Lu  <hongjiu.lu@intel.com>
	PR other/49325
	* acinclude.m4 (gcc_AC_INITFINI_ARRAY): Properly check if
	.init_array can be used with .ctors on targets.
	* configure: Regenerated.

	2011-08-22  H.J. Lu  <hongjiu.lu@intel.com>
	* acinclude.m4 (gcc_AC_INITFINI_ARRAY): Error if __ELF__ isn't
	defined.
	* configure: Regenerated.

	2011-08-26  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
	PR target/50166
	* acinclude.m4 (gcc_AC_INITFINI_ARRAY): Check count in main.
	* configure: Regenerate.

	2012-01-19  Jakub Jelinek  <jakub@redhat.com>
	PR bootstrap/50237
	* config/initfini-array.h: Guard content of the header
	with #ifdef HAVE_INITFINI_ARRAY.
	* configure.ac: Move gcc_AC_INITFINI_ARRAY much later into the
	file.
	Add initfini-array.h to tm_file here.
	* acinclude.m4 (gcc_AC_INITFINI_ARRAY): For non-ia64 do a
	linker test.
	* config.gcc: Don't add initfini-array.h to tm_file here.
	* configure: Regenerated.


Added:
    branches/google/gcc-4_6/gcc/config/initfini-array.h
Modified:
    branches/google/gcc-4_6/gcc/ChangeLog.google-4_6
    branches/google/gcc-4_6/gcc/acinclude.m4
    branches/google/gcc-4_6/gcc/configure
    branches/google/gcc-4_6/gcc/configure.ac
    branches/google/gcc-4_6/gcc/crtstuff.c
    branches/google/gcc-4_6/gcc/output.h
    branches/google/gcc-4_6/gcc/varasm.c
Comment 8 Jing Yu 2012-02-22 22:26:46 UTC
Author: jingyu
Date: Wed Feb 22 22:26:40 2012
New Revision: 184494

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=184494
Log:
2012-02-21   Jing Yu  <jingyu@google.com>

	Bakcport r175181, r177963, r178116, r183299 from mainline.

	2011-06-18  H.J. Lu  <hongjiu.lu@intel.com>
	PR other/49325
	* acinclude.m4 (gcc_AC_INITFINI_ARRAY): Properly check if
	.init_array can be used with .ctors on targets.
	* configure: Regenerated.

	2011-08-22  H.J. Lu  <hongjiu.lu@intel.com>
	* acinclude.m4 (gcc_AC_INITFINI_ARRAY): Error if __ELF__ isn't
	defined.
	* configure: Regenerated.

	2011-08-26  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
	PR target/50166
	* acinclude.m4 (gcc_AC_INITFINI_ARRAY): Check count in main.
	* configure: Regenerate.

	2012-01-19  Jakub Jelinek  <jakub@redhat.com>
	PR bootstrap/50237
	* config/initfini-array.h: Guard content of the header
	with #ifdef HAVE_INITFINI_ARRAY.
	* configure.ac: Move gcc_AC_INITFINI_ARRAY much later into the
	file.
	Add initfini-array.h to tm_file here.
	* acinclude.m4 (gcc_AC_INITFINI_ARRAY): For non-ia64 do a
	linker test.
	* config.gcc: Don't add initfini-array.h to tm_file here.
	* configure: Regenerated.


Modified:
    branches/google/gcc-4_6_2-mobile/gcc/ChangeLog.google-4_6
    branches/google/gcc-4_6_2-mobile/gcc/acinclude.m4
    branches/google/gcc-4_6_2-mobile/gcc/config.gcc
    branches/google/gcc-4_6_2-mobile/gcc/config/initfini-array.h
    branches/google/gcc-4_6_2-mobile/gcc/configure
    branches/google/gcc-4_6_2-mobile/gcc/configure.ac
Comment 9 Richard Biener 2012-03-22 08:26:08 UTC
GCC 4.7.0 is being released, adjusting target milestone.