2012-03-19 Doug Kwan <dougkwan@google.com>
authorDoug Kwan <dougkwan@google.com>
Mon, 19 Mar 2012 23:54:07 +0000 (23:54 +0000)
committerDoug Kwan <dougkwan@google.com>
Mon, 19 Mar 2012 23:54:07 +0000 (23:54 +0000)
* arm.cc (Target_arm::do_define_standard_symbols): New method.
  (Target_arm::do_finalize_sections): Remove code which defines
__exidx_start and __exidx_end.  Make symbol table parameter
anonymous as it is not used.
* gold.cc (queue_middle_tasks): Call target hook to define any
target-specific symbols.
* target.h (Target::define_standard_symbols): New method.
(Target::do_define_standard_symbols): Same.
* testsuite/Makefile.am (arm_exidx_test): Dump relocations also.
* testsuite/Makefile.in: Regenerate.
* testsuite/arm_exidx.s: Generate data relocations for __exidx_start
and __exidx_end.
* testsuite/arm_exidx_test.sh: Check that no unused dynamic
relocations are generated for __exidx_start and __exidx_end.

gold/ChangeLog
gold/arm.cc
gold/gold.cc
gold/target.h
gold/testsuite/Makefile.am
gold/testsuite/Makefile.in
gold/testsuite/arm_exidx_test.s
gold/testsuite/arm_exidx_test.sh

index adcd6479ef75831fc0c67bf89cd983046084f304..e2515707ac5f1fca7ac39a2f0b6199f5c498d11d 100644 (file)
@@ -1,3 +1,20 @@
+2012-03-19  Doug Kwan  <dougkwan@google.com>
+
+       * arm.cc (Target_arm::do_define_standard_symbols): New method.
+       (Target_arm::do_finalize_sections): Remove code which defines
+       __exidx_start and __exidx_end.  Make symbol table parameter
+       anonymous as it is not used.
+       * gold.cc (queue_middle_tasks): Call target hook to define any
+       target-specific symbols.
+       * target.h (Target::define_standard_symbols): New method.
+       (Target::do_define_standard_symbols): Same.
+       * testsuite/Makefile.am (arm_exidx_test): Dump relocations also.
+       * testsuite/Makefile.in: Regenerate.
+       * testsuite/arm_exidx.s: Generate data relocations for __exidx_start
+       and __exidx_end.
+       * testsuite/arm_exidx_test.sh: Check that no unused dynamic
+       relocations are generated for __exidx_start and __exidx_end.
+
 2012-03-16  Doug Kwan  <dougkwan@google.com>
 
        * testsuite/Makefile.am: Disable test initpri3b.
index 32a4638e430ce2249c518ebb8f4f4d2320768ddc..dc6e64a742e6e0630a2c4bd75aa3c86586b02584 100644 (file)
@@ -2515,6 +2515,9 @@ class Target_arm : public Sized_target<32, big_endian>
            && Target::do_section_may_have_icf_unsafe_pointers(section_name));
   }
   
+  virtual void
+  do_define_standard_symbols(Symbol_table*, Layout*);
+
  private:
   // The class which scans relocations.
   class Scan
