* 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.
This commit is contained in:
parent
9e9a97982d
commit
2d924fd9eb
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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_)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
52
gold/testsuite/relro_script_test.t
Normal file
52
gold/testsuite/relro_script_test.t
Normal file
@ -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 (.);
|
||||
}
|
@ -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);
|
||||
|
||||
|
@ -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 ')'
|
||||
|
Loading…
x
Reference in New Issue
Block a user