Fix PowerPC64 ELFv2 icf_safe failures
authorAlan Modra <amodra@gmail.com>
Sun, 1 Jun 2014 12:31:44 +0000 (22:01 +0930)
committerAlan Modra <amodra@gmail.com>
Sun, 1 Jun 2014 23:56:23 +0000 (09:26 +0930)
ELFv2 doesn't use .opd, so folding function code can't be allowed
in safe mode if a function's address might be taken.

* powerpc.cc (Target_powerpc::local_reloc_may_be_function_pointer):
Only ignore relocs on ELFv1.
(Target_powerpc::global_reloc_may_be_function_pointer): Likewise.

gold/ChangeLog
gold/powerpc.cc

index 7b6fa81..b421ad9 100644 (file)
@@ -1,3 +1,9 @@
+2014-06-02  Alan Modra  <amodra@gmail.com>
+
+       * powerpc.cc (Target_powerpc::local_reloc_may_be_function_pointer):
+       Only ignore relocs on ELFv1.
+       (Target_powerpc::global_reloc_may_be_function_pointer): Likewise.
+
 2014-05-30  Cary Coutant  <ccoutant@google.com>
 
        * testsuite/Makefile.am (ehdr_start_test_4): Fix typo in -B option.
index e59c319..1078017 100644 (file)
@@ -947,7 +947,7 @@ class Target_powerpc : public Sized_target<size, big_endian>
     inline bool
     local_reloc_may_be_function_pointer(Symbol_table* , Layout* ,
                                        Target_powerpc* ,
-                                       Sized_relobj_file<size, big_endian>* ,
+                                       Sized_relobj_file<size, big_endian>* relobj,
                                        unsigned int ,
                                        Output_section* ,
                                        const elfcpp::Rela<size, big_endian>& ,
@@ -958,8 +958,13 @@ class Target_powerpc : public Sized_target<size, big_endian>
       // may be folded and we'll still keep function addresses distinct.
       // That means no reloc is of concern here.
       if (size == 64)
-       return false;
-      // For 32-bit, conservatively assume anything but calls to
+       {
+         Powerpc_relobj<size, big_endian>* ppcobj = static_cast
+           <Powerpc_relobj<size, big_endian>*>(relobj);
+         if (ppcobj->abiversion() == 1)
+           return false;
+       }
+      // For 32-bit and ELFv2, conservatively assume anything but calls to
       // function code might be taking the address of the function.
       return !is_branch_reloc(r_type);
     }
@@ -967,7 +972,7 @@ class Target_powerpc : public Sized_target<size, big_endian>
     inline bool
     global_reloc_may_be_function_pointer(Symbol_table* , Layout* ,
                                         Target_powerpc* ,
-                                        Sized_relobj_file<size, big_endian>* ,
+                                        Sized_relobj_file<size, big_endian>* relobj,
                                         unsigned int ,
                                         Output_section* ,
                                         const elfcpp::Rela<size, big_endian>& ,
@@ -976,7 +981,12 @@ class Target_powerpc : public Sized_target<size, big_endian>
     {
       // As above.
       if (size == 64)
-       return false;
+       {
+         Powerpc_relobj<size, big_endian>* ppcobj = static_cast
+           <Powerpc_relobj<size, big_endian>*>(relobj);
+         if (ppcobj->abiversion() == 1)
+           return false;
+       }
       return !is_branch_reloc(r_type);
     }