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]

gold patch committed: Better support for TLS and RELRO with scripts


This patch improves the support for TLS sections and RELRO sections
when using a linker script.  This probably does not fix all problems,
but it should improve matters.  This includes a small test case for
RELRO; before this patch, the test case would crash.

These problems were found linking glibc with a GNU ld linker script.

Ian


2008-08-13  Ian Lance Taylor  <iant@google.com>

	* layout.cc (Layout::attach_allocated_section_to_segment): Don't
	set tls_segment_ or relro_segment_.
	(Layout::make_output_segment): Set tls_segment_ and relro_segment_
	when appropriate.
	* output.h (Output_section::clear_is_relro): New function.
	* output.cc (Output_segment::add_output_section): Handle SHF_TLS
	sections specially even when output_data_ is empty.
	(Output_segment::maximum_alignment): When first section is relro,
	only force alignment for PT_LOAD segments.
	* script.cc (script_data_segment_align): New function.
	(script_data_segment_relro_end): New function.
	* script-c.h (script_data_segment_align): Declare.
	(script_data_segment_relro_end): Declare.
	* script-sections.h (class Script_sections): Declare
	data_segment_align and data_segment_relro_end.  Add fields
	segment_align_index_ and saw_relro_end_.
	* script-sections.cc (class Sections_element): Add set_is_relro
	virtual function.  Add new bool* parameter to place_orphan_here.
	Add get_output_section virtual function.
	(class Output_section_definition): Add set_is_relro.  Add new
	bool* parameter to place_orphan_here.  Add get_output_section.
	Add is_relro_ field.
	(Output_section_definition::Output_section_definition): Initialize
	evaluated_address_, evaluated_load_address, evaluated_addralign_,
	and is_relro_ fields.
	(Output_section_definition::place_orphan_here): Add is_relro
	parameter.
	(Output_section_definition::set_section_addresses): Set relro for
	output section.
	(Output_section_definition::alternate_constraint): Likewise.
	(class Orphan_output_section): Add new bool* parameter to
	place_orphan_here.  Add get_output_section.
	(Orphan_output_section::place_orphan_here): Add is_relro
	parameter.
	(Script_sections::Script_sections): Initialize
	data_segment_align_index_ and saw_relro_end_.
	(Script_sections::data_segment_align): New function.
	(Script_sections::data_segment_relro_end): New function.
	(Script_sections::place_orphan): Set or clear is_relro.
	(Script_sections::set_section_addresses): Force alignment of first
	TLS section.
	* yyscript.y (exp): Call script_data_segment_align and
	script_data_segment_relro_end.
	* testsuite/relro_script_test.t: New file.
	* testsuite/relro_test.cc (using_script): Declare.
	(t1, t2): Test using_script.
	* testsuite/Makefile.am (check_PROGRAMS): Add relro_script_test.
	(relro_script_test_SOURCES): Define.
	(relro_script_test_DEPENDENCIES): Define.
	(relro_script_test_LDFLAGS): Define.
	(relro_script_test_LDADD): Define.
	(relro_script_test.so): New target.
	* testsuite/Makefile.in: Rebuild.


Index: layout.cc
===================================================================
RCS file: /cvs/src/src/gold/layout.cc,v
retrieving revision 1.111
diff -p -u -r1.111 layout.cc
--- layout.cc	25 Jul 2008 04:25:49 -0000	1.111
+++ layout.cc	13 Aug 2008 07:24:25 -0000
@@ -921,8 +921,7 @@ Layout::attach_allocated_section_to_segm
   if ((flags & elfcpp::SHF_TLS) != 0)
     {
       if (this->tls_segment_ == NULL)
-        this->tls_segment_ = this->make_output_segment(elfcpp::PT_TLS,
-                                                       seg_flags);
+	this->make_output_segment(elfcpp::PT_TLS, seg_flags);
       this->tls_segment_->add_output_section(os, seg_flags);
     }
 
