diff options
author | Alan Modra <amodra@gmail.com> | 2014-06-01 22:01:44 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2014-06-02 09:26:23 +0930 |
commit | f697178787b1200fcbea13f6504c108e7714c6bd (patch) | |
tree | 51d222d94a0293ad0bff2112ce970fa248b30e6c | |
parent | 16954d5d9d7d44356b46864d41b06dbefd867521 (diff) | |
download | fsf-binutils-gdb-f697178787b1200fcbea13f6504c108e7714c6bd.zip fsf-binutils-gdb-f697178787b1200fcbea13f6504c108e7714c6bd.tar.gz fsf-binutils-gdb-f697178787b1200fcbea13f6504c108e7714c6bd.tar.bz2 |
Fix PowerPC64 ELFv2 icf_safe failures
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.
-rw-r--r-- | gold/ChangeLog | 6 | ||||
-rw-r--r-- | gold/powerpc.cc | 20 |
2 files changed, 21 insertions, 5 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 7b6fa81..b421ad9 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -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. diff --git a/gold/powerpc.cc b/gold/powerpc.cc index e59c319..1078017 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -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); } |