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.
This commit is contained in:
parent
e918b09c1c
commit
647f15745a
@ -1,3 +1,20 @@
|
||||
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.
|
||||
|
85
gold/arm.cc
85
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;
|
||||
|
||||
|
@ -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<Target*>(¶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<Target*>(¶meters->target());
|
||||
workqueue->queue(new Task_function(new Layout_task_runner(options,
|
||||
input_objects,
|
||||
symtab,
|
||||
|
@ -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.
|
||||
|
@ -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 $@ $<
|
||||
|
@ -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 $@ $<
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user