]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/elfxx-ia64.c
* bfd-in.h (bfd_get_section_limit): Don't use rawsize with output
[thirdparty/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,
e57278ef 3 2008, 2009, 2010, 2011 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"
6f8027ae 31#include "bfd_stdint.h"
800eeca4 32
5a260b66
L
33#define ARCH_SIZE NN
34
35#if ARCH_SIZE == 64
36#define LOG_SECTION_ALIGN 3
37#endif
38
39#if ARCH_SIZE == 32
40#define LOG_SECTION_ALIGN 2
41#endif
42
5e8d7549 43/* THE RULES for all the stuff the linker creates --
b34976b6 44
5e8d7549
NC
45 GOT Entries created in response to LTOFF or LTOFF_FPTR
46 relocations. Dynamic relocs created for dynamic
47 symbols in an application; REL relocs for locals
48 in a shared library.
b34976b6 49
5e8d7549
NC
50 FPTR The canonical function descriptor. Created for local
51 symbols in applications. Descriptors for dynamic symbols
52 and local symbols in shared libraries are created by
53 ld.so. Thus there are no dynamic relocs against these
54 objects. The FPTR relocs for such _are_ passed through
55 to the dynamic relocation tables.
b34976b6 56
5e8d7549
NC
57 FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
58 Requires the creation of a PLTOFF entry. This does not
59 require any dynamic relocations.
b34976b6 60
5e8d7549
NC
61 PLTOFF Created by PLTOFF relocations. For local symbols, this
62 is an alternate function descriptor, and in shared libraries
63 requires two REL relocations. Note that this cannot be
64 transformed into an FPTR relocation, since it must be in
65 range of the GP. For dynamic symbols, this is a function
66 descriptor for a MIN_PLT entry, and requires one IPLT reloc.
b34976b6 67
5e8d7549 68 MIN_PLT Created by PLTOFF entries against dynamic symbols. This
4cc11e76 69 does not require dynamic relocations. */
800eeca4 70
7256a114
TG
71/* Only add code for vms when the vms target is enabled. This is required
72 because it depends on vms-lib.c for its archive format and we don't want
73 to compile that code if it is not used. */
74#if ARCH_SIZE == 64 && \
75 (defined (HAVE_bfd_elf64_ia64_vms_vec) || defined (HAVE_all_vecs))
76#define INCLUDE_IA64_VMS
77#endif
78
79
800eeca4
JW
80#define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
81
82typedef struct bfd_hash_entry *(*new_hash_entry_func)
4dfe6ac6 83 (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
800eeca4
JW
84
85/* In dynamically (linker-) created sections, we generally need to keep track
86 of the place a symbol or expression got allocated to. This is done via hash
87 tables that store entries of the following type. */
88
bbe66d08 89struct elfNN_ia64_dyn_sym_info
800eeca4
JW
90{
91 /* The addend for which this entry is relevant. */
92 bfd_vma addend;
93
800eeca4
JW
94 bfd_vma got_offset;
95 bfd_vma fptr_offset;
96 bfd_vma pltoff_offset;
97 bfd_vma plt_offset;
98 bfd_vma plt2_offset;
13ae64f3
JJ
99 bfd_vma tprel_offset;
100 bfd_vma dtpmod_offset;
101 bfd_vma dtprel_offset;
800eeca4 102
4cc11e76 103 /* The symbol table entry, if any, that this was derived from. */
800eeca4 104 struct elf_link_hash_entry *h;
3e932841 105
800eeca4
JW
106 /* Used to count non-got, non-plt relocations for delayed sizing
107 of relocation sections. */
bbe66d08 108 struct elfNN_ia64_dyn_reloc_entry
800eeca4 109 {
bbe66d08 110 struct elfNN_ia64_dyn_reloc_entry *next;
800eeca4
JW
111 asection *srel;
112 int type;
113 int count;
ac33696c
L
114
115 /* Is this reloc against readonly section? */
116 bfd_boolean reltext;
800eeca4
JW
117 } *reloc_entries;
118
b34976b6 119 /* TRUE when the section contents have been updated. */
800eeca4
JW
120 unsigned got_done : 1;
121 unsigned fptr_done : 1;
122 unsigned pltoff_done : 1;
13ae64f3
JJ
123 unsigned tprel_done : 1;
124 unsigned dtpmod_done : 1;
125 unsigned dtprel_done : 1;
800eeca4 126
b34976b6 127 /* TRUE for the different kinds of linker data we want created. */
800eeca4 128 unsigned want_got : 1;
2c4c2bc0 129 unsigned want_gotx : 1;
800eeca4
JW
130 unsigned want_fptr : 1;
131 unsigned want_ltoff_fptr : 1;
132 unsigned want_plt : 1;
133 unsigned want_plt2 : 1;
134 unsigned want_pltoff : 1;
13ae64f3
JJ
135 unsigned want_tprel : 1;
136 unsigned want_dtpmod : 1;
137 unsigned want_dtprel : 1;
800eeca4
JW
138};
139
bbe66d08 140struct elfNN_ia64_local_hash_entry
800eeca4 141{
0aa92b58
JJ
142 int id;
143 unsigned int r_sym;
396a682d
L
144 /* The number of elements in elfNN_ia64_dyn_sym_info array. */
145 unsigned int count;
146 /* The number of sorted elements in elfNN_ia64_dyn_sym_info array. */
147 unsigned int sorted_count;
148 /* The size of elfNN_ia64_dyn_sym_info array. */
149 unsigned int size;
150 /* The array of elfNN_ia64_dyn_sym_info. */
bbe66d08 151 struct elfNN_ia64_dyn_sym_info *info;
f7460f5f 152
b34976b6 153 /* TRUE if this hash entry's addends was translated for
f7460f5f
JJ
154 SHF_MERGE optimization. */
155 unsigned sec_merge_done : 1;
800eeca4
JW
156};
157
bbe66d08 158struct elfNN_ia64_link_hash_entry
800eeca4
JW
159{
160 struct elf_link_hash_entry root;
396a682d
L
161 /* The number of elements in elfNN_ia64_dyn_sym_info array. */
162 unsigned int count;
163 /* The number of sorted elements in elfNN_ia64_dyn_sym_info array. */
164 unsigned int sorted_count;
165 /* The size of elfNN_ia64_dyn_sym_info array. */
166 unsigned int size;
167 /* The array of elfNN_ia64_dyn_sym_info. */
bbe66d08 168 struct elfNN_ia64_dyn_sym_info *info;
800eeca4
JW
169};
170
bbe66d08 171struct elfNN_ia64_link_hash_table
800eeca4 172{
5e8d7549 173 /* The main hash table. */
800eeca4
JW
174 struct elf_link_hash_table root;
175
4dfe6ac6
NC
176 asection *fptr_sec; /* Function descriptor table (or NULL). */
177 asection *rel_fptr_sec; /* Dynamic relocation section for same. */
178 asection *pltoff_sec; /* Private descriptors for plt (or NULL). */
179 asection *rel_pltoff_sec; /* Dynamic relocation section for same. */
800eeca4 180
4dfe6ac6
NC
181 bfd_size_type minplt_entries; /* Number of minplt entries. */
182 unsigned reltext : 1; /* Are there relocs against readonly sections? */
183 unsigned self_dtpmod_done : 1;/* Has self DTPMOD entry been finished? */
184 bfd_vma self_dtpmod_offset; /* .got offset to self DTPMOD entry. */
a231ddc0
L
185 /* There are maybe R_IA64_GPREL22 relocations, including those
186 optimized from R_IA64_LTOFF22X, against non-SHF_IA_64_SHORT
187 sections. We need to record those sections so that we can choose
188 a proper GP to cover all R_IA64_GPREL22 relocations. */
4dfe6ac6
NC
189 asection *max_short_sec; /* Maximum short output section. */
190 bfd_vma max_short_offset; /* Maximum short offset. */
191 asection *min_short_sec; /* Minimum short output section. */
192 bfd_vma min_short_offset; /* Minimum short offset. */
800eeca4 193
0aa92b58
JJ
194 htab_t loc_hash_table;
195 void *loc_hash_memory;
800eeca4
JW
196};
197
2c4c2bc0
RH
198struct elfNN_ia64_allocate_data
199{
200 struct bfd_link_info *info;
201 bfd_size_type ofs;
4a78a1f4 202 bfd_boolean only_got;
2c4c2bc0
RH
203};
204
bbe66d08 205#define elfNN_ia64_hash_table(p) \
4dfe6ac6
NC
206 (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
207 == IA64_ELF_DATA ? ((struct elfNN_ia64_link_hash_table *) ((p)->hash)) : NULL)
800eeca4 208
eae50df2
L
209static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
210 (struct elfNN_ia64_link_hash_table *ia64_info,
211 struct elf_link_hash_entry *h,
212 bfd *abfd, const Elf_Internal_Rela *rel, bfd_boolean create);
b34976b6 213static bfd_boolean elfNN_ia64_dynamic_symbol_p
eae50df2
L
214 (struct elf_link_hash_entry *h, struct bfd_link_info *info, int);
215static bfd_reloc_status_type elfNN_ia64_install_value
216 (bfd_byte *hit_addr, bfd_vma val, unsigned int r_type);
217static bfd_boolean elfNN_ia64_choose_gp
e57278ef 218 (bfd *abfd, struct bfd_link_info *info, bfd_boolean final);
eae50df2
L
219static void elfNN_ia64_relax_ldxmov
220 (bfd_byte *contents, bfd_vma off);
bbe66d08 221static void elfNN_ia64_dyn_sym_traverse
eae50df2
L
222 (struct elfNN_ia64_link_hash_table *ia64_info,
223 bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
224 PTR info);
b34976b6 225static bfd_boolean allocate_global_data_got
eae50df2 226 (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data);
b34976b6 227static bfd_boolean allocate_global_fptr_got
eae50df2 228 (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data);
b34976b6 229static bfd_boolean allocate_local_got
eae50df2 230 (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data);
b34976b6 231static bfd_boolean elfNN_ia64_hpux_vec
eae50df2
L
232 (const bfd_target *vec);
233static bfd_boolean allocate_dynrel_entries
234 (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data);
235static asection *get_pltoff
236 (bfd *abfd, struct bfd_link_info *info,
237 struct elfNN_ia64_link_hash_table *ia64_info);
800eeca4 238\f
5e8d7549 239/* ia64-specific relocation. */
800eeca4
JW
240
241/* Perform a relocation. Not much to do here as all the hard work is
bbe66d08 242 done in elfNN_ia64_final_link_relocate. */
800eeca4 243static bfd_reloc_status_type
eae50df2
L
244elfNN_ia64_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc,
245 asymbol *sym ATTRIBUTE_UNUSED,
246 PTR data ATTRIBUTE_UNUSED, asection *input_section,
247 bfd *output_bfd, char **error_message)
800eeca4
JW
248{
249 if (output_bfd)
250 {
251 reloc->address += input_section->output_offset;
252 return bfd_reloc_ok;
253 }
6e84a906
DJ
254
255 if (input_section->flags & SEC_DEBUGGING)
256 return bfd_reloc_continue;
257
bbe66d08 258 *error_message = "Unsupported call to elfNN_ia64_reloc";
800eeca4
JW
259 return bfd_reloc_notsupported;
260}
261
262#define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
263 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
eff26f78 264 elfNN_ia64_reloc, NAME, FALSE, 0, -1, IN)
800eeca4
JW
265
266/* This table has to be sorted according to increasing number of the
267 TYPE field. */
268static reloc_howto_type ia64_howto_table[] =
269 {
b34976b6
AM
270 IA64_HOWTO (R_IA64_NONE, "NONE", 0, FALSE, TRUE),
271
272 IA64_HOWTO (R_IA64_IMM14, "IMM14", 0, FALSE, TRUE),
273 IA64_HOWTO (R_IA64_IMM22, "IMM22", 0, FALSE, TRUE),
274 IA64_HOWTO (R_IA64_IMM64, "IMM64", 0, FALSE, TRUE),
275 IA64_HOWTO (R_IA64_DIR32MSB, "DIR32MSB", 2, FALSE, TRUE),
276 IA64_HOWTO (R_IA64_DIR32LSB, "DIR32LSB", 2, FALSE, TRUE),
277 IA64_HOWTO (R_IA64_DIR64MSB, "DIR64MSB", 4, FALSE, TRUE),
278 IA64_HOWTO (R_IA64_DIR64LSB, "DIR64LSB", 4, FALSE, TRUE),
279
280 IA64_HOWTO (R_IA64_GPREL22, "GPREL22", 0, FALSE, TRUE),
281 IA64_HOWTO (R_IA64_GPREL64I, "GPREL64I", 0, FALSE, TRUE),
282 IA64_HOWTO (R_IA64_GPREL32MSB, "GPREL32MSB", 2, FALSE, TRUE),
283 IA64_HOWTO (R_IA64_GPREL32LSB, "GPREL32LSB", 2, FALSE, TRUE),
284 IA64_HOWTO (R_IA64_GPREL64MSB, "GPREL64MSB", 4, FALSE, TRUE),
285 IA64_HOWTO (R_IA64_GPREL64LSB, "GPREL64LSB", 4, FALSE, TRUE),
286
287 IA64_HOWTO (R_IA64_LTOFF22, "LTOFF22", 0, FALSE, TRUE),
288 IA64_HOWTO (R_IA64_LTOFF64I, "LTOFF64I", 0, FALSE, TRUE),
289
290 IA64_HOWTO (R_IA64_PLTOFF22, "PLTOFF22", 0, FALSE, TRUE),
291 IA64_HOWTO (R_IA64_PLTOFF64I, "PLTOFF64I", 0, FALSE, TRUE),
292 IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, FALSE, TRUE),
293 IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, FALSE, TRUE),
294
295 IA64_HOWTO (R_IA64_FPTR64I, "FPTR64I", 0, FALSE, TRUE),
296 IA64_HOWTO (R_IA64_FPTR32MSB, "FPTR32MSB", 2, FALSE, TRUE),
297 IA64_HOWTO (R_IA64_FPTR32LSB, "FPTR32LSB", 2, FALSE, TRUE),
298 IA64_HOWTO (R_IA64_FPTR64MSB, "FPTR64MSB", 4, FALSE, TRUE),
299 IA64_HOWTO (R_IA64_FPTR64LSB, "FPTR64LSB", 4, FALSE, TRUE),
300
301 IA64_HOWTO (R_IA64_PCREL60B, "PCREL60B", 0, TRUE, TRUE),
302 IA64_HOWTO (R_IA64_PCREL21B, "PCREL21B", 0, TRUE, TRUE),
303 IA64_HOWTO (R_IA64_PCREL21M, "PCREL21M", 0, TRUE, TRUE),
304 IA64_HOWTO (R_IA64_PCREL21F, "PCREL21F", 0, TRUE, TRUE),
305 IA64_HOWTO (R_IA64_PCREL32MSB, "PCREL32MSB", 2, TRUE, TRUE),
306 IA64_HOWTO (R_IA64_PCREL32LSB, "PCREL32LSB", 2, TRUE, TRUE),
307 IA64_HOWTO (R_IA64_PCREL64MSB, "PCREL64MSB", 4, TRUE, TRUE),
308 IA64_HOWTO (R_IA64_PCREL64LSB, "PCREL64LSB", 4, TRUE, TRUE),
309
310 IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, FALSE, TRUE),
311 IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, FALSE, TRUE),
312 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB, "LTOFF_FPTR32MSB", 2, FALSE, TRUE),
313 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB, "LTOFF_FPTR32LSB", 2, FALSE, TRUE),
314 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, FALSE, TRUE),
315 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, FALSE, TRUE),
316
317 IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, FALSE, TRUE),
318 IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, FALSE, TRUE),
319 IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, FALSE, TRUE),
320 IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, FALSE, TRUE),
321
322 IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, FALSE, TRUE),
323 IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, FALSE, TRUE),
324 IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, FALSE, TRUE),
325 IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, FALSE, TRUE),
326
327 IA64_HOWTO (R_IA64_REL32MSB, "REL32MSB", 2, FALSE, TRUE),
328 IA64_HOWTO (R_IA64_REL32LSB, "REL32LSB", 2, FALSE, TRUE),
329 IA64_HOWTO (R_IA64_REL64MSB, "REL64MSB", 4, FALSE, TRUE),
330 IA64_HOWTO (R_IA64_REL64LSB, "REL64LSB", 4, FALSE, TRUE),
331
332 IA64_HOWTO (R_IA64_LTV32MSB, "LTV32MSB", 2, FALSE, TRUE),
333 IA64_HOWTO (R_IA64_LTV32LSB, "LTV32LSB", 2, FALSE, TRUE),
334 IA64_HOWTO (R_IA64_LTV64MSB, "LTV64MSB", 4, FALSE, TRUE),
335 IA64_HOWTO (R_IA64_LTV64LSB, "LTV64LSB", 4, FALSE, TRUE),
336
337 IA64_HOWTO (R_IA64_PCREL21BI, "PCREL21BI", 0, TRUE, TRUE),
338 IA64_HOWTO (R_IA64_PCREL22, "PCREL22", 0, TRUE, TRUE),
339 IA64_HOWTO (R_IA64_PCREL64I, "PCREL64I", 0, TRUE, TRUE),
340
341 IA64_HOWTO (R_IA64_IPLTMSB, "IPLTMSB", 4, FALSE, TRUE),
342 IA64_HOWTO (R_IA64_IPLTLSB, "IPLTLSB", 4, FALSE, TRUE),
343 IA64_HOWTO (R_IA64_COPY, "COPY", 4, FALSE, TRUE),
344 IA64_HOWTO (R_IA64_LTOFF22X, "LTOFF22X", 0, FALSE, TRUE),
345 IA64_HOWTO (R_IA64_LDXMOV, "LDXMOV", 0, FALSE, TRUE),
346
347 IA64_HOWTO (R_IA64_TPREL14, "TPREL14", 0, FALSE, FALSE),
348 IA64_HOWTO (R_IA64_TPREL22, "TPREL22", 0, FALSE, FALSE),
349 IA64_HOWTO (R_IA64_TPREL64I, "TPREL64I", 0, FALSE, FALSE),
1fc0d173
JJ
350 IA64_HOWTO (R_IA64_TPREL64MSB, "TPREL64MSB", 4, FALSE, FALSE),
351 IA64_HOWTO (R_IA64_TPREL64LSB, "TPREL64LSB", 4, FALSE, FALSE),
b34976b6
AM
352 IA64_HOWTO (R_IA64_LTOFF_TPREL22, "LTOFF_TPREL22", 0, FALSE, FALSE),
353
0ca3e455
JB
354 IA64_HOWTO (R_IA64_DTPMOD64MSB, "DTPMOD64MSB", 4, FALSE, FALSE),
355 IA64_HOWTO (R_IA64_DTPMOD64LSB, "DTPMOD64LSB", 4, FALSE, FALSE),
b34976b6
AM
356 IA64_HOWTO (R_IA64_LTOFF_DTPMOD22, "LTOFF_DTPMOD22", 0, FALSE, FALSE),
357
358 IA64_HOWTO (R_IA64_DTPREL14, "DTPREL14", 0, FALSE, FALSE),
359 IA64_HOWTO (R_IA64_DTPREL22, "DTPREL22", 0, FALSE, FALSE),
360 IA64_HOWTO (R_IA64_DTPREL64I, "DTPREL64I", 0, FALSE, FALSE),
1fc0d173
JJ
361 IA64_HOWTO (R_IA64_DTPREL32MSB, "DTPREL32MSB", 2, FALSE, FALSE),
362 IA64_HOWTO (R_IA64_DTPREL32LSB, "DTPREL32LSB", 2, FALSE, FALSE),
363 IA64_HOWTO (R_IA64_DTPREL64MSB, "DTPREL64MSB", 4, FALSE, FALSE),
364 IA64_HOWTO (R_IA64_DTPREL64LSB, "DTPREL64LSB", 4, FALSE, FALSE),
b34976b6 365 IA64_HOWTO (R_IA64_LTOFF_DTPREL22, "LTOFF_DTPREL22", 0, FALSE, FALSE),
800eeca4
JW
366 };
367
368static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
369
370/* Given a BFD reloc type, return the matching HOWTO structure. */
371
5e8d7549 372static reloc_howto_type *
eae50df2 373lookup_howto (unsigned int rtype)
800eeca4
JW
374{
375 static int inited = 0;
376 int i;
377
378 if (!inited)
379 {
380 inited = 1;
381
382 memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
383 for (i = 0; i < NELEMS (ia64_howto_table); ++i)
384 elf_code_to_howto_index[ia64_howto_table[i].type] = i;
385 }
386
d0fb9a8d
JJ
387 if (rtype > R_IA64_MAX_RELOC_CODE)
388 return 0;
800eeca4
JW
389 i = elf_code_to_howto_index[rtype];
390 if (i >= NELEMS (ia64_howto_table))
391 return 0;
392 return ia64_howto_table + i;
393}
394
395static reloc_howto_type*
eae50df2
L
396elfNN_ia64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
397 bfd_reloc_code_real_type bfd_code)
800eeca4
JW
398{
399 unsigned int rtype;
400
401 switch (bfd_code)
402 {
403 case BFD_RELOC_NONE: rtype = R_IA64_NONE; break;
404
405 case BFD_RELOC_IA64_IMM14: rtype = R_IA64_IMM14; break;
406 case BFD_RELOC_IA64_IMM22: rtype = R_IA64_IMM22; break;
407 case BFD_RELOC_IA64_IMM64: rtype = R_IA64_IMM64; break;
408
409 case BFD_RELOC_IA64_DIR32MSB: rtype = R_IA64_DIR32MSB; break;
410 case BFD_RELOC_IA64_DIR32LSB: rtype = R_IA64_DIR32LSB; break;
411 case BFD_RELOC_IA64_DIR64MSB: rtype = R_IA64_DIR64MSB; break;
412 case BFD_RELOC_IA64_DIR64LSB: rtype = R_IA64_DIR64LSB; break;
413
414 case BFD_RELOC_IA64_GPREL22: rtype = R_IA64_GPREL22; break;
415 case BFD_RELOC_IA64_GPREL64I: rtype = R_IA64_GPREL64I; break;
416 case BFD_RELOC_IA64_GPREL32MSB: rtype = R_IA64_GPREL32MSB; break;
417 case BFD_RELOC_IA64_GPREL32LSB: rtype = R_IA64_GPREL32LSB; break;
418 case BFD_RELOC_IA64_GPREL64MSB: rtype = R_IA64_GPREL64MSB; break;
419 case BFD_RELOC_IA64_GPREL64LSB: rtype = R_IA64_GPREL64LSB; break;
420
421 case BFD_RELOC_IA64_LTOFF22: rtype = R_IA64_LTOFF22; break;
422 case BFD_RELOC_IA64_LTOFF64I: rtype = R_IA64_LTOFF64I; break;
423
424 case BFD_RELOC_IA64_PLTOFF22: rtype = R_IA64_PLTOFF22; break;
425 case BFD_RELOC_IA64_PLTOFF64I: rtype = R_IA64_PLTOFF64I; break;
426 case BFD_RELOC_IA64_PLTOFF64MSB: rtype = R_IA64_PLTOFF64MSB; break;
427 case BFD_RELOC_IA64_PLTOFF64LSB: rtype = R_IA64_PLTOFF64LSB; break;
428 case BFD_RELOC_IA64_FPTR64I: rtype = R_IA64_FPTR64I; break;
429 case BFD_RELOC_IA64_FPTR32MSB: rtype = R_IA64_FPTR32MSB; break;
430 case BFD_RELOC_IA64_FPTR32LSB: rtype = R_IA64_FPTR32LSB; break;
431 case BFD_RELOC_IA64_FPTR64MSB: rtype = R_IA64_FPTR64MSB; break;
432 case BFD_RELOC_IA64_FPTR64LSB: rtype = R_IA64_FPTR64LSB; break;
433
434 case BFD_RELOC_IA64_PCREL21B: rtype = R_IA64_PCREL21B; break;
748abff6 435 case BFD_RELOC_IA64_PCREL21BI: rtype = R_IA64_PCREL21BI; break;
800eeca4
JW
436 case BFD_RELOC_IA64_PCREL21M: rtype = R_IA64_PCREL21M; break;
437 case BFD_RELOC_IA64_PCREL21F: rtype = R_IA64_PCREL21F; break;
748abff6
RH
438 case BFD_RELOC_IA64_PCREL22: rtype = R_IA64_PCREL22; break;
439 case BFD_RELOC_IA64_PCREL60B: rtype = R_IA64_PCREL60B; break;
440 case BFD_RELOC_IA64_PCREL64I: rtype = R_IA64_PCREL64I; break;
800eeca4
JW
441 case BFD_RELOC_IA64_PCREL32MSB: rtype = R_IA64_PCREL32MSB; break;
442 case BFD_RELOC_IA64_PCREL32LSB: rtype = R_IA64_PCREL32LSB; break;
443 case BFD_RELOC_IA64_PCREL64MSB: rtype = R_IA64_PCREL64MSB; break;
444 case BFD_RELOC_IA64_PCREL64LSB: rtype = R_IA64_PCREL64LSB; break;
445
446 case BFD_RELOC_IA64_LTOFF_FPTR22: rtype = R_IA64_LTOFF_FPTR22; break;
447 case BFD_RELOC_IA64_LTOFF_FPTR64I: rtype = R_IA64_LTOFF_FPTR64I; break;
a4bd8390
JW
448 case BFD_RELOC_IA64_LTOFF_FPTR32MSB: rtype = R_IA64_LTOFF_FPTR32MSB; break;
449 case BFD_RELOC_IA64_LTOFF_FPTR32LSB: rtype = R_IA64_LTOFF_FPTR32LSB; break;
800eeca4
JW
450 case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
451 case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
452
800eeca4
JW
453 case BFD_RELOC_IA64_SEGREL32MSB: rtype = R_IA64_SEGREL32MSB; break;
454 case BFD_RELOC_IA64_SEGREL32LSB: rtype = R_IA64_SEGREL32LSB; break;
455 case BFD_RELOC_IA64_SEGREL64MSB: rtype = R_IA64_SEGREL64MSB; break;
456 case BFD_RELOC_IA64_SEGREL64LSB: rtype = R_IA64_SEGREL64LSB; break;
457
458 case BFD_RELOC_IA64_SECREL32MSB: rtype = R_IA64_SECREL32MSB; break;
459 case BFD_RELOC_IA64_SECREL32LSB: rtype = R_IA64_SECREL32LSB; break;
460 case BFD_RELOC_IA64_SECREL64MSB: rtype = R_IA64_SECREL64MSB; break;
461 case BFD_RELOC_IA64_SECREL64LSB: rtype = R_IA64_SECREL64LSB; break;
462
463 case BFD_RELOC_IA64_REL32MSB: rtype = R_IA64_REL32MSB; break;
464 case BFD_RELOC_IA64_REL32LSB: rtype = R_IA64_REL32LSB; break;
465 case BFD_RELOC_IA64_REL64MSB: rtype = R_IA64_REL64MSB; break;
466 case BFD_RELOC_IA64_REL64LSB: rtype = R_IA64_REL64LSB; break;
467
468 case BFD_RELOC_IA64_LTV32MSB: rtype = R_IA64_LTV32MSB; break;
469 case BFD_RELOC_IA64_LTV32LSB: rtype = R_IA64_LTV32LSB; break;
470 case BFD_RELOC_IA64_LTV64MSB: rtype = R_IA64_LTV64MSB; break;
471 case BFD_RELOC_IA64_LTV64LSB: rtype = R_IA64_LTV64LSB; break;
472
473 case BFD_RELOC_IA64_IPLTMSB: rtype = R_IA64_IPLTMSB; break;
474 case BFD_RELOC_IA64_IPLTLSB: rtype = R_IA64_IPLTLSB; break;
800eeca4
JW
475 case BFD_RELOC_IA64_COPY: rtype = R_IA64_COPY; break;
476 case BFD_RELOC_IA64_LTOFF22X: rtype = R_IA64_LTOFF22X; break;
477 case BFD_RELOC_IA64_LDXMOV: rtype = R_IA64_LDXMOV; break;
478
13ae64f3 479 case BFD_RELOC_IA64_TPREL14: rtype = R_IA64_TPREL14; break;
800eeca4 480 case BFD_RELOC_IA64_TPREL22: rtype = R_IA64_TPREL22; break;
13ae64f3 481 case BFD_RELOC_IA64_TPREL64I: rtype = R_IA64_TPREL64I; break;
800eeca4
JW
482 case BFD_RELOC_IA64_TPREL64MSB: rtype = R_IA64_TPREL64MSB; break;
483 case BFD_RELOC_IA64_TPREL64LSB: rtype = R_IA64_TPREL64LSB; break;
13ae64f3
JJ
484 case BFD_RELOC_IA64_LTOFF_TPREL22: rtype = R_IA64_LTOFF_TPREL22; break;
485
486 case BFD_RELOC_IA64_DTPMOD64MSB: rtype = R_IA64_DTPMOD64MSB; break;
487 case BFD_RELOC_IA64_DTPMOD64LSB: rtype = R_IA64_DTPMOD64LSB; break;
488 case BFD_RELOC_IA64_LTOFF_DTPMOD22: rtype = R_IA64_LTOFF_DTPMOD22; break;
489
490 case BFD_RELOC_IA64_DTPREL14: rtype = R_IA64_DTPREL14; break;
491 case BFD_RELOC_IA64_DTPREL22: rtype = R_IA64_DTPREL22; break;
492 case BFD_RELOC_IA64_DTPREL64I: rtype = R_IA64_DTPREL64I; break;
493 case BFD_RELOC_IA64_DTPREL32MSB: rtype = R_IA64_DTPREL32MSB; break;
494 case BFD_RELOC_IA64_DTPREL32LSB: rtype = R_IA64_DTPREL32LSB; break;
495 case BFD_RELOC_IA64_DTPREL64MSB: rtype = R_IA64_DTPREL64MSB; break;
496 case BFD_RELOC_IA64_DTPREL64LSB: rtype = R_IA64_DTPREL64LSB; break;
497 case BFD_RELOC_IA64_LTOFF_DTPREL22: rtype = R_IA64_LTOFF_DTPREL22; break;
800eeca4
JW
498
499 default: return 0;
500 }
501 return lookup_howto (rtype);
502}
503
157090f7
AM
504static reloc_howto_type *
505elfNN_ia64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
506 const char *r_name)
507{
508 unsigned int i;
509
510 for (i = 0;
511 i < sizeof (ia64_howto_table) / sizeof (ia64_howto_table[0]);
512 i++)
513 if (ia64_howto_table[i].name != NULL
514 && strcasecmp (ia64_howto_table[i].name, r_name) == 0)
515 return &ia64_howto_table[i];
516
517 return NULL;
518}
519
800eeca4
JW
520/* Given a ELF reloc, return the matching HOWTO structure. */
521
522static void
eae50df2
L
523elfNN_ia64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
524 arelent *bfd_reloc,
525 Elf_Internal_Rela *elf_reloc)
800eeca4 526{
dc810e39
AM
527 bfd_reloc->howto
528 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc->r_info));
800eeca4
JW
529}
530\f
531#define PLT_HEADER_SIZE (3 * 16)
532#define PLT_MIN_ENTRY_SIZE (1 * 16)
533#define PLT_FULL_ENTRY_SIZE (2 * 16)
534#define PLT_RESERVED_WORDS 3
535
536static const bfd_byte plt_header[PLT_HEADER_SIZE] =
537{
538 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
539 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
540 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
541 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
542 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
543 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
544 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
545 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
546 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
547};
548
549static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
550{
551 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
552 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
553 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
554};
555
556static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
557{
558 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
8b6f2683 559 0x00, 0x41, 0x3c, 0x70, 0x29, 0xc0, /* ld8.acq r16=[r15],8*/
800eeca4
JW
560 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
561 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
562 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
563 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
564};
565
566#define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
748abff6 567
748abff6
RH
568static const bfd_byte oor_brl[16] =
569{
570 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
571 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
572 0x00, 0x00, 0x00, 0xc0
573};
3f7deb8a
L
574
575static const bfd_byte oor_ip[48] =
576{
577 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
578 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
579 0x01, 0x00, 0x00, 0x60,
580 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
581 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
582 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
583 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
584 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
585 0x60, 0x00, 0x80, 0x00 /* br b6;; */
586};
587
588static size_t oor_branch_size = sizeof (oor_brl);
589
590void
591bfd_elfNN_ia64_after_parse (int itanium)
592{
593 oor_branch_size = itanium ? sizeof (oor_ip) : sizeof (oor_brl);
594}
595
83b6bd86
L
596#define BTYPE_SHIFT 6
597#define Y_SHIFT 26
598#define X6_SHIFT 27
599#define X4_SHIFT 27
600#define X3_SHIFT 33
601#define X2_SHIFT 31
602#define X_SHIFT 33
603#define OPCODE_SHIFT 37
604
605#define OPCODE_BITS (0xfLL << OPCODE_SHIFT)
606#define X6_BITS (0x3fLL << X6_SHIFT)
607#define X4_BITS (0xfLL << X4_SHIFT)
608#define X3_BITS (0x7LL << X3_SHIFT)
609#define X2_BITS (0x3LL << X2_SHIFT)
610#define X_BITS (0x1LL << X_SHIFT)
611#define Y_BITS (0x1LL << Y_SHIFT)
612#define BTYPE_BITS (0x7LL << BTYPE_SHIFT)
613#define PREDICATE_BITS (0x3fLL)
614
615#define IS_NOP_B(i) \
616 (((i) & (OPCODE_BITS | X6_BITS)) == (2LL << OPCODE_SHIFT))
617#define IS_NOP_F(i) \
618 (((i) & (OPCODE_BITS | X_BITS | X6_BITS | Y_BITS)) \
619 == (0x1LL << X6_SHIFT))
620#define IS_NOP_I(i) \
621 (((i) & (OPCODE_BITS | X3_BITS | X6_BITS | Y_BITS)) \
622 == (0x1LL << X6_SHIFT))
623#define IS_NOP_M(i) \
624 (((i) & (OPCODE_BITS | X3_BITS | X2_BITS | X4_BITS | Y_BITS)) \
625 == (0x1LL << X4_SHIFT))
626#define IS_BR_COND(i) \
627 (((i) & (OPCODE_BITS | BTYPE_BITS)) == (0x4LL << OPCODE_SHIFT))
628#define IS_BR_CALL(i) \
629 (((i) & OPCODE_BITS) == (0x5LL << OPCODE_SHIFT))
630
631static bfd_boolean
632elfNN_ia64_relax_br (bfd_byte *contents, bfd_vma off)
633{
d3ce72d0 634 unsigned int template_val, mlx;
83b6bd86
L
635 bfd_vma t0, t1, s0, s1, s2, br_code;
636 long br_slot;
637 bfd_byte *hit_addr;
638
639 hit_addr = (bfd_byte *) (contents + off);
d68cd58c 640 br_slot = (intptr_t) hit_addr & 0x3;
83b6bd86
L
641 hit_addr -= br_slot;
642 t0 = bfd_getl64 (hit_addr + 0);
643 t1 = bfd_getl64 (hit_addr + 8);
644
645 /* Check if we can turn br into brl. A label is always at the start
646 of the bundle. Even if there are predicates on NOPs, we still
647 perform this optimization. */
d3ce72d0 648 template_val = t0 & 0x1e;
83b6bd86
L
649 s0 = (t0 >> 5) & 0x1ffffffffffLL;
650 s1 = ((t0 >> 46) | (t1 << 18)) & 0x1ffffffffffLL;
651 s2 = (t1 >> 23) & 0x1ffffffffffLL;
652 switch (br_slot)
653 {
654 case 0:
655 /* Check if slot 1 and slot 2 are NOPs. Possible template is
656 BBB. We only need to check nop.b. */
657 if (!(IS_NOP_B (s1) && IS_NOP_B (s2)))
658 return FALSE;
659 br_code = s0;
660 break;
661 case 1:
662 /* Check if slot 2 is NOP. Possible templates are MBB and BBB.
663 For BBB, slot 0 also has to be nop.b. */
d3ce72d0 664 if (!((template_val == 0x12 /* MBB */
83b6bd86 665 && IS_NOP_B (s2))
d3ce72d0 666 || (template_val == 0x16 /* BBB */
83b6bd86
L
667 && IS_NOP_B (s0)
668 && IS_NOP_B (s2))))
669 return FALSE;
670 br_code = s1;
671 break;
672 case 2:
673 /* Check if slot 1 is NOP. Possible templates are MIB, MBB, BBB,
674 MMB and MFB. For BBB, slot 0 also has to be nop.b. */
d3ce72d0 675 if (!((template_val == 0x10 /* MIB */
83b6bd86 676 && IS_NOP_I (s1))
d3ce72d0 677 || (template_val == 0x12 /* MBB */
83b6bd86 678 && IS_NOP_B (s1))
d3ce72d0 679 || (template_val == 0x16 /* BBB */
83b6bd86
L
680 && IS_NOP_B (s0)
681 && IS_NOP_B (s1))
d3ce72d0 682 || (template_val == 0x18 /* MMB */
83b6bd86 683 && IS_NOP_M (s1))
d3ce72d0 684 || (template_val == 0x1c /* MFB */
83b6bd86
L
685 && IS_NOP_F (s1))))
686 return FALSE;
687 br_code = s2;
688 break;
689 default:
690 /* It should never happen. */
691 abort ();
692 }
9a2e389a 693
83b6bd86
L
694 /* We can turn br.cond/br.call into brl.cond/brl.call. */
695 if (!(IS_BR_COND (br_code) || IS_BR_CALL (br_code)))
696 return FALSE;
697
698 /* Turn br into brl by setting bit 40. */
699 br_code |= 0x1LL << 40;
700
701 /* Turn the old bundle into a MLX bundle with the same stop-bit
702 variety. */
703 if (t0 & 0x1)
704 mlx = 0x5;
705 else
706 mlx = 0x4;
707
d3ce72d0 708 if (template_val == 0x16)
83b6bd86 709 {
5e27d427
L
710 /* For BBB, we need to put nop.m in slot 0. We keep the original
711 predicate only if slot 0 isn't br. */
712 if (br_slot == 0)
713 t0 = 0LL;
714 else
715 t0 &= PREDICATE_BITS << 5;
83b6bd86
L
716 t0 |= 0x1LL << (X4_SHIFT + 5);
717 }
718 else
719 {
720 /* Keep the original instruction in slot 0. */
721 t0 &= 0x1ffffffffffLL << 5;
722 }
723
724 t0 |= mlx;
725
726 /* Put brl in slot 1. */
727 t1 = br_code << 23;
728
729 bfd_putl64 (t0, hit_addr);
730 bfd_putl64 (t1, hit_addr + 8);
731 return TRUE;
732}
733
03609792 734static void
bbb268c3 735elfNN_ia64_relax_brl (bfd_byte *contents, bfd_vma off)
03609792 736{
d3ce72d0 737 int template_val;
03609792 738 bfd_byte *hit_addr;
fc3ab699 739 bfd_vma t0, t1, i0, i1, i2;
03609792
L
740
741 hit_addr = (bfd_byte *) (contents + off);
d68cd58c 742 hit_addr -= (intptr_t) hit_addr & 0x3;
fc3ab699
L
743 t0 = bfd_getl64 (hit_addr);
744 t1 = bfd_getl64 (hit_addr + 8);
03609792 745
7e3102a7 746 /* Keep the instruction in slot 0. */
fc3ab699
L
747 i0 = (t0 >> 5) & 0x1ffffffffffLL;
748 /* Use nop.b for slot 1. */
749 i1 = 0x4000000000LL;
7e3102a7 750 /* For slot 2, turn brl into br by masking out bit 40. */
fc3ab699 751 i2 = (t1 >> 23) & 0x0ffffffffffLL;
7e3102a7 752
fc3ab699
L
753 /* Turn a MLX bundle into a MBB bundle with the same stop-bit
754 variety. */
755 if (t0 & 0x1)
d3ce72d0 756 template_val = 0x13;
fc3ab699 757 else
d3ce72d0
NC
758 template_val = 0x12;
759 t0 = (i1 << 46) | (i0 << 5) | template_val;
fc3ab699 760 t1 = (i2 << 23) | (i1 >> 18);
7e3102a7 761
fc3ab699
L
762 bfd_putl64 (t0, hit_addr);
763 bfd_putl64 (t1, hit_addr + 8);
03609792 764}
fbbc3759
L
765
766/* Rename some of the generic section flags to better document how they
767 are used here. */
b0dddeec
AM
768#define skip_relax_pass_0 sec_flg0
769#define skip_relax_pass_1 sec_flg1
fbbc3759 770
748abff6 771\f
2c4c2bc0 772/* These functions do relaxation for IA-64 ELF. */
748abff6 773
a231ddc0
L
774static void
775elfNN_ia64_update_short_info (asection *sec, bfd_vma offset,
776 struct elfNN_ia64_link_hash_table *ia64_info)
777{
f4dcf782
L
778 /* Skip ABS and SHF_IA_64_SHORT sections. */
779 if (sec == bfd_abs_section_ptr
780 || (sec->flags & SEC_SMALL_DATA) != 0)
a231ddc0
L
781 return;
782
783 if (!ia64_info->min_short_sec)
784 {
785 ia64_info->max_short_sec = sec;
786 ia64_info->max_short_offset = offset;
787 ia64_info->min_short_sec = sec;
788 ia64_info->min_short_offset = offset;
789 }
790 else if (sec == ia64_info->max_short_sec
791 && offset > ia64_info->max_short_offset)
792 ia64_info->max_short_offset = offset;
793 else if (sec == ia64_info->min_short_sec
794 && offset < ia64_info->min_short_offset)
795 ia64_info->min_short_offset = offset;
796 else if (sec->output_section->vma
affb4bf3 797 > ia64_info->max_short_sec->vma)
a231ddc0
L
798 {
799 ia64_info->max_short_sec = sec;
800 ia64_info->max_short_offset = offset;
801 }
802 else if (sec->output_section->vma
affb4bf3 803 < ia64_info->min_short_sec->vma)
a231ddc0
L
804 {
805 ia64_info->min_short_sec = sec;
806 ia64_info->min_short_offset = offset;
807 }
808}
809
b34976b6 810static bfd_boolean
eae50df2
L
811elfNN_ia64_relax_section (bfd *abfd, asection *sec,
812 struct bfd_link_info *link_info,
813 bfd_boolean *again)
748abff6
RH
814{
815 struct one_fixup
816 {
817 struct one_fixup *next;
818 asection *tsec;
819 bfd_vma toff;
820 bfd_vma trampoff;
821 };
822
823 Elf_Internal_Shdr *symtab_hdr;
824 Elf_Internal_Rela *internal_relocs;
748abff6
RH
825 Elf_Internal_Rela *irel, *irelend;
826 bfd_byte *contents;
6cdc0ccc 827 Elf_Internal_Sym *isymbuf = NULL;
bbe66d08 828 struct elfNN_ia64_link_hash_table *ia64_info;
748abff6 829 struct one_fixup *fixups = NULL;
b34976b6
AM
830 bfd_boolean changed_contents = FALSE;
831 bfd_boolean changed_relocs = FALSE;
2c4c2bc0 832 bfd_boolean changed_got = FALSE;
fbbc3759
L
833 bfd_boolean skip_relax_pass_0 = TRUE;
834 bfd_boolean skip_relax_pass_1 = TRUE;
2c4c2bc0 835 bfd_vma gp = 0;
748abff6 836
46f5aac8
KH
837 /* Assume we're not going to change any sizes, and we'll only need
838 one pass. */
b34976b6 839 *again = FALSE;
748abff6 840
c8a1f254
NS
841 if (link_info->relocatable)
842 (*link_info->callbacks->einfo)
843 (_("%P%F: --relax and -r may not be used together\n"));
844
04b3329b 845 /* Don't even try to relax for non-ELF outputs. */
0eddce27 846 if (!is_elf_hash_table (link_info->hash))
04b3329b
L
847 return FALSE;
848
c7996ad6 849 /* Nothing to do if there are no relocations or there is no need for
fbbc3759 850 the current pass. */
748abff6 851 if ((sec->flags & SEC_RELOC) == 0
c7996ad6 852 || sec->reloc_count == 0
fbbc3759
L
853 || (link_info->relax_pass == 0 && sec->skip_relax_pass_0)
854 || (link_info->relax_pass == 1 && sec->skip_relax_pass_1))
b34976b6 855 return TRUE;
748abff6 856
4dfe6ac6
NC
857 ia64_info = elfNN_ia64_hash_table (link_info);
858 if (ia64_info == NULL)
859 return FALSE;
860
748abff6
RH
861 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
862
863 /* Load the relocations for this section. */
45d6a902 864 internal_relocs = (_bfd_elf_link_read_relocs
4dfe6ac6 865 (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
748abff6
RH
866 link_info->keep_memory));
867 if (internal_relocs == NULL)
b34976b6 868 return FALSE;
748abff6 869
748abff6
RH
870 irelend = internal_relocs + sec->reloc_count;
871
748abff6 872 /* Get the section contents. */
748abff6
RH
873 if (elf_section_data (sec)->this_hdr.contents != NULL)
874 contents = elf_section_data (sec)->this_hdr.contents;
875 else
876 {
eea6121a 877 if (!bfd_malloc_and_get_section (abfd, sec, &contents))
748abff6
RH
878 goto error_return;
879 }
880
2c4c2bc0 881 for (irel = internal_relocs; irel < irelend; irel++)
748abff6 882 {
2f9bd3f6 883 unsigned long r_type = ELFNN_R_TYPE (irel->r_info);
748abff6 884 bfd_vma symaddr, reladdr, trampoff, toff, roff;
748abff6
RH
885 asection *tsec;
886 struct one_fixup *f;
dc810e39 887 bfd_size_type amt;
2c4c2bc0
RH
888 bfd_boolean is_branch;
889 struct elfNN_ia64_dyn_sym_info *dyn_i;
bf8b15af 890 char symtype;
748abff6 891
2c4c2bc0
RH
892 switch (r_type)
893 {
894 case R_IA64_PCREL21B:
895 case R_IA64_PCREL21BI:
896 case R_IA64_PCREL21M:
897 case R_IA64_PCREL21F:
fbbc3759
L
898 /* In pass 1, all br relaxations are done. We can skip it. */
899 if (link_info->relax_pass == 1)
c7996ad6 900 continue;
fbbc3759 901 skip_relax_pass_0 = FALSE;
2c4c2bc0
RH
902 is_branch = TRUE;
903 break;
904
03609792 905 case R_IA64_PCREL60B:
fbbc3759
L
906 /* We can't optimize brl to br in pass 0 since br relaxations
907 will increase the code size. Defer it to pass 1. */
908 if (link_info->relax_pass == 0)
03609792 909 {
fbbc3759 910 skip_relax_pass_1 = FALSE;
03609792
L
911 continue;
912 }
913 is_branch = TRUE;
914 break;
915
a231ddc0
L
916 case R_IA64_GPREL22:
917 /* Update max_short_sec/min_short_sec. */
918
2c4c2bc0
RH
919 case R_IA64_LTOFF22X:
920 case R_IA64_LDXMOV:
fbbc3759
L
921 /* We can't relax ldx/mov in pass 0 since br relaxations will
922 increase the code size. Defer it to pass 1. */
923 if (link_info->relax_pass == 0)
c7996ad6 924 {
fbbc3759 925 skip_relax_pass_1 = FALSE;
c7996ad6
L
926 continue;
927 }
2c4c2bc0
RH
928 is_branch = FALSE;
929 break;
930
931 default:
932 continue;
933 }
748abff6
RH
934
935 /* Get the value of the symbol referred to by the reloc. */
bbe66d08 936 if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
748abff6
RH
937 {
938 /* A local symbol. */
6cdc0ccc
AM
939 Elf_Internal_Sym *isym;
940
941 /* Read this BFD's local symbols. */
942 if (isymbuf == NULL)
943 {
944 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
945 if (isymbuf == NULL)
946 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
947 symtab_hdr->sh_info, 0,
948 NULL, NULL, NULL);
949 if (isymbuf == 0)
950 goto error_return;
951 }
952
60d8b524 953 isym = isymbuf + ELFNN_R_SYM (irel->r_info);
6cdc0ccc 954 if (isym->st_shndx == SHN_UNDEF)
4cc11e76 955 continue; /* We can't do anything with undefined symbols. */
6cdc0ccc 956 else if (isym->st_shndx == SHN_ABS)
748abff6 957 tsec = bfd_abs_section_ptr;
6cdc0ccc 958 else if (isym->st_shndx == SHN_COMMON)
748abff6 959 tsec = bfd_com_section_ptr;
6cdc0ccc 960 else if (isym->st_shndx == SHN_IA_64_ANSI_COMMON)
d9cf1b54 961 tsec = bfd_com_section_ptr;
3e932841 962 else
6cdc0ccc 963 tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
748abff6 964
6cdc0ccc 965 toff = isym->st_value;
2c4c2bc0 966 dyn_i = get_dyn_sym_info (ia64_info, NULL, abfd, irel, FALSE);
bf8b15af 967 symtype = ELF_ST_TYPE (isym->st_info);
748abff6
RH
968 }
969 else
970 {
971 unsigned long indx;
972 struct elf_link_hash_entry *h;
748abff6 973
bbe66d08 974 indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
748abff6
RH
975 h = elf_sym_hashes (abfd)[indx];
976 BFD_ASSERT (h != NULL);
977
978 while (h->root.type == bfd_link_hash_indirect
979 || h->root.type == bfd_link_hash_warning)
980 h = (struct elf_link_hash_entry *) h->root.u.i.link;
981
b34976b6 982 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, FALSE);
748abff6
RH
983
984 /* For branches to dynamic symbols, we're interested instead
985 in a branch to the PLT entry. */
2c4c2bc0 986 if (is_branch && dyn_i && dyn_i->want_plt2)
748abff6 987 {
2f9bd3f6
RH
988 /* Internal branches shouldn't be sent to the PLT.
989 Leave this for now and we'll give an error later. */
990 if (r_type != R_IA64_PCREL21B)
991 continue;
992
cc3bd654 993 tsec = ia64_info->root.splt;
748abff6 994 toff = dyn_i->plt2_offset;
3fa1d917 995 BFD_ASSERT (irel->r_addend == 0);
748abff6 996 }
2c4c2bc0
RH
997
998 /* Can't do anything else with dynamic symbols. */
986a241f 999 else if (elfNN_ia64_dynamic_symbol_p (h, link_info, r_type))
2c4c2bc0
RH
1000 continue;
1001
748abff6
RH
1002 else
1003 {
4cc11e76 1004 /* We can't do anything with undefined symbols. */
748abff6
RH
1005 if (h->root.type == bfd_link_hash_undefined
1006 || h->root.type == bfd_link_hash_undefweak)
1007 continue;
1008
1009 tsec = h->root.u.def.section;
1010 toff = h->root.u.def.value;
1011 }
bf8b15af
L
1012
1013 symtype = h->type;
5dd23ec1 1014 }
3fa1d917 1015
9f2e92c5 1016 if (tsec->sec_info_type == ELF_INFO_TYPE_MERGE)
bf8b15af
L
1017 {
1018 /* At this stage in linking, no SEC_MERGE symbol has been
1019 adjusted, so all references to such symbols need to be
1020 passed through _bfd_merged_section_offset. (Later, in
1021 relocate_section, all SEC_MERGE symbols *except* for
1022 section symbols have been adjusted.)
1023
1024 gas may reduce relocations against symbols in SEC_MERGE
1025 sections to a relocation against the section symbol when
1026 the original addend was zero. When the reloc is against
1027 a section symbol we should include the addend in the
1028 offset passed to _bfd_merged_section_offset, since the
1029 location of interest is the original symbol. On the
1030 other hand, an access to "sym+addend" where "sym" is not
1031 a section symbol should not include the addend; Such an
1032 access is presumed to be an offset from "sym"; The
1033 location of interest is just "sym". */
1034 if (symtype == STT_SECTION)
1035 toff += irel->r_addend;
f12123c0 1036
bf8b15af
L
1037 toff = _bfd_merged_section_offset (abfd, &tsec,
1038 elf_section_data (tsec)->sec_info,
1039 toff);
1040
1041 if (symtype != STT_SECTION)
1042 toff += irel->r_addend;
1043 }
9f2e92c5
L
1044 else
1045 toff += irel->r_addend;
1046
3fa1d917 1047 symaddr = tsec->output_section->vma + tsec->output_offset + toff;
748abff6
RH
1048
1049 roff = irel->r_offset;
748abff6 1050
2c4c2bc0
RH
1051 if (is_branch)
1052 {
de0d9f33
L
1053 bfd_signed_vma offset;
1054
2c4c2bc0
RH
1055 reladdr = (sec->output_section->vma
1056 + sec->output_offset
1057 + roff) & (bfd_vma) -4;
748abff6 1058
feddcd0d
L
1059 /* The .plt section is aligned at 32byte and the .text section
1060 is aligned at 64byte. The .text section is right after the
1061 .plt section. After the first relaxation pass, linker may
1062 increase the gap between the .plt and .text sections up
1063 to 32byte. We assume linker will always insert 32byte
1064 between the .plt and .text sections after the the first
1065 relaxation pass. */
cc3bd654 1066 if (tsec == ia64_info->root.splt)
feddcd0d
L
1067 offset = -0x1000000 + 32;
1068 else
1069 offset = -0x1000000;
1070
2c4c2bc0 1071 /* If the branch is in range, no need to do anything. */
feddcd0d 1072 if ((bfd_signed_vma) (symaddr - reladdr) >= offset
2c4c2bc0 1073 && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
03609792
L
1074 {
1075 /* If the 60-bit branch is in 21-bit range, optimize it. */
1076 if (r_type == R_IA64_PCREL60B)
1077 {
bbb268c3 1078 elfNN_ia64_relax_brl (contents, roff);
03609792
L
1079
1080 irel->r_info
7e3102a7 1081 = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
03609792
L
1082 R_IA64_PCREL21B);
1083
1084 /* If the original relocation offset points to slot
1085 1, change it to slot 2. */
1086 if ((irel->r_offset & 3) == 1)
1087 irel->r_offset += 1;
1088 }
1089
1090 continue;
1091 }
1092 else if (r_type == R_IA64_PCREL60B)
2c4c2bc0 1093 continue;
83b6bd86
L
1094 else if (elfNN_ia64_relax_br (contents, roff))
1095 {
1096 irel->r_info
1097 = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1098 R_IA64_PCREL60B);
1099
1100 /* Make the relocation offset point to slot 1. */
1101 irel->r_offset = (irel->r_offset & ~((bfd_vma) 0x3)) + 1;
1102 continue;
1103 }
748abff6 1104
e525914f
L
1105 /* We can't put a trampoline in a .init/.fini section. Issue
1106 an error. */
1107 if (strcmp (sec->output_section->name, ".init") == 0
1108 || strcmp (sec->output_section->name, ".fini") == 0)
1109 {
1110 (*_bfd_error_handler)
d003868e
AM
1111 (_("%B: Can't relax br at 0x%lx in section `%A'. Please use brl or indirect branch."),
1112 sec->owner, sec, (unsigned long) roff);
e525914f
L
1113 bfd_set_error (bfd_error_bad_value);
1114 goto error_return;
1115 }
1116
2c4c2bc0 1117 /* If the branch and target are in the same section, you've
c5509b92
L
1118 got one honking big section and we can't help you unless
1119 you are branching backwards. You'll get an error message
1120 later. */
1121 if (tsec == sec && toff > roff)
2c4c2bc0 1122 continue;
748abff6 1123
2c4c2bc0
RH
1124 /* Look for an existing fixup to this address. */
1125 for (f = fixups; f ; f = f->next)
1126 if (f->tsec == tsec && f->toff == toff)
1127 break;
748abff6 1128
2c4c2bc0 1129 if (f == NULL)
748abff6 1130 {
2c4c2bc0
RH
1131 /* Two alternatives: If it's a branch to a PLT entry, we can
1132 make a copy of the FULL_PLT entry. Otherwise, we'll have
1133 to use a `brl' insn to get where we're going. */
1134
1135 size_t size;
1136
cc3bd654 1137 if (tsec == ia64_info->root.splt)
2c4c2bc0
RH
1138 size = sizeof (plt_full_entry);
1139 else
3f7deb8a 1140 size = oor_branch_size;
748abff6 1141
2c4c2bc0 1142 /* Resize the current section to make room for the new branch. */
eea6121a 1143 trampoff = (sec->size + 15) & (bfd_vma) -16;
de0d9f33
L
1144
1145 /* If trampoline is out of range, there is nothing we
1146 can do. */
1147 offset = trampoff - (roff & (bfd_vma) -4);
1148 if (offset < -0x1000000 || offset > 0x0FFFFF0)
1149 continue;
1150
2c4c2bc0
RH
1151 amt = trampoff + size;
1152 contents = (bfd_byte *) bfd_realloc (contents, amt);
1153 if (contents == NULL)
1154 goto error_return;
eea6121a 1155 sec->size = amt;
748abff6 1156
cc3bd654 1157 if (tsec == ia64_info->root.splt)
2c4c2bc0
RH
1158 {
1159 memcpy (contents + trampoff, plt_full_entry, size);
748abff6 1160
2c4c2bc0
RH
1161 /* Hijack the old relocation for use as the PLTOFF reloc. */
1162 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1163 R_IA64_PLTOFF22);
1164 irel->r_offset = trampoff;
1165 }
1166 else
1167 {
3f7deb8a
L
1168 if (size == sizeof (oor_ip))
1169 {
1170 memcpy (contents + trampoff, oor_ip, size);
1171 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1172 R_IA64_PCREL64I);
1173 irel->r_addend -= 16;
1174 irel->r_offset = trampoff + 2;
1175 }
1176 else
1177 {
1178 memcpy (contents + trampoff, oor_brl, size);
1179 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1180 R_IA64_PCREL60B);
1181 irel->r_offset = trampoff + 2;
1182 }
1183
2c4c2bc0
RH
1184 }
1185
1186 /* Record the fixup so we don't do it again this section. */
1187 f = (struct one_fixup *)
1188 bfd_malloc ((bfd_size_type) sizeof (*f));
1189 f->next = fixups;
1190 f->tsec = tsec;
1191 f->toff = toff;
1192 f->trampoff = trampoff;
1193 fixups = f;
748abff6 1194 }
2c4c2bc0
RH
1195 else
1196 {
de0d9f33
L
1197 /* If trampoline is out of range, there is nothing we
1198 can do. */
1199 offset = f->trampoff - (roff & (bfd_vma) -4);
1200 if (offset < -0x1000000 || offset > 0x0FFFFF0)
1201 continue;
1202
2c4c2bc0
RH
1203 /* Nop out the reloc, since we're finalizing things here. */
1204 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
1205 }
1206
de0d9f33 1207 /* Fix up the existing branch to hit the trampoline. */
bbb268c3
JW
1208 if (elfNN_ia64_install_value (contents + roff, offset, r_type)
1209 != bfd_reloc_ok)
2c4c2bc0 1210 goto error_return;
748abff6 1211
2c4c2bc0
RH
1212 changed_contents = TRUE;
1213 changed_relocs = TRUE;
748abff6
RH
1214 }
1215 else
1216 {
2c4c2bc0
RH
1217 /* Fetch the gp. */
1218 if (gp == 0)
1219 {
1220 bfd *obfd = sec->output_section->owner;
1221 gp = _bfd_get_gp_value (obfd);
1222 if (gp == 0)
1223 {
e57278ef 1224 if (!elfNN_ia64_choose_gp (obfd, link_info, FALSE))
2c4c2bc0
RH
1225 goto error_return;
1226 gp = _bfd_get_gp_value (obfd);
1227 }
1228 }
748abff6 1229
2c4c2bc0 1230 /* If the data is out of range, do nothing. */
484a4f9c
RH
1231 if ((bfd_signed_vma) (symaddr - gp) >= 0x200000
1232 ||(bfd_signed_vma) (symaddr - gp) < -0x200000)
2c4c2bc0 1233 continue;
748abff6 1234
a231ddc0 1235 if (r_type == R_IA64_GPREL22)
affb4bf3 1236 elfNN_ia64_update_short_info (tsec->output_section,
a231ddc0
L
1237 tsec->output_offset + toff,
1238 ia64_info);
1239 else if (r_type == R_IA64_LTOFF22X)
2c4c2bc0
RH
1240 {
1241 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1242 R_IA64_GPREL22);
1243 changed_relocs = TRUE;
1244 if (dyn_i->want_gotx)
1245 {
1246 dyn_i->want_gotx = 0;
1247 changed_got |= !dyn_i->want_got;
1248 }
a231ddc0 1249
affb4bf3 1250 elfNN_ia64_update_short_info (tsec->output_section,
a231ddc0
L
1251 tsec->output_offset + toff,
1252 ia64_info);
2c4c2bc0
RH
1253 }
1254 else
1255 {
bbb268c3 1256 elfNN_ia64_relax_ldxmov (contents, roff);
2c4c2bc0
RH
1257 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
1258 changed_contents = TRUE;
1259 changed_relocs = TRUE;
1260 }
1261 }
748abff6
RH
1262 }
1263
2c4c2bc0
RH
1264 /* ??? If we created fixups, this may push the code segment large
1265 enough that the data segment moves, which will change the GP.
1266 Reset the GP so that we re-calculate next round. We need to
1267 do this at the _beginning_ of the next round; now will not do. */
f12123c0 1268
748abff6
RH
1269 /* Clean up and go home. */
1270 while (fixups)
1271 {
1272 struct one_fixup *f = fixups;
1273 fixups = fixups->next;
1274 free (f);
1275 }
1276
6cdc0ccc
AM
1277 if (isymbuf != NULL
1278 && symtab_hdr->contents != (unsigned char *) isymbuf)
748abff6
RH
1279 {
1280 if (! link_info->keep_memory)
6cdc0ccc 1281 free (isymbuf);
748abff6
RH
1282 else
1283 {
6cdc0ccc
AM
1284 /* Cache the symbols for elf_link_input_bfd. */
1285 symtab_hdr->contents = (unsigned char *) isymbuf;
748abff6
RH
1286 }
1287 }
1288
6cdc0ccc
AM
1289 if (contents != NULL
1290 && elf_section_data (sec)->this_hdr.contents != contents)
748abff6 1291 {
6cdc0ccc
AM
1292 if (!changed_contents && !link_info->keep_memory)
1293 free (contents);
748abff6
RH
1294 else
1295 {
6cdc0ccc
AM
1296 /* Cache the section contents for elf_link_input_bfd. */
1297 elf_section_data (sec)->this_hdr.contents = contents;
748abff6
RH
1298 }
1299 }
1300
6cdc0ccc
AM
1301 if (elf_section_data (sec)->relocs != internal_relocs)
1302 {
1303 if (!changed_relocs)
1304 free (internal_relocs);
1305 else
1306 elf_section_data (sec)->relocs = internal_relocs;
1307 }
1308
2c4c2bc0
RH
1309 if (changed_got)
1310 {
1311 struct elfNN_ia64_allocate_data data;
1312 data.info = link_info;
1313 data.ofs = 0;
9d73f260 1314 ia64_info->self_dtpmod_offset = (bfd_vma) -1;
2c4c2bc0
RH
1315
1316 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
1317 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
1318 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
cc3bd654 1319 ia64_info->root.sgot->size = data.ofs;
2c4c2bc0 1320
90b263f3 1321 if (ia64_info->root.dynamic_sections_created
cc3bd654 1322 && ia64_info->root.srelgot != NULL)
4a78a1f4
AS
1323 {
1324 /* Resize .rela.got. */
cc3bd654 1325 ia64_info->root.srelgot->size = 0;
4a78a1f4
AS
1326 if (link_info->shared
1327 && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
cc3bd654 1328 ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
4a78a1f4
AS
1329 data.only_got = TRUE;
1330 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries,
1331 &data);
1332 }
2c4c2bc0
RH
1333 }
1334
fbbc3759
L
1335 if (link_info->relax_pass == 0)
1336 {
1337 /* Pass 0 is only needed to relax br. */
1338 sec->skip_relax_pass_0 = skip_relax_pass_0;
1339 sec->skip_relax_pass_1 = skip_relax_pass_1;
1340 }
c7996ad6 1341
748abff6 1342 *again = changed_contents || changed_relocs;
b34976b6 1343 return TRUE;
748abff6
RH
1344
1345 error_return:
6cdc0ccc
AM
1346 if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
1347 free (isymbuf);
1348 if (contents != NULL
1349 && elf_section_data (sec)->this_hdr.contents != contents)
1350 free (contents);
1351 if (internal_relocs != NULL
1352 && elf_section_data (sec)->relocs != internal_relocs)
1353 free (internal_relocs);
b34976b6 1354 return FALSE;
748abff6 1355}
fbbc3759
L
1356#undef skip_relax_pass_0
1357#undef skip_relax_pass_1
2c4c2bc0
RH
1358
1359static void
eae50df2 1360elfNN_ia64_relax_ldxmov (bfd_byte *contents, bfd_vma off)
2c4c2bc0
RH
1361{
1362 int shift, r1, r3;
1363 bfd_vma dword, insn;
1364
1365 switch ((int)off & 0x3)
1366 {
1367 case 0: shift = 5; break;
1368 case 1: shift = 14; off += 3; break;
1369 case 2: shift = 23; off += 6; break;
60d8b524 1370 default:
2c4c2bc0
RH
1371 abort ();
1372 }
1373
bbb268c3 1374 dword = bfd_getl64 (contents + off);
2c4c2bc0
RH
1375 insn = (dword >> shift) & 0x1ffffffffffLL;
1376
1377 r1 = (insn >> 6) & 127;
1378 r3 = (insn >> 20) & 127;
1379 if (r1 == r3)
1380 insn = 0x8000000; /* nop */
1381 else
1382 insn = (insn & 0x7f01fff) | 0x10800000000LL; /* (qp) mov r1 = r3 */
1383
1384 dword &= ~(0x1ffffffffffLL << shift);
1385 dword |= (insn << shift);
bbb268c3 1386 bfd_putl64 (dword, contents + off);
2c4c2bc0 1387}
800eeca4 1388\f
b34976b6 1389/* Return TRUE if NAME is an unwind table section name. */
81545d45 1390
b34976b6 1391static inline bfd_boolean
0112cd26 1392is_unwind_section_name (bfd *abfd, const char *name)
81545d45 1393{
d9cf1b54
AM
1394 if (elfNN_ia64_hpux_vec (abfd->xvec)
1395 && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
b34976b6 1396 return FALSE;
d9cf1b54 1397
0112cd26
NC
1398 return ((CONST_STRNEQ (name, ELF_STRING_ia64_unwind)
1399 && ! CONST_STRNEQ (name, ELF_STRING_ia64_unwind_info))
1400 || CONST_STRNEQ (name, ELF_STRING_ia64_unwind_once));
81545d45
RH
1401}
1402
800eeca4 1403/* Handle an IA-64 specific section when reading an object file. This
6dc132d9
L
1404 is called when bfd_section_from_shdr finds a section with an unknown
1405 type. */
800eeca4 1406
b34976b6 1407static bfd_boolean
6dc132d9
L
1408elfNN_ia64_section_from_shdr (bfd *abfd,
1409 Elf_Internal_Shdr *hdr,
1410 const char *name,
1411 int shindex)
800eeca4 1412{
800eeca4
JW
1413 /* There ought to be a place to keep ELF backend specific flags, but
1414 at the moment there isn't one. We just keep track of the
1415 sections by their name, instead. Fortunately, the ABI gives
1416 suggested names for all the MIPS specific sections, so we will
1417 probably get away with this. */
1418 switch (hdr->sh_type)
1419 {
1420 case SHT_IA_64_UNWIND:
d9cf1b54 1421 case SHT_IA_64_HP_OPT_ANOT:
800eeca4
JW
1422 break;
1423
1424 case SHT_IA_64_EXT:
1425 if (strcmp (name, ELF_STRING_ia64_archext) != 0)
b34976b6 1426 return FALSE;
800eeca4
JW
1427 break;
1428
1429 default:
b34976b6 1430 return FALSE;
800eeca4
JW
1431 }
1432
6dc132d9 1433 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
b34976b6 1434 return FALSE;
800eeca4 1435
b34976b6 1436 return TRUE;
fa152c49
JW
1437}
1438
1439/* Convert IA-64 specific section flags to bfd internal section flags. */
1440
1441/* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1442 flag. */
1443
b34976b6 1444static bfd_boolean
eae50df2
L
1445elfNN_ia64_section_flags (flagword *flags,
1446 const Elf_Internal_Shdr *hdr)
fa152c49 1447{
800eeca4 1448 if (hdr->sh_flags & SHF_IA_64_SHORT)
fa152c49 1449 *flags |= SEC_SMALL_DATA;
800eeca4 1450
b34976b6 1451 return TRUE;
800eeca4
JW
1452}
1453
1454/* Set the correct type for an IA-64 ELF section. We do this by the
1455 section name, which is a hack, but ought to work. */
1456
b34976b6 1457static bfd_boolean
eae50df2
L
1458elfNN_ia64_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr,
1459 asection *sec)
800eeca4 1460{
91d6fa6a 1461 const char *name;
800eeca4
JW
1462
1463 name = bfd_get_section_name (abfd, sec);
1464
d9cf1b54 1465 if (is_unwind_section_name (abfd, name))
81545d45
RH
1466 {
1467 /* We don't have the sections numbered at this point, so sh_info
1468 is set later, in elfNN_ia64_final_write_processing. */
1469 hdr->sh_type = SHT_IA_64_UNWIND;
1470 hdr->sh_flags |= SHF_LINK_ORDER;
1471 }
800eeca4
JW
1472 else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
1473 hdr->sh_type = SHT_IA_64_EXT;
d9cf1b54
AM
1474 else if (strcmp (name, ".HP.opt_annot") == 0)
1475 hdr->sh_type = SHT_IA_64_HP_OPT_ANOT;
800eeca4 1476 else if (strcmp (name, ".reloc") == 0)
5e8d7549
NC
1477 /* This is an ugly, but unfortunately necessary hack that is
1478 needed when producing EFI binaries on IA-64. It tells
1479 elf.c:elf_fake_sections() not to consider ".reloc" as a section
1480 containing ELF relocation info. We need this hack in order to
1481 be able to generate ELF binaries that can be translated into
1482 EFI applications (which are essentially COFF objects). Those
1483 files contain a COFF ".reloc" section inside an ELFNN object,
1484 which would normally cause BFD to segfault because it would
1485 attempt to interpret this section as containing relocation
1486 entries for section "oc". With this hack enabled, ".reloc"
1487 will be treated as a normal data section, which will avoid the
1488 segfault. However, you won't be able to create an ELFNN binary
1489 with a section named "oc" that needs relocations, but that's
1490 the kind of ugly side-effects you get when detecting section
1491 types based on their names... In practice, this limitation is
1492 unlikely to bite. */
800eeca4
JW
1493 hdr->sh_type = SHT_PROGBITS;
1494
1495 if (sec->flags & SEC_SMALL_DATA)
1496 hdr->sh_flags |= SHF_IA_64_SHORT;
1497
75eb734c
SE
1498 /* Some HP linkers look for the SHF_IA_64_HP_TLS flag instead of SHF_TLS. */
1499
1500 if (elfNN_ia64_hpux_vec (abfd->xvec) && (sec->flags & SHF_TLS))
1501 hdr->sh_flags |= SHF_IA_64_HP_TLS;
1502
b34976b6 1503 return TRUE;
800eeca4
JW
1504}
1505
81545d45
RH
1506/* The final processing done just before writing out an IA-64 ELF
1507 object file. */
1508
1509static void
eae50df2
L
1510elfNN_ia64_final_write_processing (bfd *abfd,
1511 bfd_boolean linker ATTRIBUTE_UNUSED)
81545d45
RH
1512{
1513 Elf_Internal_Shdr *hdr;
38ce5b11 1514 asection *s;
81545d45
RH
1515
1516 for (s = abfd->sections; s; s = s->next)
1517 {
1518 hdr = &elf_section_data (s)->this_hdr;
1519 switch (hdr->sh_type)
1520 {
1521 case SHT_IA_64_UNWIND:
38ce5b11
L
1522 /* The IA-64 processor-specific ABI requires setting sh_link
1523 to the unwind section, whereas HP-UX requires sh_info to
1524 do so. For maximum compatibility, we'll set both for
1525 now... */
1526 hdr->sh_info = hdr->sh_link;
81545d45
RH
1527 break;
1528 }
1529 }
9d46020e
AM
1530
1531 if (! elf_flags_init (abfd))
1532 {
1533 unsigned long flags = 0;
1534
1535 if (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
1536 flags |= EF_IA_64_BE;
1537 if (bfd_get_mach (abfd) == bfd_mach_ia64_elf64)
1538 flags |= EF_IA_64_ABI64;
1539
1540 elf_elfheader(abfd)->e_flags = flags;
b34976b6 1541 elf_flags_init (abfd) = TRUE;
9d46020e 1542 }
81545d45
RH
1543}
1544
800eeca4
JW
1545/* Hook called by the linker routine which adds symbols from an object
1546 file. We use it to put .comm items in .sbss, and not .bss. */
1547
b34976b6 1548static bfd_boolean
a30e5f5f
AM
1549elfNN_ia64_add_symbol_hook (bfd *abfd,
1550 struct bfd_link_info *info,
eae50df2 1551 Elf_Internal_Sym *sym,
a30e5f5f
AM
1552 const char **namep ATTRIBUTE_UNUSED,
1553 flagword *flagsp ATTRIBUTE_UNUSED,
1554 asection **secp,
1555 bfd_vma *valp)
800eeca4
JW
1556{
1557 if (sym->st_shndx == SHN_COMMON
1049f94e 1558 && !info->relocatable
c0846b23 1559 && sym->st_size <= elf_gp_size (abfd))
800eeca4
JW
1560 {
1561 /* Common symbols less than or equal to -G nn bytes are
1562 automatically put into .sbss. */
1563
1564 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1565
1566 if (scomm == NULL)
1567 {
3496cb2a
L
1568 scomm = bfd_make_section_with_flags (abfd, ".scommon",
1569 (SEC_ALLOC
1570 | SEC_IS_COMMON
1571 | SEC_LINKER_CREATED));
1572 if (scomm == NULL)
b34976b6 1573 return FALSE;
800eeca4
JW
1574 }
1575
1576 *secp = scomm;
1577 *valp = sym->st_size;
1578 }
1579
b34976b6 1580 return TRUE;
800eeca4
JW
1581}
1582
1583/* Return the number of additional phdrs we will need. */
1584
1585static int
a6b96beb
AM
1586elfNN_ia64_additional_program_headers (bfd *abfd,
1587 struct bfd_link_info *info ATTRIBUTE_UNUSED)
800eeca4
JW
1588{
1589 asection *s;
1590 int ret = 0;
1591
1592 /* See if we need a PT_IA_64_ARCHEXT segment. */
1593 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1594 if (s && (s->flags & SEC_LOAD))
1595 ++ret;
1596
81545d45
RH
1597 /* Count how many PT_IA_64_UNWIND segments we need. */
1598 for (s = abfd->sections; s; s = s->next)
d9cf1b54 1599 if (is_unwind_section_name (abfd, s->name) && (s->flags & SEC_LOAD))
81545d45 1600 ++ret;
800eeca4
JW
1601
1602 return ret;
1603}
1604
b34976b6 1605static bfd_boolean
8ded5a0f
AM
1606elfNN_ia64_modify_segment_map (bfd *abfd,
1607 struct bfd_link_info *info ATTRIBUTE_UNUSED)
800eeca4
JW
1608{
1609 struct elf_segment_map *m, **pm;
81545d45 1610 Elf_Internal_Shdr *hdr;
800eeca4
JW
1611 asection *s;
1612
1613 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1614 all PT_LOAD segments. */
1615 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1616 if (s && (s->flags & SEC_LOAD))
1617 {
1618 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1619 if (m->p_type == PT_IA_64_ARCHEXT)
1620 break;
1621 if (m == NULL)
1622 {
dc810e39
AM
1623 m = ((struct elf_segment_map *)
1624 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
800eeca4 1625 if (m == NULL)
b34976b6 1626 return FALSE;
800eeca4
JW
1627
1628 m->p_type = PT_IA_64_ARCHEXT;
1629 m->count = 1;
1630 m->sections[0] = s;
1631
1632 /* We want to put it after the PHDR and INTERP segments. */
1633 pm = &elf_tdata (abfd)->segment_map;
1634 while (*pm != NULL
1635 && ((*pm)->p_type == PT_PHDR
1636 || (*pm)->p_type == PT_INTERP))
1637 pm = &(*pm)->next;
1638
1639 m->next = *pm;
1640 *pm = m;
1641 }
1642 }
1643
81545d45
RH
1644 /* Install PT_IA_64_UNWIND segments, if needed. */
1645 for (s = abfd->sections; s; s = s->next)
800eeca4 1646 {
81545d45
RH
1647 hdr = &elf_section_data (s)->this_hdr;
1648 if (hdr->sh_type != SHT_IA_64_UNWIND)
1649 continue;
1650
1651 if (s && (s->flags & SEC_LOAD))
800eeca4 1652 {
81545d45 1653 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
d9cf1b54
AM
1654 if (m->p_type == PT_IA_64_UNWIND)
1655 {
40c97fc6
AM
1656 int i;
1657
d9cf1b54
AM
1658 /* Look through all sections in the unwind segment
1659 for a match since there may be multiple sections
1660 to a segment. */
40c97fc6
AM
1661 for (i = m->count - 1; i >= 0; --i)
1662 if (m->sections[i] == s)
1663 break;
d9cf1b54 1664
40c97fc6 1665 if (i >= 0)
d9cf1b54
AM
1666 break;
1667 }
81545d45 1668
800eeca4 1669 if (m == NULL)
81545d45 1670 {
dc810e39
AM
1671 m = ((struct elf_segment_map *)
1672 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
81545d45 1673 if (m == NULL)
b34976b6 1674 return FALSE;
800eeca4 1675
81545d45
RH
1676 m->p_type = PT_IA_64_UNWIND;
1677 m->count = 1;
1678 m->sections[0] = s;
1679 m->next = NULL;
800eeca4 1680
81545d45
RH
1681 /* We want to put it last. */
1682 pm = &elf_tdata (abfd)->segment_map;
1683 while (*pm != NULL)
1684 pm = &(*pm)->next;
1685 *pm = m;
1686 }
800eeca4
JW
1687 }
1688 }
1689
e36284ab
AM
1690 return TRUE;
1691}
1692
1693/* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1694 the input sections for each output section in the segment and testing
1695 for SHF_IA_64_NORECOV on each. */
1696
1697static bfd_boolean
1698elfNN_ia64_modify_program_headers (bfd *abfd,
1699 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1700{
1701 struct elf_obj_tdata *tdata = elf_tdata (abfd);
1702 struct elf_segment_map *m;
1703 Elf_Internal_Phdr *p;
1704
1705 for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++)
800eeca4
JW
1706 if (m->p_type == PT_LOAD)
1707 {
1708 int i;
1709 for (i = m->count - 1; i >= 0; --i)
1710 {
8423293d 1711 struct bfd_link_order *order = m->sections[i]->map_head.link_order;
e36284ab
AM
1712
1713 while (order != NULL)
800eeca4
JW
1714 {
1715 if (order->type == bfd_indirect_link_order)
1716 {
1717 asection *is = order->u.indirect.section;
1718 bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
1719 if (flags & SHF_IA_64_NORECOV)
1720 {
e36284ab 1721 p->p_flags |= PF_IA_64_NORECOV;
800eeca4
JW
1722 goto found;
1723 }
1724 }
1725 order = order->next;
1726 }
1727 }
1728 found:;
1729 }
1730
b34976b6 1731 return TRUE;
800eeca4
JW
1732}
1733
800eeca4
JW
1734/* According to the Tahoe assembler spec, all labels starting with a
1735 '.' are local. */
1736
b34976b6 1737static bfd_boolean
eae50df2
L
1738elfNN_ia64_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
1739 const char *name)
800eeca4
JW
1740{
1741 return name[0] == '.';
1742}
1743
1744/* Should we do dynamic things to this symbol? */
1745
b34976b6 1746static bfd_boolean
eae50df2
L
1747elfNN_ia64_dynamic_symbol_p (struct elf_link_hash_entry *h,
1748 struct bfd_link_info *info, int r_type)
800eeca4 1749{
986a241f
RH
1750 bfd_boolean ignore_protected
1751 = ((r_type & 0xf8) == 0x40 /* FPTR relocs */
1752 || (r_type & 0xf8) == 0x50); /* LTOFF_FPTR relocs */
800eeca4 1753
986a241f 1754 return _bfd_elf_dynamic_symbol_p (h, info, ignore_protected);
800eeca4
JW
1755}
1756\f
800eeca4 1757static struct bfd_hash_entry*
eae50df2
L
1758elfNN_ia64_new_elf_hash_entry (struct bfd_hash_entry *entry,
1759 struct bfd_hash_table *table,
1760 const char *string)
800eeca4 1761{
bbe66d08
JW
1762 struct elfNN_ia64_link_hash_entry *ret;
1763 ret = (struct elfNN_ia64_link_hash_entry *) entry;
800eeca4
JW
1764
1765 /* Allocate the structure if it has not already been allocated by a
1766 subclass. */
1767 if (!ret)
1768 ret = bfd_hash_allocate (table, sizeof (*ret));
1769
1770 if (!ret)
1771 return 0;
1772
800eeca4 1773 /* Call the allocation method of the superclass. */
bbe66d08 1774 ret = ((struct elfNN_ia64_link_hash_entry *)
800eeca4
JW
1775 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1776 table, string));
1777
4f40114d 1778 ret->info = NULL;
396a682d
L
1779 ret->count = 0;
1780 ret->sorted_count = 0;
1781 ret->size = 0;
800eeca4
JW
1782 return (struct bfd_hash_entry *) ret;
1783}
1784
1785static void
eae50df2
L
1786elfNN_ia64_hash_copy_indirect (struct bfd_link_info *info,
1787 struct elf_link_hash_entry *xdir,
1788 struct elf_link_hash_entry *xind)
800eeca4 1789{
bbe66d08 1790 struct elfNN_ia64_link_hash_entry *dir, *ind;
800eeca4 1791
57c7194e
AM
1792 dir = (struct elfNN_ia64_link_hash_entry *) xdir;
1793 ind = (struct elfNN_ia64_link_hash_entry *) xind;
800eeca4 1794
3e932841 1795 /* Copy down any references that we may have already seen to the
800eeca4
JW
1796 symbol which just became indirect. */
1797
f5385ebf
AM
1798 dir->root.ref_dynamic |= ind->root.ref_dynamic;
1799 dir->root.ref_regular |= ind->root.ref_regular;
1800 dir->root.ref_regular_nonweak |= ind->root.ref_regular_nonweak;
1801 dir->root.needs_plt |= ind->root.needs_plt;
800eeca4 1802
1e370bd2 1803 if (ind->root.root.type != bfd_link_hash_indirect)
0a991dfe
AM
1804 return;
1805
800eeca4
JW
1806 /* Copy over the got and plt data. This would have been done
1807 by check_relocs. */
1808
fcfa13d2 1809 if (ind->info != NULL)
800eeca4 1810 {
bbe66d08 1811 struct elfNN_ia64_dyn_sym_info *dyn_i;
396a682d
L
1812 unsigned int count;
1813
1814 if (dir->info)
1815 free (dir->info);
1816
1817 dir->info = ind->info;
1818 dir->count = ind->count;
1819 dir->sorted_count = ind->sorted_count;
1820 dir->size = ind->size;
800eeca4 1821
800eeca4 1822 ind->info = NULL;
396a682d
L
1823 ind->count = 0;
1824 ind->sorted_count = 0;
1825 ind->size = 0;
800eeca4
JW
1826
1827 /* Fix up the dyn_sym_info pointers to the global symbol. */
396a682d
L
1828 for (count = dir->count, dyn_i = dir->info;
1829 count != 0;
1830 count--, dyn_i++)
800eeca4
JW
1831 dyn_i->h = &dir->root;
1832 }
800eeca4
JW
1833
1834 /* Copy over the dynindx. */
1835
fcfa13d2 1836 if (ind->root.dynindx != -1)
800eeca4 1837 {
fcfa13d2
AM
1838 if (dir->root.dynindx != -1)
1839 _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
1840 dir->root.dynstr_index);
800eeca4
JW
1841 dir->root.dynindx = ind->root.dynindx;
1842 dir->root.dynstr_index = ind->root.dynstr_index;
1843 ind->root.dynindx = -1;
1844 ind->root.dynstr_index = 0;
1845 }
800eeca4
JW
1846}
1847
1848static void
eae50df2
L
1849elfNN_ia64_hash_hide_symbol (struct bfd_link_info *info,
1850 struct elf_link_hash_entry *xh,
1851 bfd_boolean force_local)
800eeca4 1852{
bbe66d08
JW
1853 struct elfNN_ia64_link_hash_entry *h;
1854 struct elfNN_ia64_dyn_sym_info *dyn_i;
396a682d 1855 unsigned int count;
800eeca4 1856
bbe66d08 1857 h = (struct elfNN_ia64_link_hash_entry *)xh;
800eeca4 1858
e5094212 1859 _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
800eeca4 1860
396a682d
L
1861 for (count = h->count, dyn_i = h->info;
1862 count != 0;
1863 count--, dyn_i++)
6a32c710
L
1864 {
1865 dyn_i->want_plt2 = 0;
1866 dyn_i->want_plt = 0;
1867 }
800eeca4
JW
1868}
1869
0aa92b58
JJ
1870/* Compute a hash of a local hash entry. */
1871
1872static hashval_t
eae50df2 1873elfNN_ia64_local_htab_hash (const void *ptr)
0aa92b58
JJ
1874{
1875 struct elfNN_ia64_local_hash_entry *entry
1876 = (struct elfNN_ia64_local_hash_entry *) ptr;
1877
d2149d72 1878 return ELF_LOCAL_SYMBOL_HASH (entry->id, entry->r_sym);
0aa92b58
JJ
1879}
1880
1881/* Compare local hash entries. */
1882
1883static int
eae50df2 1884elfNN_ia64_local_htab_eq (const void *ptr1, const void *ptr2)
0aa92b58
JJ
1885{
1886 struct elfNN_ia64_local_hash_entry *entry1
1887 = (struct elfNN_ia64_local_hash_entry *) ptr1;
1888 struct elfNN_ia64_local_hash_entry *entry2
1889 = (struct elfNN_ia64_local_hash_entry *) ptr2;
1890
1891 return entry1->id == entry2->id && entry1->r_sym == entry2->r_sym;
1892}
1893
800eeca4
JW
1894/* Create the derived linker hash table. The IA-64 ELF port uses this
1895 derived hash table to keep information specific to the IA-64 ElF
1896 linker (without using static variables). */
1897
4dfe6ac6 1898static struct bfd_link_hash_table *
eae50df2 1899elfNN_ia64_hash_table_create (bfd *abfd)
800eeca4 1900{
bbe66d08 1901 struct elfNN_ia64_link_hash_table *ret;
800eeca4 1902
6e84a906 1903 ret = bfd_zmalloc ((bfd_size_type) sizeof (*ret));
800eeca4 1904 if (!ret)
4dfe6ac6 1905 return NULL;
6e84a906 1906
800eeca4 1907 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
66eb6687 1908 elfNN_ia64_new_elf_hash_entry,
4dfe6ac6
NC
1909 sizeof (struct elfNN_ia64_link_hash_entry),
1910 IA64_ELF_DATA))
800eeca4 1911 {
6e84a906 1912 free (ret);
4dfe6ac6 1913 return NULL;
800eeca4
JW
1914 }
1915
0aa92b58
JJ
1916 ret->loc_hash_table = htab_try_create (1024, elfNN_ia64_local_htab_hash,
1917 elfNN_ia64_local_htab_eq, NULL);
1918 ret->loc_hash_memory = objalloc_create ();
1919 if (!ret->loc_hash_table || !ret->loc_hash_memory)
6e84a906
DJ
1920 {
1921 free (ret);
4dfe6ac6 1922 return NULL;
6e84a906
DJ
1923 }
1924
800eeca4
JW
1925 return &ret->root.root;
1926}
1927
396a682d
L
1928/* Free the global elfNN_ia64_dyn_sym_info array. */
1929
1930static bfd_boolean
1931elfNN_ia64_global_dyn_info_free (void **xentry,
1932 PTR unused ATTRIBUTE_UNUSED)
1933{
1934 struct elfNN_ia64_link_hash_entry *entry
1935 = (struct elfNN_ia64_link_hash_entry *) xentry;
1936
1937 if (entry->root.root.type == bfd_link_hash_warning)
1938 entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
1939
1940 if (entry->info)
1941 {
1942 free (entry->info);
1943 entry->info = NULL;
1944 entry->count = 0;
1945 entry->sorted_count = 0;
1946 entry->size = 0;
1947 }
1948
1949 return TRUE;
1950}
1951
1952/* Free the local elfNN_ia64_dyn_sym_info array. */
1953
1954static bfd_boolean
1955elfNN_ia64_local_dyn_info_free (void **slot,
1956 PTR unused ATTRIBUTE_UNUSED)
1957{
1958 struct elfNN_ia64_local_hash_entry *entry
1959 = (struct elfNN_ia64_local_hash_entry *) *slot;
1960
1961 if (entry->info)
1962 {
1963 free (entry->info);
1964 entry->info = NULL;
1965 entry->count = 0;
1966 entry->sorted_count = 0;
1967 entry->size = 0;
1968 }
1969
1970 return TRUE;
1971}
1972
0aa92b58 1973/* Destroy IA-64 linker hash table. */
800eeca4 1974
0aa92b58 1975static void
eae50df2 1976elfNN_ia64_hash_table_free (struct bfd_link_hash_table *hash)
800eeca4 1977{
0aa92b58
JJ
1978 struct elfNN_ia64_link_hash_table *ia64_info
1979 = (struct elfNN_ia64_link_hash_table *) hash;
1980 if (ia64_info->loc_hash_table)
396a682d
L
1981 {
1982 htab_traverse (ia64_info->loc_hash_table,
1983 elfNN_ia64_local_dyn_info_free, NULL);
1984 htab_delete (ia64_info->loc_hash_table);
1985 }
0aa92b58
JJ
1986 if (ia64_info->loc_hash_memory)
1987 objalloc_free ((struct objalloc *) ia64_info->loc_hash_memory);
396a682d
L
1988 elf_link_hash_traverse (&ia64_info->root,
1989 elfNN_ia64_global_dyn_info_free, NULL);
0aa92b58 1990 _bfd_generic_link_hash_table_free (hash);
800eeca4
JW
1991}
1992
1993/* Traverse both local and global hash tables. */
1994
bbe66d08 1995struct elfNN_ia64_dyn_sym_traverse_data
800eeca4 1996{
eae50df2 1997 bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR);
800eeca4
JW
1998 PTR data;
1999};
2000
b34976b6 2001static bfd_boolean
eae50df2
L
2002elfNN_ia64_global_dyn_sym_thunk (struct bfd_hash_entry *xentry,
2003 PTR xdata)
800eeca4 2004{
bbe66d08
JW
2005 struct elfNN_ia64_link_hash_entry *entry
2006 = (struct elfNN_ia64_link_hash_entry *) xentry;
2007 struct elfNN_ia64_dyn_sym_traverse_data *data
2008 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
2009 struct elfNN_ia64_dyn_sym_info *dyn_i;
396a682d 2010 unsigned int count;
800eeca4 2011
e92d460e
AM
2012 if (entry->root.root.type == bfd_link_hash_warning)
2013 entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
2014
396a682d
L
2015 for (count = entry->count, dyn_i = entry->info;
2016 count != 0;
2017 count--, dyn_i++)
800eeca4 2018 if (! (*data->func) (dyn_i, data->data))
b34976b6
AM
2019 return FALSE;
2020 return TRUE;
800eeca4
JW
2021}
2022
b34976b6 2023static bfd_boolean
eae50df2 2024elfNN_ia64_local_dyn_sym_thunk (void **slot, PTR xdata)
800eeca4 2025{
bbe66d08 2026 struct elfNN_ia64_local_hash_entry *entry
0aa92b58 2027 = (struct elfNN_ia64_local_hash_entry *) *slot;
bbe66d08
JW
2028 struct elfNN_ia64_dyn_sym_traverse_data *data
2029 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
2030 struct elfNN_ia64_dyn_sym_info *dyn_i;
396a682d 2031 unsigned int count;
800eeca4 2032
396a682d
L
2033 for (count = entry->count, dyn_i = entry->info;
2034 count != 0;
2035 count--, dyn_i++)
800eeca4 2036 if (! (*data->func) (dyn_i, data->data))
396a682d
L
2037 return FALSE;
2038 return TRUE;
800eeca4
JW
2039}
2040
2041static void
eae50df2
L
2042elfNN_ia64_dyn_sym_traverse (struct elfNN_ia64_link_hash_table *ia64_info,
2043 bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
2044 PTR data)
800eeca4 2045{
bbe66d08 2046 struct elfNN_ia64_dyn_sym_traverse_data xdata;
800eeca4
JW
2047
2048 xdata.func = func;
2049 xdata.data = data;
2050
2051 elf_link_hash_traverse (&ia64_info->root,
bbe66d08 2052 elfNN_ia64_global_dyn_sym_thunk, &xdata);
0aa92b58
JJ
2053 htab_traverse (ia64_info->loc_hash_table,
2054 elfNN_ia64_local_dyn_sym_thunk, &xdata);
800eeca4
JW
2055}
2056\f
b34976b6 2057static bfd_boolean
eae50df2
L
2058elfNN_ia64_create_dynamic_sections (bfd *abfd,
2059 struct bfd_link_info *info)
800eeca4 2060{
bbe66d08 2061 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
2062 asection *s;
2063
2064 if (! _bfd_elf_create_dynamic_sections (abfd, info))
b34976b6 2065 return FALSE;
800eeca4 2066
bbe66d08 2067 ia64_info = elfNN_ia64_hash_table (info);
4dfe6ac6
NC
2068 if (ia64_info == NULL)
2069 return FALSE;
800eeca4 2070
800eeca4 2071 {
cc3bd654
L
2072 flagword flags = bfd_get_section_flags (abfd, ia64_info->root.sgot);
2073 bfd_set_section_flags (abfd, ia64_info->root.sgot,
2074 SEC_SMALL_DATA | flags);
69bbc4c0 2075 /* The .got section is always aligned at 8 bytes. */
cc3bd654 2076 bfd_set_section_alignment (abfd, ia64_info->root.sgot, 3);
800eeca4
JW
2077 }
2078
2079 if (!get_pltoff (abfd, info, ia64_info))
b34976b6 2080 return FALSE;
800eeca4 2081
3496cb2a
L
2082 s = bfd_make_section_with_flags (abfd, ".rela.IA_64.pltoff",
2083 (SEC_ALLOC | SEC_LOAD
2084 | SEC_HAS_CONTENTS
2085 | SEC_IN_MEMORY
2086 | SEC_LINKER_CREATED
2087 | SEC_READONLY));
800eeca4 2088 if (s == NULL
5a260b66 2089 || !bfd_set_section_alignment (abfd, s, LOG_SECTION_ALIGN))
b34976b6 2090 return FALSE;
800eeca4
JW
2091 ia64_info->rel_pltoff_sec = s;
2092
b34976b6 2093 return TRUE;
800eeca4
JW
2094}
2095
f7460f5f
JJ
2096/* Find and/or create a hash entry for local symbol. */
2097static struct elfNN_ia64_local_hash_entry *
eae50df2
L
2098get_local_sym_hash (struct elfNN_ia64_link_hash_table *ia64_info,
2099 bfd *abfd, const Elf_Internal_Rela *rel,
2100 bfd_boolean create)
f7460f5f 2101{
0aa92b58 2102 struct elfNN_ia64_local_hash_entry e, *ret;
d48770d4 2103 asection *sec = abfd->sections;
d2149d72
L
2104 hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
2105 ELFNN_R_SYM (rel->r_info));
0aa92b58 2106 void **slot;
d48770d4 2107
0aa92b58
JJ
2108 e.id = sec->id;
2109 e.r_sym = ELFNN_R_SYM (rel->r_info);
2110 slot = htab_find_slot_with_hash (ia64_info->loc_hash_table, &e, h,
2111 create ? INSERT : NO_INSERT);
f7460f5f 2112
0aa92b58
JJ
2113 if (!slot)
2114 return NULL;
f7460f5f 2115
0aa92b58
JJ
2116 if (*slot)
2117 return (struct elfNN_ia64_local_hash_entry *) *slot;
f7460f5f 2118
0aa92b58
JJ
2119 ret = (struct elfNN_ia64_local_hash_entry *)
2120 objalloc_alloc ((struct objalloc *) ia64_info->loc_hash_memory,
2121 sizeof (struct elfNN_ia64_local_hash_entry));
2122 if (ret)
2123 {
2124 memset (ret, 0, sizeof (*ret));
2125 ret->id = sec->id;
2126 ret->r_sym = ELFNN_R_SYM (rel->r_info);
2127 *slot = ret;
2128 }
fcf12726 2129 return ret;
f7460f5f
JJ
2130}
2131
396a682d
L
2132/* Used to sort elfNN_ia64_dyn_sym_info array. */
2133
2134static int
2135addend_compare (const void *xp, const void *yp)
2136{
2137 const struct elfNN_ia64_dyn_sym_info *x
2138 = (const struct elfNN_ia64_dyn_sym_info *) xp;
2139 const struct elfNN_ia64_dyn_sym_info *y
2140 = (const struct elfNN_ia64_dyn_sym_info *) yp;
2141
c26620e3 2142 return x->addend < y->addend ? -1 : x->addend > y->addend ? 1 : 0;
396a682d
L
2143}
2144
2145/* Sort elfNN_ia64_dyn_sym_info array and remove duplicates. */
2146
2147static unsigned int
2148sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info *info,
2149 unsigned int count)
2150{
293a0124 2151 bfd_vma curr, prev, got_offset;
91d6fa6a 2152 unsigned int i, kept, dupes, diff, dest, src, len;
396a682d
L
2153
2154 qsort (info, count, sizeof (*info), addend_compare);
2155
2156 /* Find the first duplicate. */
2157 prev = info [0].addend;
293a0124 2158 got_offset = info [0].got_offset;
396a682d
L
2159 for (i = 1; i < count; i++)
2160 {
2161 curr = info [i].addend;
2162 if (curr == prev)
293a0124
L
2163 {
2164 /* For duplicates, make sure that GOT_OFFSET is valid. */
2165 if (got_offset == (bfd_vma) -1)
2166 got_offset = info [i].got_offset;
2167 break;
2168 }
2169 got_offset = info [i].got_offset;
396a682d
L
2170 prev = curr;
2171 }
2172
293a0124
L
2173 /* We may move a block of elements to here. */
2174 dest = i++;
2175
396a682d
L
2176 /* Remove duplicates. */
2177 if (i < count)
2178 {
396a682d
L
2179 while (i < count)
2180 {
293a0124
L
2181 /* For duplicates, make sure that the kept one has a valid
2182 got_offset. */
2183 kept = dest - 1;
2184 if (got_offset != (bfd_vma) -1)
2185 info [kept].got_offset = got_offset;
2186
396a682d 2187 curr = info [i].addend;
293a0124 2188 got_offset = info [i].got_offset;
396a682d
L
2189
2190 /* Move a block of elements whose first one is different from
2191 the previous. */
2192 if (curr == prev)
2193 {
2194 for (src = i + 1; src < count; src++)
293a0124
L
2195 {
2196 if (info [src].addend != curr)
2197 break;
2198 /* For duplicates, make sure that GOT_OFFSET is
2199 valid. */
2200 if (got_offset == (bfd_vma) -1)
2201 got_offset = info [src].got_offset;
2202 }
2203
2204 /* Make sure that the kept one has a valid got_offset. */
2205 if (got_offset != (bfd_vma) -1)
2206 info [kept].got_offset = got_offset;
396a682d
L
2207 }
2208 else
2209 src = i;
2210
2211 if (src >= count)
2212 break;
2213
293a0124 2214 /* Find the next duplicate. SRC will be kept. */
396a682d 2215 prev = info [src].addend;
293a0124 2216 got_offset = info [src].got_offset;
91d6fa6a 2217 for (dupes = src + 1; dupes < count; dupes ++)
396a682d 2218 {
91d6fa6a 2219 curr = info [dupes].addend;
396a682d 2220 if (curr == prev)
293a0124
L
2221 {
2222 /* Make sure that got_offset is valid. */
2223 if (got_offset == (bfd_vma) -1)
91d6fa6a 2224 got_offset = info [dupes].got_offset;
293a0124
L
2225
2226 /* For duplicates, make sure that the kept one has
2227 a valid got_offset. */
2228 if (got_offset != (bfd_vma) -1)
91d6fa6a 2229 info [dupes - 1].got_offset = got_offset;
293a0124
L
2230 break;
2231 }
91d6fa6a 2232 got_offset = info [dupes].got_offset;
396a682d
L
2233 prev = curr;
2234 }
2235
2236 /* How much to move. */
91d6fa6a
NC
2237 len = dupes - src;
2238 i = dupes + 1;
396a682d 2239
91d6fa6a 2240 if (len == 1 && dupes < count)
396a682d
L
2241 {
2242 /* If we only move 1 element, we combine it with the next
293a0124
L
2243 one. There must be at least a duplicate. Find the
2244 next different one. */
91d6fa6a 2245 for (diff = dupes + 1, src++; diff < count; diff++, src++)
293a0124
L
2246 {
2247 if (info [diff].addend != curr)
2248 break;
2249 /* Make sure that got_offset is valid. */
2250 if (got_offset == (bfd_vma) -1)
2251 got_offset = info [diff].got_offset;
2252 }
2253
2254 /* Makre sure that the last duplicated one has an valid
2255 offset. */
2256 BFD_ASSERT (curr == prev);
2257 if (got_offset != (bfd_vma) -1)
2258 info [diff - 1].got_offset = got_offset;
396a682d
L
2259
2260 if (diff < count)
2261 {
293a0124
L
2262 /* Find the next duplicate. Track the current valid
2263 offset. */
396a682d 2264 prev = info [diff].addend;
293a0124 2265 got_offset = info [diff].got_offset;
91d6fa6a 2266 for (dupes = diff + 1; dupes < count; dupes ++)
396a682d 2267 {
91d6fa6a 2268 curr = info [dupes].addend;
396a682d 2269 if (curr == prev)
293a0124
L
2270 {
2271 /* For duplicates, make sure that GOT_OFFSET
2272 is valid. */
2273 if (got_offset == (bfd_vma) -1)
91d6fa6a 2274 got_offset = info [dupes].got_offset;
293a0124
L
2275 break;
2276 }
91d6fa6a 2277 got_offset = info [dupes].got_offset;
396a682d
L
2278 prev = curr;
2279 diff++;
2280 }
2281
2282 len = diff - src + 1;
2283 i = diff + 1;
2284 }
2285 }
2286
2287 memmove (&info [dest], &info [src], len * sizeof (*info));
2288
2289 dest += len;
2290 }
2291
2292 count = dest;
2293 }
293a0124
L
2294 else
2295 {
2296 /* When we get here, either there is no duplicate at all or
2297 the only duplicate is the last element. */
2298 if (dest < count)
2299 {
2300 /* If the last element is a duplicate, make sure that the
2301 kept one has a valid got_offset. We also update count. */
2302 if (got_offset != (bfd_vma) -1)
2303 info [dest - 1].got_offset = got_offset;
2304 count = dest;
2305 }
2306 }
396a682d
L
2307
2308 return count;
2309}
2310
800eeca4 2311/* Find and/or create a descriptor for dynamic symbol info. This will
396a682d
L
2312 vary based on global or local symbol, and the addend to the reloc.
2313
2314 We don't sort when inserting. Also, we sort and eliminate
2315 duplicates if there is an unsorted section. Typically, this will
2316 only happen once, because we do all insertions before lookups. We
2317 then use bsearch to do a lookup. This also allows lookups to be
2318 fast. So we have fast insertion (O(log N) due to duplicate check),
2319 fast lookup (O(log N)) and one sort (O(N log N) expected time).
2320 Previously, all lookups were O(N) because of the use of the linked
2321 list and also all insertions were O(N) because of the check for
2322 duplicates. There are some complications here because the array
2323 size grows occasionally, which may add an O(N) factor, but this
2324 should be rare. Also, we free the excess array allocation, which
2325 requires a copy which is O(N), but this only happens once. */
800eeca4 2326
bbe66d08 2327static struct elfNN_ia64_dyn_sym_info *
eae50df2
L
2328get_dyn_sym_info (struct elfNN_ia64_link_hash_table *ia64_info,
2329 struct elf_link_hash_entry *h, bfd *abfd,
2330 const Elf_Internal_Rela *rel, bfd_boolean create)
800eeca4 2331{
396a682d
L
2332 struct elfNN_ia64_dyn_sym_info **info_p, *info, *dyn_i, key;
2333 unsigned int *count_p, *sorted_count_p, *size_p;
2334 unsigned int count, sorted_count, size;
800eeca4 2335 bfd_vma addend = rel ? rel->r_addend : 0;
396a682d 2336 bfd_size_type amt;
3e932841 2337
800eeca4 2338 if (h)
396a682d
L
2339 {
2340 struct elfNN_ia64_link_hash_entry *global_h;
2341
2342 global_h = (struct elfNN_ia64_link_hash_entry *) h;
2343 info_p = &global_h->info;
2344 count_p = &global_h->count;
2345 sorted_count_p = &global_h->sorted_count;
2346 size_p = &global_h->size;
2347 }
800eeca4
JW
2348 else
2349 {
bbe66d08 2350 struct elfNN_ia64_local_hash_entry *loc_h;
800eeca4 2351
f7460f5f 2352 loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
f86b235a
RH
2353 if (!loc_h)
2354 {
2355 BFD_ASSERT (!create);
2356 return NULL;
2357 }
800eeca4 2358
396a682d
L
2359 info_p = &loc_h->info;
2360 count_p = &loc_h->count;
2361 sorted_count_p = &loc_h->sorted_count;
2362 size_p = &loc_h->size;
3e932841 2363 }
800eeca4 2364
396a682d
L
2365 count = *count_p;
2366 sorted_count = *sorted_count_p;
2367 size = *size_p;
2368 info = *info_p;
2369 if (create)
800eeca4 2370 {
396a682d
L
2371 /* When we create the array, we don't check for duplicates,
2372 except in the previously sorted section if one exists, and
2373 against the last inserted entry. This allows insertions to
2374 be fast. */
2375 if (info)
2376 {
2377 if (sorted_count)
2378 {
2379 /* Try bsearch first on the sorted section. */
2380 key.addend = addend;
2381 dyn_i = bsearch (&key, info, sorted_count,
2382 sizeof (*info), addend_compare);
2383
2384 if (dyn_i)
2385 {
2386 return dyn_i;
2387 }
2388 }
2389
2390 /* Do a quick check for the last inserted entry. */
2391 dyn_i = info + count - 1;
2392 if (dyn_i->addend == addend)
2393 {
2394 return dyn_i;
2395 }
2396 }
2397
2398 if (size == 0)
2399 {
2400 /* It is the very first element. We create the array of size
2401 1. */
2402 size = 1;
2403 amt = size * sizeof (*info);
2404 info = bfd_malloc (amt);
2405 }
2406 else if (size <= count)
2407 {
2408 /* We double the array size every time when we reach the
2409 size limit. */
2410 size += size;
2411 amt = size * sizeof (*info);
2412 info = bfd_realloc (info, amt);
2413 }
2414 else
2415 goto has_space;
2416
2417 if (info == NULL)
2418 return NULL;
2419 *size_p = size;
2420 *info_p = info;
2421
2422has_space:
2423 /* Append the new one to the array. */
2424 dyn_i = info + count;
2425 memset (dyn_i, 0, sizeof (*dyn_i));
293a0124 2426 dyn_i->got_offset = (bfd_vma) -1;
800eeca4 2427 dyn_i->addend = addend;
9a2e389a 2428
396a682d
L
2429 /* We increment count only since the new ones are unsorted and
2430 may have duplicate. */
2431 (*count_p)++;
2432 }
2433 else
2434 {
2435 /* It is a lookup without insertion. Sort array if part of the
2436 array isn't sorted. */
2437 if (count != sorted_count)
2438 {
2439 count = sort_dyn_sym_info (info, count);
2440 *count_p = count;
2441 *sorted_count_p = count;
2442 }
2443
2444 /* Free unused memory. */
2445 if (size != count)
2446 {
2447 amt = count * sizeof (*info);
2448 info = bfd_malloc (amt);
2449 if (info != NULL)
2450 {
2451 memcpy (info, *info_p, amt);
2452 free (*info_p);
2453 *size_p = count;
2454 *info_p = info;
2455 }
2456 }
2457
2458 key.addend = addend;
2459 dyn_i = bsearch (&key, info, count,
2460 sizeof (*info), addend_compare);
800eeca4
JW
2461 }
2462
2463 return dyn_i;
2464}
2465
2466static asection *
eae50df2
L
2467get_got (bfd *abfd, struct bfd_link_info *info,
2468 struct elfNN_ia64_link_hash_table *ia64_info)
800eeca4 2469{
64bf6ae6 2470 asection *got;
800eeca4
JW
2471 bfd *dynobj;
2472
cc3bd654 2473 got = ia64_info->root.sgot;
800eeca4
JW
2474 if (!got)
2475 {
2476 flagword flags;
2477
2478 dynobj = ia64_info->root.dynobj;
2479 if (!dynobj)
2480 ia64_info->root.dynobj = dynobj = abfd;
2481 if (!_bfd_elf_create_got_section (dynobj, info))
2482 return 0;
2483
cc3bd654 2484 got = ia64_info->root.sgot;
800eeca4 2485
8651fcf9
L
2486 /* The .got section is always aligned at 8 bytes. */
2487 if (!bfd_set_section_alignment (abfd, got, 3))
2488 return 0;
2489
800eeca4
JW
2490 flags = bfd_get_section_flags (abfd, got);
2491 bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
2492 }
2493
2494 return got;
2495}
2496
2497/* Create function descriptor section (.opd). This section is called .opd
4cc11e76 2498 because it contains "official procedure descriptors". The "official"
800eeca4
JW
2499 refers to the fact that these descriptors are used when taking the address
2500 of a procedure, thus ensuring a unique address for each procedure. */
2501
2502static asection *
eae50df2
L
2503get_fptr (bfd *abfd, struct bfd_link_info *info,
2504 struct elfNN_ia64_link_hash_table *ia64_info)
800eeca4
JW
2505{
2506 asection *fptr;
2507 bfd *dynobj;
2508
2509 fptr = ia64_info->fptr_sec;
2510 if (!fptr)
2511 {
2512 dynobj = ia64_info->root.dynobj;
2513 if (!dynobj)
2514 ia64_info->root.dynobj = dynobj = abfd;
2515
3496cb2a
L
2516 fptr = bfd_make_section_with_flags (dynobj, ".opd",
2517 (SEC_ALLOC
2518 | SEC_LOAD
2519 | SEC_HAS_CONTENTS
2520 | SEC_IN_MEMORY
2521 | (info->pie ? 0 : SEC_READONLY)
2522 | SEC_LINKER_CREATED));
800eeca4 2523 if (!fptr
800eeca4
JW
2524 || !bfd_set_section_alignment (abfd, fptr, 4))
2525 {
2526 BFD_ASSERT (0);
2527 return NULL;
2528 }
2529
2530 ia64_info->fptr_sec = fptr;
9203ba99
JJ
2531
2532 if (info->pie)
2533 {
2534 asection *fptr_rel;
3496cb2a
L
2535 fptr_rel = bfd_make_section_with_flags (dynobj, ".rela.opd",
2536 (SEC_ALLOC | SEC_LOAD
2537 | SEC_HAS_CONTENTS
2538 | SEC_IN_MEMORY
2539 | SEC_LINKER_CREATED
2540 | SEC_READONLY));
9203ba99 2541 if (fptr_rel == NULL
5a260b66
L
2542 || !bfd_set_section_alignment (abfd, fptr_rel,
2543 LOG_SECTION_ALIGN))
9203ba99
JJ
2544 {
2545 BFD_ASSERT (0);
2546 return NULL;
2547 }
2548
2549 ia64_info->rel_fptr_sec = fptr_rel;
2550 }
800eeca4
JW
2551 }
2552
2553 return fptr;
2554}
2555
2556static asection *
eae50df2
L
2557get_pltoff (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED,
2558 struct elfNN_ia64_link_hash_table *ia64_info)
800eeca4
JW
2559{
2560 asection *pltoff;
2561 bfd *dynobj;
2562
2563 pltoff = ia64_info->pltoff_sec;
2564 if (!pltoff)
2565 {
2566 dynobj = ia64_info->root.dynobj;
2567 if (!dynobj)
2568 ia64_info->root.dynobj = dynobj = abfd;
2569
3496cb2a
L
2570 pltoff = bfd_make_section_with_flags (dynobj,
2571 ELF_STRING_ia64_pltoff,
2572 (SEC_ALLOC
2573 | SEC_LOAD
2574 | SEC_HAS_CONTENTS
2575 | SEC_IN_MEMORY
2576 | SEC_SMALL_DATA
2577 | SEC_LINKER_CREATED));
800eeca4 2578 if (!pltoff
800eeca4
JW
2579 || !bfd_set_section_alignment (abfd, pltoff, 4))
2580 {
2581 BFD_ASSERT (0);
2582 return NULL;
2583 }
2584
2585 ia64_info->pltoff_sec = pltoff;
2586 }
2587
2588 return pltoff;
2589}
2590
2591static asection *
eae50df2
L
2592get_reloc_section (bfd *abfd,
2593 struct elfNN_ia64_link_hash_table *ia64_info,
2594 asection *sec, bfd_boolean create)
800eeca4
JW
2595{
2596 const char *srel_name;
2597 asection *srel;
2598 bfd *dynobj;
2599
2600 srel_name = (bfd_elf_string_from_elf_section
2601 (abfd, elf_elfheader(abfd)->e_shstrndx,
d4730f92 2602 _bfd_elf_single_rel_hdr (sec)->sh_name));
800eeca4
JW
2603 if (srel_name == NULL)
2604 return NULL;
2605
800eeca4
JW
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:
d68cd58c 3878 hit_addr -= (intptr_t) 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 3906 case IA64_OPND_TGT64:
d68cd58c 3907 hit_addr -= (intptr_t) 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 3931 default:
d68cd58c 3932 switch ((intptr_t) hit_addr & 0x3)
800eeca4
JW
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
e57278ef 4301elfNN_ia64_choose_gp (bfd *abfd, struct bfd_link_info *info, bfd_boolean final)
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;
e57278ef
AM
4324 /* When this function is called from elfNN_ia64_final_link
4325 the correct value to use is os->size. When called from
4326 elfNN_ia64_relax_section we are in the middle of section
4327 sizing; some sections will already have os->size set, others
4328 will have os->size zero and os->rawsize the previous size. */
4329 hi = os->vma + (!final && os->rawsize ? os->rawsize : os->size);
2c4c2bc0
RH
4330 if (hi < lo)
4331 hi = (bfd_vma) -1;
4332
4333 if (min_vma > lo)
4334 min_vma = lo;
4335 if (max_vma < hi)
4336 max_vma = hi;
4337 if (os->flags & SEC_SMALL_DATA)
800eeca4 4338 {
2c4c2bc0
RH
4339 if (min_short_vma > lo)
4340 min_short_vma = lo;
4341 if (max_short_vma < hi)
4342 max_short_vma = hi;
4343 }
4344 }
800eeca4 4345
a231ddc0
L
4346 if (ia64_info->min_short_sec)
4347 {
4348 if (min_short_vma
affb4bf3 4349 > (ia64_info->min_short_sec->vma
a231ddc0 4350 + ia64_info->min_short_offset))
affb4bf3 4351 min_short_vma = (ia64_info->min_short_sec->vma
a231ddc0
L
4352 + ia64_info->min_short_offset);
4353 if (max_short_vma
affb4bf3 4354 < (ia64_info->max_short_sec->vma
a231ddc0 4355 + ia64_info->max_short_offset))
affb4bf3 4356 max_short_vma = (ia64_info->max_short_sec->vma
a231ddc0
L
4357 + ia64_info->max_short_offset);
4358 }
4359
2c4c2bc0
RH
4360 /* See if the user wants to force a value. */
4361 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
4362 FALSE, FALSE);
800eeca4 4363
2c4c2bc0
RH
4364 if (gp
4365 && (gp->root.type == bfd_link_hash_defined
4366 || gp->root.type == bfd_link_hash_defweak))
4367 {
4368 asection *gp_sec = gp->root.u.def.section;
4369 gp_val = (gp->root.u.def.value
4370 + gp_sec->output_section->vma
4371 + gp_sec->output_offset);
4372 }
4373 else
4374 {
4375 /* Pick a sensible value. */
800eeca4 4376
a231ddc0
L
4377 if (ia64_info->min_short_sec)
4378 {
4379 bfd_vma short_range = max_short_vma - min_short_vma;
2c4c2bc0 4380
a231ddc0
L
4381 /* If min_short_sec is set, pick one in the middle bewteen
4382 min_short_vma and max_short_vma. */
4383 if (short_range >= 0x400000)
4384 goto overflow;
4385 gp_val = min_short_vma + short_range / 2;
4386 }
6d2cf7d8 4387 else
a231ddc0
L
4388 {
4389 asection *got_sec = ia64_info->root.sgot;
4390
4391 /* Start with just the address of the .got. */
4392 if (got_sec)
4393 gp_val = got_sec->output_section->vma;
4394 else if (max_short_vma != 0)
4395 gp_val = min_short_vma;
4396 else if (max_vma - min_vma < 0x200000)
4397 gp_val = min_vma;
4398 else
4399 gp_val = max_vma - 0x200000 + 8;
4400 }
2c4c2bc0
RH
4401
4402 /* If it is possible to address the entire image, but we
4403 don't with the choice above, adjust. */
4404 if (max_vma - min_vma < 0x400000
6d2cf7d8
L
4405 && (max_vma - gp_val >= 0x200000
4406 || gp_val - min_vma > 0x200000))
2c4c2bc0
RH
4407 gp_val = min_vma + 0x200000;
4408 else if (max_short_vma != 0)
4409 {
4410 /* If we don't cover all the short data, adjust. */
4411 if (max_short_vma - gp_val >= 0x200000)
4412 gp_val = min_short_vma + 0x200000;
4413
4414 /* If we're addressing stuff past the end, adjust back. */
4415 if (gp_val > max_vma)
4416 gp_val = max_vma - 0x200000 + 8;
800eeca4 4417 }
2c4c2bc0 4418 }
800eeca4 4419
2c4c2bc0
RH
4420 /* Validate whether all SHF_IA_64_SHORT sections are within
4421 range of the chosen GP. */
800eeca4 4422
2c4c2bc0
RH
4423 if (max_short_vma != 0)
4424 {
4425 if (max_short_vma - min_short_vma >= 0x400000)
800eeca4 4426 {
a231ddc0 4427overflow:
2c4c2bc0
RH
4428 (*_bfd_error_handler)
4429 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
4430 bfd_get_filename (abfd),
4431 (unsigned long) (max_short_vma - min_short_vma));
4432 return FALSE;
800eeca4 4433 }
2c4c2bc0
RH
4434 else if ((gp_val > min_short_vma
4435 && gp_val - min_short_vma > 0x200000)
4436 || (gp_val < max_short_vma
4437 && max_short_vma - gp_val >= 0x200000))
800eeca4 4438 {
2c4c2bc0
RH
4439 (*_bfd_error_handler)
4440 (_("%s: __gp does not cover short data segment"),
4441 bfd_get_filename (abfd));
4442 return FALSE;
4443 }
4444 }
800eeca4 4445
2c4c2bc0 4446 _bfd_set_gp_value (abfd, gp_val);
800eeca4 4447
2c4c2bc0
RH
4448 return TRUE;
4449}
800eeca4 4450
2c4c2bc0 4451static bfd_boolean
eae50df2 4452elfNN_ia64_final_link (bfd *abfd, struct bfd_link_info *info)
2c4c2bc0
RH
4453{
4454 struct elfNN_ia64_link_hash_table *ia64_info;
4455 asection *unwind_output_sec;
800eeca4 4456
2c4c2bc0 4457 ia64_info = elfNN_ia64_hash_table (info);
4dfe6ac6
NC
4458 if (ia64_info == NULL)
4459 return FALSE;
800eeca4 4460
2c4c2bc0 4461 /* Make sure we've got ourselves a nice fat __gp value. */
1049f94e 4462 if (!info->relocatable)
2c4c2bc0 4463 {
a38a2e96 4464 bfd_vma gp_val;
2c4c2bc0
RH
4465 struct elf_link_hash_entry *gp;
4466
a38a2e96
L
4467 /* We assume after gp is set, section size will only decrease. We
4468 need to adjust gp for it. */
4469 _bfd_set_gp_value (abfd, 0);
e57278ef 4470 if (! elfNN_ia64_choose_gp (abfd, info, TRUE))
a38a2e96
L
4471 return FALSE;
4472 gp_val = _bfd_get_gp_value (abfd);
800eeca4 4473
2c4c2bc0
RH
4474 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
4475 FALSE, FALSE);
b4adccfd
RH
4476 if (gp)
4477 {
4478 gp->root.type = bfd_link_hash_defined;
4479 gp->root.u.def.value = gp_val;
4480 gp->root.u.def.section = bfd_abs_section_ptr;
4481 }
800eeca4
JW
4482 }
4483
f3b6f7c3 4484 /* If we're producing a final executable, we need to sort the contents
9a951beb
RH
4485 of the .IA_64.unwind section. Force this section to be relocated
4486 into memory rather than written immediately to the output file. */
4487 unwind_output_sec = NULL;
1049f94e 4488 if (!info->relocatable)
f3b6f7c3
RH
4489 {
4490 asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
4491 if (s)
4492 {
9a951beb
RH
4493 unwind_output_sec = s->output_section;
4494 unwind_output_sec->contents
eea6121a 4495 = bfd_malloc (unwind_output_sec->size);
9a951beb 4496 if (unwind_output_sec->contents == NULL)
b34976b6 4497 return FALSE;
9a951beb
RH
4498 }
4499 }
f3b6f7c3 4500
9a951beb 4501 /* Invoke the regular ELF backend linker to do all the work. */
c152c796 4502 if (!bfd_elf_final_link (abfd, info))
b34976b6 4503 return FALSE;
f3b6f7c3 4504
9a951beb
RH
4505 if (unwind_output_sec)
4506 {
4507 elfNN_ia64_unwind_entry_compare_bfd = abfd;
dc810e39 4508 qsort (unwind_output_sec->contents,
eea6121a 4509 (size_t) (unwind_output_sec->size / 24),
dc810e39
AM
4510 24,
4511 elfNN_ia64_unwind_entry_compare);
9a951beb
RH
4512
4513 if (! bfd_set_section_contents (abfd, unwind_output_sec,
dc810e39 4514 unwind_output_sec->contents, (bfd_vma) 0,
eea6121a 4515 unwind_output_sec->size))
b34976b6 4516 return FALSE;
f3b6f7c3
RH
4517 }
4518
b34976b6 4519 return TRUE;
800eeca4
JW
4520}
4521
b34976b6 4522static bfd_boolean
eae50df2
L
4523elfNN_ia64_relocate_section (bfd *output_bfd,
4524 struct bfd_link_info *info,
4525 bfd *input_bfd,
4526 asection *input_section,
4527 bfd_byte *contents,
4528 Elf_Internal_Rela *relocs,
4529 Elf_Internal_Sym *local_syms,
4530 asection **local_sections)
800eeca4 4531{
bbe66d08 4532 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
4533 Elf_Internal_Shdr *symtab_hdr;
4534 Elf_Internal_Rela *rel;
4535 Elf_Internal_Rela *relend;
4536 asection *srel;
b34976b6 4537 bfd_boolean ret_val = TRUE; /* for non-fatal errors */
800eeca4
JW
4538 bfd_vma gp_val;
4539
4540 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
bbe66d08 4541 ia64_info = elfNN_ia64_hash_table (info);
4dfe6ac6
NC
4542 if (ia64_info == NULL)
4543 return FALSE;
800eeca4
JW
4544
4545 /* Infect various flags from the input section to the output section. */
1049f94e 4546 if (info->relocatable)
800eeca4
JW
4547 {
4548 bfd_vma flags;
4549
4550 flags = elf_section_data(input_section)->this_hdr.sh_flags;
4551 flags &= SHF_IA_64_NORECOV;
4552
4553 elf_section_data(input_section->output_section)
4554 ->this_hdr.sh_flags |= flags;
4555 }
4556
4557 gp_val = _bfd_get_gp_value (output_bfd);
b34976b6 4558 srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
800eeca4
JW
4559
4560 rel = relocs;
4561 relend = relocs + input_section->reloc_count;
4562 for (; rel < relend; ++rel)
4563 {
4564 struct elf_link_hash_entry *h;
bbe66d08 4565 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4
JW
4566 bfd_reloc_status_type r;
4567 reloc_howto_type *howto;
4568 unsigned long r_symndx;
4569 Elf_Internal_Sym *sym;
4570 unsigned int r_type;
4571 bfd_vma value;
4572 asection *sym_sec;
4573 bfd_byte *hit_addr;
b34976b6
AM
4574 bfd_boolean dynamic_symbol_p;
4575 bfd_boolean undef_weak_ref;
800eeca4 4576
bbe66d08 4577 r_type = ELFNN_R_TYPE (rel->r_info);
800eeca4
JW
4578 if (r_type > R_IA64_MAX_RELOC_CODE)
4579 {
4580 (*_bfd_error_handler)
d003868e
AM
4581 (_("%B: unknown relocation type %d"),
4582 input_bfd, (int) r_type);
800eeca4 4583 bfd_set_error (bfd_error_bad_value);
b34976b6 4584 ret_val = FALSE;
800eeca4
JW
4585 continue;
4586 }
b491616a 4587
800eeca4 4588 howto = lookup_howto (r_type);
bbe66d08 4589 r_symndx = ELFNN_R_SYM (rel->r_info);
800eeca4
JW
4590 h = NULL;
4591 sym = NULL;
4592 sym_sec = NULL;
b34976b6 4593 undef_weak_ref = FALSE;
800eeca4
JW
4594
4595 if (r_symndx < symtab_hdr->sh_info)
4596 {
4597 /* Reloc against local symbol. */
8517fae7 4598 asection *msec;
800eeca4
JW
4599 sym = local_syms + r_symndx;
4600 sym_sec = local_sections[r_symndx];
8517fae7
AM
4601 msec = sym_sec;
4602 value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
ab96bf03
AM
4603 if (!info->relocatable
4604 && (sym_sec->flags & SEC_MERGE) != 0
f7460f5f 4605 && ELF_ST_TYPE (sym->st_info) == STT_SECTION
68bfbfcc 4606 && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
f7460f5f
JJ
4607 {
4608 struct elfNN_ia64_local_hash_entry *loc_h;
b34976b6
AM
4609
4610 loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
f7460f5f
JJ
4611 if (loc_h && ! loc_h->sec_merge_done)
4612 {
4613 struct elfNN_ia64_dyn_sym_info *dynent;
396a682d 4614 unsigned int count;
f7460f5f 4615
396a682d
L
4616 for (count = loc_h->count, dynent = loc_h->info;
4617 count != 0;
4618 count--, dynent++)
f7460f5f
JJ
4619 {
4620 msec = sym_sec;
4621 dynent->addend =
4622 _bfd_merged_section_offset (output_bfd, &msec,
4623 elf_section_data (msec)->
65765700 4624 sec_info,
f7460f5f 4625 sym->st_value
753731ee 4626 + dynent->addend);
f7460f5f
JJ
4627 dynent->addend -= sym->st_value;
4628 dynent->addend += msec->output_section->vma
4629 + msec->output_offset
4630 - sym_sec->output_section->vma
4631 - sym_sec->output_offset;
4632 }
293a0124
L
4633
4634 /* We may have introduced duplicated entries. We need
4635 to remove them properly. */
4636 count = sort_dyn_sym_info (loc_h->info, loc_h->count);
4637 if (count != loc_h->count)
4638 {
4639 loc_h->count = count;
4640 loc_h->sorted_count = count;
4641 }
396a682d 4642
f7460f5f
JJ
4643 loc_h->sec_merge_done = 1;
4644 }
4645 }
800eeca4
JW
4646 }
4647 else
4648 {
560e09e9
NC
4649 bfd_boolean unresolved_reloc;
4650 bfd_boolean warned;
b2a8e766 4651 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
800eeca4 4652
b2a8e766
AM
4653 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
4654 r_symndx, symtab_hdr, sym_hashes,
4655 h, sym_sec, value,
4656 unresolved_reloc, warned);
800eeca4 4657
560e09e9 4658 if (h->root.type == bfd_link_hash_undefweak)
b34976b6 4659 undef_weak_ref = TRUE;
560e09e9
NC
4660 else if (warned)
4661 continue;
800eeca4
JW
4662 }
4663
ab96bf03 4664 if (sym_sec != NULL && elf_discarded_section (sym_sec))
e4067dbb
DJ
4665 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
4666 rel, relend, howto, contents);
ab96bf03
AM
4667
4668 if (info->relocatable)
4669 continue;
4670
800eeca4
JW
4671 hit_addr = contents + rel->r_offset;
4672 value += rel->r_addend;
986a241f 4673 dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type);
800eeca4
JW
4674
4675 switch (r_type)
4676 {
4677 case R_IA64_NONE:
4678 case R_IA64_LDXMOV:
4679 continue;
4680
4681 case R_IA64_IMM14:
4682 case R_IA64_IMM22:
4683 case R_IA64_IMM64:
4684 case R_IA64_DIR32MSB:
4685 case R_IA64_DIR32LSB:
4686 case R_IA64_DIR64MSB:
4687 case R_IA64_DIR64LSB:
4688 /* Install a dynamic relocation for this reloc. */
02e6ad56 4689 if ((dynamic_symbol_p || info->shared)
cf35638d 4690 && r_symndx != STN_UNDEF
800eeca4
JW
4691 && (input_section->flags & SEC_ALLOC) != 0)
4692 {
4693 unsigned int dyn_r_type;
4694 long dynindx;
18b27f17 4695 bfd_vma addend;
800eeca4
JW
4696
4697 BFD_ASSERT (srel != NULL);
4698
838e70c5
L
4699 switch (r_type)
4700 {
4701 case R_IA64_IMM14:
4702 case R_IA64_IMM22:
4703 case R_IA64_IMM64:
4704 /* ??? People shouldn't be doing non-pic code in
4705 shared libraries nor dynamic executables. */
4706 (*_bfd_error_handler)
d003868e
AM
4707 (_("%B: non-pic code with imm relocation against dynamic symbol `%s'"),
4708 input_bfd,
26c61ae5
L
4709 h ? h->root.root.string
4710 : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4711 sym_sec));
838e70c5
L
4712 ret_val = FALSE;
4713 continue;
4714
4715 default:
4716 break;
4717 }
4718
800eeca4
JW
4719 /* If we don't need dynamic symbol lookup, find a
4720 matching RELATIVE relocation. */
4721 dyn_r_type = r_type;
986a241f 4722 if (dynamic_symbol_p)
18b27f17
RH
4723 {
4724 dynindx = h->dynindx;
4725 addend = rel->r_addend;
4726 value = 0;
4727 }
800eeca4
JW
4728 else
4729 {
4730 switch (r_type)
4731 {
4732 case R_IA64_DIR32MSB:
4733 dyn_r_type = R_IA64_REL32MSB;
4734 break;
4735 case R_IA64_DIR32LSB:
4736 dyn_r_type = R_IA64_REL32LSB;
4737 break;
4738 case R_IA64_DIR64MSB:
4739 dyn_r_type = R_IA64_REL64MSB;
4740 break;
4741 case R_IA64_DIR64LSB:
4742 dyn_r_type = R_IA64_REL64LSB;
4743 break;
4744
4745 default:
838e70c5 4746 break;
800eeca4
JW
4747 }
4748 dynindx = 0;
18b27f17 4749 addend = value;
800eeca4
JW
4750 }
4751
bbe66d08 4752 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
800eeca4 4753 srel, rel->r_offset, dyn_r_type,
18b27f17 4754 dynindx, addend);
800eeca4 4755 }
ae9a127f 4756 /* Fall through. */
800eeca4
JW
4757
4758 case R_IA64_LTV32MSB:
4759 case R_IA64_LTV32LSB:
4760 case R_IA64_LTV64MSB:
4761 case R_IA64_LTV64LSB:
bbb268c3 4762 r = elfNN_ia64_install_value (hit_addr, value, r_type);
800eeca4
JW
4763 break;
4764
4765 case R_IA64_GPREL22:
4766 case R_IA64_GPREL64I:
4767 case R_IA64_GPREL32MSB:
4768 case R_IA64_GPREL32LSB:
4769 case R_IA64_GPREL64MSB:
4770 case R_IA64_GPREL64LSB:
4771 if (dynamic_symbol_p)
4772 {
4773 (*_bfd_error_handler)
d003868e 4774 (_("%B: @gprel relocation against dynamic symbol %s"),
26c61ae5
L
4775 input_bfd,
4776 h ? h->root.root.string
4777 : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4778 sym_sec));
b34976b6 4779 ret_val = FALSE;
800eeca4
JW
4780 continue;
4781 }
4782 value -= gp_val;
bbb268c3 4783 r = elfNN_ia64_install_value (hit_addr, value, r_type);
800eeca4
JW
4784 break;
4785
4786 case R_IA64_LTOFF22:
4787 case R_IA64_LTOFF22X:
4788 case R_IA64_LTOFF64I:
b34976b6 4789 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
800eeca4 4790 value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
5a260b66 4791 rel->r_addend, value, R_IA64_DIRNNLSB);
800eeca4 4792 value -= gp_val;
bbb268c3 4793 r = elfNN_ia64_install_value (hit_addr, value, r_type);
800eeca4
JW
4794 break;
4795
4796 case R_IA64_PLTOFF22:
4797 case R_IA64_PLTOFF64I:
4798 case R_IA64_PLTOFF64MSB:
4799 case R_IA64_PLTOFF64LSB:
b34976b6
AM
4800 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4801 value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
800eeca4 4802 value -= gp_val;
bbb268c3 4803 r = elfNN_ia64_install_value (hit_addr, value, r_type);
800eeca4
JW
4804 break;
4805
4806 case R_IA64_FPTR64I:
4807 case R_IA64_FPTR32MSB:
4808 case R_IA64_FPTR32LSB:
4809 case R_IA64_FPTR64MSB:
4810 case R_IA64_FPTR64LSB:
b34976b6 4811 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
800eeca4
JW
4812 if (dyn_i->want_fptr)
4813 {
4814 if (!undef_weak_ref)
4815 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4816 }
9203ba99 4817 if (!dyn_i->want_fptr || info->pie)
800eeca4
JW
4818 {
4819 long dynindx;
9203ba99
JJ
4820 unsigned int dyn_r_type = r_type;
4821 bfd_vma addend = rel->r_addend;
800eeca4
JW
4822
4823 /* Otherwise, we expect the dynamic linker to create
4824 the entry. */
4825
9203ba99
JJ
4826 if (dyn_i->want_fptr)
4827 {
4828 if (r_type == R_IA64_FPTR64I)
4829 {
4830 /* We can't represent this without a dynamic symbol.
4831 Adjust the relocation to be against an output
4832 section symbol, which are always present in the
4833 dynamic symbol table. */
4834 /* ??? People shouldn't be doing non-pic code in
4835 shared libraries. Hork. */
4836 (*_bfd_error_handler)
d003868e
AM
4837 (_("%B: linking non-pic code in a position independent executable"),
4838 input_bfd);
9203ba99
JJ
4839 ret_val = FALSE;
4840 continue;
4841 }
4842 dynindx = 0;
4843 addend = value;
5a260b66 4844 dyn_r_type = r_type + R_IA64_RELNNLSB - R_IA64_FPTRNNLSB;
9203ba99
JJ
4845 }
4846 else if (h)
800eeca4
JW
4847 {
4848 if (h->dynindx != -1)
4849 dynindx = h->dynindx;
4850 else
4851 dynindx = (_bfd_elf_link_lookup_local_dynindx
4852 (info, h->root.u.def.section->owner,
4853 global_sym_index (h)));
9203ba99 4854 value = 0;
800eeca4
JW
4855 }
4856 else
4857 {
4858 dynindx = (_bfd_elf_link_lookup_local_dynindx
dc810e39 4859 (info, input_bfd, (long) r_symndx));
9203ba99 4860 value = 0;
800eeca4
JW
4861 }
4862
bbe66d08 4863 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
9203ba99
JJ
4864 srel, rel->r_offset, dyn_r_type,
4865 dynindx, addend);
800eeca4
JW
4866 }
4867
bbb268c3 4868 r = elfNN_ia64_install_value (hit_addr, value, r_type);
800eeca4
JW
4869 break;
4870
4871 case R_IA64_LTOFF_FPTR22:
4872 case R_IA64_LTOFF_FPTR64I:
a4bd8390
JW
4873 case R_IA64_LTOFF_FPTR32MSB:
4874 case R_IA64_LTOFF_FPTR32LSB:
800eeca4
JW
4875 case R_IA64_LTOFF_FPTR64MSB:
4876 case R_IA64_LTOFF_FPTR64LSB:
4877 {
4878 long dynindx;
4879
b34976b6 4880 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
800eeca4
JW
4881 if (dyn_i->want_fptr)
4882 {
f12123c0 4883 BFD_ASSERT (h == NULL || h->dynindx == -1);
800eeca4
JW
4884 if (!undef_weak_ref)
4885 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4886 dynindx = -1;
4887 }
4888 else
4889 {
4890 /* Otherwise, we expect the dynamic linker to create
4891 the entry. */
4892 if (h)
4893 {
4894 if (h->dynindx != -1)
4895 dynindx = h->dynindx;
4896 else
4897 dynindx = (_bfd_elf_link_lookup_local_dynindx
4898 (info, h->root.u.def.section->owner,
4899 global_sym_index (h)));
4900 }
4901 else
4902 dynindx = (_bfd_elf_link_lookup_local_dynindx
dc810e39 4903 (info, input_bfd, (long) r_symndx));
800eeca4
JW
4904 value = 0;
4905 }
4906
4907 value = set_got_entry (output_bfd, info, dyn_i, dynindx,
5a260b66 4908 rel->r_addend, value, R_IA64_FPTRNNLSB);
800eeca4 4909 value -= gp_val;
bbb268c3 4910 r = elfNN_ia64_install_value (hit_addr, value, r_type);
800eeca4
JW
4911 }
4912 break;
4913
4914 case R_IA64_PCREL32MSB:
4915 case R_IA64_PCREL32LSB:
4916 case R_IA64_PCREL64MSB:
4917 case R_IA64_PCREL64LSB:
4918 /* Install a dynamic relocation for this reloc. */
cf35638d 4919 if (dynamic_symbol_p && r_symndx != STN_UNDEF)
800eeca4
JW
4920 {
4921 BFD_ASSERT (srel != NULL);
4922
bbe66d08 4923 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
800eeca4
JW
4924 srel, rel->r_offset, r_type,
4925 h->dynindx, rel->r_addend);
4926 }
4927 goto finish_pcrel;
4928
800eeca4 4929 case R_IA64_PCREL21B:
748abff6 4930 case R_IA64_PCREL60B:
800eeca4 4931 /* We should have created a PLT entry for any dynamic symbol. */
800eeca4
JW
4932 dyn_i = NULL;
4933 if (h)
b34976b6 4934 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
800eeca4
JW
4935
4936 if (dyn_i && dyn_i->want_plt2)
4937 {
4938 /* Should have caught this earlier. */
4939 BFD_ASSERT (rel->r_addend == 0);
4940
cc3bd654
L
4941 value = (ia64_info->root.splt->output_section->vma
4942 + ia64_info->root.splt->output_offset
800eeca4
JW
4943 + dyn_i->plt2_offset);
4944 }
4945 else
4946 {
4947 /* Since there's no PLT entry, Validate that this is
4948 locally defined. */
4949 BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
4950
4951 /* If the symbol is undef_weak, we shouldn't be trying
4952 to call it. There's every chance that we'd wind up
4953 with an out-of-range fixup here. Don't bother setting
4954 any value at all. */
4955 if (undef_weak_ref)
4956 continue;
4957 }
4958 goto finish_pcrel;
4959
2f9bd3f6
RH
4960 case R_IA64_PCREL21BI:
4961 case R_IA64_PCREL21F:
4962 case R_IA64_PCREL21M:
748abff6
RH
4963 case R_IA64_PCREL22:
4964 case R_IA64_PCREL64I:
2f9bd3f6
RH
4965 /* The PCREL21BI reloc is specifically not intended for use with
4966 dynamic relocs. PCREL21F and PCREL21M are used for speculation
f12123c0 4967 fixup code, and thus probably ought not be dynamic. The
2f9bd3f6
RH
4968 PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
4969 if (dynamic_symbol_p)
4970 {
4971 const char *msg;
4972
4973 if (r_type == R_IA64_PCREL21BI)
d003868e 4974 msg = _("%B: @internal branch to dynamic symbol %s");
2f9bd3f6 4975 else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
d003868e 4976 msg = _("%B: speculation fixup to dynamic symbol %s");
2f9bd3f6 4977 else
d003868e 4978 msg = _("%B: @pcrel relocation against dynamic symbol %s");
26c61ae5
L
4979 (*_bfd_error_handler) (msg, input_bfd,
4980 h ? h->root.root.string
4981 : bfd_elf_sym_name (input_bfd,
4982 symtab_hdr,
4983 sym,
4984 sym_sec));
2f9bd3f6
RH
4985 ret_val = FALSE;
4986 continue;
4987 }
4988 goto finish_pcrel;
4989
800eeca4
JW
4990 finish_pcrel:
4991 /* Make pc-relative. */
4992 value -= (input_section->output_section->vma
4993 + input_section->output_offset
4994 + rel->r_offset) & ~ (bfd_vma) 0x3;
bbb268c3 4995 r = elfNN_ia64_install_value (hit_addr, value, r_type);
800eeca4
JW
4996 break;
4997
4998 case R_IA64_SEGREL32MSB:
4999 case R_IA64_SEGREL32LSB:
5000 case R_IA64_SEGREL64MSB:
5001 case R_IA64_SEGREL64LSB:
d7458677 5002 {
d7458677 5003 /* Find the segment that contains the output_section. */
2ea37f1c 5004 Elf_Internal_Phdr *p = _bfd_elf_find_segment_containing_section
992824d5 5005 (output_bfd, input_section->output_section);
800eeca4 5006
2ea37f1c 5007 if (p == NULL)
d7458677 5008 {
800eeca4 5009 r = bfd_reloc_notsupported;
d7458677
AM
5010 }
5011 else
5012 {
5013 /* The VMA of the segment is the vaddr of the associated
5014 program header. */
5015 if (value > p->p_vaddr)
5016 value -= p->p_vaddr;
5017 else
5018 value = 0;
bbb268c3 5019 r = elfNN_ia64_install_value (hit_addr, value, r_type);
d7458677
AM
5020 }
5021 break;
5022 }
800eeca4
JW
5023
5024 case R_IA64_SECREL32MSB:
5025 case R_IA64_SECREL32LSB:
5026 case R_IA64_SECREL64MSB:
5027 case R_IA64_SECREL64LSB:
97ecf322
L
5028 /* Make output-section relative to section where the symbol
5029 is defined. PR 475 */
bf718458
L
5030 if (sym_sec)
5031 value -= sym_sec->output_section->vma;
bbb268c3 5032 r = elfNN_ia64_install_value (hit_addr, value, r_type);
800eeca4
JW
5033 break;
5034
800eeca4
JW
5035 case R_IA64_IPLTMSB:
5036 case R_IA64_IPLTLSB:
18b27f17
RH
5037 /* Install a dynamic relocation for this reloc. */
5038 if ((dynamic_symbol_p || info->shared)
5039 && (input_section->flags & SEC_ALLOC) != 0)
5040 {
18b27f17
RH
5041 BFD_ASSERT (srel != NULL);
5042
5043 /* If we don't need dynamic symbol lookup, install two
5044 RELATIVE relocations. */
986a241f 5045 if (!dynamic_symbol_p)
18b27f17
RH
5046 {
5047 unsigned int dyn_r_type;
3e932841 5048
18b27f17
RH
5049 if (r_type == R_IA64_IPLTMSB)
5050 dyn_r_type = R_IA64_REL64MSB;
5051 else
5052 dyn_r_type = R_IA64_REL64LSB;
5053
5054 elfNN_ia64_install_dyn_reloc (output_bfd, info,
5055 input_section,
5056 srel, rel->r_offset,
5057 dyn_r_type, 0, value);
5058 elfNN_ia64_install_dyn_reloc (output_bfd, info,
5059 input_section,
5060 srel, rel->r_offset + 8,
5061 dyn_r_type, 0, gp_val);
5062 }
5063 else
5064 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
5065 srel, rel->r_offset, r_type,
5066 h->dynindx, rel->r_addend);
5067 }
5068
5069 if (r_type == R_IA64_IPLTMSB)
5070 r_type = R_IA64_DIR64MSB;
5071 else
5072 r_type = R_IA64_DIR64LSB;
bbb268c3
JW
5073 elfNN_ia64_install_value (hit_addr, value, r_type);
5074 r = elfNN_ia64_install_value (hit_addr + 8, gp_val, r_type);
18b27f17 5075 break;
800eeca4 5076
13ae64f3
JJ
5077 case R_IA64_TPREL14:
5078 case R_IA64_TPREL22:
5079 case R_IA64_TPREL64I:
0f2830ff
L
5080 if (elf_hash_table (info)->tls_sec == NULL)
5081 goto missing_tls_sec;
13ae64f3 5082 value -= elfNN_ia64_tprel_base (info);
bbb268c3 5083 r = elfNN_ia64_install_value (hit_addr, value, r_type);
13ae64f3
JJ
5084 break;
5085
5086 case R_IA64_DTPREL14:
5087 case R_IA64_DTPREL22:
5088 case R_IA64_DTPREL64I:
5a260b66
L
5089 case R_IA64_DTPREL32LSB:
5090 case R_IA64_DTPREL32MSB:
b3dfd7fe
JJ
5091 case R_IA64_DTPREL64LSB:
5092 case R_IA64_DTPREL64MSB:
0f2830ff
L
5093 if (elf_hash_table (info)->tls_sec == NULL)
5094 goto missing_tls_sec;
13ae64f3 5095 value -= elfNN_ia64_dtprel_base (info);
bbb268c3 5096 r = elfNN_ia64_install_value (hit_addr, value, r_type);
13ae64f3
JJ
5097 break;
5098
5099 case R_IA64_LTOFF_TPREL22:
5100 case R_IA64_LTOFF_DTPMOD22:
5101 case R_IA64_LTOFF_DTPREL22:
5102 {
5103 int got_r_type;
a823975a
JJ
5104 long dynindx = h ? h->dynindx : -1;
5105 bfd_vma r_addend = rel->r_addend;
13ae64f3
JJ
5106
5107 switch (r_type)
5108 {
5109 default:
5110 case R_IA64_LTOFF_TPREL22:
a823975a
JJ
5111 if (!dynamic_symbol_p)
5112 {
0f2830ff
L
5113 if (elf_hash_table (info)->tls_sec == NULL)
5114 goto missing_tls_sec;
a823975a
JJ
5115 if (!info->shared)
5116 value -= elfNN_ia64_tprel_base (info);
5117 else
5118 {
5119 r_addend += value - elfNN_ia64_dtprel_base (info);
5120 dynindx = 0;
5121 }
5122 }
13ae64f3
JJ
5123 got_r_type = R_IA64_TPREL64LSB;
5124 break;
5125 case R_IA64_LTOFF_DTPMOD22:
5126 if (!dynamic_symbol_p && !info->shared)
5127 value = 1;
5128 got_r_type = R_IA64_DTPMOD64LSB;
5129 break;
5130 case R_IA64_LTOFF_DTPREL22:
5131 if (!dynamic_symbol_p)
0f2830ff
L
5132 {
5133 if (elf_hash_table (info)->tls_sec == NULL)
5134 goto missing_tls_sec;
5135 value -= elfNN_ia64_dtprel_base (info);
5136 }
5a260b66 5137 got_r_type = R_IA64_DTPRELNNLSB;
13ae64f3
JJ
5138 break;
5139 }
b34976b6 5140 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
a823975a 5141 value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
13ae64f3
JJ
5142 value, got_r_type);
5143 value -= gp_val;
bbb268c3 5144 r = elfNN_ia64_install_value (hit_addr, value, r_type);
13ae64f3
JJ
5145 }
5146 break;
5147
800eeca4
JW
5148 default:
5149 r = bfd_reloc_notsupported;
5150 break;
5151 }
5152
5153 switch (r)
5154 {
5155 case bfd_reloc_ok:
5156 break;
5157
5158 case bfd_reloc_undefined:
5159 /* This can happen for global table relative relocs if
5160 __gp is undefined. This is a panic situation so we
5161 don't try to continue. */
5162 (*info->callbacks->undefined_symbol)
5163 (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
b34976b6 5164 return FALSE;
800eeca4
JW
5165
5166 case bfd_reloc_notsupported:
5167 {
5168 const char *name;
5169
5170 if (h)
5171 name = h->root.root.string;
5172 else
26c61ae5
L
5173 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
5174 sym_sec);
800eeca4
JW
5175 if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
5176 name, input_bfd,
5177 input_section, rel->r_offset))
b34976b6
AM
5178 return FALSE;
5179 ret_val = FALSE;
800eeca4
JW
5180 }
5181 break;
5182
5183 case bfd_reloc_dangerous:
5184 case bfd_reloc_outofrange:
5185 case bfd_reloc_overflow:
5186 default:
0f2830ff 5187missing_tls_sec:
800eeca4
JW
5188 {
5189 const char *name;
5190
5191 if (h)
f0581930 5192 name = h->root.root.string;
800eeca4 5193 else
26c61ae5
L
5194 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
5195 sym_sec);
c5509b92
L
5196
5197 switch (r_type)
5198 {
0f2830ff
L
5199 case R_IA64_TPREL14:
5200 case R_IA64_TPREL22:
5201 case R_IA64_TPREL64I:
5202 case R_IA64_DTPREL14:
5203 case R_IA64_DTPREL22:
5204 case R_IA64_DTPREL64I:
5205 case R_IA64_DTPREL32LSB:
5206 case R_IA64_DTPREL32MSB:
5207 case R_IA64_DTPREL64LSB:
5208 case R_IA64_DTPREL64MSB:
5209 case R_IA64_LTOFF_TPREL22:
5210 case R_IA64_LTOFF_DTPMOD22:
5211 case R_IA64_LTOFF_DTPREL22:
5212 (*_bfd_error_handler)
5213 (_("%B: missing TLS section for relocation %s against `%s' at 0x%lx in section `%A'."),
5214 input_bfd, input_section, howto->name, name,
5215 rel->r_offset);
5216 break;
5217
c5509b92
L
5218 case R_IA64_PCREL21B:
5219 case R_IA64_PCREL21BI:
5220 case R_IA64_PCREL21M:
5221 case R_IA64_PCREL21F:
5222 if (is_elf_hash_table (info->hash))
5223 {
5224 /* Relaxtion is always performed for ELF output.
5225 Overflow failures for those relocations mean
5226 that the section is too big to relax. */
5227 (*_bfd_error_handler)
5228 (_("%B: Can't relax br (%s) to `%s' at 0x%lx in section `%A' with size 0x%lx (> 0x1000000)."),
5229 input_bfd, input_section, howto->name, name,
5230 rel->r_offset, input_section->size);
5231 break;
5232 }
5233 default:
5234 if (!(*info->callbacks->reloc_overflow) (info,
5235 &h->root,
5236 name,
5237 howto->name,
5238 (bfd_vma) 0,
5239 input_bfd,
5240 input_section,
5241 rel->r_offset))
5242 return FALSE;
5243 break;
5244 }
5245
b34976b6 5246 ret_val = FALSE;
800eeca4
JW
5247 }
5248 break;
5249 }
5250 }
5251
5252 return ret_val;
5253}
5254
b34976b6 5255static bfd_boolean
eae50df2
L
5256elfNN_ia64_finish_dynamic_symbol (bfd *output_bfd,
5257 struct bfd_link_info *info,
5258 struct elf_link_hash_entry *h,
5259 Elf_Internal_Sym *sym)
800eeca4 5260{
bbe66d08
JW
5261 struct elfNN_ia64_link_hash_table *ia64_info;
5262 struct elfNN_ia64_dyn_sym_info *dyn_i;
800eeca4 5263
bbe66d08 5264 ia64_info = elfNN_ia64_hash_table (info);
4dfe6ac6
NC
5265 if (ia64_info == NULL)
5266 return FALSE;
5267
b34976b6 5268 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
800eeca4
JW
5269
5270 /* Fill in the PLT data, if required. */
5271 if (dyn_i && dyn_i->want_plt)
5272 {
5273 Elf_Internal_Rela outrel;
5274 bfd_byte *loc;
5275 asection *plt_sec;
91d6fa6a 5276 bfd_vma plt_addr, pltoff_addr, gp_val, plt_index;
800eeca4
JW
5277
5278 gp_val = _bfd_get_gp_value (output_bfd);
5279
5280 /* Initialize the minimal PLT entry. */
5281
91d6fa6a 5282 plt_index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
cc3bd654 5283 plt_sec = ia64_info->root.splt;
800eeca4
JW
5284 loc = plt_sec->contents + dyn_i->plt_offset;
5285
5286 memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
91d6fa6a 5287 elfNN_ia64_install_value (loc, plt_index, R_IA64_IMM22);
bbb268c3 5288 elfNN_ia64_install_value (loc+2, -dyn_i->plt_offset, R_IA64_PCREL21B);
800eeca4
JW
5289
5290 plt_addr = (plt_sec->output_section->vma
5291 + plt_sec->output_offset
5292 + dyn_i->plt_offset);
b34976b6 5293 pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
800eeca4
JW
5294
5295 /* Initialize the FULL PLT entry, if needed. */
5296 if (dyn_i->want_plt2)
5297 {
5298 loc = plt_sec->contents + dyn_i->plt2_offset;
5299
5300 memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
bbb268c3 5301 elfNN_ia64_install_value (loc, pltoff_addr - gp_val, R_IA64_IMM22);
800eeca4
JW
5302
5303 /* Mark the symbol as undefined, rather than as defined in the
5304 plt section. Leave the value alone. */
5305 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
c152c796 5306 first place. But perhaps elflink.c did some for us. */
f5385ebf 5307 if (!h->def_regular)
800eeca4
JW
5308 sym->st_shndx = SHN_UNDEF;
5309 }
5310
5311 /* Create the dynamic relocation. */
5312 outrel.r_offset = pltoff_addr;
5313 if (bfd_little_endian (output_bfd))
bbe66d08 5314 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
800eeca4 5315 else
bbe66d08 5316 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
800eeca4
JW
5317 outrel.r_addend = 0;
5318
5319 /* This is fun. In the .IA_64.pltoff section, we've got entries
5320 that correspond both to real PLT entries, and those that
5321 happened to resolve to local symbols but need to be created
5322 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
5323 relocations for the real PLT should come at the end of the
5324 section, so that they can be indexed by plt entry at runtime.
5325
5326 We emitted all of the relocations for the non-PLT @pltoff
5327 entries during relocate_section. So we can consider the
5328 existing sec->reloc_count to be the base of the array of
5329 PLT relocations. */
5330
947216bf 5331 loc = ia64_info->rel_pltoff_sec->contents;
91d6fa6a 5332 loc += ((ia64_info->rel_pltoff_sec->reloc_count + plt_index)
37cd2629 5333 * sizeof (ElfNN_External_Rela));
947216bf 5334 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
800eeca4
JW
5335 }
5336
5337 /* Mark some specially defined symbols as absolute. */
5338 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
22edb2f1
RS
5339 || h == ia64_info->root.hgot
5340 || h == ia64_info->root.hplt)
800eeca4
JW
5341 sym->st_shndx = SHN_ABS;
5342
b34976b6 5343 return TRUE;
800eeca4
JW
5344}
5345
b34976b6 5346static bfd_boolean
eae50df2
L
5347elfNN_ia64_finish_dynamic_sections (bfd *abfd,
5348 struct bfd_link_info *info)
800eeca4 5349{
bbe66d08 5350 struct elfNN_ia64_link_hash_table *ia64_info;
800eeca4
JW
5351 bfd *dynobj;
5352
bbe66d08 5353 ia64_info = elfNN_ia64_hash_table (info);
4dfe6ac6
NC
5354 if (ia64_info == NULL)
5355 return FALSE;
5356
800eeca4
JW
5357 dynobj = ia64_info->root.dynobj;
5358
5359 if (elf_hash_table (info)->dynamic_sections_created)
5360 {
bbe66d08 5361 ElfNN_External_Dyn *dyncon, *dynconend;
800eeca4
JW
5362 asection *sdyn, *sgotplt;
5363 bfd_vma gp_val;
5364
5365 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
5366 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
5367 BFD_ASSERT (sdyn != NULL);
bbe66d08 5368 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
eea6121a 5369 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
800eeca4
JW
5370
5371 gp_val = _bfd_get_gp_value (abfd);
5372
5373 for (; dyncon < dynconend; dyncon++)
5374 {
5375 Elf_Internal_Dyn dyn;
800eeca4 5376
bbe66d08 5377 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
800eeca4
JW
5378
5379 switch (dyn.d_tag)
5380 {
5381 case DT_PLTGOT:
5382 dyn.d_un.d_ptr = gp_val;
5383 break;
5384
5385 case DT_PLTRELSZ:
5386 dyn.d_un.d_val = (ia64_info->minplt_entries
bbe66d08 5387 * sizeof (ElfNN_External_Rela));
800eeca4
JW
5388 break;
5389
5390 case DT_JMPREL:
5391 /* See the comment above in finish_dynamic_symbol. */
5392 dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
5393 + ia64_info->rel_pltoff_sec->output_offset
5394 + (ia64_info->rel_pltoff_sec->reloc_count
bbe66d08 5395 * sizeof (ElfNN_External_Rela)));
800eeca4
JW
5396 break;
5397
5398 case DT_IA_64_PLT_RESERVE:
5399 dyn.d_un.d_ptr = (sgotplt->output_section->vma
5400 + sgotplt->output_offset);
5401 break;
5402
5403 case DT_RELASZ:
5404 /* Do not have RELASZ include JMPREL. This makes things
3e932841 5405 easier on ld.so. This is not what the rest of BFD set up. */
800eeca4 5406 dyn.d_un.d_val -= (ia64_info->minplt_entries
bbe66d08 5407 * sizeof (ElfNN_External_Rela));
800eeca4 5408 break;
800eeca4
JW
5409 }
5410
bbe66d08 5411 bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
800eeca4
JW
5412 }
5413
ae9a127f 5414 /* Initialize the PLT0 entry. */
cc3bd654 5415 if (ia64_info->root.splt)
800eeca4 5416 {
cc3bd654 5417 bfd_byte *loc = ia64_info->root.splt->contents;
800eeca4
JW
5418 bfd_vma pltres;
5419
5420 memcpy (loc, plt_header, PLT_HEADER_SIZE);
5421
5422 pltres = (sgotplt->output_section->vma
5423 + sgotplt->output_offset
5424 - gp_val);
5425
bbb268c3 5426 elfNN_ia64_install_value (loc+1, pltres, R_IA64_GPREL22);
800eeca4
JW
5427 }
5428 }
5429
b34976b6 5430 return TRUE;
800eeca4
JW
5431}
5432\f
ae9a127f 5433/* ELF file flag handling: */
800eeca4 5434
3e932841 5435/* Function to keep IA-64 specific file flags. */
b34976b6 5436static bfd_boolean
eae50df2 5437elfNN_ia64_set_private_flags (bfd *abfd, flagword flags)
800eeca4
JW
5438{
5439 BFD_ASSERT (!elf_flags_init (abfd)
5440 || elf_elfheader (abfd)->e_flags == flags);
5441
5442 elf_elfheader (abfd)->e_flags = flags;
b34976b6
AM
5443 elf_flags_init (abfd) = TRUE;
5444 return TRUE;
800eeca4
JW
5445}
5446
800eeca4
JW
5447/* Merge backend specific data from an object file to the output
5448 object file when linking. */
b34976b6 5449static bfd_boolean
eae50df2 5450elfNN_ia64_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
800eeca4
JW
5451{
5452 flagword out_flags;
5453 flagword in_flags;
b34976b6 5454 bfd_boolean ok = TRUE;
800eeca4
JW
5455
5456 /* Don't even pretend to support mixed-format linking. */
5457 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
5458 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
b34976b6 5459 return FALSE;
800eeca4
JW
5460
5461 in_flags = elf_elfheader (ibfd)->e_flags;
5462 out_flags = elf_elfheader (obfd)->e_flags;
5463
5464 if (! elf_flags_init (obfd))
5465 {
b34976b6 5466 elf_flags_init (obfd) = TRUE;
800eeca4
JW
5467 elf_elfheader (obfd)->e_flags = in_flags;
5468
5469 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
5470 && bfd_get_arch_info (obfd)->the_default)
5471 {
5472 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
5473 bfd_get_mach (ibfd));
5474 }
5475
b34976b6 5476 return TRUE;
800eeca4
JW
5477 }
5478
5479 /* Check flag compatibility. */
5480 if (in_flags == out_flags)
b34976b6 5481 return TRUE;
800eeca4 5482
c43c2cc5
JW
5483 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
5484 if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
5485 elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
5486
800eeca4
JW
5487 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
5488 {
5489 (*_bfd_error_handler)
d003868e
AM
5490 (_("%B: linking trap-on-NULL-dereference with non-trapping files"),
5491 ibfd);
800eeca4
JW
5492
5493 bfd_set_error (bfd_error_bad_value);
b34976b6 5494 ok = FALSE;
800eeca4
JW
5495 }
5496 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
5497 {
5498 (*_bfd_error_handler)
d003868e
AM
5499 (_("%B: linking big-endian files with little-endian files"),
5500 ibfd);
800eeca4
JW
5501
5502 bfd_set_error (bfd_error_bad_value);
b34976b6 5503 ok = FALSE;
800eeca4
JW
5504 }
5505 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
5506 {
5507 (*_bfd_error_handler)
d003868e
AM
5508 (_("%B: linking 64-bit files with 32-bit files"),
5509 ibfd);
800eeca4
JW
5510
5511 bfd_set_error (bfd_error_bad_value);
b34976b6 5512 ok = FALSE;
800eeca4 5513 }
c43c2cc5
JW
5514 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
5515 {
5516 (*_bfd_error_handler)
d003868e
AM
5517 (_("%B: linking constant-gp files with non-constant-gp files"),
5518 ibfd);
c43c2cc5
JW
5519
5520 bfd_set_error (bfd_error_bad_value);
b34976b6 5521 ok = FALSE;
c43c2cc5
JW
5522 }
5523 if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
5524 != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
5525 {
5526 (*_bfd_error_handler)
d003868e
AM
5527 (_("%B: linking auto-pic files with non-auto-pic files"),
5528 ibfd);
c43c2cc5
JW
5529
5530 bfd_set_error (bfd_error_bad_value);
b34976b6 5531 ok = FALSE;
c43c2cc5 5532 }
800eeca4
JW
5533
5534 return ok;
5535}
5536
b34976b6 5537static bfd_boolean
eae50df2 5538elfNN_ia64_print_private_bfd_data (bfd *abfd, PTR ptr)
800eeca4
JW
5539{
5540 FILE *file = (FILE *) ptr;
5541 flagword flags = elf_elfheader (abfd)->e_flags;
5542
5543 BFD_ASSERT (abfd != NULL && ptr != NULL);
5544
c43c2cc5 5545 fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
800eeca4
JW
5546 (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
5547 (flags & EF_IA_64_EXT) ? "EXT, " : "",
5548 (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
c43c2cc5
JW
5549 (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
5550 (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
5551 (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
5552 (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
800eeca4 5553 (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
3e932841 5554
800eeca4 5555 _bfd_elf_print_private_bfd_data (abfd, ptr);
b34976b6 5556 return TRUE;
800eeca4 5557}
db6751f2
JJ
5558
5559static enum elf_reloc_type_class
eae50df2 5560elfNN_ia64_reloc_type_class (const Elf_Internal_Rela *rela)
db6751f2 5561{
f51e552e 5562 switch ((int) ELFNN_R_TYPE (rela->r_info))
db6751f2
JJ
5563 {
5564 case R_IA64_REL32MSB:
5565 case R_IA64_REL32LSB:
5566 case R_IA64_REL64MSB:
5567 case R_IA64_REL64LSB:
5568 return reloc_class_relative;
5569 case R_IA64_IPLTMSB:
5570 case R_IA64_IPLTLSB:
5571 return reloc_class_plt;
5572 case R_IA64_COPY:
5573 return reloc_class_copy;
5574 default:
5575 return reloc_class_normal;
5576 }
5577}
fcf12726 5578
b35d266b 5579static const struct bfd_elf_special_section elfNN_ia64_special_sections[] =
2f89ff8d 5580{
0112cd26
NC
5581 { STRING_COMMA_LEN (".sbss"), -1, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
5582 { STRING_COMMA_LEN (".sdata"), -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
5583 { NULL, 0, 0, 0, 0 }
7f4d3958
L
5584};
5585
da9f89d4
L
5586static bfd_boolean
5587elfNN_ia64_object_p (bfd *abfd)
5588{
5589 asection *sec;
da9f89d4
L
5590 asection *group, *unwi, *unw;
5591 flagword flags;
5592 const char *name;
5593 char *unwi_name, *unw_name;
5594 bfd_size_type amt;
5595
5596 if (abfd->flags & DYNAMIC)
5597 return TRUE;
5598
5599 /* Flags for fake group section. */
5600 flags = (SEC_LINKER_CREATED | SEC_GROUP | SEC_LINK_ONCE
5601 | SEC_EXCLUDE);
5602
5603 /* We add a fake section group for each .gnu.linkonce.t.* section,
5604 which isn't in a section group, and its unwind sections. */
5605 for (sec = abfd->sections; sec != NULL; sec = sec->next)
5606 {
5607 if (elf_sec_group (sec) == NULL
5608 && ((sec->flags & (SEC_LINK_ONCE | SEC_CODE | SEC_GROUP))
5609 == (SEC_LINK_ONCE | SEC_CODE))
0112cd26 5610 && CONST_STRNEQ (sec->name, ".gnu.linkonce.t."))
da9f89d4
L
5611 {
5612 name = sec->name + 16;
5613
5614 amt = strlen (name) + sizeof (".gnu.linkonce.ia64unwi.");
5615 unwi_name = bfd_alloc (abfd, amt);
5616 if (!unwi_name)
5617 return FALSE;
5618
5619 strcpy (stpcpy (unwi_name, ".gnu.linkonce.ia64unwi."), name);
5620 unwi = bfd_get_section_by_name (abfd, unwi_name);
5621
5622 amt = strlen (name) + sizeof (".gnu.linkonce.ia64unw.");
5623 unw_name = bfd_alloc (abfd, amt);
5624 if (!unw_name)
5625 return FALSE;
5626
5627 strcpy (stpcpy (unw_name, ".gnu.linkonce.ia64unw."), name);
5628 unw = bfd_get_section_by_name (abfd, unw_name);
5629
da9f89d4
L
5630 /* We need to create a fake group section for it and its
5631 unwind sections. */
3496cb2a
L
5632 group = bfd_make_section_anyway_with_flags (abfd, name,
5633 flags);
5634 if (group == NULL)
da9f89d4
L
5635 return FALSE;
5636
5637 /* Move the fake group section to the beginning. */
5daa8fe7 5638 bfd_section_list_remove (abfd, group);
04dd1667 5639 bfd_section_list_prepend (abfd, group);
da9f89d4
L
5640
5641 elf_next_in_group (group) = sec;
5642
5643 elf_group_name (sec) = name;
5644 elf_next_in_group (sec) = sec;
5645 elf_sec_group (sec) = group;
5646
5647 if (unwi)
5648 {
5649 elf_group_name (unwi) = name;
5650 elf_next_in_group (unwi) = sec;
5651 elf_next_in_group (sec) = unwi;
5652 elf_sec_group (unwi) = group;
5653 }
5654
5655 if (unw)
5656 {
5657 elf_group_name (unw) = name;
5658 if (unwi)
5659 {
5660 elf_next_in_group (unw) = elf_next_in_group (unwi);
5661 elf_next_in_group (unwi) = unw;
5662 }
5663 else
5664 {
5665 elf_next_in_group (unw) = sec;
5666 elf_next_in_group (sec) = unw;
5667 }
5668 elf_sec_group (unw) = group;
5669 }
5670
5671 /* Fake SHT_GROUP section header. */
5672 elf_section_data (group)->this_hdr.bfd_section = group;
5673 elf_section_data (group)->this_hdr.sh_type = SHT_GROUP;
5674 }
5675 }
5676 return TRUE;
5677}
5678
b34976b6 5679static bfd_boolean
d9cf1b54
AM
5680elfNN_ia64_hpux_vec (const bfd_target *vec)
5681{
5682 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
5683 return (vec == & bfd_elfNN_ia64_hpux_big_vec);
5684}
5685
fcf12726 5686static void
eae50df2
L
5687elfNN_hpux_post_process_headers (bfd *abfd,
5688 struct bfd_link_info *info ATTRIBUTE_UNUSED)
fcf12726
AM
5689{
5690 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
5691
d1036acb 5692 i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
fcf12726
AM
5693 i_ehdrp->e_ident[EI_ABIVERSION] = 1;
5694}
d9cf1b54 5695
eae50df2
L
5696static bfd_boolean
5697elfNN_hpux_backend_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
5698 asection *sec, int *retval)
d9cf1b54
AM
5699{
5700 if (bfd_is_com_section (sec))
5701 {
5702 *retval = SHN_IA_64_ANSI_COMMON;
b34976b6 5703 return TRUE;
d9cf1b54 5704 }
b34976b6 5705 return FALSE;
d9cf1b54 5706}
b59dd4a5
L
5707
5708static void
5709elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
5710 asymbol *asym)
5711{
5f1cb353 5712 elf_symbol_type *elfsym = (elf_symbol_type *) asym;
b59dd4a5
L
5713
5714 switch (elfsym->internal_elf_sym.st_shndx)
5715 {
5716 case SHN_IA_64_ANSI_COMMON:
5717 asym->section = bfd_com_section_ptr;
5718 asym->value = elfsym->internal_elf_sym.st_size;
5719 asym->flags &= ~BSF_GLOBAL;
5720 break;
5721 }
5722}
5723
7256a114
TG
5724#ifdef INCLUDE_IA64_VMS
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{
01e1a5bc
NC
5732 switch (hdr->sh_type)
5733 {
5734 case SHT_IA_64_VMS_TRACE:
5735 case SHT_IA_64_VMS_DEBUG:
5736 case SHT_IA_64_VMS_DEBUG_STR:
5737 break;
5738
5739 default:
5740 return elfNN_ia64_section_from_shdr (abfd, hdr, name, shindex);
5741 }
5742
5743 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
5744 return FALSE;
01e1a5bc
NC
5745
5746 return TRUE;
5747}
5748
5749static bfd_boolean
5750elfNN_vms_object_p (bfd *abfd)
5751{
5752 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
5753 Elf_Internal_Phdr *i_phdr = elf_tdata (abfd)->phdr;
5754 unsigned int i;
5755 unsigned int num_text = 0;
5756 unsigned int num_data = 0;
5757 unsigned int num_rodata = 0;
5758 char name[16];
5759
5760 if (!elfNN_ia64_object_p (abfd))
5761 return FALSE;
5762
5763 for (i = 0; i < i_ehdrp->e_phnum; i++, i_phdr++)
5764 {
5765 /* Is there a section for this segment? */
5766 bfd_vma base_vma = i_phdr->p_vaddr;
5767 bfd_vma limit_vma = base_vma + i_phdr->p_filesz;
5768
5769 if (i_phdr->p_type != PT_LOAD)
5770 continue;
5771
5772 again:
5773 while (base_vma < limit_vma)
5774 {
5775 bfd_vma next_vma = limit_vma;
5776 asection *nsec;
5777 asection *sec;
5778 flagword flags;
5779 char *nname = NULL;
5780
5781 /* Find a section covering base_vma. */
5782 for (sec = abfd->sections; sec != NULL; sec = sec->next)
5783 {
5784 if ((sec->flags & (SEC_ALLOC | SEC_LOAD)) == 0)
5785 continue;
5786 if (sec->vma <= base_vma && sec->vma + sec->size > base_vma)
5787 {
5788 base_vma = sec->vma + sec->size;
5789 goto again;
5790 }
5791 if (sec->vma < next_vma && sec->vma + sec->size >= base_vma)
5792 next_vma = sec->vma;
5793 }
5794
5795 /* No section covering [base_vma; next_vma). Create a fake one. */
5796 flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS;
5797 if (i_phdr->p_flags & PF_X)
5798 {
5799 flags |= SEC_CODE;
5800 if (num_text++ == 0)
5801 nname = ".text";
5802 else
5803 sprintf (name, ".text$%u", num_text);
5804 }
5805 else if ((i_phdr->p_flags & (PF_R | PF_W)) == PF_R)
5806 {
5807 flags |= SEC_READONLY;
5808 sprintf (name, ".rodata$%u", num_rodata++);
5809 }
5810 else
5811 {
5812 flags |= SEC_DATA;
5813 sprintf (name, ".data$%u", num_data++);
5814 }
5815
5816 /* Allocate name. */
5817 if (nname == NULL)
5818 {
5819 size_t name_len = strlen (name) + 1;
5820 nname = bfd_alloc (abfd, name_len);
5821 if (nname == NULL)
5822 return FALSE;
5823 memcpy (nname, name, name_len);
5824 }
5825
5826 /* Create and fill new section. */
5827 nsec = bfd_make_section_anyway_with_flags (abfd, nname, flags);
5828 if (nsec == NULL)
5829 return FALSE;
5830 nsec->vma = base_vma;
5831 nsec->size = next_vma - base_vma;
5832 nsec->filepos = i_phdr->p_offset + (base_vma - i_phdr->p_vaddr);
5833
5834 base_vma = next_vma;
5835 }
5836 }
5837 return TRUE;
5838}
5839
5840static void
5841elfNN_vms_post_process_headers (bfd *abfd,
5842 struct bfd_link_info *info ATTRIBUTE_UNUSED)
5843{
5844 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
5845
5846 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_OPENVMS;
5847 i_ehdrp->e_ident[EI_ABIVERSION] = 2;
5848}
5849
5850static bfd_boolean
5851elfNN_vms_section_processing (bfd *abfd ATTRIBUTE_UNUSED,
5852 Elf_Internal_Shdr *hdr)
5853{
5854 if (hdr->bfd_section != NULL)
5855 {
5856 const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
5857
5858 if (strcmp (name, ".text") == 0)
5859 hdr->sh_flags |= SHF_IA_64_VMS_SHARED;
5860 else if ((strcmp (name, ".debug") == 0)
5861 || (strcmp (name, ".debug_abbrev") == 0)
5862 || (strcmp (name, ".debug_aranges") == 0)
5863 || (strcmp (name, ".debug_frame") == 0)
5864 || (strcmp (name, ".debug_info") == 0)
5865 || (strcmp (name, ".debug_loc") == 0)
5866 || (strcmp (name, ".debug_macinfo") == 0)
5867 || (strcmp (name, ".debug_pubnames") == 0)
5868 || (strcmp (name, ".debug_pubtypes") == 0))
5869 hdr->sh_type = SHT_IA_64_VMS_DEBUG;
5870 else if ((strcmp (name, ".debug_line") == 0)
5871 || (strcmp (name, ".debug_ranges") == 0))
5872 hdr->sh_type = SHT_IA_64_VMS_TRACE;
5873 else if (strcmp (name, ".debug_str") == 0)
5874 hdr->sh_type = SHT_IA_64_VMS_DEBUG_STR;
5875 else if (strcmp (name, ".vms_display_name_info") == 0)
5876 {
5877 int idx, symcount;
5878 asymbol **syms;
5879 struct elf_obj_tdata *t = elf_tdata (abfd);
5880 int buf[2];
5881 int demangler_sym_idx = -1;
5882
5883 symcount = bfd_get_symcount (abfd);
5884 syms = bfd_get_outsymbols (abfd);
5885 for (idx = 0; idx < symcount; idx++)
5886 {
5887 asymbol *sym;
5888 sym = syms[idx];
5889 if ((sym->flags & (BSF_DEBUGGING | BSF_DYNAMIC))
5890 && strchr (sym->name, '@')
5891 && (strcmp (sym->section->name, BFD_ABS_SECTION_NAME) == 0))
5892 {
5893 demangler_sym_idx = sym->udata.i;
5894 break;
5895 }
5896 }
5897
5898 hdr->sh_type = SHT_IA_64_VMS_DISPLAY_NAME_INFO;
5899 hdr->sh_entsize = 4;
5900 hdr->sh_addralign = 0;
5901 hdr->sh_link = t->symtab_section;
5902
5903 /* Find symtab index of demangler routine and stuff it in
5904 the second long word of section data. */
5905
5906 if (demangler_sym_idx > -1)
5907 {
5908 bfd_seek (abfd, hdr->sh_offset, SEEK_SET);
5909 bfd_bread (buf, hdr->sh_size, abfd);
5910 buf [1] = demangler_sym_idx;
5911 bfd_seek (abfd, hdr->sh_offset, SEEK_SET);
5912 bfd_bwrite (buf, hdr->sh_size, abfd);
5913 }
5914 }
5915 }
5916
5917 return TRUE;
5918}
5919
5920/* The final processing done just before writing out a VMS IA-64 ELF
5921 object file. */
5922
5923static void
5924elfNN_vms_final_write_processing (bfd *abfd,
5925 bfd_boolean linker ATTRIBUTE_UNUSED)
5926{
5927 Elf_Internal_Shdr *hdr;
5928 asection *s;
5929 int unwind_info_sect_idx = 0;
5930
5931 for (s = abfd->sections; s; s = s->next)
5932 {
5933 hdr = &elf_section_data (s)->this_hdr;
5934
5935 if (strcmp (bfd_get_section_name (abfd, hdr->bfd_section),
5936 ".IA_64.unwind_info") == 0)
5937 unwind_info_sect_idx = elf_section_data (s)->this_idx;
5938
5939 switch (hdr->sh_type)
5940 {
5941 case SHT_IA_64_UNWIND:
5942 /* VMS requires sh_info to point to the unwind info section. */
5943 hdr->sh_info = unwind_info_sect_idx;
5944 break;
5945 }
5946 }
5947
5948 if (! elf_flags_init (abfd))
5949 {
5950 unsigned long flags = 0;
5951
5952 if (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
5953 flags |= EF_IA_64_BE;
5954 if (bfd_get_mach (abfd) == bfd_mach_ia64_elf64)
5955 flags |= EF_IA_64_ABI64;
5956
5957 elf_elfheader(abfd)->e_flags = flags;
5958 elf_flags_init (abfd) = TRUE;
5959 }
5960}
5961
5962static bfd_boolean
5963elfNN_vms_close_and_cleanup (bfd *abfd)
5964{
5965 if (bfd_get_format (abfd) == bfd_object)
5966 {
5967 long isize, irsize;
5968
5969 if (elf_shstrtab (abfd) != NULL)
5970 _bfd_elf_strtab_free (elf_shstrtab (abfd));
5971
5972 /* Pad to 8 byte boundary for IPF/VMS. */
5973 isize = bfd_get_size (abfd);
5974 if ((irsize = isize/8*8) < isize)
5975 {
5976 int ishort = (irsize + 8) - isize;
5977 bfd_seek (abfd, isize, SEEK_SET);
5978 bfd_bwrite (bfd_zmalloc (ishort), ishort, abfd);
5979 }
5980 }
5981
5982 return _bfd_generic_close_and_cleanup (abfd);
5983}
7256a114 5984#endif /* INCLUDE_IA64_VMS */
800eeca4 5985\f
bbe66d08
JW
5986#define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
5987#define TARGET_LITTLE_NAME "elfNN-ia64-little"
5988#define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
5989#define TARGET_BIG_NAME "elfNN-ia64-big"
800eeca4 5990#define ELF_ARCH bfd_arch_ia64
ae95ffa6 5991#define ELF_TARGET_ID IA64_ELF_DATA
800eeca4
JW
5992#define ELF_MACHINE_CODE EM_IA_64
5993#define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
5994#define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
5995#define ELF_MAXPAGESIZE 0x10000 /* 64KB */
24718e3b 5996#define ELF_COMMONPAGESIZE 0x4000 /* 16KB */
800eeca4
JW
5997
5998#define elf_backend_section_from_shdr \
bbe66d08 5999 elfNN_ia64_section_from_shdr
fa152c49 6000#define elf_backend_section_flags \
bbe66d08 6001 elfNN_ia64_section_flags
800eeca4 6002#define elf_backend_fake_sections \
bbe66d08 6003 elfNN_ia64_fake_sections
81545d45
RH
6004#define elf_backend_final_write_processing \
6005 elfNN_ia64_final_write_processing
800eeca4 6006#define elf_backend_add_symbol_hook \
bbe66d08 6007 elfNN_ia64_add_symbol_hook
800eeca4 6008#define elf_backend_additional_program_headers \
bbe66d08 6009 elfNN_ia64_additional_program_headers
800eeca4 6010#define elf_backend_modify_segment_map \
bbe66d08 6011 elfNN_ia64_modify_segment_map
e36284ab
AM
6012#define elf_backend_modify_program_headers \
6013 elfNN_ia64_modify_program_headers
800eeca4 6014#define elf_info_to_howto \
bbe66d08 6015 elfNN_ia64_info_to_howto
800eeca4 6016
bbe66d08
JW
6017#define bfd_elfNN_bfd_reloc_type_lookup \
6018 elfNN_ia64_reloc_type_lookup
157090f7
AM
6019#define bfd_elfNN_bfd_reloc_name_lookup \
6020 elfNN_ia64_reloc_name_lookup
bbe66d08
JW
6021#define bfd_elfNN_bfd_is_local_label_name \
6022 elfNN_ia64_is_local_label_name
6023#define bfd_elfNN_bfd_relax_section \
6024 elfNN_ia64_relax_section
800eeca4 6025
da9f89d4
L
6026#define elf_backend_object_p \
6027 elfNN_ia64_object_p
6028
800eeca4 6029/* Stuff for the BFD linker: */
bbe66d08
JW
6030#define bfd_elfNN_bfd_link_hash_table_create \
6031 elfNN_ia64_hash_table_create
0aa92b58
JJ
6032#define bfd_elfNN_bfd_link_hash_table_free \
6033 elfNN_ia64_hash_table_free
800eeca4 6034#define elf_backend_create_dynamic_sections \
bbe66d08 6035 elfNN_ia64_create_dynamic_sections
800eeca4 6036#define elf_backend_check_relocs \
bbe66d08 6037 elfNN_ia64_check_relocs
800eeca4 6038#define elf_backend_adjust_dynamic_symbol \
bbe66d08 6039 elfNN_ia64_adjust_dynamic_symbol
800eeca4 6040#define elf_backend_size_dynamic_sections \
bbe66d08 6041 elfNN_ia64_size_dynamic_sections
74541ad4
AM
6042#define elf_backend_omit_section_dynsym \
6043 ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
800eeca4 6044#define elf_backend_relocate_section \
bbe66d08 6045 elfNN_ia64_relocate_section
800eeca4 6046#define elf_backend_finish_dynamic_symbol \
bbe66d08 6047 elfNN_ia64_finish_dynamic_symbol
800eeca4 6048#define elf_backend_finish_dynamic_sections \
bbe66d08
JW
6049 elfNN_ia64_finish_dynamic_sections
6050#define bfd_elfNN_bfd_final_link \
6051 elfNN_ia64_final_link
6052
bbe66d08
JW
6053#define bfd_elfNN_bfd_merge_private_bfd_data \
6054 elfNN_ia64_merge_private_bfd_data
6055#define bfd_elfNN_bfd_set_private_flags \
6056 elfNN_ia64_set_private_flags
6057#define bfd_elfNN_bfd_print_private_bfd_data \
6058 elfNN_ia64_print_private_bfd_data
800eeca4
JW
6059
6060#define elf_backend_plt_readonly 1
6061#define elf_backend_want_plt_sym 0
6062#define elf_backend_plt_alignment 5
6063#define elf_backend_got_header_size 0
800eeca4
JW
6064#define elf_backend_want_got_plt 1
6065#define elf_backend_may_use_rel_p 1
6066#define elf_backend_may_use_rela_p 1
6067#define elf_backend_default_use_rela_p 1
6068#define elf_backend_want_dynbss 0
bbe66d08
JW
6069#define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
6070#define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
508c3946 6071#define elf_backend_fixup_symbol _bfd_elf_link_hash_fixup_symbol
db6751f2 6072#define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
b491616a 6073#define elf_backend_rela_normal 1
29ef7005 6074#define elf_backend_special_sections elfNN_ia64_special_sections
d4d2b80b 6075#define elf_backend_default_execstack 0
800eeca4 6076
185d09ad 6077/* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
e04bcc6d 6078 SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
185d09ad
L
6079 We don't want to flood users with so many error messages. We turn
6080 off the warning for now. It will be turned on later when the Intel
6081 compiler is fixed. */
6082#define elf_backend_link_order_error_handler NULL
6083
bbe66d08 6084#include "elfNN-target.h"
7b6dab7f 6085
fcf12726
AM
6086/* HPUX-specific vectors. */
6087
6088#undef TARGET_LITTLE_SYM
6089#undef TARGET_LITTLE_NAME
6090#undef TARGET_BIG_SYM
6091#define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
6092#undef TARGET_BIG_NAME
6093#define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
6094
254ed743
NC
6095/* These are HP-UX specific functions. */
6096
fcf12726
AM
6097#undef elf_backend_post_process_headers
6098#define elf_backend_post_process_headers elfNN_hpux_post_process_headers
6099
d9cf1b54
AM
6100#undef elf_backend_section_from_bfd_section
6101#define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
6102
b59dd4a5
L
6103#undef elf_backend_symbol_processing
6104#define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
6105
5e8d7549
NC
6106#undef elf_backend_want_p_paddr_set_to_zero
6107#define elf_backend_want_p_paddr_set_to_zero 1
6108
24718e3b 6109#undef ELF_COMMONPAGESIZE
d1036acb
L
6110#undef ELF_OSABI
6111#define ELF_OSABI ELFOSABI_HPUX
fcf12726
AM
6112
6113#undef elfNN_bed
6114#define elfNN_bed elfNN_ia64_hpux_bed
6115
6116#include "elfNN-target.h"
5e8d7549 6117
01e1a5bc 6118/* VMS-specific vectors. */
7256a114 6119#ifdef INCLUDE_IA64_VMS
01e1a5bc
NC
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
7256a114
TG
6163/* Use VMS-style archives (in particular, don't use the standard coff
6164 archive format). */
6165#define bfd_elfNN_archive_functions
6166
6167#undef bfd_elfNN_archive_p
6168#define bfd_elfNN_archive_p _bfd_vms_lib_ia64_archive_p
09266d1a
TG
6169#undef bfd_elfNN_write_archive_contents
6170#define bfd_elfNN_write_archive_contents _bfd_vms_lib_write_archive_contents
6171#undef bfd_elfNN_mkarchive
6172#define bfd_elfNN_mkarchive _bfd_vms_lib_ia64_mkarchive
7256a114
TG
6173
6174#define bfd_elfNN_archive_slurp_armap \
6175 _bfd_vms_lib_slurp_armap
6176#define bfd_elfNN_archive_slurp_extended_name_table \
6177 _bfd_vms_lib_slurp_extended_name_table
6178#define bfd_elfNN_archive_construct_extended_name_table \
6179 _bfd_vms_lib_construct_extended_name_table
6180#define bfd_elfNN_archive_truncate_arname \
6181 _bfd_vms_lib_truncate_arname
6182#define bfd_elfNN_archive_write_armap \
6183 _bfd_vms_lib_write_armap
6184#define bfd_elfNN_archive_read_ar_hdr \
6185 _bfd_vms_lib_read_ar_hdr
6186#define bfd_elfNN_archive_write_ar_hdr \
6187 _bfd_vms_lib_write_ar_hdr
6188#define bfd_elfNN_archive_openr_next_archived_file \
6189 _bfd_vms_lib_openr_next_archived_file
6190#define bfd_elfNN_archive_get_elt_at_index \
6191 _bfd_vms_lib_get_elt_at_index
6192#define bfd_elfNN_archive_generic_stat_arch_elt \
6193 _bfd_vms_lib_generic_stat_arch_elt
6194#define bfd_elfNN_archive_update_armap_timestamp \
6195 _bfd_vms_lib_update_armap_timestamp
6196
01e1a5bc 6197#include "elfNN-target.h"
7256a114
TG
6198
6199#endif /* INCLUDE_IA64_VMS */