diff options
author | Doug Kwan <dougkwan@google.com> | 2010-02-12 05:51:32 +0000 |
---|---|---|
committer | Doug Kwan <dougkwan@google.com> | 2010-02-12 05:51:32 +0000 |
commit | e4782e838130706e2d2d53a9e3c29f71419863ae (patch) | |
tree | 06d8666079258a16b125509735d9c22f3a044b6f | |
parent | ecc13e538fab510f27fb5de27f93b6be8aff983f (diff) | |
download | gdb-e4782e838130706e2d2d53a9e3c29f71419863ae.zip gdb-e4782e838130706e2d2d53a9e3c29f71419863ae.tar.gz gdb-e4782e838130706e2d2d53a9e3c29f71419863ae.tar.bz2 |
2010-02-11 Doug Kwan <dougkwan@google.com>
* arm.cc (Target_arm::Scan::local): Fix bugs in relocation handling.
(Target_arm::Scan::global): Ditto. Also remove a comment before the
beginning of function.
(Target_arm::Relocate::relocate): Remove error messages for MOVW_ABS
and MOVT_ABS relocations. Those are non issued in scanning. Fix
parameter is_32bit in calls to should_apply_static_reloc.
* testsuite/Makefile.am (check_SCRIPTS): Add arm_abs_global.sh.
(check_DATA): Add arm_abs_global.stdout.
(arm_abs_lib.o, libarm_abs.so, arm_abs_global.o, arm_abs_global,
arm_abs_global.stdout): New rules.
(MOSTLLYCLEANFILES): Add arm_abs_global
* Makefile.in: Regenerate.
* testsuite/arm_abs_global.s: New file.
* testsuite/arm_abs_global.sh: Ditto.
* testsuite/arm_abs_lib.s: Ditto.
-rw-r--r-- | gold/ChangeLog | 18 | ||||
-rw-r--r-- | gold/arm.cc | 322 | ||||
-rw-r--r-- | gold/testsuite/Makefile.am | 19 | ||||
-rw-r--r-- | gold/testsuite/Makefile.in | 20 | ||||
-rw-r--r-- | gold/testsuite/arm_abs_global.s | 31 | ||||
-rwxr-xr-x | gold/testsuite/arm_abs_global.sh | 57 | ||||
-rw-r--r-- | gold/testsuite/arm_abs_lib.s | 37 |
7 files changed, 361 insertions, 143 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 03191eb..0b50ead 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,21 @@ +2010-02-11 Doug Kwan <dougkwan@google.com> + + * arm.cc (Target_arm::Scan::local): Fix bugs in relocation handling. + (Target_arm::Scan::global): Ditto. Also remove a comment before the + beginning of function. + (Target_arm::Relocate::relocate): Remove error messages for MOVW_ABS + and MOVT_ABS relocations. Those are non issued in scanning. Fix + parameter is_32bit in calls to should_apply_static_reloc. + * testsuite/Makefile.am (check_SCRIPTS): Add arm_abs_global.sh. + (check_DATA): Add arm_abs_global.stdout. + (arm_abs_lib.o, libarm_abs.so, arm_abs_global.o, arm_abs_global, + arm_abs_global.stdout): New rules. + (MOSTLLYCLEANFILES): Add arm_abs_global + * Makefile.in: Regenerate. + * testsuite/arm_abs_global.s: New file. + * testsuite/arm_abs_global.sh: Ditto. + * testsuite/arm_abs_lib.s: Ditto. + 2010-02-11 Ian Lance Taylor <iant@google.com> * gold.cc (queue_middle_gc_tasks): Use a separate blocker for each diff --git a/gold/arm.cc b/gold/arm.cc index 902805c..d40ab2c 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -6572,12 +6572,15 @@ Target_arm<big_endian>::Scan::local(Symbol_table* symtab, Output_section* output_section, const elfcpp::Rel<32, big_endian>& reloc, unsigned int r_type, - const elfcpp::Sym<32, big_endian>&) + const elfcpp::Sym<32, big_endian>& lsym) { r_type = get_real_reloc_type(r_type); switch (r_type) { case elfcpp::R_ARM_NONE: + case elfcpp::R_ARM_V4BX: + case elfcpp::R_ARM_GNU_VTENTRY: + case elfcpp::R_ARM_GNU_VTINHERIT: break; case elfcpp::R_ARM_ABS32: @@ -6600,79 +6603,116 @@ Target_arm<big_endian>::Scan::local(Symbol_table* symtab, } break; - case elfcpp::R_ARM_REL32: - case elfcpp::R_ARM_THM_CALL: - case elfcpp::R_ARM_CALL: - case elfcpp::R_ARM_PREL31: - case elfcpp::R_ARM_JUMP24: - case elfcpp::R_ARM_THM_JUMP24: - case elfcpp::R_ARM_THM_JUMP19: - case elfcpp::R_ARM_PLT32: + case elfcpp::R_ARM_ABS16: + case elfcpp::R_ARM_ABS12: case elfcpp::R_ARM_THM_ABS5: case elfcpp::R_ARM_ABS8: - case elfcpp::R_ARM_ABS12: - case elfcpp::R_ARM_ABS16: case elfcpp::R_ARM_BASE_ABS: case elfcpp::R_ARM_MOVW_ABS_NC: case elfcpp::R_ARM_MOVT_ABS: case elfcpp::R_ARM_THM_MOVW_ABS_NC: case elfcpp::R_ARM_THM_MOVT_ABS: + // If building a shared library (or a position-independent + // executable), we need to create a dynamic relocation for + // this location. Because the addend needs to remain in the + // data section, we need to be careful not to apply this + // relocation statically. + if (parameters->options().output_is_position_independent()) + { + check_non_pic(object, r_type); + Reloc_section* rel_dyn = target->rel_dyn_section(layout); + unsigned int r_sym = elfcpp::elf_r_sym<32>(reloc.get_r_info()); + if (lsym.get_st_type() != elfcpp::STT_SECTION) + rel_dyn->add_local(object, r_sym, r_type, output_section, + data_shndx, reloc.get_r_offset()); + else + { + gold_assert(lsym.get_st_value() == 0); + unsigned int shndx = lsym.get_st_shndx(); + bool is_ordinary; + shndx = object->adjust_sym_shndx(r_sym, shndx, + &is_ordinary); + if (!is_ordinary) + object->error(_("section symbol %u has bad shndx %u"), + r_sym, shndx); + else + rel_dyn->add_local_section(object, shndx, + r_type, output_section, + data_shndx, reloc.get_r_offset()); + } + } + break; + + case elfcpp::R_ARM_PC24: + case elfcpp::R_ARM_REL32: + case elfcpp::R_ARM_LDR_PC_G0: + case elfcpp::R_ARM_SBREL32: + case elfcpp::R_ARM_THM_CALL: + case elfcpp::R_ARM_THM_PC8: + case elfcpp::R_ARM_BASE_PREL: + case elfcpp::R_ARM_PLT32: + case elfcpp::R_ARM_CALL: + case elfcpp::R_ARM_JUMP24: + case elfcpp::R_ARM_THM_JUMP24: + case elfcpp::R_ARM_LDR_SBREL_11_0_NC: + case elfcpp::R_ARM_ALU_SBREL_19_12_NC: + case elfcpp::R_ARM_ALU_SBREL_27_20_CK: + case elfcpp::R_ARM_SBREL31: + case elfcpp::R_ARM_PREL31: case elfcpp::R_ARM_MOVW_PREL_NC: case elfcpp::R_ARM_MOVT_PREL: case elfcpp::R_ARM_THM_MOVW_PREL_NC: case elfcpp::R_ARM_THM_MOVT_PREL: - case elfcpp::R_ARM_MOVW_BREL_NC: - case elfcpp::R_ARM_MOVT_BREL: - case elfcpp::R_ARM_MOVW_BREL: - case elfcpp::R_ARM_THM_MOVW_BREL_NC: - case elfcpp::R_ARM_THM_MOVT_BREL: - case elfcpp::R_ARM_THM_MOVW_BREL: + case elfcpp::R_ARM_THM_JUMP19: case elfcpp::R_ARM_THM_JUMP6: - case elfcpp::R_ARM_THM_JUMP8: - case elfcpp::R_ARM_THM_JUMP11: - case elfcpp::R_ARM_V4BX: - case elfcpp::R_ARM_THM_PC8: - case elfcpp::R_ARM_THM_PC12: case elfcpp::R_ARM_THM_ALU_PREL_11_0: + case elfcpp::R_ARM_THM_PC12: + case elfcpp::R_ARM_REL32_NOI: case elfcpp::R_ARM_ALU_PC_G0_NC: case elfcpp::R_ARM_ALU_PC_G0: case elfcpp::R_ARM_ALU_PC_G1_NC: case elfcpp::R_ARM_ALU_PC_G1: case elfcpp::R_ARM_ALU_PC_G2: + case elfcpp::R_ARM_LDR_PC_G1: + case elfcpp::R_ARM_LDR_PC_G2: + case elfcpp::R_ARM_LDRS_PC_G0: + case elfcpp::R_ARM_LDRS_PC_G1: + case elfcpp::R_ARM_LDRS_PC_G2: + case elfcpp::R_ARM_LDC_PC_G0: + case elfcpp::R_ARM_LDC_PC_G1: + case elfcpp::R_ARM_LDC_PC_G2: case elfcpp::R_ARM_ALU_SB_G0_NC: case elfcpp::R_ARM_ALU_SB_G0: case elfcpp::R_ARM_ALU_SB_G1_NC: case elfcpp::R_ARM_ALU_SB_G1: case elfcpp::R_ARM_ALU_SB_G2: - case elfcpp::R_ARM_LDR_PC_G0: - case elfcpp::R_ARM_LDR_PC_G1: - case elfcpp::R_ARM_LDR_PC_G2: case elfcpp::R_ARM_LDR_SB_G0: case elfcpp::R_ARM_LDR_SB_G1: case elfcpp::R_ARM_LDR_SB_G2: - case elfcpp::R_ARM_LDRS_PC_G0: - case elfcpp::R_ARM_LDRS_PC_G1: - case elfcpp::R_ARM_LDRS_PC_G2: case elfcpp::R_ARM_LDRS_SB_G0: case elfcpp::R_ARM_LDRS_SB_G1: case elfcpp::R_ARM_LDRS_SB_G2: - case elfcpp::R_ARM_LDC_PC_G0: - case elfcpp::R_ARM_LDC_PC_G1: - case elfcpp::R_ARM_LDC_PC_G2: case elfcpp::R_ARM_LDC_SB_G0: case elfcpp::R_ARM_LDC_SB_G1: case elfcpp::R_ARM_LDC_SB_G2: + case elfcpp::R_ARM_MOVW_BREL_NC: + case elfcpp::R_ARM_MOVT_BREL: + case elfcpp::R_ARM_MOVW_BREL: + case elfcpp::R_ARM_THM_MOVW_BREL_NC: + case elfcpp::R_ARM_THM_MOVT_BREL: + case elfcpp::R_ARM_THM_MOVW_BREL: + case elfcpp::R_ARM_THM_JUMP11: + case elfcpp::R_ARM_THM_JUMP8: + // We don't need to do anything for a relative addressing relocation + // against a local symbol if it does not reference the GOT. break; case elfcpp::R_ARM_GOTOFF32: + case elfcpp::R_ARM_GOTOFF12: // We need a GOT section: target->got_section(symtab, layout); break; - case elfcpp::R_ARM_BASE_PREL: - // FIXME: What about this? - break; - case elfcpp::R_ARM_GOT_BREL: case elfcpp::R_ARM_GOT_PREL: { @@ -6697,6 +6737,7 @@ Target_arm<big_endian>::Scan::local(Symbol_table* symtab, break; case elfcpp::R_ARM_TARGET1: + case elfcpp::R_ARM_TARGET2: // This should have been mapped to another type already. // Fall through. case elfcpp::R_ARM_COPY: @@ -6729,8 +6770,6 @@ Target_arm<big_endian>::Scan::unsupported_reloc_global( } // Scan a relocation for a global symbol. -// FIXME: This only handles a subset of relocation types used by Android -// on ARM v5te devices. template<bool big_endian> inline void @@ -6748,109 +6787,118 @@ Target_arm<big_endian>::Scan::global(Symbol_table* symtab, switch (r_type) { case elfcpp::R_ARM_NONE: + case elfcpp::R_ARM_V4BX: + case elfcpp::R_ARM_GNU_VTENTRY: + case elfcpp::R_ARM_GNU_VTINHERIT: break; case elfcpp::R_ARM_ABS32: + case elfcpp::R_ARM_ABS16: + case elfcpp::R_ARM_ABS12: + case elfcpp::R_ARM_THM_ABS5: + case elfcpp::R_ARM_ABS8: + case elfcpp::R_ARM_BASE_ABS: + case elfcpp::R_ARM_MOVW_ABS_NC: + case elfcpp::R_ARM_MOVT_ABS: + case elfcpp::R_ARM_THM_MOVW_ABS_NC: + case elfcpp::R_ARM_THM_MOVT_ABS: case elfcpp::R_ARM_ABS32_NOI: + // Absolute addressing relocations. { - // Make a dynamic relocation if necessary. - if (gsym->needs_dynamic_reloc(Symbol::ABSOLUTE_REF)) - { - if (target->may_need_copy_reloc(gsym)) - { - target->copy_reloc(symtab, layout, object, - data_shndx, output_section, gsym, reloc); - } - else if (gsym->can_use_relative_reloc(false)) - { - // If we are to add more other reloc types than R_ARM_ABS32, - // we need to add check_non_pic(object, r_type) here. - Reloc_section* rel_dyn = target->rel_dyn_section(layout); - rel_dyn->add_global_relative(gsym, elfcpp::R_ARM_RELATIVE, - output_section, object, - data_shndx, reloc.get_r_offset()); - } - else - { - // If we are to add more other reloc types than R_ARM_ABS32, - // we need to add check_non_pic(object, r_type) here. - Reloc_section* rel_dyn = target->rel_dyn_section(layout); - rel_dyn->add_global(gsym, r_type, output_section, object, - data_shndx, reloc.get_r_offset()); - } - } + // Make a PLT entry if necessary. + if (this->symbol_needs_plt_entry(gsym)) + { + target->make_plt_entry(symtab, layout, gsym); + // Since this is not a PC-relative relocation, we may be + // taking the address of a function. In that case we need to + // set the entry in the dynamic symbol table to the address of + // the PLT entry. + if (gsym->is_from_dynobj() && !parameters->options().shared()) + gsym->set_needs_dynsym_value(); + } + // Make a dynamic relocation if necessary. + if (gsym->needs_dynamic_reloc(Symbol::ABSOLUTE_REF)) + { + if (gsym->may_need_copy_reloc()) + { + target->copy_reloc(symtab, layout, object, + data_shndx, output_section, gsym, reloc); + } + else if ((r_type == elfcpp::R_ARM_ABS32 + || r_type == elfcpp::R_ARM_ABS32_NOI) + && gsym->can_use_relative_reloc(false)) + { + Reloc_section* rel_dyn = target->rel_dyn_section(layout); + rel_dyn->add_global_relative(gsym, elfcpp::R_ARM_RELATIVE, + output_section, object, + data_shndx, reloc.get_r_offset()); + } + else + { + check_non_pic(object, r_type); + Reloc_section* rel_dyn = target->rel_dyn_section(layout); + rel_dyn->add_global(gsym, r_type, output_section, object, + data_shndx, reloc.get_r_offset()); + } + } } break; - case elfcpp::R_ARM_MOVW_ABS_NC: - case elfcpp::R_ARM_MOVT_ABS: - case elfcpp::R_ARM_THM_MOVW_ABS_NC: - case elfcpp::R_ARM_THM_MOVT_ABS: + case elfcpp::R_ARM_GOTOFF32: + case elfcpp::R_ARM_GOTOFF12: + // We need a GOT section. + target->got_section(symtab, layout); + break; + + case elfcpp::R_ARM_REL32: + case elfcpp::R_ARM_LDR_PC_G0: + case elfcpp::R_ARM_SBREL32: + case elfcpp::R_ARM_THM_PC8: + case elfcpp::R_ARM_BASE_PREL: + case elfcpp::R_ARM_LDR_SBREL_11_0_NC: + case elfcpp::R_ARM_ALU_SBREL_19_12_NC: + case elfcpp::R_ARM_ALU_SBREL_27_20_CK: case elfcpp::R_ARM_MOVW_PREL_NC: case elfcpp::R_ARM_MOVT_PREL: case elfcpp::R_ARM_THM_MOVW_PREL_NC: case elfcpp::R_ARM_THM_MOVT_PREL: - case elfcpp::R_ARM_MOVW_BREL_NC: - case elfcpp::R_ARM_MOVT_BREL: - case elfcpp::R_ARM_MOVW_BREL: - case elfcpp::R_ARM_THM_MOVW_BREL_NC: - case elfcpp::R_ARM_THM_MOVT_BREL: - case elfcpp::R_ARM_THM_MOVW_BREL: - case elfcpp::R_ARM_THM_JUMP6: - case elfcpp::R_ARM_THM_JUMP8: - case elfcpp::R_ARM_THM_JUMP11: - case elfcpp::R_ARM_V4BX: - case elfcpp::R_ARM_THM_PC8: - case elfcpp::R_ARM_THM_PC12: case elfcpp::R_ARM_THM_ALU_PREL_11_0: + case elfcpp::R_ARM_THM_PC12: + case elfcpp::R_ARM_REL32_NOI: case elfcpp::R_ARM_ALU_PC_G0_NC: case elfcpp::R_ARM_ALU_PC_G0: case elfcpp::R_ARM_ALU_PC_G1_NC: case elfcpp::R_ARM_ALU_PC_G1: case elfcpp::R_ARM_ALU_PC_G2: + case elfcpp::R_ARM_LDR_PC_G1: + case elfcpp::R_ARM_LDR_PC_G2: + case elfcpp::R_ARM_LDRS_PC_G0: + case elfcpp::R_ARM_LDRS_PC_G1: + case elfcpp::R_ARM_LDRS_PC_G2: + case elfcpp::R_ARM_LDC_PC_G0: + case elfcpp::R_ARM_LDC_PC_G1: + case elfcpp::R_ARM_LDC_PC_G2: case elfcpp::R_ARM_ALU_SB_G0_NC: case elfcpp::R_ARM_ALU_SB_G0: case elfcpp::R_ARM_ALU_SB_G1_NC: case elfcpp::R_ARM_ALU_SB_G1: case elfcpp::R_ARM_ALU_SB_G2: - case elfcpp::R_ARM_LDR_PC_G0: - case elfcpp::R_ARM_LDR_PC_G1: - case elfcpp::R_ARM_LDR_PC_G2: case elfcpp::R_ARM_LDR_SB_G0: case elfcpp::R_ARM_LDR_SB_G1: case elfcpp::R_ARM_LDR_SB_G2: - case elfcpp::R_ARM_LDRS_PC_G0: - case elfcpp::R_ARM_LDRS_PC_G1: - case elfcpp::R_ARM_LDRS_PC_G2: case elfcpp::R_ARM_LDRS_SB_G0: case elfcpp::R_ARM_LDRS_SB_G1: case elfcpp::R_ARM_LDRS_SB_G2: - case elfcpp::R_ARM_LDC_PC_G0: - case elfcpp::R_ARM_LDC_PC_G1: - case elfcpp::R_ARM_LDC_PC_G2: case elfcpp::R_ARM_LDC_SB_G0: case elfcpp::R_ARM_LDC_SB_G1: case elfcpp::R_ARM_LDC_SB_G2: - break; - - case elfcpp::R_ARM_THM_ABS5: - case elfcpp::R_ARM_ABS8: - case elfcpp::R_ARM_ABS12: - case elfcpp::R_ARM_ABS16: - case elfcpp::R_ARM_BASE_ABS: - { - // No dynamic relocs of this kinds. - // Report the error in case of PIC. - int flags = Symbol::NON_PIC_REF; - if (gsym->type() == elfcpp::STT_FUNC - || gsym->type() == elfcpp::STT_ARM_TFUNC) - flags |= Symbol::FUNCTION_CALL; - if (gsym->needs_dynamic_reloc(flags)) - check_non_pic(object, r_type); - } - break; - - case elfcpp::R_ARM_REL32: + case elfcpp::R_ARM_MOVW_BREL_NC: + case elfcpp::R_ARM_MOVT_BREL: + case elfcpp::R_ARM_MOVW_BREL: + case elfcpp::R_ARM_THM_MOVW_BREL_NC: + case elfcpp::R_ARM_THM_MOVT_BREL: + case elfcpp::R_ARM_THM_MOVW_BREL: + // Relative addressing relocations. { // Make a dynamic relocation if necessary. int flags = Symbol::NON_PIC_REF; @@ -6872,14 +6920,27 @@ Target_arm<big_endian>::Scan::global(Symbol_table* symtab, } break; - case elfcpp::R_ARM_JUMP24: - case elfcpp::R_ARM_THM_JUMP24: - case elfcpp::R_ARM_THM_JUMP19: - case elfcpp::R_ARM_CALL: + case elfcpp::R_ARM_PC24: case elfcpp::R_ARM_THM_CALL: case elfcpp::R_ARM_PLT32: + case elfcpp::R_ARM_CALL: + case elfcpp::R_ARM_JUMP24: + case elfcpp::R_ARM_THM_JUMP24: + case elfcpp::R_ARM_SBREL31: case elfcpp::R_ARM_PREL31: - case elfcpp::R_ARM_PC24: + case elfcpp::R_ARM_THM_JUMP19: + case elfcpp::R_ARM_THM_JUMP6: + case elfcpp::R_ARM_THM_JUMP11: + case elfcpp::R_ARM_THM_JUMP8: + // All the relocation above are branches except for the PREL31 ones. + // A PREL31 relocation can point to a personality function in a shared + // library. In that case we want to use a PLT because we want to + // call the personality routine and the dyanmic linkers we care about + // do not support dynamic PREL31 relocations. An REL31 relocation may + // point to a function whose unwinding behaviour is being described but + // we will not mistakenly generate a PLT for that because we should use + // a local section symbol. + // If the symbol is fully resolved, this is just a relative // local reloc. Otherwise we need a PLT entry. if (gsym->final_value_is_known()) @@ -6894,16 +6955,8 @@ Target_arm<big_endian>::Scan::global(Symbol_table* symtab, target->make_plt_entry(symtab, layout, gsym); break; - case elfcpp::R_ARM_GOTOFF32: - // We need a GOT section. - target->got_section(symtab, layout); - break; - - case elfcpp::R_ARM_BASE_PREL: - // FIXME: What about this? - break; - case elfcpp::R_ARM_GOT_BREL: + case elfcpp::R_ARM_GOT_ABS: case elfcpp::R_ARM_GOT_PREL: { // The symbol requires a GOT entry. @@ -6933,7 +6986,8 @@ Target_arm<big_endian>::Scan::global(Symbol_table* symtab, break; case elfcpp::R_ARM_TARGET1: - // This should have been mapped to another type already. + case elfcpp::R_ARM_TARGET2: + // These should have been mapped to other types already. // Fall through. case elfcpp::R_ARM_COPY: case elfcpp::R_ARM_GLOB_DAT: @@ -7403,43 +7457,31 @@ Target_arm<big_endian>::Relocate::relocate( break; case elfcpp::R_ARM_MOVW_ABS_NC: - if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, true, + if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false, output_section)) reloc_status = Arm_relocate_functions::movw(view, object, psymval, 0, thumb_bit, check_overflow); - else - gold_error(_("relocation R_ARM_MOVW_ABS_NC cannot be used when making" - "a shared object; recompile with -fPIC")); break; case elfcpp::R_ARM_MOVT_ABS: - if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, true, + if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false, output_section)) reloc_status = Arm_relocate_functions::movt(view, object, psymval, 0); - else - gold_error(_("relocation R_ARM_MOVT_ABS cannot be used when making" - "a shared object; recompile with -fPIC")); break; case elfcpp::R_ARM_THM_MOVW_ABS_NC: - if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, true, + if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false, output_section)) reloc_status = Arm_relocate_functions::thm_movw(view, object, psymval, 0, thumb_bit, false); - else - gold_error(_("relocation R_ARM_THM_MOVW_ABS_NC cannot be used when" - "making a shared object; recompile with -fPIC")); break; case elfcpp::R_ARM_THM_MOVT_ABS: - if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, true, + if (should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false, output_section)) reloc_status = Arm_relocate_functions::thm_movt(view, object, psymval, 0); - else - gold_error(_("relocation R_ARM_THM_MOVT_ABS cannot be used when" - "making a shared object; recompile with -fPIC")); break; case elfcpp::R_ARM_MOVW_PREL_NC: @@ -7512,7 +7554,7 @@ Target_arm<big_endian>::Relocate::relocate( case elfcpp::R_ARM_BASE_ABS: { - if (!should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, true, + if (!should_apply_static_reloc(gsym, Symbol::ABSOLUTE_REF, false, output_section)) break; diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index 1ffb7b0..a1889bb 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -1435,3 +1435,22 @@ MOSTLYCLEANFILES += split_x86_64_1 split_x86_64_2 split_x86_64_3 \ split_x86_64_4 split_x86_64_r endif DEFAULT_TARGET_X86_64 + +if DEFAULT_TARGET_ARM + +check_SCRIPTS += arm_abs_global.sh +check_DATA += arm_abs_global.stdout +arm_abs_lib.o: arm_abs_lib.s + $(TEST_AS) -march=armv7-a -o $@ $< +libarm_abs.so: arm_abs_lib.o + ../ld-new -shared -o $@ arm_abs_lib.o +arm_abs_global.o: arm_abs_global.s + $(TEST_AS) -march=armv7-a -o $@ $< +arm_abs_global: arm_abs_global.o libarm_abs.so + ../ld-new -o $@ arm_abs_global.o -L. -larm_abs +arm_abs_global.stdout: arm_abs_global + $(TEST_READELF) -r $< > $@ + +MOSTLYCLEANFILES += arm_abs_global + +endif DEFAULT_TARGET_ARM diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index a806b34..e5fd65f 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -318,6 +318,9 @@ check_PROGRAMS = object_unittest$(EXEEXT) binary_unittest$(EXEEXT) \ @DEFAULT_TARGET_X86_64_TRUE@am__append_37 = split_x86_64_1 split_x86_64_2 split_x86_64_3 \ @DEFAULT_TARGET_X86_64_TRUE@ split_x86_64_4 split_x86_64_r +@DEFAULT_TARGET_ARM_TRUE@am__append_38 = arm_abs_global.sh +@DEFAULT_TARGET_ARM_TRUE@am__append_39 = arm_abs_global.stdout +@DEFAULT_TARGET_ARM_TRUE@am__append_40 = arm_abs_global subdir = testsuite DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -1378,15 +1381,16 @@ TEST_AS = $(top_builddir)/../gas/as-new # the right choice for files 'make' builds that people rebuild. MOSTLYCLEANFILES = *.so *.syms *.stdout $(am__append_3) \ $(am__append_8) $(am__append_17) $(am__append_25) \ - $(am__append_29) $(am__append_34) $(am__append_37) + $(am__append_29) $(am__append_34) $(am__append_37) \ + $(am__append_40) # We will add to these later, for each individual test. Note # that we add each test under check_SCRIPTS or check_PROGRAMS; # the TESTS variable is automatically populated from these. check_SCRIPTS = $(am__append_1) $(am__append_23) $(am__append_27) \ - $(am__append_32) $(am__append_35) + $(am__append_32) $(am__append_35) $(am__append_38) check_DATA = $(am__append_2) $(am__append_24) $(am__append_28) \ - $(am__append_33) $(am__append_36) + $(am__append_33) $(am__append_36) $(am__append_39) BUILT_SOURCES = $(am__append_16) TESTS = $(check_SCRIPTS) $(check_PROGRAMS) @@ -3193,6 +3197,16 @@ uninstall-am: @DEFAULT_TARGET_X86_64_TRUE@ $(TEST_OBJDUMP) -d $< > $@ @DEFAULT_TARGET_X86_64_TRUE@split_x86_64_r.stdout: split_x86_64_1.o split_x86_64_n.o ../ld-new @DEFAULT_TARGET_X86_64_TRUE@ ../ld-new -r split_x86_64_1.o split_x86_64_n.o -o split_x86_64_r > $@ 2>&1 || exit 0 +@DEFAULT_TARGET_ARM_TRUE@arm_abs_lib.o: arm_abs_lib.s +@DEFAULT_TARGET_ARM_TRUE@ $(TEST_AS) -march=armv7-a -o $@ $< +@DEFAULT_TARGET_ARM_TRUE@libarm_abs.so: arm_abs_lib.o +@DEFAULT_TARGET_ARM_TRUE@ ../ld-new -shared -o $@ arm_abs_lib.o +@DEFAULT_TARGET_ARM_TRUE@arm_abs_global.o: arm_abs_global.s +@DEFAULT_TARGET_ARM_TRUE@ $(TEST_AS) -march=armv7-a -o $@ $< +@DEFAULT_TARGET_ARM_TRUE@arm_abs_global: arm_abs_global.o libarm_abs.so +@DEFAULT_TARGET_ARM_TRUE@ ../ld-new -o $@ arm_abs_global.o -L. -larm_abs +@DEFAULT_TARGET_ARM_TRUE@arm_abs_global.stdout: arm_abs_global +@DEFAULT_TARGET_ARM_TRUE@ $(TEST_READELF) -r $< > $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/gold/testsuite/arm_abs_global.s b/gold/testsuite/arm_abs_global.s new file mode 100644 index 0000000..65cb309 --- /dev/null +++ b/gold/testsuite/arm_abs_global.s @@ -0,0 +1,31 @@ + .syntax unified + + .text + .align 2 + + .global _start + .type _start, %function +_start: + bx lr + .size _start, .-_start + + .global _arm_test + .type _arm_test, %function +_arm_test: + movt r0, #:upper16:_movt_abs_global + movw r0, #:lower16:_movw_abs_global + bx lr + .size _arm_test, .-_arm_test + + .thumb + .global _thumb_test +_thumb_test: + movt r0, #:upper16:_thm_movt_abs_global + movw r0, #:lower16:_thm_movw_abs_global + bx lr + .size _thumb_test, .-_thumb_test + + .data +_data_test: + .word _abs32_global + .word _abs32_global_plt diff --git a/gold/testsuite/arm_abs_global.sh b/gold/testsuite/arm_abs_global.sh new file mode 100755 index 0000000..26abc24 --- /dev/null +++ b/gold/testsuite/arm_abs_global.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# arm_abs_global.sh -- test ARM absolute relocations against global symbols. + +# Copyright 2010 Free Software Foundation, Inc. +# Written by Doug Kwan <dougkwan@google.com> + +# This file is part of gold. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. + +# This file goes with the assembler source file arm_abs_global.s, +# that is assembled and linked with a shared object libarm_abs.so. We +# want to check that a MOV[TW] instruction referencing an external function +# causes a PLT to be created. + +check() +{ + file=$1 + sym=$2 + reloc=$3 + + found=`grep " $sym\$" $file` + if test -z "$found"; then + echo "Symbol $sym not found." + exit 1 + fi + + match_reloc=`grep " $sym\$" $file | grep " $reloc "` + if test -z "$match_reloc"; then + echo "Expected symbol $sym to have relocation $reloc but found" + echo "$found" + exit 1 + fi +} + +check "arm_abs_global.stdout" "_movt_abs_global" "R_ARM_JUMP_SLOT" +check "arm_abs_global.stdout" "_movw_abs_global" "R_ARM_JUMP_SLOT" +check "arm_abs_global.stdout" "_thm_movt_abs_global" "R_ARM_JUMP_SLOT" +check "arm_abs_global.stdout" "_thm_movw_abs_global" "R_ARM_JUMP_SLOT" +check "arm_abs_global.stdout" "_abs32_global_plt" "R_ARM_JUMP_SLOT" +check "arm_abs_global.stdout" "_abs32_global" "R_ARM_ABS32" + +exit 0 diff --git a/gold/testsuite/arm_abs_lib.s b/gold/testsuite/arm_abs_lib.s new file mode 100644 index 0000000..a2d7207 --- /dev/null +++ b/gold/testsuite/arm_abs_lib.s @@ -0,0 +1,37 @@ + .syntax unified + + .text + .align 2 + .global _movt_abs_global + .type _movt_abs_global, %function +_movt_abs_global: + bx lr + .size _movt_abs_global, .-_movt_abs_global + + .global _movw_abs_global + .type _movw_abs_global, %function +_movw_abs_global: + bx lr + .size _movw_abs_global, .-_movw_abs_global + + .thumb + .align 2 + .global _thm_movt_abs_global + .type _thm_movt_abs_global, %function +_thm_movt_abs_global: + bx lr + .size _thm_movt_abs_global, .-_thm_movt_abs_global + + .global _thm_movw_abs_global + .type _thm_movw_abs_global, %function +_thm_movw_abs_global: + bx lr + .size _thm_movw_abs_global, .-_thm_movw_abs_global + + .global _abs32_global_plt + .type _abs32_global_plt, %function +_abs32_global_plt: + bx lr + .size _abs32_global_plt, .-_abs32_global_plt + + .comm _abs32_global,4,4 |