binutils-gdb/gold/aarch64-reloc-property.h
Jing Yu 9363c7c3ad 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.
2014-08-08 14:18:35 -07:00

246 lines
7.0 KiB
C++

// 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)