* 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

@@ -659,7 +659,7 @@ Sized_relobj_file<size, big_endian>::do_relocate(const Symbol_table* symtab,
// section data to the output file. The second one applies
// relocations.
this->write_sections(pshdrs, of, &views);
this->write_sections(layout, pshdrs, of, &views);
// To speed up relocations, we set up hash tables for fast lookup of
// input offsets to output addresses.
@@ -678,6 +678,8 @@ Sized_relobj_file<size, big_endian>::do_relocate(const Symbol_table* symtab,
{
if (views[i].view != NULL)
{
if (views[i].is_ctors_reverse_view)
this->reverse_words(views[i].view, views[i].view_size);
if (!views[i].is_postprocessing_view)
{
if (views[i].is_input_output_view)
@@ -712,7 +714,8 @@ struct Read_multiple_compare
template<int size, bool big_endian>
void
Sized_relobj_file<size, big_endian>::write_sections(const unsigned char* pshdrs,
Sized_relobj_file<size, big_endian>::write_sections(const Layout* layout,
const unsigned char* pshdrs,
Output_file* of,
Views* pviews)
{
@@ -761,6 +764,7 @@ Sized_relobj_file<size, big_endian>::write_sections(const unsigned char* pshdrs,
pvs->address = posd->address();
pvs->is_input_output_view = false;
pvs->is_postprocessing_view = false;
pvs->is_ctors_reverse_view = false;
continue;
}
@@ -875,6 +879,12 @@ Sized_relobj_file<size, big_endian>::write_sections(const unsigned char* pshdrs,
pvs->view_size = view_size;
pvs->is_input_output_view = output_offset == invalid_address;
pvs->is_postprocessing_view = os->requires_postprocessing();
pvs->is_ctors_reverse_view =
(!parameters->options().relocatable()
&& view_size > size / 8
&& (strcmp(os->name(), ".init_array") == 0
|| strcmp(os->name(), ".fini_array") == 0)
&& layout->is_ctors_in_init_array(this, i));
}
// Actually read the data.
@@ -1483,6 +1493,26 @@ Sized_relobj_file<size, big_endian>::find_functions(
}
}
// Reverse the words in a section. Used for .ctors sections mapped to
// .init_array sections. See ctors_sections_in_init_array in
// layout.cc.
template<int size, bool big_endian>
void
Sized_relobj_file<size, big_endian>::reverse_words(unsigned char* view,
section_size_type view_size)
{
typedef typename elfcpp::Swap<size, big_endian>::Valtype Valtype;
Valtype* vview = reinterpret_cast<Valtype*>(view);
section_size_type vview_size = view_size / (size / 8);
for (section_size_type i = 0; i < vview_size / 2; ++i)
{
Valtype tmp = vview[i];
vview[i] = vview[vview_size - 1 - i];
vview[vview_size - 1 - i] = tmp;
}
}
// Class Merged_symbol_value.
template<int size>