diff options
-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); } |