[PATCH][GOLD] Allow a target to fix up output section flags.

Doug Kwan (關振德) dougkwan@google.com
Tue Apr 5 07:54:00 GMT 2011


Hi Ian,

    This patch adds code to allow a target to fix up some flags in an
output section header.  We need this for ARM's EXIDX section, which is
required to have SHF_LINK_ORDER set.  We currently do not handle that
flag correctly in layout, it would be desirable to fix that in the
long run.  I have tested this for both ARM and X86_64 and I also added
a new test case.

-Doug

2011-04-05  Doug Kwan  <dougkwan@google.com>

        * arm.cc (Target_arm::do_adjust_output_section_flags): New
        method definition.
        * output.cc (Output_section::write_header): Allow a target to adjust
        output section flags.
        * target.h (Target::adjust_output_section_flags): New method definition.
        (Target::do_adjust_output_section_flags): Same.
        * testsuite/Makefile.am (arm_exidx_test): New test rules.
        * testsuite/Makefile.in: Regenerate.
        * testsuite/arm_exidx_test.s: New file.
        * testsuite/arm_exidx_test.sh: Same.
-------------- next part --------------
Index: gold/arm.cc
===================================================================
RCS file: /cvs/src/src/gold/arm.cc,v
retrieving revision 1.130
diff -u -u -p -r1.130 arm.cc
--- gold/arm.cc	14 Dec 2010 19:03:29 -0000	1.130
+++ gold/arm.cc	5 Apr 2011 07:46:55 -0000
@@ -2547,6 +2547,16 @@ class Target_arm : public Sized_target<3
     arm_reloc_property_table = new Arm_reloc_property_table();
   }
 
+  // We need to set SHF_LINK flag for an EXIDX section always.
+  elfcpp::Elf_Xword
+  do_adjust_output_section_flags(elfcpp::Elf_Word type,
+				 elfcpp::Elf_Xword flags) const
+  {
+    return (type == elfcpp::SHT_ARM_EXIDX
+            ? flags | elfcpp::SHF_LINK_ORDER
+            : flags);
+  }
+
  private:
   // The class which scans relocations.
   class Scan
