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]

Support TLS common symbols


Looking at the failures from gcc's libgomp testsuite showed me that
gold doesn't support TLS common symbols.  As far as I can tell, the
only way to get such a symbol is to use an OpenMP directive.  This
patch adds support for TLS common symbols, with a test case.

(With this patch, the whole libgomp testsuite passes with gold.)

Ian


	* common.cc (Symbol_table::allocate_commons): Remove options
	parameter.  Change caller.
	(Symbol_table::do_allocate_commons): Remove options parameter.
	Change caller.  Just call do_allocate_commons_list twice.
	(Symbol_table::do_allocate_commons_list): New function, broken out
	of do_allocate_commons.
	* common.h (class Allocate_commons_task): Remove options_ field.
	Update constructor.
	* symtab.cc (Symbol_table::Symbol_table): Initialize
	tls_commons_.
	(Symbol_table::add_from_object): Put TLS common symbols on
	tls_commons_ list.
	(Symbol_table::sized_finalize_symbol): Handle STT_TLS symbols
	which are IN_OUTPUT_DATA.
	* symtab.h (class Symbol_table): Add tls_commons_ field.  Update
	allocate_commons and do_allocate_commons declarations.  Declare
	do_allocate_commons_list.
	* gold.cc (queue_middle_tasks): Update creation of
	Allocate_commons_task to not pass options.
	* testsuite/Makefile.am (INCLUDES): Add -I.. .
	(TLS_TEST_C_FLAGS): New variable.
	(tls_test_c_pic.o): New target.
	(tls_test_shared.so): Link in tls_test_c_pic.o.
	(tls_test_c_pic_ie.o): New target.
	(tls_test_ie_shared.so): Link in tls_test_c_pic_ie.o.
	(tls_test_DEPENDENCIES, tls_test_LDADD): Add tls_test_c.o.
	(tls_test_c.o): New target.
	(tls_pic_test_DEPENDENCIES): Add tls_test_c_pic.o.
	(tls_pic_test_LDADD): Likewise.
	(tls_shared_gd_to_ie_test_DEPENDENCIES): Add tls_test_c_pic.o.
	(tls_shared_gd_to_ie_test_LDADD): Likewise.
	(tls_test_c_gnu2.o): New target.
	(tls_shared_gnu2_gd_to_ie_test_DEPENDENCIES): Add
	tls_test_c_gnu2.o.
	(tls_shared_gnu2_gd_to_ie_test_LDADD): Likewise.
	(tls_test_gnu2_shared.so): Link in tls_test_c_gnu2.o.
	(tls_test_shared_nonpic.so): Link in tls_test_c.o.
	* testsuite/tls_test.cc: Include "config.h".
	(t_last): Call t11_last.
	* testsuite/tls_test.h (t11, t11_last): Declare.
	* testsuite/tls_test_c.c: New file.
	* testsuite/tls_test_main.cc (thread_routine): Call t11.
	* configure.ac: Check for OpenMP support.
	* configure, config.in, Makefile.in: Rebuild.
	* testsuite/Makefile.in: Rebuild.


