This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: Properly support Solaris 2 ABI for symbol versioning in GNU ld


During my work to support Sun symbol versioning in the GCC runtime
libraries with Sun ld, I had to compare the version information
generated by GNU ld and Sun ld.  Doing so, I noticed one important
(though minor) difference.  Comparing the output of pvs -dsv

        libstdc++.so.6 [BASE]:
                _GLOBAL_OFFSET_TABLE_;
                _etext;
                _DYNAMIC;
                _edata;
                _end;
                _PROCEDURE_LINKAGE_TABLE_;

the shared objects created by the Sun linker had a couple of symbols in
he base version, while the base version with GNU ld is empty.  I found
that this is a requirement of the Solaris 2 ABI, documented in the Linker
and Libraries Guide, Ch. 2, Link-Editor, Generating the Output File, p.63.

	http://docs.sun.com/app/docs/doc/819-0690/chapter2-88783?a=view

Those 6 symbols above should be in the base version, with global
linkage.  GNU ld not only didn't do this, but marked _DYNAMIC and
_GLOBAL_OFFSET_TABLE_ as hidden instead, while _PROCEDURE_LINKAGE_TABLE_
wasn't emitted at all on i386.

After several false starts, the solution proved to be relatively easy
(once I'd found my way through the maze that is bfd and ld ;-):

* To enable generation of the _PROCEDURE_LINKAGE_TABLE_ symbol, I had to
  redefine elf_backend_want_plt_sym, which required creating two new
  target vectors (bfd_elf32_i386_sol2_vec, bfd_elf64_x86_64_sol2_vec).
  SPARC is not affected: the plt symbol is created here by default.

* I've made that new target vector the default for the
  i[3-7]86-*-solaris2* and x86_64-*-solaris2* targets.

* To enable associating those 6 symbols with the base version, I've
  created a new ld emulation, solaris2.em, which uses an
  _before_allocation hook to register them as version patterns and
  associate them with a new version node.  This part is a bit hacky
  since it requires duplicating the logic in
  bfd_elf_size_dynamic_sections to get the same version name, and of
  course has to reset to vernum so this becomes a tree for the base
  version.

  With this in place, it just undoes the hiding on the symbols and emits
  them into the .dynamic section, where they are required for version
  symbols.

  Two minor changes to elflink.c (bfd_elf_size_dynamic_sections) were
  required as well to avoid emitting the base version again.

* To use this emulation, I've created four new ones ending in _sol2 and
  changed the i[3-7]86-*-solaris2*, x86_64-*-solaris2*,
  sparc-*-solaris2.[0-6]*, sparc-*-solaris2*, and sparcv9-*-solaris2*
  targets.  While this is sort of ugly, and will reqire subsequent
  changes to the GCC configury to make use of them, I think it's the
  cleanest way to group all Solaris 2 related changes in the future.

With those changes in place, a minimal shared object had exactly the
required symbols in the base version, just as Sun ld does.

Tested so far on i386-pc-solaris2.11, yielding the expected pvs -dsvo
output for a minimal testcase.  sparc-sun-solaris2.11 testing still
outstanding.

Ok for mainline?

	Rainer

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


2010-02-22  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	ld:
	* Makefile.am (ALL_EMULATIONS): Add eelf32_sparc_sol2.o,
	eelf_i386_sol2.o.
	(ALL_64_EMULATIONS): Add eelf_x86_64_sol2.o, eelf64_sparc_sol2.o.
	(eelf32_sparc_sol2.c): New rule.
	(eelf64_sparc_sol2.c): Likewise.
	(eelf_x86_64_sol2.c): Likewise.
	(eelf_i386_sol2.c): Likewise.
	* Makefile.in: Regenerate.
	* configure.tgt (i[3-7]86-*-solaris2*): Change targ_emul to
	elf_i386_sol2.
	Add elf_i386_ldso, elf_x86_64_sol2 to targ_extra_emuls.
	(x86_64-*-solaris2*): Change targ_emul to elf_x86_64_sol2.
	Add elf_x86_64, elf_i386_sol2, elf_i386 to targ_extra_emuls.
	(sparc-*-solaris2.[0-6]*): Change targ_emul to elf32_sparc_sol2.
	Add target_extra_emuls.
	(sparc-*-solaris2*): Change targ_emul to elf32_sparc_sol2.
	Add elf32_sparc, elf64_sparc_sol2 to targ_extra_emuls.
	(sparcv9-*-solaris2*): Change targ_emul to elf64_sparc_sol2.
	Add elf64_sparc, elf32_sparc_sol2 to target_extra_emuls.
	* emulparams/elf32_sparc_sol2.sh: New file.
	* emulparams/elf64_sparc_sol2.sh: New file.
	* emulparams/elf_i386_sol2.sh: New file.
	* emulparams/elf_x86_64_sol2.sh: New file.
	* emultempl/solaris2.em: New file.

	bfd:
	* elflink.c (bfd_elf_size_dynamic_sections): Don't emit base
	version twice.

	Handle Solaris 2 ABI.
	* elf32-i386.c (TARGET_LITTLE_SYM): Redefine to
	bfd_elf32_i386_sol2_vec.
	(TARGET_LITTLE_NAME): Redefine to elf32-i386-sol2.
	(elf32_bed): Redefine to elf32_i386_sol2_bed.
	(elf_backend_want_plt_sym): Redefine to 1.

	* elf64-x86-64.c (TARGET_LITTLE_SYM): Redefine to
	bfd_elf64_x86_64_sol2_vec.
	(TARGET_LITTLE_NAME): Redefine to elf64-x86-64-sol2.
	(elf64_bed): Redefine to elf64_x86_64_sol2_bed.
	(elf_backend_want_plt_sym): Redefine to 1.

	* configure.tgt (i[3-7]86-*-solaris2*): Set targ_defvec to
	bfd_elf32_i386_sol2_vec.
	Add bfd_elf32_i386_vec to targ_selvecs.
	Add bfd_elf64_x86_64_sol2_vec to targ64_selvecs.
	(x86_64-*-solaris2*): Set targ_defvec to bfd_elf32_i386_sol2_vec.
	Add bfd_elf64_x86_64_sol2_vec, bfd_elf32_i386_vec to targ_selvecs.

	* configure.in: Handle bfd_elf32_i386_sol2_vec,
	bfd_elf64_x86_64_sol2_vec.
	* configure: Regenerate.

	* targets.c (bfd_elf32_i386_sol2_vec): Declare.
	(bfd_elf64_x86_64_sol2_vec): Declare.
	(_bfd_target_vector): Add bfd_elf32_i386_sol2_vec,
	bfd_elf64_x86_64_sol2_vec.

Index: bfd/config.bfd
===================================================================
RCS file: /vol/gnu/src/binutils/src-cvs/src/bfd/config.bfd,v
retrieving revision 1.257
diff -u -p -u -p -r1.257 config.bfd
--- bfd/config.bfd	13 Jan 2010 11:49:36 -0000	1.257
+++ bfd/config.bfd	22 Feb 2010 15:35:01 -0000
@@ -499,15 +499,15 @@ case "${targ}" in
     targ_selvecs=i386coff_vec
     ;;
   i[3-7]86-*-solaris2*)
