diff options
-rw-r--r-- | gold/ChangeLog | 14 | ||||
-rw-r--r-- | gold/arm.cc | 92 |
2 files changed, 61 insertions, 45 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 1c0401e3743..9d5883f5aa6 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,17 @@ +2009-12-05 Doug Kwan <dougkwan@google.com> + + * arm.cc: Update comments about interworking and stub generation. + (Target_arm::Relocate::reloc_is_non_pic): Update list of relocations + considered as non-PIC. + (Arm_relocate_functions::base_abs): Fix formatting. + (Arm_relocate_functions::got_prel): Fix comment. Change interface + of function to use GOT entry address instead of offset. + (Target_arm::Scan::global): Issue an error if a symbol would need a + PLT does not get one because it is untyped. Remove code to create + dynamic symbols for relative branches. + (Target_arm::Relocate::relocate: Use 0 instead of false since function + takes unsigned integer instead of boolean. + 2009-12-05 H.J. Lu <hongjiu.lu@intel.com> * testsuite/Makefile.am (constructor_test_LDADD): New. Empty. diff --git a/gold/arm.cc b/gold/arm.cc index d8c58ea5d16..aa5ec8cd2cd 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -121,8 +121,6 @@ const int32_t THM2_MAX_BWD_BRANCH_OFFSET = (-(1 << 24) + 4); // R_ARM_THM_MOVT_PREL // // TODOs: -// - Generate various branch stubs. -// - Support interworking. // - Support more relocation types as needed. // - Make PLTs more flexible for different architecture features like // Thumb-2 and BE8. @@ -1475,25 +1473,36 @@ class Target_arm : public Sized_target<32, big_endian> section_size_type); // Return whether we want to pass flag NON_PIC_REF for this - // reloc. + // reloc. This means the relocation type accesses a symbol not via + // GOT or PLT. static inline bool reloc_is_non_pic (unsigned int r_type) { switch (r_type) { - case elfcpp::R_ARM_REL32: - case elfcpp::R_ARM_THM_CALL: + // These relocation types reference GOT or PLT entries explicitly. + case elfcpp::R_ARM_GOT_BREL: + case elfcpp::R_ARM_GOT_ABS: + case elfcpp::R_ARM_GOT_PREL: + case elfcpp::R_ARM_GOT_BREL12: + case elfcpp::R_ARM_PLT32_ABS: + case elfcpp::R_ARM_TLS_GD32: + case elfcpp::R_ARM_TLS_LDM32: + case elfcpp::R_ARM_TLS_IE32: + case elfcpp::R_ARM_TLS_IE12GP: + + // These relocate types may use PLT entries. case elfcpp::R_ARM_CALL: + case elfcpp::R_ARM_THM_CALL: case elfcpp::R_ARM_JUMP24: - case elfcpp::R_ARM_PREL31: - 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: - return true; - default: + case elfcpp::R_ARM_THM_JUMP24: + case elfcpp::R_ARM_THM_JUMP19: + case elfcpp::R_ARM_PLT32: + case elfcpp::R_ARM_THM_XPC22: return false; + + default: + return true; } } }; @@ -1925,7 +1934,7 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian> // R_ARM_BASE_ABS: B(S) + A static inline typename This::Status base_abs(unsigned char* view, - Arm_address origin) + Arm_address origin) { Base::rel32(view, origin); return STATUS_OKAY; @@ -1940,13 +1949,13 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian> return This::STATUS_OKAY; } - // R_ARM_GOT_PREL: GOT(S) + A – P + // R_ARM_GOT_PREL: GOT(S) + A - P static inline typename This::Status - got_prel(unsigned char* view, - typename elfcpp::Swap<32, big_endian>::Valtype got_offset, + got_prel(unsigned char *view, + Arm_address got_entry, Arm_address address) { - Base::rel32(view, got_offset - address); + Base::rel32(view, got_entry - address); return This::STATUS_OKAY; } @@ -4381,33 +4390,26 @@ Target_arm<big_endian>::Scan::global(Symbol_table* symtab, break; case elfcpp::R_ARM_JUMP24: - case elfcpp::R_ARM_THM_CALL: + case elfcpp::R_ARM_THM_JUMP24: case elfcpp::R_ARM_CALL: - { - if (Target_arm<big_endian>::Scan::symbol_needs_plt_entry(gsym)) - target->make_plt_entry(symtab, layout, gsym); - // Make a dynamic relocation if necessary. - 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)) - { - if (target->may_need_copy_reloc(gsym)) - { - target->copy_reloc(symtab, layout, object, - data_shndx, output_section, gsym, - reloc); - } - 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()); - } - } - } + case elfcpp::R_ARM_THM_CALL: + + if (Target_arm<big_endian>::Scan::symbol_needs_plt_entry(gsym)) + target->make_plt_entry(symtab, layout, gsym); + else + { + // Check to see if this is a function that would need a PLT + // but does not get one because the function symbol is untyped. + // This happens in assembly code missing a proper .type directive. + if ((!gsym->is_undefined() || parameters->options().shared()) + && !parameters->doing_static_link() + && gsym->type() == elfcpp::STT_NOTYPE + && (gsym->is_from_dynobj() + || gsym->is_undefined() + || gsym->is_preemptible())) + gold_error(_("%s is not a function."), + gsym->demangled_name().c_str()); + } break; case elfcpp::R_ARM_PLT32: @@ -4857,7 +4859,7 @@ Target_arm<big_endian>::Relocate::relocate( output_section)) // No thumb bit for this relocation: (S + A) reloc_status = Arm_relocate_functions::abs32(view, object, psymval, - false); + 0); break; case elfcpp::R_ARM_MOVW_ABS_NC: |