diff options
author | Ian Lance Taylor <ian@airs.com> | 2011-06-25 00:40:57 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2011-06-25 00:40:57 +0000 |
commit | 487b39dfdd6cdfcac1124f2bcacd70a2da92f242 (patch) | |
tree | dae756aa105cf7da1781b1b7cec907e38c082167 /gold/layout.cc | |
parent | 79763091fb5ba8a787fc19b37edb5608ec5e3ec5 (diff) | |
download | gdb-487b39dfdd6cdfcac1124f2bcacd70a2da92f242.zip gdb-487b39dfdd6cdfcac1124f2bcacd70a2da92f242.tar.gz gdb-487b39dfdd6cdfcac1124f2bcacd70a2da92f242.tar.bz2 |
* 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/layout.cc')
-rw-r--r-- | gold/layout.cc | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/gold/layout.cc b/gold/layout.cc index 82964ce..bfb1a7e 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -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(); |