X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gold%2Faarch64.cc;h=46a278bd466bf14dc8f3700963a5882844b7b5c6;hb=5a8f5960fd8fc5136fc24ddaf08a25c73f9c8329;hp=04da01d51fa7626c823ca864cc09a450ac87804a;hpb=e0feb133429709603eeeb382c1ebb6edd0a886aa;p=binutils-gdb.git diff --git a/gold/aarch64.cc b/gold/aarch64.cc index 04da01d51fa..46a278bd466 100644 --- a/gold/aarch64.cc +++ b/gold/aarch64.cc @@ -1,6 +1,6 @@ // aarch64.cc -- aarch64 target support for gold. -// Copyright (C) 2014-2017 Free Software Foundation, Inc. +// Copyright (C) 2014-2023 Free Software Foundation, Inc. // Written by Jing Yu and Han Shen . // This file is part of gold. @@ -1031,6 +1031,18 @@ public: set_erratum_address(AArch64_address addr) { this->erratum_address_ = addr; } + // Later relaxation passes of may alter the recorded erratum and destination + // address. Given an up to date output section address of shidx_ in + // relobj_ we can derive the erratum_address and destination address. + void + update_erratum_address(AArch64_address output_section_addr) + { + const int BPI = AArch64_insn_utilities::BYTES_PER_INSN; + AArch64_address updated_addr = output_section_addr + this->sh_offset_; + this->set_erratum_address(updated_addr); + this->set_destination_address(updated_addr + BPI); + } + // Comparator used to group Erratum_stubs in a set by (obj, shndx, // sh_offset). We do not include 'type' in the calculation, because there is // at most one stub type at (obj, shndx, sh_offset). @@ -1170,7 +1182,8 @@ class Reloc_stub : public Stub_base aarch64_valid_for_adrp_p(AArch64_address location, AArch64_address dest) { typedef AArch64_relocate_functions Reloc; - int64_t adrp_imm = (Reloc::Page(dest) - Reloc::Page(location)) >> 12; + int64_t adrp_imm = Reloc::Page (dest) - Reloc::Page (location); + adrp_imm = adrp_imm < 0 ? ~(~adrp_imm >> 12) : adrp_imm >> 12; return adrp_imm >= MIN_ADRP_IMM && adrp_imm <= MAX_ADRP_IMM; } @@ -2304,6 +2317,19 @@ AArch64_relobj::scan_errata( output_address = poris->address(); } + // Update the addresses in previously generated erratum stubs. Unlike when + // we scan relocations for stubs, if section addresses have changed due to + // other relaxations we are unlikely to scan the same erratum instances + // again. + The_stub_table* stub_table = this->stub_table(shndx); + if (stub_table) + { + std::pair + ipair(stub_table->find_erratum_stubs_for_input_section(this, shndx)); + for (Erratum_stub_set_iter p = ipair.first; p != ipair.second; ++p) + (*p)->update_erratum_address(output_address); + } + section_size_type input_view_size = 0; const unsigned char* input_view = this->section_contents(shndx, &input_view_size, false); @@ -3540,6 +3566,7 @@ const Target::Target_info Target_aarch64<64, false>::aarch64_info = NULL, // attributes_vendor "_start", // entry_symbol_name 32, // hash_entry_size + elfcpp::SHT_PROGBITS, // unwind_section_type }; template<> @@ -3568,6 +3595,7 @@ const Target::Target_info Target_aarch64<32, false>::aarch64_info = NULL, // attributes_vendor "_start", // entry_symbol_name 32, // hash_entry_size + elfcpp::SHT_PROGBITS, // unwind_section_type }; template<> @@ -3596,6 +3624,7 @@ const Target::Target_info Target_aarch64<64, true>::aarch64_info = NULL, // attributes_vendor "_start", // entry_symbol_name 32, // hash_entry_size + elfcpp::SHT_PROGBITS, // unwind_section_type }; template<> @@ -3624,6 +3653,7 @@ const Target::Target_info Target_aarch64<32, true>::aarch64_info = NULL, // attributes_vendor "_start", // entry_symbol_name 32, // hash_entry_size + elfcpp::SHT_PROGBITS, // unwind_section_type }; // Get the GOT section, creating it if necessary. @@ -3943,6 +3973,7 @@ Target_aarch64::scan_reloc_section_for_stubs( const Symbol_value *psymval; bool is_defined_in_discarded_section; unsigned int shndx; + const Symbol* gsym = NULL; if (r_sym < local_count) { sym = NULL; @@ -3995,7 +4026,6 @@ Target_aarch64::scan_reloc_section_for_stubs( } else { - const Symbol* gsym; gsym = object->global_symbol(r_sym); gold_assert(gsym != NULL); if (gsym->is_forwarder()) @@ -4036,16 +4066,16 @@ Target_aarch64::scan_reloc_section_for_stubs( Symbol_value symval2; if (is_defined_in_discarded_section) { + std::string name = object->section_name(relinfo->data_shndx); + if (comdat_behavior == CB_UNDETERMINED) - { - std::string name = object->section_name(relinfo->data_shndx); comdat_behavior = default_comdat_behavior.get(name.c_str()); - } + if (comdat_behavior == CB_PRETEND) { bool found; typename elfcpp::Elf_types::Elf_Addr value = - object->map_to_kept_section(shndx, &found); + object->map_to_kept_section(shndx, name, &found); if (found) symval2.set_output_value(value + psymval->input_value()); else @@ -4053,10 +4083,8 @@ Target_aarch64::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(); @@ -5891,6 +5919,14 @@ Target_aarch64::optimize_tls_reloc(bool is_final, case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12: case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12: case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST8_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST16_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST32_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST64_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: // When we already have Local-Exec, there is nothing further we // can do. return tls::TLSOPT_NONE; @@ -6237,6 +6273,14 @@ Target_aarch64::Scan::local( case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12: case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12: case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST8_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST16_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST32_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST64_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: { layout->set_has_static_tls(); bool output_is_shared = parameters->options().shared(); @@ -6453,6 +6497,17 @@ Target_aarch64::Scan::global( gold_error(_("%s: unsupported reloc %u in pos independent link."), object->name().c_str(), r_type); } + // Make a PLT entry if necessary. + if (gsym->needs_plt_entry()) + { + 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(); + } break; case elfcpp::R_AARCH64_LD_PREL_LO19: // 273 @@ -6654,7 +6709,15 @@ Target_aarch64::Scan::global( case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC: case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12: case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12: - case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: // Local executable + case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST8_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST16_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST32_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST64_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: // Local executable layout->set_has_static_tls(); if (parameters->options().shared()) gold_error(_("%s: unsupported TLSLE reloc type %u in shared objects."), @@ -6914,11 +6977,11 @@ Target_aarch64::do_finalize_sections( } // Set the size of the _GLOBAL_OFFSET_TABLE_ symbol to the size of - // the .got.plt section. + // the .got section. Symbol* sym = this->global_offset_table_; if (sym != NULL) { - uint64_t data_size = this->got_plt_->current_data_size(); + uint64_t data_size = this->got_->current_data_size(); symtab->get_sized_symbol(sym)->set_symsize(data_size); // If the .got section is more than 0x8000 bytes, we add @@ -7251,6 +7314,14 @@ Target_aarch64::Relocate::relocate( case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12: case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12: case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST8_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST16_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST32_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST64_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21: case elfcpp::R_AARCH64_TLSDESC_LD64_LO12: case elfcpp::R_AARCH64_TLSDESC_ADD_LO12: @@ -7530,6 +7601,14 @@ Target_aarch64::Relocate::relocate_tls( case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12: case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12: case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST8_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST16_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST32_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: + case elfcpp::R_AARCH64_TLSLE_LDST64_TPREL_LO12: + case elfcpp::R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: { gold_assert(tls_segment != NULL); AArch64_address value = psymval->value(object, 0);