diff options
author | Andrew Hsieh <andrewhsieh@google.com> | 2014-12-09 17:57:18 +0800 |
---|---|---|
committer | Andrew Hsieh <andrewhsieh@google.com> | 2014-12-09 19:50:14 +0800 |
commit | 5e8c1cf25beccac1d22d10dc866912394f42771b (patch) | |
tree | ee16b70f804484dc8e434e647e699ab50da2620f /binutils-2.25/gold/aarch64-reloc-property.cc | |
parent | 8eebd7953384e6662ca926b003f2cdda8ccd3ee5 (diff) | |
download | toolchain_binutils-5e8c1cf25beccac1d22d10dc866912394f42771b.zip toolchain_binutils-5e8c1cf25beccac1d22d10dc866912394f42771b.tar.gz toolchain_binutils-5e8c1cf25beccac1d22d10dc866912394f42771b.tar.bz2 |
[2.25] sync to a30720e3e633f275250e26f85ccae5dbdddfb6c6
local patches will be re-applied later
commit a30720e3e633f275250e26f85ccae5dbdddfb6c6
Author: Alan Modra <amodra@gmail.com>
Date: Wed Nov 19 10:30:16 2014 +1030
daily update
Change-Id: Ieb2a3f4dd2ecb289ac5305ff08d428b2847494ab
Diffstat (limited to 'binutils-2.25/gold/aarch64-reloc-property.cc')
-rw-r--r-- | binutils-2.25/gold/aarch64-reloc-property.cc | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/binutils-2.25/gold/aarch64-reloc-property.cc b/binutils-2.25/gold/aarch64-reloc-property.cc new file mode 100644 index 0000000..16f8449 --- /dev/null +++ b/binutils-2.25/gold/aarch64-reloc-property.cc @@ -0,0 +1,163 @@ +// aarch64-reloc-property.cc -- 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. + +#include "gold.h" + +#include "aarch64-reloc-property.h" +#include "aarch64.h" + +#include "symtab.h" + +#include<stdio.h> + +namespace gold +{ + +template<int L, int U> +bool +rvalue_checkup(int64_t x) +{ + // We save the extra_alignment_requirement bits on [31:16] of U. + // "extra_alignment_requirement" could be 0, 1, 3, 7 and 15. + unsigned short extra_alignment_requirement = (U & 0xFFFF0000) >> 16; + // [15:0] of U indicates the upper bound check. + int64_t u = U & 0x0000FFFF; + if (u == 0) + { + // No requirement to check overflow. + gold_assert(L == 0); + return (x & extra_alignment_requirement) == 0; + } + + // Check both overflow and alignment if needed. + int64_t low_bound = -(L == 0 ? 0 : ((int64_t)1 << L)); + int64_t up_bound = ((int64_t)1 << u); + return ((low_bound <= x && x < up_bound) + && ((x & extra_alignment_requirement) == 0)); +} + +template<> +bool +rvalue_checkup<0, 0>(int64_t) { return true; } + +template<int L, int U> +uint64_t +rvalue_bit_select(uint64_t x) +{ + if (U == 63) return x >> L; + return (x & (((uint64_t)1 << (U+1)) - 1)) >> L; +} + +template<> +uint64_t +rvalue_bit_select<0, 0>(uint64_t x) { return x; } + +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) + : code_(code), name_(name), reloc_type_(rtype), reloc_class_(rclass), + group_index_(group_index), + is_implemented_(is_implemented), + reference_flags_(reference_flags), + reloc_inst_(reloc_inst), + rvalue_checkup_func_(rvalue_checkup_func), + rvalue_bit_select_func_(rvalue_bit_select) +{} + +AArch64_reloc_property_table::AArch64_reloc_property_table() +{ + const bool Y(true), N(false); + for (unsigned int i = 0; i < Property_table_size; ++i) + table_[i] = NULL; + +#define RL_CHECK_ALIGN2 (1 << 16) +#define RL_CHECK_ALIGN4 (3 << 16) +#define RL_CHECK_ALIGN8 (7 << 16) +#define RL_CHECK_ALIGN16 (15 << 16) + +#undef ARD +#define ARD(rname, type, class, is_implemented, group_index, LB, UB, BSL, BSH, RFLAGS, inst) \ + do \ + { \ + int tidx = code_to_array_index(elfcpp::R_AARCH64_##rname); \ + AArch64_reloc_property * p = new AArch64_reloc_property( \ + elfcpp::R_AARCH64_##rname, "R_AARCH64_" #rname, \ + AArch64_reloc_property::RT_##type, \ + AArch64_reloc_property::RC_##class, \ + is_implemented, \ + group_index, \ + (RFLAGS), \ + AArch64_reloc_property::INST_##inst, \ + rvalue_checkup<LB,UB>, \ + rvalue_bit_select<BSL,BSH>); \ + table_[tidx] = p; \ + } \ + while (0); +#include"aarch64-reloc.def" +#undef ARD +} + +// Return a string describing a relocation code that fails to get a +// relocation property in get_implemented_static_reloc_property(). + +std::string +AArch64_reloc_property_table::reloc_name_in_error_message(unsigned int code) +{ + int tidx = code_to_array_index(code); + const AArch64_reloc_property* arp = this->table_[tidx]; + + if (arp == NULL) + { + char buffer[100]; + sprintf(buffer, _("invalid reloc %u"), code); + return std::string(buffer); + } + + // gold only implements static relocation codes. + AArch64_reloc_property::Reloc_type reloc_type = arp->reloc_type(); + gold_assert(reloc_type == AArch64_reloc_property::RT_STATIC + || !arp->is_implemented()); + + const char* prefix = NULL; + switch (reloc_type) + { + case AArch64_reloc_property::RT_STATIC: + prefix = arp->is_implemented() ? _("reloc ") : _("unimplemented reloc "); + break; + case AArch64_reloc_property::RT_DYNAMIC: + prefix = _("dynamic reloc "); + break; + default: + gold_unreachable(); + } + return std::string(prefix) + arp->name(); +} + +} |