diff options
author | Doug Kwan <dougkwan@google.com> | 2012-03-19 23:54:07 +0000 |
---|---|---|
committer | Doug Kwan <dougkwan@google.com> | 2012-03-19 23:54:07 +0000 |
commit | 647f15745ab30d29fbcd8fb56ffba69f8b545886 (patch) | |
tree | b0e4404eda01fbb8bb1c625a0b9171708c05fb63 /gold/arm.cc | |
parent | e918b09c1c4dd627527cbc0ab429ecdef16d3545 (diff) | |
download | gdb-647f15745ab30d29fbcd8fb56ffba69f8b545886.zip gdb-647f15745ab30d29fbcd8fb56ffba69f8b545886.tar.gz gdb-647f15745ab30d29fbcd8fb56ffba69f8b545886.tar.bz2 |
2012-03-19 Doug Kwan <dougkwan@google.com>
* arm.cc (Target_arm::do_define_standard_symbols): New method.
(Target_arm::do_finalize_sections): Remove code which defines
__exidx_start and __exidx_end. Make symbol table parameter
anonymous as it is not used.
* gold.cc (queue_middle_tasks): Call target hook to define any
target-specific symbols.
* target.h (Target::define_standard_symbols): New method.
(Target::do_define_standard_symbols): Same.
* testsuite/Makefile.am (arm_exidx_test): Dump relocations also.
* testsuite/Makefile.in: Regenerate.
* testsuite/arm_exidx.s: Generate data relocations for __exidx_start
and __exidx_end.
* testsuite/arm_exidx_test.sh: Check that no unused dynamic
relocations are generated for __exidx_start and __exidx_end.
Diffstat (limited to 'gold/arm.cc')
-rw-r--r-- | gold/arm.cc | 85 |
1 files changed, 59 insertions, 26 deletions
diff --git a/gold/arm.cc b/gold/arm.cc index 32a4638..dc6e64a 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -2515,6 +2515,9 @@ class Target_arm : public Sized_target<32, big_endian> && Target::do_section_may_have_icf_unsafe_pointers(section_name)); } + virtual void + do_define_standard_symbols(Symbol_table*, Layout*); + private: // The class which scans relocations. class Scan @@ -8535,7 +8538,7 @@ void Target_arm<big_endian>::do_finalize_sections( Layout* layout, const Input_objects* input_objects, - Symbol_table* symtab) + Symbol_table*) { bool merged_any_attributes = false; // Merge processor-specific flags. @@ -8622,18 +8625,6 @@ Target_arm<big_endian>::do_finalize_sections( if (exidx_section != NULL && exidx_section->type() == elfcpp::SHT_ARM_EXIDX) { - // Create __exidx_start and __exidx_end symbols. - symtab->define_in_output_data("__exidx_start", NULL, - Symbol_table::PREDEFINED, - exidx_section, 0, 0, elfcpp::STT_OBJECT, - elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN, - 0, false, true); - symtab->define_in_output_data("__exidx_end", NULL, - Symbol_table::PREDEFINED, - exidx_section, 0, 0, elfcpp::STT_OBJECT, - elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN, - 0, true, true); - // For the ARM target, we need to add a PT_ARM_EXIDX segment for // the .ARM.exidx section. if (!layout->script_options()->saw_phdrs_clause()) @@ -8647,19 +8638,6 @@ Target_arm<big_endian>::do_finalize_sections( elfcpp::PF_R); } } - else - { - symtab->define_as_constant("__exidx_start", NULL, - Symbol_table::PREDEFINED, - 0, 0, elfcpp::STT_OBJECT, - elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN, 0, - true, false); - symtab->define_as_constant("__exidx_end", NULL, - Symbol_table::PREDEFINED, - 0, 0, elfcpp::STT_OBJECT, - elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN, 0, - true, false); - } } // Create an .ARM.attributes section if we have merged any attributes @@ -11947,6 +11925,61 @@ Target_arm<big_endian>::fix_exidx_coverage( merge_exidx_entries(), task); } +template<bool big_endian> +void +Target_arm<big_endian>::do_define_standard_symbols( + Symbol_table* symtab, + Layout* layout) +{ + // Handle the .ARM.exidx section. + Output_section* exidx_section = layout->find_output_section(".ARM.exidx"); + + if (exidx_section != NULL) + { + // Create __exidx_start and __exidx_end symbols. + symtab->define_in_output_data("__exidx_start", + NULL, // version + Symbol_table::PREDEFINED, + exidx_section, + 0, // value + 0, // symsize + elfcpp::STT_NOTYPE, + elfcpp::STB_GLOBAL, + elfcpp::STV_HIDDEN, + 0, // nonvis + false, // offset_is_from_end + true); // only_if_ref + + symtab->define_in_output_data("__exidx_end", + NULL, // version + Symbol_table::PREDEFINED, + exidx_section, + 0, // value + 0, // symsize + elfcpp::STT_NOTYPE, + elfcpp::STB_GLOBAL, + elfcpp::STV_HIDDEN, + 0, // nonvis + true, // offset_is_from_end + true); // only_if_ref + } + else + { + // Define __exidx_start and __exidx_end even when .ARM.exidx + // section is missing to match ld's behaviour. + symtab->define_as_constant("__exidx_start", NULL, + Symbol_table::PREDEFINED, + 0, 0, elfcpp::STT_OBJECT, + elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN, 0, + true, false); + symtab->define_as_constant("__exidx_end", NULL, + Symbol_table::PREDEFINED, + 0, 0, elfcpp::STT_OBJECT, + elfcpp::STB_GLOBAL, elfcpp::STV_HIDDEN, 0, + true, false); + } +} + Target_selector_arm<false> target_selector_arm; Target_selector_arm<true> target_selector_armbe; |