* layout.cc: Include "object.h".

(ctors_sections_in_init_array): New static variable.
	(Layout::is_ctors_in_init_array): New function.
	(Layout::layout): Add entry to ctors_sections_in_init_array if
	appropriate.
	* layout.h (class Layout): Declare is_ctors_in_init_array.
	* reloc.cc (Sized_relobj_file::do_relocate): Call reverse_words if
	is_ctors_reverse_view is set.
	(Sized_relobj_file::write_sections): Add layout parameter.  Change
	all callers.  Set is_ctors_reverse_view field of View_size.
	(Sized_relobj_file::reverse_words): New function.
	* object.h (Sized_relobj_file::View_size): Add
	is_ctors_reverse_view field.
	(class Sized_relobj_file): Update declarations.
	* testsuite/initpri3.c: New test.
	* testsuite/Makefile.am: (check_PROGRAMS): Add initpri3a and
	initpri3b.
	(initpri3a_SOURCES, initpri3a_DEPENDENCIES): New variables.
	(initpri3a_LDFLAGS, initpri3a_LDADD): New variables.
	(initpri3b_SOURCES, initpri3b_DEPENDENCIES): New variables.
	(initpri3b_LDFLAGS, initpri3b_LDADD): New variables.
	* testsuite/Makefile.in: Rebuild.
This commit is contained in:
Ian Lance Taylor 2011-06-25 00:40:57 +00:00
parent 79763091fb
commit 487b39dfdd
8 changed files with 253 additions and 16 deletions

View file

@ -46,6 +46,7 @@
#include "ehframe.h"
#include "compressed_output.h"
#include "reduced_debug_output.h"
#include "object.h"
#include "reloc.h"
#include "descriptors.h"
#include "plugin.h"
@ -617,6 +618,30 @@ Layout::find_output_segment(elfcpp::PT type, elfcpp::Elf_Word set,
return NULL;
}
// When we put a .ctors or .dtors section with more than one word into
// a .init_array or .fini_array section, we need to reverse the words
// in the .ctors/.dtors section. This is because .init_array executes
// constructors front to back, where .ctors executes them back to
// front, and vice-versa for .fini_array/.dtors. Although we do want
// to remap .ctors/.dtors into .init_array/.fini_array because it can
// be more efficient, we don't want to change the order in which
// constructors/destructors are run. This set just keeps track of
// these sections which need to be reversed. It is only changed by
// Layout::layout. It should be a private member of Layout, but that
// would require layout.h to #include object.h to get the definition
// of Section_id.
static Unordered_set<Section_id, Section_id_hash> ctors_sections_in_init_array;
// Return whether OBJECT/SHNDX is a .ctors/.dtors section mapped to a
// .init_array/.fini_array section.
bool
Layout::is_ctors_in_init_array(Relobj* relobj, unsigned int shndx) const
{
return (ctors_sections_in_init_array.find(Section_id(relobj, shndx))
!= ctors_sections_in_init_array.end());
}
// Return the output section to use for section NAME with type TYPE
// and section flags FLAGS. NAME must be canonicalized in the string
// pool, and NAME_KEY is the key. ORDER is where this should appear
@ -922,11 +947,11 @@ Layout::layout(Sized_relobj_file<size, big_endian>* object, unsigned int shndx,
}
// By default the GNU linker sorts input sections whose names match
// .ctor.*, .dtor.*, .init_array.*, or .fini_array.*. The sections
// are sorted by name. This is used to implement constructor
// priority ordering. We are compatible. When we put .ctor
// sections in .init_array and .dtor sections in .fini_array, we
// must also sort plain .ctor and .dtor sections.
// .ctors.*, .dtors.*, .init_array.*, or .fini_array.*. The
// sections are sorted by name. This is used to implement
// constructor priority ordering. We are compatible. When we put
// .ctor sections in .init_array and .dtor sections in .fini_array,
// we must also sort plain .ctor and .dtor sections.
if (!this->script_options_->saw_sections_clause()
&& !parameters->options().relocatable()
&& (is_prefix_of(".ctors.", name)
@ -938,6 +963,22 @@ Layout::layout(Sized_relobj_file<size, big_endian>* object, unsigned int shndx,
|| strcmp(name, ".dtors") == 0))))
os->set_must_sort_attached_input_sections();
// If this is a .ctors or .ctors.* section being mapped to a
// .init_array section, or a .dtors or .dtors.* section being mapped
// to a .fini_array section, we will need to reverse the words if
// there is more than one. Record this section for later. See
// ctors_sections_in_init_array above.
if (!this->script_options_->saw_sections_clause()
&& !parameters->options().relocatable()
&& shdr.get_sh_size() > size / 8
&& (((strcmp(name, ".ctors") == 0
|| is_prefix_of(".ctors.", name))
&& strcmp(os->name(), ".init_array") == 0)
|| ((strcmp(name, ".dtors") == 0
|| is_prefix_of(".dtors.", name))
&& strcmp(os->name(), ".fini_array") == 0)))
ctors_sections_in_init_array.insert(Section_id(object, shndx));
// FIXME: Handle SHF_LINK_ORDER somewhere.
elfcpp::Elf_Xword orig_flags = os->flags();