X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gold%2Farm.cc;h=ad11c1bb007fd57102a36135c96867c41c67cbf8;hb=8df017996f662ce6ab23aea4abeb8f7ac1f62651;hp=ea20c3762605ae13cdf5651af41f9f7a819a6b5c;hpb=0f1254327820d7b3f67f873aa40e76679f067288;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/arm.cc b/gold/arm.cc index ea20c37626..ad11c1bb00 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -1,6 +1,6 @@ // arm.cc -- arm target support for gold. -// Copyright (C) 2009-2016 Free Software Foundation, Inc. +// Copyright (C) 2009-2020 Free Software Foundation, Inc. // Written by Doug Kwan based on the i386 code // by Ian Lance Taylor . // This file also contains borrowed and adapted code from @@ -129,7 +129,7 @@ const size_t ARM_TCB_SIZE = 8; // Target::do_select_as_default_target() hook so that we do not spend time // building the table if we are not linking ARM objects. // -// An alternative is to to process the information in arm-reloc.def in +// An alternative is to process the information in arm-reloc.def in // compilation time and generate a representation of it in PODs only. That // way we can avoid initialization when the linker starts. @@ -2132,32 +2132,7 @@ class Target_arm : public Sized_target<32, big_endian> target1_reloc_(elfcpp::R_ARM_ABS32), // This can be any reloc type but usually is R_ARM_GOT_PREL. target2_reloc_(elfcpp::R_ARM_GOT_PREL) - { - if (parameters->options().user_set_target1_rel()) - { - // FIXME: This is not strictly compatible with ld, which allows both - // --target1-abs and --target-rel to be given. - if (parameters->options().user_set_target1_abs()) - gold_error(_("Cannot use both --target1-abs and --target1-rel.")); - else - this->target1_reloc_ = elfcpp::R_ARM_REL32; - } - // We don't need to handle --target1-abs because target1_reloc_ is set - // to elfcpp::R_ARM_ABS32 in the member initializer list. - - if (parameters->options().user_set_target2()) - { - const char* target2 = parameters->options().target2(); - if (strcmp(target2, "rel") == 0) - this->target2_reloc_ = elfcpp::R_ARM_REL32; - else if (strcmp(target2, "abs") == 0) - this->target2_reloc_ = elfcpp::R_ARM_ABS32; - else if (strcmp(target2, "got-rel") == 0) - this->target2_reloc_ = elfcpp::R_ARM_GOT_PREL; - else - gold_unreachable(); - } - } + { } // Whether we force PCI branch veneers. bool @@ -2571,6 +2546,30 @@ class Target_arm : public Sized_target<32, big_endian> // as the default. gold_assert(arm_reloc_property_table == NULL); arm_reloc_property_table = new Arm_reloc_property_table(); + if (parameters->options().user_set_target1_rel()) + { + // FIXME: This is not strictly compatible with ld, which allows both + // --target1-abs and --target-rel to be given. + if (parameters->options().user_set_target1_abs()) + gold_error(_("Cannot use both --target1-abs and --target1-rel.")); + else + this->target1_reloc_ = elfcpp::R_ARM_REL32; + } + // We don't need to handle --target1-abs because target1_reloc_ is set + // to elfcpp::R_ARM_ABS32 in the member initializer list. + + if (parameters->options().user_set_target2()) + { + const char* target2 = parameters->options().target2(); + if (strcmp(target2, "rel") == 0) + this->target2_reloc_ = elfcpp::R_ARM_REL32; + else if (strcmp(target2, "abs") == 0) + this->target2_reloc_ = elfcpp::R_ARM_ABS32; + else if (strcmp(target2, "got-rel") == 0) + this->target2_reloc_ = elfcpp::R_ARM_GOT_PREL; + else + gold_unreachable(); + } } // Virtual function which is set to return true by a target if @@ -3063,6 +3062,7 @@ const Target::Target_info Target_arm::arm_info = "aeabi", // attributes_vendor "_start", // entry_symbol_name 32, // hash_entry_size + elfcpp::SHT_PROGBITS, // unwind_section_type }; // Arm relocate functions class @@ -3425,7 +3425,7 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian> const Symbol_value<32>* psymval, Arm_address address, Arm_address thumb_bit); - // R_ARM_THM_JUMP6: S + A – P + // R_ARM_THM_JUMP6: S + A - P static inline typename This::Status thm_jump6(unsigned char* view, const Sized_relobj_file<32, big_endian>* object, @@ -3436,7 +3436,7 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian> typedef typename elfcpp::Swap<16, big_endian>::Valtype Reltype; Valtype* wv = reinterpret_cast(view); Valtype val = elfcpp::Swap<16, big_endian>::readval(wv); - // bit[9]:bit[7:3]:’0’ (mask: 0x02f8) + // bit[9]:bit[7:3]:'0' (mask: 0x02f8) Reltype addend = (((val & 0x0200) >> 3) | ((val & 0x00f8) >> 2)); Reltype x = (psymval->value(object, addend) - address); val = (val & 0xfd07) | ((x & 0x0040) << 3) | ((val & 0x003e) << 2); @@ -3447,7 +3447,7 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian> : This::STATUS_OKAY); } - // R_ARM_THM_JUMP8: S + A – P + // R_ARM_THM_JUMP8: S + A - P static inline typename This::Status thm_jump8(unsigned char* view, const Sized_relobj_file<32, big_endian>* object, @@ -3467,7 +3467,7 @@ class Arm_relocate_functions : public Relocate_functions<32, big_endian> : This::STATUS_OKAY); } - // R_ARM_THM_JUMP11: S + A – P + // R_ARM_THM_JUMP11: S + A - P static inline typename This::Status thm_jump11(unsigned char* view, const Sized_relobj_file<32, big_endian>* object, @@ -4517,30 +4517,49 @@ Stub::do_fixed_endian_write(unsigned char* view, section_size_type view_size) { const Stub_template* stub_template = this->stub_template(); const Insn_template* insns = stub_template->insns(); + const bool enable_be8 = parameters->options().be8(); - // FIXME: We do not handle BE8 encoding yet. unsigned char* pov = view; for (size_t i = 0; i < stub_template->insn_count(); i++) { switch (insns[i].type()) { case Insn_template::THUMB16_TYPE: - elfcpp::Swap<16, big_endian>::writeval(pov, insns[i].data() & 0xffff); + if (enable_be8) + elfcpp::Swap<16, false>::writeval(pov, insns[i].data() & 0xffff); + else + elfcpp::Swap<16, big_endian>::writeval(pov, + insns[i].data() & 0xffff); break; case Insn_template::THUMB16_SPECIAL_TYPE: - elfcpp::Swap<16, big_endian>::writeval( - pov, - this->thumb16_special(i)); + if (enable_be8) + elfcpp::Swap<16, false>::writeval(pov, this->thumb16_special(i)); + else + elfcpp::Swap<16, big_endian>::writeval(pov, + this->thumb16_special(i)); break; case Insn_template::THUMB32_TYPE: { uint32_t hi = (insns[i].data() >> 16) & 0xffff; uint32_t lo = insns[i].data() & 0xffff; - elfcpp::Swap<16, big_endian>::writeval(pov, hi); - elfcpp::Swap<16, big_endian>::writeval(pov + 2, lo); + if (enable_be8) + { + elfcpp::Swap<16, false>::writeval(pov, hi); + elfcpp::Swap<16, false>::writeval(pov + 2, lo); + } + else + { + elfcpp::Swap<16, big_endian>::writeval(pov, hi); + elfcpp::Swap<16, big_endian>::writeval(pov + 2, lo); + } } break; case Insn_template::ARM_TYPE: + if (enable_be8) + elfcpp::Swap<32, false>::writeval(pov, insns[i].data()); + else + elfcpp::Swap<32, big_endian>::writeval(pov, insns[i].data()); + break; case Insn_template::DATA_TYPE: elfcpp::Swap<32, big_endian>::writeval(pov, insns[i].data()); break; @@ -6588,9 +6607,9 @@ Arm_relobj::do_relocate_sections( Output_file* of, typename Sized_relobj_file<32, big_endian>::Views* pviews) { - // Call parent to relocate sections. - Sized_relobj_file<32, big_endian>::do_relocate_sections(symtab, layout, - pshdrs, of, pviews); + // Relocate the section data. + this->relocate_section_range(symtab, layout, pshdrs, of, pviews, + 1, this->shnum() - 1); // We do not generate stubs if doing a relocatable link. if (parameters->options().relocatable()) @@ -11661,7 +11680,7 @@ Target_arm::merge_object_attributes( if (in_attr[elfcpp::Tag_MPextension_use].int_value() != in_attr[i].int_value()) { - gold_error(_("%s has has both the current and legacy " + gold_error(_("%s has both the current and legacy " "Tag_MPextension_use attributes"), name); } @@ -12121,6 +12140,7 @@ Target_arm::scan_reloc_section_for_stubs( const Symbol_value<32> *psymval; bool is_defined_in_discarded_section; unsigned int shndx; + const Symbol* gsym = NULL; if (r_sym < local_count) { sym = NULL; @@ -12173,7 +12193,6 @@ Target_arm::scan_reloc_section_for_stubs( } else { - const Symbol* gsym; gsym = arm_object->global_symbol(r_sym); gold_assert(gsym != NULL); if (gsym->is_forwarder()) @@ -12214,11 +12233,11 @@ Target_arm::scan_reloc_section_for_stubs( Symbol_value<32> symval2; if (is_defined_in_discarded_section) { + std::string name = arm_object->section_name(relinfo->data_shndx); + if (comdat_behavior == CB_UNDETERMINED) - { - std::string name = arm_object->section_name(relinfo->data_shndx); comdat_behavior = default_comdat_behavior.get(name.c_str()); - } + if (comdat_behavior == CB_PRETEND) { // FIXME: This case does not work for global symbols. @@ -12228,7 +12247,7 @@ Target_arm::scan_reloc_section_for_stubs( // script. bool found; typename elfcpp::Elf_types<32>::Elf_Addr value = - arm_object->map_to_kept_section(shndx, &found); + arm_object->map_to_kept_section(shndx, name, &found); if (found) symval2.set_output_value(value + psymval->input_value()); else @@ -12236,10 +12255,8 @@ Target_arm::scan_reloc_section_for_stubs( } else { - if (comdat_behavior == CB_WARNING) - gold_warning_at_location(relinfo, i, offset, - _("relocation refers to discarded " - "section")); + if (comdat_behavior == CB_ERROR) + issue_discarded_error(relinfo, i, offset, r_sym, gsym); symval2.set_output_value(0); } symval2.set_no_output_symtab_entry(); @@ -12776,7 +12793,7 @@ Target_arm::scan_span_for_cortex_a8_erratum( Arm_address target = (pc_for_insn + offset) | (is_blx ? 0 : 1); - // Add a new stub if destination address in in the same page. + // Add a new stub if destination address is in the same page. if (((address + i) & ~0xfffU) == (target & ~0xfffU)) { Cortex_a8_stub* stub = @@ -12878,7 +12895,7 @@ Target_arm::fix_exidx_coverage( const Task* task) { // We need to look at all the input sections in output in ascending - // order of of output address. We do that by building a sorted list + // order of output address. We do that by building a sorted list // of output sections by addresses. Then we looks at the output sections // in order. The input sections in an output section are already sorted // by addresses within the output section. @@ -13038,6 +13055,7 @@ const Target::Target_info Target_arm_nacl::arm_nacl_info = "aeabi", // attributes_vendor "_start", // entry_symbol_name 32, // hash_entry_size + elfcpp::SHT_PROGBITS, // unwind_section_type }; template