diff --git a/gold/aarch64.cc b/gold/aarch64.cc index aa1558f..130fcc2 100644 --- a/gold/aarch64.cc +++ b/gold/aarch64.cc @@ -581,71 +581,42 @@ template class AArch64_relobj; -// Stub type enum constants wrapped in a struct, so we refer to them as -// Stub_type::ST_XXX instead of ST_XXX. -struct Stub_type +// Stub type enum constants. + +enum { - enum - { - ST_NONE = 0, + ST_NONE = 0, - // Using adrp/add pair, 4 insns (including alignment) without mem access, - // the fastest stub. This has a limited jump distance, which is tested by - // aarch64_valid_for_adrp_p. - ST_ADRP_BRANCH = 1, + // Using adrp/add pair, 4 insns (including alignment) without mem access, + // the fastest stub. This has a limited jump distance, which is tested by + // aarch64_valid_for_adrp_p. + ST_ADRP_BRANCH = 1, - // Using ldr-absolute-address/br-register, 4 insns with 1 mem access, - // unlimited in jump distance. - ST_LONG_BRANCH_ABS = 2, + // Using ldr-absolute-address/br-register, 4 insns with 1 mem access, + // unlimited in jump distance. + ST_LONG_BRANCH_ABS = 2, - // Using ldr/calculate-pcrel/jump, 8 insns (including alignment) with 1 - // mem access, slowest one. Only used in position independent executables. - ST_LONG_BRANCH_PCREL = 3, + // Using ldr/calculate-pcrel/jump, 8 insns (including alignment) with 1 + // mem access, slowest one. Only used in position independent executables. + ST_LONG_BRANCH_PCREL = 3, - // Stub for erratum 843419 handling. - ST_E_843419 = 4, + // Stub for erratum 843419 handling. + ST_E_843419 = 4, - // Number of total stub types. - ST_NUMBER = 5 - }; - -private: - // Never allow any such instance. - Stub_type(); + // Number of total stub types. + ST_NUMBER = 5 }; -// Class that wraps insns for a particular stub. All stub templates are +// Struct that wraps insns for a particular stub. All stub templates are // created/initialized as constants by Stub_template_repertoire. template -class Stub_template +struct Stub_template { -public: - typedef typename AArch64_insn_utilities::Insntype Insntype; - - Stub_template(const Insntype* insns, const int insn_num) - : insns_(insns), insn_num_(insn_num) - {} - - ~Stub_template() {} - - // Get number of stub insns. - int - insn_num() const - { return this->insn_num_; } - - // Get the stub insn array. - const Insntype* - insns() const - { return this->insns_; } - -private: - // Stub insn array. - const Insntype* insns_; - // Number of stub insns. - const int insn_num_; -}; // End of "class Stub_template". + const typename AArch64_insn_utilities::Insntype* insns; + const int insn_num; +}; // Simple singleton class that creates/initializes/stores all types of stub @@ -657,31 +628,26 @@ class Stub_template_repertoire public: typedef typename AArch64_insn_utilities::Insntype Insntype; - // Get singleton instance. - static Stub_template_repertoire* - get_instance() - { - static Stub_template_repertoire singleton; - return &singleton; - } - - // Get stub template for a given stub type. - Stub_template* + // Single static method to get stub template for a given stub type. + static const Stub_template* get_stub_template(int type) - { return this->stub_templates_[type]; } + { + static Stub_template_repertoire singleton; + return singleton.stub_templates_[type]; + } private: - // Constructor - creates/initilizes all stub templates. + // Constructor - creates/initializes all stub templates. Stub_template_repertoire(); + ~Stub_template_repertoire() + { } - // Destructor - deletes all stub templates. - ~Stub_template_repertoire(); - + // Disallowing copy ctor and copy assignment operator. Stub_template_repertoire(Stub_template_repertoire&); - Stub_template_repertoire& operator = (Stub_template_repertoire&); + Stub_template_repertoire& operator=(Stub_template_repertoire&); // Data that stores all insn templates. - Stub_template* stub_templates_[Stub_type::ST_NUMBER]; + const Stub_template* stub_templates_[ST_NUMBER]; }; // End of "class Stub_template_repertoire". @@ -730,8 +696,9 @@ Stub_template_repertoire::Stub_template_repertoire() }; #define install_insn_template(T) \ - this->stub_templates_[Stub_type::T] = new Stub_template( \ - T##_INSNS, sizeof(T##_INSNS) / sizeof(T##_INSNS[0])) + const static Stub_template template_##T = { \ + T##_INSNS, sizeof(T##_INSNS) / sizeof(T##_INSNS[0]) }; \ + this->stub_templates_[T] = &template_##T install_insn_template(ST_NONE); install_insn_template(ST_ADRP_BRANCH); @@ -743,16 +710,6 @@ Stub_template_repertoire::Stub_template_repertoire() } -// Destructor that deletes all stub templates. - -template -Stub_template_repertoire::~Stub_template_repertoire() -{ - for (int i = 0; i < Stub_type::ST_NUMBER; ++i) - delete stub_templates_[i]; -} - - // Base class for stubs. template @@ -771,10 +728,7 @@ public: Stub_base(int type) : destination_address_(invalid_address), offset_(invalid_offset), - type_(type), - // Initialize a stub template by stub type from stub repertoire. - stub_template_(Stub_template_repertoire:: - get_instance()->get_stub_template(type)) + type_(type) {} ~Stub_base() @@ -785,6 +739,14 @@ public: type() const { return this->type_; } + // Get stub template that provides stub insn information. + const Stub_template* + stub_template() const + { + return Stub_template_repertoire:: + get_stub_template(this->type()); + } + // Get destination address. AArch64_address destination_address() const @@ -824,12 +786,12 @@ public: // Return the stub insn. const Insntype* insns() const - { return this->stub_template_->insns(); } + { return this->stub_template()->insns; } // Return num of stub insns. unsigned int insn_num() const - { return this->stub_template_->insn_num(); } + { return this->stub_template()->insn_num; } // Get size of the stub. int @@ -855,20 +817,20 @@ private: AArch64_address destination_address_; // The stub offset. Note this has difference interpretations between an // Reloc_stub and an Erratum_stub. For Reloc_stub this is the offset from the - // beginning of the containng stub_table, whereas for Erratum_stub, this is + // beginning of the containing stub_table, whereas for Erratum_stub, this is // the offset from the end of reloc_stubs. section_offset_type offset_; // Stub type. const int type_; - // Stub template that provides stub insn information. - const Stub_template* stub_template_; }; // End of "Stub_base". // Erratum stub class. An erratum stub differs from a reloc stub in that for -// each erratum occurrence, we generates an erratum stub, we never share erratum +// each erratum occurrence, we generate an erratum stub. We never share erratum // stubs, whereas for reloc stubs, different branches insns share a single reloc -// stub as long as the branch targets are the same. +// stub as long as the branch targets are the same. (More to the point, reloc +// stubs can be shared because they're used to reach a specific target, whereas +// erratum stubs branch back to the original control flow.) template class Erratum_stub : public Stub_base @@ -991,7 +953,7 @@ Erratum_stub::do_write(unsigned char* view, section_size_type) Insntype* ip = reinterpret_cast(view); // For current implemnted erratum 843419, (and 835769 which is to be // implemented soon), the first insn in the stub is always a copy of the - // problmatic insn (in 843419, the mem access insn), followed by a jump-back. + // problematic insn (in 843419, the mem access insn), followed by a jump-back. elfcpp::Swap<32, big_endian>::writeval(ip, this->erratum_insn()); for (uint32_t i = 1; i < num_insns; ++i) elfcpp::Swap<32, big_endian>::writeval(ip + i, insns[i]); @@ -1201,16 +1163,16 @@ Reloc_stub::stub_type_for_reloc( } if (aarch64_valid_branch_offset_p(branch_offset)) - return Stub_type::ST_NONE; + return ST_NONE; if (aarch64_valid_for_adrp_p(location, dest)) - return Stub_type::ST_ADRP_BRANCH; + return ST_ADRP_BRANCH; if (parameters->options().output_is_position_independent() && parameters->options().output_is_executable()) - return Stub_type::ST_LONG_BRANCH_PCREL; + return ST_LONG_BRANCH_PCREL; - return Stub_type::ST_LONG_BRANCH_ABS; + return ST_LONG_BRANCH_ABS; } // A class to hold stubs for the ARM target. @@ -1403,7 +1365,7 @@ Stub_table::find_erratum_stub( The_aarch64_relobj* a64relobj, unsigned int shndx, unsigned int sh_offset) { // A dummy object used as key to search in the set. - The_erratum_stub key(a64relobj, Stub_type::ST_NONE, + The_erratum_stub key(a64relobj, ST_NONE, shndx, sh_offset); Erratum_stub_set_iter i = this->erratum_stubs_.find(&key); if (i != this->erratum_stubs_.end()) @@ -1416,7 +1378,7 @@ Stub_table::find_erratum_stub( } -// Find all the errata for a given input sectin. The return value is a pair of +// Find all the errata for a given input section. The return value is a pair of // iterators [begin, end). template @@ -1427,7 +1389,7 @@ Stub_table::find_erratum_stubs_for_input_section( { typedef std::pair Result_pair; Erratum_stub_set_iter start, end; - The_erratum_stub low_key(a64relobj, Stub_type::ST_NONE, shndx, 0); + The_erratum_stub low_key(a64relobj, ST_NONE, shndx, 0); start = this->erratum_stubs_.lower_bound(&low_key); if (start == this->erratum_stubs_.end()) return Result_pair(this->erratum_stubs_.end(), @@ -1480,6 +1442,9 @@ relocate_stubs(const The_relocate_info* relinfo, relocate_stub(p->second, relinfo, target_aarch64, output_section, view, address, view_size); + // Just for convenience. + const int BPI = AArch64_insn_utilities::BYTES_PER_INSN; + // Now 'relocate' erratum stubs. for(Erratum_stub_set_iter i = this->erratum_stubs_.begin(); i != this->erratum_stubs_.end(); ++i) @@ -1491,11 +1456,10 @@ relocate_stubs(const The_relocate_info* relinfo, int b_offset = 0; switch ((*i)->type()) { - case Stub_type::ST_E_843419: + case ST_E_843419: // For the erratum, the 2nd insn is a b-insn to be patched // (relocated). - stub_b_insn_address = stub_address - + 1 * AArch64_insn_utilities::BYTES_PER_INSN; + stub_b_insn_address = stub_address + 1 * BPI; b_offset = (*i)->destination_address() - stub_b_insn_address; AArch64_relocate_functions::construct_b( view + (stub_b_insn_address - this->address()), @@ -3507,7 +3471,7 @@ Target_aarch64::scan_reloc_for_stub( int stub_type = The_reloc_stub:: stub_type_for_reloc(r_type, address, destination); - if (stub_type == Stub_type::ST_NONE) + if (stub_type == ST_NONE) return; The_stub_table* stub_table = aarch64_relobj->stub_table(relinfo->data_shndx); @@ -3774,7 +3738,7 @@ relocate_stub(The_reloc_stub* stub, switch(stub->type()) { - case Stub_type::ST_ADRP_BRANCH: + case ST_ADRP_BRANCH: { // 1st reloc is ADR_PREL_PG_HI21 The_reloc_functions_status status = @@ -3795,12 +3759,12 @@ relocate_stub(The_reloc_stub* stub, } break; - case Stub_type::ST_LONG_BRANCH_ABS: + case ST_LONG_BRANCH_ABS: // 1st reloc is R_AARCH64_PREL64, at offset 8 elfcpp::Swap<64,big_endian>::writeval(view + 8, dest); break; - case Stub_type::ST_LONG_BRANCH_PCREL: + case ST_LONG_BRANCH_PCREL: { // "PC" calculation is the 2nd insn in the stub. uint64_t offset = dest - (address + 4); @@ -5137,7 +5101,7 @@ maybe_apply_stub(unsigned int r_type, Address branch_target = psymval->value(object, 0) + addend; int stub_type = The_reloc_stub::stub_type_for_reloc(r_type, address, branch_target); - if (stub_type == Stub_type::ST_NONE) + if (stub_type == ST_NONE) return false; const The_aarch64_relobj* aarch64_relobj = @@ -7790,7 +7754,7 @@ Target_aarch64::scan_erratum_843419_span( errata_insn_offset) == NULL) { The_erratum_stub* stub = new The_erratum_stub( - relobj, Stub_type::ST_E_843419, shndx, + relobj, ST_E_843419, shndx, errata_insn_offset); Address erratum_address = output_address + offset + insn_offset;