diff options
author | Sriraman Tallam <tmsriram@google.com> | 2010-02-13 02:04:21 +0000 |
---|---|---|
committer | Sriraman Tallam <tmsriram@google.com> | 2010-02-13 02:04:21 +0000 |
commit | 21bb3914d64c5fb946423572fe895d2a08531030 (patch) | |
tree | e54ee31d83ccdcab0f5d392c6e1d1a683809b98d /gold/x86_64.cc | |
parent | 6076632b700e20fbb180fd582ed892ed3d0c2d91 (diff) | |
download | gdb-21bb3914d64c5fb946423572fe895d2a08531030.zip gdb-21bb3914d64c5fb946423572fe895d2a08531030.tar.gz gdb-21bb3914d64c5fb946423572fe895d2a08531030.tar.bz2 |
2010-02-12 Sriraman Tallam <tmsriram@google.com>
* arm.cc (Scan::local_reloc_may_be_function_pointer): New function.
(Scan::global_reloc_may_be_function_pointer): New function.
* sparc.cc (Scan::local_reloc_may_be_function_pointer): New function.
(Scan::global_reloc_may_be_function_pointer): New function.
* powerpc.cc (Scan::local_reloc_may_be_function_pointer): New function.
(Scan::global_reloc_may_be_function_pointer): New function.
* i386.cc (Scan::local_reloc_may_be_function_pointer): New function.
(Scan::global_reloc_may_be_function_pointer): New function.
* x86_64.cc (Scan::local_reloc_may_be_function_pointer): New function.
(Scan::global_reloc_may_be_function_pointer): New function.
(Scan::possible_function_pointer_reloc): New function.
(Target_x86_64::can_check_for_function_pointers): New function.
* gc.h (gc_process_relocs): Scan relocation types to determine if
function pointers were taken for targets that support it.
* icf.cc (Icf::find_identical_sections): Include functions for
folding in safe ICF whose pointer is not taken.
* icf.h (Secn_fptr_taken_set): New typedef.
(fptr_section_id_): New member.
(section_has_function_pointers): New function.
(set_section_has_function_pointers): New function.
(check_section_for_function_pointers): New function.
* options.h: Fix comment for safe ICF option.
* target.h (can_check_for_function_pointers): New function.
* testsuite/Makefile.am: Add icf_safe_so_test test case.
Modify icf_safe_test for X86-64.
* testsuite/Makefile.in: Regenerate.
* testsuite/icf_safe_so_test.cc: New file.
* testsuite/icf_safe_so_test.sh: New file.
* testsuite/icf_safe_test.cc (kept_func_3): New function.
(main): Change to take pointer to function kept_func_3.
* testsuite/icf_safe_test.sh (arch_specific_safe_fold): Check if safe
folding is done correctly for X86-64.
Diffstat (limited to 'gold/x86_64.cc')
-rw-r--r-- | gold/x86_64.cc | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/gold/x86_64.cc b/gold/x86_64.cc index 802d498..e9dd5ae 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -39,6 +39,7 @@ #include "tls.h" #include "freebsd.h" #include "gc.h" +#include "icf.h" namespace { @@ -69,6 +70,16 @@ class Target_x86_64 : public Target_freebsd<64, false> tls_base_symbol_defined_(false) { } + // This function should be defined in targets that can use relocation + // types to determine (implemented in local_reloc_may_be_function_pointer + // and global_reloc_may_be_function_pointer) + // if a function's pointer is taken. ICF uses this in safe mode to only + // fold those functions whose pointer is defintely not taken. For x86_64 + // pie binaries, safe ICF cannot be done by looking at relocation types. + inline bool + can_check_for_function_pointers() const + { return !parameters->options().pie(); } + // Hook for a new output section. void do_new_output_section(Output_section*) const; @@ -224,6 +235,26 @@ class Target_x86_64 : public Target_freebsd<64, false> const elfcpp::Rela<64, false>& reloc, unsigned int r_type, Symbol* gsym); + inline bool + local_reloc_may_be_function_pointer(Symbol_table* symtab, Layout* layout, + Target_x86_64* target, + Sized_relobj<64, false>* object, + unsigned int data_shndx, + Output_section* output_section, + const elfcpp::Rela<64, false>& reloc, + unsigned int r_type, + const elfcpp::Sym<64, false>& lsym); + + inline bool + global_reloc_may_be_function_pointer(Symbol_table* symtab, Layout* layout, + Target_x86_64* target, + Sized_relobj<64, false>* object, + unsigned int data_shndx, + Output_section* output_section, + const elfcpp::Rela<64, false>& reloc, + unsigned int r_type, + Symbol* gsym); + private: static void unsupported_reloc_local(Sized_relobj<64, false>*, unsigned int r_type); @@ -235,6 +266,9 @@ class Target_x86_64 : public Target_freebsd<64, false> void check_non_pic(Relobj*, unsigned int r_type); + inline bool + possible_function_pointer_reloc(unsigned int r_type); + // Whether we have issued an error about a non-PIC compilation. bool issued_non_pic_error_; }; @@ -1364,6 +1398,76 @@ Target_x86_64::Scan::unsupported_reloc_global(Sized_relobj<64, false>* object, object->name().c_str(), r_type, gsym->demangled_name().c_str()); } +// Returns true if this relocation type could be that of a function pointer +// only if the target is not position-independent code. +inline bool +Target_x86_64::Scan::possible_function_pointer_reloc(unsigned int r_type) +{ + if (parameters->options().shared()) + return false; + + switch (r_type) + { + case elfcpp::R_X86_64_64: + case elfcpp::R_X86_64_32: + case elfcpp::R_X86_64_32S: + case elfcpp::R_X86_64_16: + case elfcpp::R_X86_64_8: + { + return true; + } + } + return false; +} + +// For safe ICF, scan a relocation for a local symbol to check if it +// corresponds to a function pointer being taken. In that case mark +// the function whose pointer was taken as not foldable. + +inline bool +Target_x86_64::Scan::local_reloc_may_be_function_pointer( + Symbol_table* , + Layout* , + Target_x86_64* , + Sized_relobj<64, false>* , + unsigned int , + Output_section* , + const elfcpp::Rela<64, false>& , + unsigned int r_type, + const elfcpp::Sym<64, false>&) +{ + // When building a shared library, do not fold any local symbols as it is + // not possible to distinguish pointer taken versus a call by looking at + // the relocation types. + return (parameters->options().shared() + || possible_function_pointer_reloc(r_type)); +} + +// For safe ICF, scan a relocation for a global symbol to check if it +// corresponds to a function pointer being taken. In that case mark +// the function whose pointer was taken as not foldable. + +inline bool +Target_x86_64::Scan::global_reloc_may_be_function_pointer( + Symbol_table*, + Layout* , + Target_x86_64* , + Sized_relobj<64, false>* , + unsigned int , + Output_section* , + const elfcpp::Rela<64, false>& , + unsigned int r_type, + Symbol* gsym) +{ + // When building a shared library, do not fold symbols whose visibility + // is hidden, internal or protected. + return ((parameters->options().shared() + && (gsym->visibility() == elfcpp::STV_INTERNAL + || gsym->visibility() == elfcpp::STV_PROTECTED + || gsym->visibility() == elfcpp::STV_HIDDEN)) + || possible_function_pointer_reloc(r_type)); +} + // Scan a relocation for a global symbol. inline void |