-    targ_defvec=bfd_elf32_i386_vec
-    targ_selvecs=i386coff_vec
-    targ64_selvecs="bfd_elf64_x86_64_vec bfd_elf64_l1om_vec"
+    targ_defvec=bfd_elf32_i386_sol2_vec
+    targ_selvecs="bfd_elf32_i386_vec i386coff_vec"
+    targ64_selvecs="bfd_elf64_x86_64_sol2_vec bfd_elf64_x86_64_vec bfd_elf64_l1om_vec"
     want64=true
     ;;
 #ifdef BFD64
   x86_64-*-solaris2*)
-    targ_defvec=bfd_elf32_i386_vec
-    targ_selvecs="bfd_elf64_x86_64_vec bfd_elf64_l1om_vec i386coff_vec"
+    targ_defvec=bfd_elf32_i386_sol2_vec
+    targ_selvecs="bfd_elf64_x86_64_sol2_vec bfd_elf64_x86_64_vec bfd_elf64_l1om_vec bfd_elf32_i386_vec i386coff_vec"
     want64=true
     ;;
 #endif
Index: bfd/configure.in
===================================================================
RCS file: /vol/gnu/src/binutils/src-cvs/src/bfd/configure.in,v
retrieving revision 1.276
diff -u -p -u -p -r1.276 configure.in
--- bfd/configure.in	13 Jan 2010 11:49:36 -0000	1.276
+++ bfd/configure.in	22 Feb 2010 15:52:54 -0000
@@ -687,6 +687,7 @@ do
     bfd_elf32_i370_vec)		tb="$tb elf32-i370.lo elf32.lo $elf" ;;
     bfd_elf32_i386_dragonfly_vec)
 				tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
