Add -Wshadow to the gcc command line options used when compiling the binutils.
[deliverable/binutils-gdb.git] / bfd / elfxx-ia64.c
1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
3 2008, 2009 Free Software Foundation, Inc.
4 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5
6 This file is part of BFD, the Binary File Descriptor library.
7
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
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
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.
17
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
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
22
23 #include "sysdep.h"
24 #include "bfd.h"
25 #include "libbfd.h"
26 #include "elf-bfd.h"
27 #include "opcode/ia64.h"
28 #include "elf/ia64.h"
29 #include "objalloc.h"
30 #include "hashtab.h"
31
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
42 /* THE RULES for all the stuff the linker creates --
43
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.
48
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.
55
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.
59
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.
66
67 MIN_PLT Created by PLTOFF entries against dynamic symbols. This
68 does not require dynamic relocations. */
69
70 #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
71
72 typedef 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
79 struct elfNN_ia64_dyn_sym_info
80 {
81 /* The addend for which this entry is relevant. */
82 bfd_vma addend;
83
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;
89 bfd_vma tprel_offset;
90 bfd_vma dtpmod_offset;
91 bfd_vma dtprel_offset;
92
93 /* The symbol table entry, if any, that this was derived from. */
94 struct elf_link_hash_entry *h;
95
96 /* Used to count non-got, non-plt relocations for delayed sizing
97 of relocation sections. */
98 struct elfNN_ia64_dyn_reloc_entry
99 {
100 struct elfNN_ia64_dyn_reloc_entry *next;
101 asection *srel;
102 int type;
103 int count;
104
105 /* Is this reloc against readonly section? */
106 bfd_boolean reltext;
107 } *reloc_entries;
108
109 /* TRUE when the section contents have been updated. */
110 unsigned got_done : 1;
111 unsigned fptr_done : 1;
112 unsigned pltoff_done : 1;
113 unsigned tprel_done : 1;
114 unsigned dtpmod_done : 1;
115 unsigned dtprel_done : 1;
116
117 /* TRUE for the different kinds of linker data we want created. */
118 unsigned want_got : 1;
119 unsigned want_gotx : 1;
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;
125 unsigned want_tprel : 1;
126 unsigned want_dtpmod : 1;
127 unsigned want_dtprel : 1;
128 };
129
130 struct elfNN_ia64_local_hash_entry
131 {
132 int id;
133 unsigned int r_sym;
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. */
141 struct elfNN_ia64_dyn_sym_info *info;
142
143 /* TRUE if this hash entry's addends was translated for
144 SHF_MERGE optimization. */
145 unsigned sec_merge_done : 1;
146 };
147
148 struct elfNN_ia64_link_hash_entry
149 {
150 struct elf_link_hash_entry root;
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. */
158 struct elfNN_ia64_dyn_sym_info *info;
159 };
160
161 struct elfNN_ia64_link_hash_table
162 {
163 /* The main hash table. */
164 struct elf_link_hash_table root;
165
166 asection *fptr_sec; /* function descriptor table (or NULL) */
167 asection *rel_fptr_sec; /* dynamic relocation section for same */
168 asection *pltoff_sec; /* private descriptors for plt (or NULL) */
169 asection *rel_pltoff_sec; /* dynamic relocation section for same */
170
171 bfd_size_type minplt_entries; /* number of minplt entries */
172 unsigned reltext : 1; /* are there relocs against readonly sections? */
173 unsigned self_dtpmod_done : 1;/* has self DTPMOD entry been finished? */
174 bfd_vma self_dtpmod_offset; /* .got offset to self DTPMOD entry */
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. */
179 asection *max_short_sec; /* maximum short output section */
180 bfd_vma max_short_offset; /* maximum short offset */
181 asection *min_short_sec; /* minimum short output section */
182 bfd_vma min_short_offset; /* minimum short offset */
183
184 htab_t loc_hash_table;
185 void *loc_hash_memory;
186 };
187
188 struct elfNN_ia64_allocate_data
189 {
190 struct bfd_link_info *info;
191 bfd_size_type ofs;
192 bfd_boolean only_got;
193 };
194
195 #define elfNN_ia64_hash_table(p) \
196 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
197
198 static 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);
202 static bfd_boolean elfNN_ia64_dynamic_symbol_p
203 (struct elf_link_hash_entry *h, struct bfd_link_info *info, int);
204 static bfd_reloc_status_type elfNN_ia64_install_value
205 (bfd_byte *hit_addr, bfd_vma val, unsigned int r_type);
206 static bfd_boolean elfNN_ia64_choose_gp
207 (bfd *abfd, struct bfd_link_info *info);
208 static void elfNN_ia64_relax_ldxmov
209 (bfd_byte *contents, bfd_vma off);
210 static void elfNN_ia64_dyn_sym_traverse
211 (struct elfNN_ia64_link_hash_table *ia64_info,
212 bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
213 PTR info);
214 static bfd_boolean allocate_global_data_got
215 (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data);
216 static bfd_boolean allocate_global_fptr_got
217 (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data);
218 static bfd_boolean allocate_local_got
219 (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data);
220 static bfd_boolean elfNN_ia64_hpux_vec
221 (const bfd_target *vec);
222 static bfd_boolean allocate_dynrel_entries
223 (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data);
224 static asection *get_pltoff
225 (bfd *abfd, struct bfd_link_info *info,
226 struct elfNN_ia64_link_hash_table *ia64_info);
227 \f
228 /* ia64-specific relocation. */
229
230 /* Perform a relocation. Not much to do here as all the hard work is
231 done in elfNN_ia64_final_link_relocate. */
232 static bfd_reloc_status_type
233 elfNN_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)
237 {
238 if (output_bfd)
239 {
240 reloc->address += input_section->output_offset;
241 return bfd_reloc_ok;
242 }
243
244 if (input_section->flags & SEC_DEBUGGING)
245 return bfd_reloc_continue;
246
247 *error_message = "Unsupported call to elfNN_ia64_reloc";
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, \
253 elfNN_ia64_reloc, NAME, FALSE, 0, -1, IN)
254
255 /* This table has to be sorted according to increasing number of the
256 TYPE field. */
257 static reloc_howto_type ia64_howto_table[] =
258 {
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),
339 IA64_HOWTO (R_IA64_TPREL64MSB, "TPREL64MSB", 4, FALSE, FALSE),
340 IA64_HOWTO (R_IA64_TPREL64LSB, "TPREL64LSB", 4, FALSE, FALSE),
341 IA64_HOWTO (R_IA64_LTOFF_TPREL22, "LTOFF_TPREL22", 0, FALSE, FALSE),
342
343 IA64_HOWTO (R_IA64_DTPMOD64MSB, "DTPMOD64MSB", 4, FALSE, FALSE),
344 IA64_HOWTO (R_IA64_DTPMOD64LSB, "DTPMOD64LSB", 4, FALSE, FALSE),
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),
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),
354 IA64_HOWTO (R_IA64_LTOFF_DTPREL22, "LTOFF_DTPREL22", 0, FALSE, FALSE),
355 };
356
357 static 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
361 static reloc_howto_type *
362 lookup_howto (unsigned int rtype)
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
376 if (rtype > R_IA64_MAX_RELOC_CODE)
377 return 0;
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
384 static reloc_howto_type*
385 elfNN_ia64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
386 bfd_reloc_code_real_type bfd_code)
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;
424 case BFD_RELOC_IA64_PCREL21BI: rtype = R_IA64_PCREL21BI; break;
425 case BFD_RELOC_IA64_PCREL21M: rtype = R_IA64_PCREL21M; break;
426 case BFD_RELOC_IA64_PCREL21F: rtype = R_IA64_PCREL21F; break;
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;
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;
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;
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
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;
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
468 case BFD_RELOC_IA64_TPREL14: rtype = R_IA64_TPREL14; break;
469 case BFD_RELOC_IA64_TPREL22: rtype = R_IA64_TPREL22; break;
470 case BFD_RELOC_IA64_TPREL64I: rtype = R_IA64_TPREL64I; break;
471 case BFD_RELOC_IA64_TPREL64MSB: rtype = R_IA64_TPREL64MSB; break;
472 case BFD_RELOC_IA64_TPREL64LSB: rtype = R_IA64_TPREL64LSB; break;
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;
487
488 default: return 0;
489 }
490 return lookup_howto (rtype);
491 }
492
493 static reloc_howto_type *
494 elfNN_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
509 /* Given a ELF reloc, return the matching HOWTO structure. */
510
511 static void
512 elfNN_ia64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
513 arelent *bfd_reloc,
514 Elf_Internal_Rela *elf_reloc)
515 {
516 bfd_reloc->howto
517 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc->r_info));
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
525 static 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
538 static 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
545 static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
546 {
547 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
548 0x00, 0x41, 0x3c, 0x70, 0x29, 0xc0, /* ld8.acq r16=[r15],8*/
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"
556
557 static 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 };
563
564 static 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
577 static size_t oor_branch_size = sizeof (oor_brl);
578
579 void
580 bfd_elfNN_ia64_after_parse (int itanium)
581 {
582 oor_branch_size = itanium ? sizeof (oor_ip) : sizeof (oor_brl);
583 }
584
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
620 static bfd_boolean
621 elfNN_ia64_relax_br (bfd_byte *contents, bfd_vma off)
622 {
623 unsigned int template_val, mlx;
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. */
637 template_val = t0 & 0x1e;
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. */
653 if (!((template_val == 0x12 /* MBB */
654 && IS_NOP_B (s2))
655 || (template_val == 0x16 /* BBB */
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. */
664 if (!((template_val == 0x10 /* MIB */
665 && IS_NOP_I (s1))
666 || (template_val == 0x12 /* MBB */
667 && IS_NOP_B (s1))
668 || (template_val == 0x16 /* BBB */
669 && IS_NOP_B (s0)
670 && IS_NOP_B (s1))
671 || (template_val == 0x18 /* MMB */
672 && IS_NOP_M (s1))
673 || (template_val == 0x1c /* MFB */
674 && IS_NOP_F (s1))))
675 return FALSE;
676 br_code = s2;
677 break;
678 default:
679 /* It should never happen. */
680 abort ();
681 }
682
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
697 if (template_val == 0x16)
698 {
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;
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
723 static void
724 elfNN_ia64_relax_brl (bfd_byte *contents, bfd_vma off)
725 {
726 int template_val;
727 bfd_byte *hit_addr;
728 bfd_vma t0, t1, i0, i1, i2;
729
730 hit_addr = (bfd_byte *) (contents + off);
731 hit_addr -= (long) hit_addr & 0x3;
732 t0 = bfd_getl64 (hit_addr);
733 t1 = bfd_getl64 (hit_addr + 8);
734
735 /* Keep the instruction in slot 0. */
736 i0 = (t0 >> 5) & 0x1ffffffffffLL;
737 /* Use nop.b for slot 1. */
738 i1 = 0x4000000000LL;
739 /* For slot 2, turn brl into br by masking out bit 40. */
740 i2 = (t1 >> 23) & 0x0ffffffffffLL;
741
742 /* Turn a MLX bundle into a MBB bundle with the same stop-bit
743 variety. */
744 if (t0 & 0x1)
745 template_val = 0x13;
746 else
747 template_val = 0x12;
748 t0 = (i1 << 46) | (i0 << 5) | template_val;
749 t1 = (i2 << 23) | (i1 >> 18);
750
751 bfd_putl64 (t0, hit_addr);
752 bfd_putl64 (t1, hit_addr + 8);
753 }
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
760 \f
761 /* These functions do relaxation for IA-64 ELF. */
762
763 static void
764 elfNN_ia64_update_short_info (asection *sec, bfd_vma offset,
765 struct elfNN_ia64_link_hash_table *ia64_info)
766 {
767 /* Skip ABS and SHF_IA_64_SHORT sections. */
768 if (sec == bfd_abs_section_ptr
769 || (sec->flags & SEC_SMALL_DATA) != 0)
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
786 > ia64_info->max_short_sec->vma)
787 {
788 ia64_info->max_short_sec = sec;
789 ia64_info->max_short_offset = offset;
790 }
791 else if (sec->output_section->vma
792 < ia64_info->min_short_sec->vma)
793 {
794 ia64_info->min_short_sec = sec;
795 ia64_info->min_short_offset = offset;
796 }
797 }
798
799 static bfd_boolean
800 elfNN_ia64_relax_section (bfd *abfd, asection *sec,
801 struct bfd_link_info *link_info,
802 bfd_boolean *again)
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;
814 Elf_Internal_Rela *irel, *irelend;
815 bfd_byte *contents;
816 Elf_Internal_Sym *isymbuf = NULL;
817 struct elfNN_ia64_link_hash_table *ia64_info;
818 struct one_fixup *fixups = NULL;
819 bfd_boolean changed_contents = FALSE;
820 bfd_boolean changed_relocs = FALSE;
821 bfd_boolean changed_got = FALSE;
822 bfd_boolean skip_relax_pass_0 = TRUE;
823 bfd_boolean skip_relax_pass_1 = TRUE;
824 bfd_vma gp = 0;
825
826 /* Assume we're not going to change any sizes, and we'll only need
827 one pass. */
828 *again = FALSE;
829
830 if (link_info->relocatable)
831 (*link_info->callbacks->einfo)
832 (_("%P%F: --relax and -r may not be used together\n"));
833
834 /* Don't even try to relax for non-ELF outputs. */
835 if (!is_elf_hash_table (link_info->hash))
836 return FALSE;
837
838 /* Nothing to do if there are no relocations or there is no need for
839 the current pass. */
840 if ((sec->flags & SEC_RELOC) == 0
841 || sec->reloc_count == 0
842 || (link_info->relax_pass == 0 && sec->skip_relax_pass_0)
843 || (link_info->relax_pass == 1 && sec->skip_relax_pass_1))
844 return TRUE;
845
846 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
847
848 /* Load the relocations for this section. */
849 internal_relocs = (_bfd_elf_link_read_relocs
850 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
851 link_info->keep_memory));
852 if (internal_relocs == NULL)
853 return FALSE;
854
855 ia64_info = elfNN_ia64_hash_table (link_info);
856 irelend = internal_relocs + sec->reloc_count;
857
858 /* Get the section contents. */
859 if (elf_section_data (sec)->this_hdr.contents != NULL)
860 contents = elf_section_data (sec)->this_hdr.contents;
861 else
862 {
863 if (!bfd_malloc_and_get_section (abfd, sec, &contents))
864 goto error_return;
865 }
866
867 for (irel = internal_relocs; irel < irelend; irel++)
868 {
869 unsigned long r_type = ELFNN_R_TYPE (irel->r_info);
870 bfd_vma symaddr, reladdr, trampoff, toff, roff;
871 asection *tsec;
872 struct one_fixup *f;
873 bfd_size_type amt;
874 bfd_boolean is_branch;
875 struct elfNN_ia64_dyn_sym_info *dyn_i;
876 char symtype;
877
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:
884 /* In pass 1, all br relaxations are done. We can skip it. */
885 if (link_info->relax_pass == 1)
886 continue;
887 skip_relax_pass_0 = FALSE;
888 is_branch = TRUE;
889 break;
890
891 case R_IA64_PCREL60B:
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)
895 {
896 skip_relax_pass_1 = FALSE;
897 continue;
898 }
899 is_branch = TRUE;
900 break;
901
902 case R_IA64_GPREL22:
903 /* Update max_short_sec/min_short_sec. */
904
905 case R_IA64_LTOFF22X:
906 case R_IA64_LDXMOV:
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)
910 {
911 skip_relax_pass_1 = FALSE;
912 continue;
913 }
914 is_branch = FALSE;
915 break;
916
917 default:
918 continue;
919 }
920
921 /* Get the value of the symbol referred to by the reloc. */
922 if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
923 {
924 /* A local symbol. */
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
939 isym = isymbuf + ELFNN_R_SYM (irel->r_info);
940 if (isym->st_shndx == SHN_UNDEF)
941 continue; /* We can't do anything with undefined symbols. */
942 else if (isym->st_shndx == SHN_ABS)
943 tsec = bfd_abs_section_ptr;
944 else if (isym->st_shndx == SHN_COMMON)
945 tsec = bfd_com_section_ptr;
946 else if (isym->st_shndx == SHN_IA_64_ANSI_COMMON)
947 tsec = bfd_com_section_ptr;
948 else
949 tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
950
951 toff = isym->st_value;
952 dyn_i = get_dyn_sym_info (ia64_info, NULL, abfd, irel, FALSE);
953 symtype = ELF_ST_TYPE (isym->st_info);
954 }
955 else
956 {
957 unsigned long indx;
958 struct elf_link_hash_entry *h;
959
960 indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
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
968 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, FALSE);
969
970 /* For branches to dynamic symbols, we're interested instead
971 in a branch to the PLT entry. */
972 if (is_branch && dyn_i && dyn_i->want_plt2)
973 {
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
979 tsec = ia64_info->root.splt;
980 toff = dyn_i->plt2_offset;
981 BFD_ASSERT (irel->r_addend == 0);
982 }
983
984 /* Can't do anything else with dynamic symbols. */
985 else if (elfNN_ia64_dynamic_symbol_p (h, link_info, r_type))
986 continue;
987
988 else
989 {
990 /* We can't do anything with undefined symbols. */
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 }
998
999 symtype = h->type;
1000 }
1001
1002 if (tsec->sec_info_type == ELF_INFO_TYPE_MERGE)
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;
1022
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 }
1030 else
1031 toff += irel->r_addend;
1032
1033 symaddr = tsec->output_section->vma + tsec->output_offset + toff;
1034
1035 roff = irel->r_offset;
1036
1037 if (is_branch)
1038 {
1039 bfd_signed_vma offset;
1040
1041 reladdr = (sec->output_section->vma
1042 + sec->output_offset
1043 + roff) & (bfd_vma) -4;
1044
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. */
1052 if (tsec == ia64_info->root.splt)
1053 offset = -0x1000000 + 32;
1054 else
1055 offset = -0x1000000;
1056
1057 /* If the branch is in range, no need to do anything. */
1058 if ((bfd_signed_vma) (symaddr - reladdr) >= offset
1059 && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
1060 {
1061 /* If the 60-bit branch is in 21-bit range, optimize it. */
1062 if (r_type == R_IA64_PCREL60B)
1063 {
1064 elfNN_ia64_relax_brl (contents, roff);
1065
1066 irel->r_info
1067 = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
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)
1079 continue;
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 }
1090
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)
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);
1099 bfd_set_error (bfd_error_bad_value);
1100 goto error_return;
1101 }
1102
1103 /* If the branch and target are in the same section, you've
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)
1108 continue;
1109
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;
1114
1115 if (f == NULL)
1116 {
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
1123 if (tsec == ia64_info->root.splt)
1124 size = sizeof (plt_full_entry);
1125 else
1126 size = oor_branch_size;
1127
1128 /* Resize the current section to make room for the new branch. */
1129 trampoff = (sec->size + 15) & (bfd_vma) -16;
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
1137 amt = trampoff + size;
1138 contents = (bfd_byte *) bfd_realloc (contents, amt);
1139 if (contents == NULL)
1140 goto error_return;
1141 sec->size = amt;
1142
1143 if (tsec == ia64_info->root.splt)
1144 {
1145 memcpy (contents + trampoff, plt_full_entry, size);
1146
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 {
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
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;
1180 }
1181 else
1182 {
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
1189 /* Nop out the reloc, since we're finalizing things here. */
1190 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
1191 }
1192
1193 /* Fix up the existing branch to hit the trampoline. */
1194 if (elfNN_ia64_install_value (contents + roff, offset, r_type)
1195 != bfd_reloc_ok)
1196 goto error_return;
1197
1198 changed_contents = TRUE;
1199 changed_relocs = TRUE;
1200 }
1201 else
1202 {
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 }
1215
1216 /* If the data is out of range, do nothing. */
1217 if ((bfd_signed_vma) (symaddr - gp) >= 0x200000
1218 ||(bfd_signed_vma) (symaddr - gp) < -0x200000)
1219 continue;
1220
1221 if (r_type == R_IA64_GPREL22)
1222 elfNN_ia64_update_short_info (tsec->output_section,
1223 tsec->output_offset + toff,
1224 ia64_info);
1225 else if (r_type == R_IA64_LTOFF22X)
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 }
1235
1236 elfNN_ia64_update_short_info (tsec->output_section,
1237 tsec->output_offset + toff,
1238 ia64_info);
1239 }
1240 else
1241 {
1242 elfNN_ia64_relax_ldxmov (contents, roff);
1243 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
1244 changed_contents = TRUE;
1245 changed_relocs = TRUE;
1246 }
1247 }
1248 }
1249
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. */
1254
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
1263 if (isymbuf != NULL
1264 && symtab_hdr->contents != (unsigned char *) isymbuf)
1265 {
1266 if (! link_info->keep_memory)
1267 free (isymbuf);
1268 else
1269 {
1270 /* Cache the symbols for elf_link_input_bfd. */
1271 symtab_hdr->contents = (unsigned char *) isymbuf;
1272 }
1273 }
1274
1275 if (contents != NULL
1276 && elf_section_data (sec)->this_hdr.contents != contents)
1277 {
1278 if (!changed_contents && !link_info->keep_memory)
1279 free (contents);
1280 else
1281 {
1282 /* Cache the section contents for elf_link_input_bfd. */
1283 elf_section_data (sec)->this_hdr.contents = contents;
1284 }
1285 }
1286
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
1295 if (changed_got)
1296 {
1297 struct elfNN_ia64_allocate_data data;
1298 data.info = link_info;
1299 data.ofs = 0;
1300 ia64_info->self_dtpmod_offset = (bfd_vma) -1;
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);
1305 ia64_info->root.sgot->size = data.ofs;
1306
1307 if (ia64_info->root.dynamic_sections_created
1308 && ia64_info->root.srelgot != NULL)
1309 {
1310 /* Resize .rela.got. */
1311 ia64_info->root.srelgot->size = 0;
1312 if (link_info->shared
1313 && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
1314 ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
1315 data.only_got = TRUE;
1316 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries,
1317 &data);
1318 }
1319 }
1320
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 }
1327
1328 *again = changed_contents || changed_relocs;
1329 return TRUE;
1330
1331 error_return:
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);
1340 return FALSE;
1341 }
1342 #undef skip_relax_pass_0
1343 #undef skip_relax_pass_1
1344
1345 static void
1346 elfNN_ia64_relax_ldxmov (bfd_byte *contents, bfd_vma off)
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;
1356 default:
1357 abort ();
1358 }
1359
1360 dword = bfd_getl64 (contents + off);
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);
1372 bfd_putl64 (dword, contents + off);
1373 }
1374 \f
1375 /* Return TRUE if NAME is an unwind table section name. */
1376
1377 static inline bfd_boolean
1378 is_unwind_section_name (bfd *abfd, const char *name)
1379 {
1380 if (elfNN_ia64_hpux_vec (abfd->xvec)
1381 && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
1382 return FALSE;
1383
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));
1387 }
1388
1389 /* Handle an IA-64 specific section when reading an object file. This
1390 is called when bfd_section_from_shdr finds a section with an unknown
1391 type. */
1392
1393 static bfd_boolean
1394 elfNN_ia64_section_from_shdr (bfd *abfd,
1395 Elf_Internal_Shdr *hdr,
1396 const char *name,
1397 int shindex)
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:
1409 case SHT_IA_64_HP_OPT_ANOT:
1410 break;
1411
1412 case SHT_IA_64_EXT:
1413 if (strcmp (name, ELF_STRING_ia64_archext) != 0)
1414 return FALSE;
1415 break;
1416
1417 default:
1418 return FALSE;
1419 }
1420
1421 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
1422 return FALSE;
1423 newsect = hdr->bfd_section;
1424
1425 return TRUE;
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
1433 static bfd_boolean
1434 elfNN_ia64_section_flags (flagword *flags,
1435 const Elf_Internal_Shdr *hdr)
1436 {
1437 if (hdr->sh_flags & SHF_IA_64_SHORT)
1438 *flags |= SEC_SMALL_DATA;
1439
1440 return TRUE;
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
1446 static bfd_boolean
1447 elfNN_ia64_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr,
1448 asection *sec)
1449 {
1450 const char *name;
1451
1452 name = bfd_get_section_name (abfd, sec);
1453
1454 if (is_unwind_section_name (abfd, name))
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 }
1461 else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
1462 hdr->sh_type = SHT_IA_64_EXT;
1463 else if (strcmp (name, ".HP.opt_annot") == 0)
1464 hdr->sh_type = SHT_IA_64_HP_OPT_ANOT;
1465 else if (strcmp (name, ".reloc") == 0)
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. */
1482 hdr->sh_type = SHT_PROGBITS;
1483
1484 if (sec->flags & SEC_SMALL_DATA)
1485 hdr->sh_flags |= SHF_IA_64_SHORT;
1486
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
1492 return TRUE;
1493 }
1494
1495 /* The final processing done just before writing out an IA-64 ELF
1496 object file. */
1497
1498 static void
1499 elfNN_ia64_final_write_processing (bfd *abfd,
1500 bfd_boolean linker ATTRIBUTE_UNUSED)
1501 {
1502 Elf_Internal_Shdr *hdr;
1503 asection *s;
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:
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;
1516 break;
1517 }
1518 }
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;
1530 elf_flags_init (abfd) = TRUE;
1531 }
1532 }
1533
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
1537 static bfd_boolean
1538 elfNN_ia64_add_symbol_hook (bfd *abfd,
1539 struct bfd_link_info *info,
1540 Elf_Internal_Sym *sym,
1541 const char **namep ATTRIBUTE_UNUSED,
1542 flagword *flagsp ATTRIBUTE_UNUSED,
1543 asection **secp,
1544 bfd_vma *valp)
1545 {
1546 if (sym->st_shndx == SHN_COMMON
1547 && !info->relocatable
1548 && sym->st_size <= elf_gp_size (abfd))
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 {
1557 scomm = bfd_make_section_with_flags (abfd, ".scommon",
1558 (SEC_ALLOC
1559 | SEC_IS_COMMON
1560 | SEC_LINKER_CREATED));
1561 if (scomm == NULL)
1562 return FALSE;
1563 }
1564
1565 *secp = scomm;
1566 *valp = sym->st_size;
1567 }
1568
1569 return TRUE;
1570 }
1571
1572 /* Return the number of additional phdrs we will need. */
1573
1574 static int
1575 elfNN_ia64_additional_program_headers (bfd *abfd,
1576 struct bfd_link_info *info ATTRIBUTE_UNUSED)
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
1586 /* Count how many PT_IA_64_UNWIND segments we need. */
1587 for (s = abfd->sections; s; s = s->next)
1588 if (is_unwind_section_name (abfd, s->name) && (s->flags & SEC_LOAD))
1589 ++ret;
1590
1591 return ret;
1592 }
1593
1594 static bfd_boolean
1595 elfNN_ia64_modify_segment_map (bfd *abfd,
1596 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1597 {
1598 struct elf_segment_map *m, **pm;
1599 Elf_Internal_Shdr *hdr;
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 {
1612 m = ((struct elf_segment_map *)
1613 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1614 if (m == NULL)
1615 return FALSE;
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
1633 /* Install PT_IA_64_UNWIND segments, if needed. */
1634 for (s = abfd->sections; s; s = s->next)
1635 {
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))
1641 {
1642 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1643 if (m->p_type == PT_IA_64_UNWIND)
1644 {
1645 int i;
1646
1647 /* Look through all sections in the unwind segment
1648 for a match since there may be multiple sections
1649 to a segment. */
1650 for (i = m->count - 1; i >= 0; --i)
1651 if (m->sections[i] == s)
1652 break;
1653
1654 if (i >= 0)
1655 break;
1656 }
1657
1658 if (m == NULL)
1659 {
1660 m = ((struct elf_segment_map *)
1661 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1662 if (m == NULL)
1663 return FALSE;
1664
1665 m->p_type = PT_IA_64_UNWIND;
1666 m->count = 1;
1667 m->sections[0] = s;
1668 m->next = NULL;
1669
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 }
1676 }
1677 }
1678
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
1686 static bfd_boolean
1687 elfNN_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++)
1695 if (m->p_type == PT_LOAD)
1696 {
1697 int i;
1698 for (i = m->count - 1; i >= 0; --i)
1699 {
1700 struct bfd_link_order *order = m->sections[i]->map_head.link_order;
1701
1702 while (order != NULL)
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 {
1710 p->p_flags |= PF_IA_64_NORECOV;
1711 goto found;
1712 }
1713 }
1714 order = order->next;
1715 }
1716 }
1717 found:;
1718 }
1719
1720 return TRUE;
1721 }
1722
1723 /* According to the Tahoe assembler spec, all labels starting with a
1724 '.' are local. */
1725
1726 static bfd_boolean
1727 elfNN_ia64_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
1728 const char *name)
1729 {
1730 return name[0] == '.';
1731 }
1732
1733 /* Should we do dynamic things to this symbol? */
1734
1735 static bfd_boolean
1736 elfNN_ia64_dynamic_symbol_p (struct elf_link_hash_entry *h,
1737 struct bfd_link_info *info, int r_type)
1738 {
1739 bfd_boolean ignore_protected
1740 = ((r_type & 0xf8) == 0x40 /* FPTR relocs */
1741 || (r_type & 0xf8) == 0x50); /* LTOFF_FPTR relocs */
1742
1743 return _bfd_elf_dynamic_symbol_p (h, info, ignore_protected);
1744 }
1745 \f
1746 static struct bfd_hash_entry*
1747 elfNN_ia64_new_elf_hash_entry (struct bfd_hash_entry *entry,
1748 struct bfd_hash_table *table,
1749 const char *string)
1750 {
1751 struct elfNN_ia64_link_hash_entry *ret;
1752 ret = (struct elfNN_ia64_link_hash_entry *) entry;
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
1762 /* Call the allocation method of the superclass. */
1763 ret = ((struct elfNN_ia64_link_hash_entry *)
1764 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1765 table, string));
1766
1767 ret->info = NULL;
1768 ret->count = 0;
1769 ret->sorted_count = 0;
1770 ret->size = 0;
1771 return (struct bfd_hash_entry *) ret;
1772 }
1773
1774 static void
1775 elfNN_ia64_hash_copy_indirect (struct bfd_link_info *info,
1776 struct elf_link_hash_entry *xdir,
1777 struct elf_link_hash_entry *xind)
1778 {
1779 struct elfNN_ia64_link_hash_entry *dir, *ind;
1780
1781 dir = (struct elfNN_ia64_link_hash_entry *) xdir;
1782 ind = (struct elfNN_ia64_link_hash_entry *) xind;
1783
1784 /* Copy down any references that we may have already seen to the
1785 symbol which just became indirect. */
1786
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;
1791
1792 if (ind->root.root.type != bfd_link_hash_indirect)
1793 return;
1794
1795 /* Copy over the got and plt data. This would have been done
1796 by check_relocs. */
1797
1798 if (ind->info != NULL)
1799 {
1800 struct elfNN_ia64_dyn_sym_info *dyn_i;
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;
1810
1811 ind->info = NULL;
1812 ind->count = 0;
1813 ind->sorted_count = 0;
1814 ind->size = 0;
1815
1816 /* Fix up the dyn_sym_info pointers to the global symbol. */
1817 for (count = dir->count, dyn_i = dir->info;
1818 count != 0;
1819 count--, dyn_i++)
1820 dyn_i->h = &dir->root;
1821 }
1822
1823 /* Copy over the dynindx. */
1824
1825 if (ind->root.dynindx != -1)
1826 {
1827 if (dir->root.dynindx != -1)
1828 _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
1829 dir->root.dynstr_index);
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 }
1835 }
1836
1837 static void
1838 elfNN_ia64_hash_hide_symbol (struct bfd_link_info *info,
1839 struct elf_link_hash_entry *xh,
1840 bfd_boolean force_local)
1841 {
1842 struct elfNN_ia64_link_hash_entry *h;
1843 struct elfNN_ia64_dyn_sym_info *dyn_i;
1844 unsigned int count;
1845
1846 h = (struct elfNN_ia64_link_hash_entry *)xh;
1847
1848 _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1849
1850 for (count = h->count, dyn_i = h->info;
1851 count != 0;
1852 count--, dyn_i++)
1853 {
1854 dyn_i->want_plt2 = 0;
1855 dyn_i->want_plt = 0;
1856 }
1857 }
1858
1859 /* Compute a hash of a local hash entry. */
1860
1861 static hashval_t
1862 elfNN_ia64_local_htab_hash (const void *ptr)
1863 {
1864 struct elfNN_ia64_local_hash_entry *entry
1865 = (struct elfNN_ia64_local_hash_entry *) ptr;
1866
1867 return ELF_LOCAL_SYMBOL_HASH (entry->id, entry->r_sym);
1868 }
1869
1870 /* Compare local hash entries. */
1871
1872 static int
1873 elfNN_ia64_local_htab_eq (const void *ptr1, const void *ptr2)
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
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
1887 static struct bfd_link_hash_table*
1888 elfNN_ia64_hash_table_create (bfd *abfd)
1889 {
1890 struct elfNN_ia64_link_hash_table *ret;
1891
1892 ret = bfd_zmalloc ((bfd_size_type) sizeof (*ret));
1893 if (!ret)
1894 return 0;
1895
1896 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1897 elfNN_ia64_new_elf_hash_entry,
1898 sizeof (struct elfNN_ia64_link_hash_entry)))
1899 {
1900 free (ret);
1901 return 0;
1902 }
1903
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)
1908 {
1909 free (ret);
1910 return 0;
1911 }
1912
1913 return &ret->root.root;
1914 }
1915
1916 /* Free the global elfNN_ia64_dyn_sym_info array. */
1917
1918 static bfd_boolean
1919 elfNN_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
1942 static bfd_boolean
1943 elfNN_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
1961 /* Destroy IA-64 linker hash table. */
1962
1963 static void
1964 elfNN_ia64_hash_table_free (struct bfd_link_hash_table *hash)
1965 {
1966 struct elfNN_ia64_link_hash_table *ia64_info
1967 = (struct elfNN_ia64_link_hash_table *) hash;
1968 if (ia64_info->loc_hash_table)
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 }
1974 if (ia64_info->loc_hash_memory)
1975 objalloc_free ((struct objalloc *) ia64_info->loc_hash_memory);
1976 elf_link_hash_traverse (&ia64_info->root,
1977 elfNN_ia64_global_dyn_info_free, NULL);
1978 _bfd_generic_link_hash_table_free (hash);
1979 }
1980
1981 /* Traverse both local and global hash tables. */
1982
1983 struct elfNN_ia64_dyn_sym_traverse_data
1984 {
1985 bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR);
1986 PTR data;
1987 };
1988
1989 static bfd_boolean
1990 elfNN_ia64_global_dyn_sym_thunk (struct bfd_hash_entry *xentry,
1991 PTR xdata)
1992 {
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;
1998 unsigned int count;
1999
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
2003 for (count = entry->count, dyn_i = entry->info;
2004 count != 0;
2005 count--, dyn_i++)
2006 if (! (*data->func) (dyn_i, data->data))
2007 return FALSE;
2008 return TRUE;
2009 }
2010
2011 static bfd_boolean
2012 elfNN_ia64_local_dyn_sym_thunk (void **slot, PTR xdata)
2013 {
2014 struct elfNN_ia64_local_hash_entry *entry
2015 = (struct elfNN_ia64_local_hash_entry *) *slot;
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;
2019 unsigned int count;
2020
2021 for (count = entry->count, dyn_i = entry->info;
2022 count != 0;
2023 count--, dyn_i++)
2024 if (! (*data->func) (dyn_i, data->data))
2025 return FALSE;
2026 return TRUE;
2027 }
2028
2029 static void
2030 elfNN_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)
2033 {
2034 struct elfNN_ia64_dyn_sym_traverse_data xdata;
2035
2036 xdata.func = func;
2037 xdata.data = data;
2038
2039 elf_link_hash_traverse (&ia64_info->root,
2040 elfNN_ia64_global_dyn_sym_thunk, &xdata);
2041 htab_traverse (ia64_info->loc_hash_table,
2042 elfNN_ia64_local_dyn_sym_thunk, &xdata);
2043 }
2044 \f
2045 static bfd_boolean
2046 elfNN_ia64_create_dynamic_sections (bfd *abfd,
2047 struct bfd_link_info *info)
2048 {
2049 struct elfNN_ia64_link_hash_table *ia64_info;
2050 asection *s;
2051
2052 if (! _bfd_elf_create_dynamic_sections (abfd, info))
2053 return FALSE;
2054
2055 ia64_info = elfNN_ia64_hash_table (info);
2056
2057 {
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);
2061 /* The .got section is always aligned at 8 bytes. */
2062 bfd_set_section_alignment (abfd, ia64_info->root.sgot, 3);
2063 }
2064
2065 if (!get_pltoff (abfd, info, ia64_info))
2066 return FALSE;
2067
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));
2074 if (s == NULL
2075 || !bfd_set_section_alignment (abfd, s, LOG_SECTION_ALIGN))
2076 return FALSE;
2077 ia64_info->rel_pltoff_sec = s;
2078
2079 return TRUE;
2080 }
2081
2082 /* Find and/or create a hash entry for local symbol. */
2083 static struct elfNN_ia64_local_hash_entry *
2084 get_local_sym_hash (struct elfNN_ia64_link_hash_table *ia64_info,
2085 bfd *abfd, const Elf_Internal_Rela *rel,
2086 bfd_boolean create)
2087 {
2088 struct elfNN_ia64_local_hash_entry e, *ret;
2089 asection *sec = abfd->sections;
2090 hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
2091 ELFNN_R_SYM (rel->r_info));
2092 void **slot;
2093
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);
2098
2099 if (!slot)
2100 return NULL;
2101
2102 if (*slot)
2103 return (struct elfNN_ia64_local_hash_entry *) *slot;
2104
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 }
2115 return ret;
2116 }
2117
2118 /* Used to sort elfNN_ia64_dyn_sym_info array. */
2119
2120 static int
2121 addend_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
2128 return x->addend < y->addend ? -1 : x->addend > y->addend ? 1 : 0;
2129 }
2130
2131 /* Sort elfNN_ia64_dyn_sym_info array and remove duplicates. */
2132
2133 static unsigned int
2134 sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info *info,
2135 unsigned int count)
2136 {
2137 bfd_vma curr, prev, got_offset;
2138 unsigned int i, kept, dupes, diff, dest, src, len;
2139
2140 qsort (info, count, sizeof (*info), addend_compare);
2141
2142 /* Find the first duplicate. */
2143 prev = info [0].addend;
2144 got_offset = info [0].got_offset;
2145 for (i = 1; i < count; i++)
2146 {
2147 curr = info [i].addend;
2148 if (curr == prev)
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;
2156 prev = curr;
2157 }
2158
2159 /* We may move a block of elements to here. */
2160 dest = i++;
2161
2162 /* Remove duplicates. */
2163 if (i < count)
2164 {
2165 while (i < count)
2166 {
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
2173 curr = info [i].addend;
2174 got_offset = info [i].got_offset;
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++)
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;
2193 }
2194 else
2195 src = i;
2196
2197 if (src >= count)
2198 break;
2199
2200 /* Find the next duplicate. SRC will be kept. */
2201 prev = info [src].addend;
2202 got_offset = info [src].got_offset;
2203 for (dupes = src + 1; dupes < count; dupes ++)
2204 {
2205 curr = info [dupes].addend;
2206 if (curr == prev)
2207 {
2208 /* Make sure that got_offset is valid. */
2209 if (got_offset == (bfd_vma) -1)
2210 got_offset = info [dupes].got_offset;
2211
2212 /* For duplicates, make sure that the kept one has
2213 a valid got_offset. */
2214 if (got_offset != (bfd_vma) -1)
2215 info [dupes - 1].got_offset = got_offset;
2216 break;
2217 }
2218 got_offset = info [dupes].got_offset;
2219 prev = curr;
2220 }
2221
2222 /* How much to move. */
2223 len = dupes - src;
2224 i = dupes + 1;
2225
2226 if (len == 1 && dupes < count)
2227 {
2228 /* If we only move 1 element, we combine it with the next
2229 one. There must be at least a duplicate. Find the
2230 next different one. */
2231 for (diff = dupes + 1, src++; diff < count; diff++, src++)
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;
2245
2246 if (diff < count)
2247 {
2248 /* Find the next duplicate. Track the current valid
2249 offset. */
2250 prev = info [diff].addend;
2251 got_offset = info [diff].got_offset;
2252 for (dupes = diff + 1; dupes < count; dupes ++)
2253 {
2254 curr = info [dupes].addend;
2255 if (curr == prev)
2256 {
2257 /* For duplicates, make sure that GOT_OFFSET
2258 is valid. */
2259 if (got_offset == (bfd_vma) -1)
2260 got_offset = info [dupes].got_offset;
2261 break;
2262 }
2263 got_offset = info [dupes].got_offset;
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 }
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 }
2293
2294 return count;
2295 }
2296
2297 /* Find and/or create a descriptor for dynamic symbol info. This will
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. */
2312
2313 static struct elfNN_ia64_dyn_sym_info *
2314 get_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)
2317 {
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;
2321 bfd_vma addend = rel ? rel->r_addend : 0;
2322 bfd_size_type amt;
2323
2324 if (h)
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 }
2334 else
2335 {
2336 struct elfNN_ia64_local_hash_entry *loc_h;
2337
2338 loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
2339 if (!loc_h)
2340 {
2341 BFD_ASSERT (!create);
2342 return NULL;
2343 }
2344
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;
2349 }
2350
2351 count = *count_p;
2352 sorted_count = *sorted_count_p;
2353 size = *size_p;
2354 info = *info_p;
2355 if (create)
2356 {
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
2408 has_space:
2409 /* Append the new one to the array. */
2410 dyn_i = info + count;
2411 memset (dyn_i, 0, sizeof (*dyn_i));
2412 dyn_i->got_offset = (bfd_vma) -1;
2413 dyn_i->addend = addend;
2414
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);
2447 }
2448
2449 return dyn_i;
2450 }
2451
2452 static asection *
2453 get_got (bfd *abfd, struct bfd_link_info *info,
2454 struct elfNN_ia64_link_hash_table *ia64_info)
2455 {
2456 asection *got;
2457 bfd *dynobj;
2458
2459 got = ia64_info->root.sgot;
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
2470 got = ia64_info->root.sgot;
2471
2472 /* The .got section is always aligned at 8 bytes. */
2473 if (!bfd_set_section_alignment (abfd, got, 3))
2474 return 0;
2475
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
2484 because it contains "official procedure descriptors". The "official"
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
2488 static asection *
2489 get_fptr (bfd *abfd, struct bfd_link_info *info,
2490 struct elfNN_ia64_link_hash_table *ia64_info)
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
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));
2509 if (!fptr
2510 || !bfd_set_section_alignment (abfd, fptr, 4))
2511 {
2512 BFD_ASSERT (0);
2513 return NULL;
2514 }
2515
2516 ia64_info->fptr_sec = fptr;
2517
2518 if (info->pie)
2519 {
2520 asection *fptr_rel;
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));
2527 if (fptr_rel == NULL
2528 || !bfd_set_section_alignment (abfd, fptr_rel,
2529 LOG_SECTION_ALIGN))
2530 {
2531 BFD_ASSERT (0);
2532 return NULL;
2533 }
2534
2535 ia64_info->rel_fptr_sec = fptr_rel;
2536 }
2537 }
2538
2539 return fptr;
2540 }
2541
2542 static asection *
2543 get_pltoff (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED,
2544 struct elfNN_ia64_link_hash_table *ia64_info)
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
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));
2564 if (!pltoff
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
2577 static asection *
2578 get_reloc_section (bfd *abfd,
2579 struct elfNN_ia64_link_hash_table *ia64_info,
2580 asection *sec, bfd_boolean create)
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
2592 BFD_ASSERT ((CONST_STRNEQ (srel_name, ".rela")
2593 && strcmp (bfd_get_section_name (abfd, sec),
2594 srel_name+5) == 0)
2595 || (CONST_STRNEQ (srel_name, ".rel")
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 {
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));
2612 if (srel == NULL
2613 || !bfd_set_section_alignment (dynobj, srel,
2614 LOG_SECTION_ALIGN))
2615 return NULL;
2616 }
2617
2618 return srel;
2619 }
2620
2621 static bfd_boolean
2622 count_dyn_reloc (bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
2623 asection *srel, int type, bfd_boolean reltext)
2624 {
2625 struct elfNN_ia64_dyn_reloc_entry *rent;
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 {
2633 rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2634 bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
2635 if (!rent)
2636 return FALSE;
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 }
2644 rent->reltext = reltext;
2645 rent->count++;
2646
2647 return TRUE;
2648 }
2649
2650 static bfd_boolean
2651 elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
2652 asection *sec,
2653 const Elf_Internal_Rela *relocs)
2654 {
2655 struct elfNN_ia64_link_hash_table *ia64_info;
2656 const Elf_Internal_Rela *relend;
2657 Elf_Internal_Shdr *symtab_hdr;
2658 const Elf_Internal_Rela *rel;
2659 asection *got, *fptr, *srel, *pltoff;
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;
2677
2678 if (info->relocatable)
2679 return TRUE;
2680
2681 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2682 ia64_info = elfNN_ia64_hash_table (info);
2683
2684 got = fptr = srel = pltoff = NULL;
2685
2686 relend = relocs + sec->reloc_count;
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
2710 && (!SYMBOLIC_BIND (info, h)
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
2855 with the modified get_dyn_sym_info. */
2856 for (rel = relocs; rel < relend; ++rel)
2857 {
2858 struct elfNN_ia64_dyn_sym_info *dyn_i;
2859 int dynrel_type = R_IA64_NONE;
2860
2861 r_symndx = ELFNN_R_SYM (rel->r_info);
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
2872 h->ref_regular = 1;
2873 }
2874 else
2875 h = NULL;
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. */
2881 maybe_dynamic = (h && ((!info->executable
2882 && (!SYMBOLIC_BIND (info, h)
2883 || info->unresolved_syms_in_shared_libs == RM_IGNORE))
2884 || !h->def_regular
2885 || h->root.type == bfd_link_hash_defweak));
2886
2887 need_entry = 0;
2888 switch (ELFNN_R_TYPE (rel->r_info))
2889 {
2890 case R_IA64_TPREL64MSB:
2891 case R_IA64_TPREL64LSB:
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
2905 case R_IA64_DTPREL32MSB:
2906 case R_IA64_DTPREL32LSB:
2907 case R_IA64_DTPREL64MSB:
2908 case R_IA64_DTPREL64LSB:
2909 if (info->shared || maybe_dynamic)
2910 need_entry = NEED_DYNREL;
2911 dynrel_type = R_IA64_DTPRELNNLSB;
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;
2928
2929 case R_IA64_LTOFF_FPTR22:
2930 case R_IA64_LTOFF_FPTR64I:
2931 case R_IA64_LTOFF_FPTR32MSB:
2932 case R_IA64_LTOFF_FPTR32LSB:
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:
2943 if (info->shared || h)
2944 need_entry = NEED_FPTR | NEED_DYNREL;
2945 else
2946 need_entry = NEED_FPTR;
2947 dynrel_type = R_IA64_FPTRNNLSB;
2948 break;
2949
2950 case R_IA64_LTOFF22:
2951 case R_IA64_LTOFF64I:
2952 need_entry = NEED_GOT;
2953 break;
2954
2955 case R_IA64_LTOFF22X:
2956 need_entry = NEED_GOTX;
2957 break;
2958
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 }
2969 break;
2970
2971 case R_IA64_PCREL21B:
2972 case R_IA64_PCREL60B:
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. */
2989 if (info->shared || maybe_dynamic)
2990 need_entry = NEED_DYNREL;
2991 dynrel_type = R_IA64_DIRNNLSB;
2992 break;
2993
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
3002 case R_IA64_PCREL22:
3003 case R_IA64_PCREL64I:
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;
3010 dynrel_type = R_IA64_PCRELNNLSB;
3011 break;
3012 }
3013
3014 if (!need_entry)
3015 continue;
3016
3017 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, FALSE);
3018
3019 /* Record whether or not this is a local symbol. */
3020 dyn_i->h = h;
3021
3022 /* Create what's needed. */
3023 if (need_entry & (NEED_GOT | NEED_GOTX | NEED_TPREL
3024 | NEED_DTPMOD | NEED_DTPREL))
3025 {
3026 if (!got)
3027 {
3028 got = get_got (abfd, info, ia64_info);
3029 if (!got)
3030 return FALSE;
3031 }
3032 if (need_entry & NEED_GOT)
3033 dyn_i->want_got = 1;
3034 if (need_entry & NEED_GOTX)
3035 dyn_i->want_gotx = 1;
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;
3042 }
3043 if (need_entry & NEED_FPTR)
3044 {
3045 if (!fptr)
3046 {
3047 fptr = get_fptr (abfd, info, ia64_info);
3048 if (!fptr)
3049 return FALSE;
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. */
3055 if (!h && info->shared)
3056 {
3057 if (! (bfd_elf_link_record_local_dynamic_symbol
3058 (info, abfd, (long) r_symndx)))
3059 return FALSE;
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;
3070 h->needs_plt = 1;
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)
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 }
3085
3086 dyn_i->want_pltoff = 1;
3087 }
3088 if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
3089 {
3090 if (!srel)
3091 {
3092 srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
3093 if (!srel)
3094 return FALSE;
3095 }
3096 if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type,
3097 (sec->flags & SEC_READONLY) != 0))
3098 return FALSE;
3099 }
3100 }
3101
3102 return TRUE;
3103 }
3104
3105 /* For cleanliness, and potentially faster dynamic loading, allocate
3106 external GOT entries first. */
3107
3108 static bfd_boolean
3109 allocate_global_data_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
3110 PTR data)
3111 {
3112 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3113
3114 if ((dyn_i->want_got || dyn_i->want_gotx)
3115 && ! dyn_i->want_fptr
3116 && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
3117 {
3118 dyn_i->got_offset = x->ofs;
3119 x->ofs += 8;
3120 }
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 {
3128 if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
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 }
3145 }
3146 if (dyn_i->want_dtprel)
3147 {
3148 dyn_i->dtprel_offset = x->ofs;
3149 x->ofs += 8;
3150 }
3151 return TRUE;
3152 }
3153
3154 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
3155
3156 static bfd_boolean
3157 allocate_global_fptr_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
3158 PTR data)
3159 {
3160 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3161
3162 if (dyn_i->want_got
3163 && dyn_i->want_fptr
3164 && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, R_IA64_FPTRNNLSB))
3165 {
3166 dyn_i->got_offset = x->ofs;
3167 x->ofs += 8;
3168 }
3169 return TRUE;
3170 }
3171
3172 /* Lastly, allocate all the GOT entries for local data. */
3173
3174 static bfd_boolean
3175 allocate_local_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
3176 PTR data)
3177 {
3178 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3179
3180 if ((dyn_i->want_got || dyn_i->want_gotx)
3181 && !elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
3182 {
3183 dyn_i->got_offset = x->ofs;
3184 x->ofs += 8;
3185 }
3186 return TRUE;
3187 }
3188
3189 /* Search for the index of a global symbol in it's defining object file. */
3190
3191 static long
3192 global_sym_index (struct elf_link_hash_entry *h)
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
3210 static bfd_boolean
3211 allocate_fptr (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data)
3212 {
3213 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3214
3215 if (dyn_i->want_fptr)
3216 {
3217 struct elf_link_hash_entry *h = dyn_i->h;
3218
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
3224 if (!x->info->executable
3225 && (!h
3226 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
3227 || (h->root.type != bfd_link_hash_undefweak
3228 && h->root.type != bfd_link_hash_undefined)))
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
3235 if (!bfd_elf_link_record_local_dynamic_symbol
3236 (x->info, h->root.u.def.section->owner,
3237 global_sym_index (h)))
3238 return FALSE;
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 }
3251 return TRUE;
3252 }
3253
3254 /* Allocate all the minimal PLT entries. */
3255
3256 static bfd_boolean
3257 allocate_plt_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
3258 PTR data)
3259 {
3260 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
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
3271 /* ??? Versioned symbols seem to lose NEEDS_PLT. */
3272 if (elfNN_ia64_dynamic_symbol_p (h, x->info, 0))
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 }
3288 return TRUE;
3289 }
3290
3291 /* Allocate all the full PLT entries. */
3292
3293 static bfd_boolean
3294 allocate_plt2_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
3295 PTR data)
3296 {
3297 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
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 }
3312 return TRUE;
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
3320 static bfd_boolean
3321 allocate_pltoff_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
3322 PTR data)
3323 {
3324 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3325
3326 if (dyn_i->want_pltoff)
3327 {
3328 dyn_i->pltoff_offset = x->ofs;
3329 x->ofs += 16;
3330 }
3331 return TRUE;
3332 }
3333
3334 /* Allocate dynamic relocations for those symbols that turned out
3335 to be dynamic. */
3336
3337 static bfd_boolean
3338 allocate_dynrel_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
3339 PTR data)
3340 {
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;
3344 bfd_boolean dynamic_symbol, shared, resolved_zero;
3345
3346 ia64_info = elfNN_ia64_hash_table (x->info);
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
3351 shared = x->info->shared;
3352 resolved_zero = (dyn_i->h
3353 && ELF_ST_VISIBILITY (dyn_i->h->other)
3354 && dyn_i->h->root.type == bfd_link_hash_undefweak);
3355
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)
3369 ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
3370 }
3371 if ((dynamic_symbol || shared) && dyn_i->want_tprel)
3372 ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
3373 if (dynamic_symbol && dyn_i->want_dtpmod)
3374 ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
3375 if (dynamic_symbol && dyn_i->want_dtprel)
3376 ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
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
3402 /* Take care of the normal data relocations. */
3403
3404 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
3405 {
3406 int count = rent->count;
3407
3408 switch (rent->type)
3409 {
3410 case R_IA64_FPTR32LSB:
3411 case R_IA64_FPTR64LSB:
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)
3417 continue;
3418 break;
3419 case R_IA64_PCREL32LSB:
3420 case R_IA64_PCREL64LSB:
3421 if (!dynamic_symbol)
3422 continue;
3423 break;
3424 case R_IA64_DIR32LSB:
3425 case R_IA64_DIR64LSB:
3426 if (!dynamic_symbol && !shared)
3427 continue;
3428 break;
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;
3437 case R_IA64_DTPREL32LSB:
3438 case R_IA64_TPREL64LSB:
3439 case R_IA64_DTPREL64LSB:
3440 case R_IA64_DTPMOD64LSB:
3441 break;
3442 default:
3443 abort ();
3444 }
3445 if (rent->reltext)
3446 ia64_info->reltext = 1;
3447 rent->srel->size += sizeof (ElfNN_External_Rela) * count;
3448 }
3449
3450 return TRUE;
3451 }
3452
3453 static bfd_boolean
3454 elfNN_ia64_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
3455 struct elf_link_hash_entry *h)
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. */
3463 if (h->u.weakdef != NULL)
3464 {
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;
3469 return TRUE;
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
3479 return TRUE;
3480 }
3481
3482 static bfd_boolean
3483 elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
3484 struct bfd_link_info *info)
3485 {
3486 struct elfNN_ia64_allocate_data data;
3487 struct elfNN_ia64_link_hash_table *ia64_info;
3488 asection *sec;
3489 bfd *dynobj;
3490 bfd_boolean relplt = FALSE;
3491
3492 dynobj = elf_hash_table(info)->dynobj;
3493 ia64_info = elfNN_ia64_hash_table (info);
3494 ia64_info->self_dtpmod_offset = (bfd_vma) -1;
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
3500 && info->executable)
3501 {
3502 sec = bfd_get_section_by_name (dynobj, ".interp");
3503 BFD_ASSERT (sec != NULL);
3504 sec->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
3505 sec->size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
3506 }
3507
3508 /* Allocate the GOT entries. */
3509
3510 if (ia64_info->root.sgot)
3511 {
3512 data.ofs = 0;
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);
3516 ia64_info->root.sgot->size = data.ofs;
3517 }
3518
3519 /* Allocate the FPTR entries. */
3520
3521 if (ia64_info->fptr_sec)
3522 {
3523 data.ofs = 0;
3524 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
3525 ia64_info->fptr_sec->size = data.ofs;
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.
3530 We do this even though dynamic_sections_created may be FALSE, because
3531 this has the side-effect of clearing want_plt and want_plt2. */
3532
3533 data.ofs = 0;
3534 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
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. */
3544 data.ofs = (data.ofs + 31) & (bfd_vma) -32;
3545
3546 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
3547 if (data.ofs != 0 || ia64_info->root.dynamic_sections_created)
3548 {
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
3553 BFD_ASSERT (ia64_info->root.dynamic_sections_created);
3554
3555 ia64_info->root.splt->size = data.ofs;
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");
3560 sec->size = 8 * PLT_RESERVED_WORDS;
3561 }
3562
3563 /* Allocate the PLTOFF entries. */
3564
3565 if (ia64_info->pltoff_sec)
3566 {
3567 data.ofs = 0;
3568 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
3569 ia64_info->pltoff_sec->size = data.ofs;
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
3577 if (info->shared && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
3578 ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
3579 data.only_got = FALSE;
3580 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
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 {
3587 bfd_boolean strip;
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
3600 strip = (sec->size == 0);
3601
3602 if (sec == ia64_info->root.sgot)
3603 strip = FALSE;
3604 else if (sec == ia64_info->root.srelgot)
3605 {
3606 if (strip)
3607 ia64_info->root.srelgot = NULL;
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 }
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 }
3627 else if (sec == ia64_info->root.splt)
3628 {
3629 if (strip)
3630 ia64_info->root.splt = NULL;
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 {
3643 relplt = TRUE;
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)
3658 strip = FALSE;
3659 else if (CONST_STRNEQ (name, ".rel"))
3660 {
3661 if (!strip)
3662 {
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)
3673 sec->flags |= SEC_EXCLUDE;
3674 else
3675 {
3676 /* Allocate memory for the section contents. */
3677 sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->size);
3678 if (sec->contents == NULL && sec->size != 0)
3679 return FALSE;
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
3689 if (info->executable)
3690 {
3691 /* The DT_DEBUG entry is filled in by the dynamic linker and used
3692 by the debugger. */
3693 #define add_dynamic_entry(TAG, VAL) \
3694 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3695
3696 if (!add_dynamic_entry (DT_DEBUG, 0))
3697 return FALSE;
3698 }
3699
3700 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
3701 return FALSE;
3702 if (!add_dynamic_entry (DT_PLTGOT, 0))
3703 return FALSE;
3704
3705 if (relplt)
3706 {
3707 if (!add_dynamic_entry (DT_PLTRELSZ, 0)
3708 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3709 || !add_dynamic_entry (DT_JMPREL, 0))
3710 return FALSE;
3711 }
3712
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)))
3716 return FALSE;
3717
3718 if (ia64_info->reltext)
3719 {
3720 if (!add_dynamic_entry (DT_TEXTREL, 0))
3721 return FALSE;
3722 info->flags |= DF_TEXTREL;
3723 }
3724 }
3725
3726 /* ??? Perhaps force __gp local. */
3727
3728 return TRUE;
3729 }
3730
3731 static bfd_reloc_status_type
3732 elfNN_ia64_install_value (bfd_byte *hit_addr, bfd_vma v,
3733 unsigned int r_type)
3734 {
3735 const struct ia64_operand *op;
3736 int bigendian = 0, shift = 0;
3737 bfd_vma t0, t1, dword;
3738 ia64_insn insn;
3739 enum ia64_opnd opnd;
3740 const char *err;
3741 size_t size = 8;
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
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
3755 /* Instruction relocations. */
3756
3757 case R_IA64_IMM14:
3758 case R_IA64_TPREL14:
3759 case R_IA64_DTPREL14:
3760 opnd = IA64_OPND_IMM14;
3761 break;
3762
3763 case R_IA64_PCREL21F: opnd = IA64_OPND_TGT25; break;
3764 case R_IA64_PCREL21M: opnd = IA64_OPND_TGT25b; break;
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;
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:
3776 case R_IA64_PCREL22:
3777 case R_IA64_LTOFF_FPTR22:
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:
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:
3790 case R_IA64_PCREL64I:
3791 case R_IA64_FPTR64I:
3792 case R_IA64_LTOFF_FPTR64I:
3793 case R_IA64_TPREL64I:
3794 case R_IA64_DTPREL64I:
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:
3804 case R_IA64_LTOFF_FPTR32MSB:
3805 case R_IA64_SEGREL32MSB:
3806 case R_IA64_SECREL32MSB:
3807 case R_IA64_LTV32MSB:
3808 case R_IA64_DTPREL32MSB:
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:
3816 case R_IA64_LTOFF_FPTR32LSB:
3817 case R_IA64_SEGREL32LSB:
3818 case R_IA64_SECREL32LSB:
3819 case R_IA64_LTV32LSB:
3820 case R_IA64_DTPREL32LSB:
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:
3833 case R_IA64_TPREL64MSB:
3834 case R_IA64_DTPMOD64MSB:
3835 case R_IA64_DTPREL64MSB:
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:
3848 case R_IA64_TPREL64LSB:
3849 case R_IA64_DTPMOD64LSB:
3850 case R_IA64_DTPREL64LSB:
3851 size = 8; bigendian = 0;
3852 break;
3853
3854 /* Unsupported / Dynamic relocations. */
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;
3863 t0 = bfd_getl64 (hit_addr);
3864 t1 = bfd_getl64 (hit_addr + 8);
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
3886 bfd_putl64 (t0, hit_addr);
3887 bfd_putl64 (t1, hit_addr + 8);
3888 break;
3889
3890 case IA64_OPND_TGT64:
3891 hit_addr -= (long) hit_addr & 0x3;
3892 t0 = bfd_getl64 (hit_addr);
3893 t1 = bfd_getl64 (hit_addr + 8);
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
3911 bfd_putl64 (t0, hit_addr);
3912 bfd_putl64 (t1, hit_addr + 8);
3913 break;
3914
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;
3921 case 3: return bfd_reloc_notsupported; /* shouldn't happen... */
3922 }
3923 dword = bfd_getl64 (hit_addr);
3924 insn = (dword >> shift) & 0x1ffffffffffLL;
3925
3926 op = elf64_ia64_operands + opnd;
3927 err = (*op->insert) (op, val, &insn);
3928 if (err)
3929 return bfd_reloc_overflow;
3930
3931 dword &= ~(0x1ffffffffffLL << shift);
3932 dword |= (insn << shift);
3933 bfd_putl64 (dword, hit_addr);
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
3954 static void
3955 elfNN_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)
3959 {
3960 Elf_Internal_Rela outrel;
3961 bfd_byte *loc;
3962
3963 BFD_ASSERT (dynindx != -1);
3964 outrel.r_info = ELFNN_R_INFO (dynindx, type);
3965 outrel.r_addend = addend;
3966 outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
3967 if (outrel.r_offset >= (bfd_vma) -2)
3968 {
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;
3974 }
3975 else
3976 outrel.r_offset += sec->output_section->vma + sec->output_offset;
3977
3978 loc = srel->contents;
3979 loc += srel->reloc_count++ * sizeof (ElfNN_External_Rela);
3980 bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3981 BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count <= srel->size);
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
3987 static bfd_vma
3988 set_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)
3992 {
3993 struct elfNN_ia64_link_hash_table *ia64_info;
3994 asection *got_sec;
3995 bfd_boolean done;
3996 bfd_vma got_offset;
3997
3998 ia64_info = elfNN_ia64_hash_table (info);
3999 got_sec = ia64_info->root.sgot;
4000
4001 switch (dyn_r_type)
4002 {
4003 case R_IA64_TPREL64LSB:
4004 done = dyn_i->tprel_done;
4005 dyn_i->tprel_done = TRUE;
4006 got_offset = dyn_i->tprel_offset;
4007 break;
4008 case R_IA64_DTPMOD64LSB:
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 }
4020 got_offset = dyn_i->dtpmod_offset;
4021 break;
4022 case R_IA64_DTPREL32LSB:
4023 case R_IA64_DTPREL64LSB:
4024 done = dyn_i->dtprel_done;
4025 dyn_i->dtprel_done = TRUE;
4026 got_offset = dyn_i->dtprel_offset;
4027 break;
4028 default:
4029 done = dyn_i->got_done;
4030 dyn_i->got_done = TRUE;
4031 got_offset = dyn_i->got_offset;
4032 break;
4033 }
4034
4035 BFD_ASSERT ((got_offset & 7) == 0);
4036
4037 if (! done)
4038 {
4039 /* Store the target address in the linkage table entry. */
4040 bfd_put_64 (abfd, value, got_sec->contents + got_offset);
4041
4042 /* Install a dynamic relocation if needed. */
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)
4047 && dyn_r_type != R_IA64_DTPREL32LSB
4048 && dyn_r_type != R_IA64_DTPREL64LSB)
4049 || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info, dyn_r_type)
4050 || (dynindx != -1
4051 && (dyn_r_type == R_IA64_FPTR32LSB
4052 || dyn_r_type == R_IA64_FPTR64LSB)))
4053 && (!dyn_i->want_ltoff_fptr
4054 || !info->pie
4055 || !dyn_i->h
4056 || dyn_i->h->root.type != bfd_link_hash_undefweak))
4057 {
4058 if (dynindx == -1
4059 && dyn_r_type != R_IA64_TPREL64LSB
4060 && dyn_r_type != R_IA64_DTPMOD64LSB
4061 && dyn_r_type != R_IA64_DTPREL32LSB
4062 && dyn_r_type != R_IA64_DTPREL64LSB)
4063 {
4064 dyn_r_type = R_IA64_RELNNLSB;
4065 dynindx = 0;
4066 addend = value;
4067 }
4068
4069 if (bfd_big_endian (abfd))
4070 {
4071 switch (dyn_r_type)
4072 {
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;
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;
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;
4103 default:
4104 BFD_ASSERT (FALSE);
4105 break;
4106 }
4107 }
4108
4109 elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
4110 ia64_info->root.srelgot,
4111 got_offset, dyn_r_type,
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
4119 + got_offset);
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
4127 static bfd_vma
4128 set_fptr_entry (bfd *abfd, struct bfd_link_info *info,
4129 struct elfNN_ia64_dyn_sym_info *dyn_i,
4130 bfd_vma value)
4131 {
4132 struct elfNN_ia64_link_hash_table *ia64_info;
4133 asection *fptr_sec;
4134
4135 ia64_info = elfNN_ia64_hash_table (info);
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);
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 }
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
4177 static bfd_vma
4178 set_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)
4181 {
4182 struct elfNN_ia64_link_hash_table *ia64_info;
4183 asection *pltoff_sec;
4184
4185 ia64_info = elfNN_ia64_hash_table (info);
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 {
4193 bfd_vma gp = _bfd_get_gp_value (abfd);
4194
4195 /* Fill in the function descriptor. */
4196 bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
4197 bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
4198
4199 /* Install dynamic relocations if needed. */
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))
4205 {
4206 unsigned int dyn_r_type;
4207
4208 if (bfd_big_endian (abfd))
4209 dyn_r_type = R_IA64_RELNNMSB;
4210 else
4211 dyn_r_type = R_IA64_RELNNLSB;
4212
4213 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
4214 ia64_info->rel_pltoff_sec,
4215 dyn_i->pltoff_offset,
4216 dyn_r_type, 0, value);
4217 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
4218 ia64_info->rel_pltoff_sec,
4219 dyn_i->pltoff_offset + ARCH_SIZE / 8,
4220 dyn_r_type, 0, gp);
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
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)
4237 is assigned offset round(2 * size of pointer, PT_TLS p_align). */
4238
4239 static bfd_vma
4240 elfNN_ia64_tprel_base (struct bfd_link_info *info)
4241 {
4242 asection *tls_sec = elf_hash_table (info)->tls_sec;
4243 return tls_sec->vma - align_power ((bfd_vma) ARCH_SIZE / 4,
4244 tls_sec->alignment_power);
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
4251 static bfd_vma
4252 elfNN_ia64_dtprel_base (struct bfd_link_info *info)
4253 {
4254 return elf_hash_table (info)->tls_sec->vma;
4255 }
4256
4257 /* Called through qsort to sort the .IA_64.unwind section during a
4258 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
4259 to the output bfd so we can do proper endianness frobbing. */
4260
4261 static bfd *elfNN_ia64_unwind_entry_compare_bfd;
4262
4263 static int
4264 elfNN_ia64_unwind_entry_compare (const PTR a, const PTR b)
4265 {
4266 bfd_vma av, bv;
4267
4268 av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
4269 bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
4270
4271 return (av < bv ? -1 : av > bv ? 1 : 0);
4272 }
4273
4274 /* Make sure we've got ourselves a nice fat __gp value. */
4275 static bfd_boolean
4276 elfNN_ia64_choose_gp (bfd *abfd, struct bfd_link_info *info)
4277 {
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;
4283 struct elfNN_ia64_link_hash_table *ia64_info;
4284
4285 ia64_info = elfNN_ia64_hash_table (info);
4286
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)
4290 {
4291 bfd_vma lo, hi;
4292
4293 if ((os->flags & SEC_ALLOC) == 0)
4294 continue;
4295
4296 lo = os->vma;
4297 hi = os->vma + (os->rawsize ? os->rawsize : os->size);
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)
4306 {
4307 if (min_short_vma > lo)
4308 min_short_vma = lo;
4309 if (max_short_vma < hi)
4310 max_short_vma = hi;
4311 }
4312 }
4313
4314 if (ia64_info->min_short_sec)
4315 {
4316 if (min_short_vma
4317 > (ia64_info->min_short_sec->vma
4318 + ia64_info->min_short_offset))
4319 min_short_vma = (ia64_info->min_short_sec->vma
4320 + ia64_info->min_short_offset);
4321 if (max_short_vma
4322 < (ia64_info->max_short_sec->vma
4323 + ia64_info->max_short_offset))
4324 max_short_vma = (ia64_info->max_short_sec->vma
4325 + ia64_info->max_short_offset);
4326 }
4327
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);
4331
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. */
4344
4345 if (ia64_info->min_short_sec)
4346 {
4347 bfd_vma short_range = max_short_vma - min_short_vma;
4348
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 }
4355 else
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 }
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
4373 && (max_vma - gp_val >= 0x200000
4374 || gp_val - min_vma > 0x200000))
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;
4385 }
4386 }
4387
4388 /* Validate whether all SHF_IA_64_SHORT sections are within
4389 range of the chosen GP. */
4390
4391 if (max_short_vma != 0)
4392 {
4393 if (max_short_vma - min_short_vma >= 0x400000)
4394 {
4395 overflow:
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;
4401 }
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))
4406 {
4407 (*_bfd_error_handler)
4408 (_("%s: __gp does not cover short data segment"),
4409 bfd_get_filename (abfd));
4410 return FALSE;
4411 }
4412 }
4413
4414 _bfd_set_gp_value (abfd, gp_val);
4415
4416 return TRUE;
4417 }
4418
4419 static bfd_boolean
4420 elfNN_ia64_final_link (bfd *abfd, struct bfd_link_info *info)
4421 {
4422 struct elfNN_ia64_link_hash_table *ia64_info;
4423 asection *unwind_output_sec;
4424
4425 ia64_info = elfNN_ia64_hash_table (info);
4426
4427 /* Make sure we've got ourselves a nice fat __gp value. */
4428 if (!info->relocatable)
4429 {
4430 bfd_vma gp_val;
4431 struct elf_link_hash_entry *gp;
4432
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);
4439
4440 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
4441 FALSE, FALSE);
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 }
4448 }
4449
4450 /* If we're producing a final executable, we need to sort the contents
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;
4454 if (!info->relocatable)
4455 {
4456 asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
4457 if (s)
4458 {
4459 unwind_output_sec = s->output_section;
4460 unwind_output_sec->contents
4461 = bfd_malloc (unwind_output_sec->size);
4462 if (unwind_output_sec->contents == NULL)
4463 return FALSE;
4464 }
4465 }
4466
4467 /* Invoke the regular ELF backend linker to do all the work. */
4468 if (!bfd_elf_final_link (abfd, info))
4469 return FALSE;
4470
4471 if (unwind_output_sec)
4472 {
4473 elfNN_ia64_unwind_entry_compare_bfd = abfd;
4474 qsort (unwind_output_sec->contents,
4475 (size_t) (unwind_output_sec->size / 24),
4476 24,
4477 elfNN_ia64_unwind_entry_compare);
4478
4479 if (! bfd_set_section_contents (abfd, unwind_output_sec,
4480 unwind_output_sec->contents, (bfd_vma) 0,
4481 unwind_output_sec->size))
4482 return FALSE;
4483 }
4484
4485 return TRUE;
4486 }
4487
4488 static bfd_boolean
4489 elfNN_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)
4497 {
4498 struct elfNN_ia64_link_hash_table *ia64_info;
4499 Elf_Internal_Shdr *symtab_hdr;
4500 Elf_Internal_Rela *rel;
4501 Elf_Internal_Rela *relend;
4502 asection *srel;
4503 bfd_boolean ret_val = TRUE; /* for non-fatal errors */
4504 bfd_vma gp_val;
4505
4506 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
4507 ia64_info = elfNN_ia64_hash_table (info);
4508
4509 /* Infect various flags from the input section to the output section. */
4510 if (info->relocatable)
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);
4522 srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
4523
4524 rel = relocs;
4525 relend = relocs + input_section->reloc_count;
4526 for (; rel < relend; ++rel)
4527 {
4528 struct elf_link_hash_entry *h;
4529 struct elfNN_ia64_dyn_sym_info *dyn_i;
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;
4538 bfd_boolean dynamic_symbol_p;
4539 bfd_boolean undef_weak_ref;
4540
4541 r_type = ELFNN_R_TYPE (rel->r_info);
4542 if (r_type > R_IA64_MAX_RELOC_CODE)
4543 {
4544 (*_bfd_error_handler)
4545 (_("%B: unknown relocation type %d"),
4546 input_bfd, (int) r_type);
4547 bfd_set_error (bfd_error_bad_value);
4548 ret_val = FALSE;
4549 continue;
4550 }
4551
4552 howto = lookup_howto (r_type);
4553 r_symndx = ELFNN_R_SYM (rel->r_info);
4554 h = NULL;
4555 sym = NULL;
4556 sym_sec = NULL;
4557 undef_weak_ref = FALSE;
4558
4559 if (r_symndx < symtab_hdr->sh_info)
4560 {
4561 /* Reloc against local symbol. */
4562 asection *msec;
4563 sym = local_syms + r_symndx;
4564 sym_sec = local_sections[r_symndx];
4565 msec = sym_sec;
4566 value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
4567 if (!info->relocatable
4568 && (sym_sec->flags & SEC_MERGE) != 0
4569 && ELF_ST_TYPE (sym->st_info) == STT_SECTION
4570 && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
4571 {
4572 struct elfNN_ia64_local_hash_entry *loc_h;
4573
4574 loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
4575 if (loc_h && ! loc_h->sec_merge_done)
4576 {
4577 struct elfNN_ia64_dyn_sym_info *dynent;
4578 unsigned int count;
4579
4580 for (count = loc_h->count, dynent = loc_h->info;
4581 count != 0;
4582 count--, dynent++)
4583 {
4584 msec = sym_sec;
4585 dynent->addend =
4586 _bfd_merged_section_offset (output_bfd, &msec,
4587 elf_section_data (msec)->
4588 sec_info,
4589 sym->st_value
4590 + dynent->addend);
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 }
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 }
4606
4607 loc_h->sec_merge_done = 1;
4608 }
4609 }
4610 }
4611 else
4612 {
4613 bfd_boolean unresolved_reloc;
4614 bfd_boolean warned;
4615 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
4616
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);
4621
4622 if (h->root.type == bfd_link_hash_undefweak)
4623 undef_weak_ref = TRUE;
4624 else if (warned)
4625 continue;
4626 }
4627
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
4642 hit_addr = contents + rel->r_offset;
4643 value += rel->r_addend;
4644 dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type);
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. */
4660 if ((dynamic_symbol_p || info->shared)
4661 && r_symndx != 0
4662 && (input_section->flags & SEC_ALLOC) != 0)
4663 {
4664 unsigned int dyn_r_type;
4665 long dynindx;
4666 bfd_vma addend;
4667
4668 BFD_ASSERT (srel != NULL);
4669
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)
4678 (_("%B: non-pic code with imm relocation against dynamic symbol `%s'"),
4679 input_bfd,
4680 h ? h->root.root.string
4681 : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4682 sym_sec));
4683 ret_val = FALSE;
4684 continue;
4685
4686 default:
4687 break;
4688 }
4689
4690 /* If we don't need dynamic symbol lookup, find a
4691 matching RELATIVE relocation. */
4692 dyn_r_type = r_type;
4693 if (dynamic_symbol_p)
4694 {
4695 dynindx = h->dynindx;
4696 addend = rel->r_addend;
4697 value = 0;
4698 }
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:
4717 break;
4718 }
4719 dynindx = 0;
4720 addend = value;
4721 }
4722
4723 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4724 srel, rel->r_offset, dyn_r_type,
4725 dynindx, addend);
4726 }
4727 /* Fall through. */
4728
4729 case R_IA64_LTV32MSB:
4730 case R_IA64_LTV32LSB:
4731 case R_IA64_LTV64MSB:
4732 case R_IA64_LTV64LSB:
4733 r = elfNN_ia64_install_value (hit_addr, value, r_type);
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)
4745 (_("%B: @gprel relocation against dynamic symbol %s"),
4746 input_bfd,
4747 h ? h->root.root.string
4748 : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4749 sym_sec));
4750 ret_val = FALSE;
4751 continue;
4752 }
4753 value -= gp_val;
4754 r = elfNN_ia64_install_value (hit_addr, value, r_type);
4755 break;
4756
4757 case R_IA64_LTOFF22:
4758 case R_IA64_LTOFF22X:
4759 case R_IA64_LTOFF64I:
4760 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4761 value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
4762 rel->r_addend, value, R_IA64_DIRNNLSB);
4763 value -= gp_val;
4764 r = elfNN_ia64_install_value (hit_addr, value, r_type);
4765 break;
4766
4767 case R_IA64_PLTOFF22:
4768 case R_IA64_PLTOFF64I:
4769 case R_IA64_PLTOFF64MSB:
4770 case R_IA64_PLTOFF64LSB:
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);
4773 value -= gp_val;
4774 r = elfNN_ia64_install_value (hit_addr, value, r_type);
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:
4782 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4783 if (dyn_i->want_fptr)
4784 {
4785 if (!undef_weak_ref)
4786 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4787 }
4788 if (!dyn_i->want_fptr || info->pie)
4789 {
4790 long dynindx;
4791 unsigned int dyn_r_type = r_type;
4792 bfd_vma addend = rel->r_addend;
4793
4794 /* Otherwise, we expect the dynamic linker to create
4795 the entry. */
4796
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)
4808 (_("%B: linking non-pic code in a position independent executable"),
4809 input_bfd);
4810 ret_val = FALSE;
4811 continue;
4812 }
4813 dynindx = 0;
4814 addend = value;
4815 dyn_r_type = r_type + R_IA64_RELNNLSB - R_IA64_FPTRNNLSB;
4816 }
4817 else if (h)
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)));
4825 value = 0;
4826 }
4827 else
4828 {
4829 dynindx = (_bfd_elf_link_lookup_local_dynindx
4830 (info, input_bfd, (long) r_symndx));
4831 value = 0;
4832 }
4833
4834 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4835 srel, rel->r_offset, dyn_r_type,
4836 dynindx, addend);
4837 }
4838
4839 r = elfNN_ia64_install_value (hit_addr, value, r_type);
4840 break;
4841
4842 case R_IA64_LTOFF_FPTR22:
4843 case R_IA64_LTOFF_FPTR64I:
4844 case R_IA64_LTOFF_FPTR32MSB:
4845 case R_IA64_LTOFF_FPTR32LSB:
4846 case R_IA64_LTOFF_FPTR64MSB:
4847 case R_IA64_LTOFF_FPTR64LSB:
4848 {
4849 long dynindx;
4850
4851 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4852 if (dyn_i->want_fptr)
4853 {
4854 BFD_ASSERT (h == NULL || h->dynindx == -1);
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
4874 (info, input_bfd, (long) r_symndx));
4875 value = 0;
4876 }
4877
4878 value = set_got_entry (output_bfd, info, dyn_i, dynindx,
4879 rel->r_addend, value, R_IA64_FPTRNNLSB);
4880 value -= gp_val;
4881 r = elfNN_ia64_install_value (hit_addr, value, r_type);
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. */
4890 if (dynamic_symbol_p && r_symndx != 0)
4891 {
4892 BFD_ASSERT (srel != NULL);
4893
4894 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4895 srel, rel->r_offset, r_type,
4896 h->dynindx, rel->r_addend);
4897 }
4898 goto finish_pcrel;
4899
4900 case R_IA64_PCREL21B:
4901 case R_IA64_PCREL60B:
4902 /* We should have created a PLT entry for any dynamic symbol. */
4903 dyn_i = NULL;
4904 if (h)
4905 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4906
4907 if (dyn_i && dyn_i->want_plt2)
4908 {
4909 /* Should have caught this earlier. */
4910 BFD_ASSERT (rel->r_addend == 0);
4911
4912 value = (ia64_info->root.splt->output_section->vma
4913 + ia64_info->root.splt->output_offset
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
4931 case R_IA64_PCREL21BI:
4932 case R_IA64_PCREL21F:
4933 case R_IA64_PCREL21M:
4934 case R_IA64_PCREL22:
4935 case R_IA64_PCREL64I:
4936 /* The PCREL21BI reloc is specifically not intended for use with
4937 dynamic relocs. PCREL21F and PCREL21M are used for speculation
4938 fixup code, and thus probably ought not be dynamic. The
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)
4945 msg = _("%B: @internal branch to dynamic symbol %s");
4946 else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
4947 msg = _("%B: speculation fixup to dynamic symbol %s");
4948 else
4949 msg = _("%B: @pcrel relocation against dynamic symbol %s");
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));
4956 ret_val = FALSE;
4957 continue;
4958 }
4959 goto finish_pcrel;
4960
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;
4966 r = elfNN_ia64_install_value (hit_addr, value, r_type);
4967 break;
4968
4969 case R_IA64_SEGREL32MSB:
4970 case R_IA64_SEGREL32LSB:
4971 case R_IA64_SEGREL64MSB:
4972 case R_IA64_SEGREL64LSB:
4973 {
4974 /* Find the segment that contains the output_section. */
4975 Elf_Internal_Phdr *p = _bfd_elf_find_segment_containing_section
4976 (output_bfd, input_section->output_section);
4977
4978 if (p == NULL)
4979 {
4980 r = bfd_reloc_notsupported;
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;
4990 r = elfNN_ia64_install_value (hit_addr, value, r_type);
4991 }
4992 break;
4993 }
4994
4995 case R_IA64_SECREL32MSB:
4996 case R_IA64_SECREL32LSB:
4997 case R_IA64_SECREL64MSB:
4998 case R_IA64_SECREL64LSB:
4999 /* Make output-section relative to section where the symbol
5000 is defined. PR 475 */
5001 if (sym_sec)
5002 value -= sym_sec->output_section->vma;
5003 r = elfNN_ia64_install_value (hit_addr, value, r_type);
5004 break;
5005
5006 case R_IA64_IPLTMSB:
5007 case R_IA64_IPLTLSB:
5008 /* Install a dynamic relocation for this reloc. */
5009 if ((dynamic_symbol_p || info->shared)
5010 && (input_section->flags & SEC_ALLOC) != 0)
5011 {
5012 BFD_ASSERT (srel != NULL);
5013
5014 /* If we don't need dynamic symbol lookup, install two
5015 RELATIVE relocations. */
5016 if (!dynamic_symbol_p)
5017 {
5018 unsigned int dyn_r_type;
5019
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;
5044 elfNN_ia64_install_value (hit_addr, value, r_type);
5045 r = elfNN_ia64_install_value (hit_addr + 8, gp_val, r_type);
5046 break;
5047
5048 case R_IA64_TPREL14:
5049 case R_IA64_TPREL22:
5050 case R_IA64_TPREL64I:
5051 if (elf_hash_table (info)->tls_sec == NULL)
5052 goto missing_tls_sec;
5053 value -= elfNN_ia64_tprel_base (info);
5054 r = elfNN_ia64_install_value (hit_addr, value, r_type);
5055 break;
5056
5057 case R_IA64_DTPREL14:
5058 case R_IA64_DTPREL22:
5059 case R_IA64_DTPREL64I:
5060 case R_IA64_DTPREL32LSB:
5061 case R_IA64_DTPREL32MSB:
5062 case R_IA64_DTPREL64LSB:
5063 case R_IA64_DTPREL64MSB:
5064 if (elf_hash_table (info)->tls_sec == NULL)
5065 goto missing_tls_sec;
5066 value -= elfNN_ia64_dtprel_base (info);
5067 r = elfNN_ia64_install_value (hit_addr, value, r_type);
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;
5075 long dynindx = h ? h->dynindx : -1;
5076 bfd_vma r_addend = rel->r_addend;
5077
5078 switch (r_type)
5079 {
5080 default:
5081 case R_IA64_LTOFF_TPREL22:
5082 if (!dynamic_symbol_p)
5083 {
5084 if (elf_hash_table (info)->tls_sec == NULL)
5085 goto missing_tls_sec;
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 }
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)
5103 {
5104 if (elf_hash_table (info)->tls_sec == NULL)
5105 goto missing_tls_sec;
5106 value -= elfNN_ia64_dtprel_base (info);
5107 }
5108 got_r_type = R_IA64_DTPRELNNLSB;
5109 break;
5110 }
5111 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
5112 value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
5113 value, got_r_type);
5114 value -= gp_val;
5115 r = elfNN_ia64_install_value (hit_addr, value, r_type);
5116 }
5117 break;
5118
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);
5135 return FALSE;
5136
5137 case bfd_reloc_notsupported:
5138 {
5139 const char *name;
5140
5141 if (h)
5142 name = h->root.root.string;
5143 else
5144 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
5145 sym_sec);
5146 if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
5147 name, input_bfd,
5148 input_section, rel->r_offset))
5149 return FALSE;
5150 ret_val = FALSE;
5151 }
5152 break;
5153
5154 case bfd_reloc_dangerous:
5155 case bfd_reloc_outofrange:
5156 case bfd_reloc_overflow:
5157 default:
5158 missing_tls_sec:
5159 {
5160 const char *name;
5161
5162 if (h)
5163 name = h->root.root.string;
5164 else
5165 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
5166 sym_sec);
5167
5168 switch (r_type)
5169 {
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
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
5217 ret_val = FALSE;
5218 }
5219 break;
5220 }
5221 }
5222
5223 return ret_val;
5224 }
5225
5226 static bfd_boolean
5227 elfNN_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)
5231 {
5232 struct elfNN_ia64_link_hash_table *ia64_info;
5233 struct elfNN_ia64_dyn_sym_info *dyn_i;
5234
5235 ia64_info = elfNN_ia64_hash_table (info);
5236 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
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;
5244 bfd_vma plt_addr, pltoff_addr, gp_val, plt_index;
5245
5246 gp_val = _bfd_get_gp_value (output_bfd);
5247
5248 /* Initialize the minimal PLT entry. */
5249
5250 plt_index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
5251 plt_sec = ia64_info->root.splt;
5252 loc = plt_sec->contents + dyn_i->plt_offset;
5253
5254 memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
5255 elfNN_ia64_install_value (loc, plt_index, R_IA64_IMM22);
5256 elfNN_ia64_install_value (loc+2, -dyn_i->plt_offset, R_IA64_PCREL21B);
5257
5258 plt_addr = (plt_sec->output_section->vma
5259 + plt_sec->output_offset
5260 + dyn_i->plt_offset);
5261 pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
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);
5269 elfNN_ia64_install_value (loc, pltoff_addr - gp_val, R_IA64_IMM22);
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
5274 first place. But perhaps elflink.c did some for us. */
5275 if (!h->def_regular)
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))
5282 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
5283 else
5284 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
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
5299 loc = ia64_info->rel_pltoff_sec->contents;
5300 loc += ((ia64_info->rel_pltoff_sec->reloc_count + plt_index)
5301 * sizeof (ElfNN_External_Rela));
5302 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
5303 }
5304
5305 /* Mark some specially defined symbols as absolute. */
5306 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
5307 || h == ia64_info->root.hgot
5308 || h == ia64_info->root.hplt)
5309 sym->st_shndx = SHN_ABS;
5310
5311 return TRUE;
5312 }
5313
5314 static bfd_boolean
5315 elfNN_ia64_finish_dynamic_sections (bfd *abfd,
5316 struct bfd_link_info *info)
5317 {
5318 struct elfNN_ia64_link_hash_table *ia64_info;
5319 bfd *dynobj;
5320
5321 ia64_info = elfNN_ia64_hash_table (info);
5322 dynobj = ia64_info->root.dynobj;
5323
5324 if (elf_hash_table (info)->dynamic_sections_created)
5325 {
5326 ElfNN_External_Dyn *dyncon, *dynconend;
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);
5333 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
5334 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->size);
5335
5336 gp_val = _bfd_get_gp_value (abfd);
5337
5338 for (; dyncon < dynconend; dyncon++)
5339 {
5340 Elf_Internal_Dyn dyn;
5341
5342 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
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
5352 * sizeof (ElfNN_External_Rela));
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
5360 * sizeof (ElfNN_External_Rela)));
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
5370 easier on ld.so. This is not what the rest of BFD set up. */
5371 dyn.d_un.d_val -= (ia64_info->minplt_entries
5372 * sizeof (ElfNN_External_Rela));
5373 break;
5374 }
5375
5376 bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
5377 }
5378
5379 /* Initialize the PLT0 entry. */
5380 if (ia64_info->root.splt)
5381 {
5382 bfd_byte *loc = ia64_info->root.splt->contents;
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
5391 elfNN_ia64_install_value (loc+1, pltres, R_IA64_GPREL22);
5392 }
5393 }
5394
5395 return TRUE;
5396 }
5397 \f
5398 /* ELF file flag handling: */
5399
5400 /* Function to keep IA-64 specific file flags. */
5401 static bfd_boolean
5402 elfNN_ia64_set_private_flags (bfd *abfd, flagword flags)
5403 {
5404 BFD_ASSERT (!elf_flags_init (abfd)
5405 || elf_elfheader (abfd)->e_flags == flags);
5406
5407 elf_elfheader (abfd)->e_flags = flags;
5408 elf_flags_init (abfd) = TRUE;
5409 return TRUE;
5410 }
5411
5412 /* Merge backend specific data from an object file to the output
5413 object file when linking. */
5414 static bfd_boolean
5415 elfNN_ia64_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
5416 {
5417 flagword out_flags;
5418 flagword in_flags;
5419 bfd_boolean ok = TRUE;
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)
5424 return FALSE;
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 {
5431 elf_flags_init (obfd) = TRUE;
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
5441 return TRUE;
5442 }
5443
5444 /* Check flag compatibility. */
5445 if (in_flags == out_flags)
5446 return TRUE;
5447
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
5452 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
5453 {
5454 (*_bfd_error_handler)
5455 (_("%B: linking trap-on-NULL-dereference with non-trapping files"),
5456 ibfd);
5457
5458 bfd_set_error (bfd_error_bad_value);
5459 ok = FALSE;
5460 }
5461 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
5462 {
5463 (*_bfd_error_handler)
5464 (_("%B: linking big-endian files with little-endian files"),
5465 ibfd);
5466
5467 bfd_set_error (bfd_error_bad_value);
5468 ok = FALSE;
5469 }
5470 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
5471 {
5472 (*_bfd_error_handler)
5473 (_("%B: linking 64-bit files with 32-bit files"),
5474 ibfd);
5475
5476 bfd_set_error (bfd_error_bad_value);
5477 ok = FALSE;
5478 }
5479 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
5480 {
5481 (*_bfd_error_handler)
5482 (_("%B: linking constant-gp files with non-constant-gp files"),
5483 ibfd);
5484
5485 bfd_set_error (bfd_error_bad_value);
5486 ok = FALSE;
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)
5492 (_("%B: linking auto-pic files with non-auto-pic files"),
5493 ibfd);
5494
5495 bfd_set_error (bfd_error_bad_value);
5496 ok = FALSE;
5497 }
5498
5499 return ok;
5500 }
5501
5502 static bfd_boolean
5503 elfNN_ia64_print_private_bfd_data (bfd *abfd, PTR ptr)
5504 {
5505 FILE *file = (FILE *) ptr;
5506 flagword flags = elf_elfheader (abfd)->e_flags;
5507
5508 BFD_ASSERT (abfd != NULL && ptr != NULL);
5509
5510 fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
5511 (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
5512 (flags & EF_IA_64_EXT) ? "EXT, " : "",
5513 (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
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, " : "",
5518 (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
5519
5520 _bfd_elf_print_private_bfd_data (abfd, ptr);
5521 return TRUE;
5522 }
5523
5524 static enum elf_reloc_type_class
5525 elfNN_ia64_reloc_type_class (const Elf_Internal_Rela *rela)
5526 {
5527 switch ((int) ELFNN_R_TYPE (rela->r_info))
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 }
5543
5544 static const struct bfd_elf_special_section elfNN_ia64_special_sections[] =
5545 {
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 }
5549 };
5550
5551 static bfd_boolean
5552 elfNN_ia64_object_p (bfd *abfd)
5553 {
5554 asection *sec;
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))
5575 && CONST_STRNEQ (sec->name, ".gnu.linkonce.t."))
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
5595 /* We need to create a fake group section for it and its
5596 unwind sections. */
5597 group = bfd_make_section_anyway_with_flags (abfd, name,
5598 flags);
5599 if (group == NULL)
5600 return FALSE;
5601
5602 /* Move the fake group section to the beginning. */
5603 bfd_section_list_remove (abfd, group);
5604 bfd_section_list_prepend (abfd, group);
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
5644 static bfd_boolean
5645 elfNN_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
5651 static void
5652 elfNN_hpux_post_process_headers (bfd *abfd,
5653 struct bfd_link_info *info ATTRIBUTE_UNUSED)
5654 {
5655 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
5656
5657 i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
5658 i_ehdrp->e_ident[EI_ABIVERSION] = 1;
5659 }
5660
5661 static bfd_boolean
5662 elfNN_hpux_backend_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
5663 asection *sec, int *retval)
5664 {
5665 if (bfd_is_com_section (sec))
5666 {
5667 *retval = SHN_IA_64_ANSI_COMMON;
5668 return TRUE;
5669 }
5670 return FALSE;
5671 }
5672
5673 static void
5674 elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
5675 asymbol *asym)
5676 {
5677 elf_symbol_type *elfsym = (elf_symbol_type *) asym;
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
5689 static bfd_boolean
5690 elfNN_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
5715 static bfd_boolean
5716 elfNN_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
5806 static void
5807 elfNN_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
5816 static bfd_boolean
5817 elfNN_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
5889 static void
5890 elfNN_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
5928 static bfd_boolean
5929 elfNN_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 }
5950 \f
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"
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 */
5960 #define ELF_COMMONPAGESIZE 0x4000 /* 16KB */
5961
5962 #define elf_backend_section_from_shdr \
5963 elfNN_ia64_section_from_shdr
5964 #define elf_backend_section_flags \
5965 elfNN_ia64_section_flags
5966 #define elf_backend_fake_sections \
5967 elfNN_ia64_fake_sections
5968 #define elf_backend_final_write_processing \
5969 elfNN_ia64_final_write_processing
5970 #define elf_backend_add_symbol_hook \
5971 elfNN_ia64_add_symbol_hook
5972 #define elf_backend_additional_program_headers \
5973 elfNN_ia64_additional_program_headers
5974 #define elf_backend_modify_segment_map \
5975 elfNN_ia64_modify_segment_map
5976 #define elf_backend_modify_program_headers \
5977 elfNN_ia64_modify_program_headers
5978 #define elf_info_to_howto \
5979 elfNN_ia64_info_to_howto
5980
5981 #define bfd_elfNN_bfd_reloc_type_lookup \
5982 elfNN_ia64_reloc_type_lookup
5983 #define bfd_elfNN_bfd_reloc_name_lookup \
5984 elfNN_ia64_reloc_name_lookup
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
5989
5990 #define elf_backend_object_p \
5991 elfNN_ia64_object_p
5992
5993 /* Stuff for the BFD linker: */
5994 #define bfd_elfNN_bfd_link_hash_table_create \
5995 elfNN_ia64_hash_table_create
5996 #define bfd_elfNN_bfd_link_hash_table_free \
5997 elfNN_ia64_hash_table_free
5998 #define elf_backend_create_dynamic_sections \
5999 elfNN_ia64_create_dynamic_sections
6000 #define elf_backend_check_relocs \
6001 elfNN_ia64_check_relocs
6002 #define elf_backend_adjust_dynamic_symbol \
6003 elfNN_ia64_adjust_dynamic_symbol
6004 #define elf_backend_size_dynamic_sections \
6005 elfNN_ia64_size_dynamic_sections
6006 #define elf_backend_omit_section_dynsym \
6007 ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
6008 #define elf_backend_relocate_section \
6009 elfNN_ia64_relocate_section
6010 #define elf_backend_finish_dynamic_symbol \
6011 elfNN_ia64_finish_dynamic_symbol
6012 #define elf_backend_finish_dynamic_sections \
6013 elfNN_ia64_finish_dynamic_sections
6014 #define bfd_elfNN_bfd_final_link \
6015 elfNN_ia64_final_link
6016
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
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
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
6033 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
6034 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
6035 #define elf_backend_fixup_symbol _bfd_elf_link_hash_fixup_symbol
6036 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
6037 #define elf_backend_rela_normal 1
6038 #define elf_backend_special_sections elfNN_ia64_special_sections
6039 #define elf_backend_default_execstack 0
6040
6041 /* FIXME: PR 290: The Intel C compiler generates SHT_IA_64_UNWIND with
6042 SHF_LINK_ORDER. But it doesn't set the sh_link or sh_info fields.
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
6048 #include "elfNN-target.h"
6049
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
6059 /* These are HP-UX specific functions. */
6060
6061 #undef elf_backend_post_process_headers
6062 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
6063
6064 #undef elf_backend_section_from_bfd_section
6065 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
6066
6067 #undef elf_backend_symbol_processing
6068 #define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
6069
6070 #undef elf_backend_want_p_paddr_set_to_zero
6071 #define elf_backend_want_p_paddr_set_to_zero 1
6072
6073 #undef ELF_COMMONPAGESIZE
6074 #undef ELF_OSABI
6075 #define ELF_OSABI ELFOSABI_HPUX
6076
6077 #undef elfNN_bed
6078 #define elfNN_bed elfNN_ia64_hpux_bed
6079
6080 #include "elfNN-target.h"
6081
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
6115 #undef elf_backend_want_p_paddr_set_to_zero
6116
6117 #undef ELF_OSABI
6118 #define ELF_OSABI ELFOSABI_OPENVMS
6119
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.162421 seconds and 4 git commands to generate.