Avoid link error with Solaris ld and local COMDAT group signature symbols (PR gas/12181)

Rainer Orth ro@CeBiTec.Uni-Bielefeld.DE
Wed Nov 10 12:50:00 GMT 2010


As reported in PR gas/12181, this patch

2010-10-23  Mark Mitchell  <mark@codesourcery.com>

	* config/obj-elf.c (elf_adjust_symtab): New.  Move group section
	processing here from elf_frob_file.  Ensure that group signature
	symbols have the name of the group.
	(elf_frob_file): Move group section processing to
	elf_adjust_symtab.
	* config/obj-elf.h (elf_adjust_symtab): Declare.
	(obj_adjust_symtab): Define.
	* config/tc-arm.c (arm_adjust_symtab): Call elf_adjust_symtab.

broke GCC mainline bootstrap on Solaris 11 with CVS gas and Sun ld.

The problem is seen with this testcase:

$ cat group.s
	.section	.text.D2Ev,"axG",@progbits,D5Ev,comdat
	.type	D2Ev, @function
D2Ev:
	.section	.text.D0Ev,"axG",@progbits,D5Ev,comdat
	.type	D0Ev, @function
D0Ev:
$  gas -o group.o group.s
$ ld -G -o group.so group.o
ld: fatal: file group.o: group section [1].group: invalid group symbol D5Ev
ld: fatal: file group.o: section [1].group: SHF_GROUP flag set, but no
corresponding SHT_GROUP section found
ld: fatal: file group.o: section [5].text.D2Ev: SHF_GROUP flag set, but no
corresponding SHT_GROUP section found
ld: fatal: file group.o: section [6].text.D0Ev: SHF_GROUP flag set, but no
corresponding SHT_GROUP section found
ld: fatal: file processing errors. No output written to group.so

Currently, ld chokes on the local group signature symbol.

While the Solaris linker maintainers are willing to change ld,
unfortunately nobody cared to comment on their analysis in the PR.
Could someone (Mark?) please to so to get some progress on the Sun ld
side of things?

On the other hand, this doesn't help for existing installations.  To
remedy this, I've tried my idea to make the group signature symbol
global hidden instead of local, and this worked without problems.

Therefore I'd like to propose the following patch, both for mainline and
the 2.21 branch:

2010-11-10  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	gas:
	PR gas/12181
	* config/obj-elf.c (elf_adjust_symtab): Make sy global hidden.

diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
index 79f8033..34d11fe 100644
--- a/gas/config/obj-elf.c
+++ b/gas/config/obj-elf.c
@@ -2142,7 +2142,8 @@ elf_adjust_symtab (void)
 	{
 	  /* Create the symbol now.  */
 	  sy = symbol_new (group_name, now_seg, (valueT) 0, frag_now);
-	  symbol_get_obj (sy)->local = 1;
+	  symbol_get_bfdsym (sy)->flags |= BSF_OBJECT | BSF_GLOBAL;
+	  S_SET_OTHER (sy, STV_HIDDEN);
 	  symbol_table_insert (sy);
 	}
       elf_group_id (s) = symbol_get_bfdsym (sy);

Mainline GCC bootstrap with CVS gas and gld worked, and a bootstrap with
gas and Sun ld allowed libstdc++.so to link.  It later failed linking
various libjava tools against libgcj.so, but this is an artefact of the
Solaris symbol versioning support in GCC: the contrib/make_sunver.pl
script currently uses nm and doesn't take symbol visibility support into
account, so a global hidden symbol becomes global with default
visibility in libgcj.so.  I'm working to use elfdump -s instead of nm
there, both to avoid this issue and because it has become obvious that
the nm-based variant is very fragile.

Ok for mainline and 2.21 branch?

	Rainer

-- 
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University



More information about the Binutils mailing list