+    bfd_elf32_i386_sol2_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_i386_freebsd_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_i386_vxworks_vec)	tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
     bfd_elf32_i386_vec)		tb="$tb elf32-i386.lo elf-ifunc.lo elf-vxworks.lo elf32.lo $elf" ;;
@@ -800,6 +801,7 @@ do
     bfd_elf64_tradbigmips_vec)	tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
     bfd_elf64_tradlittlemips_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
     bfd_elf64_x86_64_freebsd_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
+    bfd_elf64_x86_64_sol2_vec)  tb="$tb elf64-x86-64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
     bfd_elf64_x86_64_vec)	tb="$tb elf64-x86-64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
     bfd_elf64_l1om_vec)		tb="$tb elf64-x86-64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
     bfd_elf64_l1om_freebsd_vec) tb="$tb elf64-x86-64.lo elf-ifunc.lo elf64.lo $elf"; target_size=64 ;;
Index: bfd/elf32-i386.c
===================================================================
RCS file: /vol/gnu/src/binutils/src-cvs/src/bfd/elf32-i386.c,v
retrieving revision 1.229
diff -u -p -u -p -r1.229 elf32-i386.c
--- bfd/elf32-i386.c	5 Feb 2010 14:58:11 -0000	1.229
+++ bfd/elf32-i386.c	22 Feb 2010 13:49:57 -0000
@@ -4718,6 +4718,29 @@ elf_i386_fbsd_post_process_headers (bfd 
 
 #include "elf32-target.h"
 
+/* Solaris 2.  */
+
+#undef	TARGET_LITTLE_SYM
+#define	TARGET_LITTLE_SYM		bfd_elf32_i386_sol2_vec
+#undef	TARGET_LITTLE_NAME
+#define	TARGET_LITTLE_NAME		"elf32-i386-sol2"
+
+/* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE
+   objects won't be recognized.  */
+#undef ELF_OSABI
+
+#undef	elf32_bed
+#define	elf32_bed			elf32_i386_sol2_bed
+
+/* The Solaris 2 ABI requires a plt symbol on all platforms.
+
+   Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output
+   File, p.63.  */
+#undef elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym	1
+
+#include "elf32-target.h"
+
 /* VxWorks support.  */
 
 #undef	TARGET_LITTLE_SYM
Index: bfd/elf64-x86-64.c
===================================================================
RCS file: /vol/gnu/src/binutils/src-cvs/src/bfd/elf64-x86-64.c,v
retrieving revision 1.190
diff -u -p -u -p -r1.190 elf64-x86-64.c
--- bfd/elf64-x86-64.c	5 Feb 2010 14:58:11 -0000	1.190
+++ bfd/elf64-x86-64.c	22 Feb 2010 13:49:33 -0000
@@ -4509,6 +4509,29 @@ static const struct bfd_elf_special_sect
 
 #include "elf64-target.h"
 
+/* Solaris 2 support.  */
+
+#undef  TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM		    bfd_elf64_x86_64_sol2_vec
+#undef  TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME		    "elf64-x86-64-sol2"
+
+/* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE
+   objects won't be recognized.  */
+#undef ELF_OSABI
+
+#undef  elf64_bed
+#define elf64_bed			    elf64_x86_64_sol2_bed
+
+/* The Solaris 2 ABI requires a plt symbol on all platforms.
+
+   Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output
+   File, p.63.  */
+#undef elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym	    1
+
+#include "elf64-target.h"
+
 /* Intel L1OM support.  */
 
 static bfd_boolean
Index: bfd/elflink.c
===================================================================
RCS file: /vol/gnu/src/binutils/src-cvs/src/bfd/elflink.c,v
retrieving revision 1.368
diff -u -p -u -p -r1.368 elflink.c
--- bfd/elflink.c	4 Feb 2010 09:16:41 -0000	1.368
+++ bfd/elflink.c	22 Feb 2010 14:31:06 -0000
@@ -5928,6 +5928,10 @@ bfd_elf_size_dynamic_sections (bfd *outp
 	    {
 	      struct bfd_elf_version_deps *n;
 
+	      /* Don't emit base version twice.  */
+	      if (t->vernum == 0)
+		continue;
+
 	      size += sizeof (Elf_External_Verdef);
 	      size += sizeof (Elf_External_Verdaux);
 	      ++cdefs;
@@ -6027,6 +6031,10 @@ bfd_elf_size_dynamic_sections (bfd *outp
 	      unsigned int cdeps;
 	      struct bfd_elf_version_deps *n;
 
+	      /* Don't emit the base version twice.  */
+	      if (t->vernum == 0)
+		continue;
+
 	      cdeps = 0;
 	      for (n = t->deps; n != NULL; n = n->next)
 		++cdeps;
@@ -6159,7 +6167,7 @@ bfd_elf_size_dynamic_sections (bfd *outp
 	    unsigned int crefs;
 	    bfd_byte *p;
 
-	    /* Build the version definition section.  */
+	    /* Build the version dependency section.  */
 	    size = 0;
 	    crefs = 0;
 	    for (t = elf_tdata (output_bfd)->verref;
Index: bfd/targets.c
===================================================================
RCS file: /vol/gnu/src/binutils/src-cvs/src/bfd/targets.c,v
retrieving revision 1.185
diff -u -p -u -p -r1.185 targets.c
--- bfd/targets.c	26 Jan 2010 13:42:26 -0000	1.185
+++ bfd/targets.c	22 Feb 2010 13:14:45 -0000
@@ -603,6 +603,7 @@ extern const bfd_target bfd_elf32_hppa_n
 extern const bfd_target bfd_elf32_hppa_vec;
 extern const bfd_target bfd_elf32_i370_vec;
 extern const bfd_target bfd_elf32_i386_freebsd_vec;
+extern const bfd_target bfd_elf32_i386_sol2_vec;
 extern const bfd_target bfd_elf32_i386_vxworks_vec;
 extern const bfd_target bfd_elf32_i386_vec;
 extern const bfd_target bfd_elf32_i860_little_vec;
@@ -709,6 +710,7 @@ extern const bfd_target bfd_elf64_sparc_
 extern const bfd_target bfd_elf64_tradbigmips_vec;
 extern const bfd_target bfd_elf64_tradlittlemips_vec;
 extern const bfd_target bfd_elf64_x86_64_freebsd_vec;
+extern const bfd_target bfd_elf64_x86_64_sol2_vec;
 extern const bfd_target bfd_elf64_x86_64_vec;
 extern const bfd_target bfd_elf64_l1om_freebsd_vec;
 extern const bfd_target bfd_elf64_l1om_vec;
@@ -939,6 +941,7 @@ static const bfd_target * const _bfd_tar
 	&bfd_elf32_hppa_vec,
 	&bfd_elf32_i370_vec,
 	&bfd_elf32_i386_freebsd_vec,
+	&bfd_elf32_i386_sol2_vec,
 	&bfd_elf32_i386_vxworks_vec,
 	&bfd_elf32_i386_vec,
 	&bfd_elf32_i860_little_vec,
@@ -1054,6 +1057,7 @@ static const bfd_target * const _bfd_tar
 	&bfd_elf64_tradbigmips_vec,
 	&bfd_elf64_tradlittlemips_vec,
 	&bfd_elf64_x86_64_freebsd_vec,
+	&bfd_elf64_x86_64_sol2_vec,
 	&bfd_elf64_x86_64_vec,
 	&bfd_elf64_l1om_freebsd_vec,
 	&bfd_elf64_l1om_vec,
Index: ld/Makefile.am
===================================================================
RCS file: /vol/gnu/src/binutils/src-cvs/src/ld/Makefile.am,v
retrieving revision 1.277
diff -u -p -u -p -r1.277 Makefile.am
--- ld/Makefile.am	10 Feb 2010 19:48:15 -0000	1.277
+++ ld/Makefile.am	21 Feb 2010 21:25:36 -0000
@@ -163,6 +163,7 @@ ALL_EMULATIONS = \
 	eelf32_i960.o \
 	eelf32_i860.o \
 	eelf32_sparc.o \
+	eelf32_sparc_sol2.o \
 	eelf32_sparc_vxworks.o \
 	eelf32b4300.o \
 	eelf32bfin.o \
@@ -198,7 +199,7 @@ ALL_EMULATIONS = \
 	eelf32mcore.o \
 	eelf32mep.o \
 	eelf32mb_linux.o \
- 	eelf32microblaze.o \
+	eelf32microblaze.o \
 	eelf32mipswindiss.o \
 	eelf32mt.o \
 	eelf32openrisc.o \
@@ -221,6 +222,7 @@ ALL_EMULATIONS = \
 	eelf_i386_chaos.o \
 	eelf_i386_fbsd.o \
 	eelf_i386_ldso.o \
+	eelf_i386_sol2.o \
 	eelf_i386_vxworks.o \
 	eelf_s390.o \
 	egld960.o \
@@ -422,11 +424,13 @@ ALL_64_EMULATIONS = \
 	eshlelf64_nbsd.o \
 	eelf_x86_64.o \
 	eelf_x86_64_fbsd.o \
+	eelf_x86_64_sol2.o \
 	eelf_l1om.o \
 	eelf_l1om_fbsd.o \
 	eelf64_s390.o \
 	eelf64_sparc.o \
 	eelf64_sparc_fbsd.o \
+	eelf64_sparc_sol2.o \
 	eelf64alpha.o \
 	eelf64alpha_fbsd.o \
 	eelf64alpha_nbsd.o \
@@ -833,6 +837,11 @@ em32rlelf_linux.c: $(srcdir)/emulparams/
 eelf32_sparc.c: $(srcdir)/emulparams/elf32_sparc.sh \
   $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} elf32_sparc "$(tdir_elf32_sparc)"
+eelf32_sparc_sol2.c: $(srcdir)/emulparams/elf32_sparc_sol2.sh \
+  $(srcdir)/emulparams/elf32_sparc.sh \
+  $(srcdir)/emultempl/solaris2.em $(ELF_DEPS) \
+  $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+	${GENSCRIPTS} elf32_sparc_sol2 "$(tdir_elf32_sparc_sol2)"
 eelf32_sparc_vxworks.c: $(srcdir)/emulparams/elf32_sparc_vxworks.sh \
   $(srcdir)/emulparams/vxworks.sh $(srcdir)/emulparams/elf32_sparc.sh \
   $(srcdir)/emultempl/vxworks.em $(ELF_DEPS) \
@@ -1086,6 +1095,11 @@ eelf64_sparc_fbsd.c: $(srcdir)/emulparam
   $(srcdir)/emulparams/elf64_sparc.sh \
   $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} elf64_sparc_fbsd "$(tdir_elf64_sparc_fbsd)"
+eelf64_sparc_sol2.c: $(srcdir)/emulparams/elf64_sparc_sol2.sh \
+  $(srcdir)/emulparams/elf64_sparc.sh \
+  $(srcdir)/emultempl/solaris2.em \
+  $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+	${GENSCRIPTS} elf64_sparc_sol2 "$(tdir_elf64_sparc_sol2)"
 eelf64bmip.c: $(srcdir)/emulparams/elf64bmip.sh \
   $(srcdir)/emulparams/elf64bmip-defs.sh \
   $(srcdir)/emulparams/elf32bmipn32-defs.sh $(ELF_DEPS) \
@@ -1121,6 +1135,11 @@ eelf_x86_64_fbsd.c: $(srcdir)/emulparams
   $(srcdir)/emulparams/elf_x86_64.sh \
   $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} elf_x86_64_fbsd "$(tdir_elf_x86_64_fbsd)"
+eelf_x86_64_sol2.c: $(srcdir)/emulparams/elf_x86_64_sol2.sh \
+  $(srcdir)/emulparams/elf_x86_64.sh \
+  $(srcdir)/emultempl/solaris2.em \
+  $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+	${GENSCRIPTS} elf_x86_64_sol2 "$(tdir_elf_x86_64_sol2)"
 eelf_l1om.c: $(srcdir)/emulparams/elf_l1om.sh \
   $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} elf_l1om "$(tdir_elf_l1om)"
@@ -1141,6 +1160,10 @@ eelf_i386_fbsd.c: $(srcdir)/emulparams/e
 eelf_i386_ldso.c: $(srcdir)/emulparams/elf_i386_ldso.sh \
   $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 	${GENSCRIPTS} elf_i386_ldso "$(tdir_elf_i386_ldso)"
+eelf_i386_sol2.c: $(srcdir)/emulparams/elf_i386_sol2.sh \
+  $(srcdir)/emultempl/solaris2.em \
+  $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
+	${GENSCRIPTS} elf_i386_sol2 "$(tdir_elf_i386_sol2)"
 eelf_i386_vxworks.c: $(srcdir)/emulparams/elf_i386_vxworks.sh \
   $(srcdir)/emulparams/vxworks.sh $(srcdir)/emultempl/vxworks.em \
   $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
Index: ld/configure.tgt
===================================================================
RCS file: /vol/gnu/src/binutils/src-cvs/src/ld/configure.tgt,v
retrieving revision 1.230
diff -u -p -u -p -r1.230 configure.tgt
--- ld/configure.tgt	29 Sep 2009 14:17:17 -0000	1.230
+++ ld/configure.tgt	22 Feb 2010 15:48:19 -0000
@@ -207,13 +207,13 @@ x86_64-*-linux-*)	targ_emul=elf_x86_64
 			tdir_i386linux=`echo ${targ_alias}aout | sed -e 's/x86_64/i386/'`
 			tdir_elf_i386=`echo ${targ_alias} | sed -e 's/x86_64/i386/'` ;;
 i[3-7]86-*-sysv[45]*)	targ_emul=elf_i386 ;;
