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