aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2008-08-13 07:37:46 +0000
committerIan Lance Taylor <ian@airs.com>2008-08-13 07:37:46 +0000
commit2d924fd9ebc6a97f9ef93208597e563c88f5e9e8 (patch)
treeecbfc504dee9ce3475f988e5bce567d070e0c0c1
parent9e9a97982d36c9b5e6b3d79ecbaf68041981e23b (diff)
downloadgdb-2d924fd9ebc6a97f9ef93208597e563c88f5e9e8.zip
gdb-2d924fd9ebc6a97f9ef93208597e563c88f5e9e8.tar.gz
gdb-2d924fd9ebc6a97f9ef93208597e563c88f5e9e8.tar.bz2
* 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.
-rw-r--r--gold/ChangeLog56
-rw-r--r--gold/layout.cc12
-rw-r--r--gold/output.cc7
-rw-r--r--gold/output.h5
-rw-r--r--gold/script-c.h8
-rw-r--r--gold/script-sections.cc128
-rw-r--r--gold/script-sections.h13
-rw-r--r--gold/script.cc28
-rw-r--r--gold/script.h1
-rw-r--r--gold/testsuite/Makefile.am8
-rw-r--r--gold/testsuite/Makefile.in32
-rw-r--r--gold/testsuite/relro_script_test.t52
-rw-r--r--gold/testsuite/relro_test.cc11
-rw-r--r--gold/yyscript.y10
14 files changed, 346 insertions, 25 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index db1a24f..aec50a5 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,59 @@
+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.
+
2008-08-06 Cary Coutant <ccoutant@google.com>
* archive.cc (Archive::total_archives, Archive::total_members)
diff --git a/gold/layout.cc b/gold/layout.cc
index a08ec72..99819d6 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -921,8 +921,7 @@ Layout::attach_allocated_section_to_segment(Output_section* os)
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_segment(Output_section* os)
{
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_Word type, elfcpp::Elf_Word flags)
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;
}
diff --git a/gold/output.cc b/gold/output.cc
index 145fca1..2a46195 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -2651,8 +2651,7 @@ Output_segment::add_output_section(Output_section* os,
// 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_)
diff --git a/gold/output.h b/gold/output.h
index e2c41c7..1c95881 100644
--- a/gold/output.h
+++ b/gold/output.h
@@ -2177,6 +2177,11 @@ class Output_section : public Output_data
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
diff --git a/gold/script-c.h b/gold/script-c.h
index 4f19b63..d94ba51 100644
--- a/gold/script-c.h
+++ b/gold/script-c.h
@@ -364,6 +364,14 @@ script_add_phdr(void* closure, const char* name, size_t namelen,
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
diff --git a/gold/script-sections.cc b/gold/script-sections.cc
index 13c9771..990a1a2 100644
--- a/gold/script-sections.cc
+++ b/gold/script-sections.cc
@@ -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 Sections_element
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 Sections_element
// 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 Sections_element
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 Sections_element
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_section_definition(
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_section_name(const char* file_name,
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_addresses(Symbol_table* symtab,
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_constraint(
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 Sections_element
// 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 Sections_element
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 Sections_element
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 Input_section_spec* spec, bool keep)
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_section* os)
{
// 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_section* os)
++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(Symbol_table* symtab, Layout* layout)
}
}
+ // 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;
diff --git a/gold/script-sections.h b/gold/script-sections.h
index 73bf33f..465c24e 100644
--- a/gold/script-sections.h
+++ b/gold/script-sections.h
@@ -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.
diff --git a/gold/script.cc b/gold/script.cc
index f6e4a39..53fcf66 100644
--- a/gold/script.cc
+++ b/gold/script.cc
@@ -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
diff --git a/gold/script.h b/gold/script.h
index e688a74..3397bf0 100644
--- a/gold/script.h
+++ b/gold/script.h
@@ -407,7 +407,6 @@ read_commandline_script(const char* filename, Command_line*);
bool
read_version_script(const char* filename, Command_line* cmdline);
-
} // End namespace gold.
#endif // !defined(GOLD_SCRIPT_H)
diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am
index df98677..c9dd470 100644
--- a/gold/testsuite/Makefile.am
+++ b/gold/testsuite/Makefile.am
@@ -835,6 +835,14 @@ relro_test.so: gcctestdir/ld relro_test_pic.o
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
diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in
index c5e929a..9f72b88 100644
--- a/gold/testsuite/Makefile.in
+++ b/gold/testsuite/Makefile.in
@@ -229,9 +229,10 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_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_a_OBJECTS)
@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_main_1.cc protected_3.cc
@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_pic_test.c \
$(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) basic_pic_test.c \
$(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_unittest.cc
@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_OBJECTS) $(protected_1_DEPENDENCIES)
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
diff --git a/gold/testsuite/relro_script_test.t b/gold/testsuite/relro_script_test.t
new file mode 100644
index 0000000..cacb84d
--- /dev/null
+++ b/gold/testsuite/relro_script_test.t
@@ -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 (.);
+}
diff --git a/gold/testsuite/relro_test.cc b/gold/testsuite/relro_test.cc
index 1fc1b43..bc6c77b 100644
--- a/gold/testsuite/relro_test.cc
+++ b/gold/testsuite/relro_test.cc
@@ -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);
diff --git a/gold/yyscript.y b/gold/yyscript.y
index ec2e8c0..683273b 100644
--- a/gold/yyscript.y
+++ b/gold/yyscript.y
@@ -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 ')'