-i[3-7]86-*-solaris2*)	targ_emul=elf_i386_ldso
-                        targ_extra_emuls="elf_i386 elf_x86_64 elf_l1om"
+i[3-7]86-*-solaris2*)	targ_emul=elf_i386_sol2
+                        targ_extra_emuls="elf_i386_ldso elf_i386 elf_x86_64_sol2 elf_x86_64 elf_l1om"
 			targ_extra_libpath=$targ_extra_emuls
                         ;;
 x86_64-*-solaris2*)
-			targ_emul=elf_x86_64
-			targ_extra_emuls="elf_i386 elf_i386_ldso elf_l1om"
+			targ_emul=elf_x86_64_sol2
+			targ_extra_emuls="elf_x86_64 elf_i386_sol2 elf_i386_ldso elf_i386 elf_l1om"
 			targ_extra_libpath=elf_i386
 			tdir_elf_i386=`echo ${targ_alias} | sed -e 's/x86_64/i386/'` ;;
 i[3-7]86-*-unixware)	targ_emul=elf_i386 ;;
@@ -601,14 +601,15 @@ sparc64-*-netbsd* | sparc64-*-openbsd*)
 sparc*-*-netbsd*elf*)	targ_emul=elf32_sparc ;;
 sparc*-*-netbsd*)	targ_emul=sparcnbsd ;;
 sparc-*-solaris2.[0-6] | sparc-*-solaris2.[0-6].*)
