This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Implement SORT_BY_INIT_PRIORITY.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=f224a3c59068fc8060c261d329f54bdc7374d63a

commit f224a3c59068fc8060c261d329f54bdc7374d63a
Author: Igor Kudrin <ikudrin@accesssoftek.com>
Date:   Tue Jun 28 13:56:05 2016 -0700

    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.

Diff:
---
 gold/ChangeLog                   | 17 ++++++++
 gold/script-c.h                  |  3 +-
 gold/script-sections.cc          | 57 ++++++++++++++++++++++++++-
 gold/script.cc                   |  1 +
 gold/testsuite/Makefile.am       | 11 ++++++
 gold/testsuite/Makefile.in       | 21 ++++++++--
 gold/testsuite/script_test_14.s  | 59 ++++++++++++++++++++++++++++
 gold/testsuite/script_test_14.sh | 84 ++++++++++++++++++++++++++++++++++++++++
 gold/testsuite/script_test_14.t  | 30 ++++++++++++++
 gold/yyscript.y                  |  6 +++
 10 files changed, 283 insertions(+), 6 deletions(-)

diff --git a/gold/ChangeLog b/gold/ChangeLog
index 1a52b85..1883cc3 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -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
diff --git a/gold/script-c.h b/gold/script-c.h
index b6ca932..478cf25 100644
--- a/gold/script-c.h
+++ b/gold/script-c.h
@@ -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.  */
diff --git a/gold/script-sections.cc b/gold/script-sections.cc
index ef82953..96c68de 100644
--- a/gold/script-sections.cc
+++ b/gold/script-sections.cc
@@ -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();
 	    }
diff --git a/gold/script.cc b/gold/script.cc
index f2ac3f7..d6aa7b2 100644
--- a/gold/script.cc
+++ b/gold/script.cc
@@ -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 },
diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am
index 01cae9f..9e232e9 100644
--- a/gold/testsuite/Makefile.am
+++ b/gold/testsuite/Makefile.am
@@ -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
 
diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in
index 3771f79..5b66c9c 100644
--- a/gold/testsuite/Makefile.in
+++ b/gold/testsuite/Makefile.in
@@ -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 \
diff --git a/gold/testsuite/script_test_14.s b/gold/testsuite/script_test_14.s
new file mode 100644
index 0000000..7fbe895
--- /dev/null
+++ b/gold/testsuite/script_test_14.s
@@ -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
diff --git a/gold/testsuite/script_test_14.sh b/gold/testsuite/script_test_14.sh
new file mode 100644
index 0000000..b780027
--- /dev/null
+++ b/gold/testsuite/script_test_14.sh
@@ -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"
+
diff --git a/gold/testsuite/script_test_14.t b/gold/testsuite/script_test_14.t
new file mode 100644
index 0000000..c068be3
--- /dev/null
+++ b/gold/testsuite/script_test_14.t
@@ -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*)) }
+}
diff --git a/gold/yyscript.y b/gold/yyscript.y
index 4f3fa50..7e6bd27 100644
--- a/gold/yyscript.y
+++ b/gold/yyscript.y
@@ -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.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]