summaryrefslogtreecommitdiffstats
path: root/binutils-2.22/gold
diff options
context:
space:
mode:
authorAndrew Hsieh <andrewhsieh@google.com>2012-10-09 16:30:58 +0800
committerAndrew Hsieh <andrewhsieh@google.com>2012-10-09 16:35:48 +0800
commitf4d5da627307cfd6dc9f83e0ce692a4ac9a012f2 (patch)
tree730cded36ad57aa614935456d255e813568971ee /binutils-2.22/gold
parentf9dadca89a4a993e5c68137b5b162b5e79fa4455 (diff)
downloadtoolchain_binutils-f4d5da627307cfd6dc9f83e0ce692a4ac9a012f2.zip
toolchain_binutils-f4d5da627307cfd6dc9f83e0ce692a4ac9a012f2.tar.gz
toolchain_binutils-f4d5da627307cfd6dc9f83e0ce692a4ac9a012f2.tar.bz2
[2.22] Fix ld.gold/arm from producing __exidx_start/__exidx_end
See http://sourceware.org/ml/binutils/2012-03/txt00005.txt Backport of binutils (revision, file) 1.146 gold/arm.cc 1.97 gold/gold.cc 1.63 gold/target.h 1.188 gold/testsuite/Makefile.am 1.2 gold/testsuite/arm_exidx_test.s 1.1 gold/testsuite/arm_exidx_test.sh Change-Id: Id7d79684fec9945540ff17a5773163214bd9d371
Diffstat (limited to 'binutils-2.22/gold')
-rw-r--r--binutils-2.22/gold/arm.cc85
-rw-r--r--binutils-2.22/gold/gold.cc8
-rw-r--r--binutils-2.22/gold/target.h10
-rw-r--r--binutils-2.22/gold/testsuite/Makefile.am2
-rw-r--r--binutils-2.22/gold/testsuite/arm_exidx_test.s6
-rwxr-xr-xbinutils-2.22/gold/testsuite/arm_exidx_test.sh19
6 files changed, 99 insertions, 31 deletions
diff --git a/binutils-2.22/gold/arm.cc b/binutils-2.22/gold/arm.cc
index e31bb60..d41ba350 100644
--- a/binutils-2.22/gold/arm.cc
+++ b/binutils-2.22/gold/arm.cc
@@ -2574,6 +2574,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
@@ -8582,7 +8585,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.
@@ -8669,18 +8672,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())
@@ -8694,19 +8685,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
@@ -11994,6 +11972,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;
diff --git a/binutils-2.22/gold/gold.cc b/binutils-2.22/gold/gold.cc
index 12f25b7..f2d73fe 100644
--- a/binutils-2.22/gold/gold.cc
+++ b/binutils-2.22/gold/gold.cc
@@ -674,6 +674,9 @@ queue_middle_tasks(const General_options& options,
// Define symbols from any linker scripts.
layout->define_script_symbols(symtab);
+ // TODO(csilvers): figure out a more principled way to get the target
+ Target* target = const_cast<Target*>(&parameters->target());
+
// Attach sections to segments.
layout->attach_sections_to_segments();
@@ -685,6 +688,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.
@@ -766,8 +772,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*>(&parameters->target());
workqueue->queue(new Task_function(new Layout_task_runner(options,
input_objects,
symtab,
diff --git a/binutils-2.22/gold/target.h b/binutils-2.22/gold/target.h
index a378120..a4aab43 100644
--- a/binutils-2.22/gold/target.h
+++ b/binutils-2.22/gold/target.h
@@ -397,6 +397,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
@@ -630,6 +635,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/binutils-2.22/gold/testsuite/Makefile.am b/binutils-2.22/gold/testsuite/Makefile.am
index 9b8605b..fdb37e5 100644
--- a/binutils-2.22/gold/testsuite/Makefile.am
+++ b/binutils-2.22/gold/testsuite/Makefile.am
@@ -2483,7 +2483,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/binutils-2.22/gold/testsuite/arm_exidx_test.s b/binutils-2.22/gold/testsuite/arm_exidx_test.s
index 14dcc94..8e550e4 100644
--- a/binutils-2.22/gold/testsuite/arm_exidx_test.s
+++ b/binutils-2.22/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/binutils-2.22/gold/testsuite/arm_exidx_test.sh b/binutils-2.22/gold/testsuite/arm_exidx_test.sh
index f732a68..e196f12 100755
--- a/binutils-2.22/gold/testsuite/arm_exidx_test.sh
+++ b/binutils-2.22/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