2010-06-25 Doug Kwan <dougkwan@google.com>
* arm.cc (Target_arm::can_check_for_functions_pointers): Return true. (Target_arm::section_may_have_icf_unsafe_pointers): New method definition. (Target_arm::Scan::local_reloc_may_be_function_pointer, Target_arm::Scan::global_reloc_may_be_function_pointer): Implement target hook to detect function points. (Target_arm::Scan::possible_function_pointer_reloc): New method. * icf.h (Icf::check_section_for_function_pointers): Change type of parameter SECTION_NAME to const reference to std::string. Use target hook to determine if section may have unsafe pointers. * target.h (Target::section_may_have_icf_unsafe_pointers): New method definition.
This commit is contained in:
parent
4f2a93bda2
commit
8a75a161b2
4 changed files with 120 additions and 8 deletions
|
@ -1,3 +1,18 @@
|
|||
2010-06-25 Doug Kwan <dougkwan@google.com>
|
||||
|
||||
* arm.cc (Target_arm::can_check_for_functions_pointers): Return true.
|
||||
(Target_arm::section_may_have_icf_unsafe_pointers): New method
|
||||
definition.
|
||||
(Target_arm::Scan::local_reloc_may_be_function_pointer,
|
||||
Target_arm::Scan::global_reloc_may_be_function_pointer): Implement
|
||||
target hook to detect function points.
|
||||
(Target_arm::Scan::possible_function_pointer_reloc): New method.
|
||||
* icf.h (Icf::check_section_for_function_pointers): Change type of
|
||||
parameter SECTION_NAME to const reference to std::string. Use
|
||||
target hook to determine if section may have unsafe pointers.
|
||||
* target.h (Target::section_may_have_icf_unsafe_pointers): New
|
||||
method definition.
|
||||
|
||||
2010-06-21 Rafael Espindola <espindola@google.com>
|
||||
|
||||
* fileread.cc (Input_file::find_fie): New
|
||||
|
|
92
gold/arm.cc
92
gold/arm.cc
|
@ -2109,6 +2109,23 @@ class Target_arm : public Sized_target<32, big_endian>
|
|||
fix_cortex_a8_(false), cortex_a8_relocs_info_()
|
||||
{ }
|
||||
|
||||
// Virtual function which is set to return true by a target if
|
||||
// it can use relocation types to determine if a function's
|
||||
// pointer is taken.
|
||||
virtual bool
|
||||
can_check_for_function_pointers() const
|
||||
{ return true; }
|
||||
|
||||
// Whether a section called SECTION_NAME may have function pointers to
|
||||
// sections not eligible for safe ICF folding.
|
||||
virtual bool
|
||||
section_may_have_icf_unsafe_pointers(const char* section_name) const
|
||||
{
|
||||
return (!is_prefix_of(".ARM.exidx", section_name)
|
||||
&& !is_prefix_of(".ARM.extab", section_name)
|
||||
&& Target::section_may_have_icf_unsafe_pointers(section_name));
|
||||
}
|
||||
|
||||
// Whether we can use BLX.
|
||||
bool
|
||||
may_use_blx() const
|
||||
|
@ -2474,8 +2491,7 @@ class Target_arm : public Sized_target<32, big_endian>
|
|||
Output_section* ,
|
||||
const elfcpp::Rel<32, big_endian>& ,
|
||||
unsigned int ,
|
||||
const elfcpp::Sym<32, big_endian>&)
|
||||
{ return false; }
|
||||
const elfcpp::Sym<32, big_endian>&);
|
||||
|
||||
inline bool
|
||||
global_reloc_may_be_function_pointer(Symbol_table* , Layout* , Target_arm* ,
|
||||
|
@ -2483,8 +2499,7 @@ class Target_arm : public Sized_target<32, big_endian>
|
|||
unsigned int ,
|
||||
Output_section* ,
|
||||
const elfcpp::Rel<32, big_endian>& ,
|
||||
unsigned int , Symbol*)
|
||||
{ return false; }
|
||||
unsigned int , Symbol*);
|
||||
|
||||
private:
|
||||
static void
|
||||
|
@ -2515,6 +2530,9 @@ class Target_arm : public Sized_target<32, big_endian>
|
|||
|| sym->is_preemptible()));
|
||||
}
|
||||
|
||||
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_;
|
||||
};
|
||||
|
@ -7688,6 +7706,72 @@ Target_arm<big_endian>::Scan::unsupported_reloc_global(
|
|||
object->name().c_str(), r_type, gsym->demangled_name().c_str());
|
||||
}
|
||||
|
||||
template<bool big_endian>
|
||||
inline bool
|
||||
Target_arm<big_endian>::Scan::possible_function_pointer_reloc(
|
||||
unsigned int r_type)
|
||||
{
|
||||
switch (r_type)
|
||||
{
|
||||
case elfcpp::R_ARM_PC24:
|
||||
case elfcpp::R_ARM_THM_CALL:
|
||||
case elfcpp::R_ARM_PLT32:
|
||||
case elfcpp::R_ARM_CALL:
|
||||
case elfcpp::R_ARM_JUMP24:
|
||||
case elfcpp::R_ARM_THM_JUMP24:
|
||||
case elfcpp::R_ARM_SBREL31:
|
||||
case elfcpp::R_ARM_PREL31:
|
||||
case elfcpp::R_ARM_THM_JUMP19:
|
||||
case elfcpp::R_ARM_THM_JUMP6:
|
||||
case elfcpp::R_ARM_THM_JUMP11:
|
||||
case elfcpp::R_ARM_THM_JUMP8:
|
||||
// All the relocations above are branches except SBREL31 and PREL31.
|
||||
return false;
|
||||
|
||||
default:
|
||||
// Be conservative and assume this is a function pointer.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
template<bool big_endian>
|
||||
inline bool
|
||||
Target_arm<big_endian>::Scan::local_reloc_may_be_function_pointer(
|
||||
Symbol_table*,
|
||||
Layout*,
|
||||
Target_arm<big_endian>* target,
|
||||
Sized_relobj<32, big_endian>*,
|
||||
unsigned int,
|
||||
Output_section*,
|
||||
const elfcpp::Rel<32, big_endian>&,
|
||||
unsigned int r_type,
|
||||
const elfcpp::Sym<32, big_endian>&)
|
||||
{
|
||||
r_type = target->get_real_reloc_type(r_type);
|
||||
return possible_function_pointer_reloc(r_type);
|
||||
}
|
||||
|
||||
template<bool big_endian>
|
||||
inline bool
|
||||
Target_arm<big_endian>::Scan::global_reloc_may_be_function_pointer(
|
||||
Symbol_table*,
|
||||
Layout*,
|
||||
Target_arm<big_endian>* target,
|
||||
Sized_relobj<32, big_endian>*,
|
||||
unsigned int,
|
||||
Output_section*,
|
||||
const elfcpp::Rel<32, big_endian>&,
|
||||
unsigned int r_type,
|
||||
Symbol* gsym)
|
||||
{
|
||||
// GOT is not a function.
|
||||
if (strcmp(gsym->name(), "_GLOBAL_OFFSET_TABLE_") == 0)
|
||||
return false;
|
||||
|
||||
r_type = target->get_real_reloc_type(r_type);
|
||||
return possible_function_pointer_reloc(r_type);
|
||||
}
|
||||
|
||||
// Scan a relocation for a global symbol.
|
||||
|
||||
template<bool big_endian>
|
||||
|
|
|
@ -121,14 +121,13 @@ class Icf
|
|||
// corresponding to taken function pointers. Ignores eh_frame
|
||||
// and vtable sections.
|
||||
inline bool
|
||||
check_section_for_function_pointers(std::string section_name,
|
||||
check_section_for_function_pointers(const std::string& section_name,
|
||||
Target* target)
|
||||
{
|
||||
return (parameters->options().icf_safe_folding()
|
||||
&& target->can_check_for_function_pointers()
|
||||
&& !is_prefix_of(".rodata._ZTV", section_name.c_str())
|
||||
&& !is_prefix_of(".data.rel.ro._ZTV", section_name.c_str())
|
||||
&& !is_prefix_of(".eh_frame", section_name.c_str()));
|
||||
&& target->section_may_have_icf_unsafe_pointers(
|
||||
section_name.c_str()));
|
||||
}
|
||||
|
||||
// Returns a map of a section to info (Reloc_info) about its relocations.
|
||||
|
|
|
@ -71,6 +71,20 @@ class Target
|
|||
can_check_for_function_pointers() const
|
||||
{ return false; }
|
||||
|
||||
// Whether a section called SECTION_NAME may have function pointers to
|
||||
// sections not eligible for safe ICF folding.
|
||||
virtual bool
|
||||
section_may_have_icf_unsafe_pointers(const char* section_name) const
|
||||
{
|
||||
// We recognize sections for normal vtables, construction vtables and
|
||||
// EH frames.
|
||||
return (!is_prefix_of(".rodata._ZTV", section_name)
|
||||
&& !is_prefix_of(".data.rel.ro._ZTV", section_name)
|
||||
&& !is_prefix_of(".rodata._ZTC", section_name)
|
||||
&& !is_prefix_of(".data.rel.ro._ZTC", section_name)
|
||||
&& !is_prefix_of(".eh_frame", section_name));
|
||||
}
|
||||
|
||||
// Return the bit size that this target implements. This should
|
||||
// return 32 or 64.
|
||||
int
|
||||
|
|
Loading…
Add table
Reference in a new issue