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