Implement SORT_BY_INIT_PRIORITY.

2016-06-28  Igor Kudrin  <ikudrin@accesssoftek.com>

gold/
	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.
This commit is contained in:
Igor Kudrin 2016-06-28 13:56:05 -07:00 committed by Cary Coutant
parent 9abdce70ac
commit f224a3c590
10 changed files with 283 additions and 6 deletions

View file

@ -1,3 +1,20 @@
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

View file

@ -139,7 +139,8 @@ enum Sort_wildcard
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. */

View file

@ -1524,18 +1524,69 @@ class Input_section_sorter
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();
@ -1827,6 +1878,10 @@ Output_section_element_input::print(FILE* f) const
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();
}

View file

@ -1792,6 +1792,7 @@ script_keyword_parsecodes[] =
{ "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 },

View file

@ -1859,6 +1859,17 @@ script_test_12a.o: script_test_12a.c
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

View file

@ -340,9 +340,9 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
@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
@ -370,6 +370,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
# 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 \
@ -386,7 +388,9 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
@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.
@ -432,6 +436,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
@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 =
@ -4605,6 +4610,8 @@ script_test_8.sh.log: script_test_8.sh
@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
@ -6057,6 +6064,12 @@ uninstall-am:
@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 \

View file

@ -0,0 +1,59 @@
.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

View file

@ -0,0 +1,84 @@
#!/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"

View file

@ -0,0 +1,30 @@
/* 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*)) }
}

View file

@ -175,6 +175,7 @@
%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
@ -677,6 +678,11 @@ wildcard_section:
abort();
}
}
| SORT_BY_INIT_PRIORITY '(' wildcard_name ')'
{
$$.name = $3;
$$.sort = SORT_WILDCARD_BY_INIT_PRIORITY;
}
;
/* A list of file names to exclude. */