summaryrefslogtreecommitdiff
path: root/gold/reloc.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2011-06-25 00:40:57 +0000
committerIan Lance Taylor <ian@airs.com>2011-06-25 00:40:57 +0000
commit487b39dfdd6cdfcac1124f2bcacd70a2da92f242 (patch)
treedae756aa105cf7da1781b1b7cec907e38c082167 /gold/reloc.cc
parent79763091fb5ba8a787fc19b37edb5608ec5e3ec5 (diff)
* 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.
Diffstat (limited to 'gold/reloc.cc')
-rw-r--r--gold/reloc.cc34
1 files changed, 32 insertions, 2 deletions
diff --git a/gold/reloc.cc b/gold/reloc.cc
index dacab35f67..4c28b03be8 100644
--- a/gold/reloc.cc
+++ b/gold/reloc.cc
@@ -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>