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