@@ -932,8 +931,7 @@ Layout::attach_allocated_section_to_segm
     {
       gold_assert(seg_flags == (elfcpp::PF_R | elfcpp::PF_W));
       if (this->relro_segment_ == NULL)
-	this->relro_segment_ = this->make_output_segment(elfcpp::PT_GNU_RELRO,
-							 seg_flags);
+	this->make_output_segment(elfcpp::PT_GNU_RELRO, seg_flags);
       this->relro_segment_->add_output_section(os, seg_flags);
     }
 }
@@ -2999,6 +2997,12 @@ Layout::make_output_segment(elfcpp::Elf_
   gold_assert(!parameters->options().relocatable());
   Output_segment* oseg = new Output_segment(type, flags);
   this->segment_list_.push_back(oseg);
+
+  if (type == elfcpp::PT_TLS)
+    this->tls_segment_ = oseg;
+  else if (type == elfcpp::PT_GNU_RELRO)
+    this->relro_segment_ = oseg;
+
   return oseg;
 }
 
Index: output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.82
diff -p -u -r1.82 output.cc
--- output.cc	25 Jul 2008 04:25:49 -0000	1.82
+++ output.cc	13 Aug 2008 07:24:25 -0000
@@ -2651,8 +2651,7 @@ Output_segment::add_output_section(Outpu
   // and the PT_TLS segment -- we do this grouping only for the
   // PT_LOAD segment.
   if (this->type_ != elfcpp::PT_TLS
-      && (os->flags() & elfcpp::SHF_TLS) != 0
-      && !this->output_data_.empty())
+      && (os->flags() & elfcpp::SHF_TLS) != 0)
     {
       pdl = &this->output_data_;
       bool nobits = os->type() == elfcpp::SHT_NOBITS;
@@ -2777,7 +2776,9 @@ Output_segment::maximum_alignment()
       // segment is a relro section, then the segment must be aligned
       // to at least the common page size.  This ensures that the
       // PT_GNU_RELRO segment will start at a page boundary.
-      if (parameters->options().relro() && this->is_first_section_relro())
+      if (this->type_ == elfcpp::PT_LOAD
+	  && parameters->options().relro()
+	  && this->is_first_section_relro())
 	{
 	  addralign = parameters->target().common_pagesize();
 	  if (addralign > this->max_align_)
Index: output.h
===================================================================
RCS file: /cvs/src/src/gold/output.h,v
retrieving revision 1.74
diff -p -u -r1.74 output.h
--- output.h	10 Jul 2008 23:01:19 -0000	1.74
+++ output.h	13 Aug 2008 07:24:25 -0000
@@ -2177,6 +2177,11 @@ class Output_section : public Output_dat
   set_is_relro()
   { this->is_relro_ = true; }
 
+  // Record that this section does not hold relro data.
+  void
+  clear_is_relro()
+  { this->is_relro_ = false; }
+
   // True if this section holds relro local data--relro data for which
   // the dynamic relocations are all RELATIVE relocations.
   bool
Index: script-c.h
===================================================================
RCS file: /cvs/src/src/gold/script-c.h,v
retrieving revision 1.11
diff -p -u -r1.11 script-c.h
--- script-c.h	28 Feb 2008 20:35:39 -0000	1.11
+++ script-c.h	13 Aug 2008 07:24:25 -0000
@@ -364,6 +364,14 @@ script_add_phdr(void* closure, const cha
 extern unsigned int
 script_phdr_string_to_type(void* closure, const char*, size_t);
 
+/* Handle DATA_SEGMENT_ALIGN and DATA_SEGMENT_RELRO_END.  */
+
+extern void
+script_data_segment_align(void* closure);
+
+extern void
+script_data_segment_relro_end(void* closure);
+
 /* Called by the bison parser for expressions.  */
 
 extern Expression_ptr
Index: script-sections.cc
===================================================================
RCS file: /cvs/src/src/gold/script-sections.cc,v
retrieving revision 1.16
diff -p -u -r1.16 script-sections.cc
--- script-sections.cc	22 Jul 2008 23:01:20 -0000	1.16
+++ script-sections.cc	13 Aug 2008 07:24:26 -0000
@@ -54,6 +54,11 @@ class Sections_element
   virtual ~Sections_element()
   { }
 
+  // Record that an output section is relro.
+  virtual void
+  set_is_relro()
+  { }
+
   // Create any required output sections.  The only real
   // implementation is in Output_section_definition.
   virtual void
@@ -80,7 +85,7 @@ class Sections_element
   // Return whether to place an orphan output section after this
   // element.
   virtual bool
-  place_orphan_here(const Output_section *, bool*) const
+  place_orphan_here(const Output_section *, bool*, bool*) const
   { return false; }
 
   // Set section addresses.  This includes applying assignments if the
@@ -126,6 +131,11 @@ class Sections_element
                           uint64_t*) const
   { return false; }
 
+  // Return the associated Output_section if there is one.
+  virtual Output_section*
+  get_output_section() const
+  { return NULL; }
+
   // Print the element for debugging purposes.
   virtual void
   print(FILE* f) const = 0;
@@ -1231,6 +1241,11 @@ class Output_section_definition : public
   void
   add_input_section(const Input_section_spec* spec, bool keep);
 
+  // Record that the output section is relro.
+  void
+  set_is_relro()
+  { this->is_relro_ = true; }
+
   // Create any required output sections.
   void
   create_sections(Layout*);
@@ -1251,7 +1266,7 @@ class Output_section_definition : public
 
   // Return whether to place an orphan section after this one.
   bool
-  place_orphan_here(const Output_section *os, bool* exact) const;
+  place_orphan_here(const Output_section *os, bool* exact, bool*) const;
 
   // Set the section address.
   void
@@ -1284,6 +1299,11 @@ class Output_section_definition : public
   get_output_section_info(const char*, uint64_t*, uint64_t*, uint64_t*,
                           uint64_t*) const;
 
+  // Return the associated Output_section if there is one.
+  Output_section*
+  get_output_section() const
+  { return this->output_section_; }
+
   // Print the contents to the FILE.  This is for debugging.
   void
   print(FILE*) const;
@@ -1319,6 +1339,8 @@ class Output_section_definition : public
   uint64_t evaluated_load_address_;
   // The alignment after it has been evaluated.
   uint64_t evaluated_addralign_;
+  // The output section is relro.
+  bool is_relro_;
 };
 
 // Constructor.
@@ -1336,7 +1358,11 @@ Output_section_definition::Output_sectio
     fill_(NULL),
     phdrs_(NULL),
     elements_(),
-    output_section_(NULL)
+    output_section_(NULL),
+    evaluated_address_(0),
+    evaluated_load_address_(0),
+    evaluated_addralign_(0),
+    is_relro_(false)
 {
 }
 
@@ -1517,8 +1543,11 @@ Output_section_definition::output_sectio
 
 bool
 Output_section_definition::place_orphan_here(const Output_section *os,
-					     bool* exact) const
+					     bool* exact,
+					     bool* is_relro) const
 {
+  *is_relro = this->is_relro_;
+
   // Check for the simple case first.
   if (this->output_section_ != NULL
       && this->output_section_->type() == os->type()
@@ -1754,6 +1783,14 @@ Output_section_definition::set_section_a
   else
     *load_address = (this->output_section_->load_address()
                      + (*dot_value - start_address));
+
+  if (this->output_section_ != NULL)
+    {
+      if (this->is_relro_)
+	this->output_section_->set_is_relro();
+      else
+	this->output_section_->clear_is_relro();
+    }
 }
 
 // Check a constraint (ONLY_IF_RO, etc.) on an output section.  If
@@ -1835,6 +1872,11 @@ Output_section_definition::alternate_con
   this->output_section_ = posd->output_section_;
   posd->output_section_ = NULL;
 
+  if (this->is_relro_)
+    this->output_section_->set_is_relro();
+  else
+    this->output_section_->clear_is_relro();
+
   return true;
 }
 
