aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2014-06-01 22:01:44 +0930
committerAlan Modra <amodra@gmail.com>2014-06-02 09:26:23 +0930
commitf697178787b1200fcbea13f6504c108e7714c6bd (patch)
tree51d222d94a0293ad0bff2112ce970fa248b30e6c
parent16954d5d9d7d44356b46864d41b06dbefd867521 (diff)
downloadgdb-f697178787b1200fcbea13f6504c108e7714c6bd.zip
gdb-f697178787b1200fcbea13f6504c108e7714c6bd.tar.gz
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/ChangeLog6
-rw-r--r--gold/powerpc.cc20
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);
}