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