+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.
+
2012-03-16 Doug Kwan <dougkwan@google.com>
* testsuite/Makefile.am: Disable test initpri3b.
&& 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
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.
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())
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
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;
// 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<Target*>(¶meters->target());
if (!parameters->options().relocatable())
{
// Predefine standard symbols.
// 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.
// 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<Target*>(¶meters->target());
workqueue->queue(new Task_function(new Layout_task_runner(options,
input_objects,
symtab,