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