Fix bug in plugin section ordering infrastructure when layout is deferred.
Sriraman Tallam
tmsriram@google.com
Thu Sep 29 18:19:00 GMT 2011
Hi Cary,
All done. Patch attached.
Thanks,
-Sri.
On Thu, Sep 29, 2011 at 10:50 AM, Cary Coutant <ccoutant@google.com> wrote:
> In gold.cc...
> @@ -556,6 +556,19 @@ queue_middle_tasks(const General_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 ());
> + }
>
> Remove space before '()'.
>
> In layout.cc...
> @@ -410,6 +410,7 @@ Layout::Layout(int number_of_input_files
> + section_order_map_ (),
>
> Likewise.
>
> In layout.h...
> @@ -522,6 +522,10 @@ class Layout
> + std::map<Section_id, unsigned int> &
> + get_section_order_map()
> + { return this->section_order_map_; }
>
> Remove space before '&'. If you're going to return a reference, it
> should generally be a const reference, and the method should also be
> marked const. In this case, it looks like you can't make it const, so
> I think it would be better to return a straight pointer.
>
> In output.cc...
> @@ -2476,7 +2476,10 @@ Output_section::add_input_section(Layout
> + /* 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 ())
>
> Remove space before '()'.
>
> In plugin.cc...
> @@ -1588,8 +1588,14 @@ update_section_order(const struct ld_plu
> + std::map<Section_id, unsigned int> &order_map
> + = layout->get_section_order_map ();
>
> Likewise. This should be a pointer instead of a reference, and put the
> space after '*' instead of before.
>
> (Yeah, it's hard to switch between C and C++ formatting conventions.)
>
> -cary
>
-------------- next part --------------
Index: gold.cc
===================================================================
RCS file: /cvs/src/src/gold/gold.cc,v
retrieving revision 1.94
diff -u -u -p -r1.94 gold.cc
--- gold.cc 15 Jul 2011 21:43:08 -0000 1.94
+++ gold.cc 29 Sep 2011 18:14:21 -0000
@@ -556,6 +556,19 @@ queue_middle_tasks(const General_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.
if (parameters->options().has_plugins())
{
Index: layout.cc
===================================================================
RCS file: /cvs/src/src/gold/layout.cc,v
retrieving revision 1.220
diff -u -u -p -r1.220 layout.cc
--- layout.cc 18 Sep 2011 15:06:28 -0000 1.220
+++ layout.cc 29 Sep 2011 18:14:21 -0000
@@ -410,6 +410,7 @@ Layout::Layout(int number_of_input_files
script_output_section_data_list_(),
segment_states_(NULL),
relaxation_debug_check_(NULL),
+ section_order_map_(),
input_section_position_(),
input_section_glob_(),
incremental_base_(NULL),
Index: layout.h
===================================================================
RCS file: /cvs/src/src/gold/layout.h,v
retrieving revision 1.100
diff -u -u -p -r1.100 layout.h
--- layout.h 27 Aug 2011 01:28:17 -0000 1.100
+++ layout.h 29 Sep 2011 18:14:21 -0000
@@ -522,6 +522,10 @@ class Layout
const char* name, const elfcpp::Shdr<size, big_endian>& shdr,
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
is_section_ordering_specified()
{ return this->section_ordering_specified_; }
@@ -1322,6 +1326,9 @@ class Layout
Segment_states* segment_states_;
// A relaxation debug checker. We only create one when in debugging mode.
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.
Unordered_map<std::string, unsigned int> input_section_position_;
// Vector of glob only patterns in the section_ordering file.
Index: output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.159
diff -u -u -p -r1.159 output.cc
--- output.cc 10 Sep 2011 05:15:43 -0000 1.159
+++ output.cc 29 Sep 2011 18:14:22 -0000
@@ -2476,7 +2476,10 @@ Output_section::add_input_section(Layout
|| layout->is_section_ordering_specified())
{
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 =
layout->find_section_order_index(std::string(secname));
@@ -3485,7 +3488,7 @@ Output_section::Input_section_sort_secti
void
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();
p != this->input_sections_.end();
@@ -3499,8 +3502,8 @@ Output_section::update_section_layout(
: p->relaxed_input_section()->relobj());
unsigned int shndx = p->shndx();
Section_layout_order::const_iterator it
- = order_map.find(Section_id(obj, shndx));
- if (it == order_map.end())
+ = order_map->find(Section_id(obj, shndx));
+ if (it == order_map->end())
continue;
unsigned int section_order_index = it->second;
if (section_order_index != 0)
Index: output.h
===================================================================
RCS file: /cvs/src/src/gold/output.h,v
retrieving revision 1.128
diff -u -u -p -r1.128 output.h
--- output.h 27 Aug 2011 01:28:18 -0000 1.128
+++ output.h 29 Sep 2011 18:14:22 -0000
@@ -2761,7 +2761,7 @@ class Output_section : public Output_dat
typedef std::map<Section_id, unsigned int> Section_layout_order;
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.
void
Index: plugin.cc
===================================================================
RCS file: /cvs/src/src/gold/plugin.cc,v
retrieving revision 1.48
diff -u -u -p -r1.48 plugin.cc
--- plugin.cc 14 Jul 2011 00:55:18 -0000 1.48
+++ plugin.cc 29 Sep 2011 18:14:22 -0000
@@ -1577,7 +1577,7 @@ get_input_section_contents(const struct
// which they should appear in the final layout.
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)
{
gold_assert(parameters->options().has_plugins());
@@ -1588,8 +1588,14 @@ update_section_order(const struct ld_plu
if (section_list == NULL)
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)
{
Object* obj = parameters->options().plugins()->get_elf_object(
@@ -1598,17 +1604,9 @@ update_section_order(const struct ld_plu
return LDPS_BAD_HANDLE;
unsigned int shndx = section_list[i].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;
}
cvs diff: Diffing po
cvs diff: Diffing testsuite
Index: testsuite/Makefile.am
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.am,v
retrieving revision 1.182
diff -u -u -p -r1.182 Makefile.am
--- testsuite/Makefile.am 14 Sep 2011 01:29:01 -0000 1.182
+++ testsuite/Makefile.am 29 Sep 2011 18:14:22 -0000
@@ -1510,6 +1510,20 @@ unused.o: unused.c
unused.c:
@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
check_PROGRAMS += exclude_libs_test
Index: testsuite/Makefile.in
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.in,v
retrieving revision 1.192
diff -u -u -p -r1.192 Makefile.in
--- testsuite/Makefile.in 23 Sep 2011 15:02:32 -0000 1.192
+++ testsuite/Makefile.in 29 Sep 2011 18:14:22 -0000
@@ -306,7 +306,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__E
@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_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
# produce an unresolved symbol error.
@@ -318,7 +319,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__E
@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.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.
@GCC_TRUE@@NATIVE_LINKER_TRUE@@PLUGINS_TRUE@am__append_36 = \
@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)
plugin_test_7.sh.log: plugin_test_7.sh
@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
@p='exclude_libs_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
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@unused.c:
@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@ $(TEST_READELF) -sW $< >$@ 2>/dev/null
@GCC_TRUE@@NATIVE_LINKER_TRUE@libexclude_libs_test_1.a: exclude_libs_test_1.o
Index: testsuite/plugin_final_layout.cc
===================================================================
RCS file: testsuite/plugin_final_layout.cc
diff -N testsuite/plugin_final_layout.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/plugin_final_layout.cc 29 Sep 2011 18:14:22 -0000
@@ -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;
+}
Index: testsuite/plugin_final_layout.sh
===================================================================
RCS file: testsuite/plugin_final_layout.sh
diff -N testsuite/plugin_final_layout.sh
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/plugin_final_layout.sh 29 Sep 2011 18:14:22 -0000
@@ -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"
Index: testsuite/plugin_section_order.c
===================================================================
RCS file: testsuite/plugin_section_order.c
diff -N testsuite/plugin_section_order.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/plugin_section_order.c 29 Sep 2011 18:14:22 -0000
@@ -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;
+}
+
More information about the Binutils
mailing list