-			targ_emul=elf32_sparc ;;
-sparc-*-solaris2*)	targ_emul=elf32_sparc
-			targ_extra_emuls="elf64_sparc"
+			targ_emul=elf32_sparc_sol2
+			targ_extra_emuls=elf32_sparc ;;
+sparc-*-solaris2*)	targ_emul=elf32_sparc_sol2
+			targ_extra_emuls="elf32_sparc elf64_sparc_sol2 elf64_sparc"
 			targ_extra_libpath=$targ_extra_emuls
 			tdir_elf64_sparc=`echo ${targ_alias} | sed -e 's/32//'`	;;
 sparcv9-*-solaris2* | sparc64-*-solaris2*)
-			targ_emul=elf64_sparc
-			targ_extra_emuls="elf32_sparc"
+			targ_emul=elf64_sparc_sol2
+			targ_extra_emuls="elf64_sparc elf32_sparc_sol2 elf32_sparc"
 			targ_extra_libpath=$targ_extra_emuls
 			tdir_elf32_sparc=`echo ${targ_alias} | sed -e 's/64//'` ;;
 sparc*-*-solaris2*)	targ_emul=elf32_sparc ;;
Index: ld/emulparams/elf32_sparc_sol2.h
===================================================================
RCS file: ld/emulparams/elf32_sparc_sol2.h
diff -N ld/emulparams/elf32_sparc_sol2.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/emulparams/elf32_sparc_sol2.h	21 Feb 2010 20:58:03 -0000
@@ -0,0 +1,2 @@
+. ${srcdir}/emulparams/elf32_sparc.sh
+EXTRA_EM_FILE=solaris2
Index: ld/emulparams/elf64_sparc_sol2.h
===================================================================
RCS file: ld/emulparams/elf64_sparc_sol2.h
diff -N ld/emulparams/elf64_sparc_sol2.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/emulparams/elf64_sparc_sol2.h	21 Feb 2010 20:58:20 -0000
@@ -0,0 +1,2 @@
+. ${srcdir}/emulparams/elf64_sparc.sh
+EXTRA_EM_FILE=solaris2
Index: ld/emulparams/elf_i386_sol2.sh
===================================================================
RCS file: ld/emulparams/elf_i386_sol2.sh
diff -N ld/emulparams/elf_i386_sol2.sh
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/emulparams/elf_i386_sol2.sh	22 Feb 2010 13:05:19 -0000
@@ -0,0 +1,3 @@
+. ${srcdir}/emulparams/elf_i386_ldso.sh
+EXTRA_EM_FILE=solaris2
+OUTPUT_FORMAT="elf32-i386-sol2"
Index: ld/emulparams/elf_x86_64_sol2.sh
===================================================================
RCS file: ld/emulparams/elf_x86_64_sol2.sh
diff -N ld/emulparams/elf_x86_64_sol2.sh
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/emulparams/elf_x86_64_sol2.sh	22 Feb 2010 13:05:27 -0000
@@ -0,0 +1,3 @@
+. ${srcdir}/emulparams/elf_x86_64.sh
+EXTRA_EM_FILE=solaris2
+OUTPUT_FORMAT="elf32-x86-64-sol2"
Index: ld/emultempl/solaris2.em
===================================================================
RCS file: ld/emultempl/solaris2.em
diff -N ld/emultempl/solaris2.em
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/emultempl/solaris2.em	22 Feb 2010 16:20:59 -0000
@@ -0,0 +1,108 @@
+# This shell script emits a C file. -*- C -*-
+# It does some substitutions.
+if [ -z "$MACHINE" ]; then
+  OUTPUT_ARCH=${ARCH}
+else
+  OUTPUT_ARCH=${ARCH}:${MACHINE}
+fi
+fragment <<EOF
+/* This file is generated by a shell script.  DO NOT EDIT! */
+
+/* Solaris 2 emulation code for ${EMULATION_NAME}
+   Copyright 2010 Free Software Foundation, Inc.
+   Written by Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+   This file is part of the GNU Binutils.
+
+   This program 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 of the License, or
+   (at your option) any later version.
+
+   This program 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.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#define TARGET_IS_${EMULATION_NAME}
+
+/* The Solaris 2 ABI requires some symbols to always be bound to the base
+   version in a shared object.
+
+   Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output
+   File, p.63.  */
+static void
+elf_solaris2_before_allocation (void)
+{
+  /* Symbols required to be bound to the base version.  */
+  static const char *basever_syms[] = {
+    "_DYNAMIC",
+    "_GLOBAL_OFFSET_TABLE_",
+    "_PROCEDURE_LINKAGE_TABLE_",
+    "_edata",
+    "_end",
+    "_etext",
+    NULL
+  };
+  const char **sym;
+
+  /* Only do this if emitting a shared object and versioning is in place. */
+  if (link_info.shared
+      && (lang_elf_version_info != NULL || link_info.create_default_symver))
+    {
+      struct bfd_elf_version_expr *globals = NULL, *locals = NULL;
+      struct bfd_elf_version_tree *basever;
+      const char *soname;
+
+      for (sym = basever_syms; *sym != NULL; sym++)
+	{
+	  /* Create a version pattern for this symbol.  Some of them start
+	     off as local, others as global, so try both.  */
+	  globals = lang_new_vers_pattern (globals, *sym, NULL, TRUE);
+	  locals = lang_new_vers_pattern (locals, *sym, NULL, TRUE);
+	}
+
+      /* New version node for those symbols.  */
+      basever = lang_new_vers_node (globals, locals);
+
+      /* The version name matches what bfd_elf_size_dynamic_sections uses
+	 for the base version.  */
+      soname = bfd_elf_get_dt_soname (link_info.output_bfd);
+      if (soname == NULL)
+	soname = lbasename (bfd_get_filename (link_info.output_bfd));
+
+      /* Register the node.  */
+      lang_register_vers_node (soname, basever, NULL);
+      /* Enforce base version.  The encoded vd_ndx is vernum + 1.  */
+      basever->vernum = 0;
+
+      for (sym = basever_syms; *sym != NULL; sym++)
+	{
+	  struct elf_link_hash_entry *h;
+
+	  /* Lookup symbol.  */
+	  h = elf_link_hash_lookup (elf_hash_table (&link_info), *sym,
+				    FALSE, FALSE, FALSE);
+	  if (h == NULL)
+	    continue;
+
+	  /* Undo the hiding done by _bfd_elf_define_linkage_sym.  */
+	  h->forced_local = 0;
+	  h->other &= ~STV_HIDDEN;
+
+	  /* Emit it into the .dynamic section, too.  */
+	  bfd_elf_link_record_dynamic_symbol (&link_info, h);
+	}
+    }
+
+  gld${EMULATION_NAME}_before_allocation ();
+}
+
+EOF
+
+LDEMUL_BEFORE_ALLOCATION=elf_solaris2_before_allocation


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]