Gold: Enable safe ICF for shared object on x86-64
authorH.J. Lu <hjl.tools@gmail.com>
Tue, 13 Oct 2020 12:10:24 +0000 (05:10 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Tue, 13 Oct 2020 12:10:36 +0000 (05:10 -0700)
With

commit 4aebb6312eb5dcd12f2f8420028547584b708907
Author: Rahul Chaudhry <rahulchaudhry@google.com>
Date:   Wed Feb 15 00:37:10 2017 -0800

    Improved support for --icf=safe when used with -pie.

we now check opcode with R_X86_64_PC32 relocation, which tell branches
from other instructions.  We can enable safe ICF for shared object on
x86-64.  Also, global symbols with non-default visibility should be
folded like local symbols.

PR gold/21452
* x86_64.cc (Scan::local_reloc_may_be_function_pointer): Remove
check for shared library.
(Scan::global_reloc_may_be_function_pointer): Remove check for
shared library and symbol visibility.
* testsuite/icf_safe_so_test.cc (bar_static): New function.
(main): Take function address of bar_static and use it.
* testsuite/icf_safe_so_test.sh (arch_specific_safe_fold): Also
check fold on x86-64.  Check bar_static isn't folded.

gold/ChangeLog
gold/testsuite/icf_safe_so_test.cc
gold/testsuite/icf_safe_so_test.sh
gold/x86_64.cc

index 0300722c3a6eecbe879afe9f54570d6b06b1f007..5defad4ceeac78cbad6e4d1980e952d2c2eed252 100644 (file)
@@ -1,3 +1,15 @@
+2020-10-13  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR gold/21452
+       * x86_64.cc (Scan::local_reloc_may_be_function_pointer): Remove
+       check for shared library.
+       (Scan::global_reloc_may_be_function_pointer): Remove check for
+       shared library and symbol visibility.
+       * testsuite/icf_safe_so_test.cc (bar_static): New function.
+       (main): Take function address of bar_static and use it.
+       * testsuite/icf_safe_so_test.sh (arch_specific_safe_fold): Also
+       check fold on x86-64.  Check bar_static isn't folded.
+
 2020-10-13  H.J. Lu  <hongjiu.lu@intel.com>
 
        * icf.cc (Icf::find_identical_sections): Skip zero-sized sections.
index 1c593031d05ecf49d47565c7f8eed543e4b63977..3256655327609c47978d11a06eae77f85bd3a0f7 100644 (file)
@@ -61,10 +61,18 @@ int bar_glob()
   return 2;
 }
 
+static int
+bar_static()
+{
+  return 2;
+}
+
 int main()
 {
   int (*p)() = foo_glob;
   (void)p;
+  p = bar_static;
+  (void)p;
   foo_static();
   foo_prot();
   foo_hidden();
index 10f8782d1f5736ea8bfdf4c4adb84500211b9a7c..4c253c55d20d2321fa58c64a762a62303ed81d6c 100755 (executable)
@@ -83,7 +83,7 @@ END {
 
 arch_specific_safe_fold()
 {
-    if grep -q -e "Intel 80386" -e "ARM" -e "PowerPC" $1;
+    if grep -q -e "Advanced Micro Devices X86-64" -e "Intel 80386" -e "ARM" -e "PowerPC" $1;
     then
        shift
        shift
index 1d9d9209bf3ac9721b6fbc21e61136d7e831195e..9cb2cf0a322467e3e7c12cbd43c04097792345e8 100644 (file)
@@ -3992,12 +3992,6 @@ Target_x86_64<size>::Scan::local_reloc_may_be_function_pointer(
   unsigned int r_type,
   const elfcpp::Sym<size, false>&)
 {
-  // When building a shared library, do not fold any local symbols as it is
-  // not possible to distinguish pointer taken versus a call by looking at
-  // the relocation types.
-  if (parameters->options().shared())
-    return true;
-
   return possible_function_pointer_reloc(src_obj, src_indx,
                                          reloc.get_r_offset(), r_type);
 }
@@ -4017,16 +4011,8 @@ Target_x86_64<size>::Scan::global_reloc_may_be_function_pointer(
   Output_section* ,
   const elfcpp::Rela<size, false>& reloc,
   unsigned int r_type,
-  Symbol* gsym)
-{
-  // When building a shared library, do not fold symbols whose visibility
-  // is hidden, internal or protected.
-  if (parameters->options().shared()
-      && (gsym->visibility() == elfcpp::STV_INTERNAL
-         || gsym->visibility() == elfcpp::STV_PROTECTED
-         || gsym->visibility() == elfcpp::STV_HIDDEN))
-    return true;
-
+  Symbol*)
+{
   return possible_function_pointer_reloc(src_obj, src_indx,
                                          reloc.get_r_offset(), r_type);
 }