From 647f15745ab30d29fbcd8fb56ffba69f8b545886 Mon Sep 17 00:00:00 2001 From: Doug Kwan Date: Mon, 19 Mar 2012 23:54:07 +0000 Subject: [PATCH] 2012-03-19 Doug Kwan * 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. --- gold/ChangeLog | 17 ++++++++ gold/arm.cc | 85 ++++++++++++++++++++++++++++------------ gold/gold.cc | 7 +++- gold/target.h | 10 +++++ gold/testsuite/Makefile.am | 2 +- gold/testsuite/Makefile.in | 2 +- gold/testsuite/arm_exidx_test.s | 6 +++ gold/testsuite/arm_exidx_test.sh | 19 ++++++++- 8 files changed, 116 insertions(+), 32 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index adcd647..e251570 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,20 @@ +2012-03-19 Doug Kwan + + * 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. + 2012-03-16 Doug Kwan * testsuite/Makefile.am: Disable test initpri3b. 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::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::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::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::fix_exidx_coverage( merge_exidx_entries(), task); } +template +void +Target_arm::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 target_selector_arm; Target_selector_arm target_selector_armbe; diff --git a/gold/gold.cc b/gold/gold.cc index f455ec8..f810bf9 100644 --- a/gold/gold.cc +++ b/gold/gold.cc @@ -679,6 +679,8 @@ queue_middle_tasks(const General_options& options, // Attach sections to segments. layout->attach_sections_to_segments(); + // TODO(csilvers): figure out a more principled way to get the target + Target* target = const_cast(¶meters->target()); if (!parameters->options().relocatable()) { // Predefine standard symbols. @@ -687,6 +689,9 @@ queue_middle_tasks(const General_options& options, // Define __start and __stop symbols for output sections where // appropriate. layout->define_section_symbols(symtab); + + // Define target-specific symbols. + target->define_standard_symbols(symtab, layout); } // Make sure we have symbols for any required group signatures. @@ -768,8 +773,6 @@ queue_middle_tasks(const General_options& options, // When all those tasks are complete, we can start laying out the // output file. - // TODO(csilvers): figure out a more principled way to get the target - Target* target = const_cast(¶meters->target()); workqueue->queue(new Task_function(new Layout_task_runner(options, input_objects, symtab, diff --git a/gold/target.h b/gold/target.h index 1035427..ff97aba 100644 --- a/gold/target.h +++ b/gold/target.h @@ -396,6 +396,11 @@ class Target set_osabi(elfcpp::ELFOSABI osabi) { this->osabi_ = osabi; } + // Define target-specific standard symbols. + void + define_standard_symbols(Symbol_table* symtab, Layout* layout) + { this->do_define_standard_symbols(symtab, layout); } + protected: // This struct holds the constant information for a child class. We // use a struct to avoid the overhead of virtual function calls for @@ -629,6 +634,11 @@ class Target do_select_as_default_target() { } + // This may be overridden by the child class. + virtual void + do_define_standard_symbols(Symbol_table*, Layout*) + { } + private: // The implementations of the four do_make_elf_object virtual functions are // almost identical except for their sizes and endianness. We use a template. diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index a14dd3e..a7fd06d 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -2505,7 +2505,7 @@ check_SCRIPTS += arm_exidx_test.sh check_DATA += arm_exidx_test.stdout arm_exidx_test.stdout: arm_exidx_test.so - $(TEST_READELF) -S $< > $@ + $(TEST_READELF) -Sr $< > $@ arm_exidx_test.so: arm_exidx_test.o ../ld-new ../ld-new -shared -o $@ $< diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index 7379071..251bdce 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -5463,7 +5463,7 @@ uninstall-am: @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@arm_exidx_test.stdout: arm_exidx_test.so -@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_READELF) -S $< > $@ +@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_READELF) -Sr $< > $@ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@arm_exidx_test.so: arm_exidx_test.o ../ld-new @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new -shared -o $@ $< diff --git a/gold/testsuite/arm_exidx_test.s b/gold/testsuite/arm_exidx_test.s index 14dcc94..8e550e4 100644 --- a/gold/testsuite/arm_exidx_test.s +++ b/gold/testsuite/arm_exidx_test.s @@ -23,3 +23,9 @@ empty: .fnend .size empty, .-empty +# Check that no dynamic relocations for __exidx_start and __exidx_stop +# generated. + .data + .align 12 + .word __exidx_start(got) + .word __exidx_end(got) diff --git a/gold/testsuite/arm_exidx_test.sh b/gold/testsuite/arm_exidx_test.sh index f732a68..e196f12 100755 --- a/gold/testsuite/arm_exidx_test.sh +++ b/gold/testsuite/arm_exidx_test.sh @@ -29,10 +29,23 @@ check() { if ! grep -q "$2" "$1" then - echo "Did not find section header in $1:" + echo "Did not find expected output in $1:" echo " $2" echo "" - echo "Actual headers below:" + echo "Actual output below:" + cat "$1" + exit 1 + fi +} + +check_not() +{ + if grep -q "$2" "$1" + then + echo "Found unexpected output in $1:" + echo " $2" + echo "" + echo "Actual output below:" cat "$1" exit 1 fi @@ -41,5 +54,7 @@ check() # Check that SHF_LINK_ORDER is set. check arm_exidx_test.stdout ".* .ARM.exidx .* ARM_EXIDX .* AL .*" check arm_exidx_test.stdout ".* .ARM.extab .* PROGBITS .* A .*" +check_not arm_exidx_test.stdout ".* .* R_ARM_GLOB_DAT .* __exidx_start" +check_not arm_exidx_test.stdout ".* .* R_ARM_GLOB_DAT .* __exidx_end" exit 0 -- 2.7.4