diff options
author | Jing Yu <jingyu@google.com> | 2014-08-08 14:18:35 -0700 |
---|---|---|
committer | Jing Yu <jingyu@google.com> | 2014-08-08 14:18:35 -0700 |
commit | 9363c7c3ad54a5f92d74ec8e48eda570de229f63 (patch) | |
tree | a1c7605c93a72b11d9ed6634b0e2891e8ae44b8d /gold/aarch64-reloc-property.h | |
parent | a957de07689be21b85497bdfea6389068f8c9375 (diff) | |
download | fsf-binutils-gdb-9363c7c3ad54a5f92d74ec8e48eda570de229f63.zip fsf-binutils-gdb-9363c7c3ad54a5f92d74ec8e48eda570de229f63.tar.gz fsf-binutils-gdb-9363c7c3ad54a5f92d74ec8e48eda570de229f63.tar.bz2 |
gold aarch64 patch to enable linking hello_wolrd.
elfcpp/ChangeLog:
2014-08-08 Han Shen <shenhan@google.com>
* aarch64.h (withdrawn): Replaced with R_AARCH64_withdrawn.
2014-08-08 Jing Yu <jingyu@google.com>
Han Shen <shenhan@google.com>
* Makefile.am (HFILES): Add aarch64-reloc-property.h.
(DEFFILES): add aarch64-reloc.def.
(TARGETSOURCES): Add aarch64-reloc-property.cc.
(ALL_TARGETOBJS): Add aarch64-reloc-property.$(OBJEXT).
* Makefile.in: Regenerate.
* aarch64-reloc-property.cc: New file.
* aarch64-reloc-property.h: New file.
* aarch64-reloc.def: New file.
* aarch64.cc: Include aarch64-reloc-property.h. Replace spaces
with tab to make the format consistent.
(Output_data_got_aarch64::symbol_table_): New method.
(Target_aarch64::do_plt_address_for_global): New method.
(Target_aarch64::do_plt_address_for_local): New method.
(Target_aarch64::do_select_as_default_target): New method.
(Target_aarch64::do_make_data_plt): New method.
(Target_aarch64::make_data_plt): New method.
(Output_data_plt_aarch64::has_irelative_section): New method.
(Output_data_plt_aarch64::address_for_global): New method.
(Output_data_plt_aarch64::address_for_local): New method.
(Output_data_plt_aarch64::irelative_rel_): New parameter.
(Output_data_plt_aarch64::add_entry): Implement contents.
(Output_data_plt_aarch64::set_final_data_size): Fix typo.
(Output_data_plt_aarch64::do_write): Remove useless got_base. Set
the got_pov entry to plt0.
(Output_data_plt_aarch64_standard::do_fill_first_plt_entry):
Implement contents.
(Output_data_plt_aarch64_standard::do_fill_plt_entry): Implement.
(AArch64_howto): New struct.
(aarch64_howto[]): New static const array.
(AArch64_relocate_functions): New class.
(Target_aarch64::Scan::get_reference_flags): Remove method.
(Target_aarch64::Scan::local): Implement to support a few relocations.
(Target_aarch64::Scan::global): Implement to support a few relocations.
(Target_aarch64::make_plt_section): Implement contents.
(Target_aarch64::make_plt_entry): Implement contents.
(Target_aarch64::do_finalize_sections): Implement contents.
(Target_aarch64::Relocate::relocate): Implement a few relocations.
(Target_aarch64::relocate_section): Implement contents.
Diffstat (limited to 'gold/aarch64-reloc-property.h')
-rw-r--r-- | gold/aarch64-reloc-property.h | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/gold/aarch64-reloc-property.h b/gold/aarch64-reloc-property.h new file mode 100644 index 0000000..d8d1301 --- /dev/null +++ b/gold/aarch64-reloc-property.h @@ -0,0 +1,245 @@ +// aarch64-reloc-property.h -- AArch64 relocation properties -*- C++ -*- + +// Copyright (C) 2014 Free Software Foundation, Inc. +// Written by Han Shen <shenhan@google.com> and Jing Yu <jingyu@google.com>. + +// This file is part of gold. + +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +// MA 02110-1301, USA. + +#ifndef GOLD_AARCH64_RELOC_PROPERTY_H +#define GOLD_AARCH64_RELOC_PROPERTY_H + +#include<vector> +#include<string> + +#include"aarch64.h" + +namespace gold +{ +// The AArch64_reloc_property class is to store information about a particular +// relocation code. + +class AArch64_reloc_property +{ + public: + // Types of relocation codes. + enum Reloc_type { + RT_NONE, // No relocation type. + RT_STATIC, // Relocations processed by static linkers. + RT_DYNAMIC, // Relocations processed by dynamic linkers. + }; + + // Classes of relocation codes. + enum Reloc_class { + RC_NONE, // No relocation class. + RC_DATA, // Data relocation. + RC_AARCH64, // Static AArch64 relocations + RC_CFLOW, // Control flow + RC_TLS, // Thread local storage + RC_DYNAMIC, // Dynamic relocation + }; + + // Instructions that are associated with relocations. + enum Reloc_inst { + INST_DATA = 0, + INST_MOVW = 1, // movz, movk, movn + INST_LD = 2, // ld literal + INST_ADR = 3, // adr + INST_ADRP = 4, // adrp + INST_ADD = 5, // add + INST_LDST = 6, // ld/st + INST_TBZNZ = 7, // tbz/tbnz + INST_CONDB = 8, // B.cond + INST_B = 9, // b [25:0] + INST_CALL = 10, // bl [25:0] + INST_NUM = 11, // total number of entries in the table + }; + + // Types of bases of relative addressing relocation codes. + // enum Relative_address_base { + // RAB_NONE, // Relocation is not relative addressing + // }; + + typedef bool (*rvalue_checkup_func_p)(int64_t); + typedef uint64_t (*rvalue_bit_select_func)(uint64_t); + + // Relocation code represented by this. + unsigned int + code() const + { return this->code_; } + + // Name of the relocation code. + const std::string& + name() const + { return this->name_; } + + // Type of relocation code. + Reloc_type + reloc_type() const + { return this->reloc_type_; } + + // Class of relocation code. + Reloc_class + reloc_class() const + { return this->reloc_class_; } + + // Whether this code is implemented in gold. + bool + is_implemented() const + { return this->is_implemented_; } + + // If code is a group relocation code, return the group number, otherwise -1. + int + group_index() const + { return this->group_index_; } + + // Return alignment of relocation. + size_t + align() const + { return this->align_; } + + int + reference_flags() const + { return this->reference_flags_; } + + // Instruction associated with this relocation. + Reloc_inst + reloc_inst() const + { return this->reloc_inst_; } + + // Check overflow of x + bool checkup_x_value(int64_t x) const + { return this->rvalue_checkup_func_(x); } + + // Return portions of x as is defined in aarch64-reloc.def. + uint64_t select_x_value(uint64_t x) const + { return this->rvalue_bit_select_func_(x); } + + protected: + // These are protected. We only allow AArch64_reloc_property_table to + // manage AArch64_reloc_property. + AArch64_reloc_property(unsigned int code, const char* name, Reloc_type rtype, + Reloc_class rclass, + bool is_implemented, + int group_index, + int reference_flags, + Reloc_inst reloc_inst, + rvalue_checkup_func_p rvalue_checkup_func, + rvalue_bit_select_func rvalue_bit_select); + + friend class AArch64_reloc_property_table; + + private: + // Copying is not allowed. + AArch64_reloc_property(const AArch64_reloc_property&); + AArch64_reloc_property& operator=(const AArch64_reloc_property&); + + // Relocation code. + const unsigned int code_; + // Relocation name. + const std::string name_; + // Type of relocation. + Reloc_type reloc_type_; + // Class of relocation. + Reloc_class reloc_class_; + // Group index (0, 1, or 2) if this is a group relocation or -1 otherwise. + int group_index_; + // Size of relocation. + size_t size_; + // Alignment of relocation. + size_t align_; + // Relative address base. + // Relative_address_base relative_address_base_; + // Whether this is deprecated. + bool is_deprecated_ : 1; + // Whether this is implemented in gold. + bool is_implemented_ : 1; + // Whether this checks overflow. + bool checks_overflow_ : 1; + const int reference_flags_; + // Instruction associated with relocation. + Reloc_inst reloc_inst_; + rvalue_checkup_func_p rvalue_checkup_func_; + rvalue_bit_select_func rvalue_bit_select_func_; +}; + +class AArch64_reloc_property_table +{ + public: + AArch64_reloc_property_table(); + + const AArch64_reloc_property* + get_reloc_property(unsigned int code) const + { + unsigned int idx = code_to_array_index(code); + return this->table_[idx]; + } + + // Like get_reloc_property but only return non-NULL if relocation code is + // static and implemented. + const AArch64_reloc_property* + get_implemented_static_reloc_property(unsigned int code) const + { + unsigned int idx = code_to_array_index(code); + const AArch64_reloc_property* arp = this->table_[idx]; + return ((arp != NULL + && (arp->reloc_type() == AArch64_reloc_property::RT_STATIC) + && arp->is_implemented()) + ? arp + : NULL); + } + + // Return a string describing the relocation code that is not + // an implemented static reloc code. + std::string + reloc_name_in_error_message(unsigned int code); + + private: + // Copying is not allowed. + AArch64_reloc_property_table(const AArch64_reloc_property_table&); + AArch64_reloc_property_table& operator=(const AArch64_reloc_property_table&); + + // Map aarch64 rtypes into range(0,300) as following + // 256 ~ 313 -> 0 ~ 57 + // 512 ~ 573 -> 128 ~ 189 + int + code_to_array_index(unsigned int code) const + { + if (code == 0) return 0; + if (!((code >= elfcpp::R_AARCH64_ABS64 && + code <= elfcpp::R_AARCH64_LD64_GOTPAGE_LO15) + || (code >= elfcpp::R_AARCH64_TLSGD_ADR_PREL21 && + code <= elfcpp::R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC))) + { + gold_error(_("Invalid/unrecognized reloc reloc %d."), code); + } + unsigned int rv = -1; + if (code & (1 << 9)) + rv = 128 + code - 512; // 512 - 573 + else if (code & (1 << 8)) + rv = code - 256; // 256 - 313 + gold_assert(rv <= Property_table_size); + return rv; + } + + static const unsigned int Property_table_size = 300; + AArch64_reloc_property* table_[Property_table_size]; +}; // End of class AArch64_reloc_property_table + +} // End namespace gold. + +#endif // !defined(GOLD_AARCH64_RELOC_PROPERTY_H) |