From bca7fb637f653f086fcf935585eb6395b3893cf6 Mon Sep 17 00:00:00 2001 From: Doug Kwan Date: Fri, 17 Sep 2010 23:51:42 +0000 Subject: [PATCH] 2010-09-17 Doug Kwan * arm.cc (Target_arm::Relocate::relocate): Ignore symbol type and defintion if relocation uses GOT entries of the symbol. * testsuite/icf_safe_test.sh: Fix test. * testsuite/icf_safe_so_test.sh: Fix test. --- gold/ChangeLog | 7 ++++ gold/arm.cc | 71 +++++++++++++++++++++----------------- gold/testsuite/icf_safe_so_test.sh | 16 ++++----- gold/testsuite/icf_safe_test.sh | 2 +- 4 files changed, 56 insertions(+), 40 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 5df7be5..4fb82b7 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,10 @@ +2010-09-17 Doug Kwan + + * arm.cc (Target_arm::Relocate::relocate): Ignore symbol type and + defintion if relocation uses GOT entries of the symbol. + * testsuite/icf_safe_test.sh: Fix test. + * testsuite/icf_safe_so_test.sh: Fix test. + 2010-09-16 Cary Coutant * script_sections.cc (class Memory_region): Remove "NULL" from diff --git a/gold/arm.cc b/gold/arm.cc index 79a9663..d6590f0 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -8582,7 +8582,46 @@ Target_arm::Relocate::relocate( Arm_address thumb_bit = 0; Symbol_value<32> symval; bool is_weakly_undefined_without_plt = false; - if (relnum != Target_arm::fake_relnum_for_stubs) + bool have_got_offset = false; + unsigned int got_offset = 0; + + // If the relocation uses the GOT entry of a symbol instead of the symbol + // itself, we don't care about whether the symbol is defined or what kind + // of symbol it is. + if (reloc_property->uses_got_entry()) + { + // Get the GOT offset. + // The GOT pointer points to the end of the GOT section. + // We need to subtract the size of the GOT section to get + // the actual offset to use in the relocation. + // TODO: We should move GOT offset computing code in TLS relocations + // to here. + switch (r_type) + { + case elfcpp::R_ARM_GOT_BREL: + case elfcpp::R_ARM_GOT_PREL: + if (gsym != NULL) + { + gold_assert(gsym->has_got_offset(GOT_TYPE_STANDARD)); + got_offset = (gsym->got_offset(GOT_TYPE_STANDARD) + - target->got_size()); + } + else + { + unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info()); + gold_assert(object->local_has_got_offset(r_sym, + GOT_TYPE_STANDARD)); + got_offset = (object->local_got_offset(r_sym, GOT_TYPE_STANDARD) + - target->got_size()); + } + have_got_offset = true; + break; + + default: + break; + } + } + else if (relnum != Target_arm::fake_relnum_for_stubs) { if (gsym != NULL) { @@ -8651,36 +8690,6 @@ Target_arm::Relocate::relocate( psymval = &symval; } - // Get the GOT offset if needed. - // The GOT pointer points to the end of the GOT section. - // We need to subtract the size of the GOT section to get - // the actual offset to use in the relocation. - bool have_got_offset = false; - unsigned int got_offset = 0; - switch (r_type) - { - case elfcpp::R_ARM_GOT_BREL: - case elfcpp::R_ARM_GOT_PREL: - if (gsym != NULL) - { - gold_assert(gsym->has_got_offset(GOT_TYPE_STANDARD)); - got_offset = (gsym->got_offset(GOT_TYPE_STANDARD) - - target->got_size()); - } - else - { - unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info()); - gold_assert(object->local_has_got_offset(r_sym, GOT_TYPE_STANDARD)); - got_offset = (object->local_got_offset(r_sym, GOT_TYPE_STANDARD) - - target->got_size()); - } - have_got_offset = true; - break; - - default: - break; - } - // To look up relocation stubs, we need to pass the symbol table index of // a local symbol. unsigned int r_sym = elfcpp::elf_r_sym<32>(rel.get_r_info()); diff --git a/gold/testsuite/icf_safe_so_test.sh b/gold/testsuite/icf_safe_so_test.sh index 47ad390..315a016 100755 --- a/gold/testsuite/icf_safe_so_test.sh +++ b/gold/testsuite/icf_safe_so_test.sh @@ -84,9 +84,9 @@ arch_specific_safe_fold() fi } -X86_32_specific_safe_fold() +X86_32_or_ARM_specific_safe_fold() { - grep -e "Intel 80386" $1 > /dev/null 2>&1 + grep -e "Intel 80386" -e "ARM" $1 > /dev/null 2>&1 arch_specific_safe_fold $? $2 $3 $4 } @@ -96,10 +96,10 @@ X86_64_specific_safe_fold() arch_specific_safe_fold $? $2 $3 $4 } -X86_32_specific_safe_fold icf_safe_so_test_2.stdout icf_safe_so_test_1.stdout "foo_prot" "foo_hidden" -X86_32_specific_safe_fold icf_safe_so_test_2.stdout icf_safe_so_test_1.stdout "foo_prot" "foo_internal" -X86_32_specific_safe_fold icf_safe_so_test_2.stdout icf_safe_so_test_1.stdout "foo_prot" "foo_static" -X86_32_specific_safe_fold icf_safe_so_test_2.stdout icf_safe_so_test_1.stdout "foo_hidden" "foo_internal" -X86_32_specific_safe_fold icf_safe_so_test_2.stdout icf_safe_so_test_1.stdout "foo_hidden" "foo_static" -X86_32_specific_safe_fold icf_safe_so_test_2.stdout icf_safe_so_test_1.stdout "foo_internal" "foo_static" +X86_32_or_ARM_specific_safe_fold icf_safe_so_test_2.stdout icf_safe_so_test_1.stdout "foo_prot" "foo_hidden" +X86_32_or_ARM_specific_safe_fold icf_safe_so_test_2.stdout icf_safe_so_test_1.stdout "foo_prot" "foo_internal" +X86_32_or_ARM_specific_safe_fold icf_safe_so_test_2.stdout icf_safe_so_test_1.stdout "foo_prot" "foo_static" +X86_32_or_ARM_specific_safe_fold icf_safe_so_test_2.stdout icf_safe_so_test_1.stdout "foo_hidden" "foo_internal" +X86_32_or_ARM_specific_safe_fold icf_safe_so_test_2.stdout icf_safe_so_test_1.stdout "foo_hidden" "foo_static" +X86_32_or_ARM_specific_safe_fold icf_safe_so_test_2.stdout icf_safe_so_test_1.stdout "foo_internal" "foo_static" check_nofold icf_safe_so_test_1.stdout "foo_glob" "bar_glob" diff --git a/gold/testsuite/icf_safe_test.sh b/gold/testsuite/icf_safe_test.sh index 23e4e29..d26d40b 100755 --- a/gold/testsuite/icf_safe_test.sh +++ b/gold/testsuite/icf_safe_test.sh @@ -49,7 +49,7 @@ check_fold() arch_specific_safe_fold() { - grep_x86=`grep -q -e "Advanced Micro Devices X86-64" -e "Intel 80386" $2` + grep_x86=`grep -q -e "Advanced Micro Devices X86-64" -e "Intel 80386" -e "ARM" $2` if [ $? == 0 ]; then check_fold $1 $3 $4 -- 2.7.4