From fd6798fa2d6f0374d45449c4212869da93623b1e Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Thu, 30 Nov 2017 15:07:26 -0800 Subject: Fix internal error in fix_errata on aarch64. The addresses of erratum stubs can be changed by relaxation passes, and need to be updated. gold/ PR gold/20765 * aarch64.cc (Aarch64_relobj::update_erratum_address): New method. (AArch64_relobj::scan_errata): Update addresses in stub table after relaxation pass. --- gold/ChangeLog | 7 +++++++ gold/aarch64.cc | 25 +++++++++++++++++++++++++ 2 files changed, 32 insertions(+) (limited to 'gold') diff --git a/gold/ChangeLog b/gold/ChangeLog index 1245da5..43a3d70 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,4 +1,11 @@ 2017-11-30 Peter Smith + + PR gold/20765 + * aarch64.cc (Aarch64_relobj::update_erratum_address): New method. + (AArch64_relobj::scan_errata): Update addresses in stub table after + relaxation pass. + +2017-11-30 Peter Smith Cary Coutant PR gold/20765 diff --git a/gold/aarch64.cc b/gold/aarch64.cc index 04da01d..5e702db 100644 --- a/gold/aarch64.cc +++ b/gold/aarch64.cc @@ -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). @@ -2304,6 +2316,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); -- cgit v1.1