mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-25 21:41:47 +08:00
2011-09-29 Sriraman Tallam <tmsriram@google.com>
* layout.h (section_order_map_): New member. (get_section_order_map): New member function. * output.cc (Output_section::add_input_section): Check for patterns only when --section-ordering-file is specified. * gold.cc (queue_middle_tasks): Delay updating order of sections till output_sections have been formed. * layout.cc (Layout_Layout): Initialize section_order_map_. * plugin.cc (update_section_order): Store order in order_map. Do not update the order. * testsuite/Makefile.am: Add test case for plugin_final_layout. * testsuite/Makefile.in: Regenerate. * testsuite/plugin_section_order.c: New file. * testsuite/plugin_final_layout.cc: New file. * testsuite/plugin_final_layout.sh: New file.
This commit is contained in:
@ -1,3 +1,20 @@
|
|||||||
|
2011-09-29 Sriraman Tallam <tmsriram@google.com>
|
||||||
|
|
||||||
|
* layout.h (section_order_map_): New member.
|
||||||
|
(get_section_order_map): New member function.
|
||||||
|
* output.cc (Output_section::add_input_section): Check for patterns
|
||||||
|
only when --section-ordering-file is specified.
|
||||||
|
* gold.cc (queue_middle_tasks): Delay updating order of sections till
|
||||||
|
output_sections have been formed.
|
||||||
|
* layout.cc (Layout_Layout): Initialize section_order_map_.
|
||||||
|
* plugin.cc (update_section_order): Store order in order_map. Do not
|
||||||
|
update the order.
|
||||||
|
* testsuite/Makefile.am: Add test case for plugin_final_layout.
|
||||||
|
* testsuite/Makefile.in: Regenerate.
|
||||||
|
* testsuite/plugin_section_order.c: New file.
|
||||||
|
* testsuite/plugin_final_layout.cc: New file.
|
||||||
|
* testsuite/plugin_final_layout.sh: New file.
|
||||||
|
|
||||||
2011-09-29 Cary Coutant <ccoutant@google.com>
|
2011-09-29 Cary Coutant <ccoutant@google.com>
|
||||||
|
|
||||||
* gold/incremental.cc (Sized_incremental_binary::do_process_got_plt):
|
* gold/incremental.cc (Sized_incremental_binary::do_process_got_plt):
|
||||||
|
14
gold/gold.cc
14
gold/gold.cc
@ -539,6 +539,20 @@ queue_middle_tasks(const General_options& options,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If plugins have specified a section order, re-arrange input sections
|
||||||
|
according to a specified section order. If --section-ordering-file is
|
||||||
|
also specified, do not do anything here. */
|
||||||
|
if (parameters->options().has_plugins()
|
||||||
|
&& layout->is_section_ordering_specified()
|
||||||
|
&& !parameters->options().section_ordering_file ())
|
||||||
|
{
|
||||||
|
for (Layout::Section_list::const_iterator p
|
||||||
|
= layout->section_list().begin();
|
||||||
|
p != layout->section_list().end();
|
||||||
|
++p)
|
||||||
|
(*p)->update_section_layout(layout->get_section_order_map());
|
||||||
|
}
|
||||||
|
|
||||||
// Layout deferred objects due to plugins.
|
// Layout deferred objects due to plugins.
|
||||||
if (parameters->options().has_plugins())
|
if (parameters->options().has_plugins())
|
||||||
{
|
{
|
||||||
|
@ -410,6 +410,7 @@ Layout::Layout(int number_of_input_files, Script_options* script_options)
|
|||||||
script_output_section_data_list_(),
|
script_output_section_data_list_(),
|
||||||
segment_states_(NULL),
|
segment_states_(NULL),
|
||||||
relaxation_debug_check_(NULL),
|
relaxation_debug_check_(NULL),
|
||||||
|
section_order_map_(),
|
||||||
input_section_position_(),
|
input_section_position_(),
|
||||||
input_section_glob_(),
|
input_section_glob_(),
|
||||||
incremental_base_(NULL),
|
incremental_base_(NULL),
|
||||||
|
@ -522,6 +522,10 @@ class Layout
|
|||||||
const char* name, const elfcpp::Shdr<size, big_endian>& shdr,
|
const char* name, const elfcpp::Shdr<size, big_endian>& shdr,
|
||||||
unsigned int reloc_shndx, unsigned int reloc_type, off_t* offset);
|
unsigned int reloc_shndx, unsigned int reloc_type, off_t* offset);
|
||||||
|
|
||||||
|
std::map<Section_id, unsigned int>*
|
||||||
|
get_section_order_map()
|
||||||
|
{ return &this->section_order_map_; }
|
||||||
|
|
||||||
bool
|
bool
|
||||||
is_section_ordering_specified()
|
is_section_ordering_specified()
|
||||||
{ return this->section_ordering_specified_; }
|
{ return this->section_ordering_specified_; }
|
||||||
@ -1322,6 +1326,9 @@ class Layout
|
|||||||
Segment_states* segment_states_;
|
Segment_states* segment_states_;
|
||||||
// A relaxation debug checker. We only create one when in debugging mode.
|
// A relaxation debug checker. We only create one when in debugging mode.
|
||||||
Relaxation_debug_check* relaxation_debug_check_;
|
Relaxation_debug_check* relaxation_debug_check_;
|
||||||
|
// Plugins specify section_ordering using this map. This is set in
|
||||||
|
// update_section_order in plugin.cc
|
||||||
|
std::map<Section_id, unsigned int> section_order_map_;
|
||||||
// Hash a pattern to its position in the section ordering file.
|
// Hash a pattern to its position in the section ordering file.
|
||||||
Unordered_map<std::string, unsigned int> input_section_position_;
|
Unordered_map<std::string, unsigned int> input_section_position_;
|
||||||
// Vector of glob only patterns in the section_ordering file.
|
// Vector of glob only patterns in the section_ordering file.
|
||||||
|
@ -2476,7 +2476,10 @@ Output_section::add_input_section(Layout* layout,
|
|||||||
|| layout->is_section_ordering_specified())
|
|| layout->is_section_ordering_specified())
|
||||||
{
|
{
|
||||||
Input_section isecn(object, shndx, input_section_size, addralign);
|
Input_section isecn(object, shndx, input_section_size, addralign);
|
||||||
if (layout->is_section_ordering_specified())
|
/* If section ordering is requested by specifying a ordering file,
|
||||||
|
using --section-ordering-file, match the section name with
|
||||||
|
a pattern. */
|
||||||
|
if (parameters->options().section_ordering_file())
|
||||||
{
|
{
|
||||||
unsigned int section_order_index =
|
unsigned int section_order_index =
|
||||||
layout->find_section_order_index(std::string(secname));
|
layout->find_section_order_index(std::string(secname));
|
||||||
@ -3485,7 +3488,7 @@ Output_section::Input_section_sort_section_order_index_compare::operator()(
|
|||||||
|
|
||||||
void
|
void
|
||||||
Output_section::update_section_layout(
|
Output_section::update_section_layout(
|
||||||
const Section_layout_order& order_map)
|
const Section_layout_order* order_map)
|
||||||
{
|
{
|
||||||
for (Input_section_list::iterator p = this->input_sections_.begin();
|
for (Input_section_list::iterator p = this->input_sections_.begin();
|
||||||
p != this->input_sections_.end();
|
p != this->input_sections_.end();
|
||||||
@ -3499,8 +3502,8 @@ Output_section::update_section_layout(
|
|||||||
: p->relaxed_input_section()->relobj());
|
: p->relaxed_input_section()->relobj());
|
||||||
unsigned int shndx = p->shndx();
|
unsigned int shndx = p->shndx();
|
||||||
Section_layout_order::const_iterator it
|
Section_layout_order::const_iterator it
|
||||||
= order_map.find(Section_id(obj, shndx));
|
= order_map->find(Section_id(obj, shndx));
|
||||||
if (it == order_map.end())
|
if (it == order_map->end())
|
||||||
continue;
|
continue;
|
||||||
unsigned int section_order_index = it->second;
|
unsigned int section_order_index = it->second;
|
||||||
if (section_order_index != 0)
|
if (section_order_index != 0)
|
||||||
|
@ -2761,7 +2761,7 @@ class Output_section : public Output_data
|
|||||||
typedef std::map<Section_id, unsigned int> Section_layout_order;
|
typedef std::map<Section_id, unsigned int> Section_layout_order;
|
||||||
|
|
||||||
void
|
void
|
||||||
update_section_layout(const Section_layout_order& order_map);
|
update_section_layout(const Section_layout_order* order_map);
|
||||||
|
|
||||||
// Update the output section flags based on input section flags.
|
// Update the output section flags based on input section flags.
|
||||||
void
|
void
|
||||||
|
@ -1630,7 +1630,7 @@ get_input_section_contents(const struct ld_plugin_section section,
|
|||||||
// which they should appear in the final layout.
|
// which they should appear in the final layout.
|
||||||
|
|
||||||
static enum ld_plugin_status
|
static enum ld_plugin_status
|
||||||
update_section_order(const struct ld_plugin_section *section_list,
|
update_section_order(const struct ld_plugin_section* section_list,
|
||||||
unsigned int num_sections)
|
unsigned int num_sections)
|
||||||
{
|
{
|
||||||
gold_assert(parameters->options().has_plugins());
|
gold_assert(parameters->options().has_plugins());
|
||||||
@ -1641,8 +1641,14 @@ update_section_order(const struct ld_plugin_section *section_list,
|
|||||||
if (section_list == NULL)
|
if (section_list == NULL)
|
||||||
return LDPS_ERR;
|
return LDPS_ERR;
|
||||||
|
|
||||||
std::map<Section_id, unsigned int> order_map;
|
Layout* layout = parameters->options().plugins()->layout();
|
||||||
|
gold_assert (layout != NULL);
|
||||||
|
|
||||||
|
std::map<Section_id, unsigned int>* order_map
|
||||||
|
= layout->get_section_order_map();
|
||||||
|
|
||||||
|
/* Store the mapping from Section_id to section position in layout's
|
||||||
|
order_map to consult after output sections are added. */
|
||||||
for (unsigned int i = 0; i < num_sections; ++i)
|
for (unsigned int i = 0; i < num_sections; ++i)
|
||||||
{
|
{
|
||||||
Object* obj = parameters->options().plugins()->get_elf_object(
|
Object* obj = parameters->options().plugins()->get_elf_object(
|
||||||
@ -1651,17 +1657,9 @@ update_section_order(const struct ld_plugin_section *section_list,
|
|||||||
return LDPS_BAD_HANDLE;
|
return LDPS_BAD_HANDLE;
|
||||||
unsigned int shndx = section_list[i].shndx;
|
unsigned int shndx = section_list[i].shndx;
|
||||||
Section_id secn_id(obj, shndx);
|
Section_id secn_id(obj, shndx);
|
||||||
order_map[secn_id] = i + 1;
|
(*order_map)[secn_id] = i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Layout* layout = parameters->options().plugins()->layout();
|
|
||||||
gold_assert (layout != NULL);
|
|
||||||
|
|
||||||
for (Layout::Section_list::const_iterator p = layout->section_list().begin();
|
|
||||||
p != layout->section_list().end();
|
|
||||||
++p)
|
|
||||||
(*p)->update_section_layout(order_map);
|
|
||||||
|
|
||||||
return LDPS_OK;
|
return LDPS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1510,6 +1510,20 @@ unused.o: unused.c
|
|||||||
unused.c:
|
unused.c:
|
||||||
@cp /dev/null $@
|
@cp /dev/null $@
|
||||||
|
|
||||||
|
check_SCRIPTS += plugin_final_layout.sh
|
||||||
|
check_DATA += plugin_final_layout.stdout
|
||||||
|
plugin_final_layout.o: plugin_final_layout.cc
|
||||||
|
$(CXXCOMPILE) -O0 -c -ffunction-sections -fdata-sections -g -o $@ $<
|
||||||
|
plugin_final_layout: plugin_final_layout.o plugin_section_order.so gcctestdir/ld
|
||||||
|
$(CXXLINK) -Bgcctestdir/ -Wl,--plugin,"./plugin_section_order.so" plugin_final_layout.o
|
||||||
|
plugin_final_layout.stdout: plugin_final_layout
|
||||||
|
$(TEST_NM) -n plugin_final_layout > plugin_final_layout.stdout
|
||||||
|
|
||||||
|
plugin_section_order.so: plugin_section_order.o
|
||||||
|
$(LINK) -Bgcctestdir/ -shared plugin_section_order.o
|
||||||
|
plugin_section_order.o: plugin_section_order.c
|
||||||
|
$(COMPILE) -O0 -c -fpic -o $@ $<
|
||||||
|
|
||||||
endif PLUGINS
|
endif PLUGINS
|
||||||
|
|
||||||
check_PROGRAMS += exclude_libs_test
|
check_PROGRAMS += exclude_libs_test
|
||||||
|
@ -306,7 +306,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
|
|||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_3.sh \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_3.sh \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_4.sh \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_4.sh \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_6.sh \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_6.sh \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_7.sh
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_7.sh \
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_final_layout.sh
|
||||||
|
|
||||||
# Test that symbols known in the IR file but not in the replacement file
|
# Test that symbols known in the IR file but not in the replacement file
|
||||||
# produce an unresolved symbol error.
|
# produce an unresolved symbol error.
|
||||||
@ -318,7 +319,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
|
|||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_6.err \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_6.err \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_7.err \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_7.err \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_7.syms \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_7.syms \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_9.err
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_9.err \
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_final_layout.stdout
|
||||||
# Make a copy of two_file_test_1.o, which does not define the symbol _Z4t16av.
|
# Make a copy of two_file_test_1.o, which does not define the symbol _Z4t16av.
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@am__append_36 = \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@am__append_36 = \
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_1.err \
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ plugin_test_1.err \
|
||||||
@ -3644,6 +3646,8 @@ plugin_test_6.sh.log: plugin_test_6.sh
|
|||||||
@p='plugin_test_6.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
|
@p='plugin_test_6.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
|
||||||
plugin_test_7.sh.log: plugin_test_7.sh
|
plugin_test_7.sh.log: plugin_test_7.sh
|
||||||
@p='plugin_test_7.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
|
@p='plugin_test_7.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
|
||||||
|
plugin_final_layout.sh.log: plugin_final_layout.sh
|
||||||
|
@p='plugin_final_layout.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
|
||||||
exclude_libs_test.sh.log: exclude_libs_test.sh
|
exclude_libs_test.sh.log: exclude_libs_test.sh
|
||||||
@p='exclude_libs_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
|
@p='exclude_libs_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
|
||||||
discard_locals_test.sh.log: discard_locals_test.sh
|
discard_locals_test.sh.log: discard_locals_test.sh
|
||||||
@ -4756,6 +4760,17 @@ uninstall-am:
|
|||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ $(COMPILE) -c -o $@ $<
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ $(COMPILE) -c -o $@ $<
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@unused.c:
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@unused.c:
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ @cp /dev/null $@
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ @cp /dev/null $@
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_final_layout.o: plugin_final_layout.cc
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ $(CXXCOMPILE) -O0 -c -ffunction-sections -fdata-sections -g -o $@ $<
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_final_layout: plugin_final_layout.o plugin_section_order.so gcctestdir/ld
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ $(CXXLINK) -Bgcctestdir/ -Wl,--plugin,"./plugin_section_order.so" plugin_final_layout.o
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_final_layout.stdout: plugin_final_layout
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ $(TEST_NM) -n plugin_final_layout > plugin_final_layout.stdout
|
||||||
|
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_section_order.so: plugin_section_order.o
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ $(LINK) -Bgcctestdir/ -shared plugin_section_order.o
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@plugin_section_order.o: plugin_section_order.c
|
||||||
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@ $(COMPILE) -O0 -c -fpic -o $@ $<
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@exclude_libs_test.syms: exclude_libs_test
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@exclude_libs_test.syms: exclude_libs_test
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -sW $< >$@ 2>/dev/null
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_READELF) -sW $< >$@ 2>/dev/null
|
||||||
@GCC_TRUE@@NATIVE_LINKER_TRUE@libexclude_libs_test_1.a: exclude_libs_test_1.o
|
@GCC_TRUE@@NATIVE_LINKER_TRUE@libexclude_libs_test_1.a: exclude_libs_test_1.o
|
||||||
|
41
gold/testsuite/plugin_final_layout.cc
Normal file
41
gold/testsuite/plugin_final_layout.cc
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// plugin_final_layout.cc -- a test case for gold
|
||||||
|
|
||||||
|
// Copyright 2011 Free Software Foundation, Inc.
|
||||||
|
// Written by Sriraman Tallam <tmsriram@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.
|
||||||
|
|
||||||
|
// The goal of this program is to verify if section ordering
|
||||||
|
// via plugins happens correctly.
|
||||||
|
|
||||||
|
void bar ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void baz ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void foo ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
60
gold/testsuite/plugin_final_layout.sh
Executable file
60
gold/testsuite/plugin_final_layout.sh
Executable file
@ -0,0 +1,60 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# plugin_final_layout.sh -- test
|
||||||
|
|
||||||
|
# Copyright 2011 Free Software Foundation, Inc.
|
||||||
|
# Written by Sriraman Tallam <tmsriram@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.
|
||||||
|
|
||||||
|
# The goal of this program is to verify if --section-ordering-file works as
|
||||||
|
# intended. File final_layout.cc is in this test.
|
||||||
|
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
check()
|
||||||
|
{
|
||||||
|
awk "
|
||||||
|
BEGIN { saw1 = 0; saw2 = 0; err = 0; }
|
||||||
|
/.*$2\$/ { saw1 = 1; }
|
||||||
|
/.*$3\$/ {
|
||||||
|
saw2 = 1;
|
||||||
|
if (!saw1)
|
||||||
|
{
|
||||||
|
printf \"layout of $2 and $3 is not right\\n\";
|
||||||
|
err = 1;
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
if (!saw1 && !err)
|
||||||
|
{
|
||||||
|
printf \"did not see $2\\n\";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
if (!saw2 && !err)
|
||||||
|
{
|
||||||
|
printf \"did not see $3\\n\";
|
||||||
|
exit 1;
|
||||||
|
}
|
||||||
|
}" $1
|
||||||
|
}
|
||||||
|
|
||||||
|
check plugin_final_layout.stdout "_Z3foov" "_Z3barv"
|
||||||
|
check plugin_final_layout.stdout "_Z3barv" "_Z3bazv"
|
167
gold/testsuite/plugin_section_order.c
Normal file
167
gold/testsuite/plugin_section_order.c
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
/* plugin_section_reorder.c -- Simple plugin to reorder function sections
|
||||||
|
|
||||||
|
Copyright 2011 Free Software Foundation, Inc.
|
||||||
|
Written by Sriraman Tallam <tmsriram@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. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "plugin-api.h"
|
||||||
|
|
||||||
|
static ld_plugin_get_input_section_count get_input_section_count = NULL;
|
||||||
|
static ld_plugin_get_input_section_type get_input_section_type = NULL;
|
||||||
|
static ld_plugin_get_input_section_name get_input_section_name = NULL;
|
||||||
|
static ld_plugin_get_input_section_contents get_input_section_contents = NULL;
|
||||||
|
static ld_plugin_update_section_order update_section_order = NULL;
|
||||||
|
static ld_plugin_allow_section_ordering allow_section_ordering = NULL;
|
||||||
|
|
||||||
|
enum ld_plugin_status onload(struct ld_plugin_tv *tv);
|
||||||
|
enum ld_plugin_status claim_file_hook(const struct ld_plugin_input_file *file,
|
||||||
|
int *claimed);
|
||||||
|
enum ld_plugin_status all_symbols_read_hook(void);
|
||||||
|
|
||||||
|
/* Plugin entry point. */
|
||||||
|
enum ld_plugin_status
|
||||||
|
onload(struct ld_plugin_tv *tv)
|
||||||
|
{
|
||||||
|
struct ld_plugin_tv *entry;
|
||||||
|
for (entry = tv; entry->tv_tag != LDPT_NULL; ++entry)
|
||||||
|
{
|
||||||
|
switch (entry->tv_tag)
|
||||||
|
{
|
||||||
|
case LDPT_REGISTER_CLAIM_FILE_HOOK:
|
||||||
|
assert((*entry->tv_u.tv_register_claim_file) (claim_file_hook) == LDPS_OK);
|
||||||
|
break;
|
||||||
|
case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK:
|
||||||
|
assert((*entry->tv_u.tv_register_all_symbols_read) (all_symbols_read_hook)
|
||||||
|
== LDPS_OK);
|
||||||
|
break;
|
||||||
|
case LDPT_GET_INPUT_SECTION_COUNT:
|
||||||
|
get_input_section_count = *entry->tv_u.tv_get_input_section_count;
|
||||||
|
break;
|
||||||
|
case LDPT_GET_INPUT_SECTION_TYPE:
|
||||||
|
get_input_section_type = *entry->tv_u.tv_get_input_section_type;
|
||||||
|
break;
|
||||||
|
case LDPT_GET_INPUT_SECTION_NAME:
|
||||||
|
get_input_section_name = *entry->tv_u.tv_get_input_section_name;
|
||||||
|
break;
|
||||||
|
case LDPT_GET_INPUT_SECTION_CONTENTS:
|
||||||
|
get_input_section_contents = *entry->tv_u.tv_get_input_section_contents;
|
||||||
|
break;
|
||||||
|
case LDPT_UPDATE_SECTION_ORDER:
|
||||||
|
update_section_order = *entry->tv_u.tv_update_section_order;
|
||||||
|
break;
|
||||||
|
case LDPT_ALLOW_SECTION_ORDERING:
|
||||||
|
allow_section_ordering = *entry->tv_u.tv_allow_section_ordering;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_input_section_count == NULL
|
||||||
|
|| get_input_section_type == NULL
|
||||||
|
|| get_input_section_name == NULL
|
||||||
|
|| get_input_section_contents == NULL
|
||||||
|
|| update_section_order == NULL
|
||||||
|
|| allow_section_ordering == NULL)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Some interfaces are missing\n");
|
||||||
|
return LDPS_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return LDPS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static int is_prefix_of(const char *prefix, const char *str)
|
||||||
|
{
|
||||||
|
return strncmp(prefix, str, strlen (prefix)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ld_plugin_section section_list[3];
|
||||||
|
int num_entries = 0;
|
||||||
|
|
||||||
|
/* This function is called by the linker for every new object it encounters. */
|
||||||
|
enum ld_plugin_status
|
||||||
|
claim_file_hook(const struct ld_plugin_input_file *file, int *claimed)
|
||||||
|
{
|
||||||
|
static int is_ordering_specified = 0;
|
||||||
|
struct ld_plugin_section section;
|
||||||
|
unsigned int count = 0;
|
||||||
|
unsigned int shndx;
|
||||||
|
|
||||||
|
*claimed = 0;
|
||||||
|
if (is_ordering_specified == 0)
|
||||||
|
{
|
||||||
|
/* Inform the linker to prepare for section reordering. */
|
||||||
|
(*allow_section_ordering)();
|
||||||
|
is_ordering_specified = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*get_input_section_count)(file->handle, &count);
|
||||||
|
|
||||||
|
for (shndx = 0; shndx < count; ++shndx)
|
||||||
|
{
|
||||||
|
char *name = NULL;
|
||||||
|
int position = 3;
|
||||||
|
|
||||||
|
section.handle = file->handle;
|
||||||
|
section.shndx = shndx;
|
||||||
|
(*get_input_section_name)(section, &name);
|
||||||
|
|
||||||
|
/* Order is foo() followed by bar() followed by baz() */
|
||||||
|
if (is_prefix_of(".text.", name))
|
||||||
|
{
|
||||||
|
if (strstr(name, "_Z3foov") != NULL)
|
||||||
|
position = 0;
|
||||||
|
else if (strstr(name, "_Z3barv") != NULL)
|
||||||
|
position = 1;
|
||||||
|
else if (strstr(name, "_Z3bazv") != NULL)
|
||||||
|
position = 2;
|
||||||
|
else
|
||||||
|
position = 3;
|
||||||
|
}
|
||||||
|
if (position < 3)
|
||||||
|
{
|
||||||
|
section_list[position].handle = file->handle;
|
||||||
|
section_list[position].shndx = shndx;
|
||||||
|
num_entries++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return LDPS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function is called by the linker after all the symbols have been read.
|
||||||
|
At this stage, it is fine to tell the linker the desired function order. */
|
||||||
|
|
||||||
|
enum ld_plugin_status
|
||||||
|
all_symbols_read_hook(void)
|
||||||
|
{
|
||||||
|
if (num_entries == 3)
|
||||||
|
update_section_order(section_list, num_entries);
|
||||||
|
|
||||||
|
return LDPS_OK;
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user