Copyright update for binutils
[deliverable/binutils-gdb.git] / gold / aarch64-reloc-property.cc
CommitLineData
9363c7c3
JY
1// aarch64-reloc-property.cc -- AArch64 relocation properties -*- C++ -*-
2
6f2750fe 3// Copyright (C) 2014-2016 Free Software Foundation, Inc.
9363c7c3
JY
4// Written by Han Shen <shenhan@google.com> and Jing Yu <jingyu@google.com>.
5
6// This file is part of gold.
7
8// This program is free software; you can redistribute it and/or modify
9// it under the terms of the GNU General Public License as published by
10// the Free Software Foundation; either version 3 of the License, or
11// (at your option) any later version.
12
13// This program is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16// GNU General Public License for more details.
17
18// You should have received a copy of the GNU General Public License
19// along with this program; if not, write to the Free Software
20// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21// MA 02110-1301, USA.
22
23#include "gold.h"
24
25#include "aarch64-reloc-property.h"
26#include "aarch64.h"
27
28#include "symtab.h"
29
30#include<stdio.h>
31
32namespace gold
33{
34
35template<int L, int U>
36bool
37rvalue_checkup(int64_t x)
38{
39 // We save the extra_alignment_requirement bits on [31:16] of U.
40 // "extra_alignment_requirement" could be 0, 1, 3, 7 and 15.
41 unsigned short extra_alignment_requirement = (U & 0xFFFF0000) >> 16;
42 // [15:0] of U indicates the upper bound check.
43 int64_t u = U & 0x0000FFFF;
44 if (u == 0)
45 {
46 // No requirement to check overflow.
47 gold_assert(L == 0);
48 return (x & extra_alignment_requirement) == 0;
49 }
50
51 // Check both overflow and alignment if needed.
52 int64_t low_bound = -(L == 0 ? 0 : ((int64_t)1 << L));
53 int64_t up_bound = ((int64_t)1 << u);
54 return ((low_bound <= x && x < up_bound)
55 && ((x & extra_alignment_requirement) == 0));
56}
57
58template<>
59bool
60rvalue_checkup<0, 0>(int64_t) { return true; }
61
62template<int L, int U>
63uint64_t
64rvalue_bit_select(uint64_t x)
65{
66 if (U == 63) return x >> L;
67 return (x & (((uint64_t)1 << (U+1)) - 1)) >> L;
68}
69
70template<>
71uint64_t
72rvalue_bit_select<0, 0>(uint64_t x) { return x; }
73
74AArch64_reloc_property::AArch64_reloc_property(
75 unsigned int code,
76 const char* name,
77 Reloc_type rtype,
78 Reloc_class rclass,
79 bool is_implemented,
80 int group_index,
81 int reference_flags,
82 Reloc_inst reloc_inst,
83 rvalue_checkup_func_p rvalue_checkup_func,
84 rvalue_bit_select_func rvalue_bit_select)
85 : code_(code), name_(name), reloc_type_(rtype), reloc_class_(rclass),
86 group_index_(group_index),
87 is_implemented_(is_implemented),
88 reference_flags_(reference_flags),
89 reloc_inst_(reloc_inst),
90 rvalue_checkup_func_(rvalue_checkup_func),
91 rvalue_bit_select_func_(rvalue_bit_select)
92{}
93
94AArch64_reloc_property_table::AArch64_reloc_property_table()
95{
96 const bool Y(true), N(false);
97 for (unsigned int i = 0; i < Property_table_size; ++i)
98 table_[i] = NULL;
99
100#define RL_CHECK_ALIGN2 (1 << 16)
101#define RL_CHECK_ALIGN4 (3 << 16)
102#define RL_CHECK_ALIGN8 (7 << 16)
103#define RL_CHECK_ALIGN16 (15 << 16)
104
105#undef ARD
106#define ARD(rname, type, class, is_implemented, group_index, LB, UB, BSL, BSH, RFLAGS, inst) \
107 do \
108 { \
109 int tidx = code_to_array_index(elfcpp::R_AARCH64_##rname); \
110 AArch64_reloc_property * p = new AArch64_reloc_property( \
111 elfcpp::R_AARCH64_##rname, "R_AARCH64_" #rname, \
112 AArch64_reloc_property::RT_##type, \
113 AArch64_reloc_property::RC_##class, \
114 is_implemented, \
115 group_index, \
116 (RFLAGS), \
117 AArch64_reloc_property::INST_##inst, \
118 rvalue_checkup<LB,UB>, \
119 rvalue_bit_select<BSL,BSH>); \
120 table_[tidx] = p; \
121 } \
122 while (0);
123#include"aarch64-reloc.def"
124#undef ARD
125}
126
127// Return a string describing a relocation code that fails to get a
128// relocation property in get_implemented_static_reloc_property().
129
130std::string
131AArch64_reloc_property_table::reloc_name_in_error_message(unsigned int code)
132{
8e33481e
HS
133 int tidx = code_to_array_index(code);
134 const AArch64_reloc_property* arp = this->table_[tidx];
9363c7c3
JY
135
136 if (arp == NULL)
137 {
138 char buffer[100];
139 sprintf(buffer, _("invalid reloc %u"), code);
140 return std::string(buffer);
141 }
142
143 // gold only implements static relocation codes.
144 AArch64_reloc_property::Reloc_type reloc_type = arp->reloc_type();
145 gold_assert(reloc_type == AArch64_reloc_property::RT_STATIC
146 || !arp->is_implemented());
147
148 const char* prefix = NULL;
149 switch (reloc_type)
150 {
151 case AArch64_reloc_property::RT_STATIC:
152 prefix = arp->is_implemented() ? _("reloc ") : _("unimplemented reloc ");
153 break;
154 case AArch64_reloc_property::RT_DYNAMIC:
155 prefix = _("dynamic reloc ");
156 break;
157 default:
158 gold_unreachable();
159 }
160 return std::string(prefix) + arp->name();
161}
162
163}
This page took 0.082229 seconds and 4 git commands to generate.