Automatic date update in version.in
[external/binutils.git] / bfd / elfxx-ia64.c
1 /* IA-64 support for 64-bit ELF
2    Copyright (C) 1998-2018 Free Software Foundation, Inc.
3    Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4
5    This file is part of BFD, the Binary File Descriptor library.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20    MA 02110-1301, USA.  */
21
22 #include "sysdep.h"
23 #include "bfd.h"
24 #include "libbfd.h"
25 #include "elf-bfd.h"
26 #include "opcode/ia64.h"
27 #include "elf/ia64.h"
28 #include "objalloc.h"
29 #include "hashtab.h"
30 #include "bfd_stdint.h"
31 #include "elfxx-ia64.h"
32
33 /* THE RULES for all the stuff the linker creates --
34
35   GOT           Entries created in response to LTOFF or LTOFF_FPTR
36                 relocations.  Dynamic relocs created for dynamic
37                 symbols in an application; REL relocs for locals
38                 in a shared library.
39
40   FPTR          The canonical function descriptor.  Created for local
41                 symbols in applications.  Descriptors for dynamic symbols
42                 and local symbols in shared libraries are created by
43                 ld.so.  Thus there are no dynamic relocs against these
44                 objects.  The FPTR relocs for such _are_ passed through
45                 to the dynamic relocation tables.
46
47   FULL_PLT      Created for a PCREL21B relocation against a dynamic symbol.
48                 Requires the creation of a PLTOFF entry.  This does not
49                 require any dynamic relocations.
50
51   PLTOFF        Created by PLTOFF relocations.  For local symbols, this
52                 is an alternate function descriptor, and in shared libraries
53                 requires two REL relocations.  Note that this cannot be
54                 transformed into an FPTR relocation, since it must be in
55                 range of the GP.  For dynamic symbols, this is a function
56                 descriptor for a MIN_PLT entry, and requires one IPLT reloc.
57
58   MIN_PLT       Created by PLTOFF entries against dynamic symbols.  This
59                 does not require dynamic relocations.  */
60
61 /* ia64-specific relocation.  */
62
63 #define NELEMS(a)       ((int) (sizeof (a) / sizeof ((a)[0])))
64
65 /* Perform a relocation.  Not much to do here as all the hard work is
66    done in elfNN_ia64_final_link_relocate.  */
67 static bfd_reloc_status_type
68 ia64_elf_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc,
69                 asymbol *sym ATTRIBUTE_UNUSED,
70                 PTR data ATTRIBUTE_UNUSED, asection *input_section,
71                 bfd *output_bfd, char **error_message)
72 {
73   if (output_bfd)
74     {
75       reloc->address += input_section->output_offset;
76       return bfd_reloc_ok;
77     }
78
79   if (input_section->flags & SEC_DEBUGGING)
80     return bfd_reloc_continue;
81
82   *error_message = "Unsupported call to ia64_elf_reloc";
83   return bfd_reloc_notsupported;
84 }
85
86 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN)                 \
87   HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed,  \
88          ia64_elf_reloc, NAME, FALSE, 0, -1, IN)
89
90 /* This table has to be sorted according to increasing number of the
91    TYPE field.  */
92 static reloc_howto_type ia64_howto_table[] =
93   {
94     IA64_HOWTO (R_IA64_NONE,        "NONE",        3, FALSE, TRUE),
95
96     IA64_HOWTO (R_IA64_IMM14,       "IMM14",       0, FALSE, TRUE),
97     IA64_HOWTO (R_IA64_IMM22,       "IMM22",       0, FALSE, TRUE),
98     IA64_HOWTO (R_IA64_IMM64,       "IMM64",       0, FALSE, TRUE),
99     IA64_HOWTO (R_IA64_DIR32MSB,    "DIR32MSB",    2, FALSE, TRUE),
100     IA64_HOWTO (R_IA64_DIR32LSB,    "DIR32LSB",    2, FALSE, TRUE),
101     IA64_HOWTO (R_IA64_DIR64MSB,    "DIR64MSB",    4, FALSE, TRUE),
102     IA64_HOWTO (R_IA64_DIR64LSB,    "DIR64LSB",    4, FALSE, TRUE),
103
104     IA64_HOWTO (R_IA64_GPREL22,     "GPREL22",     0, FALSE, TRUE),
105     IA64_HOWTO (R_IA64_GPREL64I,    "GPREL64I",    0, FALSE, TRUE),
106     IA64_HOWTO (R_IA64_GPREL32MSB,  "GPREL32MSB",  2, FALSE, TRUE),
107     IA64_HOWTO (R_IA64_GPREL32LSB,  "GPREL32LSB",  2, FALSE, TRUE),
108     IA64_HOWTO (R_IA64_GPREL64MSB,  "GPREL64MSB",  4, FALSE, TRUE),
109     IA64_HOWTO (R_IA64_GPREL64LSB,  "GPREL64LSB",  4, FALSE, TRUE),
110
111     IA64_HOWTO (R_IA64_LTOFF22,     "LTOFF22",     0, FALSE, TRUE),
112     IA64_HOWTO (R_IA64_LTOFF64I,    "LTOFF64I",    0, FALSE, TRUE),
113
114     IA64_HOWTO (R_IA64_PLTOFF22,    "PLTOFF22",    0, FALSE, TRUE),
115     IA64_HOWTO (R_IA64_PLTOFF64I,   "PLTOFF64I",   0, FALSE, TRUE),
116     IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, FALSE, TRUE),
117     IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, FALSE, TRUE),
118
119     IA64_HOWTO (R_IA64_FPTR64I,     "FPTR64I",     0, FALSE, TRUE),
120     IA64_HOWTO (R_IA64_FPTR32MSB,   "FPTR32MSB",   2, FALSE, TRUE),
121     IA64_HOWTO (R_IA64_FPTR32LSB,   "FPTR32LSB",   2, FALSE, TRUE),
122     IA64_HOWTO (R_IA64_FPTR64MSB,   "FPTR64MSB",   4, FALSE, TRUE),
123     IA64_HOWTO (R_IA64_FPTR64LSB,   "FPTR64LSB",   4, FALSE, TRUE),
124
125     IA64_HOWTO (R_IA64_PCREL60B,    "PCREL60B",    0, TRUE, TRUE),
126     IA64_HOWTO (R_IA64_PCREL21B,    "PCREL21B",    0, TRUE, TRUE),
127     IA64_HOWTO (R_IA64_PCREL21M,    "PCREL21M",    0, TRUE, TRUE),
128     IA64_HOWTO (R_IA64_PCREL21F,    "PCREL21F",    0, TRUE, TRUE),
129     IA64_HOWTO (R_IA64_PCREL32MSB,  "PCREL32MSB",  2, TRUE, TRUE),
130     IA64_HOWTO (R_IA64_PCREL32LSB,  "PCREL32LSB",  2, TRUE, TRUE),
131     IA64_HOWTO (R_IA64_PCREL64MSB,  "PCREL64MSB",  4, TRUE, TRUE),
132     IA64_HOWTO (R_IA64_PCREL64LSB,  "PCREL64LSB",  4, TRUE, TRUE),
133
134     IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, FALSE, TRUE),
135     IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, FALSE, TRUE),
136     IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB, "LTOFF_FPTR32MSB", 2, FALSE, TRUE),
137     IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB, "LTOFF_FPTR32LSB", 2, FALSE, TRUE),
138     IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, FALSE, TRUE),
139     IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, FALSE, TRUE),
140
141     IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, FALSE, TRUE),
142     IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, FALSE, TRUE),
143     IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, FALSE, TRUE),
144     IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, FALSE, TRUE),
145
146     IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, FALSE, TRUE),
147     IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, FALSE, TRUE),
148     IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, FALSE, TRUE),
149     IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, FALSE, TRUE),
150
151     IA64_HOWTO (R_IA64_REL32MSB,    "REL32MSB",    2, FALSE, TRUE),
152     IA64_HOWTO (R_IA64_REL32LSB,    "REL32LSB",    2, FALSE, TRUE),
153     IA64_HOWTO (R_IA64_REL64MSB,    "REL64MSB",    4, FALSE, TRUE),
154     IA64_HOWTO (R_IA64_REL64LSB,    "REL64LSB",    4, FALSE, TRUE),
155
156     IA64_HOWTO (R_IA64_LTV32MSB,    "LTV32MSB",    2, FALSE, TRUE),
157     IA64_HOWTO (R_IA64_LTV32LSB,    "LTV32LSB",    2, FALSE, TRUE),
158     IA64_HOWTO (R_IA64_LTV64MSB,    "LTV64MSB",    4, FALSE, TRUE),
159     IA64_HOWTO (R_IA64_LTV64LSB,    "LTV64LSB",    4, FALSE, TRUE),
160
161     IA64_HOWTO (R_IA64_PCREL21BI,   "PCREL21BI",   0, TRUE, TRUE),
162     IA64_HOWTO (R_IA64_PCREL22,     "PCREL22",     0, TRUE, TRUE),
163     IA64_HOWTO (R_IA64_PCREL64I,    "PCREL64I",    0, TRUE, TRUE),
164
165     IA64_HOWTO (R_IA64_IPLTMSB,     "IPLTMSB",     4, FALSE, TRUE),
166     IA64_HOWTO (R_IA64_IPLTLSB,     "IPLTLSB",     4, FALSE, TRUE),
167     IA64_HOWTO (R_IA64_COPY,        "COPY",        4, FALSE, TRUE),
168     IA64_HOWTO (R_IA64_LTOFF22X,    "LTOFF22X",    0, FALSE, TRUE),
169     IA64_HOWTO (R_IA64_LDXMOV,      "LDXMOV",      0, FALSE, TRUE),
170
171     IA64_HOWTO (R_IA64_TPREL14,     "TPREL14",     0, FALSE, FALSE),
172     IA64_HOWTO (R_IA64_TPREL22,     "TPREL22",     0, FALSE, FALSE),
173     IA64_HOWTO (R_IA64_TPREL64I,    "TPREL64I",    0, FALSE, FALSE),
174     IA64_HOWTO (R_IA64_TPREL64MSB,  "TPREL64MSB",  4, FALSE, FALSE),
175     IA64_HOWTO (R_IA64_TPREL64LSB,  "TPREL64LSB",  4, FALSE, FALSE),
176     IA64_HOWTO (R_IA64_LTOFF_TPREL22, "LTOFF_TPREL22",  0, FALSE, FALSE),
177
178     IA64_HOWTO (R_IA64_DTPMOD64MSB, "DTPMOD64MSB",  4, FALSE, FALSE),
179     IA64_HOWTO (R_IA64_DTPMOD64LSB, "DTPMOD64LSB",  4, FALSE, FALSE),
180     IA64_HOWTO (R_IA64_LTOFF_DTPMOD22, "LTOFF_DTPMOD22", 0, FALSE, FALSE),
181
182     IA64_HOWTO (R_IA64_DTPREL14,    "DTPREL14",    0, FALSE, FALSE),
183     IA64_HOWTO (R_IA64_DTPREL22,    "DTPREL22",    0, FALSE, FALSE),
184     IA64_HOWTO (R_IA64_DTPREL64I,   "DTPREL64I",   0, FALSE, FALSE),
185     IA64_HOWTO (R_IA64_DTPREL32MSB, "DTPREL32MSB", 2, FALSE, FALSE),
186     IA64_HOWTO (R_IA64_DTPREL32LSB, "DTPREL32LSB", 2, FALSE, FALSE),
187     IA64_HOWTO (R_IA64_DTPREL64MSB, "DTPREL64MSB", 4, FALSE, FALSE),
188     IA64_HOWTO (R_IA64_DTPREL64LSB, "DTPREL64LSB", 4, FALSE, FALSE),
189     IA64_HOWTO (R_IA64_LTOFF_DTPREL22, "LTOFF_DTPREL22", 0, FALSE, FALSE),
190   };
191
192 static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
193
194 /* Given a BFD reloc type, return the matching HOWTO structure.  */
195
196 reloc_howto_type *
197 ia64_elf_lookup_howto (unsigned int rtype)
198 {
199   static bfd_boolean inited = FALSE;
200   int i;
201
202   if (!inited)
203     {
204       inited = TRUE;
205
206       memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
207       for (i = 0; i < NELEMS (ia64_howto_table); ++i)
208         elf_code_to_howto_index[ia64_howto_table[i].type] = i;
209     }
210
211   if (rtype > R_IA64_MAX_RELOC_CODE)
212     return NULL;
213   i = elf_code_to_howto_index[rtype];
214   if (i >= NELEMS (ia64_howto_table))
215     return NULL;
216   return ia64_howto_table + i;
217 }
218
219 reloc_howto_type *
220 ia64_elf_reloc_type_lookup (bfd *abfd,
221                             bfd_reloc_code_real_type bfd_code)
222 {
223   unsigned int rtype;
224
225   switch (bfd_code)
226     {
227     case BFD_RELOC_NONE:                rtype = R_IA64_NONE; break;
228
229     case BFD_RELOC_IA64_IMM14:          rtype = R_IA64_IMM14; break;
230     case BFD_RELOC_IA64_IMM22:          rtype = R_IA64_IMM22; break;
231     case BFD_RELOC_IA64_IMM64:          rtype = R_IA64_IMM64; break;
232
233     case BFD_RELOC_IA64_DIR32MSB:       rtype = R_IA64_DIR32MSB; break;
234     case BFD_RELOC_IA64_DIR32LSB:       rtype = R_IA64_DIR32LSB; break;
235     case BFD_RELOC_IA64_DIR64MSB:       rtype = R_IA64_DIR64MSB; break;
236     case BFD_RELOC_IA64_DIR64LSB:       rtype = R_IA64_DIR64LSB; break;
237
238     case BFD_RELOC_IA64_GPREL22:        rtype = R_IA64_GPREL22; break;
239     case BFD_RELOC_IA64_GPREL64I:       rtype = R_IA64_GPREL64I; break;
240     case BFD_RELOC_IA64_GPREL32MSB:     rtype = R_IA64_GPREL32MSB; break;
241     case BFD_RELOC_IA64_GPREL32LSB:     rtype = R_IA64_GPREL32LSB; break;
242     case BFD_RELOC_IA64_GPREL64MSB:     rtype = R_IA64_GPREL64MSB; break;
243     case BFD_RELOC_IA64_GPREL64LSB:     rtype = R_IA64_GPREL64LSB; break;
244
245     case BFD_RELOC_IA64_LTOFF22:        rtype = R_IA64_LTOFF22; break;
246     case BFD_RELOC_IA64_LTOFF64I:       rtype = R_IA64_LTOFF64I; break;
247
248     case BFD_RELOC_IA64_PLTOFF22:       rtype = R_IA64_PLTOFF22; break;
249     case BFD_RELOC_IA64_PLTOFF64I:      rtype = R_IA64_PLTOFF64I; break;
250     case BFD_RELOC_IA64_PLTOFF64MSB:    rtype = R_IA64_PLTOFF64MSB; break;
251     case BFD_RELOC_IA64_PLTOFF64LSB:    rtype = R_IA64_PLTOFF64LSB; break;
252     case BFD_RELOC_IA64_FPTR64I:        rtype = R_IA64_FPTR64I; break;
253     case BFD_RELOC_IA64_FPTR32MSB:      rtype = R_IA64_FPTR32MSB; break;
254     case BFD_RELOC_IA64_FPTR32LSB:      rtype = R_IA64_FPTR32LSB; break;
255     case BFD_RELOC_IA64_FPTR64MSB:      rtype = R_IA64_FPTR64MSB; break;
256     case BFD_RELOC_IA64_FPTR64LSB:      rtype = R_IA64_FPTR64LSB; break;
257
258     case BFD_RELOC_IA64_PCREL21B:       rtype = R_IA64_PCREL21B; break;
259     case BFD_RELOC_IA64_PCREL21BI:      rtype = R_IA64_PCREL21BI; break;
260     case BFD_RELOC_IA64_PCREL21M:       rtype = R_IA64_PCREL21M; break;
261     case BFD_RELOC_IA64_PCREL21F:       rtype = R_IA64_PCREL21F; break;
262     case BFD_RELOC_IA64_PCREL22:        rtype = R_IA64_PCREL22; break;
263     case BFD_RELOC_IA64_PCREL60B:       rtype = R_IA64_PCREL60B; break;
264     case BFD_RELOC_IA64_PCREL64I:       rtype = R_IA64_PCREL64I; break;
265     case BFD_RELOC_IA64_PCREL32MSB:     rtype = R_IA64_PCREL32MSB; break;
266     case BFD_RELOC_IA64_PCREL32LSB:     rtype = R_IA64_PCREL32LSB; break;
267     case BFD_RELOC_IA64_PCREL64MSB:     rtype = R_IA64_PCREL64MSB; break;
268     case BFD_RELOC_IA64_PCREL64LSB:     rtype = R_IA64_PCREL64LSB; break;
269
270     case BFD_RELOC_IA64_LTOFF_FPTR22:   rtype = R_IA64_LTOFF_FPTR22; break;
271     case BFD_RELOC_IA64_LTOFF_FPTR64I:  rtype = R_IA64_LTOFF_FPTR64I; break;
272     case BFD_RELOC_IA64_LTOFF_FPTR32MSB: rtype = R_IA64_LTOFF_FPTR32MSB; break;
273     case BFD_RELOC_IA64_LTOFF_FPTR32LSB: rtype = R_IA64_LTOFF_FPTR32LSB; break;
274     case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
275     case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
276
277     case BFD_RELOC_IA64_SEGREL32MSB:    rtype = R_IA64_SEGREL32MSB; break;
278     case BFD_RELOC_IA64_SEGREL32LSB:    rtype = R_IA64_SEGREL32LSB; break;
279     case BFD_RELOC_IA64_SEGREL64MSB:    rtype = R_IA64_SEGREL64MSB; break;
280     case BFD_RELOC_IA64_SEGREL64LSB:    rtype = R_IA64_SEGREL64LSB; break;
281
282     case BFD_RELOC_IA64_SECREL32MSB:    rtype = R_IA64_SECREL32MSB; break;
283     case BFD_RELOC_IA64_SECREL32LSB:    rtype = R_IA64_SECREL32LSB; break;
284     case BFD_RELOC_IA64_SECREL64MSB:    rtype = R_IA64_SECREL64MSB; break;
285     case BFD_RELOC_IA64_SECREL64LSB:    rtype = R_IA64_SECREL64LSB; break;
286
287     case BFD_RELOC_IA64_REL32MSB:       rtype = R_IA64_REL32MSB; break;
288     case BFD_RELOC_IA64_REL32LSB:       rtype = R_IA64_REL32LSB; break;
289     case BFD_RELOC_IA64_REL64MSB:       rtype = R_IA64_REL64MSB; break;
290     case BFD_RELOC_IA64_REL64LSB:       rtype = R_IA64_REL64LSB; break;
291
292     case BFD_RELOC_IA64_LTV32MSB:       rtype = R_IA64_LTV32MSB; break;
293     case BFD_RELOC_IA64_LTV32LSB:       rtype = R_IA64_LTV32LSB; break;
294     case BFD_RELOC_IA64_LTV64MSB:       rtype = R_IA64_LTV64MSB; break;
295     case BFD_RELOC_IA64_LTV64LSB:       rtype = R_IA64_LTV64LSB; break;
296
297     case BFD_RELOC_IA64_IPLTMSB:        rtype = R_IA64_IPLTMSB; break;
298     case BFD_RELOC_IA64_IPLTLSB:        rtype = R_IA64_IPLTLSB; break;
299     case BFD_RELOC_IA64_COPY:           rtype = R_IA64_COPY; break;
300     case BFD_RELOC_IA64_LTOFF22X:       rtype = R_IA64_LTOFF22X; break;
301     case BFD_RELOC_IA64_LDXMOV:         rtype = R_IA64_LDXMOV; break;
302
303     case BFD_RELOC_IA64_TPREL14:        rtype = R_IA64_TPREL14; break;
304     case BFD_RELOC_IA64_TPREL22:        rtype = R_IA64_TPREL22; break;
305     case BFD_RELOC_IA64_TPREL64I:       rtype = R_IA64_TPREL64I; break;
306     case BFD_RELOC_IA64_TPREL64MSB:     rtype = R_IA64_TPREL64MSB; break;
307     case BFD_RELOC_IA64_TPREL64LSB:     rtype = R_IA64_TPREL64LSB; break;
308     case BFD_RELOC_IA64_LTOFF_TPREL22:  rtype = R_IA64_LTOFF_TPREL22; break;
309
310     case BFD_RELOC_IA64_DTPMOD64MSB:    rtype = R_IA64_DTPMOD64MSB; break;
311     case BFD_RELOC_IA64_DTPMOD64LSB:    rtype = R_IA64_DTPMOD64LSB; break;
312     case BFD_RELOC_IA64_LTOFF_DTPMOD22: rtype = R_IA64_LTOFF_DTPMOD22; break;
313
314     case BFD_RELOC_IA64_DTPREL14:       rtype = R_IA64_DTPREL14; break;
315     case BFD_RELOC_IA64_DTPREL22:       rtype = R_IA64_DTPREL22; break;
316     case BFD_RELOC_IA64_DTPREL64I:      rtype = R_IA64_DTPREL64I; break;
317     case BFD_RELOC_IA64_DTPREL32MSB:    rtype = R_IA64_DTPREL32MSB; break;
318     case BFD_RELOC_IA64_DTPREL32LSB:    rtype = R_IA64_DTPREL32LSB; break;
319     case BFD_RELOC_IA64_DTPREL64MSB:    rtype = R_IA64_DTPREL64MSB; break;
320     case BFD_RELOC_IA64_DTPREL64LSB:    rtype = R_IA64_DTPREL64LSB; break;
321     case BFD_RELOC_IA64_LTOFF_DTPREL22: rtype = R_IA64_LTOFF_DTPREL22; break;
322
323     default:
324       /* xgettext:c-format */
325       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
326                           abfd, (int) bfd_code);
327       bfd_set_error (bfd_error_bad_value);
328       return NULL;
329     }
330   return ia64_elf_lookup_howto (rtype);
331 }
332
333 reloc_howto_type *
334 ia64_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
335                             const char *r_name)
336 {
337   unsigned int i;
338
339   for (i = 0;
340        i < sizeof (ia64_howto_table) / sizeof (ia64_howto_table[0]);
341        i++)
342     if (ia64_howto_table[i].name != NULL
343         && strcasecmp (ia64_howto_table[i].name, r_name) == 0)
344       return &ia64_howto_table[i];
345
346   return NULL;
347 }
348
349 #define BTYPE_SHIFT     6
350 #define Y_SHIFT         26
351 #define X6_SHIFT        27
352 #define X4_SHIFT        27
353 #define X3_SHIFT        33
354 #define X2_SHIFT        31
355 #define X_SHIFT         33
356 #define OPCODE_SHIFT    37
357
358 #define OPCODE_BITS     (0xfLL << OPCODE_SHIFT)
359 #define X6_BITS         (0x3fLL << X6_SHIFT)
360 #define X4_BITS         (0xfLL << X4_SHIFT)
361 #define X3_BITS         (0x7LL << X3_SHIFT)
362 #define X2_BITS         (0x3LL << X2_SHIFT)
363 #define X_BITS          (0x1LL << X_SHIFT)
364 #define Y_BITS          (0x1LL << Y_SHIFT)
365 #define BTYPE_BITS      (0x7LL << BTYPE_SHIFT)
366 #define PREDICATE_BITS  (0x3fLL)
367
368 #define IS_NOP_B(i) \
369   (((i) & (OPCODE_BITS | X6_BITS)) == (2LL << OPCODE_SHIFT))
370 #define IS_NOP_F(i) \
371   (((i) & (OPCODE_BITS | X_BITS | X6_BITS | Y_BITS)) \
372    == (0x1LL << X6_SHIFT))
373 #define IS_NOP_I(i) \
374   (((i) & (OPCODE_BITS | X3_BITS | X6_BITS | Y_BITS)) \
375    == (0x1LL << X6_SHIFT))
376 #define IS_NOP_M(i) \
377   (((i) & (OPCODE_BITS | X3_BITS | X2_BITS | X4_BITS | Y_BITS)) \
378    == (0x1LL << X4_SHIFT))
379 #define IS_BR_COND(i) \
380   (((i) & (OPCODE_BITS | BTYPE_BITS)) == (0x4LL << OPCODE_SHIFT))
381 #define IS_BR_CALL(i) \
382   (((i) & OPCODE_BITS) == (0x5LL << OPCODE_SHIFT))
383
384 bfd_boolean
385 ia64_elf_relax_br (bfd_byte *contents, bfd_vma off)
386 {
387   unsigned int template_val, mlx;
388   bfd_vma t0, t1, s0, s1, s2, br_code;
389   long br_slot;
390   bfd_byte *hit_addr;
391
392   hit_addr = (bfd_byte *) (contents + off);
393   br_slot = (intptr_t) hit_addr & 0x3;
394   hit_addr -= br_slot;
395   t0 = bfd_getl64 (hit_addr + 0);
396   t1 = bfd_getl64 (hit_addr + 8);
397
398   /* Check if we can turn br into brl.  A label is always at the start
399      of the bundle.  Even if there are predicates on NOPs, we still
400      perform this optimization.  */
401   template_val = t0 & 0x1e;
402   s0 = (t0 >> 5) & 0x1ffffffffffLL;
403   s1 = ((t0 >> 46) | (t1 << 18)) & 0x1ffffffffffLL;
404   s2 = (t1 >> 23) & 0x1ffffffffffLL;
405   switch (br_slot)
406     {
407     case 0:
408       /* Check if slot 1 and slot 2 are NOPs. Possible template is
409          BBB.  We only need to check nop.b.  */
410       if (!(IS_NOP_B (s1) && IS_NOP_B (s2)))
411         return FALSE;
412       br_code = s0;
413       break;
414     case 1:
415       /* Check if slot 2 is NOP. Possible templates are MBB and BBB.
416          For BBB, slot 0 also has to be nop.b.  */
417       if (!((template_val == 0x12                               /* MBB */
418              && IS_NOP_B (s2))
419             || (template_val == 0x16                    /* BBB */
420                 && IS_NOP_B (s0)
421                 && IS_NOP_B (s2))))
422         return FALSE;
423       br_code = s1;
424       break;
425     case 2:
426       /* Check if slot 1 is NOP. Possible templates are MIB, MBB, BBB,
427          MMB and MFB. For BBB, slot 0 also has to be nop.b.  */
428       if (!((template_val == 0x10                               /* MIB */
429              && IS_NOP_I (s1))
430             || (template_val == 0x12                    /* MBB */
431                 && IS_NOP_B (s1))
432             || (template_val == 0x16                    /* BBB */
433                 && IS_NOP_B (s0)
434                 && IS_NOP_B (s1))
435             || (template_val == 0x18                    /* MMB */
436                 && IS_NOP_M (s1))
437             || (template_val == 0x1c                    /* MFB */
438                 && IS_NOP_F (s1))))
439         return FALSE;
440       br_code = s2;
441       break;
442     default:
443       /* It should never happen.  */
444       abort ();
445     }
446
447   /* We can turn br.cond/br.call into brl.cond/brl.call.  */
448   if (!(IS_BR_COND (br_code) || IS_BR_CALL (br_code)))
449     return FALSE;
450
451   /* Turn br into brl by setting bit 40.  */
452   br_code |= 0x1LL << 40;
453
454   /* Turn the old bundle into a MLX bundle with the same stop-bit
455      variety.  */
456   if (t0 & 0x1)
457     mlx = 0x5;
458   else
459     mlx = 0x4;
460
461   if (template_val == 0x16)
462     {
463       /* For BBB, we need to put nop.m in slot 0.  We keep the original
464          predicate only if slot 0 isn't br.  */
465       if (br_slot == 0)
466         t0 = 0LL;
467       else
468         t0 &= PREDICATE_BITS << 5;
469       t0 |= 0x1LL << (X4_SHIFT + 5);
470     }
471   else
472     {
473       /* Keep the original instruction in slot 0.  */
474       t0 &= 0x1ffffffffffLL << 5;
475     }
476
477   t0 |= mlx;
478
479   /* Put brl in slot 1.  */
480   t1 = br_code << 23;
481
482   bfd_putl64 (t0, hit_addr);
483   bfd_putl64 (t1, hit_addr + 8);
484   return TRUE;
485 }
486
487 void
488 ia64_elf_relax_brl (bfd_byte *contents, bfd_vma off)
489 {
490   int template_val;
491   bfd_byte *hit_addr;
492   bfd_vma t0, t1, i0, i1, i2;
493
494   hit_addr = (bfd_byte *) (contents + off);
495   hit_addr -= (intptr_t) hit_addr & 0x3;
496   t0 = bfd_getl64 (hit_addr);
497   t1 = bfd_getl64 (hit_addr + 8);
498
499   /* Keep the instruction in slot 0. */
500   i0 = (t0 >> 5) & 0x1ffffffffffLL;
501   /* Use nop.b for slot 1. */
502   i1 = 0x4000000000LL;
503   /* For slot 2, turn brl into br by masking out bit 40.  */
504   i2 = (t1 >> 23) & 0x0ffffffffffLL;
505
506   /* Turn a MLX bundle into a MBB bundle with the same stop-bit
507      variety.  */
508   if (t0 & 0x1)
509     template_val = 0x13;
510   else
511     template_val = 0x12;
512   t0 = (i1 << 46) | (i0 << 5) | template_val;
513   t1 = (i2 << 23) | (i1 >> 18);
514
515   bfd_putl64 (t0, hit_addr);
516   bfd_putl64 (t1, hit_addr + 8);
517 }
518
519 void
520 ia64_elf_relax_ldxmov (bfd_byte *contents, bfd_vma off)
521 {
522   int shift, r1, r3;
523   bfd_vma dword, insn;
524
525   switch ((int)off & 0x3)
526     {
527     case 0: shift =  5; break;
528     case 1: shift = 14; off += 3; break;
529     case 2: shift = 23; off += 6; break;
530     default:
531       abort ();
532     }
533
534   dword = bfd_getl64 (contents + off);
535   insn = (dword >> shift) & 0x1ffffffffffLL;
536
537   r1 = (insn >> 6) & 127;
538   r3 = (insn >> 20) & 127;
539   if (r1 == r3)
540     insn = 0x8000000;                              /* nop */
541   else
542     insn = (insn & 0x7f01fff) | 0x10800000000LL;   /* (qp) mov r1 = r3 */
543
544   dword &= ~(0x1ffffffffffLL << shift);
545   dword |= (insn << shift);
546   bfd_putl64 (dword, contents + off);
547 }
548 \f
549 bfd_reloc_status_type
550 ia64_elf_install_value (bfd_byte *hit_addr, bfd_vma v, unsigned int r_type)
551 {
552   const struct ia64_operand *op;
553   int bigendian = 0, shift = 0;
554   bfd_vma t0, t1, dword;
555   ia64_insn insn;
556   enum ia64_opnd opnd;
557   const char *err;
558   size_t size = 8;
559 #ifdef BFD_HOST_U_64_BIT
560   BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
561 #else
562   bfd_vma val = v;
563 #endif
564
565   opnd = IA64_OPND_NIL;
566   switch (r_type)
567     {
568     case R_IA64_NONE:
569     case R_IA64_LDXMOV:
570       return bfd_reloc_ok;
571
572       /* Instruction relocations.  */
573
574     case R_IA64_IMM14:
575     case R_IA64_TPREL14:
576     case R_IA64_DTPREL14:
577       opnd = IA64_OPND_IMM14;
578       break;
579
580     case R_IA64_PCREL21F:       opnd = IA64_OPND_TGT25; break;
581     case R_IA64_PCREL21M:       opnd = IA64_OPND_TGT25b; break;
582     case R_IA64_PCREL60B:       opnd = IA64_OPND_TGT64; break;
583     case R_IA64_PCREL21B:
584     case R_IA64_PCREL21BI:
585       opnd = IA64_OPND_TGT25c;
586       break;
587
588     case R_IA64_IMM22:
589     case R_IA64_GPREL22:
590     case R_IA64_LTOFF22:
591     case R_IA64_LTOFF22X:
592     case R_IA64_PLTOFF22:
593     case R_IA64_PCREL22:
594     case R_IA64_LTOFF_FPTR22:
595     case R_IA64_TPREL22:
596     case R_IA64_DTPREL22:
597     case R_IA64_LTOFF_TPREL22:
598     case R_IA64_LTOFF_DTPMOD22:
599     case R_IA64_LTOFF_DTPREL22:
600       opnd = IA64_OPND_IMM22;
601       break;
602
603     case R_IA64_IMM64:
604     case R_IA64_GPREL64I:
605     case R_IA64_LTOFF64I:
606     case R_IA64_PLTOFF64I:
607     case R_IA64_PCREL64I:
608     case R_IA64_FPTR64I:
609     case R_IA64_LTOFF_FPTR64I:
610     case R_IA64_TPREL64I:
611     case R_IA64_DTPREL64I:
612       opnd = IA64_OPND_IMMU64;
613       break;
614
615       /* Data relocations.  */
616
617     case R_IA64_DIR32MSB:
618     case R_IA64_GPREL32MSB:
619     case R_IA64_FPTR32MSB:
620     case R_IA64_PCREL32MSB:
621     case R_IA64_LTOFF_FPTR32MSB:
622     case R_IA64_SEGREL32MSB:
623     case R_IA64_SECREL32MSB:
624     case R_IA64_LTV32MSB:
625     case R_IA64_DTPREL32MSB:
626       size = 4; bigendian = 1;
627       break;
628
629     case R_IA64_DIR32LSB:
630     case R_IA64_GPREL32LSB:
631     case R_IA64_FPTR32LSB:
632     case R_IA64_PCREL32LSB:
633     case R_IA64_LTOFF_FPTR32LSB:
634     case R_IA64_SEGREL32LSB:
635     case R_IA64_SECREL32LSB:
636     case R_IA64_LTV32LSB:
637     case R_IA64_DTPREL32LSB:
638       size = 4; bigendian = 0;
639       break;
640
641     case R_IA64_DIR64MSB:
642     case R_IA64_GPREL64MSB:
643     case R_IA64_PLTOFF64MSB:
644     case R_IA64_FPTR64MSB:
645     case R_IA64_PCREL64MSB:
646     case R_IA64_LTOFF_FPTR64MSB:
647     case R_IA64_SEGREL64MSB:
648     case R_IA64_SECREL64MSB:
649     case R_IA64_LTV64MSB:
650     case R_IA64_TPREL64MSB:
651     case R_IA64_DTPMOD64MSB:
652     case R_IA64_DTPREL64MSB:
653       size = 8; bigendian = 1;
654       break;
655
656     case R_IA64_DIR64LSB:
657     case R_IA64_GPREL64LSB:
658     case R_IA64_PLTOFF64LSB:
659     case R_IA64_FPTR64LSB:
660     case R_IA64_PCREL64LSB:
661     case R_IA64_LTOFF_FPTR64LSB:
662     case R_IA64_SEGREL64LSB:
663     case R_IA64_SECREL64LSB:
664     case R_IA64_LTV64LSB:
665     case R_IA64_TPREL64LSB:
666     case R_IA64_DTPMOD64LSB:
667     case R_IA64_DTPREL64LSB:
668       size = 8; bigendian = 0;
669       break;
670
671       /* Unsupported / Dynamic relocations.  */
672     default:
673       return bfd_reloc_notsupported;
674     }
675
676   switch (opnd)
677     {
678     case IA64_OPND_IMMU64:
679       hit_addr -= (intptr_t) hit_addr & 0x3;
680       t0 = bfd_getl64 (hit_addr);
681       t1 = bfd_getl64 (hit_addr + 8);
682
683       /* tmpl/s: bits  0.. 5 in t0
684          slot 0: bits  5..45 in t0
685          slot 1: bits 46..63 in t0, bits 0..22 in t1
686          slot 2: bits 23..63 in t1 */
687
688       /* First, clear the bits that form the 64 bit constant.  */
689       t0 &= ~(0x3ffffLL << 46);
690       t1 &= ~(0x7fffffLL
691               | ((  (0x07fLL << 13) | (0x1ffLL << 27)
692                     | (0x01fLL << 22) | (0x001LL << 21)
693                     | (0x001LL << 36)) << 23));
694
695       t0 |= ((val >> 22) & 0x03ffffLL) << 46;           /* 18 lsbs of imm41 */
696       t1 |= ((val >> 40) & 0x7fffffLL) <<  0;           /* 23 msbs of imm41 */
697       t1 |= (  (((val >>  0) & 0x07f) << 13)            /* imm7b */
698                | (((val >>  7) & 0x1ff) << 27)          /* imm9d */
699                | (((val >> 16) & 0x01f) << 22)          /* imm5c */
700                | (((val >> 21) & 0x001) << 21)          /* ic */
701                | (((val >> 63) & 0x001) << 36)) << 23;  /* i */
702
703       bfd_putl64 (t0, hit_addr);
704       bfd_putl64 (t1, hit_addr + 8);
705       break;
706
707     case IA64_OPND_TGT64:
708       hit_addr -= (intptr_t) hit_addr & 0x3;
709       t0 = bfd_getl64 (hit_addr);
710       t1 = bfd_getl64 (hit_addr + 8);
711
712       /* tmpl/s: bits  0.. 5 in t0
713          slot 0: bits  5..45 in t0
714          slot 1: bits 46..63 in t0, bits 0..22 in t1
715          slot 2: bits 23..63 in t1 */
716
717       /* First, clear the bits that form the 64 bit constant.  */
718       t0 &= ~(0x3ffffLL << 46);
719       t1 &= ~(0x7fffffLL
720               | ((1LL << 36 | 0xfffffLL << 13) << 23));
721
722       val >>= 4;
723       t0 |= ((val >> 20) & 0xffffLL) << 2 << 46;        /* 16 lsbs of imm39 */
724       t1 |= ((val >> 36) & 0x7fffffLL) << 0;            /* 23 msbs of imm39 */
725       t1 |= ((((val >> 0) & 0xfffffLL) << 13)           /* imm20b */
726               | (((val >> 59) & 0x1LL) << 36)) << 23;   /* i */
727
728       bfd_putl64 (t0, hit_addr);
729       bfd_putl64 (t1, hit_addr + 8);
730       break;
731
732     default:
733       switch ((intptr_t) hit_addr & 0x3)
734         {
735         case 0: shift =  5; break;
736         case 1: shift = 14; hit_addr += 3; break;
737         case 2: shift = 23; hit_addr += 6; break;
738         case 3: return bfd_reloc_notsupported; /* shouldn't happen...  */
739         }
740       dword = bfd_getl64 (hit_addr);
741       insn = (dword >> shift) & 0x1ffffffffffLL;
742
743       op = elf64_ia64_operands + opnd;
744       err = (*op->insert) (op, val, &insn);
745       if (err)
746         return bfd_reloc_overflow;
747
748       dword &= ~(0x1ffffffffffLL << shift);
749       dword |= (insn << shift);
750       bfd_putl64 (dword, hit_addr);
751       break;
752
753     case IA64_OPND_NIL:
754       /* A data relocation.  */
755       if (bigendian)
756         if (size == 4)
757           bfd_putb32 (val, hit_addr);
758         else
759           bfd_putb64 (val, hit_addr);
760       else
761         if (size == 4)
762           bfd_putl32 (val, hit_addr);
763         else
764           bfd_putl64 (val, hit_addr);
765       break;
766     }
767
768   return bfd_reloc_ok;
769 }