aboutsummaryrefslogtreecommitdiff
path: root/gold/powerpc.cc
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2013-03-12 22:46:19 +0000
committerAlan Modra <amodra@gmail.com>2013-03-12 22:46:19 +0000
commit4d9aa1551545dd5365d35a0844d3b7a5a35d02f3 (patch)
treea7dca097cb31fbcdcf14394961a242fc5c185850 /gold/powerpc.cc
parent2d450646ca4c6972bf1d2c82c9e4453fd3381339 (diff)
downloadgdb-4d9aa1551545dd5365d35a0844d3b7a5a35d02f3.zip
gdb-4d9aa1551545dd5365d35a0844d3b7a5a35d02f3.tar.gz
gdb-4d9aa1551545dd5365d35a0844d3b7a5a35d02f3.tar.bz2
* powerpc.cc (is_branch_reloc): Forward declare.
(Target_powerpc::do_can_check_for_function_pointers): New predicate. (Target_powerpc::Scan::local_reloc_may_be_function_pointer): Return false for 64-bit, true for 32-bit non-branch relocs. (Target_powerpc::Scan::global_reloc_may_be_function_pointer): Likewise. * testsuite/Makefile.am (icf_test): Use linker map file instead of nm output. (icf_safe_test): Generate linker map file as well as nm output. (icf_safe_so_test): Likewise. * testsuite/Makefile.in: Regenerate. * testsuite/icf_test.sh: Parse linker map file to determine section folding. * testsuite/icf_safe_test.sh: Likewise. Expect folding for PowerPC. * testsuite/icf_safe_so_test.sh: Likewise. (X86_32_or_ARM_specific_safe_fold): Merge into.. (arch_specific_safe_fold): ..this. (X86_64_specific_safe_fold): Delete unused function.
Diffstat (limited to 'gold/powerpc.cc')
-rw-r--r--gold/powerpc.cc33
1 files changed, 27 insertions, 6 deletions
diff --git a/gold/powerpc.cc b/gold/powerpc.cc
index b8ff86d..66109d2 100644
--- a/gold/powerpc.cc
+++ b/gold/powerpc.cc
@@ -62,6 +62,9 @@ class Output_data_glink;
template<int size, bool big_endian>
class Stub_table;
+inline bool
+is_branch_reloc(unsigned int r_type);
+
template<int size, bool big_endian>
class Powerpc_relobj : public Sized_relobj_file<size, big_endian>
{
@@ -555,6 +558,10 @@ class Target_powerpc : public Sized_target<size, big_endian>
void
do_function_location(Symbol_location*) const;
+ bool
+ do_can_check_for_function_pointers() const
+ { return true; }
+
// Relocate a section.
void
relocate_section(const Relocate_info<size, big_endian>*,
@@ -863,9 +870,18 @@ class Target_powerpc : public Sized_target<size, big_endian>
unsigned int ,
Output_section* ,
const elfcpp::Rela<size, big_endian>& ,
- unsigned int ,
+ unsigned int r_type,
const elfcpp::Sym<size, big_endian>&)
- { return false; }
+ {
+ // PowerPC64 .opd is not folded, so any identical function text
+ // 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
+ // function code might be taking the address of the function.
+ return !is_branch_reloc(r_type);
+ }
inline bool
global_reloc_may_be_function_pointer(Symbol_table* , Layout* ,
@@ -873,10 +889,15 @@ class Target_powerpc : public Sized_target<size, big_endian>
Sized_relobj_file<size, big_endian>* ,
unsigned int ,
Output_section* ,
- const elfcpp::Rela<size,
- big_endian>& ,
- unsigned int , Symbol*)
- { return false; }
+ const elfcpp::Rela<size, big_endian>& ,
+ unsigned int r_type,
+ Symbol*)
+ {
+ // As above.
+ if (size == 64)
+ return false;
+ return !is_branch_reloc(r_type);
+ }
private:
static void