Index: common.cc
===================================================================
RCS file: /cvs/src/src/gold/common.cc,v
retrieving revision 1.15
diff -u -p -r1.15 common.cc
--- common.cc	27 Mar 2008 19:57:41 -0000	1.15
+++ common.cc	17 Apr 2008 07:09:06 -0000
@@ -60,7 +60,7 @@ Allocate_commons_task::locks(Task_locker
 void
 Allocate_commons_task::run(Workqueue*)
 {
-  this->symtab_->allocate_commons(this->options_, this->layout_);
+  this->symtab_->allocate_commons(this->layout_);
 }
 
 // This class is used to sort the common symbol by size.  We put the
@@ -117,12 +117,12 @@ Sort_commons<size>::operator()(const Sym
 // Allocate the common symbols.
 
 void
-Symbol_table::allocate_commons(const General_options& options, Layout* layout)
+Symbol_table::allocate_commons(Layout* layout)
 {
   if (parameters->target().get_size() == 32)
     {
 #if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
-      this->do_allocate_commons<32>(options, layout);
+      this->do_allocate_commons<32>(layout);
 #else
       gold_unreachable();
 #endif
@@ -130,7 +130,7 @@ Symbol_table::allocate_commons(const Gen
   else if (parameters->target().get_size() == 64)
     {
 #if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
-      this->do_allocate_commons<64>(options, layout);
+      this->do_allocate_commons<64>(layout);
 #else
       gold_unreachable();
 #endif
@@ -143,8 +143,19 @@ Symbol_table::allocate_commons(const Gen
 
 template<int size>
 void
-Symbol_table::do_allocate_commons(const General_options&,
-				  Layout* layout)
+Symbol_table::do_allocate_commons(Layout* layout)
+{
+  this->do_allocate_commons_list<size>(layout, false, &this->commons_);
+  this->do_allocate_commons_list<size>(layout, true, &this->tls_commons_);
+}
+
+// Allocate the common symbols in a list.  IS_TLS indicates whether
+// these are TLS common symbols.
+
+template<int size>
+void
+Symbol_table::do_allocate_commons_list(Layout* layout, bool is_tls,
+				       Commons_type* commons)
 {
   typedef typename Sized_symbol<size>::Value_type Value_type;
   typedef typename Sized_symbol<size>::Size_type Size_type;
@@ -154,8 +165,8 @@ Symbol_table::do_allocate_commons(const 
   // forwarder.  First remove all non-common symbols.
   bool any = false;
   uint64_t addralign = 0;
-  for (Commons_type::iterator p = this->commons_.begin();
-       p != this->commons_.end();
+  for (Commons_type::iterator p = commons->begin();
+       p != commons->end();
        ++p)
     {
       Symbol* sym = *p;
@@ -179,22 +190,27 @@ Symbol_table::do_allocate_commons(const 
 
   // Sort the common symbols by size, so that they pack better into
   // memory.
-  std::sort(this->commons_.begin(), this->commons_.end(),
+  std::sort(commons->begin(), commons->end(),
 	    Sort_commons<size>(this));
 
-  // Place them in a newly allocated .bss section.
+  // Place them in a newly allocated BSS section.
 
   Output_data_space *poc = new Output_data_space(addralign);
 
-  layout->add_output_section_data(".bss", elfcpp::SHT_NOBITS,
-				  elfcpp::SHF_WRITE | elfcpp::SHF_ALLOC,
-				  poc);
+  const char* name = ".bss";
+  elfcpp::Elf_Xword flags = elfcpp::SHF_WRITE | elfcpp::SHF_ALLOC;
+  if (is_tls)
+    {
+      name = ".tbss";
+      flags |= elfcpp::SHF_TLS;
+    }
+  layout->add_output_section_data(name, elfcpp::SHT_NOBITS, flags, poc);
 
   // Allocate them all.
 
   off_t off = 0;
-  for (Commons_type::iterator p = this->commons_.begin();
-       p != this->commons_.end();
+  for (Commons_type::iterator p = commons->begin();
+       p != commons->end();
        ++p)
     {
       Symbol* sym = *p;
@@ -208,7 +224,7 @@ Symbol_table::do_allocate_commons(const 
 
   poc->set_current_data_size(off);
 
-  this->commons_.clear();
+  commons->clear();
 }
 
 } // End namespace gold.
Index: common.h
===================================================================
RCS file: /cvs/src/src/gold/common.h,v
retrieving revision 1.5
diff -u -p -r1.5 common.h
--- common.h	13 Mar 2008 21:04:21 -0000	1.5
+++ common.h	17 Apr 2008 07:09:06 -0000
@@ -28,7 +28,6 @@
 namespace gold
 {
 
-class General_options;
 class Symbol_table;
 
 // This task is used to allocate the common symbols.
@@ -36,11 +35,10 @@ class Symbol_table;
 class Allocate_commons_task : public Task
 {
  public:
-  Allocate_commons_task(const General_options& options, Symbol_table* symtab,
-			Layout* layout, Task_token* symtab_lock,
-			Task_token* blocker)
-    : options_(options), symtab_(symtab), layout_(layout),
-      symtab_lock_(symtab_lock), blocker_(blocker)
+  Allocate_commons_task(Symbol_table* symtab, Layout* layout,
+			Task_token* symtab_lock, Task_token* blocker)
+    : symtab_(symtab), layout_(layout), symtab_lock_(symtab_lock),
+      blocker_(blocker)
   { }
 
   // The standard Task methods.
@@ -59,7 +57,6 @@ class Allocate_commons_task : public Tas
   { return "Allocate_commons_task"; }
 
  private:
-  const General_options& options_;
   Symbol_table* symtab_;
   Layout* layout_;
   Task_token* symtab_lock_;
Index: configure.ac
===================================================================
RCS file: /cvs/src/src/gold/configure.ac,v
retrieving revision 1.31
diff -u -p -r1.31 configure.ac
--- configure.ac	17 Apr 2008 05:52:32 -0000	1.31
+++ configure.ac	17 Apr 2008 07:09:07 -0000
@@ -221,6 +221,22 @@ error
 
 AM_CONDITIONAL(STATIC_TLS, test "$gold_cv_lib_glibc24" = "yes")
 
+dnl Test for #pragma omp threadprivate
+AC_CACHE_CHECK([for omp support], [gold_cv_c_threadprivate],
+[save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -fopenmp"
+AC_COMPILE_IFELSE([
+#include <omp.h>
+int i;
+#pragma omp threadprivate (i)
+], [gold_cv_c_threadprivate=yes], [gold_cv_c_threadprivate=no])
+CFLAGS="$save_CFLAGS"])
+if test "$gold_cv_c_threadprivate" = "yes"; then
+  AC_DEFINE(HAVE_OMP_SUPPORT, 1,
+	    [Define if compiler supports #pragma omp threadprivate])
+fi
+AM_CONDITIONAL(OMP_SUPPORT, test "$gold_cv_c_threadprivate" = "yes")
+
 dnl Test for the -ftls-dialect=gnu2 option.
 save_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -mtls-dialect=gnu2"
Index: gold.cc
===================================================================
RCS file: /cvs/src/src/gold/gold.cc,v
retrieving revision 1.52
diff -u -p -r1.52 gold.cc
--- gold.cc	15 Apr 2008 04:06:40 -0000	1.52
+++ gold.cc	17 Apr 2008 07:09:07 -0000
@@ -260,8 +260,8 @@ queue_middle_tasks(const General_options
   if (parameters->options().define_common())
     {
       blocker->add_blocker();
-      workqueue->queue(new Allocate_commons_task(options, symtab, layout,
-						 symtab_lock, blocker));
+      workqueue->queue(new Allocate_commons_task(symtab, layout, symtab_lock,
+						 blocker));
     }
 
   // When all those tasks are complete, we can start laying out the
Index: symtab.cc
===================================================================
RCS file: /cvs/src/src/gold/symtab.cc,v
retrieving revision 1.91
diff -u -p -r1.91 symtab.cc
--- symtab.cc	17 Apr 2008 02:00:54 -0000	1.91
+++ symtab.cc	17 Apr 2008 07:09:07 -0000
@@ -360,7 +360,7 @@ Symbol::set_output_section(Output_sectio
 Symbol_table::Symbol_table(unsigned int count,
                            const Version_script_info& version_script)
   : saw_undefined_(0), offset_(0), table_(count), namepool_(),
-    forwarders_(), commons_(), forced_locals_(), warnings_(),
+    forwarders_(), commons_(), tls_commons_(), forced_locals_(), warnings_(),
     version_script_(version_script)
 {
   namepool_.reserve(count);
@@ -715,7 +715,12 @@ Symbol_table::add_from_object(Object* ob
   // Keep track of common symbols, to speed up common symbol
   // allocation.
   if (!was_common && ret->is_common())
-    this->commons_.push_back(ret);
+    {
+      if (ret->type() != elfcpp::STT_TLS)
+	this->commons_.push_back(ret);
+      else
+	this->tls_commons_.push_back(ret);
+    }
 
   if (def)
     ret->set_is_default();
@@ -1830,7 +1835,15 @@ Symbol_table::sized_finalize_symbol(Symb
     case Symbol::IN_OUTPUT_DATA:
       {
 	Output_data* od = sym->output_data();
-	value = sym->value() + od->address();
+	value = sym->value();
+	if (sym->type() != elfcpp::STT_TLS)
+	  value += od->address();
+	else
+	  {
+	    Output_section* os = od->output_section();
+	    gold_assert(os != NULL);
+	    value += os->tls_offset() + (od->address() - os->address());
+	  }
 	if (sym->offset_is_from_end())
 	  value += od->data_size();
       }
Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gold/symtab.h,v
retrieving revision 1.73
diff -u -p -r1.73 symtab.h
--- symtab.h	17 Apr 2008 00:14:36 -0000	1.73
+++ symtab.h	17 Apr 2008 07:09:07 -0000
@@ -1104,7 +1104,7 @@ class Symbol_table
 
   // Allocate the common symbols
   void
-  allocate_commons(const General_options&, Layout*);
+  allocate_commons(Layout*);
 
   // Add a warning for symbol NAME in object OBJ.  WARNING is the text
   // of the warning.
@@ -1180,6 +1180,9 @@ class Symbol_table
   Symbol_table(const Symbol_table&);
   Symbol_table& operator=(const Symbol_table&);
 
+  // The type of the list of common symbols.
+  typedef std::vector<Symbol*> Commons_type;
+
   // Make FROM a forwarder symbol to TO.
   void
   make_forwarder(Symbol* from, Symbol* to);
@@ -1282,7 +1285,12 @@ class Symbol_table
   // Allocate the common symbols, sized version.
   template<int size>
   void
-  do_allocate_commons(const General_options&, Layout*);
+  do_allocate_commons(Layout*);
+
+  // Allocate the common symbols from one list.
+  template<int size>
+  void
+  do_allocate_commons_list(Layout*, bool is_tls, Commons_type*);
 
   // Implement detect_odr_violations.
   template<int size, bool big_endian>
@@ -1347,9 +1355,6 @@ class Symbol_table
   typedef Unordered_map<Symbol_table_key, Symbol*, Symbol_table_hash,
 			Symbol_table_eq> Symbol_table_type;
 
-  // The type of the list of common symbols.
-  typedef std::vector<Symbol*> Commons_type;
-
   // The type of the list of symbols which have been forced local.
   typedef std::vector<Symbol*> Forced_locals;
 
@@ -1416,6 +1421,9 @@ class Symbol_table
   // symbol is no longer a common symbol.  It may also have become a
   // forwarder.
   Commons_type commons_;
+  // This is like the commons_ field, except that it holds TLS common
+  // symbols.
+  Commons_type tls_commons_;
   // A list of symbols which have been forced to be local.  We don't
   // expect there to be very many of them, so we keep a list of them
   // rather than walking the whole table to find them.
Index: testsuite/Makefile.am
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.am,v
retrieving revision 1.63
diff -u -p -r1.63 Makefile.am
--- testsuite/Makefile.am	17 Apr 2008 00:14:36 -0000	1.63
+++ testsuite/Makefile.am	17 Apr 2008 07:09:07 -0000
@@ -13,7 +13,7 @@ AM_CXXFLAGS = $(WARN_CXXFLAGS) $(LFS_CFL
 
 INCLUDES = \
 	-I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../../include \
-	-I$(srcdir)/../../elfcpp \
+	-I$(srcdir)/../../elfcpp -I.. \
 	-DLOCALEDIR="\"$(datadir)/locale\"" \
 	@INCINTL@
 
@@ -26,6 +26,10 @@ if THREADS
 THREADSLIB = -lpthread
 endif
 
+if OMP_SUPPORT
+TLS_TEST_C_CFLAGS = -fopenmp
+endif
+
 # 'make clean' is good about deleting some intermediate files (such as
 # .o's), but not all of them (such as .so's and .err files).  We
 # improve on that here.  automake-1.9 info docs say "mostlyclean" is
@@ -433,8 +437,10 @@ tls_test_pic.o: tls_test.cc
 	$(CXXCOMPILE) -c -fpic -o $@ $<
 tls_test_file2_pic.o: tls_test_file2.cc
 	$(CXXCOMPILE) -c -fpic -o $@ $<
-tls_test_shared.so: tls_test_pic.o tls_test_file2_pic.o gcctestdir/ld
-	$(CXXLINK) -Bgcctestdir/ -shared tls_test_pic.o tls_test_file2_pic.o
+tls_test_c_pic.o: tls_test_c.c
+	$(COMPILE) -c -fpic $(TLS_TEST_C_CFLAGS) -o $@ $<
+tls_test_shared.so: tls_test_pic.o tls_test_file2_pic.o tls_test_c_pic.o gcctestdir/ld
+	$(CXXLINK) -Bgcctestdir/ -shared tls_test_pic.o tls_test_file2_pic.o tls_test_c_pic.o
 tls_test_shared2.so: tls_test_file2_pic.o gcctestdir/ld
 	$(CXXLINK) -Bgcctestdir/ -shared tls_test_file2_pic.o
 
@@ -442,18 +448,24 @@ tls_test_pic_ie.o: tls_test.cc
 	$(CXXCOMPILE) -c -fpic -ftls-model=initial-exec -o $@ $<
 tls_test_file2_pic_ie.o: tls_test_file2.cc
 	$(CXXCOMPILE) -c -fpic -ftls-model=initial-exec -o $@ $<
-tls_test_ie_shared.so: tls_test_pic_ie.o tls_test_file2_pic_ie.o gcctestdir/ld
-	$(CXXLINK) -Bgcctestdir/ -shared tls_test_pic_ie.o tls_test_file2_pic_ie.o
+tls_test_c_pic_ie.o: tls_test_c.c
+	$(COMPILE) -c -fpic -ftls-model=initial-exec $(TLS_TEST_C_CFLAGS) -o $@ $<
+tls_test_ie_shared.so: tls_test_pic_ie.o tls_test_file2_pic_ie.o tls_test_c_pic_ie.o gcctestdir/ld
+	$(CXXLINK) -Bgcctestdir/ -shared tls_test_pic_ie.o tls_test_file2_pic_ie.o tls_test_c_pic_ie.o
 
 tls_test_SOURCES = tls_test.cc tls_test_file2.cc tls_test_main.cc tls_test.h
-tls_test_DEPENDENCIES = gcctestdir/ld
+tls_test_DEPENDENCIES = gcctestdir/ld tls_test_c.o
 tls_test_LDFLAGS = -Bgcctestdir/
-tls_test_LDADD = -lpthread
+tls_test_LDADD = tls_test_c.o -lpthread
+tls_test_c.o: tls_test_c.c
+	$(COMPILE) -c $(TLS_TEST_C_CFLAGS) -o $@ $<
 
 tls_pic_test_SOURCES = tls_test_main.cc
-tls_pic_test_DEPENDENCIES = gcctestdir/ld tls_test_pic.o tls_test_file2_pic.o
+tls_pic_test_DEPENDENCIES = gcctestdir/ld tls_test_pic.o tls_test_file2_pic.o \
+	tls_test_c_pic.o
 tls_pic_test_LDFLAGS = -Bgcctestdir/
-tls_pic_test_LDADD = tls_test_pic.o tls_test_file2_pic.o -lpthread
+tls_pic_test_LDADD = tls_test_pic.o tls_test_file2_pic.o tls_test_c_pic.o \
+	-lpthread
 
 tls_shared_test_SOURCES = tls_test_main.cc
 tls_shared_test_DEPENDENCIES = gcctestdir/ld tls_test_shared.so
@@ -466,9 +478,11 @@ tls_shared_ie_test_LDFLAGS = -Bgcctestdi
 tls_shared_ie_test_LDADD = tls_test_ie_shared.so -lpthread
 
 tls_shared_gd_to_ie_test_SOURCES = tls_test_main.cc
-tls_shared_gd_to_ie_test_DEPENDENCIES = gcctestdir/ld tls_test_pic.o tls_test_shared2.so
+tls_shared_gd_to_ie_test_DEPENDENCIES = gcctestdir/ld tls_test_pic.o \
+	tls_test_c_pic.o tls_test_shared2.so
 tls_shared_gd_to_ie_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,.
-tls_shared_gd_to_ie_test_LDADD = tls_test_pic.o tls_test_shared2.so -lpthread
+tls_shared_gd_to_ie_test_LDADD = tls_test_pic.o tls_test_c_pic.o \
+	tls_test_shared2.so -lpthread
 
 if TLS_GNU2_DIALECT
 
@@ -478,20 +492,24 @@ tls_test_gnu2.o: tls_test.cc
 	$(CXXCOMPILE) -c -fpic -mtls-dialect=gnu2 -o $@ $<
 tls_test_file2_gnu2.o: tls_test_file2.cc
 	$(CXXCOMPILE) -c -fpic -mtls-dialect=gnu2 -o $@ $<
+tls_test_c_gnu2.o: tls_test_c.c
+	$(COMPILE) -c -fpic -mtls-dialect=gnu2 $(TLS_TEST_C_CFLAGS) -o $@ $<
 tls_test_gnu2_shared2.so: tls_test_file2_gnu2.o gcctestdir/ld
 	$(CXXLINK) -Bgcctestdir/ -shared tls_test_file2_gnu2.o
 
 tls_shared_gnu2_gd_to_ie_test_SOURCES = tls_test_main.cc
-tls_shared_gnu2_gd_to_ie_test_DEPENDENCIES = gcctestdir/ld tls_test_gnu2.o tls_test_gnu2_shared2.so
+tls_shared_gnu2_gd_to_ie_test_DEPENDENCIES = gcctestdir/ld tls_test_gnu2.o \
+	tls_test_c_gnu2.o tls_test_gnu2_shared2.so
 tls_shared_gnu2_gd_to_ie_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,.
-tls_shared_gnu2_gd_to_ie_test_LDADD = tls_test_gnu2.o tls_test_gnu2_shared2.so -lpthread
+tls_shared_gnu2_gd_to_ie_test_LDADD = tls_test_gnu2.o tls_test_c_gnu2.o \
+	tls_test_gnu2_shared2.so -lpthread
 
 if TLS_DESCRIPTORS
 
 check_PROGRAMS += tls_shared_gnu2_test
 
-tls_test_gnu2_shared.so: tls_test_gnu2.o tls_test_file2_gnu2.o gcctestdir/ld
-	$(CXXLINK) -Bgcctestdir/ -shared tls_test_gnu2.o tls_test_file2_gnu2.o
+tls_test_gnu2_shared.so: tls_test_gnu2.o tls_test_file2_gnu2.o tls_test_c_gnu2.o gcctestdir/ld
+	$(CXXLINK) -Bgcctestdir/ -shared tls_test_gnu2.o tls_test_file2_gnu2.o tls_test_c_gnu2.o
 
 tls_shared_gnu2_test_SOURCES = tls_test_main.cc
 tls_shared_gnu2_test_DEPENDENCIES = gcctestdir/ld tls_test_gnu2_shared.so
@@ -519,8 +537,8 @@ endif
 
 if FN_PTRS_IN_SO_WITHOUT_PIC
 check_PROGRAMS += tls_shared_nonpic_test
-tls_test_shared_nonpic.so: tls_test.o tls_test_file2.o gcctestdir/ld
-	$(CXXLINK) -Bgcctestdir/ -shared tls_test.o tls_test_file2.o
+tls_test_shared_nonpic.so: tls_test.o tls_test_file2.o tls_test_c.o gcctestdir/ld
+	$(CXXLINK) -Bgcctestdir/ -shared tls_test.o tls_test_file2.o tls_test_c.o
 
 tls_shared_nonpic_test_SOURCES = tls_test_main.cc
 tls_shared_nonpic_test_DEPENDENCIES = gcctestdir/ld tls_test_shared_nonpic.so
Index: testsuite/tls_test.cc
===================================================================
RCS file: /cvs/src/src/gold/testsuite/tls_test.cc,v
retrieving revision 1.5
diff -u -p -r1.5 tls_test.cc
--- testsuite/tls_test.cc	19 Mar 2008 21:41:38 -0000	1.5
+++ testsuite/tls_test.cc	17 Apr 2008 07:09:08 -0000
@@ -45,6 +45,7 @@
 
 
 #include <cstdio>
+#include "config.h"
 #include "tls_test.h"
 
 #define CHECK_EQ_OR_RETURN(var, expected)				\
@@ -197,5 +198,7 @@ t_last()
   CHECK_EQ_OR_RETURN(o1, -10);
   CHECK_EQ_OR_RETURN(o2, -20);
   CHECK_EQ_OR_RETURN(o3, -30);
+  int check = t11_last();
+  CHECK_EQ_OR_RETURN(check, 1);
   return true;
 }
Index: testsuite/tls_test.h
===================================================================
RCS file: /cvs/src/src/gold/testsuite/tls_test.h,v
retrieving revision 1.4
diff -u -p -r1.4 tls_test.h
--- testsuite/tls_test.h	13 Mar 2008 21:04:21 -0000	1.4
+++ testsuite/tls_test.h	17 Apr 2008 07:09:08 -0000
@@ -43,6 +43,9 @@ extern int* f10a();
 extern void f10b(int*);
 extern bool t10();
 
+extern "C" int t11();
+extern "C" int t11_last();
+
 extern bool t_last();
 
 // These variables are defined in tls_test_file2.cc
Index: testsuite/tls_test_c.c
===================================================================
RCS file: testsuite/tls_test_c.c
diff -N testsuite/tls_test_c.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/tls_test_c.c	17 Apr 2008 07:09:08 -0000
@@ -0,0 +1,62 @@
+/* tls_test_c.c -- test TLS common symbol
+
+   Copyright 2008 Free Software Foundation, Inc.
+   Written by Ian Lance Taylor <iant@google.com>
+
+   This file is part of gold.
+
+   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.  */
+
+/* The only way I know to get gcc to generate a TLS common symbol is
+   to use a C file and an OpenMP directive.  */
+
+#include <stdio.h>
+#include "config.h"
+
+#define CHECK_EQ_OR_RETURN(var, expected)				\
+  do									\
+    {									\
+      if ((var) != (expected))						\
+	{								\
+	  printf(#var ": expected %d, found %d\n", expected, var);	\
+	  return 0;							\
+	}								\
+    }									\
+  while (0)
+
+#ifdef HAVE_OMP_SUPPORT
+int v7;
+#pragma omp threadprivate (v7)
+#endif
+
+int
+t11()
+{
+#ifdef HAVE_OMP_SUPPORT
+  CHECK_EQ_OR_RETURN(v7, 0);
+  v7 = 70;
+#endif
+  return 1;
+}
+
+int
+t11_last()
+{
+#ifdef HAVE_OMP_SUPPORT
+  CHECK_EQ_OR_RETURN(v7, 70);
+#endif
+  return 1;
+}
Index: testsuite/tls_test_main.cc
===================================================================
RCS file: /cvs/src/src/gold/testsuite/tls_test_main.cc,v
retrieving revision 1.5
diff -u -p -r1.5 tls_test_main.cc
--- testsuite/tls_test_main.cc	13 Mar 2008 21:04:21 -0000	1.5
+++ testsuite/tls_test_main.cc	17 Apr 2008 07:09:08 -0000
@@ -99,6 +99,7 @@ thread_routine(void* arg)
   check("t9", t9());
   f10b(f10a());
   check("t10", t10());
+  check("t11", t11() != 0);
   check("t_last", t_last());
 
   // Unlock the second mutex.

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