Factor our stub creation in ARM backend
[external/binutils.git] / bfd / elfxx-ia64.c
1 /* IA-64 support for 64-bit ELF
2    Copyright (C) 1998-2016 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 int inited = 0;
200   int i;
201
202   if (!inited)
203     {
204       inited = 1;
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 0;
213   i = elf_code_to_howto_index[rtype];
214   if (i >= NELEMS (ia64_howto_table))
215     return 0;
216   return ia64_howto_table + i;
217 }
218
219 reloc_howto_type*
220 ia64_elf_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
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: return 0;
324     }
325   return ia64_elf_lookup_howto (rtype);
326 }
327
328 reloc_howto_type *
329 ia64_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
330                             const char *r_name)
331 {
332   unsigned int i;
333
334   for (i = 0;
335        i < sizeof (ia64_howto_table) / sizeof (ia64_howto_table[0]);
336        i++)
337     if (ia64_howto_table[i].name != NULL
338         && strcasecmp (ia64_howto_table[i].name, r_name) == 0)
339       return &ia64_howto_table[i];
340
341   return NULL;
342 }
343
344 #define BTYPE_SHIFT     6
345 #define Y_SHIFT         26
346 #define X6_SHIFT        27
347 #define X4_SHIFT        27
348 #define X3_SHIFT        33
349 #define X2_SHIFT        31
350 #define X_SHIFT         33
351 #define OPCODE_SHIFT    37
352
353 #define OPCODE_BITS     (0xfLL << OPCODE_SHIFT)
354 #define X6_BITS         (0x3fLL << X6_SHIFT)
355 #define X4_BITS         (0xfLL << X4_SHIFT)
356 #define X3_BITS         (0x7LL << X3_SHIFT)
357 #define X2_BITS         (0x3LL << X2_SHIFT)
358 #define X_BITS          (0x1LL << X_SHIFT)
359 #define Y_BITS          (0x1LL << Y_SHIFT)
360 #define BTYPE_BITS      (0x7LL << BTYPE_SHIFT)
361 #define PREDICATE_BITS  (0x3fLL)
362
363 #define IS_NOP_B(i) \
364   (((i) & (OPCODE_BITS | X6_BITS)) == (2LL << OPCODE_SHIFT))
365 #define IS_NOP_F(i) \
366   (((i) & (OPCODE_BITS | X_BITS | X6_BITS | Y_BITS)) \
367    == (0x1LL << X6_SHIFT))
368 #define IS_NOP_I(i) \
369   (((i) & (OPCODE_BITS | X3_BITS | X6_BITS | Y_BITS)) \
370    == (0x1LL << X6_SHIFT))
371 #define IS_NOP_M(i) \
372   (((i) & (OPCODE_BITS | X3_BITS | X2_BITS | X4_BITS | Y_BITS)) \
373    == (0x1LL << X4_SHIFT))
374 #define IS_BR_COND(i) \
375   (((i) & (OPCODE_BITS | BTYPE_BITS)) == (0x4LL << OPCODE_SHIFT))
376 #define IS_BR_CALL(i) \
377   (((i) & OPCODE_BITS) == (0x5LL << OPCODE_SHIFT))
378
379 bfd_boolean
380 ia64_elf_relax_br (bfd_byte *contents, bfd_vma off)
381 {
382   unsigned int template_val, mlx;
383   bfd_vma t0, t1, s0, s1, s2, br_code;
384   long br_slot;
385   bfd_byte *hit_addr;
386
387   hit_addr = (bfd_byte *) (contents + off);
388   br_slot = (intptr_t) hit_addr & 0x3;
389   hit_addr -= br_slot;
390   t0 = bfd_getl64 (hit_addr + 0);
391   t1 = bfd_getl64 (hit_addr + 8);
392
393   /* Check if we can turn br into brl.  A label is always at the start
394      of the bundle.  Even if there are predicates on NOPs, we still
395      perform this optimization.  */
396   template_val = t0 & 0x1e;
397   s0 = (t0 >> 5) & 0x1ffffffffffLL;
398   s1 = ((t0 >> 46) | (t1 << 18)) & 0x1ffffffffffLL;
399   s2 = (t1 >> 23) & 0x1ffffffffffLL;
400   switch (br_slot)
401     {
402     case 0:
403       /* Check if slot 1 and slot 2 are NOPs. Possible template is
404          BBB.  We only need to check nop.b.  */
405       if (!(IS_NOP_B (s1) && IS_NOP_B (s2)))
406         return FALSE;
407       br_code = s0;
408       break;
409     case 1:
410       /* Check if slot 2 is NOP. Possible templates are MBB and BBB.
411          For BBB, slot 0 also has to be nop.b.  */
412       if (!((template_val == 0x12                               /* MBB */
413              && IS_NOP_B (s2))
414             || (template_val == 0x16                    /* BBB */
415                 && IS_NOP_B (s0)
416                 && IS_NOP_B (s2))))
417         return FALSE;
418       br_code = s1;
419       break;
420     case 2:
421       /* Check if slot 1 is NOP. Possible templates are MIB, MBB, BBB,
422          MMB and MFB. For BBB, slot 0 also has to be nop.b.  */
423       if (!((template_val == 0x10                               /* MIB */
424              && IS_NOP_I (s1))
425             || (template_val == 0x12                    /* MBB */
426                 && IS_NOP_B (s1))
427             || (template_val == 0x16                    /* BBB */
428                 && IS_NOP_B (s0)
429                 && IS_NOP_B (s1))
430             || (template_val == 0x18                    /* MMB */
431                 && IS_NOP_M (s1))
432             || (template_val == 0x1c                    /* MFB */
433                 && IS_NOP_F (s1))))
434         return FALSE;
435       br_code = s2;
436       break;
437     default:
438       /* It should never happen.  */
439       abort ();
440     }
441
442   /* We can turn br.cond/br.call into brl.cond/brl.call.  */
443   if (!(IS_BR_COND (br_code) || IS_BR_CALL (br_code)))
444     return FALSE;
445
446   /* Turn br into brl by setting bit 40.  */
447   br_code |= 0x1LL << 40;
448
449   /* Turn the old bundle into a MLX bundle with the same stop-bit
450      variety.  */
451   if (t0 & 0x1)
452     mlx = 0x5;
453   else
454     mlx = 0x4;
455
456   if (template_val == 0x16)
457     {
458       /* For BBB, we need to put nop.m in slot 0.  We keep the original
459          predicate only if slot 0 isn't br.  */
460       if (br_slot == 0)
461         t0 = 0LL;
462       else
463         t0 &= PREDICATE_BITS << 5;
464       t0 |= 0x1LL << (X4_SHIFT + 5);
465     }
466   else
467     {
468       /* Keep the original instruction in slot 0.  */
469       t0 &= 0x1ffffffffffLL << 5;
470     }
471
472   t0 |= mlx;
473
474   /* Put brl in slot 1.  */
475   t1 = br_code << 23;
476
477   bfd_putl64 (t0, hit_addr);
478   bfd_putl64 (t1, hit_addr + 8);
479   return TRUE;
480 }
481
482 void
483 ia64_elf_relax_brl (bfd_byte *contents, bfd_vma off)
484 {
485   int template_val;
486   bfd_byte *hit_addr;
487   bfd_vma t0, t1, i0, i1, i2;
488
489   hit_addr = (bfd_byte *) (contents + off);
490   hit_addr -= (intptr_t) hit_addr & 0x3;
491   t0 = bfd_getl64 (hit_addr);
492   t1 = bfd_getl64 (hit_addr + 8);
493
494   /* Keep the instruction in slot 0. */
495   i0 = (t0 >> 5) & 0x1ffffffffffLL;
496   /* Use nop.b for slot 1. */
497   i1 = 0x4000000000LL;
498   /* For slot 2, turn brl into br by masking out bit 40.  */
499   i2 = (t1 >> 23) & 0x0ffffffffffLL;
500
501   /* Turn a MLX bundle into a MBB bundle with the same stop-bit
502      variety.  */
503   if (t0 & 0x1)
504     template_val = 0x13;
505   else
506     template_val = 0x12;
507   t0 = (i1 << 46) | (i0 << 5) | template_val;
508   t1 = (i2 << 23) | (i1 >> 18);
509
510   bfd_putl64 (t0, hit_addr);
511   bfd_putl64 (t1, hit_addr + 8);
512 }
513
514 void
515 ia64_elf_relax_ldxmov (bfd_byte *contents, bfd_vma off)
516 {
517   int shift, r1, r3;
518   bfd_vma dword, insn;
519
520   switch ((int)off & 0x3)
521     {
522     case 0: shift =  5; break;
523     case 1: shift = 14; off += 3; break;
524     case 2: shift = 23; off += 6; break;
525     default:
526       abort ();
527     }
528
529   dword = bfd_getl64 (contents + off);
530   insn = (dword >> shift) & 0x1ffffffffffLL;
531
532   r1 = (insn >> 6) & 127;
533   r3 = (insn >> 20) & 127;
534   if (r1 == r3)
535     insn = 0x8000000;                              /* nop */
536   else
537     insn = (insn & 0x7f01fff) | 0x10800000000LL;   /* (qp) mov r1 = r3 */
538
539   dword &= ~(0x1ffffffffffLL << shift);
540   dword |= (insn << shift);
541   bfd_putl64 (dword, contents + off);
542 }
543 \f
544 bfd_reloc_status_type
545 ia64_elf_install_value (bfd_byte *hit_addr, bfd_vma v, unsigned int r_type)
546 {
547   const struct ia64_operand *op;
548   int bigendian = 0, shift = 0;
549   bfd_vma t0, t1, dword;
550   ia64_insn insn;
551   enum ia64_opnd opnd;
552   const char *err;
553   size_t size = 8;
554 #ifdef BFD_HOST_U_64_BIT
555   BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
556 #else
557   bfd_vma val = v;
558 #endif
559
560   opnd = IA64_OPND_NIL;
561   switch (r_type)
562     {
563     case R_IA64_NONE:
564     case R_IA64_LDXMOV:
565       return bfd_reloc_ok;
566
567       /* Instruction relocations.  */
568
569     case R_IA64_IMM14:
570     case R_IA64_TPREL14:
571     case R_IA64_DTPREL14:
572       opnd = IA64_OPND_IMM14;
573       break;
574
575     case R_IA64_PCREL21F:       opnd = IA64_OPND_TGT25; break;
576     case R_IA64_PCREL21M:       opnd = IA64_OPND_TGT25b; break;
577     case R_IA64_PCREL60B:       opnd = IA64_OPND_TGT64; break;
578     case R_IA64_PCREL21B:
579     case R_IA64_PCREL21BI:
580       opnd = IA64_OPND_TGT25c;
581       break;
582
583     case R_IA64_IMM22:
584     case R_IA64_GPREL22:
585     case R_IA64_LTOFF22:
586     case R_IA64_LTOFF22X:
587     case R_IA64_PLTOFF22:
588     case R_IA64_PCREL22:
589     case R_IA64_LTOFF_FPTR22:
590     case R_IA64_TPREL22:
591     case R_IA64_DTPREL22:
592     case R_IA64_LTOFF_TPREL22:
593     case R_IA64_LTOFF_DTPMOD22:
594     case R_IA64_LTOFF_DTPREL22:
595       opnd = IA64_OPND_IMM22;
596       break;
597
598     case R_IA64_IMM64:
599     case R_IA64_GPREL64I:
600     case R_IA64_LTOFF64I:
601     case R_IA64_PLTOFF64I:
602     case R_IA64_PCREL64I:
603     case R_IA64_FPTR64I:
604     case R_IA64_LTOFF_FPTR64I:
605     case R_IA64_TPREL64I:
606     case R_IA64_DTPREL64I:
607       opnd = IA64_OPND_IMMU64;
608       break;
609
610       /* Data relocations.  */
611
612     case R_IA64_DIR32MSB:
613     case R_IA64_GPREL32MSB:
614     case R_IA64_FPTR32MSB:
615     case R_IA64_PCREL32MSB:
616     case R_IA64_LTOFF_FPTR32MSB:
617     case R_IA64_SEGREL32MSB:
618     case R_IA64_SECREL32MSB:
619     case R_IA64_LTV32MSB:
620     case R_IA64_DTPREL32MSB:
621       size = 4; bigendian = 1;
622       break;
623
624     case R_IA64_DIR32LSB:
625     case R_IA64_GPREL32LSB:
626     case R_IA64_FPTR32LSB:
627     case R_IA64_PCREL32LSB:
628     case R_IA64_LTOFF_FPTR32LSB:
629     case R_IA64_SEGREL32LSB:
630     case R_IA64_SECREL32LSB:
631     case R_IA64_LTV32LSB:
632     case R_IA64_DTPREL32LSB:
633       size = 4; bigendian = 0;
634       break;
635
636     case R_IA64_DIR64MSB:
637     case R_IA64_GPREL64MSB:
638     case R_IA64_PLTOFF64MSB:
639     case R_IA64_FPTR64MSB:
640     case R_IA64_PCREL64MSB:
641     case R_IA64_LTOFF_FPTR64MSB:
642     case R_IA64_SEGREL64MSB:
643     case R_IA64_SECREL64MSB:
644     case R_IA64_LTV64MSB:
645     case R_IA64_TPREL64MSB:
646     case R_IA64_DTPMOD64MSB:
647     case R_IA64_DTPREL64MSB:
648       size = 8; bigendian = 1;
649       break;
650
651     case R_IA64_DIR64LSB:
652     case R_IA64_GPREL64LSB:
653     case R_IA64_PLTOFF64LSB:
654     case R_IA64_FPTR64LSB:
655     case R_IA64_PCREL64LSB:
656     case R_IA64_LTOFF_FPTR64LSB:
657     case R_IA64_SEGREL64LSB:
658     case R_IA64_SECREL64LSB:
659     case R_IA64_LTV64LSB:
660     case R_IA64_TPREL64LSB:
661     case R_IA64_DTPMOD64LSB:
662     case R_IA64_DTPREL64LSB:
663       size = 8; bigendian = 0;
664       break;
665
666       /* Unsupported / Dynamic relocations.  */
667     default:
668       return bfd_reloc_notsupported;
669     }
670
671   switch (opnd)
672     {
673     case IA64_OPND_IMMU64:
674       hit_addr -= (intptr_t) hit_addr & 0x3;
675       t0 = bfd_getl64 (hit_addr);
676       t1 = bfd_getl64 (hit_addr + 8);
677
678       /* tmpl/s: bits  0.. 5 in t0
679          slot 0: bits  5..45 in t0
680          slot 1: bits 46..63 in t0, bits 0..22 in t1
681          slot 2: bits 23..63 in t1 */
682
683       /* First, clear the bits that form the 64 bit constant.  */
684       t0 &= ~(0x3ffffLL << 46);
685       t1 &= ~(0x7fffffLL
686               | ((  (0x07fLL << 13) | (0x1ffLL << 27)
687                     | (0x01fLL << 22) | (0x001LL << 21)
688                     | (0x001LL << 36)) << 23));
689
690       t0 |= ((val >> 22) & 0x03ffffLL) << 46;           /* 18 lsbs of imm41 */
691       t1 |= ((val >> 40) & 0x7fffffLL) <<  0;           /* 23 msbs of imm41 */
692       t1 |= (  (((val >>  0) & 0x07f) << 13)            /* imm7b */
693                | (((val >>  7) & 0x1ff) << 27)          /* imm9d */
694                | (((val >> 16) & 0x01f) << 22)          /* imm5c */
695                | (((val >> 21) & 0x001) << 21)          /* ic */
696                | (((val >> 63) & 0x001) << 36)) << 23;  /* i */
697
698       bfd_putl64 (t0, hit_addr);
699       bfd_putl64 (t1, hit_addr + 8);
700       break;
701
702     case IA64_OPND_TGT64:
703       hit_addr -= (intptr_t) hit_addr & 0x3;
704       t0 = bfd_getl64 (hit_addr);
705       t1 = bfd_getl64 (hit_addr + 8);
706
707       /* tmpl/s: bits  0.. 5 in t0
708          slot 0: bits  5..45 in t0
709          slot 1: bits 46..63 in t0, bits 0..22 in t1
710          slot 2: bits 23..63 in t1 */
711
712       /* First, clear the bits that form the 64 bit constant.  */
713       t0 &= ~(0x3ffffLL << 46);
714       t1 &= ~(0x7fffffLL
715               | ((1LL << 36 | 0xfffffLL << 13) << 23));
716
717       val >>= 4;
718       t0 |= ((val >> 20) & 0xffffLL) << 2 << 46;        /* 16 lsbs of imm39 */
719       t1 |= ((val >> 36) & 0x7fffffLL) << 0;            /* 23 msbs of imm39 */
720       t1 |= ((((val >> 0) & 0xfffffLL) << 13)           /* imm20b */
721               | (((val >> 59) & 0x1LL) << 36)) << 23;   /* i */
722
723       bfd_putl64 (t0, hit_addr);
724       bfd_putl64 (t1, hit_addr + 8);
725       break;
726
727     default:
728       switch ((intptr_t) hit_addr & 0x3)
729         {
730         case 0: shift =  5; break;
731         case 1: shift = 14; hit_addr += 3; break;
732         case 2: shift = 23; hit_addr += 6; break;
733         case 3: return bfd_reloc_notsupported; /* shouldn't happen...  */
734         }
735       dword = bfd_getl64 (hit_addr);
736       insn = (dword >> shift) & 0x1ffffffffffLL;
737
738       op = elf64_ia64_operands + opnd;
739       err = (*op->insert) (op, val, &insn);
740       if (err)
741         return bfd_reloc_overflow;
742
743       dword &= ~(0x1ffffffffffLL << shift);
744       dword |= (insn << shift);
745       bfd_putl64 (dword, hit_addr);
746       break;
747
748     case IA64_OPND_NIL:
749       /* A data relocation.  */
750       if (bigendian)
751         if (size == 4)
752           bfd_putb32 (val, hit_addr);
753         else
754           bfd_putb64 (val, hit_addr);
755       else
756         if (size == 4)
757           bfd_putl32 (val, hit_addr);
758         else
759           bfd_putl64 (val, hit_addr);
760       break;
761     }
762
763   return bfd_reloc_ok;
764 }