+2016-06-28 Igor Kudrin <ikudrin@accesssoftek.com>
+
+ PR gold/18098
+ * script-c.h (Sort_wildcard): Add SORT_WILDCARD_BY_INIT_PRIORITY.
+ * script-sections.cc (Input_section_sorter::get_init_priority): New method.
+ (Input_section_sorter::operator()): Handle SORT_WILDCARD_BY_INIT_PRIORITY.
+ (Output_section_element_input::print): Likewise.
+ * script.cc (script_keyword_parsecodes): Add entry SORT_BY_INIT_PRIORITY.
+ * yyscript.y (SORT_BY_INIT_PRIORITY): New token.
+ (wildcard_section): Handle SORT_BY_INIT_PRIORITY.
+
+ * testsuite/Makefile.am (script_test_14): New test.
+ * testsuite/Makefile.in: Regenerate.
+ * testsuite/script_test_14.s: New test source file.
+ * testsuite/script_test_14.sh: New test script.
+ * testsuite/script_test_14.t: New test linker script.
+
2016-06-28 James Clarke <jrtc27@jrtc27.com>
* sparc.cc (Target_sparc::Scan::local): Don't convert R_SPARC_32
SORT_WILDCARD_BY_NAME,
SORT_WILDCARD_BY_ALIGNMENT,
SORT_WILDCARD_BY_NAME_BY_ALIGNMENT,
- SORT_WILDCARD_BY_ALIGNMENT_BY_NAME
+ SORT_WILDCARD_BY_ALIGNMENT_BY_NAME,
+ SORT_WILDCARD_BY_INIT_PRIORITY
};
/* The information we build for a single wildcard specification. */
operator()(const Input_section_info&, const Input_section_info&) const;
private:
+ static unsigned long
+ get_init_priority(const char*);
+
Sort_wildcard filename_sort_;
Sort_wildcard section_sort_;
};
+// Return a relative priority of the section with the specified NAME
+// (a lower value meand a higher priority), or 0 if it should be compared
+// with others as strings.
+// The implementation of this function is copied from ld/ldlang.c.
+
+unsigned long
+Input_section_sorter::get_init_priority(const char* name)
+{
+ char* end;
+ unsigned long init_priority;
+
+ // GCC uses the following section names for the init_priority
+ // attribute with numerical values 101 and 65535 inclusive. A
+ // lower value means a higher priority.
+ //
+ // 1: .init_array.NNNN/.fini_array.NNNN: Where NNNN is the
+ // decimal numerical value of the init_priority attribute.
+ // The order of execution in .init_array is forward and
+ // .fini_array is backward.
+ // 2: .ctors.NNNN/.dtors.NNNN: Where NNNN is 65535 minus the
+ // decimal numerical value of the init_priority attribute.
+ // The order of execution in .ctors is backward and .dtors
+ // is forward.
+
+ if (strncmp(name, ".init_array.", 12) == 0
+ || strncmp(name, ".fini_array.", 12) == 0)
+ {
+ init_priority = strtoul(name + 12, &end, 10);
+ return *end ? 0 : init_priority;
+ }
+ else if (strncmp(name, ".ctors.", 7) == 0
+ || strncmp(name, ".dtors.", 7) == 0)
+ {
+ init_priority = strtoul(name + 7, &end, 10);
+ return *end ? 0 : 65535 - init_priority;
+ }
+
+ return 0;
+}
+
bool
Input_section_sorter::operator()(const Input_section_info& isi1,
const Input_section_info& isi2) const
{
+ if (this->section_sort_ == SORT_WILDCARD_BY_INIT_PRIORITY)
+ {
+ unsigned long ip1 = get_init_priority(isi1.section_name().c_str());
+ unsigned long ip2 = get_init_priority(isi2.section_name().c_str());
+ if (ip1 != 0 && ip2 != 0 && ip1 != ip2)
+ return ip1 < ip2;
+ }
if (this->section_sort_ == SORT_WILDCARD_BY_NAME
|| this->section_sort_ == SORT_WILDCARD_BY_NAME_BY_ALIGNMENT
|| (this->section_sort_ == SORT_WILDCARD_BY_ALIGNMENT_BY_NAME
- && isi1.addralign() == isi2.addralign()))
+ && isi1.addralign() == isi2.addralign())
+ || this->section_sort_ == SORT_WILDCARD_BY_INIT_PRIORITY)
{
if (isi1.section_name() != isi2.section_name())
return isi1.section_name() < isi2.section_name();
fprintf(f, "SORT_BY_ALIGNMENT(SORT_BY_NAME(");
close_parens = 2;
break;
+ case SORT_WILDCARD_BY_INIT_PRIORITY:
+ fprintf(f, "SORT_BY_INIT_PRIORITY(");
+ close_parens = 1;
+ break;
default:
gold_unreachable();
}
{ "SIZEOF_HEADERS", SIZEOF_HEADERS },
{ "SORT", SORT_BY_NAME },
{ "SORT_BY_ALIGNMENT", SORT_BY_ALIGNMENT },
+ { "SORT_BY_INIT_PRIORITY", SORT_BY_INIT_PRIORITY },
{ "SORT_BY_NAME", SORT_BY_NAME },
{ "SPECIAL", SPECIAL },
{ "SQUAD", SQUAD },
script_test_12b.o: script_test_12b.c
$(COMPILE) -O0 -c -o $@ $<
+# Test for SORT_BY_INIT_PRIORITY.
+check_SCRIPTS += script_test_14.sh
+check_DATA += script_test_14.stdout
+MOSTLYCLEANFILES += script_test_14
+script_test_14.o: script_test_14.s
+ $(TEST_AS) -o $@ $<
+script_test_14: $(srcdir)/script_test_14.t script_test_14.o gcctestdir/ld
+ gcctestdir/ld -o $@ script_test_14.o -T $(srcdir)/script_test_14.t
+script_test_14.stdout: script_test_14
+ $(TEST_OBJDUMP) -s script_test_14 > $@
+
# Test --dynamic-list, --dynamic-list-data, --dynamic-list-cpp-new,
# and --dynamic-list-cpp-typeinfo
@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_4 script_test_5 \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_6 script_test_7 \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_8 script_test_9 \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ dynamic_list dynamic_list.stdout \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ libthin1.a libthin3.a \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ libthinall.a \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_14 dynamic_list \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ dynamic_list.stdout libthin1.a \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ libthin3.a libthinall.a \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ alt/thin_archive_test_2.o \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ alt/thin_archive_test_4.o \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ alt/libthin2.a alt/libthin4.a
# Similar to --detect-odr-violations: check for undefined symbols in .so's
+# Test for SORT_BY_INIT_PRIORITY.
+
# Test --dynamic-list, --dynamic-list-data, --dynamic-list-cpp-new,
# and --dynamic-list-cpp-typeinfo
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_36 = debug_msg.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_6.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_7.sh \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_8.sh \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_9.sh dynamic_list.sh
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_9.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_14.sh \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ dynamic_list.sh
# Create the data files that debug_msg.sh analyzes.
@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_7.stdout \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_8.stdout \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_9.stdout \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ script_test_14.stdout \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ dynamic_list.stdout
@GCC_FALSE@script_test_1_DEPENDENCIES =
@NATIVE_LINKER_FALSE@script_test_1_DEPENDENCIES =
@p='script_test_8.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
script_test_9.sh.log: script_test_9.sh
@p='script_test_9.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+script_test_14.sh.log: script_test_14.sh
+ @p='script_test_14.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
dynamic_list.sh.log: dynamic_list.sh
@p='dynamic_list.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
plugin_test_1.sh.log: plugin_test_1.sh
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(COMPILE) -O0 -c -o $@ $<
@GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_12b.o: script_test_12b.c
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(COMPILE) -O0 -c -o $@ $<
+@GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_14.o: script_test_14.s
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_AS) -o $@ $<
+@GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_14: $(srcdir)/script_test_14.t script_test_14.o gcctestdir/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir/ld -o $@ script_test_14.o -T $(srcdir)/script_test_14.t
+@GCC_TRUE@@NATIVE_LINKER_TRUE@script_test_14.stdout: script_test_14
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(TEST_OBJDUMP) -s script_test_14 > $@
@GCC_TRUE@@NATIVE_LINKER_TRUE@dynamic_list: basic_test.o gcctestdir/ld $(srcdir)/dynamic_list.t
@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Bgcctestdir/ basic_test.o \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ -Wl,--dynamic-list $(srcdir)/dynamic_list.t \
--- /dev/null
+ .section .init_array.101,"aw"
+ .byte 0x01
+
+ .section .init_array.103,"aw"
+ .byte 0x04
+
+ .section .init_array,"aw"
+ .byte 0x00
+
+ .section .init_array.0103,"aw"
+ .byte 0x03
+
+ .section .fini_array.101,"aw"
+ .byte 0xf1
+
+ .section .fini_array.103,"aw"
+ .byte 0xf4
+
+ .section .fini_array,"aw"
+ .byte 0xf0
+
+ .section .fini_array.0103,"aw"
+ .byte 0xf3
+
+ .section .ctors.101,"aw"
+ .byte 0xc1
+
+ .section .ctors.103, "aw"
+ .byte 0xc4
+
+ .section .ctors,"aw"
+ .byte 0xc0
+
+ .section .ctors.0103,"aw"
+ .byte 0xc3
+
+ .section .dtors.101,"aw"
+ .byte 0xd1
+
+ .section .dtors.103,"aw"
+ .byte 0xd4
+
+ .section .dtors,"aw"
+ .byte 0xd0
+
+ .section .dtors.0103,"aw"
+ .byte 0xd3
+
+ .section .sec.101,"aw"
+ .byte 0xa1
+
+ .section .sec.103,"aw"
+ .byte 0xa4
+
+ .section .sec,"aw"
+ .byte 0xa0
+
+ .section .sec.0103,"aw"
+ .byte 0xa3
--- /dev/null
+#!/bin/sh
+
+# script_test_14.sh -- test SORT_BY_INIT_PRIORITY
+
+# Copyright (C) 2016 Free Software Foundation, Inc.
+# Written by Igor Kudrin <ikudrin@accesssoftek.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.
+
+file="script_test_14.stdout"
+
+check()
+{
+ section=$1
+ pattern=$2
+ found=`fgrep "Contents of section $section:" -A1 $file | tail -n 1`
+ if test -z "$found"; then
+ echo "Section \"$section\" not found in file $file"
+ echo ""
+ echo "Actual output below:"
+ cat "$file"
+ exit 1
+ fi
+ match_pattern=`echo "$found" | grep -e "$pattern"`
+ if test -z "$match_pattern"; then
+ echo "Expected pattern was not found in section \"$section\":"
+ echo " $pattern"
+ echo ""
+ echo "Actual output below:"
+ cat "$file"
+ exit 1
+ fi
+}
+
+# Sort order for .init_array:
+# * .init_array -- Doesn't have a numeric part, compared with others as strings.
+# * .init_array.101 -- The numeric part is less than in the two others.
+# * .init_array.0103 -- These names have numeric parts with the same value,
+# * .init_array.103 / so they are compared as strings.
+check ".init_array" "\<00010304\b"
+
+# Sort order for .fini_array, the same consideration as for .init_array:
+# * .fini_array
+# * .fini_array.101
+# * .fini_array.0103
+# * .fini_array.103
+check ".fini_array" "\<f0f1f3f4\b"
+
+# Sort order for .ctors:
+# * .ctors -- Doesn't have a numeric part, compared with others as strings
+# * .ctors.0103 -- The numeric parts have the same value, which is greater than
+# * .ctors.103 / in the last section's name. This pair is compared as strings.
+# * .ctors.101 -- The least numeric part among all sections which contain them.
+check ".ctors" "\<c0c3c4c1\b"
+
+# Sort order for .dtors, the same considerations as for .ctors:
+# * .dtors
+# * .dtors.0103
+# * .dtors.103
+# * .dtors.101
+check ".dtors" "\<d0d3d4d1\b"
+
+# Sort order for .sec, just sort as strings, because it's not the reserved name:
+# * .sec
+# * .sec.0103
+# * .sec.101
+# * .sec.103
+check ".sec" "\<a0a3a1a4\b"
+
--- /dev/null
+/* script_test_14.t -- test SORT_BY_INIT_PRIORITY.
+
+ Copyright (C) 2016 Free Software Foundation, Inc.
+ Written by Igor Kudrin <ikudrin@accesssoftek.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. */
+
+SECTIONS
+{
+ .init_array : { *(SORT_BY_INIT_PRIORITY(.init_array*)) }
+ .fini_array : { *(SORT_BY_INIT_PRIORITY(.fini_array*)) }
+ .ctors : { *(SORT_BY_INIT_PRIORITY(.ctors*)) }
+ .dtors : { *(SORT_BY_INIT_PRIORITY(.dtors*)) }
+ .sec : { *(SORT_BY_INIT_PRIORITY(.sec*)) }
+}
%token SIZEOF
%token SIZEOF_HEADERS /* SIZEOF_HEADERS, sizeof_headers */
%token SORT_BY_ALIGNMENT
+%token SORT_BY_INIT_PRIORITY
%token SORT_BY_NAME
%token SPECIAL
%token SQUAD
abort();
}
}
+ | SORT_BY_INIT_PRIORITY '(' wildcard_name ')'
+ {
+ $$.name = $3;
+ $$.sort = SORT_WILDCARD_BY_INIT_PRIORITY;
+ }
;
/* A list of file names to exclude. */