@@ -8535,7 +8538,7 @@ void
 Target_arm<big_endian>::do_finalize_sections(
     Layout* layout,
     const Input_objects* input_objects,
-    Symbol_table* symtab)
+    Symbol_table*)
 {
   bool merged_any_attributes = false;
   // Merge processor-specific flags.
@@ -8622,18 +8625,6 @@ Target_arm<big_endian>::do_finalize_sections(
       if (exidx_section != NULL
           && exidx_section->type() == elfcpp::SHT_ARM_EXIDX)
         {
-          // Create __exidx_start and __exidx_end symbols.
-          symtab->define_in_output_data("__exidx_start", NULL,
-                                        Symbol_table::PREDEFINED,
-                                        exidx_section, 0, 0, elfcpp::STT_OBJECT,
-                                        elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN,
-                                        0, false, true);
-          symtab->define_in_output_data("__exidx_end", NULL,
-                                        Symbol_table::PREDEFINED,
-                                        exidx_section, 0, 0, elfcpp::STT_OBJECT,
-                                        elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN,
-                                        0, true, true);
-
           // For the ARM target, we need to add a PT_ARM_EXIDX segment for
           // the .ARM.exidx section.
           if (!layout->script_options()->saw_phdrs_clause())
@@ -8647,19 +8638,6 @@ Target_arm<big_endian>::do_finalize_sections(
                                                            elfcpp::PF_R);
             }
         }
-      else
-        {
-          symtab->define_as_constant("__exidx_start", NULL,
-                                     Symbol_table::PREDEFINED,
-                                     0, 0, elfcpp::STT_OBJECT,
-                                     elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN, 0,
-                                     true, false);
-          symtab->define_as_constant("__exidx_end", NULL,
-                                     Symbol_table::PREDEFINED,
-                                     0, 0, elfcpp::STT_OBJECT,
-                                     elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN, 0,
-                                     true, false);
-        }
     }
 
   // Create an .ARM.attributes section if we have merged any attributes
@@ -11947,6 +11925,61 @@ Target_arm<big_endian>::fix_exidx_coverage(
                                    merge_exidx_entries(), task);
 }
 
+template<bool big_endian>
+void
+Target_arm<big_endian>::do_define_standard_symbols(
+    Symbol_table* symtab,
+    Layout* layout)
+{
+  // Handle the .ARM.exidx section.
+  Output_section* exidx_section = layout->find_output_section(".ARM.exidx");
+
+  if (exidx_section != NULL)
+    {
+      // Create __exidx_start and __exidx_end symbols.
+      symtab->define_in_output_data("__exidx_start",
+                                   NULL, // version
+                                   Symbol_table::PREDEFINED,
+                                   exidx_section,
+                                   0, // value
+                                   0, // symsize
+                                   elfcpp::STT_NOTYPE,
+                                   elfcpp::STB_GLOBAL,
+                                   elfcpp::STV_HIDDEN,
+                                   0, // nonvis
+                                   false, // offset_is_from_end
+                                   true); // only_if_ref
+
+      symtab->define_in_output_data("__exidx_end",
+                                   NULL, // version
+                                   Symbol_table::PREDEFINED,
+                                   exidx_section,
+                                   0, // value
+                                   0, // symsize
+                                   elfcpp::STT_NOTYPE,
+                                   elfcpp::STB_GLOBAL,
+                                   elfcpp::STV_HIDDEN,
+                                   0, // nonvis
+                                   true, // offset_is_from_end
+                                   true); // only_if_ref
+    }
+  else
+    {
+      // Define __exidx_start and __exidx_end even when .ARM.exidx
+      // section is missing to match ld's behaviour.
+      symtab->define_as_constant("__exidx_start", NULL,
+                                 Symbol_table::PREDEFINED,
+                                 0, 0, elfcpp::STT_OBJECT,
+                                 elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN, 0,
+                                 true, false);
+      symtab->define_as_constant("__exidx_end", NULL,
+                                 Symbol_table::PREDEFINED,
+                                 0, 0, elfcpp::STT_OBJECT,
+                                 elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN, 0,
+                                 true, false);
+    }
+}
+
 Target_selector_arm<false> target_selector_arm;
 Target_selector_arm<true> target_selector_armbe;
 
