aboutsummaryrefslogtreecommitdiff
path: root/gold/aarch64-reloc-property.h
diff options
context:
space:
mode:
authorJing Yu <jingyu@google.com>2014-08-08 14:18:35 -0700
committerJing Yu <jingyu@google.com>2014-08-08 14:18:35 -0700
commit9363c7c3ad54a5f92d74ec8e48eda570de229f63 (patch)
treea1c7605c93a72b11d9ed6634b0e2891e8ae44b8d /gold/aarch64-reloc-property.h
parenta957de07689be21b85497bdfea6389068f8c9375 (diff)
downloadfsf-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.h245
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)