@@ -1968,7 +2010,7 @@ class Orphan_output_section : public Sec
 
   // Return whether to place an orphan section after this one.
   bool
-  place_orphan_here(const Output_section *os, bool* exact) const;
+  place_orphan_here(const Output_section *os, bool* exact, bool*) const;
 
   // Set section addresses.
   void
@@ -1979,6 +2021,11 @@ class Orphan_output_section : public Sec
   Output_section*
   allocate_to_segment(String_list**, bool*);
 
+  // Return the associated Output_section.
+  Output_section*
+  get_output_section() const
+  { return this->os_; }
+
   // Print for debugging.
   void
   print(FILE* f) const
@@ -1995,12 +2042,14 @@ class Orphan_output_section : public Sec
 
 bool
 Orphan_output_section::place_orphan_here(const Output_section* os,
-					 bool* exact) const
+					 bool* exact,
+					 bool* is_relro) const
 {
   if (this->os_->type() == os->type()
       && this->os_->flags() == os->flags())
     {
       *exact = true;
+      *is_relro = this->os_->is_relro();
       return true;
     }
   return false;
@@ -2206,7 +2255,9 @@ Script_sections::Script_sections()
     in_sections_clause_(false),
     sections_elements_(NULL),
     output_section_(NULL),
-    phdrs_elements_(NULL)
+    phdrs_elements_(NULL),
+    data_segment_align_index_(-1U),
+    saw_relro_end_(false)
 {
 }
 
@@ -2334,6 +2385,39 @@ Script_sections::add_input_section(const
   this->output_section_->add_input_section(spec, keep);
 }
 
+// This is called when we see DATA_SEGMENT_ALIGN.  It means that any
+// subsequent output sections may be relro.
+
+void
+Script_sections::data_segment_align()
+{
+  if (this->data_segment_align_index_ != -1U)
+    gold_error(_("DATA_SEGMENT_ALIGN may only appear once in a linker script"));
+  this->data_segment_align_index_ = this->sections_elements_->size();
+}
+
+// This is called when we see DATA_SEGMENT_RELRO_END.  It means that
+// any output sections seen since DATA_SEGMENT_ALIGN are relro.
+
+void
+Script_sections::data_segment_relro_end()
+{
+  if (this->saw_relro_end_)
+    gold_error(_("DATA_SEGMENT_RELRO_END may only appear once "
+		 "in a linker script"));
+  this->saw_relro_end_ = true;
+
+  if (this->data_segment_align_index_ == -1U)
+    gold_error(_("DATA_SEGMENT_RELRO_END must follow DATA_SEGMENT_ALIGN"));
+  else
+    {
+      for (size_t i = this->data_segment_align_index_;
+	   i < this->sections_elements_->size();
+	   ++i)
+	(*this->sections_elements_)[i]->set_is_relro();
+    }
+}
+
 // Create any required sections.
 
 void
@@ -2418,15 +2502,18 @@ Script_sections::place_orphan(Output_sec
 {
   // Look for an output section definition which matches the output
   // section.  Put a marker after that section.
+  bool is_relro = false;
   Sections_elements::iterator place = this->sections_elements_->end();
   for (Sections_elements::iterator p = this->sections_elements_->begin();
        p != this->sections_elements_->end();
        ++p)
     {
       bool exact = false;
-      if ((*p)->place_orphan_here(os, &exact))
+      bool is_relro_here;
+      if ((*p)->place_orphan_here(os, &exact, &is_relro_here))
 	{
 	  place = p;
+	  is_relro = is_relro_here;
 	  if (exact)
 	    break;
 	}
@@ -2437,6 +2524,11 @@ Script_sections::place_orphan(Output_sec
     ++place;
 
   this->sections_elements_->insert(place, new Orphan_output_section(os));
+
+  if (is_relro)
+    os->set_is_relro();
+  else
+    os->clear_is_relro();
 }
 
 // Set the addresses of all the output sections.  Walk through all the
@@ -2479,6 +2571,26 @@ Script_sections::set_section_addresses(S
 	}
     }
 
+  // Force the alignment of the first TLS section to be the maximum
+  // alignment of all TLS sections.
+  Output_section* first_tls = NULL;
+  uint64_t tls_align = 0;
+  for (Sections_elements::const_iterator p = this->sections_elements_->begin();
+       p != this->sections_elements_->end();
+       ++p)
+    {
+      Output_section *os = (*p)->get_output_section();
+      if (os != NULL && (os->flags() & elfcpp::SHF_TLS) != 0)
+	{
+	  if (first_tls == NULL)
+	    first_tls = os;
+	  if (os->addralign() > tls_align)
+	    tls_align = os->addralign();
+	}
+    }
+  if (first_tls != NULL)
+    first_tls->set_addralign(tls_align);
+
   // For a relocatable link, we implicitly set dot to zero.
   uint64_t dot_value = 0;
   uint64_t load_address = 0;
Index: script-sections.h
===================================================================
RCS file: /cvs/src/src/gold/script-sections.h,v
retrieving revision 1.6
diff -p -u -r1.6 script-sections.h
--- script-sections.h	29 Feb 2008 00:04:06 -0000	1.6
+++ script-sections.h	13 Aug 2008 07:24:26 -0000
@@ -106,6 +106,14 @@ class Script_sections
   void
   add_input_section(const Input_section_spec* spec, bool keep);
 
+  // Saw DATA_SEGMENT_ALIGN.
+  void
+  data_segment_align();
+
+  // Saw DATA_SEGMENT_RELRO_END.
+  void
+  data_segment_relro_end();
+
   // Create any required sections.
   void
   create_sections(Layout*);
@@ -224,6 +232,11 @@ class Script_sections
   Output_section_definition* output_section_;
   // The list of program headers in the PHDRS clause.
   Phdrs_elements* phdrs_elements_;
+  // The index of the next Sections_element when we see
+  // DATA_SEGMENT_ALIGN.
+  size_t data_segment_align_index_;
+  // Whether we have seen DATA_SEGMENT_RELRO_END.
+  bool saw_relro_end_;
 };
 
 } // End namespace gold.
Index: script.cc
===================================================================
RCS file: /cvs/src/src/gold/script.cc,v
retrieving revision 1.46
diff -p -u -r1.46 script.cc
--- script.cc	29 Jul 2008 22:58:03 -0000	1.46
+++ script.cc	13 Aug 2008 07:24:26 -0000
@@ -2400,6 +2400,34 @@ script_add_input_section(void* closurev,
   closure->script_options()->script_sections()->add_input_section(spec, keep);
 }
 
+// When we see DATA_SEGMENT_ALIGN we record that following output
+// sections may be relro.
+
+extern "C" void
+script_data_segment_align(void* closurev)
+{
+  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
+  if (!closure->script_options()->saw_sections_clause())
+    gold_error(_("%s:%d:%d: DATA_SEGMENT_ALIGN not in SECTIONS clause"),
+	       closure->filename(), closure->lineno(), closure->charpos());
+  else
+    closure->script_options()->script_sections()->data_segment_align();
+}
+
+// When we see DATA_SEGMENT_RELRO_END we know that all output sections
+// since DATA_SEGMENT_ALIGN should be relro.
+
+extern "C" void
+script_data_segment_relro_end(void* closurev)
+{
+  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
+  if (!closure->script_options()->saw_sections_clause())
+    gold_error(_("%s:%d:%d: DATA_SEGMENT_ALIGN not in SECTIONS clause"),
+	       closure->filename(), closure->lineno(), closure->charpos());
+  else
+    closure->script_options()->script_sections()->data_segment_relro_end();
+}
+
 // Create a new list of string/sort pairs.
 
 extern "C" String_sort_list_ptr
Index: script.h
===================================================================
RCS file: /cvs/src/src/gold/script.h,v
retrieving revision 1.20
diff -p -u -r1.20 script.h
--- script.h	23 Jul 2008 23:44:02 -0000	1.20
+++ script.h	13 Aug 2008 07:24:26 -0000
@@ -407,7 +407,6 @@ read_commandline_script(const char* file
 bool
 read_version_script(const char* filename, Command_line* cmdline);
 
-
 } // End namespace gold.
 
 #endif // !defined(GOLD_SCRIPT_H)
Index: yyscript.y
===================================================================
RCS file: /cvs/src/src/gold/yyscript.y,v
retrieving revision 1.15
diff -p -u -r1.15 yyscript.y
--- yyscript.y	25 Mar 2008 07:50:21 -0000	1.15
+++ yyscript.y	13 Aug 2008 07:24:26 -0000
@@ -811,9 +811,15 @@ exp:
 	| BLOCK '(' exp ')'
 	    { $$ = script_exp_function_align(script_exp_string(".", 1), $3); }
 	| DATA_SEGMENT_ALIGN '(' exp ',' exp ')'
-	    { $$ = script_exp_function_data_segment_align($3, $5); }
+	    {
+	      script_data_segment_align(closure);
+	      $$ = script_exp_function_data_segment_align($3, $5);
+	    }
 	| DATA_SEGMENT_RELRO_END '(' exp ',' exp ')'
-	    { $$ = script_exp_function_data_segment_relro_end($3, $5); }
+	    {
+	      script_data_segment_relro_end(closure);
+	      $$ = script_exp_function_data_segment_relro_end($3, $5);
+	    }
 	| DATA_SEGMENT_END '(' exp ')'
 	    { $$ = script_exp_function_data_segment_end($3); }
 	| SEGMENT_START '(' string ',' exp ')'
Index: testsuite/Makefile.am
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.am,v
retrieving revision 1.74
diff -p -u -r1.74 Makefile.am
--- testsuite/Makefile.am	4 Aug 2008 22:22:13 -0000	1.74
+++ testsuite/Makefile.am	13 Aug 2008 07:24:26 -0000
@@ -835,6 +835,14 @@ relro_test.so: gcctestdir/ld relro_test_
 relro_test_pic.o: relro_test.cc
 	$(CXXCOMPILE) -c -fpic -o $@ $<
 
+check_PROGRAMS += relro_script_test
+relro_script_test_SOURCES = relro_test_main.cc
+relro_script_test_DEPENDENCIES = gcctestdir/ld relro_script_test.so
+relro_script_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,.
+relro_script_test_LDADD = relro_script_test.so
+relro_script_test.so: gcctestdir/ld relro_script_test.t relro_test_pic.o
+	$(CXXLINK) -Bgcctestdir/ -shared -Wl,-z,relro -T $(srcdir)/relro_script_test.t relro_test_pic.o
+
 check_PROGRAMS += script_test_1
 script_test_1_SOURCES = script_test_1.cc
 script_test_1_DEPENDENCIES = gcctestdir/ld script_test_1.t
Index: testsuite/Makefile.in
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.in,v
retrieving revision 1.79
diff -p -u -r1.79 Makefile.in
--- testsuite/Makefile.in	4 Aug 2008 22:22:13 -0000	1.79
+++ testsuite/Makefile.in	13 Aug 2008 07:24:27 -0000
@@ -229,9 +229,10 @@ check_PROGRAMS = object_unittest$(EXEEXT
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_19 = ver_test ver_test_2 \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	ver_test_6 ver_test_8 ver_test_9 \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	protected_1 protected_2 \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@	relro_test script_test_1 \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@	script_test_2 justsyms \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@	binary_test script_test_3
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	relro_test relro_script_test \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	script_test_1 script_test_2 \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	justsyms binary_test \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	script_test_3
 @GCC_FALSE@script_test_1_DEPENDENCIES = libgoldtest.a ../libgold.a \
 @GCC_FALSE@	../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \
 @GCC_FALSE@	$(am__DEPENDENCIES_1)
@@ -351,6 +352,7 @@ libgoldtest_a_OBJECTS = $(am_libgoldtest
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	protected_1$(EXEEXT) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	protected_2$(EXEEXT) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	relro_test$(EXEEXT) \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	relro_script_test$(EXEEXT) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	script_test_1$(EXEEXT) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	script_test_2$(EXEEXT) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	justsyms$(EXEEXT) \
@@ -523,6 +525,10 @@ am__protected_2_SOURCES_DIST = protected
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	protected_main_1.$(OBJEXT) \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	protected_3.$(OBJEXT)
 protected_2_OBJECTS = $(am_protected_2_OBJECTS)
+am__relro_script_test_SOURCES_DIST = relro_test_main.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@am_relro_script_test_OBJECTS =  \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	relro_test_main.$(OBJEXT)
+relro_script_test_OBJECTS = $(am_relro_script_test_OBJECTS)
 am__relro_test_SOURCES_DIST = relro_test_main.cc
 @GCC_TRUE@@NATIVE_LINKER_TRUE@am_relro_test_OBJECTS =  \
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	relro_test_main.$(OBJEXT)
@@ -783,9 +789,10 @@ SOURCES = $(libgoldtest_a_SOURCES) basic
 	$(initpri1_SOURCES) $(justsyms_SOURCES) many_sections_r_test.c \
 	$(many_sections_test_SOURCES) $(object_unittest_SOURCES) \
 	$(protected_1_SOURCES) $(protected_2_SOURCES) \
-	$(relro_test_SOURCES) $(script_test_1_SOURCES) \
-	$(script_test_2_SOURCES) script_test_3.c \
-	$(tls_pic_test_SOURCES) $(tls_shared_gd_to_ie_test_SOURCES) \
+	$(relro_script_test_SOURCES) $(relro_test_SOURCES) \
+	$(script_test_1_SOURCES) $(script_test_2_SOURCES) \
+	script_test_3.c $(tls_pic_test_SOURCES) \
+	$(tls_shared_gd_to_ie_test_SOURCES) \
 	$(tls_shared_gnu2_gd_to_ie_test_SOURCES) \
 	$(tls_shared_gnu2_test_SOURCES) $(tls_shared_ie_test_SOURCES) \
 	$(tls_shared_nonpic_test_SOURCES) $(tls_shared_test_SOURCES) \
@@ -832,7 +839,9 @@ DIST_SOURCES = $(libgoldtest_a_SOURCES) 
 	$(am__initpri1_SOURCES_DIST) $(am__justsyms_SOURCES_DIST) \
 	many_sections_r_test.c $(am__many_sections_test_SOURCES_DIST) \
 	$(object_unittest_SOURCES) $(am__protected_1_SOURCES_DIST) \
-	$(am__protected_2_SOURCES_DIST) $(am__relro_test_SOURCES_DIST) \
+	$(am__protected_2_SOURCES_DIST) \
+	$(am__relro_script_test_SOURCES_DIST) \
+	$(am__relro_test_SOURCES_DIST) \
 	$(am__script_test_1_SOURCES_DIST) \
 	$(am__script_test_2_SOURCES_DIST) script_test_3.c \
 	$(am__tls_pic_test_SOURCES_DIST) \
@@ -1341,6 +1350,10 @@ binary_unittest_SOURCES = binary_unittes
 @GCC_TRUE@@NATIVE_LINKER_TRUE@relro_test_DEPENDENCIES = gcctestdir/ld relro_test.so
 @GCC_TRUE@@NATIVE_LINKER_TRUE@relro_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,.
 @GCC_TRUE@@NATIVE_LINKER_TRUE@relro_test_LDADD = relro_test.so
+@GCC_TRUE@@NATIVE_LINKER_TRUE@relro_script_test_SOURCES = relro_test_main.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@relro_script_test_DEPENDENCIES = gcctestdir/ld relro_script_test.so
+@GCC_TRUE@@NATIVE_LINKER_TRUE@relro_script_test_LDFLAGS = -Bgcctestdir/ -Wl,-R,.
+@GCC_TRUE@@NATIVE_LINKER_TRUE@relro_script_test_LDADD = relro_script_test.so
 @GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_1_SOURCES = script_test_1.cc
 @GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_1_DEPENDENCIES = gcctestdir/ld script_test_1.t
 @GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_1_LDFLAGS = -Bgcctestdir/ -Wl,-R,. -T $(srcdir)/script_test_1.t
@@ -1508,6 +1521,9 @@ protected_1$(EXEEXT): $(protected_1_OBJE
 protected_2$(EXEEXT): $(protected_2_OBJECTS) $(protected_2_DEPENDENCIES) 
 	@rm -f protected_2$(EXEEXT)
 	$(CXXLINK) $(protected_2_LDFLAGS) $(protected_2_OBJECTS) $(protected_2_LDADD) $(LIBS)
+relro_script_test$(EXEEXT): $(relro_script_test_OBJECTS) $(relro_script_test_DEPENDENCIES) 
+	@rm -f relro_script_test$(EXEEXT)
+	$(CXXLINK) $(relro_script_test_LDFLAGS) $(relro_script_test_OBJECTS) $(relro_script_test_LDADD) $(LIBS)
 relro_test$(EXEEXT): $(relro_test_OBJECTS) $(relro_test_DEPENDENCIES) 
 	@rm -f relro_test$(EXEEXT)
 	$(CXXLINK) $(relro_test_LDFLAGS) $(relro_test_OBJECTS) $(relro_test_LDADD) $(LIBS)
@@ -2274,6 +2290,8 @@ uninstall-am: uninstall-info-am
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	$(CXXLINK) -Bgcctestdir/ -shared -Wl,-z,relro relro_test_pic.o
 @GCC_TRUE@@NATIVE_LINKER_TRUE@relro_test_pic.o: relro_test.cc
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	$(CXXCOMPILE) -c -fpic -o $@ $<
+@GCC_TRUE@@NATIVE_LINKER_TRUE@relro_script_test.so: gcctestdir/ld relro_script_test.t relro_test_pic.o
+@GCC_TRUE@@NATIVE_LINKER_TRUE@	$(CXXLINK) -Bgcctestdir/ -shared -Wl,-z,relro -T $(srcdir)/relro_script_test.t relro_test_pic.o
 @GCC_TRUE@@NATIVE_LINKER_TRUE@justsyms_2.o: justsyms_2.cc
 @GCC_TRUE@@NATIVE_LINKER_TRUE@	$(CXXCOMPILE) -c -o $@ $<
 @GCC_TRUE@@NATIVE_LINKER_TRUE@justsyms_2r.o: justsyms_2.o gcctestdir/ld $(srcdir)/justsyms.t
Index: testsuite/relro_script_test.t
===================================================================
RCS file: testsuite/relro_script_test.t
diff -N testsuite/relro_script_test.t
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/relro_script_test.t	13 Aug 2008 07:24:27 -0000
@@ -0,0 +1,52 @@
+/* relro_test.t -- relro script test for gold
+
+   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.  */
+
+/* With luck this will work on all platforms.  */
+
+using_script = 1;
+
+SECTIONS
+{
+  . = SIZEOF_HEADERS;
+
+  .text : { *(.text) }
+
+  .eh_frame : ONLY_IF_RO { KEEP(*(.eh_frame)) }
+
+  . = (ALIGN(CONSTANT(MAXPAGESIZE))
+       - ((CONSTANT(MAXPAGESIZE) - .) & (CONSTANT(MAXPAGESIZE) - 1)));
+  . = DATA_SEGMENT_ALIGN(CONSTANT(MAXPAGESIZE), CONSTANT(COMMONPAGESIZE));
+
+  .eh_frame : ONLY_IF_RW { KEEP(*(.eh_frame)) }
+  .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
+  .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*)
+		   *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
+  .dynamic : { *(.dynamic) }
+  .got : { *(.got) }
+
+  . = DATA_SEGMENT_RELRO_END(0, .);
+
+  .data : { *(.data .data.* .gnu.linkonce.d.*) }
+
+  . = DATA_SEGMENT_END (.);
+}
Index: testsuite/relro_test.cc
===================================================================
RCS file: /cvs/src/src/gold/testsuite/relro_test.cc,v
retrieving revision 1.2
diff -p -u -r1.2 relro_test.cc
--- testsuite/relro_test.cc	9 Jun 2008 19:12:34 -0000	1.2
+++ testsuite/relro_test.cc	13 Aug 2008 07:24:27 -0000
@@ -28,6 +28,11 @@
 #include <stdint.h>
 #include <unistd.h>
 
+// This tests we were linked with a script.  If we were linked with a
+// script, relro currently does not work.
+
+extern char using_script[] __attribute__ ((weak));
+
 // This code is put into a shared library linked with -z relro.
 
 // i1 and i2 are not relro variables.
@@ -45,6 +50,9 @@ int* const p2 = &i2;
 bool
 t1()
 {
+  if (using_script)
+    return true;
+
   void* i1addr = static_cast<void*>(&i1);
   void* i2addr = static_cast<void*>(&i2);
   const void* p1addr = static_cast<const void*>(&p1);
@@ -129,6 +137,9 @@ f2()
 bool
 t2()
 {
+  if (using_script)
+    return true;
+
   signal(SIGSEGV, sigsegv_handler);
   orig_terminate = std::set_terminate(terminate_handler);
 

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