index f455ec8a4121142dfade4c8ca677f88423e675ec..f810bf913ba00fc7bdce210c3f00f1ac0819a2c4 100644 (file)
@@ -679,6 +679,8 @@ queue_middle_tasks(const General_options& options,
   // Attach sections to segments.
   layout->attach_sections_to_segments();
 
+  // TODO(csilvers): figure out a more principled way to get the target
+  Target* target = const_cast<Target*>(&parameters->target());
   if (!parameters->options().relocatable())
     {
       // Predefine standard symbols.
@@ -687,6 +689,9 @@ queue_middle_tasks(const General_options& options,
       // Define __start and __stop symbols for output sections where
       // appropriate.
       layout->define_section_symbols(symtab);
+
+      // Define target-specific symbols.
+      target->define_standard_symbols(symtab, layout);
     }
 
   // Make sure we have symbols for any required group signatures.
@@ -768,8 +773,6 @@ queue_middle_tasks(const General_options& options,
 
   // When all those tasks are complete, we can start laying out the
   // output file.
-  // TODO(csilvers): figure out a more principled way to get the target
-  Target* target = const_cast<Target*>(&parameters->target());
   workqueue->queue(new Task_function(new Layout_task_runner(options,
                                                            input_objects,
                                                            symtab,
index 10354273d2965d145862bf52e9b89bb7afbf7e28..ff97abaeb95a7c98e4e07285c28bfd04b9e14d16 100644 (file)
@@ -396,6 +396,11 @@ class Target
   set_osabi(elfcpp::ELFOSABI osabi)
   { this->osabi_ = osabi; }
 
+  // Define target-specific standard symbols.
+  void
+  define_standard_symbols(Symbol_table* symtab, Layout* layout)
+  { this->do_define_standard_symbols(symtab, layout); }
+
  protected:
   // This struct holds the constant information for a child class.  We
   // use a struct to avoid the overhead of virtual function calls for
@@ -629,6 +634,11 @@ class Target
   do_select_as_default_target()
   { }
 
+  // This may be overridden by the child class.
+  virtual void
+  do_define_standard_symbols(Symbol_table*, Layout*)
+  { }
+
  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 a14dd3eb0c65b412b895f6aad4bc1b9ab586161b..a7fd06d79c944485d684c9e6a09939c63e0e874d 100644 (file)
@@ -2505,7 +2505,7 @@ check_SCRIPTS += arm_exidx_test.sh
 check_DATA += arm_exidx_test.stdout
 
 arm_exidx_test.stdout: arm_exidx_test.so
-       $(TEST_READELF) -S $< > $@
+       $(TEST_READELF) -Sr $< > $@
 
 arm_exidx_test.so: arm_exidx_test.o ../ld-new
        ../ld-new -shared -o $@ $<
index 737907121ba43f714745e90303d878f641d1e48c..251bdceb9b1075828be41564998b18832d9351cb 100644 (file)
@@ -5463,7 +5463,7 @@ uninstall-am:
 @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@ $(TEST_READELF) -Sr $< > $@
 
 @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 $@ $<
index 14dcc9414f8536e740ae412ee33b9d8274bdde51..8e550e4e7b4a08114acfc032f97b4495cd09abc0 100644 (file)
@@ -23,3 +23,9 @@ empty:
         .fnend
         .size   empty, .-empty
 
+# Check that no dynamic relocations for __exidx_start and __exidx_stop
+# generated.
+       .data
+       .align  12
+       .word   __exidx_start(got)
+       .word   __exidx_end(got)
index f732a68dd704710bbcf85563f7fee734ab079b1e..e196f122df27a4469bbaeaf62ff86fb443eb41b0 100755 (executable)
@@ -29,10 +29,23 @@ check()
 {
     if ! grep -q "$2" "$1"
     then
-       echo "Did not find section header in $1:"
+       echo "Did not find expected output in $1:"
        echo "   $2"
        echo ""
-       echo "Actual headers below:"
+       echo "Actual output below:"
+       cat "$1"
+       exit 1
+    fi
+}
+
+check_not()
+{
+    if grep -q "$2" "$1"
+    then
+       echo "Found unexpected output in $1:"
+       echo "   $2"
+       echo ""
+       echo "Actual output below:"
        cat "$1"
        exit 1
     fi
@@ -41,5 +54,7 @@ check()
 # 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 .*"
+check_not arm_exidx_test.stdout ".* .* R_ARM_GLOB_DAT .* __exidx_start"
+check_not arm_exidx_test.stdout ".* .* R_ARM_GLOB_DAT .* __exidx_end"
 
 exit 0