Remove SIM_CHECK_MEMBER* in sim/common/.
[deliverable/binutils-gdb.git] / bfd / elfxx-ia64.c
CommitLineData
800eeca4 1/* IA-64 support for 64-bit ELF
01e1a5bc
NC
2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
3 2009 Free Software Foundation, Inc.
800eeca4
JW
4 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5
5e8d7549 6 This file is part of BFD, the Binary File Descriptor library.
800eeca4 7
5e8d7549
NC
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
cd123cb7 10 the Free Software Foundation; either version 3 of the License, or
5e8d7549 11 (at your option) any later version.
800eeca4 12
5e8d7549
NC
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
800eeca4 17
5e8d7549
NC
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
cd123cb7
NC
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
800eeca4 22
800eeca4 23#include "sysdep.h"
3db64b00 24#include "bfd.h"
800eeca4
JW
25#include "libbfd.h"
26#include "elf-bfd.h"
27#include "opcode/ia64.h"
28#include "elf/ia64.h"
0aa92b58
JJ
29#include "objalloc.h"
30#include "hashtab.h"
800eeca4 31
5a260b66
L
32#define ARCH_SIZE NN
33
34#if ARCH_SIZE == 64
35#define LOG_SECTION_ALIGN 3
36#endif
37
38#if ARCH_SIZE == 32
39#define LOG_SECTION_ALIGN 2
40#endif
41
5e8d7549 42/* THE RULES for all the stuff the linker creates --
b34976b6 43
5e8d7549
NC
44 GOT Entries created in response to LTOFF or LTOFF_FPTR
45 relocations. Dynamic relocs created for dynamic
46 symbols in an application; REL relocs for locals
47 in a shared library.
b34976b6 48
5e8d7549
NC
49 FPTR The canonical function descriptor. Created for local
50 symbols in applications. Descriptors for dynamic symbols
51 and local symbols in shared libraries are created by
52 ld.so. Thus there are no dynamic relocs against these
53 objects. The FPTR relocs for such _are_ passed through
54 to the dynamic relocation tables.
b34976b6 55
5e8d7549
NC
56 FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
57 Requires the creation of a PLTOFF entry. This does not
58 require any dynamic relocations.
b34976b6 59
5e8d7549
NC
60 PLTOFF Created by PLTOFF relocations. For local symbols, this
61 is an alternate function descriptor, and in shared libraries
62 requires two REL relocations. Note that this cannot be
63 transformed into an FPTR relocation, since it must be in
64 range of the GP. For dynamic symbols, this is a function
65 descriptor for a MIN_PLT entry, and requires one IPLT reloc.
b34976b6 66
5e8d7549 67 MIN_PLT Created by PLTOFF entries against dynamic symbols. This
4cc11e76 68 does not require dynamic relocations. */
800eeca4 69
800eeca4
JW
70#define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
71
72typedef struct bfd_hash_entry *(*new_hash_entry_func)
73 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
74
75/* In dynamically (linker-) created sections, we generally need to keep track
76 of the place a symbol or expression got allocated to. This is done via hash
77 tables that store entries of the following type. */
78
bbe66d08 79struct elfNN_ia64_dyn_sym_info
800eeca4
JW
80{
81 /* The addend for which this entry is relevant. */
82 bfd_vma addend;
83
800eeca4
JW
84 bfd_vma got_offset;
85 bfd_vma fptr_offset;
86 bfd_vma pltoff_offset;
87 bfd_vma plt_offset;
88 bfd_vma plt2_offset;
13ae64f3
JJ
89 bfd_vma tprel_offset;
90 bfd_vma dtpmod_offset;
91 bfd_vma dtprel_offset;
800eeca4 92
4cc11e76 93 /* The symbol table entry, if any, that this was derived from. */
800eeca4 94 struct elf_link_hash_entry *h;
3e932841 95
800eeca4
JW
96 /* Used to count non-got, non-plt relocations for delayed sizing
97 of relocation sections. */
bbe66d08 98 struct elfNN_ia64_dyn_reloc_entry
800eeca4 99 {
bbe66d08 100 struct elfNN_ia64_dyn_reloc_entry *next;
800eeca4
JW
101 asection *srel;
102 int type;
103 int count;
ac33696c
L
104
105 /* Is this reloc against readonly section? */
106 bfd_boolean reltext;
800eeca4
JW
107 } *reloc_entries;
108
b34976b6 109 /* TRUE when the section contents have been updated. */
800eeca4
JW
110 unsigned got_done : 1;
111 unsigned fptr_done : 1;
112 unsigned pltoff_done : 1;
13ae64f3
JJ
113 unsigned tprel_done : 1;
114 unsigned dtpmod_done : 1;
115 unsigned dtprel_done : 1;
800eeca4 116
b34976b6 117 /* TRUE for the different kinds of linker data we want created. */
800eeca4 118 unsigned want_got : 1;
2c4c2bc0 119 unsigned want_gotx : 1;
800eeca4
JW
120 unsigned want_fptr : 1;
121 unsigned want_ltoff_fptr : 1;
122 unsigned want_plt : 1;
123 unsigned want_plt2 : 1;
124 unsigned want_pltoff : 1;
13ae64f3
JJ
125 unsigned want_tprel : 1;
126 unsigned want_dtpmod : 1;
127 unsigned want_dtprel : 1;
800eeca4
JW
128};
129
bbe66d08 130struct elfNN_ia64_local_hash_entry
800eeca4 131{
0aa92b58
JJ
132 int id;
133 unsigned int r_sym;
396a682d
L
134 /* The number of elements in elfNN_ia64_dyn_sym_info array. */
135 unsigned int count;
136 /* The number of sorted elements in elfNN_ia64_dyn_sym_info array. */
137 unsigned int sorted_count;
138 /* The size of elfNN_ia64_dyn_sym_info array. */
139 unsigned int size;
140 /* The array of elfNN_ia64_dyn_sym_info. */
bbe66d08 141 struct elfNN_ia64_dyn_sym_info *info;
f7460f5f 142
b34976b6 143 /* TRUE if this hash entry's addends was translated for
f7460f5f
JJ
144 SHF_MERGE optimization. */
145 unsigned sec_merge_done : 1;
800eeca4
JW
146};
147
bbe66d08 148struct elfNN_ia64_link_hash_entry
800eeca4
JW
149{
150 struct elf_link_hash_entry root;
396a682d
L
151 /* The number of elements in elfNN_ia64_dyn_sym_info array. */
152 unsigned int count;
153 /* The number of sorted elements in elfNN_ia64_dyn_sym_info array. */
154 unsigned int sorted_count;
155 /* The size of elfNN_ia64_dyn_sym_info array. */
156 unsigned int size;
157 /* The array of elfNN_ia64_dyn_sym_info. */
bbe66d08 158 struct elfNN_ia64_dyn_sym_info *info;
800eeca4
JW
159};
160
bbe66d08 161struct elfNN_ia64_link_hash_table
800eeca4 162{
5e8d7549 163 /* The main hash table. */
800eeca4
JW
164 struct elf_link_hash_table root;
165
800eeca4 166 asection *fptr_sec; /* function descriptor table (or NULL) */
9203ba99 167 asection *rel_fptr_sec; /* dynamic relocation section for same */
800eeca4
JW
168 asection *pltoff_sec; /* private descriptors for plt (or NULL) */
169 asection *rel_pltoff_sec; /* dynamic relocation section for same */
170
171 bfd_size_type minplt_entries; /* number of minplt entries */
db6751f2 172 unsigned reltext : 1; /* are there relocs against readonly sections? */
b3dfd7fe
JJ
173 unsigned self_dtpmod_done : 1;/* has self DTPMOD entry been finished? */
174 bfd_vma self_dtpmod_offset; /* .got offset to self DTPMOD entry */
800eeca4 175
0aa92b58
JJ
176 htab_t loc_hash_table;
177 void *loc_hash_memory;
800eeca4
JW
178};
179
2c4c2bc0
RH
180struct elfNN_ia64_allocate_data
181{
182 struct bfd_link_info *info;
183 bfd_size_type ofs;
4a78a1f4 184 bfd_boolean only_got;
2c4c2bc0
RH
185};
186
bbe66d08
JW
187#define elfNN_ia64_hash_table(p) \
188 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
800eeca4 189
eae50df2
L
190static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
191 (struct elfNN_ia64_link_hash_table *ia64_info,
192 struct elf_link_hash_entry *h,
193 bfd *abfd, const Elf_Internal_Rela *rel, bfd_boolean create);
b34976b6 194static bfd_boolean elfNN_ia64_dynamic_symbol_p
eae50df2
L
195 (struct elf_link_hash_entry *h, struct bfd_link_info *info, int);
196static bfd_reloc_status_type elfNN_ia64_install_value
197 (bfd_byte *hit_addr, bfd_vma val, unsigned int r_type);
198static bfd_boolean elfNN_ia64_choose_gp
199 (bfd *abfd, struct bfd_link_info *info);
200static void elfNN_ia64_relax_ldxmov
201 (bfd_byte *contents, bfd_vma off);
bbe66d08 202static void elfNN_ia64_dyn_sym_traverse
eae50df2
L
203 (struct elfNN_ia64_link_hash_table *ia64_info,
204 bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
205 PTR info);
b34976b6 206static bfd_boolean allocate_global_data_got
eae50df2 207 (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data);
b34976b6 208static bfd_boolean allocate_global_fptr_got
eae50df2 209 (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data);
b34976b6 210static bfd_boolean allocate_local_got
eae50df2 211 (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data);
b34976b6 212static bfd_boolean elfNN_ia64_hpux_vec
eae50df2
L
213 (const bfd_target *vec);
214static bfd_boolean allocate_dynrel_entries
215 (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data);
216static asection *get_pltoff
217 (bfd *abfd, struct bfd_link_info *info,
218 struct elfNN_ia64_link_hash_table *ia64_info);
800eeca4 219\f
5e8d7549 220/* ia64-specific relocation. */
800eeca4
JW
221
222/* Perform a relocation. Not much to do here as all the hard work is
bbe66d08 223 done in elfNN_ia64_final_link_relocate. */
800eeca4 224static bfd_reloc_status_type
eae50df2
L
225elfNN_ia64_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc,
226 asymbol *sym ATTRIBUTE_UNUSED,
227 PTR data ATTRIBUTE_UNUSED, asection *input_section,
228 bfd *output_bfd, char **error_message)
800eeca4
JW
229{
230 if (output_bfd)
231 {
232 reloc->address += input_section->output_offset;
233 return bfd_reloc_ok;
234 }
6e84a906
DJ
235
236 if (input_section->flags & SEC_DEBUGGING)
237 return bfd_reloc_continue;
238
bbe66d08 239 *error_message = "Unsupported call to elfNN_ia64_reloc";
800eeca4
JW
240 return bfd_reloc_notsupported;
241}
242
243#define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
244 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
eff26f78 245 elfNN_ia64_reloc, NAME, FALSE, 0, -1, IN)
800eeca4
JW
246
247/* This table has to be sorted according to increasing number of the
248 TYPE field. */
249static reloc_howto_type ia64_howto_table[] =
250 {
b34976b6
AM
251 IA64_HOWTO (R_IA64_NONE, "NONE", 0, FALSE, TRUE),
252
253 IA64_HOWTO (R_IA64_IMM14, "IMM14", 0, FALSE, TRUE),
254 IA64_HOWTO (R_IA64_IMM22, "IMM22", 0, FALSE, TRUE),
255 IA64_HOWTO (R_IA64_IMM64, "IMM64", 0, FALSE, TRUE),
256 IA64_HOWTO (R_IA64_DIR32MSB, "DIR32MSB", 2, FALSE, TRUE),
257 IA64_HOWTO (R_IA64_DIR32LSB, "DIR32LSB", 2, FALSE, TRUE),
258 IA64_HOWTO (R_IA64_DIR64MSB, "DIR64MSB", 4, FALSE, TRUE),
259 IA64_HOWTO (R_IA64_DIR64LSB, "DIR64LSB", 4, FALSE, TRUE),
260
261 IA64_HOWTO (R_IA64_GPREL22, "GPREL22", 0, FALSE, TRUE),
262 IA64_HOWTO (R_IA64_GPREL64I, "GPREL64I", 0, FALSE, TRUE),
263 IA64_HOWTO (R_IA64_GPREL32MSB, "GPREL32MSB", 2, FALSE, TRUE),
264 IA64_HOWTO (R_IA64_GPREL32LSB, "GPREL32LSB", 2, FALSE, TRUE),
265 IA64_HOWTO (R_IA64_GPREL64MSB, "GPREL64MSB", 4, FALSE, TRUE),
266 IA64_HOWTO (R_IA64_GPREL64LSB, "GPREL64LSB", 4, FALSE, TRUE),
267
268 IA64_HOWTO (R_IA64_LTOFF22, "LTOFF22", 0, FALSE, TRUE),
269 IA64_HOWTO (R_IA64_LTOFF64I, "LTOFF64I", 0, FALSE, TRUE),
270
271 IA64_HOWTO (R_IA64_PLTOFF22, "PLTOFF22", 0, FALSE, TRUE),
272 IA64_HOWTO (R_IA64_PLTOFF64I, "PLTOFF64I", 0, FALSE, TRUE),
273 IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, FALSE, TRUE),
274 IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, FALSE, TRUE),
275
276 IA64_HOWTO (R_IA64_FPTR64I, "FPTR64I", 0, FALSE, TRUE),
277 IA64_HOWTO (R_IA64_FPTR32MSB, "FPTR32MSB", 2, FALSE, TRUE),
278 IA64_HOWTO (R_IA64_FPTR32LSB, "FPTR32LSB", 2, FALSE, TRUE),
279 IA64_HOWTO (R_IA64_FPTR64MSB, "FPTR64MSB", 4, FALSE, TRUE),
280 IA64_HOWTO (R_IA64_FPTR64LSB, "FPTR64LSB", 4, FALSE, TRUE),
281
282 IA64_HOWTO (R_IA64_PCREL60B, "PCREL60B", 0, TRUE, TRUE),
283 IA64_HOWTO (R_IA64_PCREL21B, "PCREL21B", 0, TRUE, TRUE),
284 IA64_HOWTO (R_IA64_PCREL21M, "PCREL21M", 0, TRUE, TRUE),
285 IA64_HOWTO (R_IA64_PCREL21F, "PCREL21F", 0, TRUE, TRUE),
286 IA64_HOWTO (R_IA64_PCREL32MSB, "PCREL32MSB", 2, TRUE, TRUE),
287 IA64_HOWTO (R_IA64_PCREL32LSB, "PCREL32LSB", 2, TRUE, TRUE),
288 IA64_HOWTO (R_IA64_PCREL64MSB, "PCREL64MSB", 4, TRUE, TRUE),
289 IA64_HOWTO (R_IA64_PCREL64LSB, "PCREL64LSB", 4, TRUE, TRUE),
290
291 IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, FALSE, TRUE),
292 IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, FALSE, TRUE),
293 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB, "LTOFF_FPTR32MSB", 2, FALSE, TRUE),
294 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB, "LTOFF_FPTR32LSB", 2, FALSE, TRUE),
295 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, FALSE, TRUE),
296 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, FALSE, TRUE),
297
298 IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, FALSE, TRUE),
299 IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, FALSE, TRUE),
300 IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, FALSE, TRUE),
301 IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, FALSE, TRUE),
302
303 IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, FALSE, TRUE),
304 IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, FALSE, TRUE),
305 IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, FALSE, TRUE),
306 IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, FALSE, TRUE),
307
308 IA64_HOWTO (R_IA64_REL32MSB, "REL32MSB", 2, FALSE, TRUE),
309 IA64_HOWTO (R_IA64_REL32LSB, "REL32LSB", 2, FALSE, TRUE),
310 IA64_HOWTO (R_IA64_REL64MSB, "REL64MSB", 4, FALSE, TRUE),
311 IA64_HOWTO (R_IA64_REL64LSB, "REL64LSB", 4, FALSE, TRUE),
312
313 IA64_HOWTO (R_IA64_LTV32MSB, "LTV32MSB", 2, FALSE, TRUE),
314 IA64_HOWTO (R_IA64_LTV32LSB, "LTV32LSB", 2, FALSE, TRUE),
315 IA64_HOWTO (R_IA64_LTV64MSB, "LTV64MSB", 4, FALSE, TRUE),
316 IA64_HOWTO (R_IA64_LTV64LSB, "LTV64LSB", 4, FALSE, TRUE),
317
318 IA64_HOWTO (R_IA64_PCREL21BI, "PCREL21BI", 0, TRUE, TRUE),
319 IA64_HOWTO (R_IA64_PCREL22, "PCREL22", 0, TRUE, TRUE),
320 IA64_HOWTO (R_IA64_PCREL64I, "PCREL64I", 0, TRUE, TRUE),
321
322 IA64_HOWTO (R_IA64_IPLTMSB, "IPLTMSB", 4, FALSE, TRUE),
323 IA64_HOWTO (R_IA64_IPLTLSB, "IPLTLSB", 4, FALSE, TRUE),
324 IA64_HOWTO (R_IA64_COPY, "COPY", 4, FALSE, TRUE),
325 IA64_HOWTO (R_IA64_LTOFF22X, "LTOFF22X", 0, FALSE, TRUE),
326 IA64_HOWTO (R_IA64_LDXMOV, "LDXMOV", 0, FALSE, TRUE),
327
328 IA64_HOWTO (R_IA64_TPREL14, "TPREL14", 0, FALSE, FALSE),
329 IA64_HOWTO (R_IA64_TPREL22, "TPREL22", 0, FALSE, FALSE),
330 IA64_HOWTO (R_IA64_TPREL64I, "TPREL64I", 0, FALSE, FALSE),
1fc0d173
JJ
331 IA64_HOWTO (R_IA64_TPREL64MSB, "TPREL64MSB", 4, FALSE, FALSE),
332 IA64_HOWTO (R_IA64_TPREL64LSB, "TPREL64LSB", 4, FALSE, FALSE),
b34976b6
AM
333 IA64_HOWTO (R_IA64_LTOFF_TPREL22, "LTOFF_TPREL22", 0, FALSE, FALSE),
334
0ca3e455
JB
335 IA64_HOWTO (R_IA64_DTPMOD64MSB, "DTPMOD64MSB", 4, FALSE, FALSE),
336 IA64_HOWTO (R_IA64_DTPMOD64LSB, "DTPMOD64LSB", 4, FALSE, FALSE),
b34976b6
AM
337 IA64_HOWTO (R_IA64_LTOFF_DTPMOD22, "LTOFF_DTPMOD22", 0, FALSE, FALSE),
338
339 IA64_HOWTO (R_IA64_DTPREL14, "DTPREL14", 0, FALSE, FALSE),
340 IA64_HOWTO (R_IA64_DTPREL22, "DTPREL22", 0, FALSE, FALSE),
341 IA64_HOWTO (R_IA64_DTPREL64I, "DTPREL64I", 0, FALSE, FALSE),
1fc0d173
JJ
342 IA64_HOWTO (R_IA64_DTPREL32MSB, "DTPREL32MSB", 2, FALSE, FALSE),
343 IA64_HOWTO (R_IA64_DTPREL32LSB, "DTPREL32LSB", 2, FALSE, FALSE),
344 IA64_HOWTO (R_IA64_DTPREL64MSB, "DTPREL64MSB", 4, FALSE, FALSE),
345 IA64_HOWTO (R_IA64_DTPREL64LSB, "DTPREL64LSB", 4, FALSE, FALSE),
b34976b6 346 IA64_HOWTO (R_IA64_LTOFF_DTPREL22, "LTOFF_DTPREL22", 0, FALSE, FALSE),
800eeca4
JW
347 };
348
349static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
350
351/* Given a BFD reloc type, return the matching HOWTO structure. */
352
5e8d7549 353static reloc_howto_type *
eae50df2 354lookup_howto (unsigned int rtype)
800eeca4
JW
355{
356 static int inited = 0;
357 int i;
358
359 if (!inited)
360 {
361 inited = 1;
362
363 memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
364 for (i = 0; i < NELEMS (ia64_howto_table); ++i)
365 elf_code_to_howto_index[ia64_howto_table[i].type] = i;
366 }
367
d0fb9a8d
JJ
368 if (rtype > R_IA64_MAX_RELOC_CODE)
369 return 0;
800eeca4
JW
370 i = elf_code_to_howto_index[rtype];
371 if (i >= NELEMS (ia64_howto_table))
372 return 0;
373 return ia64_howto_table + i;
374}
375
376static reloc_howto_type*
eae50df2
L
377elfNN_ia64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
378 bfd_reloc_code_real_type bfd_code)
800eeca4
JW
379{
380 unsigned int rtype;
381
382 switch (bfd_code)
383 {
384 case BFD_RELOC_NONE: rtype = R_IA64_NONE; break;
385
386 case BFD_RELOC_IA64_IMM14: rtype = R_IA64_IMM14; break;
387 case BFD_RELOC_IA64_IMM22: rtype = R_IA64_IMM22; break;
388 case BFD_RELOC_IA64_IMM64: rtype = R_IA64_IMM64; break;
389
390 case BFD_RELOC_IA64_DIR32MSB: rtype = R_IA64_DIR32MSB; break;
391 case BFD_RELOC_IA64_DIR32LSB: rtype = R_IA64_DIR32LSB; break;
392 case BFD_RELOC_IA64_DIR64MSB: rtype = R_IA64_DIR64MSB; break;
393 case BFD_RELOC_IA64_DIR64LSB: rtype = R_IA64_DIR64LSB; break;
394
395 case BFD_RELOC_IA64_GPREL22: rtype = R_IA64_GPREL22; break;
396 case BFD_RELOC_IA64_GPREL64I: rtype = R_IA64_GPREL64I; break;
397 case BFD_RELOC_IA64_GPREL32MSB: rtype = R_IA64_GPREL32MSB; break;
398 case BFD_RELOC_IA64_GPREL32LSB: rtype = R_IA64_GPREL32LSB; break;
399 case BFD_RELOC_IA64_GPREL64MSB: rtype = R_IA64_GPREL64MSB; break;
400 case BFD_RELOC_IA64_GPREL64LSB: rtype = R_IA64_GPREL64LSB; break;
401
402 case BFD_RELOC_IA64_LTOFF22: rtype = R_IA64_LTOFF22; break;
403 case BFD_RELOC_IA64_LTOFF64I: rtype = R_IA64_LTOFF64I; break;
404
405 case BFD_RELOC_IA64_PLTOFF22: rtype = R_IA64_PLTOFF22; break;
406 case BFD_RELOC_IA64_PLTOFF64I: rtype = R_IA64_PLTOFF64I; break;
407 case BFD_RELOC_IA64_PLTOFF64MSB: rtype = R_IA64_PLTOFF64MSB; break;
408 case BFD_RELOC_IA64_PLTOFF64LSB: rtype = R_IA64_PLTOFF64LSB; break;
409 case BFD_RELOC_IA64_FPTR64I: rtype = R_IA64_FPTR64I; break;
410 case BFD_RELOC_IA64_FPTR32MSB: rtype = R_IA64_FPTR32MSB; break;
411 case BFD_RELOC_IA64_FPTR32LSB: rtype = R_IA64_FPTR32LSB; break;
412 case BFD_RELOC_IA64_FPTR64MSB: rtype = R_IA64_FPTR64MSB; break;
413 case BFD_RELOC_IA64_FPTR64LSB: rtype = R_IA64_FPTR64LSB; break;
414
415 case BFD_RELOC_IA64_PCREL21B: rtype = R_IA64_PCREL21B; break;
748abff6 416 case BFD_RELOC_IA64_PCREL21BI: rtype = R_IA64_PCREL21BI; break;
800eeca4
JW
417 case BFD_RELOC_IA64_PCREL21M: rtype = R_IA64_PCREL21M; break;
418 case BFD_RELOC_IA64_PCREL21F: rtype = R_IA64_PCREL21F; break;
748abff6
RH
419 case BFD_RELOC_IA64_PCREL22: rtype = R_IA64_PCREL22; break;
420 case BFD_RELOC_IA64_PCREL60B: rtype = R_IA64_PCREL60B; break;
421 case BFD_RELOC_IA64_PCREL64I: rtype = R_IA64_PCREL64I; break;
800eeca4
JW
422 case BFD_RELOC_IA64_PCREL32MSB: rtype = R_IA64_PCREL32MSB; break;
423 case BFD_RELOC_IA64_PCREL32LSB: rtype = R_IA64_PCREL32LSB; break;
424 case BFD_RELOC_IA64_PCREL64MSB: rtype = R_IA64_PCREL64MSB; break;
425 case BFD_RELOC_IA64_PCREL64LSB: rtype = R_IA64_PCREL64LSB; break;
426
427 case BFD_RELOC_IA64_LTOFF_FPTR22: rtype = R_IA64_LTOFF_FPTR22; break;
428 case BFD_RELOC_IA64_LTOFF_FPTR64I: rtype = R_IA64_LTOFF_FPTR64I; break;
a4bd8390
JW
429 case BFD_RELOC_IA64_LTOFF_FPTR32MSB: rtype = R_IA64_LTOFF_FPTR32MSB; break;
430 case BFD_RELOC_IA64_LTOFF_FPTR32LSB: rtype = R_IA64_LTOFF_FPTR32LSB; break;
800eeca4
JW
431 case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
432 case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
433
800eeca4
JW
434 case BFD_RELOC_IA64_SEGREL32MSB: rtype = R_IA64_SEGREL32MSB; break;
435 case BFD_RELOC_IA64_SEGREL32LSB: rtype = R_IA64_SEGREL32LSB; break;
436 case BFD_RELOC_IA64_SEGREL64MSB: rtype = R_IA64_SEGREL64MSB; break;
437 case BFD_RELOC_IA64_SEGREL64LSB: rtype = R_IA64_SEGREL64LSB; break;
438
439 case BFD_RELOC_IA64_SECREL32MSB: rtype = R_IA64_SECREL32MSB; break;
440 case BFD_RELOC_IA64_SECREL32LSB: rtype = R_IA64_SECREL32LSB; break;
441 case BFD_RELOC_IA64_SECREL64MSB: rtype = R_IA64_SECREL64MSB; break;
442 case BFD_RELOC_IA64_SECREL64LSB: rtype = R_IA64_SECREL64LSB; break;
443
444 case BFD_RELOC_IA64_REL32MSB: rtype = R_IA64_REL32MSB; break;
445 case BFD_RELOC_IA64_REL32LSB: rtype = R_IA64_REL32LSB; break;
446 case BFD_RELOC_IA64_REL64MSB: rtype = R_IA64_REL64MSB; break;
447 case BFD_RELOC_IA64_REL64LSB: rtype = R_IA64_REL64LSB; break;
448
449 case BFD_RELOC_IA64_LTV32MSB: rtype = R_IA64_LTV32MSB; break;
450 case BFD_RELOC_IA64_LTV32LSB: rtype = R_IA64_LTV32LSB; break;
451 case BFD_RELOC_IA64_LTV64MSB: rtype = R_IA64_LTV64MSB; break;
452 case BFD_RELOC_IA64_LTV64LSB: rtype = R_IA64_LTV64LSB; break;
453
454 case BFD_RELOC_IA64_IPLTMSB: rtype = R_IA64_IPLTMSB; break;
455 case BFD_RELOC_IA64_IPLTLSB: rtype = R_IA64_IPLTLSB; break;
800eeca4
JW
456 case BFD_RELOC_IA64_COPY: rtype = R_IA64_COPY; break;
457 case BFD_RELOC_IA64_LTOFF22X: rtype = R_IA64_LTOFF22X; break;
458 case BFD_RELOC_IA64_LDXMOV: rtype = R_IA64_LDXMOV; break;
459
13ae64f3 460 case BFD_RELOC_IA64_TPREL14: rtype = R_IA64_TPREL14; break;
800eeca4 461 case BFD_RELOC_IA64_TPREL22: rtype = R_IA64_TPREL22; break;
13ae64f3 462 case BFD_RELOC_IA64_TPREL64I: rtype = R_IA64_TPREL64I; break;
800eeca4
JW
463 case BFD_RELOC_IA64_TPREL64MSB: rtype = R_IA64_TPREL64MSB; break;
464 case BFD_RELOC_IA64_TPREL64LSB: rtype = R_IA64_TPREL64LSB; break;
13ae64f3
JJ
465 case BFD_RELOC_IA64_LTOFF_TPREL22: rtype = R_IA64_LTOFF_TPREL22; break;
466
467 case BFD_RELOC_IA64_DTPMOD64MSB: rtype = R_IA64_DTPMOD64MSB; break;
468 case BFD_RELOC_IA64_DTPMOD64LSB: rtype = R_IA64_DTPMOD64LSB; break;
469 case BFD_RELOC_IA64_LTOFF_DTPMOD22: rtype = R_IA64_LTOFF_DTPMOD22; break;
470
471 case BFD_RELOC_IA64_DTPREL14: rtype = R_IA64_DTPREL14; break;
472 case BFD_RELOC_IA64_DTPREL22: rtype = R_IA64_DTPREL22; break;
473 case BFD_RELOC_IA64_DTPREL64I: rtype = R_IA64_DTPREL64I; break;
474 case BFD_RELOC_IA64_DTPREL32MSB: rtype = R_IA64_DTPREL32MSB; break;
475 case BFD_RELOC_IA64_DTPREL32LSB: rtype = R_IA64_DTPREL32LSB; break;
476 case BFD_RELOC_IA64_DTPREL64MSB: rtype = R_IA64_DTPREL64MSB; break;
477 case BFD_RELOC_IA64_DTPREL64LSB: rtype = R_IA64_DTPREL64LSB; break;
478 case BFD_RELOC_IA64_LTOFF_DTPREL22: rtype = R_IA64_LTOFF_DTPREL22; break;
800eeca4
JW
479
480 default: return 0;
481 }
482 return lookup_howto (rtype);
483}
484
157090f7
AM
485static reloc_howto_type *
486elfNN_ia64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
487 const char *r_name)
488{
489 unsigned int i;
490
491 for (i = 0;
492 i < sizeof (ia64_howto_table) / sizeof (ia64_howto_table[0]);
493 i++)
494 if (ia64_howto_table[i].name != NULL
495 && strcasecmp (ia64_howto_table[i].name, r_name) == 0)
496 return &ia64_howto_table[i];
497
498 return NULL;
499}
500
800eeca4
JW
501/* Given a ELF reloc, return the matching HOWTO structure. */
502
503static void
eae50df2
L
504elfNN_ia64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
505 arelent *bfd_reloc,
506 Elf_Internal_Rela *elf_reloc)
800eeca4 507{
dc810e39
AM
508 bfd_reloc->howto
509 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc->r_info));
800eeca4
JW
510}
511\f
512#define PLT_HEADER_SIZE (3 * 16)
513#define PLT_MIN_ENTRY_SIZE (1 * 16)
514#define PLT_FULL_ENTRY_SIZE (2 * 16)
515#define PLT_RESERVED_WORDS 3
516
517static const bfd_byte plt_header[PLT_HEADER_SIZE] =
518{
519 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
520 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
521 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
522 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
523 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
524 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
525 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
526 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
527 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
528};
529
530static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
531{
532 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
533 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
534 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
535};
536
537static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
538{
539 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
8b6f2683 540 0x00, 0x41, 0x3c, 0x70, 0x29, 0xc0, /* ld8.acq r16=[r15],8*/
800eeca4
JW
541 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
542 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
543 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
544 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
545};
546
547#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
748abff6 548
748abff6
RH
549static const bfd_byte oor_brl[16] =
550{
551 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
552 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
553 0x00, 0x00, 0x00, 0xc0
554};
3f7deb8a
L
555
556static const bfd_byte oor_ip[48] =
557{
558 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
559 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
560 0x01, 0x00, 0x00, 0x60,
561 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
562 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
563 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
564 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
565 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
566 0x60, 0x00, 0x80, 0x00 /* br b6;; */
567};
568
569static size_t oor_branch_size = sizeof (oor_brl);
570
571void
572bfd_elfNN_ia64_after_parse (int itanium)
573{
574 oor_branch_size = itanium ? sizeof (oor_ip) : sizeof (oor_brl);
575}
576
83b6bd86
L
577#define BTYPE_SHIFT 6
578#define Y_SHIFT 26
579#define X6_SHIFT 27
580#define X4_SHIFT 27
581#define X3_SHIFT 33
582#define X2_SHIFT 31
583#define X_SHIFT 33
584#define OPCODE_SHIFT 37
585
586#define OPCODE_BITS (0xfLL << OPCODE_SHIFT)
587#define X6_BITS (0x3fLL << X6_SHIFT)
588#define X4_BITS (0xfLL << X4_SHIFT)
589#define X3_BITS (0x7LL << X3_SHIFT)
590#define X2_BITS (0x3LL << X2_SHIFT)
591#define X_BITS (0x1LL << X_SHIFT)
592#define Y_BITS (0x1LL << Y_SHIFT)
593#define BTYPE_BITS (0x7LL << BTYPE_SHIFT)
594#define PREDICATE_BITS (0x3fLL)
595
596#define IS_NOP_B(i) \
597 (((i) & (OPCODE_BITS | X6_BITS)) == (2LL << OPCODE_SHIFT))
598#define IS_NOP_F(i) \
599 (((i) & (OPCODE_BITS | X_BITS | X6_BITS | Y_BITS)) \
600 == (0x1LL << X6_SHIFT))
601#define IS_NOP_I(i) \
602 (((i) & (OPCODE_BITS | X3_BITS | X6_BITS | Y_BITS)) \
603 == (0x1LL << X6_SHIFT))
604#define IS_NOP_M(i) \
605 (((i) & (OPCODE_BITS | X3_BITS | X2_BITS | X4_BITS | Y_BITS)) \
606 == (0x1LL << X4_SHIFT))
607#define IS_BR_COND(i) \
608 (((i) & (OPCODE_BITS | BTYPE_BITS)) == (0x4LL << OPCODE_SHIFT))
609#define IS_BR_CALL(i) \
610 (((i) & OPCODE_BITS) == (0x5LL << OPCODE_SHIFT))
611
612static bfd_boolean
613elfNN_ia64_relax_br (bfd_byte *contents, bfd_vma off)
614{
615 unsigned int template, mlx;
616 bfd_vma t0, t1, s0, s1, s2, br_code;
617 long br_slot;
618 bfd_byte *hit_addr;
619
620 hit_addr = (bfd_byte *) (contents + off);
621 br_slot = (long) hit_addr & 0x3;
622 hit_addr -= br_slot;
623 t0 = bfd_getl64 (hit_addr + 0);
624 t1 = bfd_getl64 (hit_addr + 8);
625
626 /* Check if we can turn br into brl. A label is always at the start
627 of the bundle. Even if there are predicates on NOPs, we still
628 perform this optimization. */
629 template = t0 & 0x1e;
630 s0 = (t0 >> 5) & 0x1ffffffffffLL;
631 s1 = ((t0 >> 46) | (t1 << 18)) & 0x1ffffffffffLL;
632 s2 = (t1 >> 23) & 0x1ffffffffffLL;
633 switch (br_slot)
634 {
635 case 0:
636 /* Check if slot 1 and slot 2 are NOPs. Possible template is
637 BBB. We only need to check nop.b. */
638 if (!(IS_NOP_B (s1) && IS_NOP_B (s2)))
639 return FALSE;
640 br_code = s0;
641 break;
642 case 1:
643 /* Check if slot 2 is NOP. Possible templates are MBB and BBB.
644 For BBB, slot 0 also has to be nop.b. */
645 if (!((template == 0x12 /* MBB */
646 && IS_NOP_B (s2))
647 || (template == 0x16 /* BBB */
648 && IS_NOP_B (s0)
649 && IS_NOP_B (s2))))
650 return FALSE;
651 br_code = s1;
652 break;
653 case 2:
654 /* Check if slot 1 is NOP. Possible templates are MIB, MBB, BBB,
655 MMB and MFB. For BBB, slot 0 also has to be nop.b. */
656 if (!((template == 0x10 /* MIB */
657 && IS_NOP_I (s1))
658 || (template == 0x12 /* MBB */
659 && IS_NOP_B (s1))
660 || (template == 0x16 /* BBB */
661 && IS_NOP_B (s0)
662 && IS_NOP_B (s1))
663 || (template == 0x18 /* MMB */
664 && IS_NOP_M (s1))
665 || (template == 0x1c /* MFB */
666 && IS_NOP_F (s1))))
667 return FALSE;
668 br_code = s2;
669 break;
670 default:
671 /* It should never happen. */
672 abort ();
673 }
9a2e389a 674
83b6bd86
L
675 /* We can turn br.cond/br.call into brl.cond/brl.call. */
676 if (!(IS_BR_COND (br_code) || IS_BR_CALL (br_code)))
677 return FALSE;
678
679 /* Turn br into brl by setting bit 40. */
680 br_code |= 0x1LL << 40;
681
682 /* Turn the old bundle into a MLX bundle with the same stop-bit
683 variety. */
684 if (t0 & 0x1)
685 mlx = 0x5;
686 else
687 mlx = 0x4;
688
689 if (template == 0x16)
690 {
5e27d427
L
691 /* For BBB, we need to put nop.m in slot 0. We keep the original
692 predicate only if slot 0 isn't br. */
693 if (br_slot == 0)
694 t0 = 0LL;
695 else
696 t0 &= PREDICATE_BITS << 5;
83b6bd86
L
697 t0 |= 0x1LL << (X4_SHIFT + 5);
698 }
699 else
700 {
701 /* Keep the original instruction in slot 0. */
702 t0 &= 0x1ffffffffffLL << 5;
703 }
704
705 t0 |= mlx;
706
707 /* Put brl in slot 1. */
708 t1 = br_code << 23;
709
710 bfd_putl64 (t0, hit_addr);
711 bfd_putl64 (t1, hit_addr + 8);
712 return TRUE;
713}
714
03609792 715static void
bbb268c3 716elfNN_ia64_relax_brl (bfd_byte *contents, bfd_vma off)
03609792 717{
fc3ab699 718 int template;
03609792 719 bfd_byte *hit_addr;
fc3ab699 720 bfd_vma t0, t1, i0, i1, i2;
03609792
L
721
722 hit_addr = (bfd_byte *) (contents + off);
723 hit_addr -= (long) hit_addr & 0x3;
fc3ab699
L
724 t0 = bfd_getl64 (hit_addr);
725 t1 = bfd_getl64 (hit_addr + 8);
03609792 726
7e3102a7 727 /* Keep the instruction in slot 0. */
fc3ab699
L
728 i0 = (t0 >> 5) & 0x1ffffffffffLL;
729 /* Use nop.b for slot 1. */
730 i1 = 0x4000000000LL;
7e3102a7 731 /* For slot 2, turn brl into br by masking out bit 40. */
fc3ab699 732 i2 = (t1 >> 23) & 0x0ffffffffffLL;
7e3102a7 733
fc3ab699
L
734 /* Turn a MLX bundle into a MBB bundle with the same stop-bit
735 variety. */
736 if (t0 & 0x1)
737 template = 0x13;
738 else
739 template = 0x12;
740 t0 = (i1 << 46) | (i0 << 5) | template;
741 t1 = (i2 << 23) | (i1 >> 18);
7e3102a7 742
fc3ab699
L
743 bfd_putl64 (t0, hit_addr);
744 bfd_putl64 (t1, hit_addr + 8);
03609792 745}
fbbc3759
L
746
747/* Rename some of the generic section flags to better document how they
748 are used here. */
749#define skip_relax_pass_0 need_finalize_relax
750#define skip_relax_pass_1 has_gp_reloc
751
748abff6 752\f
2c4c2bc0 753/* These functions do relaxation for IA-64 ELF. */
748abff6 754
b34976b6 755static bfd_boolean
eae50df2
L
756elfNN_ia64_relax_section (bfd *abfd, asection *sec,
757 struct bfd_link_info *link_info,
758 bfd_boolean *again)
748abff6
RH
759{
760 struct one_fixup
761 {
762 struct one_fixup *next;
763 asection *tsec;
764 bfd_vma toff;
765 bfd_vma trampoff;
766 };
767
768 Elf_Internal_Shdr *symtab_hdr;
769 Elf_Internal_Rela *internal_relocs;
748abff6
RH
770 Elf_Internal_Rela *irel, *irelend;
771 bfd_byte *contents;
6cdc0ccc 772 Elf_Internal_Sym *isymbuf = NULL;
bbe66d08 773 struct elfNN_ia64_link_hash_table *ia64_info;
748abff6 774 struct one_fixup *fixups = NULL;
b34976b6
AM
775 bfd_boolean changed_contents = FALSE;
776 bfd_boolean changed_relocs = FALSE;
2c4c2bc0 777 bfd_boolean changed_got = FALSE;
fbbc3759
L
778 bfd_boolean skip_relax_pass_0 = TRUE;
779 bfd_boolean skip_relax_pass_1 = TRUE;
2c4c2bc0 780 bfd_vma gp = 0;
748abff6 781
46f5aac8
KH
782 /* Assume we're not going to change any sizes, and we'll only need
783 one pass. */
b34976b6 784 *again = FALSE;
748abff6 785
c8a1f254
NS
786 if (link_info->relocatable)
787 (*link_info->callbacks->einfo)
788 (_("%P%F: --relax and -r may not be used together\n"));
789
04b3329b 790 /* Don't even try to relax for non-ELF outputs. */
0eddce27 791 if (!is_elf_hash_table (link_info->hash))
04b3329b
L
792 return FALSE;
793
c7996ad6 794 /* Nothing to do if there are no relocations or there is no need for
fbbc3759 795 the current pass. */
748abff6 796 if ((sec->flags & SEC_RELOC) == 0
c7996ad6 797 || sec->reloc_count == 0
fbbc3759
L
798 || (link_info->relax_pass == 0 && sec->skip_relax_pass_0)
799 || (link_info->relax_pass == 1 && sec->skip_relax_pass_1))
b34976b6 800 return TRUE;
748abff6 801
748abff6
RH
802 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
803
804 /* Load the relocations for this section. */
45d6a902 805 internal_relocs = (_bfd_elf_link_read_relocs
748abff6
RH
806 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
807 link_info->keep_memory));
808 if (internal_relocs == NULL)
b34976b6 809 return FALSE;
748abff6 810
bbe66d08 811 ia64_info = elfNN_ia64_hash_table (link_info);
748abff6
RH
812 irelend = internal_relocs + sec->reloc_count;
813
748abff6 814 /* Get the section contents. */
748abff6
RH
815 if (elf_section_data (sec)->this_hdr.contents != NULL)
816 contents = elf_section_data (sec)->this_hdr.contents;
817 else
818 {
eea6121a 819 if (!bfd_malloc_and_get_section (abfd, sec, &contents))
748abff6
RH
820 goto error_return;
821 }
822
2c4c2bc0 823 for (irel = internal_relocs; irel < irelend; irel++)
748abff6 824 {
2f9bd3f6 825 unsigned long r_type = ELFNN_R_TYPE (irel->r_info);
748abff6 826 bfd_vma symaddr, reladdr, trampoff, toff, roff;
748abff6
RH
827 asection *tsec;
828 struct one_fixup *f;
dc810e39 829 bfd_size_type amt;
2c4c2bc0
RH
830 bfd_boolean is_branch;
831 struct elfNN_ia64_dyn_sym_info *dyn_i;
bf8b15af 832 char symtype;
748abff6 833
2c4c2bc0
RH
834 switch (r_type)
835 {
836 case R_IA64_PCREL21B:
837 case R_IA64_PCREL21BI:
838 case R_IA64_PCREL21M:
839 case R_IA64_PCREL21F:
fbbc3759
L
840 /* In pass 1, all br relaxations are done. We can skip it. */
841 if (link_info->relax_pass == 1)
c7996ad6 842 continue;
fbbc3759 843 skip_relax_pass_0 = FALSE;
2c4c2bc0
RH
844 is_branch = TRUE;
845 break;
846
03609792 847 case R_IA64_PCREL60B:
fbbc3759
L
848 /* We can't optimize brl to br in pass 0 since br relaxations
849 will increase the code size. Defer it to pass 1. */
850 if (link_info->relax_pass == 0)
03609792 851 {
fbbc3759 852 skip_relax_pass_1 = FALSE;
03609792
L
853 continue;
854 }
855 is_branch = TRUE;
856 break;
857
2c4c2bc0
RH
858 case R_IA64_LTOFF22X:
859 case R_IA64_LDXMOV:
fbbc3759
L
860 /* We can't relax ldx/mov in pass 0 since br relaxations will
861 increase the code size. Defer it to pass 1. */
862 if (link_info->relax_pass == 0)
c7996ad6 863 {
fbbc3759 864 skip_relax_pass_1 = FALSE;
c7996ad6
L
865 continue;
866 }
2c4c2bc0
RH
867 is_branch = FALSE;
868 break;
869
870 default:
871 continue;
872 }
748abff6
RH
873
874 /* Get the value of the symbol referred to by the reloc. */
bbe66d08 875 if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
748abff6
RH
876 {
877 /* A local symbol. */
6cdc0ccc
AM
878 Elf_Internal_Sym *isym;
879
880 /* Read this BFD's local symbols. */
881 if (isymbuf == NULL)
882 {
883 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
884 if (isymbuf == NULL)
885 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
886 symtab_hdr->sh_info, 0,
887 NULL, NULL, NULL);
888 if (isymbuf == 0)
889 goto error_return;
890 }
891
60d8b524 892 isym = isymbuf + ELFNN_R_SYM (irel->r_info);
6cdc0ccc 893 if (isym->st_shndx == SHN_UNDEF)
4cc11e76 894 continue; /* We can't do anything with undefined symbols. */
6cdc0ccc 895 else if (isym->st_shndx == SHN_ABS)
748abff6 896 tsec = bfd_abs_section_ptr;
6cdc0ccc 897 else if (isym->st_shndx == SHN_COMMON)
748abff6 898 tsec = bfd_com_section_ptr;
6cdc0ccc 899 else if (isym->st_shndx == SHN_IA_64_ANSI_COMMON)
d9cf1b54 900 tsec = bfd_com_section_ptr;
3e932841 901 else
6cdc0ccc 902 tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
748abff6 903
6cdc0ccc 904 toff = isym->st_value;
2c4c2bc0 905 dyn_i = get_dyn_sym_info (ia64_info, NULL, abfd, irel, FALSE);
bf8b15af 906 symtype = ELF_ST_TYPE (isym->st_info);
748abff6
RH
907 }
908 else
909 {
910 unsigned long indx;
911 struct elf_link_hash_entry *h;
748abff6 912
bbe66d08 913 indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
748abff6
RH
914 h = elf_sym_hashes (abfd)[indx];
915 BFD_ASSERT (h != NULL);
916
917 while (h->root.type == bfd_link_hash_indirect
918 || h->root.type == bfd_link_hash_warning)
919 h = (struct elf_link_hash_entry *) h->root.u.i.link;
920
b34976b6 921 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, FALSE);
748abff6
RH
922
923 /* For branches to dynamic symbols, we're interested instead
924 in a branch to the PLT entry. */
2c4c2bc0 925 if (is_branch && dyn_i && dyn_i->want_plt2)
748abff6 926 {
2f9bd3f6
RH
927 /* Internal branches shouldn't be sent to the PLT.
928 Leave this for now and we'll give an error later. */
929 if (r_type != R_IA64_PCREL21B)
930 continue;
931
cc3bd654 932 tsec = ia64_info->root.splt;
748abff6 933 toff = dyn_i->plt2_offset;
3fa1d917 934 BFD_ASSERT (irel->r_addend == 0);
748abff6 935 }
2c4c2bc0
RH
936
937 /* Can't do anything else with dynamic symbols. */
986a241f 938 else if (elfNN_ia64_dynamic_symbol_p (h, link_info, r_type))
2c4c2bc0
RH
939 continue;
940
748abff6
RH
941 else
942 {
4cc11e76 943 /* We can't do anything with undefined symbols. */
748abff6
RH
944 if (h->root.type == bfd_link_hash_undefined
945 || h->root.type == bfd_link_hash_undefweak)
946 continue;
947
948 tsec = h->root.u.def.section;
949 toff = h->root.u.def.value;
950 }
bf8b15af
L
951
952 symtype = h->type;
5dd23ec1 953 }
3fa1d917 954
9f2e92c5 955 if (tsec->sec_info_type == ELF_INFO_TYPE_MERGE)
bf8b15af
L
956 {
957 /* At this stage in linking, no SEC_MERGE symbol has been
958 adjusted, so all references to such symbols need to be
959 passed through _bfd_merged_section_offset. (Later, in
960 relocate_section, all SEC_MERGE symbols *except* for
961 section symbols have been adjusted.)
962
963 gas may reduce relocations against symbols in SEC_MERGE
964 sections to a relocation against the section symbol when
965 the original addend was zero. When the reloc is against
966 a section symbol we should include the addend in the
967 offset passed to _bfd_merged_section_offset, since the
968 location of interest is the original symbol. On the
969 other hand, an access to "sym+addend" where "sym" is not
970 a section symbol should not include the addend; Such an
971 access is presumed to be an offset from "sym"; The
972 location of interest is just "sym". */
973 if (symtype == STT_SECTION)
974 toff += irel->r_addend;
f12123c0 975
bf8b15af
L
976 toff = _bfd_merged_section_offset (abfd, &tsec,
977 elf_section_data (tsec)->sec_info,
978 toff);
979
980 if (symtype != STT_SECTION)
981 toff += irel->r_addend;
982 }
9f2e92c5
L
983 else
984 toff += irel->r_addend;
985
3fa1d917 986 symaddr = tsec->output_section->vma + tsec->output_offset + toff;
748abff6
RH
987
988 roff = irel->r_offset;
748abff6 989
2c4c2bc0
RH
990 if (is_branch)
991 {
de0d9f33
L
992 bfd_signed_vma offset;
993
2c4c2bc0
RH
994 reladdr = (sec->output_section->vma
995 + sec->output_offset
996 + roff) & (bfd_vma) -4;
748abff6 997
feddcd0d
L
998 /* The .plt section is aligned at 32byte and the .text section
999 is aligned at 64byte. The .text section is right after the
1000 .plt section. After the first relaxation pass, linker may
1001 increase the gap between the .plt and .text sections up
1002 to 32byte. We assume linker will always insert 32byte
1003 between the .plt and .text sections after the the first
1004 relaxation pass. */
cc3bd654 1005 if (tsec == ia64_info->root.splt)
feddcd0d
L
1006 offset = -0x1000000 + 32;
1007 else
1008 offset = -0x1000000;
1009
2c4c2bc0 1010 /* If the branch is in range, no need to do anything. */
feddcd0d 1011 if ((bfd_signed_vma) (symaddr - reladdr) >= offset
2c4c2bc0 1012 && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
03609792
L
1013 {
1014 /* If the 60-bit branch is in 21-bit range, optimize it. */
1015 if (r_type == R_IA64_PCREL60B)
1016 {
bbb268c3 1017 elfNN_ia64_relax_brl (contents, roff);
03609792
L
1018
1019 irel->r_info
7e3102a7 1020 = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
03609792
L
1021 R_IA64_PCREL21B);
1022
1023 /* If the original relocation offset points to slot
1024 1, change it to slot 2. */
1025 if ((irel->r_offset & 3) == 1)
1026 irel->r_offset += 1;
1027 }
1028
1029 continue;
1030 }
1031 else if (r_type == R_IA64_PCREL60B)
2c4c2bc0 1032 continue;
83b6bd86
L
1033 else if (elfNN_ia64_relax_br (contents, roff))
1034 {
1035 irel->r_info
1036 = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1037 R_IA64_PCREL60B);
1038
1039 /* Make the relocation offset point to slot 1. */
1040 irel->r_offset = (irel->r_offset & ~((bfd_vma) 0x3)) + 1;
1041 continue;
1042 }
748abff6 1043
e525914f
L
1044 /* We can't put a trampoline in a .init/.fini section. Issue
1045 an error. */
1046 if (strcmp (sec->output_section->name, ".init") == 0
1047 || strcmp (sec->output_section->name, ".fini") == 0)
1048 {
1049 (*_bfd_error_handler)
d003868e
AM
1050 (_("%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."),
1051 sec->owner, sec, (unsigned long) roff);
e525914f
L
1052 bfd_set_error (bfd_error_bad_value);
1053 goto error_return;
1054 }
1055
2c4c2bc0 1056 /* If the branch and target are in the same section, you've
c5509b92
L
1057 got one honking big section and we can't help you unless
1058 you are branching backwards. You'll get an error message
1059 later. */
1060 if (tsec == sec && toff > roff)
2c4c2bc0 1061 continue;
748abff6 1062
2c4c2bc0
RH
1063 /* Look for an existing fixup to this address. */
1064 for (f = fixups; f ; f = f->next)
1065 if (f->tsec == tsec && f->toff == toff)
1066 break;
748abff6 1067
2c4c2bc0 1068 if (f == NULL)
748abff6 1069 {
2c4c2bc0
RH
1070 /* Two alternatives: If it's a branch to a PLT entry, we can
1071 make a copy of the FULL_PLT entry. Otherwise, we'll have
1072 to use a `brl' insn to get where we're going. */
1073
1074 size_t size;
1075
cc3bd654 1076 if (tsec == ia64_info->root.splt)
2c4c2bc0
RH
1077 size = sizeof (plt_full_entry);
1078 else
3f7deb8a 1079 size = oor_branch_size;
748abff6 1080
2c4c2bc0 1081 /* Resize the current section to make room for the new branch. */
eea6121a 1082 trampoff = (sec->size + 15) & (bfd_vma) -16;
de0d9f33
L
1083
1084 /* If trampoline is out of range, there is nothing we
1085 can do. */
1086 offset = trampoff - (roff & (bfd_vma) -4);
1087 if (offset < -0x1000000 || offset > 0x0FFFFF0)
1088 continue;
1089
2c4c2bc0
RH
1090 amt = trampoff + size;
1091 contents = (bfd_byte *) bfd_realloc (contents, amt);
1092 if (contents == NULL)
1093 goto error_return;
eea6121a 1094 sec->size = amt;
748abff6 1095
cc3bd654 1096 if (tsec == ia64_info->root.splt)
2c4c2bc0
RH
1097 {
1098 memcpy (contents + trampoff, plt_full_entry, size);
748abff6 1099
2c4c2bc0
RH
1100 /* Hijack the old relocation for use as the PLTOFF reloc. */
1101 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1102 R_IA64_PLTOFF22);
1103 irel->r_offset = trampoff;
1104 }
1105 else
1106 {
3f7deb8a
L
1107 if (size == sizeof (oor_ip))
1108 {
1109 memcpy (contents + trampoff, oor_ip, size);
1110 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1111 R_IA64_PCREL64I);
1112 irel->r_addend -= 16;
1113 irel->r_offset = trampoff + 2;
1114 }
1115 else
1116 {
1117 memcpy (contents + trampoff, oor_brl, size);
1118 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1119 R_IA64_PCREL60B);
1120 irel->r_offset = trampoff + 2;
1121 }
1122
2c4c2bc0
RH
1123 }
1124
1125 /* Record the fixup so we don't do it again this section. */
1126 f = (struct one_fixup *)
1127 bfd_malloc ((bfd_size_type) sizeof (*f));
1128 f->next = fixups;
1129 f->tsec = tsec;
1130 f->toff = toff;
1131 f->trampoff = trampoff;
1132 fixups = f;
748abff6 1133 }
2c4c2bc0
RH
1134 else
1135 {
de0d9f33
L
1136 /* If trampoline is out of range, there is nothing we
1137 can do. */
1138 offset = f->trampoff - (roff & (bfd_vma) -4);
1139 if (offset < -0x1000000 || offset > 0x0FFFFF0)
1140 continue;
1141
2c4c2bc0
RH
1142 /* Nop out the reloc, since we're finalizing things here. */
1143 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
1144 }
1145
de0d9f33 1146 /* Fix up the existing branch to hit the trampoline. */
bbb268c3
JW
1147 if (elfNN_ia64_install_value (contents + roff, offset, r_type)
1148 != bfd_reloc_ok)
2c4c2bc0 1149 goto error_return;
748abff6 1150
2c4c2bc0
RH
1151 changed_contents = TRUE;
1152 changed_relocs = TRUE;
748abff6
RH
1153 }
1154 else
1155 {
2c4c2bc0
RH
1156 /* Fetch the gp. */
1157 if (gp == 0)
1158 {
1159 bfd *obfd = sec->output_section->owner;
1160 gp = _bfd_get_gp_value (obfd);
1161 if (gp == 0)
1162 {
1163 if (!elfNN_ia64_choose_gp (obfd, link_info))
1164 goto error_return;
1165 gp = _bfd_get_gp_value (obfd);
1166 }
1167 }
748abff6 1168
2c4c2bc0 1169 /* If the data is out of range, do nothing. */
484a4f9c
RH
1170 if ((bfd_signed_vma) (symaddr - gp) >= 0x200000
1171 ||(bfd_signed_vma) (symaddr - gp) < -0x200000)
2c4c2bc0 1172 continue;
748abff6 1173
2c4c2bc0
RH
1174 if (r_type == R_IA64_LTOFF22X)
1175 {
1176 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1177 R_IA64_GPREL22);
1178 changed_relocs = TRUE;
1179 if (dyn_i->want_gotx)
1180 {
1181 dyn_i->want_gotx = 0;
1182 changed_got |= !dyn_i->want_got;
1183 }
1184 }
1185 else
1186 {
bbb268c3 1187 elfNN_ia64_relax_ldxmov (contents, roff);
2c4c2bc0
RH
1188 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
1189 changed_contents = TRUE;
1190 changed_relocs = TRUE;
1191 }
1192 }
748abff6
RH
1193 }
1194
2c4c2bc0
RH
1195 /* ??? If we created fixups, this may push the code segment large
1196 enough that the data segment moves, which will change the GP.
1197 Reset the GP so that we re-calculate next round. We need to
1198 do this at the _beginning_ of the next round; now will not do. */
f12123c0 1199
748abff6
RH
1200 /* Clean up and go home. */
1201 while (fixups)
1202 {
1203 struct one_fixup *f = fixups;
1204 fixups = fixups->next;
1205 free (f);
1206 }
1207
6cdc0ccc
AM
1208 if (isymbuf != NULL
1209 && symtab_hdr->contents != (unsigned char *) isymbuf)
748abff6
RH
1210 {
1211 if (! link_info->keep_memory)
6cdc0ccc 1212 free (isymbuf);
748abff6
RH
1213 else
1214 {
6cdc0ccc
AM
1215 /* Cache the symbols for elf_link_input_bfd. */
1216 symtab_hdr->contents = (unsigned char *) isymbuf;
748abff6
RH
1217 }
1218 }
1219
6cdc0ccc
AM
1220 if (contents != NULL
1221 && elf_section_data (sec)->this_hdr.contents != contents)
748abff6 1222 {
6cdc0ccc
AM
1223 if (!changed_contents && !link_info->keep_memory)
1224 free (contents);
748abff6
RH
1225 else
1226 {
6cdc0ccc
AM
1227 /* Cache the section contents for elf_link_input_bfd. */
1228 elf_section_data (sec)->this_hdr.contents = contents;
748abff6
RH
1229 }
1230 }
1231
6cdc0ccc
AM
1232 if (elf_section_data (sec)->relocs != internal_relocs)
1233 {
1234 if (!changed_relocs)
1235 free (internal_relocs);
1236 else
1237 elf_section_data (sec)->relocs = internal_relocs;
1238 }
1239
2c4c2bc0
RH
1240 if (changed_got)
1241 {
1242 struct elfNN_ia64_allocate_data data;
1243 data.info = link_info;
1244 data.ofs = 0;
9d73f260 1245 ia64_info->self_dtpmod_offset = (bfd_vma) -1;
2c4c2bc0
RH
1246
1247 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
1248 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
1249 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
cc3bd654 1250 ia64_info->root.sgot->size = data.ofs;
2c4c2bc0 1251
90b263f3 1252 if (ia64_info->root.dynamic_sections_created
cc3bd654 1253 && ia64_info->root.srelgot != NULL)
4a78a1f4
AS
1254 {
1255 /* Resize .rela.got. */
cc3bd654 1256 ia64_info->root.srelgot->size = 0;
4a78a1f4
AS
1257 if (link_info->shared
1258 && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
cc3bd654 1259 ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
4a78a1f4
AS
1260 data.only_got = TRUE;
1261 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries,
1262 &data);
1263 }
2c4c2bc0
RH
1264 }
1265
fbbc3759
L
1266 if (link_info->relax_pass == 0)
1267 {
1268 /* Pass 0 is only needed to relax br. */
1269 sec->skip_relax_pass_0 = skip_relax_pass_0;
1270 sec->skip_relax_pass_1 = skip_relax_pass_1;
1271 }
c7996ad6 1272
748abff6 1273 *again = changed_contents || changed_relocs;
b34976b6 1274 return TRUE;
748abff6
RH
1275
1276 error_return:
6cdc0ccc
AM
1277 if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
1278 free (isymbuf);
1279 if (contents != NULL
1280 && elf_section_data (sec)->this_hdr.contents != contents)
1281 free (contents);
1282 if (internal_relocs != NULL
1283 && elf_section_data (sec)->relocs != internal_relocs)
1284 free (internal_relocs);
b34976b6 1285 return FALSE;
748abff6 1286}
fbbc3759
L
1287#undef skip_relax_pass_0
1288#undef skip_relax_pass_1
2c4c2bc0
RH
1289
1290static void
eae50df2 1291elfNN_ia64_relax_ldxmov (bfd_byte *contents, bfd_vma off)
2c4c2bc0
RH
1292{
1293 int shift, r1, r3;
1294 bfd_vma dword, insn;
1295
1296 switch ((int)off & 0x3)
1297 {
1298 case 0: shift = 5; break;
1299 case 1: shift = 14; off += 3; break;
1300 case 2: shift = 23; off += 6; break;
60d8b524 1301 default:
2c4c2bc0
RH
1302 abort ();
1303 }
1304
bbb268c3 1305 dword = bfd_getl64 (contents + off);
2c4c2bc0
RH
1306 insn = (dword >> shift) & 0x1ffffffffffLL;
1307
1308 r1 = (insn >> 6) & 127;
1309 r3 = (insn >> 20) & 127;
1310 if (r1 == r3)
1311 insn = 0x8000000; /* nop */
1312 else
1313 insn = (insn & 0x7f01fff) | 0x10800000000LL; /* (qp) mov r1 = r3 */
1314
1315 dword &= ~(0x1ffffffffffLL << shift);
1316 dword |= (insn << shift);
bbb268c3 1317 bfd_putl64 (dword, contents + off);
2c4c2bc0 1318}
800eeca4 1319\f
b34976b6 1320/* Return TRUE if NAME is an unwind table section name. */
81545d45 1321
b34976b6 1322static inline bfd_boolean
0112cd26 1323is_unwind_section_name (bfd *abfd, const char *name)
81545d45 1324{
d9cf1b54
AM
1325 if (elfNN_ia64_hpux_vec (abfd->xvec)
1326 && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
b34976b6 1327 return FALSE;
d9cf1b54 1328
0112cd26
NC
1329 return ((CONST_STRNEQ (name, ELF_STRING_ia64_unwind)
1330 && ! CONST_STRNEQ (name, ELF_STRING_ia64_unwind_info))
1331 || CONST_STRNEQ (name, ELF_STRING_ia64_unwind_once));
81545d45
RH
1332}
1333
800eeca4 1334/* Handle an IA-64 specific section when reading an object file. This
6dc132d9
L
1335 is called when bfd_section_from_shdr finds a section with an unknown
1336 type. */
800eeca4 1337
b34976b6 1338static bfd_boolean
6dc132d9
L
1339elfNN_ia64_section_from_shdr (bfd *abfd,
1340 Elf_Internal_Shdr *hdr,
1341 const char *name,
1342 int shindex)
800eeca4
JW
1343{
1344 asection *newsect;
1345
1346 /* There ought to be a place to keep ELF backend specific flags, but
1347 at the moment there isn't one. We just keep track of the
1348 sections by their name, instead. Fortunately, the ABI gives
1349 suggested names for all the MIPS specific sections, so we will
1350 probably get away with this. */
1351 switch (hdr->sh_type)
1352 {
1353 case SHT_IA_64_UNWIND:
d9cf1b54 1354 case SHT_IA_64_HP_OPT_ANOT:
800eeca4
JW
1355 break;
1356
1357 case SHT_IA_64_EXT:
1358 if (strcmp (name, ELF_STRING_ia64_archext) != 0)
b34976b6 1359 return FALSE;
800eeca4
JW
1360 break;
1361
1362 default:
b34976b6 1363 return FALSE;
800eeca4
JW
1364 }
1365
6dc132d9 1366 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
b34976b6 1367 return FALSE;
800eeca4
JW
1368 newsect = hdr->bfd_section;
1369
b34976b6 1370 return TRUE;
fa152c49
JW
1371}
1372
1373/* Convert IA-64 specific section flags to bfd internal section flags. */
1374
1375/* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1376 flag. */
1377
b34976b6 1378static bfd_boolean
eae50df2
L
1379elfNN_ia64_section_flags (flagword *flags,
1380 const Elf_Internal_Shdr *hdr)
fa152c49 1381{
800eeca4 1382 if (hdr->sh_flags & SHF_IA_64_SHORT)
fa152c49 1383 *flags |= SEC_SMALL_DATA;
800eeca4 1384
b34976b6 1385 return TRUE;
800eeca4
JW
1386}
1387
1388/* Set the correct type for an IA-64 ELF section. We do this by the
1389 section name, which is a hack, but ought to work. */
1390
b34976b6 1391static bfd_boolean
eae50df2
L
1392elfNN_ia64_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr,
1393 asection *sec)
800eeca4
JW
1394{
1395 register const char *name;
1396
1397 name = bfd_get_section_name (abfd, sec);
1398
d9cf1b54 1399 if (is_unwind_section_name (abfd, name))
81545d45
RH
1400 {
1401 /* We don't have the sections numbered at this point, so sh_info
1402 is set later, in elfNN_ia64_final_write_processing. */
1403 hdr->sh_type = SHT_IA_64_UNWIND;
1404 hdr->sh_flags |= SHF_LINK_ORDER;
1405 }
800eeca4
JW
1406 else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
1407 hdr->sh_type = SHT_IA_64_EXT;
d9cf1b54
AM
1408 else if (strcmp (name, ".HP.opt_annot") == 0)
1409 hdr->sh_type = SHT_IA_64_HP_OPT_ANOT;
800eeca4 1410 else if (strcmp (name, ".reloc") == 0)
5e8d7549
NC
1411 /* This is an ugly, but unfortunately necessary hack that is
1412 needed when producing EFI binaries on IA-64. It tells
1413 elf.c:elf_fake_sections() not to consider ".reloc" as a section
1414 containing ELF relocation info. We need this hack in order to
1415 be able to generate ELF binaries that can be translated into
1416 EFI applications (which are essentially COFF objects). Those
1417 files contain a COFF ".reloc" section inside an ELFNN object,
1418 which would normally cause BFD to segfault because it would
1419 attempt to interpret this section as containing relocation
1420 entries for section "oc". With this hack enabled, ".reloc"
1421 will be treated as a normal data section, which will avoid the
1422 segfault. However, you won't be able to create an ELFNN binary
1423 with a section named "oc" that needs relocations, but that's
1424 the kind of ugly side-effects you get when detecting section
1425 types based on their names... In practice, this limitation is
1426 unlikely to bite. */
800eeca4
JW
1427 hdr->sh_type = SHT_PROGBITS;
1428
1429 if (sec->flags & SEC_SMALL_DATA)
1430 hdr->sh_flags |= SHF_IA_64_SHORT;
1431
75eb734c
SE
1432 /* Some HP linkers look for the SHF_IA_64_HP_TLS flag instead of SHF_TLS. */
1433
1434 if (elfNN_ia64_hpux_vec (abfd->xvec) && (sec->flags & SHF_TLS))
1435 hdr->sh_flags |= SHF_IA_64_HP_TLS;
1436
b34976b6 1437 return TRUE;
800eeca4
JW
1438}
1439
81545d45
RH
1440/* The final processing done just before writing out an IA-64 ELF
1441 object file. */
1442
1443static void
eae50df2
L
1444elfNN_ia64_final_write_processing (bfd *abfd,
1445 bfd_boolean linker ATTRIBUTE_UNUSED)
81545d45
RH
1446{
1447 Elf_Internal_Shdr *hdr;
38ce5b11 1448 asection *s;
81545d45
RH
1449
1450 for (s = abfd->sections; s; s = s->next)
1451 {
1452 hdr = &elf_section_data (s)->this_hdr;
1453 switch (hdr->sh_type)
1454 {
1455 case SHT_IA_64_UNWIND:
38ce5b11
L
1456 /* The IA-64 processor-specific ABI requires setting sh_link
1457 to the unwind section, whereas HP-UX requires sh_info to
1458 do so. For maximum compatibility, we'll set both for
1459 now... */
1460 hdr->sh_info = hdr->sh_link;
81545d45
RH
1461 break;
1462 }
1463 }
9d46020e
AM
1464
1465 if (! elf_flags_init (abfd))
1466 {
1467 unsigned long flags = 0;
1468
1469 if (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
1470 flags |= EF_IA_64_BE;
1471 if (bfd_get_mach (abfd) == bfd_mach_ia64_elf64)
1472 flags |= EF_IA_64_ABI64;
1473
1474 elf_elfheader(abfd)->e_flags = flags;
b34976b6 1475 elf_flags_init (abfd) = TRUE;
9d46020e 1476 }
81545d45
RH
1477}
1478
800eeca4
JW
1479/* Hook called by the linker routine which adds symbols from an object
1480 file. We use it to put .comm items in .sbss, and not .bss. */
1481
b34976b6 1482static bfd_boolean
a30e5f5f
AM
1483elfNN_ia64_add_symbol_hook (bfd *abfd,
1484 struct bfd_link_info *info,
eae50df2 1485 Elf_Internal_Sym *sym,
a30e5f5f
AM
1486 const char **namep ATTRIBUTE_UNUSED,
1487 flagword *flagsp ATTRIBUTE_UNUSED,
1488 asection **secp,
1489 bfd_vma *valp)
800eeca4
JW
1490{
1491 if (sym->st_shndx == SHN_COMMON
1049f94e 1492 && !info->relocatable
c0846b23 1493 && sym->st_size <= elf_gp_size (abfd))
800eeca4
JW
1494 {
1495 /* Common symbols less than or equal to -G nn bytes are
1496 automatically put into .sbss. */
1497
1498 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1499
1500 if (scomm == NULL)
1501 {
3496cb2a
L
1502 scomm = bfd_make_section_with_flags (abfd, ".scommon",
1503 (SEC_ALLOC
1504 | SEC_IS_COMMON
1505 | SEC_LINKER_CREATED));
1506 if (scomm == NULL)
b34976b6 1507 return FALSE;
800eeca4
JW
1508 }
1509
1510 *secp = scomm;
1511 *valp = sym->st_size;
1512 }
1513
b34976b6 1514 return TRUE;
800eeca4
JW
1515}
1516
1517/* Return the number of additional phdrs we will need. */
1518
1519static int
a6b96beb
AM
1520elfNN_ia64_additional_program_headers (bfd *abfd,
1521 struct bfd_link_info *info ATTRIBUTE_UNUSED)
800eeca4
JW
1522{
1523 asection *s;
1524 int ret = 0;
1525
1526 /* See if we need a PT_IA_64_ARCHEXT segment. */
1527 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1528 if (s && (s->flags & SEC_LOAD))
1529 ++ret;
1530
81545d45
RH
1531 /* Count how many PT_IA_64_UNWIND segments we need. */
1532 for (s = abfd->sections; s; s = s->next)
d9cf1b54 1533 if (is_unwind_section_name (abfd, s->name) && (s->flags & SEC_LOAD))
81545d45 1534 ++ret;
800eeca4
JW
1535
1536 return ret;
1537}
1538
b34976b6 1539static bfd_boolean
8ded5a0f
AM
1540elfNN_ia64_modify_segment_map (bfd *abfd,
1541 struct bfd_link_info *info ATTRIBUTE_UNUSED)
800eeca4
JW
1542{
1543 struct elf_segment_map *m, **pm;
81545d45 1544 Elf_Internal_Shdr *hdr;
800eeca4
JW
1545 asection *s;
1546
1547 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1548 all PT_LOAD segments. */
1549 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1550 if (s && (s->flags & SEC_LOAD))
1551 {
1552 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1553 if (m->p_type == PT_IA_64_ARCHEXT)
1554 break;
1555 if (m == NULL)
1556 {
dc810e39
AM
1557 m = ((struct elf_segment_map *)
1558 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
800eeca4 1559 if (m == NULL)
b34976b6 1560 return FALSE;
800eeca4
JW
1561
1562 m->p_type = PT_IA_64_ARCHEXT;
1563 m->count = 1;
1564 m->sections[0] = s;
1565
1566 /* We want to put it after the PHDR and INTERP segments. */
1567 pm = &elf_tdata (abfd)->segment_map;
1568 while (*pm != NULL
1569 && ((*pm)->p_type == PT_PHDR
1570 || (*pm)->p_type == PT_INTERP))
1571 pm = &(*pm)->next;
1572
1573 m->next = *pm;
1574 *pm = m;
1575 }
1576 }
1577
81545d45
RH
1578 /* Install PT_IA_64_UNWIND segments, if needed. */
1579 for (s = abfd->sections; s; s = s->next)
800eeca4 1580 {
81545d45
RH
1581 hdr = &elf_section_data (s)->this_hdr;
1582 if (hdr->sh_type != SHT_IA_64_UNWIND)
1583 continue;
1584
1585 if (s && (s->flags & SEC_LOAD))
800eeca4 1586 {
81545d45 1587 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
d9cf1b54
AM
1588 if (m->p_type == PT_IA_64_UNWIND)
1589 {
40c97fc6
AM
1590 int i;
1591
d9cf1b54
AM
1592 /* Look through all sections in the unwind segment
1593 for a match since there may be multiple sections
1594 to a segment. */
40c97fc6
AM
1595 for (i = m->count - 1; i >= 0; --i)
1596 if (m->sections[i] == s)
1597 break;
d9cf1b54 1598
40c97fc6 1599 if (i >= 0)
d9cf1b54
AM
1600 break;
1601 }
81545d45 1602
800eeca4 1603 if (m == NULL)
81545d45 1604 {
dc810e39
AM
1605 m = ((struct elf_segment_map *)
1606 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
81545d45 1607 if (m == NULL)
b34976b6 1608 return FALSE;
800eeca4 1609
81545d45
RH
1610 m->p_type = PT_IA_64_UNWIND;
1611 m->count = 1;
1612 m->sections[0] = s;
1613 m->next = NULL;
800eeca4 1614
81545d45
RH
1615 /* We want to put it last. */
1616 pm = &elf_tdata (abfd)->segment_map;
1617 while (*pm != NULL)
1618 pm = &(*pm)->next;
1619 *pm = m;
1620 }
800eeca4
JW
1621 }
1622 }
1623
e36284ab
AM
1624 return TRUE;
1625}
1626
1627/* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1628 the input sections for each output section in the segment and testing
1629 for SHF_IA_64_NORECOV on each. */
1630
1631static bfd_boolean
1632elfNN_ia64_modify_program_headers (bfd *abfd,
1633 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1634{
1635 struct elf_obj_tdata *tdata = elf_tdata (abfd);
1636 struct elf_segment_map *m;
1637 Elf_Internal_Phdr *p;
1638
1639 for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++)
800eeca4
JW
1640 if (m->p_type == PT_LOAD)
1641 {
1642 int i;
1643 for (i = m->count - 1; i >= 0; --i)
1644 {
8423293d 1645 struct bfd_link_order *order = m->sections[i]->map_head.link_order;
e36284ab
AM
1646
1647 while (order != NULL)
800eeca4
JW
1648 {
1649 if (order->type == bfd_indirect_link_order)
1650 {
1651 asection *is = order->u.indirect.section;
1652 bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
1653 if (flags & SHF_IA_64_NORECOV)
1654 {
e36284ab 1655 p->p_flags |= PF_IA_64_NORECOV;
800eeca4
JW
1656 goto found;
1657 }
1658 }
1659 order = order->next;
1660 }
1661 }
1662 found:;
1663 }
1664
b34976b6 1665 return TRUE;
800eeca4
JW
1666}
1667
800eeca4
JW
1668/* According to the Tahoe assembler spec, all labels starting with a
1669 '.' are local. */
1670
b34976b6 1671static bfd_boolean
eae50df2
L
1672elfNN_ia64_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
1673 const char *name)
800eeca4
JW
1674{
1675 return name[0] == '.';
1676}
1677
1678/* Should we do dynamic things to this symbol? */
1679
b34976b6 1680static bfd_boolean
eae50df2
L
1681elfNN_ia64_dynamic_symbol_p (struct elf_link_hash_entry *h,
1682 struct bfd_link_info *info, int r_type)
800eeca4 1683{
986a241f
RH
1684 bfd_boolean ignore_protected
1685 = ((r_type & 0xf8) == 0x40 /* FPTR relocs */
1686 || (r_type & 0xf8) == 0x50); /* LTOFF_FPTR relocs */
800eeca4 1687
986a241f 1688 return _bfd_elf_dynamic_symbol_p (h, info, ignore_protected);
800eeca4
JW
1689}
1690\f
800eeca4 1691static struct bfd_hash_entry*
eae50df2
L
1692elfNN_ia64_new_elf_hash_entry (struct bfd_hash_entry *entry,
1693 struct bfd_hash_table *table,
1694 const char *string)
800eeca4 1695{
bbe66d08
JW
1696 struct elfNN_ia64_link_hash_entry *ret;
1697 ret = (struct elfNN_ia64_link_hash_entry *) entry;
800eeca4
JW
1698
1699 /* Allocate the structure if it has not already been allocated by a
1700 subclass. */
1701 if (!ret)
1702 ret = bfd_hash_allocate (table, sizeof (*ret));
1703
1704 if (!ret)
1705 return 0;
1706
800eeca4 1707 /* Call the allocation method of the superclass. */
bbe66d08 1708 ret = ((struct elfNN_ia64_link_hash_entry *)
800eeca4
JW
1709 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1710 table, string));
1711
4f40114d 1712 ret->info = NULL;
396a682d
L
1713 ret->count = 0;
1714 ret->sorted_count = 0;
1715 ret->size = 0;
800eeca4
JW
1716 return (struct bfd_hash_entry *) ret;
1717}
1718
1719static void
eae50df2
L
1720elfNN_ia64_hash_copy_indirect (struct bfd_link_info *info,
1721 struct elf_link_hash_entry *xdir,
1722 struct elf_link_hash_entry *xind)
800eeca4 1723{
bbe66d08 1724 struct elfNN_ia64_link_hash_entry *dir, *ind;
800eeca4 1725
57c7194e
AM
1726 dir = (struct elfNN_ia64_link_hash_entry *) xdir;
1727 ind = (struct elfNN_ia64_link_hash_entry *) xind;
800eeca4 1728
3e932841 1729 /* Copy down any references that we may have already seen to the
800eeca4
JW
1730 symbol which just became indirect. */
1731
f5385ebf
AM
1732 dir->root.ref_dynamic |= ind->root.ref_dynamic;
1733 dir->root.ref_regular |= ind->root.ref_regular;
1734 dir->root.ref_regular_nonweak |= ind->root.ref_regular_nonweak;
1735 dir->root.needs_plt |= ind->root.needs_plt;
800eeca4 1736
1e370bd2 1737 if (ind->root.root.type != bfd_link_hash_indirect)
0a991dfe
AM
1738 return;
1739
800eeca4
JW
1740 /* Copy over the got and plt data. This would have been done
1741 by check_relocs. */
1742
fcfa13d2 1743 if (ind->info != NULL)
800eeca4 1744 {
bbe66d08 1745 struct elfNN_ia64_dyn_sym_info *dyn_i;
396a682d
L
1746 unsigned int count;
1747
1748 if (dir->info)
1749 free (dir->info);
1750
1751 dir->info = ind->info;
1752 dir->count = ind->count;
1753 dir->sorted_count = ind->sorted_count;
1754 dir->size = ind->size;
800eeca4 1755
800eeca4 1756 ind->info = NULL;
396a682d
L
1757 ind->count = 0;
1758 ind->sorted_count = 0;
1759 ind->size = 0;
800eeca4
JW
1760
1761 /* Fix up the dyn_sym_info pointers to the global symbol. */
396a682d
L
1762 for (count = dir->count, dyn_i = dir->info;
1763 count != 0;
1764 count--, dyn_i++)
800eeca4
JW
1765 dyn_i->h = &dir->root;
1766 }
800eeca4
JW
1767
1768 /* Copy over the dynindx. */
1769
fcfa13d2 1770 if (ind->root.dynindx != -1)
800eeca4 1771 {
fcfa13d2
AM
1772 if (dir->root.dynindx != -1)
1773 _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
1774 dir->root.dynstr_index);
800eeca4
JW
1775 dir->root.dynindx = ind->root.dynindx;
1776 dir->root.dynstr_index = ind->root.dynstr_index;
1777 ind->root.dynindx = -1;
1778 ind->root.dynstr_index = 0;
1779 }
800eeca4
JW
1780}
1781
1782static void
eae50df2
L
1783elfNN_ia64_hash_hide_symbol (struct bfd_link_info *info,
1784 struct elf_link_hash_entry *xh,
1785 bfd_boolean force_local)
800eeca4 1786{
bbe66d08
JW
1787 struct elfNN_ia64_link_hash_entry *h;
1788 struct elfNN_ia64_dyn_sym_info *dyn_i;
396a682d 1789 unsigned int count;
800eeca4 1790
bbe66d08 1791 h = (struct elfNN_ia64_link_hash_entry *)xh;
800eeca4 1792
e5094212 1793 _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
800eeca4 1794
396a682d
L
1795 for (count = h->count, dyn_i = h->info;
1796 count != 0;
1797 count--, dyn_i++)
6a32c710
L
1798 {
1799 dyn_i->want_plt2 = 0;
1800 dyn_i->want_plt = 0;
1801 }
800eeca4
JW
1802}
1803
0aa92b58
JJ
1804/* Compute a hash of a local hash entry. */
1805
1806static hashval_t
eae50df2 1807elfNN_ia64_local_htab_hash (const void *ptr)
0aa92b58
JJ
1808{
1809 struct elfNN_ia64_local_hash_entry *entry
1810 = (struct elfNN_ia64_local_hash_entry *) ptr;
1811
d2149d72 1812 return ELF_LOCAL_SYMBOL_HASH (entry->id, entry->r_sym);
0aa92b58
JJ
1813}
1814
1815/* Compare local hash entries. */
1816
1817static int
eae50df2 1818elfNN_ia64_local_htab_eq (const void *ptr1, const void *ptr2)
0aa92b58
JJ
1819{
1820 struct elfNN_ia64_local_hash_entry *entry1
1821 = (struct elfNN_ia64_local_hash_entry *) ptr1;
1822 struct elfNN_ia64_local_hash_entry *entry2
1823 = (struct elfNN_ia64_local_hash_entry *) ptr2;
1824
1825 return entry1->id == entry2->id && entry1->r_sym == entry2->r_sym;
1826}
1827
800eeca4
JW
1828/* Create the derived linker hash table. The IA-64 ELF port uses this
1829 derived hash table to keep information specific to the IA-64 ElF
1830 linker (without using static variables). */
1831
1832static struct bfd_link_hash_table*
eae50df2 1833elfNN_ia64_hash_table_create (bfd *abfd)
800eeca4 1834{
bbe66d08 1835 struct elfNN_ia64_link_hash_table *ret;
800eeca4 1836
6e84a906 1837 ret = bfd_zmalloc ((bfd_size_type) sizeof (*ret));
800eeca4
JW
1838 if (!ret)
1839 return 0;
6e84a906 1840
800eeca4 1841 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
66eb6687
AM
1842 elfNN_ia64_new_elf_hash_entry,
1843 sizeof (struct elfNN_ia64_link_hash_entry)))
800eeca4 1844 {
6e84a906 1845 free (ret);
800eeca4
JW
1846 return 0;
1847 }
1848
0aa92b58
JJ
1849 ret->loc_hash_table = htab_try_create (1024, elfNN_ia64_local_htab_hash,
1850 elfNN_ia64_local_htab_eq, NULL);
1851 ret->loc_hash_memory = objalloc_create ();
1852 if (!ret->loc_hash_table || !ret->loc_hash_memory)
6e84a906
DJ
1853 {
1854 free (ret);
1855 return 0;
1856 }
1857
800eeca4
JW
1858 return &ret->root.root;
1859}
1860
396a682d
L
1861/* Free the global elfNN_ia64_dyn_sym_info array. */
1862
1863static bfd_boolean
1864elfNN_ia64_global_dyn_info_free (void **xentry,
1865 PTR unused ATTRIBUTE_UNUSED)
1866{
1867 struct elfNN_ia64_link_hash_entry *entry
1868 = (struct elfNN_ia64_link_hash_entry *) xentry;
1869
1870 if (entry->root.root.type == bfd_link_hash_warning)
1871 entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
1872
1873 if (entry->info)
1874 {
1875 free (entry->info);
1876 entry->info = NULL;
1877 entry->count = 0;
1878 entry->sorted_count = 0;
1879 entry->size = 0;
1880 }
1881
1882 return TRUE;
1883}
1884
1885/* Free the local elfNN_ia64_dyn_sym_info array. */
1886
1887static bfd_boolean
1888elfNN_ia64_local_dyn_info_free (void **slot,
1889 PTR unused ATTRIBUTE_UNUSED)
1890{
1891 struct elfNN_ia64_local_hash_entry *entry
1892 = (struct elfNN_ia64_local_hash_entry *) *slot;
1893
1894 if (entry->info)
1895 {
1896 free (entry->info);
1897 entry->info = NULL;
1898 entry->count = 0;
1899 entry->sorted_count = 0;
1900 entry->size = 0;
1901 }
1902
1903 return TRUE;
1904}
1905
0aa92b58 1906/* Destroy IA-64 linker hash table. */
800eeca4 1907
0aa92b58 1908static void
eae50df2 1909elfNN_ia64_hash_table_free (struct bfd_link_hash_table *hash)
800eeca4 1910{
0aa92b58
JJ
1911 struct elfNN_ia64_link_hash_table *ia64_info
1912 = (struct elfNN_ia64_link_hash_table *) hash;
1913 if (ia64_info->loc_hash_table)
396a682d
L
1914 {
1915 htab_traverse (ia64_info->loc_hash_table,
1916 elfNN_ia64_local_dyn_info_free, NULL);
1917 htab_delete (ia64_info->loc_hash_table);
1918 }
0aa92b58
JJ
1919 if (ia64_info->loc_hash_memory)
1920 objalloc_free ((struct objalloc *) ia64_info->loc_hash_memory);
396a682d
L
1921 elf_link_hash_traverse (&ia64_info->root,
1922 elfNN_ia64_global_dyn_info_free, NULL);
0aa92b58 1923 _bfd_generic_link_hash_table_free (hash);
800eeca4
JW
1924}
1925
1926/* Traverse both local and global hash tables. */
1927
bbe66d08 1928struct elfNN_ia64_dyn_sym_traverse_data
800eeca4 1929{
eae50df2 1930 bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR);
800eeca4
JW
1931 PTR data;
1932};
1933
b34976b6 1934static bfd_boolean
eae50df2
L
1935elfNN_ia64_global_dyn_sym_thunk (struct bfd_hash_entry *xentry,
1936 PTR xdata)
800eeca4 1937{
bbe66d08
JW
1938 struct elfNN_ia64_link_hash_entry *entry
1939 = (struct elfNN_ia64_link_hash_entry *) xentry;
1940 struct elfNN_ia64_dyn_sym_traverse_data *data
1941 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1942 struct elfNN_ia64_dyn_sym_info *dyn_i;
396a682d 1943 unsigned int count;
800eeca4 1944
e92d460e
AM
1945 if (entry->root.root.type == bfd_link_hash_warning)
1946 entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
1947
396a682d
L
1948 for (count = entry->count, dyn_i = entry->info;
1949 count != 0;
1950 count--, dyn_i++)
800eeca4 1951 if (! (*data->func) (dyn_i, data->data))
b34976b6
AM
1952 return FALSE;
1953 return TRUE;
800eeca4
JW
1954}
1955
b34976b6 1956static bfd_boolean
eae50df2 1957elfNN_ia64_local_dyn_sym_thunk (void **slot, PTR xdata)
800eeca4 1958{
bbe66d08 1959 struct elfNN_ia64_local_hash_entry *entry
0aa92b58 1960 = (struct elfNN_ia64_local_hash_entry *) *slot;
bbe66d08
JW
1961 struct elfNN_ia64_dyn_sym_traverse_data *data
1962 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1963 struct elfNN_ia64_dyn_sym_info *dyn_i;
396a682d 1964 unsigned int count;
800eeca4 1965
396a682d
L
1966 for (count = entry->count, dyn_i = entry->info;
1967 count != 0;
1968 count--, dyn_i++)
800eeca4 1969 if (! (*data->func) (dyn_i, data->data))
396a682d
L
1970 return FALSE;
1971 return TRUE;
800eeca4
JW
1972}
1973
1974static void
eae50df2
L
1975elfNN_ia64_dyn_sym_traverse (struct elfNN_ia64_link_hash_table *ia64_info,
1976 bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
1977 PTR data)
800eeca4 1978{
bbe66d08 1979 struct elfNN_ia64_dyn_sym_traverse_data xdata;
800eeca4
JW
1980
1981 xdata.func = func;
1982 xdata.data = data;
1983
1984 elf_link_hash_traverse (&ia64_info->root,
bbe66d08 1985 elfNN_ia64_global_dyn_sym_thunk, &xdata);
0aa92b58
JJ
1986 htab_traverse (ia64_info->loc_hash_table,
1987 elfNN_ia64_local_dyn_sym_thunk, &xdata);
800eeca4
JW
1988}
1989\f
b34976b6 1990static bfd_boolean
eae50df2
L
1991elfNN_ia64_create_dynamic_sections (bfd *abfd,
1992 struct bfd_link_info *info)
800eeca4 1993{
bbe66d08 1994 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
1995 asection *s;
1996
1997 if (! _bfd_elf_create_dynamic_sections (abfd, info))
b34976b6 1998 return FALSE;
800eeca4 1999
bbe66d08 2000 ia64_info = elfNN_ia64_hash_table (info);
800eeca4 2001
800eeca4 2002 {
cc3bd654
L
2003 flagword flags = bfd_get_section_flags (abfd, ia64_info->root.sgot);
2004 bfd_set_section_flags (abfd, ia64_info->root.sgot,
2005 SEC_SMALL_DATA | flags);
69bbc4c0 2006 /* The .got section is always aligned at 8 bytes. */
cc3bd654 2007 bfd_set_section_alignment (abfd, ia64_info->root.sgot, 3);
800eeca4
JW
2008 }
2009
2010 if (!get_pltoff (abfd, info, ia64_info))
b34976b6 2011 return FALSE;
800eeca4 2012
3496cb2a
L
2013 s = bfd_make_section_with_flags (abfd, ".rela.IA_64.pltoff",
2014 (SEC_ALLOC | SEC_LOAD
2015 | SEC_HAS_CONTENTS
2016 | SEC_IN_MEMORY
2017 | SEC_LINKER_CREATED
2018 | SEC_READONLY));
800eeca4 2019 if (s == NULL
5a260b66 2020 || !bfd_set_section_alignment (abfd, s, LOG_SECTION_ALIGN))
b34976b6 2021 return FALSE;
800eeca4
JW
2022 ia64_info->rel_pltoff_sec = s;
2023
b34976b6 2024 return TRUE;
800eeca4
JW
2025}
2026
f7460f5f
JJ
2027/* Find and/or create a hash entry for local symbol. */
2028static struct elfNN_ia64_local_hash_entry *
eae50df2
L
2029get_local_sym_hash (struct elfNN_ia64_link_hash_table *ia64_info,
2030 bfd *abfd, const Elf_Internal_Rela *rel,
2031 bfd_boolean create)
f7460f5f 2032{
0aa92b58 2033 struct elfNN_ia64_local_hash_entry e, *ret;
d48770d4 2034 asection *sec = abfd->sections;
d2149d72
L
2035 hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
2036 ELFNN_R_SYM (rel->r_info));
0aa92b58 2037 void **slot;
d48770d4 2038
0aa92b58
JJ
2039 e.id = sec->id;
2040 e.r_sym = ELFNN_R_SYM (rel->r_info);
2041 slot = htab_find_slot_with_hash (ia64_info->loc_hash_table, &e, h,
2042 create ? INSERT : NO_INSERT);
f7460f5f 2043
0aa92b58
JJ
2044 if (!slot)
2045 return NULL;
f7460f5f 2046
0aa92b58
JJ
2047 if (*slot)
2048 return (struct elfNN_ia64_local_hash_entry *) *slot;
f7460f5f 2049
0aa92b58
JJ
2050 ret = (struct elfNN_ia64_local_hash_entry *)
2051 objalloc_alloc ((struct objalloc *) ia64_info->loc_hash_memory,
2052 sizeof (struct elfNN_ia64_local_hash_entry));
2053 if (ret)
2054 {
2055 memset (ret, 0, sizeof (*ret));
2056 ret->id = sec->id;
2057 ret->r_sym = ELFNN_R_SYM (rel->r_info);
2058 *slot = ret;
2059 }
fcf12726 2060 return ret;
f7460f5f
JJ
2061}
2062
396a682d
L
2063/* Used to sort elfNN_ia64_dyn_sym_info array. */
2064
2065static int
2066addend_compare (const void *xp, const void *yp)
2067{
2068 const struct elfNN_ia64_dyn_sym_info *x
2069 = (const struct elfNN_ia64_dyn_sym_info *) xp;
2070 const struct elfNN_ia64_dyn_sym_info *y
2071 = (const struct elfNN_ia64_dyn_sym_info *) yp;
2072
c26620e3 2073 return x->addend < y->addend ? -1 : x->addend > y->addend ? 1 : 0;
396a682d
L
2074}
2075
2076/* Sort elfNN_ia64_dyn_sym_info array and remove duplicates. */
2077
2078static unsigned int
2079sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info *info,
2080 unsigned int count)
2081{
293a0124
L
2082 bfd_vma curr, prev, got_offset;
2083 unsigned int i, kept, dup, diff, dest, src, len;
396a682d
L
2084
2085 qsort (info, count, sizeof (*info), addend_compare);
2086
2087 /* Find the first duplicate. */
2088 prev = info [0].addend;
293a0124 2089 got_offset = info [0].got_offset;
396a682d
L
2090 for (i = 1; i < count; i++)
2091 {
2092 curr = info [i].addend;
2093 if (curr == prev)
293a0124
L
2094 {
2095 /* For duplicates, make sure that GOT_OFFSET is valid. */
2096 if (got_offset == (bfd_vma) -1)
2097 got_offset = info [i].got_offset;
2098 break;
2099 }
2100 got_offset = info [i].got_offset;
396a682d
L
2101 prev = curr;
2102 }
2103
293a0124
L
2104 /* We may move a block of elements to here. */
2105 dest = i++;
2106
396a682d
L
2107 /* Remove duplicates. */
2108 if (i < count)
2109 {
396a682d
L
2110 while (i < count)
2111 {
293a0124
L
2112 /* For duplicates, make sure that the kept one has a valid
2113 got_offset. */
2114 kept = dest - 1;
2115 if (got_offset != (bfd_vma) -1)
2116 info [kept].got_offset = got_offset;
2117
396a682d 2118 curr = info [i].addend;
293a0124 2119 got_offset = info [i].got_offset;
396a682d
L
2120
2121 /* Move a block of elements whose first one is different from
2122 the previous. */
2123 if (curr == prev)
2124 {
2125 for (src = i + 1; src < count; src++)
293a0124
L
2126 {
2127 if (info [src].addend != curr)
2128 break;
2129 /* For duplicates, make sure that GOT_OFFSET is
2130 valid. */
2131 if (got_offset == (bfd_vma) -1)
2132 got_offset = info [src].got_offset;
2133 }
2134
2135 /* Make sure that the kept one has a valid got_offset. */
2136 if (got_offset != (bfd_vma) -1)
2137 info [kept].got_offset = got_offset;
396a682d
L
2138 }
2139 else
2140 src = i;
2141
2142 if (src >= count)
2143 break;
2144
293a0124 2145 /* Find the next duplicate. SRC will be kept. */
396a682d 2146 prev = info [src].addend;
293a0124 2147 got_offset = info [src].got_offset;
396a682d
L
2148 for (dup = src + 1; dup < count; dup++)
2149 {
2150 curr = info [dup].addend;
2151 if (curr == prev)
293a0124
L
2152 {
2153 /* Make sure that got_offset is valid. */
2154 if (got_offset == (bfd_vma) -1)
2155 got_offset = info [dup].got_offset;
2156
2157 /* For duplicates, make sure that the kept one has
2158 a valid got_offset. */
2159 if (got_offset != (bfd_vma) -1)
2160 info [dup - 1].got_offset = got_offset;
2161 break;
2162 }
2163 got_offset = info [dup].got_offset;
396a682d
L
2164 prev = curr;
2165 }
2166
2167 /* How much to move. */
2168 len = dup - src;
2169 i = dup + 1;
2170
2171 if (len == 1 && dup < count)
2172 {
2173 /* If we only move 1 element, we combine it with the next
293a0124
L
2174 one. There must be at least a duplicate. Find the
2175 next different one. */
396a682d 2176 for (diff = dup + 1, src++; diff < count; diff++, src++)
293a0124
L
2177 {
2178 if (info [diff].addend != curr)
2179 break;
2180 /* Make sure that got_offset is valid. */
2181 if (got_offset == (bfd_vma) -1)
2182 got_offset = info [diff].got_offset;
2183 }
2184
2185 /* Makre sure that the last duplicated one has an valid
2186 offset. */
2187 BFD_ASSERT (curr == prev);
2188 if (got_offset != (bfd_vma) -1)
2189 info [diff - 1].got_offset = got_offset;
396a682d
L
2190
2191 if (diff < count)
2192 {
293a0124
L
2193 /* Find the next duplicate. Track the current valid
2194 offset. */
396a682d 2195 prev = info [diff].addend;
293a0124 2196 got_offset = info [diff].got_offset;
396a682d
L
2197 for (dup = diff + 1; dup < count; dup++)
2198 {
2199 curr = info [dup].addend;
2200 if (curr == prev)
293a0124
L
2201 {
2202 /* For duplicates, make sure that GOT_OFFSET
2203 is valid. */
2204 if (got_offset == (bfd_vma) -1)
2205 got_offset = info [dup].got_offset;
2206 break;
2207 }
2208 got_offset = info [dup].got_offset;
396a682d
L
2209 prev = curr;
2210 diff++;
2211 }
2212
2213 len = diff - src + 1;
2214 i = diff + 1;
2215 }
2216 }
2217
2218 memmove (&info [dest], &info [src], len * sizeof (*info));
2219
2220 dest += len;
2221 }
2222
2223 count = dest;
2224 }
293a0124
L
2225 else
2226 {
2227 /* When we get here, either there is no duplicate at all or
2228 the only duplicate is the last element. */
2229 if (dest < count)
2230 {
2231 /* If the last element is a duplicate, make sure that the
2232 kept one has a valid got_offset. We also update count. */
2233 if (got_offset != (bfd_vma) -1)
2234 info [dest - 1].got_offset = got_offset;
2235 count = dest;
2236 }
2237 }
396a682d
L
2238
2239 return count;
2240}
2241
800eeca4 2242/* Find and/or create a descriptor for dynamic symbol info. This will
396a682d
L
2243 vary based on global or local symbol, and the addend to the reloc.
2244
2245 We don't sort when inserting. Also, we sort and eliminate
2246 duplicates if there is an unsorted section. Typically, this will
2247 only happen once, because we do all insertions before lookups. We
2248 then use bsearch to do a lookup. This also allows lookups to be
2249 fast. So we have fast insertion (O(log N) due to duplicate check),
2250 fast lookup (O(log N)) and one sort (O(N log N) expected time).
2251 Previously, all lookups were O(N) because of the use of the linked
2252 list and also all insertions were O(N) because of the check for
2253 duplicates. There are some complications here because the array
2254 size grows occasionally, which may add an O(N) factor, but this
2255 should be rare. Also, we free the excess array allocation, which
2256 requires a copy which is O(N), but this only happens once. */
800eeca4 2257
bbe66d08 2258static struct elfNN_ia64_dyn_sym_info *
eae50df2
L
2259get_dyn_sym_info (struct elfNN_ia64_link_hash_table *ia64_info,
2260 struct elf_link_hash_entry *h, bfd *abfd,
2261 const Elf_Internal_Rela *rel, bfd_boolean create)
800eeca4 2262{
396a682d
L
2263 struct elfNN_ia64_dyn_sym_info **info_p, *info, *dyn_i, key;
2264 unsigned int *count_p, *sorted_count_p, *size_p;
2265 unsigned int count, sorted_count, size;
800eeca4 2266 bfd_vma addend = rel ? rel->r_addend : 0;
396a682d 2267 bfd_size_type amt;
3e932841 2268
800eeca4 2269 if (h)
396a682d
L
2270 {
2271 struct elfNN_ia64_link_hash_entry *global_h;
2272
2273 global_h = (struct elfNN_ia64_link_hash_entry *) h;
2274 info_p = &global_h->info;
2275 count_p = &global_h->count;
2276 sorted_count_p = &global_h->sorted_count;
2277 size_p = &global_h->size;
2278 }
800eeca4
JW
2279 else
2280 {
bbe66d08 2281 struct elfNN_ia64_local_hash_entry *loc_h;
800eeca4 2282
f7460f5f 2283 loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
f86b235a
RH
2284 if (!loc_h)
2285 {
2286 BFD_ASSERT (!create);
2287 return NULL;
2288 }
800eeca4 2289
396a682d
L
2290 info_p = &loc_h->info;
2291 count_p = &loc_h->count;
2292 sorted_count_p = &loc_h->sorted_count;
2293 size_p = &loc_h->size;
3e932841 2294 }
800eeca4 2295
396a682d
L
2296 count = *count_p;
2297 sorted_count = *sorted_count_p;
2298 size = *size_p;
2299 info = *info_p;
2300 if (create)
800eeca4 2301 {
396a682d
L
2302 /* When we create the array, we don't check for duplicates,
2303 except in the previously sorted section if one exists, and
2304 against the last inserted entry. This allows insertions to
2305 be fast. */
2306 if (info)
2307 {
2308 if (sorted_count)
2309 {
2310 /* Try bsearch first on the sorted section. */
2311 key.addend = addend;
2312 dyn_i = bsearch (&key, info, sorted_count,
2313 sizeof (*info), addend_compare);
2314
2315 if (dyn_i)
2316 {
2317 return dyn_i;
2318 }
2319 }
2320
2321 /* Do a quick check for the last inserted entry. */
2322 dyn_i = info + count - 1;
2323 if (dyn_i->addend == addend)
2324 {
2325 return dyn_i;
2326 }
2327 }
2328
2329 if (size == 0)
2330 {
2331 /* It is the very first element. We create the array of size
2332 1. */
2333 size = 1;
2334 amt = size * sizeof (*info);
2335 info = bfd_malloc (amt);
2336 }
2337 else if (size <= count)
2338 {
2339 /* We double the array size every time when we reach the
2340 size limit. */
2341 size += size;
2342 amt = size * sizeof (*info);
2343 info = bfd_realloc (info, amt);
2344 }
2345 else
2346 goto has_space;
2347
2348 if (info == NULL)
2349 return NULL;
2350 *size_p = size;
2351 *info_p = info;
2352
2353has_space:
2354 /* Append the new one to the array. */
2355 dyn_i = info + count;
2356 memset (dyn_i, 0, sizeof (*dyn_i));
293a0124 2357 dyn_i->got_offset = (bfd_vma) -1;
800eeca4 2358 dyn_i->addend = addend;
9a2e389a 2359
396a682d
L
2360 /* We increment count only since the new ones are unsorted and
2361 may have duplicate. */
2362 (*count_p)++;
2363 }
2364 else
2365 {
2366 /* It is a lookup without insertion. Sort array if part of the
2367 array isn't sorted. */
2368 if (count != sorted_count)
2369 {
2370 count = sort_dyn_sym_info (info, count);
2371 *count_p = count;
2372 *sorted_count_p = count;
2373 }
2374
2375 /* Free unused memory. */
2376 if (size != count)
2377 {
2378 amt = count * sizeof (*info);
2379 info = bfd_malloc (amt);
2380 if (info != NULL)
2381 {
2382 memcpy (info, *info_p, amt);
2383 free (*info_p);
2384 *size_p = count;
2385 *info_p = info;
2386 }
2387 }
2388
2389 key.addend = addend;
2390 dyn_i = bsearch (&key, info, count,
2391 sizeof (*info), addend_compare);
800eeca4
JW
2392 }
2393
2394 return dyn_i;
2395}
2396
2397static asection *
eae50df2
L
2398get_got (bfd *abfd, struct bfd_link_info *info,
2399 struct elfNN_ia64_link_hash_table *ia64_info)
800eeca4 2400{
64bf6ae6 2401 asection *got;
800eeca4
JW
2402 bfd *dynobj;
2403
cc3bd654 2404 got = ia64_info->root.sgot;
800eeca4
JW
2405 if (!got)
2406 {
2407 flagword flags;
2408
2409 dynobj = ia64_info->root.dynobj;
2410 if (!dynobj)
2411 ia64_info->root.dynobj = dynobj = abfd;
2412 if (!_bfd_elf_create_got_section (dynobj, info))
2413 return 0;
2414
cc3bd654 2415 got = ia64_info->root.sgot;
800eeca4 2416
8651fcf9
L
2417 /* The .got section is always aligned at 8 bytes. */
2418 if (!bfd_set_section_alignment (abfd, got, 3))
2419 return 0;
2420
800eeca4
JW
2421 flags = bfd_get_section_flags (abfd, got);
2422 bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
2423 }
2424
2425 return got;
2426}
2427
2428/* Create function descriptor section (.opd). This section is called .opd
4cc11e76 2429 because it contains "official procedure descriptors". The "official"
800eeca4
JW
2430 refers to the fact that these descriptors are used when taking the address
2431 of a procedure, thus ensuring a unique address for each procedure. */
2432
2433static asection *
eae50df2
L
2434get_fptr (bfd *abfd, struct bfd_link_info *info,
2435 struct elfNN_ia64_link_hash_table *ia64_info)
800eeca4
JW
2436{
2437 asection *fptr;
2438 bfd *dynobj;
2439
2440 fptr = ia64_info->fptr_sec;
2441 if (!fptr)
2442 {
2443 dynobj = ia64_info->root.dynobj;
2444 if (!dynobj)
2445 ia64_info->root.dynobj = dynobj = abfd;
2446
3496cb2a
L
2447 fptr = bfd_make_section_with_flags (dynobj, ".opd",
2448 (SEC_ALLOC
2449 | SEC_LOAD
2450 | SEC_HAS_CONTENTS
2451 | SEC_IN_MEMORY
2452 | (info->pie ? 0 : SEC_READONLY)
2453 | SEC_LINKER_CREATED));
800eeca4 2454 if (!fptr
800eeca4
JW
2455 || !bfd_set_section_alignment (abfd, fptr, 4))
2456 {
2457 BFD_ASSERT (0);
2458 return NULL;
2459 }
2460
2461 ia64_info->fptr_sec = fptr;
9203ba99
JJ
2462
2463 if (info->pie)
2464 {
2465 asection *fptr_rel;
3496cb2a
L
2466 fptr_rel = bfd_make_section_with_flags (dynobj, ".rela.opd",
2467 (SEC_ALLOC | SEC_LOAD
2468 | SEC_HAS_CONTENTS
2469 | SEC_IN_MEMORY
2470 | SEC_LINKER_CREATED
2471 | SEC_READONLY));
9203ba99 2472 if (fptr_rel == NULL
5a260b66
L
2473 || !bfd_set_section_alignment (abfd, fptr_rel,
2474 LOG_SECTION_ALIGN))
9203ba99
JJ
2475 {
2476 BFD_ASSERT (0);
2477 return NULL;
2478 }
2479
2480 ia64_info->rel_fptr_sec = fptr_rel;
2481 }
800eeca4
JW
2482 }
2483
2484 return fptr;
2485}
2486
2487static asection *
eae50df2
L
2488get_pltoff (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED,
2489 struct elfNN_ia64_link_hash_table *ia64_info)
800eeca4
JW
2490{
2491 asection *pltoff;
2492 bfd *dynobj;
2493
2494 pltoff = ia64_info->pltoff_sec;
2495 if (!pltoff)
2496 {
2497 dynobj = ia64_info->root.dynobj;
2498 if (!dynobj)
2499 ia64_info->root.dynobj = dynobj = abfd;
2500
3496cb2a
L
2501 pltoff = bfd_make_section_with_flags (dynobj,
2502 ELF_STRING_ia64_pltoff,
2503 (SEC_ALLOC
2504 | SEC_LOAD
2505 | SEC_HAS_CONTENTS
2506 | SEC_IN_MEMORY
2507 | SEC_SMALL_DATA
2508 | SEC_LINKER_CREATED));
800eeca4 2509 if (!pltoff
800eeca4
JW
2510 || !bfd_set_section_alignment (abfd, pltoff, 4))
2511 {
2512 BFD_ASSERT (0);
2513 return NULL;
2514 }
2515
2516 ia64_info->pltoff_sec = pltoff;
2517 }
2518
2519 return pltoff;
2520}
2521
2522static asection *
eae50df2
L
2523get_reloc_section (bfd *abfd,
2524 struct elfNN_ia64_link_hash_table *ia64_info,
2525 asection *sec, bfd_boolean create)
800eeca4
JW
2526{
2527 const char *srel_name;
2528 asection *srel;
2529 bfd *dynobj;
2530
2531 srel_name = (bfd_elf_string_from_elf_section
2532 (abfd, elf_elfheader(abfd)->e_shstrndx,
2533 elf_section_data(sec)->rel_hdr.sh_name));
2534 if (srel_name == NULL)
2535 return NULL;
2536
0112cd26 2537 BFD_ASSERT ((CONST_STRNEQ (srel_name, ".rela")
800eeca4
JW
2538 && strcmp (bfd_get_section_name (abfd, sec),
2539 srel_name+5) == 0)
0112cd26 2540 || (CONST_STRNEQ (srel_name, ".rel")
800eeca4
JW
2541 && strcmp (bfd_get_section_name (abfd, sec),
2542 srel_name+4) == 0));
2543
2544 dynobj = ia64_info->root.dynobj;
2545 if (!dynobj)
2546 ia64_info->root.dynobj = dynobj = abfd;
2547
2548 srel = bfd_get_section_by_name (dynobj, srel_name);
2549 if (srel == NULL && create)
2550 {
3496cb2a
L
2551 srel = bfd_make_section_with_flags (dynobj, srel_name,
2552 (SEC_ALLOC | SEC_LOAD
2553 | SEC_HAS_CONTENTS
2554 | SEC_IN_MEMORY
2555 | SEC_LINKER_CREATED
2556 | SEC_READONLY));
800eeca4 2557 if (srel == NULL
5a260b66
L
2558 || !bfd_set_section_alignment (dynobj, srel,
2559 LOG_SECTION_ALIGN))
800eeca4
JW
2560 return NULL;
2561 }
2562
2563 return srel;
2564}
2565
b34976b6 2566static bfd_boolean
ac33696c
L
2567count_dyn_reloc (bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
2568 asection *srel, int type, bfd_boolean reltext)
800eeca4 2569{
bbe66d08 2570 struct elfNN_ia64_dyn_reloc_entry *rent;
800eeca4
JW
2571
2572 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2573 if (rent->srel == srel && rent->type == type)
2574 break;
2575
2576 if (!rent)
2577 {
dc810e39
AM
2578 rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2579 bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
800eeca4 2580 if (!rent)
b34976b6 2581 return FALSE;
800eeca4
JW
2582
2583 rent->next = dyn_i->reloc_entries;
2584 rent->srel = srel;
2585 rent->type = type;
2586 rent->count = 0;
2587 dyn_i->reloc_entries = rent;
2588 }
ac33696c 2589 rent->reltext = reltext;
800eeca4
JW
2590 rent->count++;
2591
b34976b6 2592 return TRUE;
800eeca4
JW
2593}
2594
b34976b6 2595static bfd_boolean
eae50df2
L
2596elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
2597 asection *sec,
2598 const Elf_Internal_Rela *relocs)
800eeca4 2599{
bbe66d08 2600 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
2601 const Elf_Internal_Rela *relend;
2602 Elf_Internal_Shdr *symtab_hdr;
2603 const Elf_Internal_Rela *rel;
21a8f7fa 2604 asection *got, *fptr, *srel, *pltoff;
396a682d
L
2605 enum {
2606 NEED_GOT = 1,
2607 NEED_GOTX = 2,
2608 NEED_FPTR = 4,
2609 NEED_PLTOFF = 8,
2610 NEED_MIN_PLT = 16,
2611 NEED_FULL_PLT = 32,
2612 NEED_DYNREL = 64,
2613 NEED_LTOFF_FPTR = 128,
2614 NEED_TPREL = 256,
2615 NEED_DTPMOD = 512,
2616 NEED_DTPREL = 1024
2617 };
2618 int need_entry;
2619 struct elf_link_hash_entry *h;
2620 unsigned long r_symndx;
2621 bfd_boolean maybe_dynamic;
800eeca4 2622
1049f94e 2623 if (info->relocatable)
b34976b6 2624 return TRUE;
800eeca4
JW
2625
2626 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
bbe66d08 2627 ia64_info = elfNN_ia64_hash_table (info);
800eeca4 2628
21a8f7fa 2629 got = fptr = srel = pltoff = NULL;
800eeca4
JW
2630
2631 relend = relocs + sec->reloc_count;
396a682d
L
2632
2633 /* We scan relocations first to create dynamic relocation arrays. We
2634 modified get_dyn_sym_info to allow fast insertion and support fast
2635 lookup in the next loop. */
2636 for (rel = relocs; rel < relend; ++rel)
2637 {
2638 r_symndx = ELFNN_R_SYM (rel->r_info);
2639 if (r_symndx >= symtab_hdr->sh_info)
2640 {
2641 long indx = r_symndx - symtab_hdr->sh_info;
2642 h = elf_sym_hashes (abfd)[indx];
2643 while (h->root.type == bfd_link_hash_indirect
2644 || h->root.type == bfd_link_hash_warning)
2645 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2646 }
2647 else
2648 h = NULL;
2649
2650 /* We can only get preliminary data on whether a symbol is
2651 locally or externally defined, as not all of the input files
2652 have yet been processed. Do something with what we know, as
2653 this may help reduce memory usage and processing time later. */
2654 maybe_dynamic = (h && ((!info->executable
55255dae 2655 && (!SYMBOLIC_BIND (info, h)
396a682d
L
2656 || info->unresolved_syms_in_shared_libs == RM_IGNORE))
2657 || !h->def_regular
2658 || h->root.type == bfd_link_hash_defweak));
2659
2660 need_entry = 0;
2661 switch (ELFNN_R_TYPE (rel->r_info))
2662 {
2663 case R_IA64_TPREL64MSB:
2664 case R_IA64_TPREL64LSB:
2665 if (info->shared || maybe_dynamic)
2666 need_entry = NEED_DYNREL;
2667 break;
2668
2669 case R_IA64_LTOFF_TPREL22:
2670 need_entry = NEED_TPREL;
2671 if (info->shared)
2672 info->flags |= DF_STATIC_TLS;
2673 break;
2674
2675 case R_IA64_DTPREL32MSB:
2676 case R_IA64_DTPREL32LSB:
2677 case R_IA64_DTPREL64MSB:
2678 case R_IA64_DTPREL64LSB:
2679 if (info->shared || maybe_dynamic)
2680 need_entry = NEED_DYNREL;
2681 break;
2682
2683 case R_IA64_LTOFF_DTPREL22:
2684 need_entry = NEED_DTPREL;
2685 break;
2686
2687 case R_IA64_DTPMOD64MSB:
2688 case R_IA64_DTPMOD64LSB:
2689 if (info->shared || maybe_dynamic)
2690 need_entry = NEED_DYNREL;
2691 break;
2692
2693 case R_IA64_LTOFF_DTPMOD22:
2694 need_entry = NEED_DTPMOD;
2695 break;
2696
2697 case R_IA64_LTOFF_FPTR22:
2698 case R_IA64_LTOFF_FPTR64I:
2699 case R_IA64_LTOFF_FPTR32MSB:
2700 case R_IA64_LTOFF_FPTR32LSB:
2701 case R_IA64_LTOFF_FPTR64MSB:
2702 case R_IA64_LTOFF_FPTR64LSB:
2703 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2704 break;
2705
2706 case R_IA64_FPTR64I:
2707 case R_IA64_FPTR32MSB:
2708 case R_IA64_FPTR32LSB:
2709 case R_IA64_FPTR64MSB:
2710 case R_IA64_FPTR64LSB:
2711 if (info->shared || h)
2712 need_entry = NEED_FPTR | NEED_DYNREL;
2713 else
2714 need_entry = NEED_FPTR;
2715 break;
2716
2717 case R_IA64_LTOFF22:
2718 case R_IA64_LTOFF64I:
2719 need_entry = NEED_GOT;
2720 break;
2721
2722 case R_IA64_LTOFF22X:
2723 need_entry = NEED_GOTX;
2724 break;
2725
2726 case R_IA64_PLTOFF22:
2727 case R_IA64_PLTOFF64I:
2728 case R_IA64_PLTOFF64MSB:
2729 case R_IA64_PLTOFF64LSB:
2730 need_entry = NEED_PLTOFF;
2731 if (h)
2732 {
2733 if (maybe_dynamic)
2734 need_entry |= NEED_MIN_PLT;
2735 }
2736 else
2737 {
2738 (*info->callbacks->warning)
2739 (info, _("@pltoff reloc against local symbol"), 0,
2740 abfd, 0, (bfd_vma) 0);
2741 }
2742 break;
2743
2744 case R_IA64_PCREL21B:
2745 case R_IA64_PCREL60B:
2746 /* Depending on where this symbol is defined, we may or may not
2747 need a full plt entry. Only skip if we know we'll not need
2748 the entry -- static or symbolic, and the symbol definition
2749 has already been seen. */
2750 if (maybe_dynamic && rel->r_addend == 0)
2751 need_entry = NEED_FULL_PLT;
2752 break;
2753
2754 case R_IA64_IMM14:
2755 case R_IA64_IMM22:
2756 case R_IA64_IMM64:
2757 case R_IA64_DIR32MSB:
2758 case R_IA64_DIR32LSB:
2759 case R_IA64_DIR64MSB:
2760 case R_IA64_DIR64LSB:
2761 /* Shared objects will always need at least a REL relocation. */
2762 if (info->shared || maybe_dynamic)
2763 need_entry = NEED_DYNREL;
2764 break;
2765
2766 case R_IA64_IPLTMSB:
2767 case R_IA64_IPLTLSB:
2768 /* Shared objects will always need at least a REL relocation. */
2769 if (info->shared || maybe_dynamic)
2770 need_entry = NEED_DYNREL;
2771 break;
2772
2773 case R_IA64_PCREL22:
2774 case R_IA64_PCREL64I:
2775 case R_IA64_PCREL32MSB:
2776 case R_IA64_PCREL32LSB:
2777 case R_IA64_PCREL64MSB:
2778 case R_IA64_PCREL64LSB:
2779 if (maybe_dynamic)
2780 need_entry = NEED_DYNREL;
2781 break;
2782 }
2783
2784 if (!need_entry)
2785 continue;
2786
2787 if ((need_entry & NEED_FPTR) != 0
2788 && rel->r_addend)
2789 {
2790 (*info->callbacks->warning)
2791 (info, _("non-zero addend in @fptr reloc"), 0,
2792 abfd, 0, (bfd_vma) 0);
2793 }
2794
2795 if (get_dyn_sym_info (ia64_info, h, abfd, rel, TRUE) == NULL)
2796 return FALSE;
2797 }
2798
2799 /* Now, we only do lookup without insertion, which is very fast
9a2e389a 2800 with the modified get_dyn_sym_info. */
800eeca4
JW
2801 for (rel = relocs; rel < relend; ++rel)
2802 {
bbe66d08 2803 struct elfNN_ia64_dyn_sym_info *dyn_i;
64bf6ae6 2804 int dynrel_type = R_IA64_NONE;
800eeca4 2805
396a682d 2806 r_symndx = ELFNN_R_SYM (rel->r_info);
800eeca4
JW
2807 if (r_symndx >= symtab_hdr->sh_info)
2808 {
2809 /* We're dealing with a global symbol -- find its hash entry
2810 and mark it as being referenced. */
2811 long indx = r_symndx - symtab_hdr->sh_info;
2812 h = elf_sym_hashes (abfd)[indx];
2813 while (h->root.type == bfd_link_hash_indirect
2814 || h->root.type == bfd_link_hash_warning)
2815 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2816
f5385ebf 2817 h->ref_regular = 1;
800eeca4 2818 }
396a682d
L
2819 else
2820 h = NULL;
800eeca4
JW
2821
2822 /* We can only get preliminary data on whether a symbol is
2823 locally or externally defined, as not all of the input files
2824 have yet been processed. Do something with what we know, as
2825 this may help reduce memory usage and processing time later. */
396a682d 2826 maybe_dynamic = (h && ((!info->executable
55255dae 2827 && (!SYMBOLIC_BIND (info, h)
396a682d
L
2828 || info->unresolved_syms_in_shared_libs == RM_IGNORE))
2829 || !h->def_regular
2830 || h->root.type == bfd_link_hash_defweak));
800eeca4
JW
2831
2832 need_entry = 0;
bbe66d08 2833 switch (ELFNN_R_TYPE (rel->r_info))
800eeca4 2834 {
800eeca4
JW
2835 case R_IA64_TPREL64MSB:
2836 case R_IA64_TPREL64LSB:
13ae64f3
JJ
2837 if (info->shared || maybe_dynamic)
2838 need_entry = NEED_DYNREL;
2839 dynrel_type = R_IA64_TPREL64LSB;
2840 if (info->shared)
2841 info->flags |= DF_STATIC_TLS;
2842 break;
2843
2844 case R_IA64_LTOFF_TPREL22:
2845 need_entry = NEED_TPREL;
2846 if (info->shared)
2847 info->flags |= DF_STATIC_TLS;
2848 break;
2849
5a260b66
L
2850 case R_IA64_DTPREL32MSB:
2851 case R_IA64_DTPREL32LSB:
13ae64f3
JJ
2852 case R_IA64_DTPREL64MSB:
2853 case R_IA64_DTPREL64LSB:
2854 if (info->shared || maybe_dynamic)
2855 need_entry = NEED_DYNREL;
5a260b66 2856 dynrel_type = R_IA64_DTPRELNNLSB;
13ae64f3
JJ
2857 break;
2858
2859 case R_IA64_LTOFF_DTPREL22:
2860 need_entry = NEED_DTPREL;
2861 break;
2862
2863 case R_IA64_DTPMOD64MSB:
2864 case R_IA64_DTPMOD64LSB:
2865 if (info->shared || maybe_dynamic)
2866 need_entry = NEED_DYNREL;
2867 dynrel_type = R_IA64_DTPMOD64LSB;
2868 break;
2869
2870 case R_IA64_LTOFF_DTPMOD22:
2871 need_entry = NEED_DTPMOD;
2872 break;
800eeca4
JW
2873
2874 case R_IA64_LTOFF_FPTR22:
2875 case R_IA64_LTOFF_FPTR64I:
a4bd8390
JW
2876 case R_IA64_LTOFF_FPTR32MSB:
2877 case R_IA64_LTOFF_FPTR32LSB:
800eeca4
JW
2878 case R_IA64_LTOFF_FPTR64MSB:
2879 case R_IA64_LTOFF_FPTR64LSB:
2880 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2881 break;
2882
2883 case R_IA64_FPTR64I:
2884 case R_IA64_FPTR32MSB:
2885 case R_IA64_FPTR32LSB:
2886 case R_IA64_FPTR64MSB:
2887 case R_IA64_FPTR64LSB:
02e6ad56 2888 if (info->shared || h)
800eeca4
JW
2889 need_entry = NEED_FPTR | NEED_DYNREL;
2890 else
2891 need_entry = NEED_FPTR;
5a260b66 2892 dynrel_type = R_IA64_FPTRNNLSB;
800eeca4
JW
2893 break;
2894
2895 case R_IA64_LTOFF22:
800eeca4
JW
2896 case R_IA64_LTOFF64I:
2897 need_entry = NEED_GOT;
2898 break;
2899
2c4c2bc0
RH
2900 case R_IA64_LTOFF22X:
2901 need_entry = NEED_GOTX;
2902 break;
2903
800eeca4
JW
2904 case R_IA64_PLTOFF22:
2905 case R_IA64_PLTOFF64I:
2906 case R_IA64_PLTOFF64MSB:
2907 case R_IA64_PLTOFF64LSB:
2908 need_entry = NEED_PLTOFF;
2909 if (h)
2910 {
2911 if (maybe_dynamic)
2912 need_entry |= NEED_MIN_PLT;
2913 }
800eeca4
JW
2914 break;
2915
2916 case R_IA64_PCREL21B:
748abff6 2917 case R_IA64_PCREL60B:
800eeca4
JW
2918 /* Depending on where this symbol is defined, we may or may not
2919 need a full plt entry. Only skip if we know we'll not need
2920 the entry -- static or symbolic, and the symbol definition
2921 has already been seen. */
2922 if (maybe_dynamic && rel->r_addend == 0)
2923 need_entry = NEED_FULL_PLT;
2924 break;
2925
2926 case R_IA64_IMM14:
2927 case R_IA64_IMM22:
2928 case R_IA64_IMM64:
2929 case R_IA64_DIR32MSB:
2930 case R_IA64_DIR32LSB:
2931 case R_IA64_DIR64MSB:
2932 case R_IA64_DIR64LSB:
2933 /* Shared objects will always need at least a REL relocation. */
02e6ad56 2934 if (info->shared || maybe_dynamic)
800eeca4 2935 need_entry = NEED_DYNREL;
5a260b66 2936 dynrel_type = R_IA64_DIRNNLSB;
800eeca4
JW
2937 break;
2938
18b27f17
RH
2939 case R_IA64_IPLTMSB:
2940 case R_IA64_IPLTLSB:
2941 /* Shared objects will always need at least a REL relocation. */
2942 if (info->shared || maybe_dynamic)
2943 need_entry = NEED_DYNREL;
2944 dynrel_type = R_IA64_IPLTLSB;
2945 break;
2946
748abff6
RH
2947 case R_IA64_PCREL22:
2948 case R_IA64_PCREL64I:
800eeca4
JW
2949 case R_IA64_PCREL32MSB:
2950 case R_IA64_PCREL32LSB:
2951 case R_IA64_PCREL64MSB:
2952 case R_IA64_PCREL64LSB:
2953 if (maybe_dynamic)
2954 need_entry = NEED_DYNREL;
5a260b66 2955 dynrel_type = R_IA64_PCRELNNLSB;
800eeca4
JW
2956 break;
2957 }
2958
2959 if (!need_entry)
2960 continue;
2961
396a682d 2962 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, FALSE);
800eeca4
JW
2963
2964 /* Record whether or not this is a local symbol. */
2965 dyn_i->h = h;
2966
2967 /* Create what's needed. */
2c4c2bc0
RH
2968 if (need_entry & (NEED_GOT | NEED_GOTX | NEED_TPREL
2969 | NEED_DTPMOD | NEED_DTPREL))
800eeca4
JW
2970 {
2971 if (!got)
2972 {
2973 got = get_got (abfd, info, ia64_info);
2974 if (!got)
b34976b6 2975 return FALSE;
800eeca4 2976 }
13ae64f3
JJ
2977 if (need_entry & NEED_GOT)
2978 dyn_i->want_got = 1;
2c4c2bc0
RH
2979 if (need_entry & NEED_GOTX)
2980 dyn_i->want_gotx = 1;
13ae64f3
JJ
2981 if (need_entry & NEED_TPREL)
2982 dyn_i->want_tprel = 1;
2983 if (need_entry & NEED_DTPMOD)
2984 dyn_i->want_dtpmod = 1;
2985 if (need_entry & NEED_DTPREL)
2986 dyn_i->want_dtprel = 1;
800eeca4
JW
2987 }
2988 if (need_entry & NEED_FPTR)
2989 {
2990 if (!fptr)
2991 {
2992 fptr = get_fptr (abfd, info, ia64_info);
2993 if (!fptr)
b34976b6 2994 return FALSE;
800eeca4
JW
2995 }
2996
2997 /* FPTRs for shared libraries are allocated by the dynamic
2998 linker. Make sure this local symbol will appear in the
2999 dynamic symbol table. */
02e6ad56 3000 if (!h && info->shared)
800eeca4 3001 {
c152c796 3002 if (! (bfd_elf_link_record_local_dynamic_symbol
dc810e39 3003 (info, abfd, (long) r_symndx)))
b34976b6 3004 return FALSE;
800eeca4
JW
3005 }
3006
3007 dyn_i->want_fptr = 1;
3008 }
3009 if (need_entry & NEED_LTOFF_FPTR)
3010 dyn_i->want_ltoff_fptr = 1;
3011 if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
3012 {
3013 if (!ia64_info->root.dynobj)
3014 ia64_info->root.dynobj = abfd;
f5385ebf 3015 h->needs_plt = 1;
800eeca4
JW
3016 dyn_i->want_plt = 1;
3017 }
3018 if (need_entry & NEED_FULL_PLT)
3019 dyn_i->want_plt2 = 1;
3020 if (need_entry & NEED_PLTOFF)
21a8f7fa
JW
3021 {
3022 /* This is needed here, in case @pltoff is used in a non-shared
3023 link. */
3024 if (!pltoff)
3025 {
3026 pltoff = get_pltoff (abfd, info, ia64_info);
3027 if (!pltoff)
3028 return FALSE;
3029 }
f12123c0 3030
21a8f7fa
JW
3031 dyn_i->want_pltoff = 1;
3032 }
800eeca4
JW
3033 if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
3034 {
3035 if (!srel)
3036 {
b34976b6 3037 srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
800eeca4 3038 if (!srel)
b34976b6 3039 return FALSE;
800eeca4 3040 }
ac33696c 3041 if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type,
de9811af 3042 (sec->flags & SEC_READONLY) != 0))
b34976b6 3043 return FALSE;
800eeca4
JW
3044 }
3045 }
3046
b34976b6 3047 return TRUE;
800eeca4
JW
3048}
3049
800eeca4
JW
3050/* For cleanliness, and potentially faster dynamic loading, allocate
3051 external GOT entries first. */
3052
b34976b6 3053static bfd_boolean
eae50df2
L
3054allocate_global_data_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
3055 PTR data)
800eeca4 3056{
bbe66d08 3057 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
800eeca4 3058
2c4c2bc0 3059 if ((dyn_i->want_got || dyn_i->want_gotx)
800eeca4 3060 && ! dyn_i->want_fptr
986a241f 3061 && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
800eeca4
JW
3062 {
3063 dyn_i->got_offset = x->ofs;
3064 x->ofs += 8;
3065 }
13ae64f3
JJ
3066 if (dyn_i->want_tprel)
3067 {
3068 dyn_i->tprel_offset = x->ofs;
3069 x->ofs += 8;
3070 }
3071 if (dyn_i->want_dtpmod)
3072 {
986a241f 3073 if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
b3dfd7fe
JJ
3074 {
3075 dyn_i->dtpmod_offset = x->ofs;
3076 x->ofs += 8;
3077 }
3078 else
3079 {
3080 struct elfNN_ia64_link_hash_table *ia64_info;
3081
3082 ia64_info = elfNN_ia64_hash_table (x->info);
3083 if (ia64_info->self_dtpmod_offset == (bfd_vma) -1)
3084 {
3085 ia64_info->self_dtpmod_offset = x->ofs;
3086 x->ofs += 8;
3087 }
3088 dyn_i->dtpmod_offset = ia64_info->self_dtpmod_offset;
3089 }
13ae64f3
JJ
3090 }
3091 if (dyn_i->want_dtprel)
3092 {
3093 dyn_i->dtprel_offset = x->ofs;
3094 x->ofs += 8;
3095 }
b34976b6 3096 return TRUE;
800eeca4
JW
3097}
3098
3099/* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
3100
b34976b6 3101static bfd_boolean
eae50df2
L
3102allocate_global_fptr_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
3103 PTR data)
800eeca4 3104{
bbe66d08 3105 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
800eeca4
JW
3106
3107 if (dyn_i->want_got
3108 && dyn_i->want_fptr
5a260b66 3109 && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, R_IA64_FPTRNNLSB))
800eeca4
JW
3110 {
3111 dyn_i->got_offset = x->ofs;
3112 x->ofs += 8;
3113 }
b34976b6 3114 return TRUE;
800eeca4
JW
3115}
3116
3117/* Lastly, allocate all the GOT entries for local data. */
3118
b34976b6 3119static bfd_boolean
eae50df2
L
3120allocate_local_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
3121 PTR data)
800eeca4 3122{
bbe66d08 3123 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
800eeca4 3124
2c4c2bc0 3125 if ((dyn_i->want_got || dyn_i->want_gotx)
986a241f 3126 && !elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
800eeca4
JW
3127 {
3128 dyn_i->got_offset = x->ofs;
3129 x->ofs += 8;
3130 }
b34976b6 3131 return TRUE;
800eeca4
JW
3132}
3133
3134/* Search for the index of a global symbol in it's defining object file. */
3135
dc810e39 3136static long
eae50df2 3137global_sym_index (struct elf_link_hash_entry *h)
800eeca4
JW
3138{
3139 struct elf_link_hash_entry **p;
3140 bfd *obj;
3141
3142 BFD_ASSERT (h->root.type == bfd_link_hash_defined
3143 || h->root.type == bfd_link_hash_defweak);
3144
3145 obj = h->root.u.def.section->owner;
3146 for (p = elf_sym_hashes (obj); *p != h; ++p)
3147 continue;
3148
3149 return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
3150}
3151
3152/* Allocate function descriptors. We can do these for every function
3153 in a main executable that is not exported. */
3154
b34976b6 3155static bfd_boolean
eae50df2 3156allocate_fptr (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data)
800eeca4 3157{
bbe66d08 3158 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
800eeca4
JW
3159
3160 if (dyn_i->want_fptr)
3161 {
3162 struct elf_link_hash_entry *h = dyn_i->h;
3e932841 3163
800eeca4
JW
3164 if (h)
3165 while (h->root.type == bfd_link_hash_indirect
3166 || h->root.type == bfd_link_hash_warning)
3167 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3168
02e6ad56
RH
3169 if (!x->info->executable
3170 && (!h
3171 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1faab634
L
3172 || (h->root.type != bfd_link_hash_undefweak
3173 && h->root.type != bfd_link_hash_undefined)))
800eeca4
JW
3174 {
3175 if (h && h->dynindx == -1)
3176 {
3177 BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
3178 || (h->root.type == bfd_link_hash_defweak));
3179
c152c796 3180 if (!bfd_elf_link_record_local_dynamic_symbol
800eeca4
JW
3181 (x->info, h->root.u.def.section->owner,
3182 global_sym_index (h)))
b34976b6 3183 return FALSE;
800eeca4
JW
3184 }
3185
3186 dyn_i->want_fptr = 0;
3187 }
3188 else if (h == NULL || h->dynindx == -1)
3189 {
3190 dyn_i->fptr_offset = x->ofs;
3191 x->ofs += 16;
3192 }
3193 else
3194 dyn_i->want_fptr = 0;
3195 }
b34976b6 3196 return TRUE;
800eeca4
JW
3197}
3198
3199/* Allocate all the minimal PLT entries. */
3200
b34976b6 3201static bfd_boolean
eae50df2
L
3202allocate_plt_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
3203 PTR data)
800eeca4 3204{
bbe66d08 3205 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
800eeca4
JW
3206
3207 if (dyn_i->want_plt)
3208 {
3209 struct elf_link_hash_entry *h = dyn_i->h;
3210
3211 if (h)
3212 while (h->root.type == bfd_link_hash_indirect
3213 || h->root.type == bfd_link_hash_warning)
3214 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3215
f5385ebf 3216 /* ??? Versioned symbols seem to lose NEEDS_PLT. */
986a241f 3217 if (elfNN_ia64_dynamic_symbol_p (h, x->info, 0))
800eeca4
JW
3218 {
3219 bfd_size_type offset = x->ofs;
3220 if (offset == 0)
3221 offset = PLT_HEADER_SIZE;
3222 dyn_i->plt_offset = offset;
3223 x->ofs = offset + PLT_MIN_ENTRY_SIZE;
3224
3225 dyn_i->want_pltoff = 1;
3226 }
3227 else
3228 {
3229 dyn_i->want_plt = 0;
3230 dyn_i->want_plt2 = 0;
3231 }
3232 }
b34976b6 3233 return TRUE;
800eeca4
JW
3234}
3235
3236/* Allocate all the full PLT entries. */
3237
b34976b6 3238static bfd_boolean
eae50df2
L
3239allocate_plt2_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
3240 PTR data)
800eeca4 3241{
bbe66d08 3242 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
800eeca4
JW
3243
3244 if (dyn_i->want_plt2)
3245 {
3246 struct elf_link_hash_entry *h = dyn_i->h;
3247 bfd_size_type ofs = x->ofs;
3248
3249 dyn_i->plt2_offset = ofs;
3250 x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
3251
3252 while (h->root.type == bfd_link_hash_indirect
3253 || h->root.type == bfd_link_hash_warning)
3254 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3255 dyn_i->h->plt.offset = ofs;
3256 }
b34976b6 3257 return TRUE;
800eeca4
JW
3258}
3259
3260/* Allocate all the PLTOFF entries requested by relocations and
3261 plt entries. We can't share space with allocated FPTR entries,
3262 because the latter are not necessarily addressable by the GP.
3263 ??? Relaxation might be able to determine that they are. */
3264
b34976b6 3265static bfd_boolean
eae50df2
L
3266allocate_pltoff_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
3267 PTR data)
800eeca4 3268{
bbe66d08 3269 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
800eeca4
JW
3270
3271 if (dyn_i->want_pltoff)
3272 {
3273 dyn_i->pltoff_offset = x->ofs;
3274 x->ofs += 16;
3275 }
b34976b6 3276 return TRUE;
800eeca4
JW
3277}
3278
3279/* Allocate dynamic relocations for those symbols that turned out
3280 to be dynamic. */
3281
b34976b6 3282static bfd_boolean
eae50df2
L
3283allocate_dynrel_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
3284 PTR data)
800eeca4 3285{
bbe66d08
JW
3286 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3287 struct elfNN_ia64_link_hash_table *ia64_info;
3288 struct elfNN_ia64_dyn_reloc_entry *rent;
ef5aade5 3289 bfd_boolean dynamic_symbol, shared, resolved_zero;
800eeca4 3290
bbe66d08 3291 ia64_info = elfNN_ia64_hash_table (x->info);
986a241f
RH
3292
3293 /* Note that this can't be used in relation to FPTR relocs below. */
3294 dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0);
3295
800eeca4 3296 shared = x->info->shared;
ef5aade5
L
3297 resolved_zero = (dyn_i->h
3298 && ELF_ST_VISIBILITY (dyn_i->h->other)
3299 && dyn_i->h->root.type == bfd_link_hash_undefweak);
800eeca4 3300
4a78a1f4
AS
3301 /* Take care of the GOT and PLT relocations. */
3302
3303 if ((!resolved_zero
3304 && (dynamic_symbol || shared)
3305 && (dyn_i->want_got || dyn_i->want_gotx))
3306 || (dyn_i->want_ltoff_fptr
3307 && dyn_i->h
3308 && dyn_i->h->dynindx != -1))
3309 {
3310 if (!dyn_i->want_ltoff_fptr
3311 || !x->info->pie
3312 || dyn_i->h == NULL
3313 || dyn_i->h->root.type != bfd_link_hash_undefweak)
cc3bd654 3314 ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
4a78a1f4
AS
3315 }
3316 if ((dynamic_symbol || shared) && dyn_i->want_tprel)
cc3bd654 3317 ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
4a78a1f4 3318 if (dynamic_symbol && dyn_i->want_dtpmod)
cc3bd654 3319 ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
4a78a1f4 3320 if (dynamic_symbol && dyn_i->want_dtprel)
cc3bd654 3321 ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
4a78a1f4
AS
3322
3323 if (x->only_got)
3324 return TRUE;
3325
3326 if (ia64_info->rel_fptr_sec && dyn_i->want_fptr)
3327 {
3328 if (dyn_i->h == NULL || dyn_i->h->root.type != bfd_link_hash_undefweak)
3329 ia64_info->rel_fptr_sec->size += sizeof (ElfNN_External_Rela);
3330 }
3331
3332 if (!resolved_zero && dyn_i->want_pltoff)
3333 {
3334 bfd_size_type t = 0;
3335
3336 /* Dynamic symbols get one IPLT relocation. Local symbols in
3337 shared libraries get two REL relocations. Local symbols in
3338 main applications get nothing. */
3339 if (dynamic_symbol)
3340 t = sizeof (ElfNN_External_Rela);
3341 else if (shared)
3342 t = 2 * sizeof (ElfNN_External_Rela);
3343
3344 ia64_info->rel_pltoff_sec->size += t;
3345 }
3346
800eeca4
JW
3347 /* Take care of the normal data relocations. */
3348
3349 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
3350 {
18b27f17
RH
3351 int count = rent->count;
3352
800eeca4
JW
3353 switch (rent->type)
3354 {
5a260b66 3355 case R_IA64_FPTR32LSB:
800eeca4 3356 case R_IA64_FPTR64LSB:
9203ba99
JJ
3357 /* Allocate one iff !want_fptr and not PIE, which by this point
3358 will be true only if we're actually allocating one statically
3359 in the main executable. Position independent executables
3360 need a relative reloc. */
3361 if (dyn_i->want_fptr && !x->info->pie)
800eeca4
JW
3362 continue;
3363 break;
5a260b66 3364 case R_IA64_PCREL32LSB:
800eeca4
JW
3365 case R_IA64_PCREL64LSB:
3366 if (!dynamic_symbol)
3367 continue;
3368 break;
5a260b66 3369 case R_IA64_DIR32LSB:
800eeca4
JW
3370 case R_IA64_DIR64LSB:
3371 if (!dynamic_symbol && !shared)
3372 continue;
3373 break;
18b27f17
RH
3374 case R_IA64_IPLTLSB:
3375 if (!dynamic_symbol && !shared)
3376 continue;
3377 /* Use two REL relocations for IPLT relocations
3378 against local symbols. */
3379 if (!dynamic_symbol)
3380 count *= 2;
3381 break;
5a260b66 3382 case R_IA64_DTPREL32LSB:
13ae64f3
JJ
3383 case R_IA64_TPREL64LSB:
3384 case R_IA64_DTPREL64LSB:
3385 case R_IA64_DTPMOD64LSB:
3386 break;
18b27f17
RH
3387 default:
3388 abort ();
800eeca4 3389 }
ac33696c
L
3390 if (rent->reltext)
3391 ia64_info->reltext = 1;
eea6121a 3392 rent->srel->size += sizeof (ElfNN_External_Rela) * count;
800eeca4
JW
3393 }
3394
b34976b6 3395 return TRUE;
800eeca4
JW
3396}
3397
b34976b6 3398static bfd_boolean
eae50df2
L
3399elfNN_ia64_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
3400 struct elf_link_hash_entry *h)
800eeca4
JW
3401{
3402 /* ??? Undefined symbols with PLT entries should be re-defined
3403 to be the PLT entry. */
3404
3405 /* If this is a weak symbol, and there is a real definition, the
3406 processor independent code will have arranged for us to see the
3407 real definition first, and we can just use the same value. */
f6e332e6 3408 if (h->u.weakdef != NULL)
800eeca4 3409 {
f6e332e6
AM
3410 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
3411 || h->u.weakdef->root.type == bfd_link_hash_defweak);
3412 h->root.u.def.section = h->u.weakdef->root.u.def.section;
3413 h->root.u.def.value = h->u.weakdef->root.u.def.value;
b34976b6 3414 return TRUE;
800eeca4
JW
3415 }
3416
3417 /* If this is a reference to a symbol defined by a dynamic object which
3418 is not a function, we might allocate the symbol in our .dynbss section
3419 and allocate a COPY dynamic relocation.
3420
3421 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
3422 of hackery. */
3423
b34976b6 3424 return TRUE;
800eeca4
JW
3425}
3426
b34976b6 3427static bfd_boolean
eae50df2
L
3428elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
3429 struct bfd_link_info *info)
800eeca4 3430{
bbe66d08
JW
3431 struct elfNN_ia64_allocate_data data;
3432 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
3433 asection *sec;
3434 bfd *dynobj;
b34976b6 3435 bfd_boolean relplt = FALSE;
800eeca4
JW
3436
3437 dynobj = elf_hash_table(info)->dynobj;
bbe66d08 3438 ia64_info = elfNN_ia64_hash_table (info);
b3dfd7fe 3439 ia64_info->self_dtpmod_offset = (bfd_vma) -1;
800eeca4
JW
3440 BFD_ASSERT(dynobj != NULL);
3441 data.info = info;
3442
3443 /* Set the contents of the .interp section to the interpreter. */
3444 if (ia64_info->root.dynamic_sections_created
36af4a4e 3445 && info->executable)
800eeca4
JW
3446 {
3447 sec = bfd_get_section_by_name (dynobj, ".interp");
3448 BFD_ASSERT (sec != NULL);
02e6ad56 3449 sec->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
eea6121a 3450 sec->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
800eeca4
JW
3451 }
3452
800eeca4
JW
3453 /* Allocate the GOT entries. */
3454
cc3bd654 3455 if (ia64_info->root.sgot)
800eeca4
JW
3456 {
3457 data.ofs = 0;
bbe66d08
JW
3458 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
3459 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
3460 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
cc3bd654 3461 ia64_info->root.sgot->size = data.ofs;
800eeca4
JW
3462 }
3463
3464 /* Allocate the FPTR entries. */
3465
3466 if (ia64_info->fptr_sec)
3467 {
3468 data.ofs = 0;
bbe66d08 3469 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
eea6121a 3470 ia64_info->fptr_sec->size = data.ofs;
800eeca4
JW
3471 }
3472
3473 /* Now that we've seen all of the input files, we can decide which
3474 symbols need plt entries. Allocate the minimal PLT entries first.
b34976b6 3475 We do this even though dynamic_sections_created may be FALSE, because
800eeca4
JW
3476 this has the side-effect of clearing want_plt and want_plt2. */
3477
3478 data.ofs = 0;
bbe66d08 3479 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
800eeca4
JW
3480
3481 ia64_info->minplt_entries = 0;
3482 if (data.ofs)
3483 {
3484 ia64_info->minplt_entries
3485 = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
3486 }
3487
3488 /* Align the pointer for the plt2 entries. */
dc810e39 3489 data.ofs = (data.ofs + 31) & (bfd_vma) -32;
800eeca4 3490
bbe66d08 3491 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
a5a58ba4 3492 if (data.ofs != 0 || ia64_info->root.dynamic_sections_created)
800eeca4 3493 {
a5a58ba4
L
3494 /* FIXME: we always reserve the memory for dynamic linker even if
3495 there are no PLT entries since dynamic linker may assume the
3496 reserved memory always exists. */
3497
800eeca4
JW
3498 BFD_ASSERT (ia64_info->root.dynamic_sections_created);
3499
cc3bd654 3500 ia64_info->root.splt->size = data.ofs;
800eeca4
JW
3501
3502 /* If we've got a .plt, we need some extra memory for the dynamic
3503 linker. We stuff these in .got.plt. */
3504 sec = bfd_get_section_by_name (dynobj, ".got.plt");
eea6121a 3505 sec->size = 8 * PLT_RESERVED_WORDS;
800eeca4
JW
3506 }
3507
3508 /* Allocate the PLTOFF entries. */
3509
3510 if (ia64_info->pltoff_sec)
3511 {
3512 data.ofs = 0;
bbe66d08 3513 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
eea6121a 3514 ia64_info->pltoff_sec->size = data.ofs;
800eeca4
JW
3515 }
3516
3517 if (ia64_info->root.dynamic_sections_created)
3518 {
3519 /* Allocate space for the dynamic relocations that turned out to be
3520 required. */
3521
b3dfd7fe 3522 if (info->shared && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
cc3bd654 3523 ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
4a78a1f4 3524 data.only_got = FALSE;
bbe66d08 3525 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
800eeca4
JW
3526 }
3527
3528 /* We have now determined the sizes of the various dynamic sections.
3529 Allocate memory for them. */
3530 for (sec = dynobj->sections; sec != NULL; sec = sec->next)
3531 {
b34976b6 3532 bfd_boolean strip;
800eeca4
JW
3533
3534 if (!(sec->flags & SEC_LINKER_CREATED))
3535 continue;
3536
3537 /* If we don't need this section, strip it from the output file.
3538 There were several sections primarily related to dynamic
3539 linking that must be create before the linker maps input
3540 sections to output sections. The linker does that before
3541 bfd_elf_size_dynamic_sections is called, and it is that
3542 function which decides whether anything needs to go into
3543 these sections. */
3544
eea6121a 3545 strip = (sec->size == 0);
800eeca4 3546
cc3bd654 3547 if (sec == ia64_info->root.sgot)
b34976b6 3548 strip = FALSE;
cc3bd654 3549 else if (sec == ia64_info->root.srelgot)
800eeca4
JW
3550 {
3551 if (strip)
cc3bd654 3552 ia64_info->root.srelgot = NULL;
800eeca4
JW
3553 else
3554 /* We use the reloc_count field as a counter if we need to
3555 copy relocs into the output file. */
3556 sec->reloc_count = 0;
3557 }
3558 else if (sec == ia64_info->fptr_sec)
3559 {
3560 if (strip)
3561 ia64_info->fptr_sec = NULL;
3562 }
55936540
JW
3563 else if (sec == ia64_info->rel_fptr_sec)
3564 {
3565 if (strip)
3566 ia64_info->rel_fptr_sec = NULL;
3567 else
3568 /* We use the reloc_count field as a counter if we need to
3569 copy relocs into the output file. */
3570 sec->reloc_count = 0;
3571 }
cc3bd654 3572 else if (sec == ia64_info->root.splt)
800eeca4
JW
3573 {
3574 if (strip)
cc3bd654 3575 ia64_info->root.splt = NULL;
800eeca4
JW
3576 }
3577 else if (sec == ia64_info->pltoff_sec)
3578 {
3579 if (strip)
3580 ia64_info->pltoff_sec = NULL;
3581 }
3582 else if (sec == ia64_info->rel_pltoff_sec)
3583 {
3584 if (strip)
3585 ia64_info->rel_pltoff_sec = NULL;
3586 else
3587 {
b34976b6 3588 relplt = TRUE;
800eeca4
JW
3589 /* We use the reloc_count field as a counter if we need to
3590 copy relocs into the output file. */
3591 sec->reloc_count = 0;
3592 }
3593 }
3594 else
3595 {
3596 const char *name;
3597
3598 /* It's OK to base decisions on the section name, because none
3599 of the dynobj section names depend upon the input files. */
3600 name = bfd_get_section_name (dynobj, sec);
3601
3602 if (strcmp (name, ".got.plt") == 0)
b34976b6 3603 strip = FALSE;
0112cd26 3604 else if (CONST_STRNEQ (name, ".rel"))
800eeca4
JW
3605 {
3606 if (!strip)
3607 {
800eeca4
JW
3608 /* We use the reloc_count field as a counter if we need to
3609 copy relocs into the output file. */
3610 sec->reloc_count = 0;
3611 }
3612 }
3613 else
3614 continue;
3615 }
3616
3617 if (strip)
8423293d 3618 sec->flags |= SEC_EXCLUDE;
800eeca4
JW
3619 else
3620 {
3621 /* Allocate memory for the section contents. */
eea6121a
AM
3622 sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->size);
3623 if (sec->contents == NULL && sec->size != 0)
b34976b6 3624 return FALSE;
800eeca4
JW
3625 }
3626 }
3627
3628 if (elf_hash_table (info)->dynamic_sections_created)
3629 {
3630 /* Add some entries to the .dynamic section. We fill in the values
3631 later (in finish_dynamic_sections) but we must add the entries now
3632 so that we get the correct size for the .dynamic section. */
3633
36af4a4e 3634 if (info->executable)
800eeca4
JW
3635 {
3636 /* The DT_DEBUG entry is filled in by the dynamic linker and used
3637 by the debugger. */
dc810e39 3638#define add_dynamic_entry(TAG, VAL) \
5a580b3a 3639 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
dc810e39
AM
3640
3641 if (!add_dynamic_entry (DT_DEBUG, 0))
b34976b6 3642 return FALSE;
800eeca4
JW
3643 }
3644
dc810e39 3645 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
b34976b6 3646 return FALSE;
dc810e39 3647 if (!add_dynamic_entry (DT_PLTGOT, 0))
b34976b6 3648 return FALSE;
800eeca4
JW
3649
3650 if (relplt)
3651 {
dc810e39
AM
3652 if (!add_dynamic_entry (DT_PLTRELSZ, 0)
3653 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3654 || !add_dynamic_entry (DT_JMPREL, 0))
b34976b6 3655 return FALSE;
800eeca4
JW
3656 }
3657
dc810e39
AM
3658 if (!add_dynamic_entry (DT_RELA, 0)
3659 || !add_dynamic_entry (DT_RELASZ, 0)
3660 || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
b34976b6 3661 return FALSE;
800eeca4 3662
db6751f2 3663 if (ia64_info->reltext)
800eeca4 3664 {
dc810e39 3665 if (!add_dynamic_entry (DT_TEXTREL, 0))
b34976b6 3666 return FALSE;
d6cf2879 3667 info->flags |= DF_TEXTREL;
800eeca4
JW
3668 }
3669 }
3670
3671 /* ??? Perhaps force __gp local. */
3672
b34976b6 3673 return TRUE;
800eeca4
JW
3674}
3675
3676static bfd_reloc_status_type
eae50df2
L
3677elfNN_ia64_install_value (bfd_byte *hit_addr, bfd_vma v,
3678 unsigned int r_type)
800eeca4
JW
3679{
3680 const struct ia64_operand *op;
3681 int bigendian = 0, shift = 0;
b4677f03
AS
3682 bfd_vma t0, t1, dword;
3683 ia64_insn insn;
800eeca4
JW
3684 enum ia64_opnd opnd;
3685 const char *err;
3686 size_t size = 8;
1e738b87
NC
3687#ifdef BFD_HOST_U_64_BIT
3688 BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
3689#else
3690 bfd_vma val = v;
3691#endif
800eeca4
JW
3692
3693 opnd = IA64_OPND_NIL;
3694 switch (r_type)
3695 {
3696 case R_IA64_NONE:
3697 case R_IA64_LDXMOV:
3698 return bfd_reloc_ok;
3699
3e932841 3700 /* Instruction relocations. */
800eeca4 3701
13ae64f3
JJ
3702 case R_IA64_IMM14:
3703 case R_IA64_TPREL14:
3704 case R_IA64_DTPREL14:
3705 opnd = IA64_OPND_IMM14;
3706 break;
748abff6 3707
800eeca4
JW
3708 case R_IA64_PCREL21F: opnd = IA64_OPND_TGT25; break;
3709 case R_IA64_PCREL21M: opnd = IA64_OPND_TGT25b; break;
748abff6
RH
3710 case R_IA64_PCREL60B: opnd = IA64_OPND_TGT64; break;
3711 case R_IA64_PCREL21B:
3712 case R_IA64_PCREL21BI:
3713 opnd = IA64_OPND_TGT25c;
3714 break;
800eeca4
JW
3715
3716 case R_IA64_IMM22:
3717 case R_IA64_GPREL22:
3718 case R_IA64_LTOFF22:
3719 case R_IA64_LTOFF22X:
3720 case R_IA64_PLTOFF22:
748abff6 3721 case R_IA64_PCREL22:
800eeca4 3722 case R_IA64_LTOFF_FPTR22:
13ae64f3
JJ
3723 case R_IA64_TPREL22:
3724 case R_IA64_DTPREL22:
3725 case R_IA64_LTOFF_TPREL22:
3726 case R_IA64_LTOFF_DTPMOD22:
3727 case R_IA64_LTOFF_DTPREL22:
800eeca4
JW
3728 opnd = IA64_OPND_IMM22;
3729 break;
3730
3731 case R_IA64_IMM64:
3732 case R_IA64_GPREL64I:
3733 case R_IA64_LTOFF64I:
3734 case R_IA64_PLTOFF64I:
748abff6 3735 case R_IA64_PCREL64I:
800eeca4
JW
3736 case R_IA64_FPTR64I:
3737 case R_IA64_LTOFF_FPTR64I:
13ae64f3
JJ
3738 case R_IA64_TPREL64I:
3739 case R_IA64_DTPREL64I:
800eeca4
JW
3740 opnd = IA64_OPND_IMMU64;
3741 break;
3742
3743 /* Data relocations. */
3744
3745 case R_IA64_DIR32MSB:
3746 case R_IA64_GPREL32MSB:
3747 case R_IA64_FPTR32MSB:
3748 case R_IA64_PCREL32MSB:
a4bd8390 3749 case R_IA64_LTOFF_FPTR32MSB:
800eeca4
JW
3750 case R_IA64_SEGREL32MSB:
3751 case R_IA64_SECREL32MSB:
3752 case R_IA64_LTV32MSB:
13ae64f3 3753 case R_IA64_DTPREL32MSB:
800eeca4
JW
3754 size = 4; bigendian = 1;
3755 break;
3756
3757 case R_IA64_DIR32LSB:
3758 case R_IA64_GPREL32LSB:
3759 case R_IA64_FPTR32LSB:
3760 case R_IA64_PCREL32LSB:
a4bd8390 3761 case R_IA64_LTOFF_FPTR32LSB:
800eeca4
JW
3762 case R_IA64_SEGREL32LSB:
3763 case R_IA64_SECREL32LSB:
3764 case R_IA64_LTV32LSB:
13ae64f3 3765 case R_IA64_DTPREL32LSB:
800eeca4
JW
3766 size = 4; bigendian = 0;
3767 break;
3768
3769 case R_IA64_DIR64MSB:
3770 case R_IA64_GPREL64MSB:
3771 case R_IA64_PLTOFF64MSB:
3772 case R_IA64_FPTR64MSB:
3773 case R_IA64_PCREL64MSB:
3774 case R_IA64_LTOFF_FPTR64MSB:
3775 case R_IA64_SEGREL64MSB:
3776 case R_IA64_SECREL64MSB:
3777 case R_IA64_LTV64MSB:
13ae64f3
JJ
3778 case R_IA64_TPREL64MSB:
3779 case R_IA64_DTPMOD64MSB:
3780 case R_IA64_DTPREL64MSB:
800eeca4
JW
3781 size = 8; bigendian = 1;
3782 break;
3783
3784 case R_IA64_DIR64LSB:
3785 case R_IA64_GPREL64LSB:
3786 case R_IA64_PLTOFF64LSB:
3787 case R_IA64_FPTR64LSB:
3788 case R_IA64_PCREL64LSB:
3789 case R_IA64_LTOFF_FPTR64LSB:
3790 case R_IA64_SEGREL64LSB:
3791 case R_IA64_SECREL64LSB:
3792 case R_IA64_LTV64LSB:
13ae64f3
JJ
3793 case R_IA64_TPREL64LSB:
3794 case R_IA64_DTPMOD64LSB:
3795 case R_IA64_DTPREL64LSB:
800eeca4
JW
3796 size = 8; bigendian = 0;
3797 break;
3798
3799 /* Unsupported / Dynamic relocations. */
800eeca4
JW
3800 default:
3801 return bfd_reloc_notsupported;
3802 }
3803
3804 switch (opnd)
3805 {
3806 case IA64_OPND_IMMU64:
3807 hit_addr -= (long) hit_addr & 0x3;
bbb268c3
JW
3808 t0 = bfd_getl64 (hit_addr);
3809 t1 = bfd_getl64 (hit_addr + 8);
800eeca4
JW
3810
3811 /* tmpl/s: bits 0.. 5 in t0
3812 slot 0: bits 5..45 in t0
3813 slot 1: bits 46..63 in t0, bits 0..22 in t1
3814 slot 2: bits 23..63 in t1 */
3815
3816 /* First, clear the bits that form the 64 bit constant. */
3817 t0 &= ~(0x3ffffLL << 46);
3818 t1 &= ~(0x7fffffLL
3819 | (( (0x07fLL << 13) | (0x1ffLL << 27)
3820 | (0x01fLL << 22) | (0x001LL << 21)
3821 | (0x001LL << 36)) << 23));
3822
3823 t0 |= ((val >> 22) & 0x03ffffLL) << 46; /* 18 lsbs of imm41 */
3824 t1 |= ((val >> 40) & 0x7fffffLL) << 0; /* 23 msbs of imm41 */
3825 t1 |= ( (((val >> 0) & 0x07f) << 13) /* imm7b */
3826 | (((val >> 7) & 0x1ff) << 27) /* imm9d */
3827 | (((val >> 16) & 0x01f) << 22) /* imm5c */
3828 | (((val >> 21) & 0x001) << 21) /* ic */
3829 | (((val >> 63) & 0x001) << 36)) << 23; /* i */
3830
bbb268c3
JW
3831 bfd_putl64 (t0, hit_addr);
3832 bfd_putl64 (t1, hit_addr + 8);
800eeca4
JW
3833 break;
3834
748abff6
RH
3835 case IA64_OPND_TGT64:
3836 hit_addr -= (long) hit_addr & 0x3;
bbb268c3
JW
3837 t0 = bfd_getl64 (hit_addr);
3838 t1 = bfd_getl64 (hit_addr + 8);
748abff6
RH
3839
3840 /* tmpl/s: bits 0.. 5 in t0
3841 slot 0: bits 5..45 in t0
3842 slot 1: bits 46..63 in t0, bits 0..22 in t1
3843 slot 2: bits 23..63 in t1 */
3844
3845 /* First, clear the bits that form the 64 bit constant. */
3846 t0 &= ~(0x3ffffLL << 46);
3847 t1 &= ~(0x7fffffLL
3848 | ((1LL << 36 | 0xfffffLL << 13) << 23));
3849
3850 val >>= 4;
3851 t0 |= ((val >> 20) & 0xffffLL) << 2 << 46; /* 16 lsbs of imm39 */
3852 t1 |= ((val >> 36) & 0x7fffffLL) << 0; /* 23 msbs of imm39 */
3853 t1 |= ((((val >> 0) & 0xfffffLL) << 13) /* imm20b */
3854 | (((val >> 59) & 0x1LL) << 36)) << 23; /* i */
3855
bbb268c3
JW
3856 bfd_putl64 (t0, hit_addr);
3857 bfd_putl64 (t1, hit_addr + 8);
748abff6
RH
3858 break;
3859
800eeca4
JW
3860 default:
3861 switch ((long) hit_addr & 0x3)
3862 {
3863 case 0: shift = 5; break;
3864 case 1: shift = 14; hit_addr += 3; break;
3865 case 2: shift = 23; hit_addr += 6; break;
3e932841 3866 case 3: return bfd_reloc_notsupported; /* shouldn't happen... */
800eeca4 3867 }
bbb268c3 3868 dword = bfd_getl64 (hit_addr);
800eeca4
JW
3869 insn = (dword >> shift) & 0x1ffffffffffLL;
3870
3871 op = elf64_ia64_operands + opnd;
b4677f03 3872 err = (*op->insert) (op, val, &insn);
800eeca4
JW
3873 if (err)
3874 return bfd_reloc_overflow;
3875
3876 dword &= ~(0x1ffffffffffLL << shift);
3877 dword |= (insn << shift);
bbb268c3 3878 bfd_putl64 (dword, hit_addr);
800eeca4
JW
3879 break;
3880
3881 case IA64_OPND_NIL:
3882 /* A data relocation. */
3883 if (bigendian)
3884 if (size == 4)
3885 bfd_putb32 (val, hit_addr);
3886 else
3887 bfd_putb64 (val, hit_addr);
3888 else
3889 if (size == 4)
3890 bfd_putl32 (val, hit_addr);
3891 else
3892 bfd_putl64 (val, hit_addr);
3893 break;
3894 }
3895
3896 return bfd_reloc_ok;
3897}
3898
3899static void
eae50df2
L
3900elfNN_ia64_install_dyn_reloc (bfd *abfd, struct bfd_link_info *info,
3901 asection *sec, asection *srel,
3902 bfd_vma offset, unsigned int type,
3903 long dynindx, bfd_vma addend)
800eeca4
JW
3904{
3905 Elf_Internal_Rela outrel;
947216bf 3906 bfd_byte *loc;
800eeca4 3907
800eeca4 3908 BFD_ASSERT (dynindx != -1);
bbe66d08 3909 outrel.r_info = ELFNN_R_INFO (dynindx, type);
800eeca4 3910 outrel.r_addend = addend;
c629eae0 3911 outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
99eb2ac8 3912 if (outrel.r_offset >= (bfd_vma) -2)
800eeca4 3913 {
c629eae0
JJ
3914 /* Run for the hills. We shouldn't be outputting a relocation
3915 for this. So do what everyone else does and output a no-op. */
3916 outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
3917 outrel.r_addend = 0;
3918 outrel.r_offset = 0;
800eeca4 3919 }
99eb2ac8
AM
3920 else
3921 outrel.r_offset += sec->output_section->vma + sec->output_offset;
800eeca4 3922
947216bf
AM
3923 loc = srel->contents;
3924 loc += srel->reloc_count++ * sizeof (ElfNN_External_Rela);
3925 bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
eea6121a 3926 BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count <= srel->size);
800eeca4
JW
3927}
3928
3929/* Store an entry for target address TARGET_ADDR in the linkage table
3930 and return the gp-relative address of the linkage table entry. */
3931
3932static bfd_vma
eae50df2
L
3933set_got_entry (bfd *abfd, struct bfd_link_info *info,
3934 struct elfNN_ia64_dyn_sym_info *dyn_i,
3935 long dynindx, bfd_vma addend, bfd_vma value,
3936 unsigned int dyn_r_type)
800eeca4 3937{
bbe66d08 3938 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4 3939 asection *got_sec;
b34976b6 3940 bfd_boolean done;
13ae64f3 3941 bfd_vma got_offset;
800eeca4 3942
bbe66d08 3943 ia64_info = elfNN_ia64_hash_table (info);
cc3bd654 3944 got_sec = ia64_info->root.sgot;
800eeca4 3945
13ae64f3 3946 switch (dyn_r_type)
800eeca4 3947 {
13ae64f3
JJ
3948 case R_IA64_TPREL64LSB:
3949 done = dyn_i->tprel_done;
b34976b6 3950 dyn_i->tprel_done = TRUE;
13ae64f3
JJ
3951 got_offset = dyn_i->tprel_offset;
3952 break;
3953 case R_IA64_DTPMOD64LSB:
b3dfd7fe
JJ
3954 if (dyn_i->dtpmod_offset != ia64_info->self_dtpmod_offset)
3955 {
3956 done = dyn_i->dtpmod_done;
3957 dyn_i->dtpmod_done = TRUE;
3958 }
3959 else
3960 {
3961 done = ia64_info->self_dtpmod_done;
3962 ia64_info->self_dtpmod_done = TRUE;
3963 dynindx = 0;
3964 }
13ae64f3
JJ
3965 got_offset = dyn_i->dtpmod_offset;
3966 break;
5a260b66 3967 case R_IA64_DTPREL32LSB:
13ae64f3
JJ
3968 case R_IA64_DTPREL64LSB:
3969 done = dyn_i->dtprel_done;
b34976b6 3970 dyn_i->dtprel_done = TRUE;
13ae64f3
JJ
3971 got_offset = dyn_i->dtprel_offset;
3972 break;
3973 default:
3974 done = dyn_i->got_done;
b34976b6 3975 dyn_i->got_done = TRUE;
13ae64f3
JJ
3976 got_offset = dyn_i->got_offset;
3977 break;
3978 }
800eeca4 3979
13ae64f3
JJ
3980 BFD_ASSERT ((got_offset & 7) == 0);
3981
3982 if (! done)
3983 {
800eeca4 3984 /* Store the target address in the linkage table entry. */
13ae64f3 3985 bfd_put_64 (abfd, value, got_sec->contents + got_offset);
800eeca4
JW
3986
3987 /* Install a dynamic relocation if needed. */
9203ba99
JJ
3988 if (((info->shared
3989 && (!dyn_i->h
3990 || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
3991 || dyn_i->h->root.type != bfd_link_hash_undefweak)
5a260b66 3992 && dyn_r_type != R_IA64_DTPREL32LSB
9203ba99 3993 && dyn_r_type != R_IA64_DTPREL64LSB)
986a241f 3994 || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info, dyn_r_type)
5a260b66
L
3995 || (dynindx != -1
3996 && (dyn_r_type == R_IA64_FPTR32LSB
3997 || dyn_r_type == R_IA64_FPTR64LSB)))
9203ba99
JJ
3998 && (!dyn_i->want_ltoff_fptr
3999 || !info->pie
4000 || !dyn_i->h
4001 || dyn_i->h->root.type != bfd_link_hash_undefweak))
800eeca4 4002 {
13ae64f3
JJ
4003 if (dynindx == -1
4004 && dyn_r_type != R_IA64_TPREL64LSB
4005 && dyn_r_type != R_IA64_DTPMOD64LSB
5a260b66 4006 && dyn_r_type != R_IA64_DTPREL32LSB
13ae64f3 4007 && dyn_r_type != R_IA64_DTPREL64LSB)
800eeca4 4008 {
5a260b66 4009 dyn_r_type = R_IA64_RELNNLSB;
800eeca4
JW
4010 dynindx = 0;
4011 addend = value;
4012 }
4013
4014 if (bfd_big_endian (abfd))
4015 {
4016 switch (dyn_r_type)
4017 {
5a260b66
L
4018 case R_IA64_REL32LSB:
4019 dyn_r_type = R_IA64_REL32MSB;
4020 break;
4021 case R_IA64_DIR32LSB:
4022 dyn_r_type = R_IA64_DIR32MSB;
4023 break;
4024 case R_IA64_FPTR32LSB:
4025 dyn_r_type = R_IA64_FPTR32MSB;
4026 break;
4027 case R_IA64_DTPREL32LSB:
4028 dyn_r_type = R_IA64_DTPREL32MSB;
4029 break;
800eeca4
JW
4030 case R_IA64_REL64LSB:
4031 dyn_r_type = R_IA64_REL64MSB;
4032 break;
4033 case R_IA64_DIR64LSB:
4034 dyn_r_type = R_IA64_DIR64MSB;
4035 break;
4036 case R_IA64_FPTR64LSB:
4037 dyn_r_type = R_IA64_FPTR64MSB;
4038 break;
13ae64f3
JJ
4039 case R_IA64_TPREL64LSB:
4040 dyn_r_type = R_IA64_TPREL64MSB;
4041 break;
4042 case R_IA64_DTPMOD64LSB:
4043 dyn_r_type = R_IA64_DTPMOD64MSB;
4044 break;
4045 case R_IA64_DTPREL64LSB:
4046 dyn_r_type = R_IA64_DTPREL64MSB;
4047 break;
800eeca4 4048 default:
b34976b6 4049 BFD_ASSERT (FALSE);
800eeca4
JW
4050 break;
4051 }
4052 }
4053
bbe66d08 4054 elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
cc3bd654 4055 ia64_info->root.srelgot,
13ae64f3 4056 got_offset, dyn_r_type,
800eeca4
JW
4057 dynindx, addend);
4058 }
4059 }
4060
4061 /* Return the address of the linkage table entry. */
4062 value = (got_sec->output_section->vma
4063 + got_sec->output_offset
13ae64f3 4064 + got_offset);
800eeca4
JW
4065
4066 return value;
4067}
4068
4069/* Fill in a function descriptor consisting of the function's code
4070 address and its global pointer. Return the descriptor's address. */
4071
4072static bfd_vma
eae50df2
L
4073set_fptr_entry (bfd *abfd, struct bfd_link_info *info,
4074 struct elfNN_ia64_dyn_sym_info *dyn_i,
4075 bfd_vma value)
800eeca4 4076{
bbe66d08 4077 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
4078 asection *fptr_sec;
4079
bbe66d08 4080 ia64_info = elfNN_ia64_hash_table (info);
800eeca4
JW
4081 fptr_sec = ia64_info->fptr_sec;
4082
4083 if (!dyn_i->fptr_done)
4084 {
4085 dyn_i->fptr_done = 1;
4086
4087 /* Fill in the function descriptor. */
4088 bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
4089 bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
4090 fptr_sec->contents + dyn_i->fptr_offset + 8);
9203ba99
JJ
4091 if (ia64_info->rel_fptr_sec)
4092 {
4093 Elf_Internal_Rela outrel;
4094 bfd_byte *loc;
4095
4096 if (bfd_little_endian (abfd))
4097 outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTLSB);
4098 else
4099 outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTMSB);
4100 outrel.r_addend = value;
4101 outrel.r_offset = (fptr_sec->output_section->vma
4102 + fptr_sec->output_offset
4103 + dyn_i->fptr_offset);
4104 loc = ia64_info->rel_fptr_sec->contents;
4105 loc += ia64_info->rel_fptr_sec->reloc_count++
4106 * sizeof (ElfNN_External_Rela);
4107 bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
4108 }
800eeca4
JW
4109 }
4110
4111 /* Return the descriptor's address. */
4112 value = (fptr_sec->output_section->vma
4113 + fptr_sec->output_offset
4114 + dyn_i->fptr_offset);
4115
4116 return value;
4117}
4118
4119/* Fill in a PLTOFF entry consisting of the function's code address
4120 and its global pointer. Return the descriptor's address. */
4121
4122static bfd_vma
eae50df2
L
4123set_pltoff_entry (bfd *abfd, struct bfd_link_info *info,
4124 struct elfNN_ia64_dyn_sym_info *dyn_i,
4125 bfd_vma value, bfd_boolean is_plt)
800eeca4 4126{
bbe66d08 4127 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
4128 asection *pltoff_sec;
4129
bbe66d08 4130 ia64_info = elfNN_ia64_hash_table (info);
800eeca4
JW
4131 pltoff_sec = ia64_info->pltoff_sec;
4132
4133 /* Don't do anything if this symbol uses a real PLT entry. In
4134 that case, we'll fill this in during finish_dynamic_symbol. */
4135 if ((! dyn_i->want_plt || is_plt)
4136 && !dyn_i->pltoff_done)
4137 {
18b27f17
RH
4138 bfd_vma gp = _bfd_get_gp_value (abfd);
4139
800eeca4
JW
4140 /* Fill in the function descriptor. */
4141 bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
18b27f17 4142 bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
800eeca4
JW
4143
4144 /* Install dynamic relocations if needed. */
ef5aade5
L
4145 if (!is_plt
4146 && info->shared
4147 && (!dyn_i->h
4148 || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
4149 || dyn_i->h->root.type != bfd_link_hash_undefweak))
800eeca4
JW
4150 {
4151 unsigned int dyn_r_type;
4152
4153 if (bfd_big_endian (abfd))
5a260b66 4154 dyn_r_type = R_IA64_RELNNMSB;
800eeca4 4155 else
5a260b66 4156 dyn_r_type = R_IA64_RELNNLSB;
800eeca4 4157
bbe66d08 4158 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
800eeca4
JW
4159 ia64_info->rel_pltoff_sec,
4160 dyn_i->pltoff_offset,
18b27f17 4161 dyn_r_type, 0, value);
bbe66d08 4162 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
800eeca4 4163 ia64_info->rel_pltoff_sec,
5a260b66 4164 dyn_i->pltoff_offset + ARCH_SIZE / 8,
18b27f17 4165 dyn_r_type, 0, gp);
800eeca4
JW
4166 }
4167
4168 dyn_i->pltoff_done = 1;
4169 }
4170
4171 /* Return the descriptor's address. */
4172 value = (pltoff_sec->output_section->vma
4173 + pltoff_sec->output_offset
4174 + dyn_i->pltoff_offset);
4175
4176 return value;
4177}
4178
13ae64f3
JJ
4179/* Return the base VMA address which should be subtracted from real addresses
4180 when resolving @tprel() relocation.
4181 Main program TLS (whose template starts at PT_TLS p_vaddr)
5a260b66 4182 is assigned offset round(2 * size of pointer, PT_TLS p_align). */
13ae64f3
JJ
4183
4184static bfd_vma
eae50df2 4185elfNN_ia64_tprel_base (struct bfd_link_info *info)
13ae64f3 4186{
e1918d23 4187 asection *tls_sec = elf_hash_table (info)->tls_sec;
5a260b66
L
4188 return tls_sec->vma - align_power ((bfd_vma) ARCH_SIZE / 4,
4189 tls_sec->alignment_power);
13ae64f3
JJ
4190}
4191
4192/* Return the base VMA address which should be subtracted from real addresses
4193 when resolving @dtprel() relocation.
4194 This is PT_TLS segment p_vaddr. */
4195
4196static bfd_vma
eae50df2 4197elfNN_ia64_dtprel_base (struct bfd_link_info *info)
13ae64f3 4198{
e1918d23 4199 return elf_hash_table (info)->tls_sec->vma;
13ae64f3
JJ
4200}
4201
f3b6f7c3 4202/* Called through qsort to sort the .IA_64.unwind section during a
bbe66d08 4203 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
f3b6f7c3
RH
4204 to the output bfd so we can do proper endianness frobbing. */
4205
bbe66d08 4206static bfd *elfNN_ia64_unwind_entry_compare_bfd;
f3b6f7c3
RH
4207
4208static int
eae50df2 4209elfNN_ia64_unwind_entry_compare (const PTR a, const PTR b)
f3b6f7c3
RH
4210{
4211 bfd_vma av, bv;
4212
bbe66d08
JW
4213 av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
4214 bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
f3b6f7c3
RH
4215
4216 return (av < bv ? -1 : av > bv ? 1 : 0);
4217}
4218
2c4c2bc0 4219/* Make sure we've got ourselves a nice fat __gp value. */
b34976b6 4220static bfd_boolean
eae50df2 4221elfNN_ia64_choose_gp (bfd *abfd, struct bfd_link_info *info)
800eeca4 4222{
2c4c2bc0
RH
4223 bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
4224 bfd_vma min_short_vma = min_vma, max_short_vma = 0;
4225 struct elf_link_hash_entry *gp;
4226 bfd_vma gp_val;
4227 asection *os;
bbe66d08 4228 struct elfNN_ia64_link_hash_table *ia64_info;
9a951beb 4229
bbe66d08 4230 ia64_info = elfNN_ia64_hash_table (info);
800eeca4 4231
2c4c2bc0
RH
4232 /* Find the min and max vma of all sections marked short. Also collect
4233 min and max vma of any type, for use in selecting a nice gp. */
4234 for (os = abfd->sections; os ; os = os->next)
800eeca4 4235 {
2c4c2bc0 4236 bfd_vma lo, hi;
800eeca4 4237
2c4c2bc0
RH
4238 if ((os->flags & SEC_ALLOC) == 0)
4239 continue;
4240
4241 lo = os->vma;
f72c3e6b 4242 hi = os->vma + (os->rawsize ? os->rawsize : os->size);
2c4c2bc0
RH
4243 if (hi < lo)
4244 hi = (bfd_vma) -1;
4245
4246 if (min_vma > lo)
4247 min_vma = lo;
4248 if (max_vma < hi)
4249 max_vma = hi;
4250 if (os->flags & SEC_SMALL_DATA)
800eeca4 4251 {
2c4c2bc0
RH
4252 if (min_short_vma > lo)
4253 min_short_vma = lo;
4254 if (max_short_vma < hi)
4255 max_short_vma = hi;
4256 }
4257 }
800eeca4 4258
2c4c2bc0
RH
4259 /* See if the user wants to force a value. */
4260 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
4261 FALSE, FALSE);
800eeca4 4262
2c4c2bc0
RH
4263 if (gp
4264 && (gp->root.type == bfd_link_hash_defined
4265 || gp->root.type == bfd_link_hash_defweak))
4266 {
4267 asection *gp_sec = gp->root.u.def.section;
4268 gp_val = (gp->root.u.def.value
4269 + gp_sec->output_section->vma
4270 + gp_sec->output_offset);
4271 }
4272 else
4273 {
4274 /* Pick a sensible value. */
800eeca4 4275
cc3bd654 4276 asection *got_sec = ia64_info->root.sgot;
2c4c2bc0
RH
4277
4278 /* Start with just the address of the .got. */
4279 if (got_sec)
4280 gp_val = got_sec->output_section->vma;
4281 else if (max_short_vma != 0)
4282 gp_val = min_short_vma;
6d2cf7d8 4283 else if (max_vma - min_vma < 0x200000)
2c4c2bc0 4284 gp_val = min_vma;
6d2cf7d8
L
4285 else
4286 gp_val = max_vma - 0x200000 + 8;
2c4c2bc0
RH
4287
4288 /* If it is possible to address the entire image, but we
4289 don't with the choice above, adjust. */
4290 if (max_vma - min_vma < 0x400000
6d2cf7d8
L
4291 && (max_vma - gp_val >= 0x200000
4292 || gp_val - min_vma > 0x200000))
2c4c2bc0
RH
4293 gp_val = min_vma + 0x200000;
4294 else if (max_short_vma != 0)
4295 {
4296 /* If we don't cover all the short data, adjust. */
4297 if (max_short_vma - gp_val >= 0x200000)
4298 gp_val = min_short_vma + 0x200000;
4299
4300 /* If we're addressing stuff past the end, adjust back. */
4301 if (gp_val > max_vma)
4302 gp_val = max_vma - 0x200000 + 8;
800eeca4 4303 }
2c4c2bc0 4304 }
800eeca4 4305
2c4c2bc0
RH
4306 /* Validate whether all SHF_IA_64_SHORT sections are within
4307 range of the chosen GP. */
800eeca4 4308
2c4c2bc0
RH
4309 if (max_short_vma != 0)
4310 {
4311 if (max_short_vma - min_short_vma >= 0x400000)
800eeca4 4312 {
2c4c2bc0
RH
4313 (*_bfd_error_handler)
4314 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
4315 bfd_get_filename (abfd),
4316 (unsigned long) (max_short_vma - min_short_vma));
4317 return FALSE;
800eeca4 4318 }
2c4c2bc0
RH
4319 else if ((gp_val > min_short_vma
4320 && gp_val - min_short_vma > 0x200000)
4321 || (gp_val < max_short_vma
4322 && max_short_vma - gp_val >= 0x200000))
800eeca4 4323 {
2c4c2bc0
RH
4324 (*_bfd_error_handler)
4325 (_("%s: __gp does not cover short data segment"),
4326 bfd_get_filename (abfd));
4327 return FALSE;
4328 }
4329 }
800eeca4 4330
2c4c2bc0 4331 _bfd_set_gp_value (abfd, gp_val);
800eeca4 4332
2c4c2bc0
RH
4333 return TRUE;
4334}
800eeca4 4335
2c4c2bc0 4336static bfd_boolean
eae50df2 4337elfNN_ia64_final_link (bfd *abfd, struct bfd_link_info *info)
2c4c2bc0
RH
4338{
4339 struct elfNN_ia64_link_hash_table *ia64_info;
4340 asection *unwind_output_sec;
800eeca4 4341
2c4c2bc0 4342 ia64_info = elfNN_ia64_hash_table (info);
800eeca4 4343
2c4c2bc0 4344 /* Make sure we've got ourselves a nice fat __gp value. */
1049f94e 4345 if (!info->relocatable)
2c4c2bc0 4346 {
a38a2e96 4347 bfd_vma gp_val;
2c4c2bc0
RH
4348 struct elf_link_hash_entry *gp;
4349
a38a2e96
L
4350 /* We assume after gp is set, section size will only decrease. We
4351 need to adjust gp for it. */
4352 _bfd_set_gp_value (abfd, 0);
4353 if (! elfNN_ia64_choose_gp (abfd, info))
4354 return FALSE;
4355 gp_val = _bfd_get_gp_value (abfd);
800eeca4 4356
2c4c2bc0
RH
4357 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
4358 FALSE, FALSE);
b4adccfd
RH
4359 if (gp)
4360 {
4361 gp->root.type = bfd_link_hash_defined;
4362 gp->root.u.def.value = gp_val;
4363 gp->root.u.def.section = bfd_abs_section_ptr;
4364 }
800eeca4
JW
4365 }
4366
f3b6f7c3 4367 /* If we're producing a final executable, we need to sort the contents
9a951beb
RH
4368 of the .IA_64.unwind section. Force this section to be relocated
4369 into memory rather than written immediately to the output file. */
4370 unwind_output_sec = NULL;
1049f94e 4371 if (!info->relocatable)
f3b6f7c3
RH
4372 {
4373 asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
4374 if (s)
4375 {
9a951beb
RH
4376 unwind_output_sec = s->output_section;
4377 unwind_output_sec->contents
eea6121a 4378 = bfd_malloc (unwind_output_sec->size);
9a951beb 4379 if (unwind_output_sec->contents == NULL)
b34976b6 4380 return FALSE;
9a951beb
RH
4381 }
4382 }
f3b6f7c3 4383
9a951beb 4384 /* Invoke the regular ELF backend linker to do all the work. */
c152c796 4385 if (!bfd_elf_final_link (abfd, info))
b34976b6 4386 return FALSE;
f3b6f7c3 4387
9a951beb
RH
4388 if (unwind_output_sec)
4389 {
4390 elfNN_ia64_unwind_entry_compare_bfd = abfd;
dc810e39 4391 qsort (unwind_output_sec->contents,
eea6121a 4392 (size_t) (unwind_output_sec->size / 24),
dc810e39
AM
4393 24,
4394 elfNN_ia64_unwind_entry_compare);
9a951beb
RH
4395
4396 if (! bfd_set_section_contents (abfd, unwind_output_sec,
dc810e39 4397 unwind_output_sec->contents, (bfd_vma) 0,
eea6121a 4398 unwind_output_sec->size))
b34976b6 4399 return FALSE;
f3b6f7c3
RH
4400 }
4401
b34976b6 4402 return TRUE;
800eeca4
JW
4403}
4404
b34976b6 4405static bfd_boolean
eae50df2
L
4406elfNN_ia64_relocate_section (bfd *output_bfd,
4407 struct bfd_link_info *info,
4408 bfd *input_bfd,
4409 asection *input_section,
4410 bfd_byte *contents,
4411 Elf_Internal_Rela *relocs,
4412 Elf_Internal_Sym *local_syms,
4413 asection **local_sections)
800eeca4 4414{
bbe66d08 4415 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
4416 Elf_Internal_Shdr *symtab_hdr;
4417 Elf_Internal_Rela *rel;
4418 Elf_Internal_Rela *relend;
4419 asection *srel;
b34976b6 4420 bfd_boolean ret_val = TRUE; /* for non-fatal errors */
800eeca4
JW
4421 bfd_vma gp_val;
4422
4423 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
bbe66d08 4424 ia64_info = elfNN_ia64_hash_table (info);
800eeca4
JW
4425
4426 /* Infect various flags from the input section to the output section. */
1049f94e 4427 if (info->relocatable)
800eeca4
JW
4428 {
4429 bfd_vma flags;
4430
4431 flags = elf_section_data(input_section)->this_hdr.sh_flags;
4432 flags &= SHF_IA_64_NORECOV;
4433
4434 elf_section_data(input_section->output_section)
4435 ->this_hdr.sh_flags |= flags;
4436 }
4437
4438 gp_val = _bfd_get_gp_value (output_bfd);
b34976b6 4439 srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
800eeca4
JW
4440
4441 rel = relocs;
4442 relend = relocs + input_section->reloc_count;
4443 for (; rel < relend; ++rel)
4444 {
4445 struct elf_link_hash_entry *h;
bbe66d08 4446 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4
JW
4447 bfd_reloc_status_type r;
4448 reloc_howto_type *howto;
4449 unsigned long r_symndx;
4450 Elf_Internal_Sym *sym;
4451 unsigned int r_type;
4452 bfd_vma value;
4453 asection *sym_sec;
4454 bfd_byte *hit_addr;
b34976b6
AM
4455 bfd_boolean dynamic_symbol_p;
4456 bfd_boolean undef_weak_ref;
800eeca4 4457
bbe66d08 4458 r_type = ELFNN_R_TYPE (rel->r_info);
800eeca4
JW
4459 if (r_type > R_IA64_MAX_RELOC_CODE)
4460 {
4461 (*_bfd_error_handler)
d003868e
AM
4462 (_("%B: unknown relocation type %d"),
4463 input_bfd, (int) r_type);
800eeca4 4464 bfd_set_error (bfd_error_bad_value);
b34976b6 4465 ret_val = FALSE;
800eeca4
JW
4466 continue;
4467 }
b491616a 4468
800eeca4 4469 howto = lookup_howto (r_type);
bbe66d08 4470 r_symndx = ELFNN_R_SYM (rel->r_info);
800eeca4
JW
4471 h = NULL;
4472 sym = NULL;
4473 sym_sec = NULL;
b34976b6 4474 undef_weak_ref = FALSE;
800eeca4
JW
4475
4476 if (r_symndx < symtab_hdr->sh_info)
4477 {
4478 /* Reloc against local symbol. */
8517fae7 4479 asection *msec;
800eeca4
JW
4480 sym = local_syms + r_symndx;
4481 sym_sec = local_sections[r_symndx];
8517fae7
AM
4482 msec = sym_sec;
4483 value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
ab96bf03
AM
4484 if (!info->relocatable
4485 && (sym_sec->flags & SEC_MERGE) != 0
f7460f5f 4486 && ELF_ST_TYPE (sym->st_info) == STT_SECTION
68bfbfcc 4487 && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
f7460f5f
JJ
4488 {
4489 struct elfNN_ia64_local_hash_entry *loc_h;
b34976b6
AM
4490
4491 loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
f7460f5f
JJ
4492 if (loc_h && ! loc_h->sec_merge_done)
4493 {
4494 struct elfNN_ia64_dyn_sym_info *dynent;
396a682d 4495 unsigned int count;
f7460f5f 4496
396a682d
L
4497 for (count = loc_h->count, dynent = loc_h->info;
4498 count != 0;
4499 count--, dynent++)
f7460f5f
JJ
4500 {
4501 msec = sym_sec;
4502 dynent->addend =
4503 _bfd_merged_section_offset (output_bfd, &msec,
4504 elf_section_data (msec)->
65765700 4505 sec_info,
f7460f5f 4506 sym->st_value
753731ee 4507 + dynent->addend);
f7460f5f
JJ
4508 dynent->addend -= sym->st_value;
4509 dynent->addend += msec->output_section->vma
4510 + msec->output_offset
4511 - sym_sec->output_section->vma
4512 - sym_sec->output_offset;
4513 }
293a0124
L
4514
4515 /* We may have introduced duplicated entries. We need
4516 to remove them properly. */
4517 count = sort_dyn_sym_info (loc_h->info, loc_h->count);
4518 if (count != loc_h->count)
4519 {
4520 loc_h->count = count;
4521 loc_h->sorted_count = count;
4522 }
396a682d 4523
f7460f5f
JJ
4524 loc_h->sec_merge_done = 1;
4525 }
4526 }
800eeca4
JW
4527 }
4528 else
4529 {
560e09e9
NC
4530 bfd_boolean unresolved_reloc;
4531 bfd_boolean warned;
b2a8e766 4532 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
800eeca4 4533
b2a8e766
AM
4534 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
4535 r_symndx, symtab_hdr, sym_hashes,
4536 h, sym_sec, value,
4537 unresolved_reloc, warned);
800eeca4 4538
560e09e9 4539 if (h->root.type == bfd_link_hash_undefweak)
b34976b6 4540 undef_weak_ref = TRUE;
560e09e9
NC
4541 else if (warned)
4542 continue;
800eeca4
JW
4543 }
4544
ab96bf03
AM
4545 /* For relocs against symbols from removed linkonce sections,
4546 or sections discarded by a linker script, we just want the
4547 section contents zeroed. Avoid any special processing. */
4548 if (sym_sec != NULL && elf_discarded_section (sym_sec))
4549 {
4550 _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
4551 rel->r_info = 0;
4552 rel->r_addend = 0;
4553 continue;
4554 }
4555
4556 if (info->relocatable)
4557 continue;
4558
800eeca4
JW
4559 hit_addr = contents + rel->r_offset;
4560 value += rel->r_addend;
986a241f 4561 dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type);
800eeca4
JW
4562
4563 switch (r_type)
4564 {
4565 case R_IA64_NONE:
4566 case R_IA64_LDXMOV:
4567 continue;
4568
4569 case R_IA64_IMM14:
4570 case R_IA64_IMM22:
4571 case R_IA64_IMM64:
4572 case R_IA64_DIR32MSB:
4573 case R_IA64_DIR32LSB:
4574 case R_IA64_DIR64MSB:
4575 case R_IA64_DIR64LSB:
4576 /* Install a dynamic relocation for this reloc. */
02e6ad56 4577 if ((dynamic_symbol_p || info->shared)
ec338859 4578 && r_symndx != 0
800eeca4
JW
4579 && (input_section->flags & SEC_ALLOC) != 0)
4580 {
4581 unsigned int dyn_r_type;
4582 long dynindx;
18b27f17 4583 bfd_vma addend;
800eeca4
JW
4584
4585 BFD_ASSERT (srel != NULL);
4586
838e70c5
L
4587 switch (r_type)
4588 {
4589 case R_IA64_IMM14:
4590 case R_IA64_IMM22:
4591 case R_IA64_IMM64:
4592 /* ??? People shouldn't be doing non-pic code in
4593 shared libraries nor dynamic executables. */
4594 (*_bfd_error_handler)
d003868e
AM
4595 (_("%B: non-pic code with imm relocation against dynamic symbol `%s'"),
4596 input_bfd,
26c61ae5
L
4597 h ? h->root.root.string
4598 : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4599 sym_sec));
838e70c5
L
4600 ret_val = FALSE;
4601 continue;
4602
4603 default:
4604 break;
4605 }
4606
800eeca4
JW
4607 /* If we don't need dynamic symbol lookup, find a
4608 matching RELATIVE relocation. */
4609 dyn_r_type = r_type;
986a241f 4610 if (dynamic_symbol_p)
18b27f17
RH
4611 {
4612 dynindx = h->dynindx;
4613 addend = rel->r_addend;
4614 value = 0;
4615 }
800eeca4
JW
4616 else
4617 {
4618 switch (r_type)
4619 {
4620 case R_IA64_DIR32MSB:
4621 dyn_r_type = R_IA64_REL32MSB;
4622 break;
4623 case R_IA64_DIR32LSB:
4624 dyn_r_type = R_IA64_REL32LSB;
4625 break;
4626 case R_IA64_DIR64MSB:
4627 dyn_r_type = R_IA64_REL64MSB;
4628 break;
4629 case R_IA64_DIR64LSB:
4630 dyn_r_type = R_IA64_REL64LSB;
4631 break;
4632
4633 default:
838e70c5 4634 break;
800eeca4
JW
4635 }
4636 dynindx = 0;
18b27f17 4637 addend = value;
800eeca4
JW
4638 }
4639
bbe66d08 4640 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
800eeca4 4641 srel, rel->r_offset, dyn_r_type,
18b27f17 4642 dynindx, addend);
800eeca4 4643 }
ae9a127f 4644 /* Fall through. */
800eeca4
JW
4645
4646 case R_IA64_LTV32MSB:
4647 case R_IA64_LTV32LSB:
4648 case R_IA64_LTV64MSB:
4649 case R_IA64_LTV64LSB:
bbb268c3 4650 r = elfNN_ia64_install_value (hit_addr, value, r_type);
800eeca4
JW
4651 break;
4652
4653 case R_IA64_GPREL22:
4654 case R_IA64_GPREL64I:
4655 case R_IA64_GPREL32MSB:
4656 case R_IA64_GPREL32LSB:
4657 case R_IA64_GPREL64MSB:
4658 case R_IA64_GPREL64LSB:
4659 if (dynamic_symbol_p)
4660 {
4661 (*_bfd_error_handler)
d003868e 4662 (_("%B: @gprel relocation against dynamic symbol %s"),
26c61ae5
L
4663 input_bfd,
4664 h ? h->root.root.string
4665 : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4666 sym_sec));
b34976b6 4667 ret_val = FALSE;
800eeca4
JW
4668 continue;
4669 }
4670 value -= gp_val;
bbb268c3 4671 r = elfNN_ia64_install_value (hit_addr, value, r_type);
800eeca4
JW
4672 break;
4673
4674 case R_IA64_LTOFF22:
4675 case R_IA64_LTOFF22X:
4676 case R_IA64_LTOFF64I:
b34976b6 4677 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
800eeca4 4678 value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
5a260b66 4679 rel->r_addend, value, R_IA64_DIRNNLSB);
800eeca4 4680 value -= gp_val;
bbb268c3 4681 r = elfNN_ia64_install_value (hit_addr, value, r_type);
800eeca4
JW
4682 break;
4683
4684 case R_IA64_PLTOFF22:
4685 case R_IA64_PLTOFF64I:
4686 case R_IA64_PLTOFF64MSB:
4687 case R_IA64_PLTOFF64LSB:
b34976b6
AM
4688 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4689 value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
800eeca4 4690 value -= gp_val;
bbb268c3 4691 r = elfNN_ia64_install_value (hit_addr, value, r_type);
800eeca4
JW
4692 break;
4693
4694 case R_IA64_FPTR64I:
4695 case R_IA64_FPTR32MSB:
4696 case R_IA64_FPTR32LSB:
4697 case R_IA64_FPTR64MSB:
4698 case R_IA64_FPTR64LSB:
b34976b6 4699 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
800eeca4
JW
4700 if (dyn_i->want_fptr)
4701 {
4702 if (!undef_weak_ref)
4703 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4704 }
9203ba99 4705 if (!dyn_i->want_fptr || info->pie)
800eeca4
JW
4706 {
4707 long dynindx;
9203ba99
JJ
4708 unsigned int dyn_r_type = r_type;
4709 bfd_vma addend = rel->r_addend;
800eeca4
JW
4710
4711 /* Otherwise, we expect the dynamic linker to create
4712 the entry. */
4713
9203ba99
JJ
4714 if (dyn_i->want_fptr)
4715 {
4716 if (r_type == R_IA64_FPTR64I)
4717 {
4718 /* We can't represent this without a dynamic symbol.
4719 Adjust the relocation to be against an output
4720 section symbol, which are always present in the
4721 dynamic symbol table. */
4722 /* ??? People shouldn't be doing non-pic code in
4723 shared libraries. Hork. */
4724 (*_bfd_error_handler)
d003868e
AM
4725 (_("%B: linking non-pic code in a position independent executable"),
4726 input_bfd);
9203ba99
JJ
4727 ret_val = FALSE;
4728 continue;
4729 }
4730 dynindx = 0;
4731 addend = value;
5a260b66 4732 dyn_r_type = r_type + R_IA64_RELNNLSB - R_IA64_FPTRNNLSB;
9203ba99
JJ
4733 }
4734 else if (h)
800eeca4
JW
4735 {
4736 if (h->dynindx != -1)
4737 dynindx = h->dynindx;
4738 else
4739 dynindx = (_bfd_elf_link_lookup_local_dynindx
4740 (info, h->root.u.def.section->owner,
4741 global_sym_index (h)));
9203ba99 4742 value = 0;
800eeca4
JW
4743 }
4744 else
4745 {
4746 dynindx = (_bfd_elf_link_lookup_local_dynindx
dc810e39 4747 (info, input_bfd, (long) r_symndx));
9203ba99 4748 value = 0;
800eeca4
JW
4749 }
4750
bbe66d08 4751 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
9203ba99
JJ
4752 srel, rel->r_offset, dyn_r_type,
4753 dynindx, addend);
800eeca4
JW
4754 }
4755
bbb268c3 4756 r = elfNN_ia64_install_value (hit_addr, value, r_type);
800eeca4
JW
4757 break;
4758
4759 case R_IA64_LTOFF_FPTR22:
4760 case R_IA64_LTOFF_FPTR64I:
a4bd8390
JW
4761 case R_IA64_LTOFF_FPTR32MSB:
4762 case R_IA64_LTOFF_FPTR32LSB:
800eeca4
JW
4763 case R_IA64_LTOFF_FPTR64MSB:
4764 case R_IA64_LTOFF_FPTR64LSB:
4765 {
4766 long dynindx;
4767
b34976b6 4768 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
800eeca4
JW
4769 if (dyn_i->want_fptr)
4770 {
f12123c0 4771 BFD_ASSERT (h == NULL || h->dynindx == -1);
800eeca4
JW
4772 if (!undef_weak_ref)
4773 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4774 dynindx = -1;
4775 }
4776 else
4777 {
4778 /* Otherwise, we expect the dynamic linker to create
4779 the entry. */
4780 if (h)
4781 {
4782 if (h->dynindx != -1)
4783 dynindx = h->dynindx;
4784 else
4785 dynindx = (_bfd_elf_link_lookup_local_dynindx
4786 (info, h->root.u.def.section->owner,
4787 global_sym_index (h)));
4788 }
4789 else
4790 dynindx = (_bfd_elf_link_lookup_local_dynindx
dc810e39 4791 (info, input_bfd, (long) r_symndx));
800eeca4
JW
4792 value = 0;
4793 }
4794
4795 value = set_got_entry (output_bfd, info, dyn_i, dynindx,
5a260b66 4796 rel->r_addend, value, R_IA64_FPTRNNLSB);
800eeca4 4797 value -= gp_val;
bbb268c3 4798 r = elfNN_ia64_install_value (hit_addr, value, r_type);
800eeca4
JW
4799 }
4800 break;
4801
4802 case R_IA64_PCREL32MSB:
4803 case R_IA64_PCREL32LSB:
4804 case R_IA64_PCREL64MSB:
4805 case R_IA64_PCREL64LSB:
4806 /* Install a dynamic relocation for this reloc. */
02e6ad56 4807 if (dynamic_symbol_p && r_symndx != 0)
800eeca4
JW
4808 {
4809 BFD_ASSERT (srel != NULL);
4810
bbe66d08 4811 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
800eeca4
JW
4812 srel, rel->r_offset, r_type,
4813 h->dynindx, rel->r_addend);
4814 }
4815 goto finish_pcrel;
4816
800eeca4 4817 case R_IA64_PCREL21B:
748abff6 4818 case R_IA64_PCREL60B:
800eeca4 4819 /* We should have created a PLT entry for any dynamic symbol. */
800eeca4
JW
4820 dyn_i = NULL;
4821 if (h)
b34976b6 4822 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
800eeca4
JW
4823
4824 if (dyn_i && dyn_i->want_plt2)
4825 {
4826 /* Should have caught this earlier. */
4827 BFD_ASSERT (rel->r_addend == 0);
4828
cc3bd654
L
4829 value = (ia64_info->root.splt->output_section->vma
4830 + ia64_info->root.splt->output_offset
800eeca4
JW
4831 + dyn_i->plt2_offset);
4832 }
4833 else
4834 {
4835 /* Since there's no PLT entry, Validate that this is
4836 locally defined. */
4837 BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
4838
4839 /* If the symbol is undef_weak, we shouldn't be trying
4840 to call it. There's every chance that we'd wind up
4841 with an out-of-range fixup here. Don't bother setting
4842 any value at all. */
4843 if (undef_weak_ref)
4844 continue;
4845 }
4846 goto finish_pcrel;
4847
2f9bd3f6
RH
4848 case R_IA64_PCREL21BI:
4849 case R_IA64_PCREL21F:
4850 case R_IA64_PCREL21M:
748abff6
RH
4851 case R_IA64_PCREL22:
4852 case R_IA64_PCREL64I:
2f9bd3f6
RH
4853 /* The PCREL21BI reloc is specifically not intended for use with
4854 dynamic relocs. PCREL21F and PCREL21M are used for speculation
f12123c0 4855 fixup code, and thus probably ought not be dynamic. The
2f9bd3f6
RH
4856 PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
4857 if (dynamic_symbol_p)
4858 {
4859 const char *msg;
4860
4861 if (r_type == R_IA64_PCREL21BI)
d003868e 4862 msg = _("%B: @internal branch to dynamic symbol %s");
2f9bd3f6 4863 else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
d003868e 4864 msg = _("%B: speculation fixup to dynamic symbol %s");
2f9bd3f6 4865 else
d003868e 4866 msg = _("%B: @pcrel relocation against dynamic symbol %s");
26c61ae5
L
4867 (*_bfd_error_handler) (msg, input_bfd,
4868 h ? h->root.root.string
4869 : bfd_elf_sym_name (input_bfd,
4870 symtab_hdr,
4871 sym,
4872 sym_sec));
2f9bd3f6
RH
4873 ret_val = FALSE;
4874 continue;
4875 }
4876 goto finish_pcrel;
4877
800eeca4
JW
4878 finish_pcrel:
4879 /* Make pc-relative. */
4880 value -= (input_section->output_section->vma
4881 + input_section->output_offset
4882 + rel->r_offset) & ~ (bfd_vma) 0x3;
bbb268c3 4883 r = elfNN_ia64_install_value (hit_addr, value, r_type);
800eeca4
JW
4884 break;
4885
4886 case R_IA64_SEGREL32MSB:
4887 case R_IA64_SEGREL32LSB:
4888 case R_IA64_SEGREL64MSB:
4889 case R_IA64_SEGREL64LSB:
d7458677 4890 {
d7458677 4891 /* Find the segment that contains the output_section. */
2ea37f1c 4892 Elf_Internal_Phdr *p = _bfd_elf_find_segment_containing_section
992824d5 4893 (output_bfd, input_section->output_section);
800eeca4 4894
2ea37f1c 4895 if (p == NULL)
d7458677 4896 {
800eeca4 4897 r = bfd_reloc_notsupported;
d7458677
AM
4898 }
4899 else
4900 {
4901 /* The VMA of the segment is the vaddr of the associated
4902 program header. */
4903 if (value > p->p_vaddr)
4904 value -= p->p_vaddr;
4905 else
4906 value = 0;
bbb268c3 4907 r = elfNN_ia64_install_value (hit_addr, value, r_type);
d7458677
AM
4908 }
4909 break;
4910 }
800eeca4
JW
4911
4912 case R_IA64_SECREL32MSB:
4913 case R_IA64_SECREL32LSB:
4914 case R_IA64_SECREL64MSB:
4915 case R_IA64_SECREL64LSB:
97ecf322
L
4916 /* Make output-section relative to section where the symbol
4917 is defined. PR 475 */
bf718458
L
4918 if (sym_sec)
4919 value -= sym_sec->output_section->vma;
bbb268c3 4920 r = elfNN_ia64_install_value (hit_addr, value, r_type);
800eeca4
JW
4921 break;
4922
800eeca4
JW
4923 case R_IA64_IPLTMSB:
4924 case R_IA64_IPLTLSB:
18b27f17
RH
4925 /* Install a dynamic relocation for this reloc. */
4926 if ((dynamic_symbol_p || info->shared)
4927 && (input_section->flags & SEC_ALLOC) != 0)
4928 {
18b27f17
RH
4929 BFD_ASSERT (srel != NULL);
4930
4931 /* If we don't need dynamic symbol lookup, install two
4932 RELATIVE relocations. */
986a241f 4933 if (!dynamic_symbol_p)
18b27f17
RH
4934 {
4935 unsigned int dyn_r_type;
3e932841 4936
18b27f17
RH
4937 if (r_type == R_IA64_IPLTMSB)
4938 dyn_r_type = R_IA64_REL64MSB;
4939 else
4940 dyn_r_type = R_IA64_REL64LSB;
4941
4942 elfNN_ia64_install_dyn_reloc (output_bfd, info,
4943 input_section,
4944 srel, rel->r_offset,
4945 dyn_r_type, 0, value);
4946 elfNN_ia64_install_dyn_reloc (output_bfd, info,
4947 input_section,
4948 srel, rel->r_offset + 8,
4949 dyn_r_type, 0, gp_val);
4950 }
4951 else
4952 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4953 srel, rel->r_offset, r_type,
4954 h->dynindx, rel->r_addend);
4955 }
4956
4957 if (r_type == R_IA64_IPLTMSB)
4958 r_type = R_IA64_DIR64MSB;
4959 else
4960 r_type = R_IA64_DIR64LSB;
bbb268c3
JW
4961 elfNN_ia64_install_value (hit_addr, value, r_type);
4962 r = elfNN_ia64_install_value (hit_addr + 8, gp_val, r_type);
18b27f17 4963 break;
800eeca4 4964
13ae64f3
JJ
4965 case R_IA64_TPREL14:
4966 case R_IA64_TPREL22:
4967 case R_IA64_TPREL64I:
0f2830ff
L
4968 if (elf_hash_table (info)->tls_sec == NULL)
4969 goto missing_tls_sec;
13ae64f3 4970 value -= elfNN_ia64_tprel_base (info);
bbb268c3 4971 r = elfNN_ia64_install_value (hit_addr, value, r_type);
13ae64f3
JJ
4972 break;
4973
4974 case R_IA64_DTPREL14:
4975 case R_IA64_DTPREL22:
4976 case R_IA64_DTPREL64I:
5a260b66
L
4977 case R_IA64_DTPREL32LSB:
4978 case R_IA64_DTPREL32MSB:
b3dfd7fe
JJ
4979 case R_IA64_DTPREL64LSB:
4980 case R_IA64_DTPREL64MSB:
0f2830ff
L
4981 if (elf_hash_table (info)->tls_sec == NULL)
4982 goto missing_tls_sec;
13ae64f3 4983 value -= elfNN_ia64_dtprel_base (info);
bbb268c3 4984 r = elfNN_ia64_install_value (hit_addr, value, r_type);
13ae64f3
JJ
4985 break;
4986
4987 case R_IA64_LTOFF_TPREL22:
4988 case R_IA64_LTOFF_DTPMOD22:
4989 case R_IA64_LTOFF_DTPREL22:
4990 {
4991 int got_r_type;
a823975a
JJ
4992 long dynindx = h ? h->dynindx : -1;
4993 bfd_vma r_addend = rel->r_addend;
13ae64f3
JJ
4994
4995 switch (r_type)
4996 {
4997 default:
4998 case R_IA64_LTOFF_TPREL22:
a823975a
JJ
4999 if (!dynamic_symbol_p)
5000 {
0f2830ff
L
5001 if (elf_hash_table (info)->tls_sec == NULL)
5002 goto missing_tls_sec;
a823975a
JJ
5003 if (!info->shared)
5004 value -= elfNN_ia64_tprel_base (info);
5005 else
5006 {
5007 r_addend += value - elfNN_ia64_dtprel_base (info);
5008 dynindx = 0;
5009 }
5010 }
13ae64f3
JJ
5011 got_r_type = R_IA64_TPREL64LSB;
5012 break;
5013 case R_IA64_LTOFF_DTPMOD22:
5014 if (!dynamic_symbol_p && !info->shared)
5015 value = 1;
5016 got_r_type = R_IA64_DTPMOD64LSB;
5017 break;
5018 case R_IA64_LTOFF_DTPREL22:
5019 if (!dynamic_symbol_p)
0f2830ff
L
5020 {
5021 if (elf_hash_table (info)->tls_sec == NULL)
5022 goto missing_tls_sec;
5023 value -= elfNN_ia64_dtprel_base (info);
5024 }
5a260b66 5025 got_r_type = R_IA64_DTPRELNNLSB;
13ae64f3
JJ
5026 break;
5027 }
b34976b6 5028 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
a823975a 5029 value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
13ae64f3
JJ
5030 value, got_r_type);
5031 value -= gp_val;
bbb268c3 5032 r = elfNN_ia64_install_value (hit_addr, value, r_type);
13ae64f3
JJ
5033 }
5034 break;
5035
800eeca4
JW
5036 default:
5037 r = bfd_reloc_notsupported;
5038 break;
5039 }
5040
5041 switch (r)
5042 {
5043 case bfd_reloc_ok:
5044 break;
5045
5046 case bfd_reloc_undefined:
5047 /* This can happen for global table relative relocs if
5048 __gp is undefined. This is a panic situation so we
5049 don't try to continue. */
5050 (*info->callbacks->undefined_symbol)
5051 (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
b34976b6 5052 return FALSE;
800eeca4
JW
5053
5054 case bfd_reloc_notsupported:
5055 {
5056 const char *name;
5057
5058 if (h)
5059 name = h->root.root.string;
5060 else
26c61ae5
L
5061 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
5062 sym_sec);
800eeca4
JW
5063 if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
5064 name, input_bfd,
5065 input_section, rel->r_offset))
b34976b6
AM
5066 return FALSE;
5067 ret_val = FALSE;
800eeca4
JW
5068 }
5069 break;
5070
5071 case bfd_reloc_dangerous:
5072 case bfd_reloc_outofrange:
5073 case bfd_reloc_overflow:
5074 default:
0f2830ff 5075missing_tls_sec:
800eeca4
JW
5076 {
5077 const char *name;
5078
5079 if (h)
f0581930 5080 name = h->root.root.string;
800eeca4 5081 else
26c61ae5
L
5082 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
5083 sym_sec);
c5509b92
L
5084
5085 switch (r_type)
5086 {
0f2830ff
L
5087 case R_IA64_TPREL14:
5088 case R_IA64_TPREL22:
5089 case R_IA64_TPREL64I:
5090 case R_IA64_DTPREL14:
5091 case R_IA64_DTPREL22:
5092 case R_IA64_DTPREL64I:
5093 case R_IA64_DTPREL32LSB:
5094 case R_IA64_DTPREL32MSB:
5095 case R_IA64_DTPREL64LSB:
5096 case R_IA64_DTPREL64MSB:
5097 case R_IA64_LTOFF_TPREL22:
5098 case R_IA64_LTOFF_DTPMOD22:
5099 case R_IA64_LTOFF_DTPREL22:
5100 (*_bfd_error_handler)
5101 (_("%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `%A'."),
5102 input_bfd, input_section, howto->name, name,
5103 rel->r_offset);
5104 break;
5105
c5509b92
L
5106 case R_IA64_PCREL21B:
5107 case R_IA64_PCREL21BI:
5108 case R_IA64_PCREL21M:
5109 case R_IA64_PCREL21F:
5110 if (is_elf_hash_table (info->hash))
5111 {
5112 /* Relaxtion is always performed for ELF output.
5113 Overflow failures for those relocations mean
5114 that the section is too big to relax. */
5115 (*_bfd_error_handler)
5116 (_("%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."),
5117 input_bfd, input_section, howto->name, name,
5118 rel->r_offset, input_section->size);
5119 break;
5120 }
5121 default:
5122 if (!(*info->callbacks->reloc_overflow) (info,
5123 &h->root,
5124 name,
5125 howto->name,
5126 (bfd_vma) 0,
5127 input_bfd,
5128 input_section,
5129 rel->r_offset))
5130 return FALSE;
5131 break;
5132 }
5133
b34976b6 5134 ret_val = FALSE;
800eeca4
JW
5135 }
5136 break;
5137 }
5138 }
5139
5140 return ret_val;
5141}
5142
b34976b6 5143static bfd_boolean
eae50df2
L
5144elfNN_ia64_finish_dynamic_symbol (bfd *output_bfd,
5145 struct bfd_link_info *info,
5146 struct elf_link_hash_entry *h,
5147 Elf_Internal_Sym *sym)
800eeca4 5148{
bbe66d08
JW
5149 struct elfNN_ia64_link_hash_table *ia64_info;
5150 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4 5151
bbe66d08 5152 ia64_info = elfNN_ia64_hash_table (info);
b34976b6 5153 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
800eeca4
JW
5154
5155 /* Fill in the PLT data, if required. */
5156 if (dyn_i && dyn_i->want_plt)
5157 {
5158 Elf_Internal_Rela outrel;
5159 bfd_byte *loc;
5160 asection *plt_sec;
5161 bfd_vma plt_addr, pltoff_addr, gp_val, index;
800eeca4
JW
5162
5163 gp_val = _bfd_get_gp_value (output_bfd);
5164
5165 /* Initialize the minimal PLT entry. */
5166
5167 index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
cc3bd654 5168 plt_sec = ia64_info->root.splt;
800eeca4
JW
5169 loc = plt_sec->contents + dyn_i->plt_offset;
5170
5171 memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
bbb268c3
JW
5172 elfNN_ia64_install_value (loc, index, R_IA64_IMM22);
5173 elfNN_ia64_install_value (loc+2, -dyn_i->plt_offset, R_IA64_PCREL21B);
800eeca4
JW
5174
5175 plt_addr = (plt_sec->output_section->vma
5176 + plt_sec->output_offset
5177 + dyn_i->plt_offset);
b34976b6 5178 pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
800eeca4
JW
5179
5180 /* Initialize the FULL PLT entry, if needed. */
5181 if (dyn_i->want_plt2)
5182 {
5183 loc = plt_sec->contents + dyn_i->plt2_offset;
5184
5185 memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
bbb268c3 5186 elfNN_ia64_install_value (loc, pltoff_addr - gp_val, R_IA64_IMM22);
800eeca4
JW
5187
5188 /* Mark the symbol as undefined, rather than as defined in the
5189 plt section. Leave the value alone. */
5190 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
c152c796 5191 first place. But perhaps elflink.c did some for us. */
f5385ebf 5192 if (!h->def_regular)
800eeca4
JW
5193 sym->st_shndx = SHN_UNDEF;
5194 }
5195
5196 /* Create the dynamic relocation. */
5197 outrel.r_offset = pltoff_addr;
5198 if (bfd_little_endian (output_bfd))
bbe66d08 5199 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
800eeca4 5200 else
bbe66d08 5201 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
800eeca4
JW
5202 outrel.r_addend = 0;
5203
5204 /* This is fun. In the .IA_64.pltoff section, we've got entries
5205 that correspond both to real PLT entries, and those that
5206 happened to resolve to local symbols but need to be created
5207 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
5208 relocations for the real PLT should come at the end of the
5209 section, so that they can be indexed by plt entry at runtime.
5210
5211 We emitted all of the relocations for the non-PLT @pltoff
5212 entries during relocate_section. So we can consider the
5213 existing sec->reloc_count to be the base of the array of
5214 PLT relocations. */
5215
947216bf
AM
5216 loc = ia64_info->rel_pltoff_sec->contents;
5217 loc += ((ia64_info->rel_pltoff_sec->reloc_count + index)
37cd2629 5218 * sizeof (ElfNN_External_Rela));
947216bf 5219 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
800eeca4
JW
5220 }
5221
5222 /* Mark some specially defined symbols as absolute. */
5223 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
22edb2f1
RS
5224 || h == ia64_info->root.hgot
5225 || h == ia64_info->root.hplt)
800eeca4
JW
5226 sym->st_shndx = SHN_ABS;
5227
b34976b6 5228 return TRUE;
800eeca4
JW
5229}
5230
b34976b6 5231static bfd_boolean
eae50df2
L
5232elfNN_ia64_finish_dynamic_sections (bfd *abfd,
5233 struct bfd_link_info *info)
800eeca4 5234{
bbe66d08 5235 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
5236 bfd *dynobj;
5237
bbe66d08 5238 ia64_info = elfNN_ia64_hash_table (info);
800eeca4
JW
5239 dynobj = ia64_info->root.dynobj;
5240
5241 if (elf_hash_table (info)->dynamic_sections_created)
5242 {
bbe66d08 5243 ElfNN_External_Dyn *dyncon, *dynconend;
800eeca4
JW
5244 asection *sdyn, *sgotplt;
5245 bfd_vma gp_val;
5246
5247 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
5248 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
5249 BFD_ASSERT (sdyn != NULL);
bbe66d08 5250 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
eea6121a 5251 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
800eeca4
JW
5252
5253 gp_val = _bfd_get_gp_value (abfd);
5254
5255 for (; dyncon < dynconend; dyncon++)
5256 {
5257 Elf_Internal_Dyn dyn;
800eeca4 5258
bbe66d08 5259 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
800eeca4
JW
5260
5261 switch (dyn.d_tag)
5262 {
5263 case DT_PLTGOT:
5264 dyn.d_un.d_ptr = gp_val;
5265 break;
5266
5267 case DT_PLTRELSZ:
5268 dyn.d_un.d_val = (ia64_info->minplt_entries
bbe66d08 5269 * sizeof (ElfNN_External_Rela));
800eeca4
JW
5270 break;
5271
5272 case DT_JMPREL:
5273 /* See the comment above in finish_dynamic_symbol. */
5274 dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
5275 + ia64_info->rel_pltoff_sec->output_offset
5276 + (ia64_info->rel_pltoff_sec->reloc_count
bbe66d08 5277 * sizeof (ElfNN_External_Rela)));
800eeca4
JW
5278 break;
5279
5280 case DT_IA_64_PLT_RESERVE:
5281 dyn.d_un.d_ptr = (sgotplt->output_section->vma
5282 + sgotplt->output_offset);
5283 break;
5284
5285 case DT_RELASZ:
5286 /* Do not have RELASZ include JMPREL. This makes things
3e932841 5287 easier on ld.so. This is not what the rest of BFD set up. */
800eeca4 5288 dyn.d_un.d_val -= (ia64_info->minplt_entries
bbe66d08 5289 * sizeof (ElfNN_External_Rela));
800eeca4 5290 break;
800eeca4
JW
5291 }
5292
bbe66d08 5293 bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
800eeca4
JW
5294 }
5295
ae9a127f 5296 /* Initialize the PLT0 entry. */
cc3bd654 5297 if (ia64_info->root.splt)
800eeca4 5298 {
cc3bd654 5299 bfd_byte *loc = ia64_info->root.splt->contents;
800eeca4
JW
5300 bfd_vma pltres;
5301
5302 memcpy (loc, plt_header, PLT_HEADER_SIZE);
5303
5304 pltres = (sgotplt->output_section->vma
5305 + sgotplt->output_offset
5306 - gp_val);
5307
bbb268c3 5308 elfNN_ia64_install_value (loc+1, pltres, R_IA64_GPREL22);
800eeca4
JW
5309 }
5310 }
5311
b34976b6 5312 return TRUE;
800eeca4
JW
5313}
5314\f
ae9a127f 5315/* ELF file flag handling: */
800eeca4 5316
3e932841 5317/* Function to keep IA-64 specific file flags. */
b34976b6 5318static bfd_boolean
eae50df2 5319elfNN_ia64_set_private_flags (bfd *abfd, flagword flags)
800eeca4
JW
5320{
5321 BFD_ASSERT (!elf_flags_init (abfd)
5322 || elf_elfheader (abfd)->e_flags == flags);
5323
5324 elf_elfheader (abfd)->e_flags = flags;
b34976b6
AM
5325 elf_flags_init (abfd) = TRUE;
5326 return TRUE;
800eeca4
JW
5327}
5328
800eeca4
JW
5329/* Merge backend specific data from an object file to the output
5330 object file when linking. */
b34976b6 5331static bfd_boolean
eae50df2 5332elfNN_ia64_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
800eeca4
JW
5333{
5334 flagword out_flags;
5335 flagword in_flags;
b34976b6 5336 bfd_boolean ok = TRUE;
800eeca4
JW
5337
5338 /* Don't even pretend to support mixed-format linking. */
5339 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
5340 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
b34976b6 5341 return FALSE;
800eeca4
JW
5342
5343 in_flags = elf_elfheader (ibfd)->e_flags;
5344 out_flags = elf_elfheader (obfd)->e_flags;
5345
5346 if (! elf_flags_init (obfd))
5347 {
b34976b6 5348 elf_flags_init (obfd) = TRUE;
800eeca4
JW
5349 elf_elfheader (obfd)->e_flags = in_flags;
5350
5351 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
5352 && bfd_get_arch_info (obfd)->the_default)
5353 {
5354 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
5355 bfd_get_mach (ibfd));
5356 }
5357
b34976b6 5358 return TRUE;
800eeca4
JW
5359 }
5360
5361 /* Check flag compatibility. */
5362 if (in_flags == out_flags)
b34976b6 5363 return TRUE;
800eeca4 5364
c43c2cc5
JW
5365 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
5366 if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
5367 elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
5368
800eeca4
JW
5369 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
5370 {
5371 (*_bfd_error_handler)
d003868e
AM
5372 (_("%B: linking trap-on-NULL-dereference with non-trapping files"),
5373 ibfd);
800eeca4
JW
5374
5375 bfd_set_error (bfd_error_bad_value);
b34976b6 5376 ok = FALSE;
800eeca4
JW
5377 }
5378 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
5379 {
5380 (*_bfd_error_handler)
d003868e
AM
5381 (_("%B: linking big-endian files with little-endian files"),
5382 ibfd);
800eeca4
JW
5383
5384 bfd_set_error (bfd_error_bad_value);
b34976b6 5385 ok = FALSE;
800eeca4
JW
5386 }
5387 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
5388 {
5389 (*_bfd_error_handler)
d003868e
AM
5390 (_("%B: linking 64-bit files with 32-bit files"),
5391 ibfd);
800eeca4
JW
5392
5393 bfd_set_error (bfd_error_bad_value);
b34976b6 5394 ok = FALSE;
800eeca4 5395 }
c43c2cc5
JW
5396 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
5397 {
5398 (*_bfd_error_handler)
d003868e
AM
5399 (_("%B: linking constant-gp files with non-constant-gp files"),
5400 ibfd);
c43c2cc5
JW
5401
5402 bfd_set_error (bfd_error_bad_value);
b34976b6 5403 ok = FALSE;
c43c2cc5
JW
5404 }
5405 if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
5406 != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
5407 {
5408 (*_bfd_error_handler)
d003868e
AM
5409 (_("%B: linking auto-pic files with non-auto-pic files"),
5410 ibfd);
c43c2cc5
JW
5411
5412 bfd_set_error (bfd_error_bad_value);
b34976b6 5413 ok = FALSE;
c43c2cc5 5414 }
800eeca4
JW
5415
5416 return ok;
5417}
5418
b34976b6 5419static bfd_boolean
eae50df2 5420elfNN_ia64_print_private_bfd_data (bfd *abfd, PTR ptr)
800eeca4
JW
5421{
5422 FILE *file = (FILE *) ptr;
5423 flagword flags = elf_elfheader (abfd)->e_flags;
5424
5425 BFD_ASSERT (abfd != NULL && ptr != NULL);
5426
c43c2cc5 5427 fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
800eeca4
JW
5428 (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
5429 (flags & EF_IA_64_EXT) ? "EXT, " : "",
5430 (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
c43c2cc5
JW
5431 (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
5432 (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
5433 (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
5434 (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
800eeca4 5435 (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
3e932841 5436
800eeca4 5437 _bfd_elf_print_private_bfd_data (abfd, ptr);
b34976b6 5438 return TRUE;
800eeca4 5439}
db6751f2
JJ
5440
5441static enum elf_reloc_type_class
eae50df2 5442elfNN_ia64_reloc_type_class (const Elf_Internal_Rela *rela)
db6751f2 5443{
f51e552e 5444 switch ((int) ELFNN_R_TYPE (rela->r_info))
db6751f2
JJ
5445 {
5446 case R_IA64_REL32MSB:
5447 case R_IA64_REL32LSB:
5448 case R_IA64_REL64MSB:
5449 case R_IA64_REL64LSB:
5450 return reloc_class_relative;
5451 case R_IA64_IPLTMSB:
5452 case R_IA64_IPLTLSB:
5453 return reloc_class_plt;
5454 case R_IA64_COPY:
5455 return reloc_class_copy;
5456 default:
5457 return reloc_class_normal;
5458 }
5459}
fcf12726 5460
b35d266b 5461static const struct bfd_elf_special_section elfNN_ia64_special_sections[] =
2f89ff8d 5462{
0112cd26
NC
5463 { STRING_COMMA_LEN (".sbss"), -1, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
5464 { STRING_COMMA_LEN (".sdata"), -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
5465 { NULL, 0, 0, 0, 0 }
7f4d3958
L
5466};
5467
da9f89d4
L
5468static bfd_boolean
5469elfNN_ia64_object_p (bfd *abfd)
5470{
5471 asection *sec;
da9f89d4
L
5472 asection *group, *unwi, *unw;
5473 flagword flags;
5474 const char *name;
5475 char *unwi_name, *unw_name;
5476 bfd_size_type amt;
5477
5478 if (abfd->flags & DYNAMIC)
5479 return TRUE;
5480
5481 /* Flags for fake group section. */
5482 flags = (SEC_LINKER_CREATED | SEC_GROUP | SEC_LINK_ONCE
5483 | SEC_EXCLUDE);
5484
5485 /* We add a fake section group for each .gnu.linkonce.t.* section,
5486 which isn't in a section group, and its unwind sections. */
5487 for (sec = abfd->sections; sec != NULL; sec = sec->next)
5488 {
5489 if (elf_sec_group (sec) == NULL
5490 && ((sec->flags & (SEC_LINK_ONCE | SEC_CODE | SEC_GROUP))
5491 == (SEC_LINK_ONCE | SEC_CODE))
0112cd26 5492 && CONST_STRNEQ (sec->name, ".gnu.linkonce.t."))
da9f89d4
L
5493 {
5494 name = sec->name + 16;
5495
5496 amt = strlen (name) + sizeof (".gnu.linkonce.ia64unwi.");
5497 unwi_name = bfd_alloc (abfd, amt);
5498 if (!unwi_name)
5499 return FALSE;
5500
5501 strcpy (stpcpy (unwi_name, ".gnu.linkonce.ia64unwi."), name);
5502 unwi = bfd_get_section_by_name (abfd, unwi_name);
5503
5504 amt = strlen (name) + sizeof (".gnu.linkonce.ia64unw.");
5505 unw_name = bfd_alloc (abfd, amt);
5506 if (!unw_name)
5507 return FALSE;
5508
5509 strcpy (stpcpy (unw_name, ".gnu.linkonce.ia64unw."), name);
5510 unw = bfd_get_section_by_name (abfd, unw_name);
5511
da9f89d4
L
5512 /* We need to create a fake group section for it and its
5513 unwind sections. */
3496cb2a
L
5514 group = bfd_make_section_anyway_with_flags (abfd, name,
5515 flags);
5516 if (group == NULL)
da9f89d4
L
5517 return FALSE;
5518
5519 /* Move the fake group section to the beginning. */
5daa8fe7 5520 bfd_section_list_remove (abfd, group);
04dd1667 5521 bfd_section_list_prepend (abfd, group);
da9f89d4
L
5522
5523 elf_next_in_group (group) = sec;
5524
5525 elf_group_name (sec) = name;
5526 elf_next_in_group (sec) = sec;
5527 elf_sec_group (sec) = group;
5528
5529 if (unwi)
5530 {
5531 elf_group_name (unwi) = name;
5532 elf_next_in_group (unwi) = sec;
5533 elf_next_in_group (sec) = unwi;
5534 elf_sec_group (unwi) = group;
5535 }
5536
5537 if (unw)
5538 {
5539 elf_group_name (unw) = name;
5540 if (unwi)
5541 {
5542 elf_next_in_group (unw) = elf_next_in_group (unwi);
5543 elf_next_in_group (unwi) = unw;
5544 }
5545 else
5546 {
5547 elf_next_in_group (unw) = sec;
5548 elf_next_in_group (sec) = unw;
5549 }
5550 elf_sec_group (unw) = group;
5551 }
5552
5553 /* Fake SHT_GROUP section header. */
5554 elf_section_data (group)->this_hdr.bfd_section = group;
5555 elf_section_data (group)->this_hdr.sh_type = SHT_GROUP;
5556 }
5557 }
5558 return TRUE;
5559}
5560
b34976b6 5561static bfd_boolean
d9cf1b54
AM
5562elfNN_ia64_hpux_vec (const bfd_target *vec)
5563{
5564 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
5565 return (vec == & bfd_elfNN_ia64_hpux_big_vec);
5566}
5567
fcf12726 5568static void
eae50df2
L
5569elfNN_hpux_post_process_headers (bfd *abfd,
5570 struct bfd_link_info *info ATTRIBUTE_UNUSED)
fcf12726
AM
5571{
5572 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
5573
d1036acb 5574 i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
fcf12726
AM
5575 i_ehdrp->e_ident[EI_ABIVERSION] = 1;
5576}
d9cf1b54 5577
eae50df2
L
5578static bfd_boolean
5579elfNN_hpux_backend_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
5580 asection *sec, int *retval)
d9cf1b54
AM
5581{
5582 if (bfd_is_com_section (sec))
5583 {
5584 *retval = SHN_IA_64_ANSI_COMMON;
b34976b6 5585 return TRUE;
d9cf1b54 5586 }
b34976b6 5587 return FALSE;
d9cf1b54 5588}
b59dd4a5
L
5589
5590static void
5591elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
5592 asymbol *asym)
5593{
5f1cb353 5594 elf_symbol_type *elfsym = (elf_symbol_type *) asym;
b59dd4a5
L
5595
5596 switch (elfsym->internal_elf_sym.st_shndx)
5597 {
5598 case SHN_IA_64_ANSI_COMMON:
5599 asym->section = bfd_com_section_ptr;
5600 asym->value = elfsym->internal_elf_sym.st_size;
5601 asym->flags &= ~BSF_GLOBAL;
5602 break;
5603 }
5604}
5605
01e1a5bc
NC
5606static bfd_boolean
5607elfNN_vms_section_from_shdr (bfd *abfd,
5608 Elf_Internal_Shdr *hdr,
5609 const char *name,
5610 int shindex)
5611{
5612 asection *newsect;
5613
5614 switch (hdr->sh_type)
5615 {
5616 case SHT_IA_64_VMS_TRACE:
5617 case SHT_IA_64_VMS_DEBUG:
5618 case SHT_IA_64_VMS_DEBUG_STR:
5619 break;
5620
5621 default:
5622 return elfNN_ia64_section_from_shdr (abfd, hdr, name, shindex);
5623 }
5624
5625 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
5626 return FALSE;
5627 newsect = hdr->bfd_section;
5628
5629 return TRUE;
5630}
5631
5632static bfd_boolean
5633elfNN_vms_object_p (bfd *abfd)
5634{
5635 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
5636 Elf_Internal_Phdr *i_phdr = elf_tdata (abfd)->phdr;
5637 unsigned int i;
5638 unsigned int num_text = 0;
5639 unsigned int num_data = 0;
5640 unsigned int num_rodata = 0;
5641 char name[16];
5642
5643 if (!elfNN_ia64_object_p (abfd))
5644 return FALSE;
5645
5646 for (i = 0; i < i_ehdrp->e_phnum; i++, i_phdr++)
5647 {
5648 /* Is there a section for this segment? */
5649 bfd_vma base_vma = i_phdr->p_vaddr;
5650 bfd_vma limit_vma = base_vma + i_phdr->p_filesz;
5651
5652 if (i_phdr->p_type != PT_LOAD)
5653 continue;
5654
5655 again:
5656 while (base_vma < limit_vma)
5657 {
5658 bfd_vma next_vma = limit_vma;
5659 asection *nsec;
5660 asection *sec;
5661 flagword flags;
5662 char *nname = NULL;
5663
5664 /* Find a section covering base_vma. */
5665 for (sec = abfd->sections; sec != NULL; sec = sec->next)
5666 {
5667 if ((sec->flags & (SEC_ALLOC | SEC_LOAD)) == 0)
5668 continue;
5669 if (sec->vma <= base_vma && sec->vma + sec->size > base_vma)
5670 {
5671 base_vma = sec->vma + sec->size;
5672 goto again;
5673 }
5674 if (sec->vma < next_vma && sec->vma + sec->size >= base_vma)
5675 next_vma = sec->vma;
5676 }
5677
5678 /* No section covering [base_vma; next_vma). Create a fake one. */
5679 flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
5680 if (i_phdr->p_flags & PF_X)
5681 {
5682 flags |= SEC_CODE;
5683 if (num_text++ == 0)
5684 nname = ".text";
5685 else
5686 sprintf (name, ".text$%u", num_text);
5687 }
5688 else if ((i_phdr->p_flags & (PF_R | PF_W)) == PF_R)
5689 {
5690 flags |= SEC_READONLY;
5691 sprintf (name, ".rodata$%u", num_rodata++);
5692 }
5693 else
5694 {
5695 flags |= SEC_DATA;
5696 sprintf (name, ".data$%u", num_data++);
5697 }
5698
5699 /* Allocate name. */
5700 if (nname == NULL)
5701 {
5702 size_t name_len = strlen (name) + 1;
5703 nname = bfd_alloc (abfd, name_len);
5704 if (nname == NULL)
5705 return FALSE;
5706 memcpy (nname, name, name_len);
5707 }
5708
5709 /* Create and fill new section. */
5710 nsec = bfd_make_section_anyway_with_flags (abfd, nname, flags);
5711 if (nsec == NULL)
5712 return FALSE;
5713 nsec->vma = base_vma;
5714 nsec->size = next_vma - base_vma;
5715 nsec->filepos = i_phdr->p_offset + (base_vma - i_phdr->p_vaddr);
5716
5717 base_vma = next_vma;
5718 }
5719 }
5720 return TRUE;
5721}
5722
5723static void
5724elfNN_vms_post_process_headers (bfd *abfd,
5725 struct bfd_link_info *info ATTRIBUTE_UNUSED)
5726{
5727 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
5728
5729 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_OPENVMS;
5730 i_ehdrp->e_ident[EI_ABIVERSION] = 2;
5731}
5732
5733static bfd_boolean
5734elfNN_vms_section_processing (bfd *abfd ATTRIBUTE_UNUSED,
5735 Elf_Internal_Shdr *hdr)
5736{
5737 if (hdr->bfd_section != NULL)
5738 {
5739 const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
5740
5741 if (strcmp (name, ".text") == 0)
5742 hdr->sh_flags |= SHF_IA_64_VMS_SHARED;
5743 else if ((strcmp (name, ".debug") == 0)
5744 || (strcmp (name, ".debug_abbrev") == 0)
5745 || (strcmp (name, ".debug_aranges") == 0)
5746 || (strcmp (name, ".debug_frame") == 0)
5747 || (strcmp (name, ".debug_info") == 0)
5748 || (strcmp (name, ".debug_loc") == 0)
5749 || (strcmp (name, ".debug_macinfo") == 0)
5750 || (strcmp (name, ".debug_pubnames") == 0)
5751 || (strcmp (name, ".debug_pubtypes") == 0))
5752 hdr->sh_type = SHT_IA_64_VMS_DEBUG;
5753 else if ((strcmp (name, ".debug_line") == 0)
5754 || (strcmp (name, ".debug_ranges") == 0))
5755 hdr->sh_type = SHT_IA_64_VMS_TRACE;
5756 else if (strcmp (name, ".debug_str") == 0)
5757 hdr->sh_type = SHT_IA_64_VMS_DEBUG_STR;
5758 else if (strcmp (name, ".vms_display_name_info") == 0)
5759 {
5760 int idx, symcount;
5761 asymbol **syms;
5762 struct elf_obj_tdata *t = elf_tdata (abfd);
5763 int buf[2];
5764 int demangler_sym_idx = -1;
5765
5766 symcount = bfd_get_symcount (abfd);
5767 syms = bfd_get_outsymbols (abfd);
5768 for (idx = 0; idx < symcount; idx++)
5769 {
5770 asymbol *sym;
5771 sym = syms[idx];
5772 if ((sym->flags & (BSF_DEBUGGING | BSF_DYNAMIC))
5773 && strchr (sym->name, '@')
5774 && (strcmp (sym->section->name, BFD_ABS_SECTION_NAME) == 0))
5775 {
5776 demangler_sym_idx = sym->udata.i;
5777 break;
5778 }
5779 }
5780
5781 hdr->sh_type = SHT_IA_64_VMS_DISPLAY_NAME_INFO;
5782 hdr->sh_entsize = 4;
5783 hdr->sh_addralign = 0;
5784 hdr->sh_link = t->symtab_section;
5785
5786 /* Find symtab index of demangler routine and stuff it in
5787 the second long word of section data. */
5788
5789 if (demangler_sym_idx > -1)
5790 {
5791 bfd_seek (abfd, hdr->sh_offset, SEEK_SET);
5792 bfd_bread (buf, hdr->sh_size, abfd);
5793 buf [1] = demangler_sym_idx;
5794 bfd_seek (abfd, hdr->sh_offset, SEEK_SET);
5795 bfd_bwrite (buf, hdr->sh_size, abfd);
5796 }
5797 }
5798 }
5799
5800 return TRUE;
5801}
5802
5803/* The final processing done just before writing out a VMS IA-64 ELF
5804 object file. */
5805
5806static void
5807elfNN_vms_final_write_processing (bfd *abfd,
5808 bfd_boolean linker ATTRIBUTE_UNUSED)
5809{
5810 Elf_Internal_Shdr *hdr;
5811 asection *s;
5812 int unwind_info_sect_idx = 0;
5813
5814 for (s = abfd->sections; s; s = s->next)
5815 {
5816 hdr = &elf_section_data (s)->this_hdr;
5817
5818 if (strcmp (bfd_get_section_name (abfd, hdr->bfd_section),
5819 ".IA_64.unwind_info") == 0)
5820 unwind_info_sect_idx = elf_section_data (s)->this_idx;
5821
5822 switch (hdr->sh_type)
5823 {
5824 case SHT_IA_64_UNWIND:
5825 /* VMS requires sh_info to point to the unwind info section. */
5826 hdr->sh_info = unwind_info_sect_idx;
5827 break;
5828 }
5829 }
5830
5831 if (! elf_flags_init (abfd))
5832 {
5833 unsigned long flags = 0;
5834
5835 if (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
5836 flags |= EF_IA_64_BE;
5837 if (bfd_get_mach (abfd) == bfd_mach_ia64_elf64)
5838 flags |= EF_IA_64_ABI64;
5839
5840 elf_elfheader(abfd)->e_flags = flags;
5841 elf_flags_init (abfd) = TRUE;
5842 }
5843}
5844
5845static bfd_boolean
5846elfNN_vms_close_and_cleanup (bfd *abfd)
5847{
5848 if (bfd_get_format (abfd) == bfd_object)
5849 {
5850 long isize, irsize;
5851
5852 if (elf_shstrtab (abfd) != NULL)
5853 _bfd_elf_strtab_free (elf_shstrtab (abfd));
5854
5855 /* Pad to 8 byte boundary for IPF/VMS. */
5856 isize = bfd_get_size (abfd);
5857 if ((irsize = isize/8*8) < isize)
5858 {
5859 int ishort = (irsize + 8) - isize;
5860 bfd_seek (abfd, isize, SEEK_SET);
5861 bfd_bwrite (bfd_zmalloc (ishort), ishort, abfd);
5862 }
5863 }
5864
5865 return _bfd_generic_close_and_cleanup (abfd);
5866}
800eeca4 5867\f
bbe66d08
JW
5868#define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
5869#define TARGET_LITTLE_NAME "elfNN-ia64-little"
5870#define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
5871#define TARGET_BIG_NAME "elfNN-ia64-big"
800eeca4
JW
5872#define ELF_ARCH bfd_arch_ia64
5873#define ELF_MACHINE_CODE EM_IA_64
5874#define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
5875#define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
5876#define ELF_MAXPAGESIZE 0x10000 /* 64KB */
24718e3b 5877#define ELF_COMMONPAGESIZE 0x4000 /* 16KB */
800eeca4
JW
5878
5879#define elf_backend_section_from_shdr \
bbe66d08 5880 elfNN_ia64_section_from_shdr
fa152c49 5881#define elf_backend_section_flags \
bbe66d08 5882 elfNN_ia64_section_flags
800eeca4 5883#define elf_backend_fake_sections \
bbe66d08 5884 elfNN_ia64_fake_sections
81545d45
RH
5885#define elf_backend_final_write_processing \
5886 elfNN_ia64_final_write_processing
800eeca4 5887#define elf_backend_add_symbol_hook \
bbe66d08 5888 elfNN_ia64_add_symbol_hook
800eeca4 5889#define elf_backend_additional_program_headers \
bbe66d08 5890 elfNN_ia64_additional_program_headers
800eeca4 5891#define elf_backend_modify_segment_map \
bbe66d08 5892 elfNN_ia64_modify_segment_map
e36284ab
AM
5893#define elf_backend_modify_program_headers \
5894 elfNN_ia64_modify_program_headers
800eeca4 5895#define elf_info_to_howto \
bbe66d08 5896 elfNN_ia64_info_to_howto
800eeca4 5897
bbe66d08
JW
5898#define bfd_elfNN_bfd_reloc_type_lookup \
5899 elfNN_ia64_reloc_type_lookup
157090f7
AM
5900#define bfd_elfNN_bfd_reloc_name_lookup \
5901 elfNN_ia64_reloc_name_lookup
bbe66d08
JW
5902#define bfd_elfNN_bfd_is_local_label_name \
5903 elfNN_ia64_is_local_label_name
5904#define bfd_elfNN_bfd_relax_section \
5905 elfNN_ia64_relax_section
800eeca4 5906
da9f89d4
L
5907#define elf_backend_object_p \
5908 elfNN_ia64_object_p
5909
800eeca4 5910/* Stuff for the BFD linker: */
bbe66d08
JW
5911#define bfd_elfNN_bfd_link_hash_table_create \
5912 elfNN_ia64_hash_table_create
0aa92b58
JJ
5913#define bfd_elfNN_bfd_link_hash_table_free \
5914 elfNN_ia64_hash_table_free
800eeca4 5915#define elf_backend_create_dynamic_sections \
bbe66d08 5916 elfNN_ia64_create_dynamic_sections
800eeca4 5917#define elf_backend_check_relocs \
bbe66d08 5918 elfNN_ia64_check_relocs
800eeca4 5919#define elf_backend_adjust_dynamic_symbol \
bbe66d08 5920 elfNN_ia64_adjust_dynamic_symbol
800eeca4 5921#define elf_backend_size_dynamic_sections \
bbe66d08 5922 elfNN_ia64_size_dynamic_sections
74541ad4
AM
5923#define elf_backend_omit_section_dynsym \
5924 ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
800eeca4 5925#define elf_backend_relocate_section \
bbe66d08 5926 elfNN_ia64_relocate_section
800eeca4 5927#define elf_backend_finish_dynamic_symbol \
bbe66d08 5928 elfNN_ia64_finish_dynamic_symbol
800eeca4 5929#define elf_backend_finish_dynamic_sections \
bbe66d08
JW
5930 elfNN_ia64_finish_dynamic_sections
5931#define bfd_elfNN_bfd_final_link \
5932 elfNN_ia64_final_link
5933
bbe66d08
JW
5934#define bfd_elfNN_bfd_merge_private_bfd_data \
5935 elfNN_ia64_merge_private_bfd_data
5936#define bfd_elfNN_bfd_set_private_flags \
5937 elfNN_ia64_set_private_flags
5938#define bfd_elfNN_bfd_print_private_bfd_data \
5939 elfNN_ia64_print_private_bfd_data
800eeca4
JW
5940
5941#define elf_backend_plt_readonly 1
5942#define elf_backend_want_plt_sym 0
5943#define elf_backend_plt_alignment 5
5944#define elf_backend_got_header_size 0
800eeca4
JW
5945#define elf_backend_want_got_plt 1
5946#define elf_backend_may_use_rel_p 1
5947#define elf_backend_may_use_rela_p 1
5948#define elf_backend_default_use_rela_p 1
5949#define elf_backend_want_dynbss 0
bbe66d08
JW
5950#define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
5951#define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
508c3946 5952#define elf_backend_fixup_symbol _bfd_elf_link_hash_fixup_symbol
db6751f2 5953#define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
b491616a 5954#define elf_backend_rela_normal 1
29ef7005 5955#define elf_backend_special_sections elfNN_ia64_special_sections
d4d2b80b 5956#define elf_backend_default_execstack 0
800eeca4 5957
185d09ad 5958/* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
e04bcc6d 5959 SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
185d09ad
L
5960 We don't want to flood users with so many error messages. We turn
5961 off the warning for now. It will be turned on later when the Intel
5962 compiler is fixed. */
5963#define elf_backend_link_order_error_handler NULL
5964
bbe66d08 5965#include "elfNN-target.h"
7b6dab7f 5966
fcf12726
AM
5967/* HPUX-specific vectors. */
5968
5969#undef TARGET_LITTLE_SYM
5970#undef TARGET_LITTLE_NAME
5971#undef TARGET_BIG_SYM
5972#define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
5973#undef TARGET_BIG_NAME
5974#define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
5975
254ed743
NC
5976/* These are HP-UX specific functions. */
5977
fcf12726
AM
5978#undef elf_backend_post_process_headers
5979#define elf_backend_post_process_headers elfNN_hpux_post_process_headers
5980
d9cf1b54
AM
5981#undef elf_backend_section_from_bfd_section
5982#define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
5983
b59dd4a5
L
5984#undef elf_backend_symbol_processing
5985#define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
5986
5e8d7549
NC
5987#undef elf_backend_want_p_paddr_set_to_zero
5988#define elf_backend_want_p_paddr_set_to_zero 1
5989
24718e3b 5990#undef ELF_COMMONPAGESIZE
d1036acb
L
5991#undef ELF_OSABI
5992#define ELF_OSABI ELFOSABI_HPUX
fcf12726
AM
5993
5994#undef elfNN_bed
5995#define elfNN_bed elfNN_ia64_hpux_bed
5996
5997#include "elfNN-target.h"
5e8d7549 5998
01e1a5bc
NC
5999/* VMS-specific vectors. */
6000
6001#undef TARGET_LITTLE_SYM
6002#define TARGET_LITTLE_SYM bfd_elfNN_ia64_vms_vec
6003#undef TARGET_LITTLE_NAME
6004#define TARGET_LITTLE_NAME "elfNN-ia64-vms"
6005#undef TARGET_BIG_SYM
6006#undef TARGET_BIG_NAME
6007
6008/* These are VMS specific functions. */
6009
6010#undef elf_backend_object_p
6011#define elf_backend_object_p elfNN_vms_object_p
6012
6013#undef elf_backend_section_from_shdr
6014#define elf_backend_section_from_shdr elfNN_vms_section_from_shdr
6015
6016#undef elf_backend_post_process_headers
6017#define elf_backend_post_process_headers elfNN_vms_post_process_headers
6018
6019#undef elf_backend_section_processing
6020#define elf_backend_section_processing elfNN_vms_section_processing
6021
6022#undef elf_backend_final_write_processing
6023#define elf_backend_final_write_processing elfNN_vms_final_write_processing
6024
6025#undef bfd_elfNN_close_and_cleanup
6026#define bfd_elfNN_close_and_cleanup elfNN_vms_close_and_cleanup
6027
6028#undef elf_backend_section_from_bfd_section
6029
6030#undef elf_backend_symbol_processing
6031
5e8d7549 6032#undef elf_backend_want_p_paddr_set_to_zero
01e1a5bc
NC
6033
6034#undef ELF_MAXPAGESIZE
6035#define ELF_MAXPAGESIZE 0x10000 /* 64KB */
6036
6037#undef elfNN_bed
6038#define elfNN_bed elfNN_ia64_vms_bed
6039
6040#include "elfNN-target.h"
This page took 0.925414 seconds and 4 git commands to generate.