Index: gold/output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.140
diff -u -u -p -r1.140 output.cc
--- gold/output.cc	12 Feb 2011 03:19:24 -0000	1.140
+++ gold/output.cc	5 Apr 2011 07:46:55 -0000
@@ -3115,6 +3115,12 @@ Output_section::write_header(const Layou
   elfcpp::Elf_Xword flags = this->flags_;
   if (this->info_section_ != NULL && this->info_uses_section_index_)
     flags |= elfcpp::SHF_INFO_LINK;
+
+  // Some targets may need to adjust the output section flags.  Currently
+  // only the ARM target does it because we do not handle SHF_LINK_ORDER
+  // properly.
+  flags = parameters->target().adjust_output_section_flags(this->type_, flags);
+
   oshdr->put_sh_flags(flags);
 
   oshdr->put_sh_addr(this->address());
Index: gold/target.h
===================================================================
RCS file: /cvs/src/src/gold/target.h,v
retrieving revision 1.54
diff -u -u -p -r1.54 target.h
--- gold/target.h	14 Dec 2010 19:03:30 -0000	1.54
+++ gold/target.h	5 Apr 2011 07:46:55 -0000
@@ -381,6 +381,12 @@ class Target
   select_as_default_target()
   { this->do_select_as_default_target(); } 
 
+  // Some targets may need to adjust output section flags.
+  elfcpp::Elf_Xword
+  adjust_output_section_flags(elfcpp::Elf_Word type,
+			      elfcpp::Elf_Xword flags) const
+  { return this->do_adjust_output_section_flags(type, flags); }
+
  protected:
   // This struct holds the constant information for a child class.  We
   // use a struct to avoid the overhead of virtual function calls for
@@ -587,6 +593,12 @@ class Target
   do_select_as_default_target()
   { }
 
+  // This may be overridden by the child class.
+  virtual elfcpp::Elf_Xword
+  do_adjust_output_section_flags(elfcpp::Elf_Word,
+				 elfcpp::Elf_Xword flags) const
+  {  return flags; }
+
  private:
   // The implementations of the four do_make_elf_object virtual functions are
   // almost identical except for their sizes and endianness.  We use a template.
Index: gold/testsuite/Makefile.am
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.am,v
retrieving revision 1.156
diff -u -u -p -r1.156 Makefile.am
--- gold/testsuite/Makefile.am	25 Mar 2011 22:58:49 -0000	1.156
+++ gold/testsuite/Makefile.am	5 Apr 2011 07:46:55 -0000
@@ -2164,6 +2164,20 @@ arm_cortex_a8_local_reloc.o: arm_cortex_
 MOSTLYCLEANFILES += arm_cortex_a8_b_cond arm_cortex_a8_b arm_cortex_a8_bl \
 	arm_cortex_a8_blx arm_cortex_a8_local arm_cortex_a8_local_reloc
 
+check_SCRIPTS += arm_exidx_test.sh
+check_DATA += arm_exidx_test.stdout
+
+arm_exidx_test.stdout: arm_exidx_test.so
+	$(TEST_READELF) -S $< > $@
+
+arm_exidx_test.so: arm_exidx_test.o ../ld-new
+	../ld-new -shared -o $@ $<
+
+arm_exidx_test.o: arm_exidx_test.s
+	$(TEST_AS) -o $@ $<
+
+MOSTLYCLEANFILES += arm_exidx_test.so
+
 endif DEFAULT_TARGET_ARM
 
 endif NATIVE_OR_CROSS_LINKER
Index: gold/testsuite/Makefile.in
===================================================================
RCS file: /cvs/src/src/gold/testsuite/Makefile.in,v
retrieving revision 1.165
diff -u -u -p -r1.165 Makefile.in
--- gold/testsuite/Makefile.in	25 Mar 2011 22:58:49 -0000	1.165
+++ gold/testsuite/Makefile.in	5 Apr 2011 07:46:55 -0000
@@ -459,7 +459,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__E
 @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_branch_out_of_range.sh \
 @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_fix_v4bx.sh \
 @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_attr_merge.sh \
-@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_cortex_a8.sh
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_cortex_a8.sh \
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_exidx_test.sh
 @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_44 = arm_abs_global.stdout \
 @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_bl_in_range.stdout \
 @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_bl_out_of_range.stdout \
@@ -483,7 +484,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__E
 @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_cortex_a8_bl.stdout \
 @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_cortex_a8_blx.stdout \
 @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_cortex_a8_local.stdout \
-@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_cortex_a8_local_reloc.stdout
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_cortex_a8_local_reloc.stdout \
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_exidx_test.stdout
 @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_45 = arm_abs_global \
 @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_bl_in_range \
 @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_bl_out_of_range \
@@ -507,7 +509,8 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__E
 @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_cortex_a8_bl \
 @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_cortex_a8_blx \
 @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_cortex_a8_local \
-@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_cortex_a8_local_reloc
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_cortex_a8_local_reloc \
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	arm_exidx_test.so
 subdir = testsuite
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -3316,6 +3319,8 @@ arm_attr_merge.sh.log: arm_attr_merge.sh
 	@p='arm_attr_merge.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 arm_cortex_a8.sh.log: arm_cortex_a8.sh
 	@p='arm_cortex_a8.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
+arm_exidx_test.sh.log: arm_exidx_test.sh
+	@p='arm_exidx_test.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 object_unittest.log: object_unittest$(EXEEXT)
 	@p='object_unittest$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
 binary_unittest.log: binary_unittest$(EXEEXT)
@@ -4790,6 +4795,15 @@ uninstall-am:
 @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@arm_cortex_a8_local_reloc.o: arm_cortex_a8_local_reloc.s
 @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	$(TEST_AS) -o $@ $<
 
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@arm_exidx_test.stdout: arm_exidx_test.so
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	$(TEST_READELF) -S $< > $@
+
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@arm_exidx_test.so: arm_exidx_test.o ../ld-new
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	../ld-new -shared -o $@ $<
+
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@arm_exidx_test.o: arm_exidx_test.s
+@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@	$(TEST_AS) -o $@ $<
+
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
Index: gold/testsuite/arm_exidx_test.s
===================================================================
RCS file: gold/testsuite/arm_exidx_test.s
diff -N gold/testsuite/arm_exidx_test.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gold/testsuite/arm_exidx_test.s	5 Apr 2011 07:46:55 -0000
@@ -0,0 +1,12 @@
+	.syntax unified	
+	.arch	armv5te
+	.text
+	.align	2
+	.global	answer
+	.type	answer, %function
+answer:
+	.fnstart
+	mov	r0, #42
+	bx	lr
+	.fnend
+	.size	answer, .-answer
Index: gold/testsuite/arm_exidx_test.sh
===================================================================
RCS file: gold/testsuite/arm_exidx_test.sh
diff -N gold/testsuite/arm_exidx_test.sh
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gold/testsuite/arm_exidx_test.sh	5 Apr 2011 07:46:55 -0000
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+# arm_exidx_test.sh -- a test case for .ARM.exidx section.
+
+# Copyright 2011 Free Software Foundation, Inc.
+# Written by Doug Kwan <dougkwan@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.
+
+# This file goes with arm_exidx_test.s, an ARM assembly source file constructed
+# to test handling of .ARM.exidx and .ARM.extab sections.
+
+check()
+{
+    if ! grep -q "$2" "$1"
+    then
+	echo "Did not find section header in $1:"
+	echo "   $2"
+	echo ""
+	echo "Actual headers below:"
+	cat "$1"
+	exit 1
+    fi
+}
+
+# Check that SHF_LINK_ORDER is set.
+check arm_exidx_test.stdout ".* .ARM.exidx .* ARM_EXIDX .* AL .*"
+check arm_exidx_test.stdout ".* .ARM.extab .* PROGBITS .* A .*"
+
+exit 0


More information about the Binutils mailing list