PR 11225
[binutils.git] / bfd / elfxx-ia64.c
blobf7563329d23fa9fcae91f5a2e6d917af1d51cd9e
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>
6 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
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"
32 #define ARCH_SIZE NN
34 #if ARCH_SIZE == 64
35 #define LOG_SECTION_ALIGN 3
36 #endif
38 #if ARCH_SIZE == 32
39 #define LOG_SECTION_ALIGN 2
40 #endif
42 /* THE RULES for all the stuff the linker creates --
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.
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.
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.
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.
67 MIN_PLT Created by PLTOFF entries against dynamic symbols. This
68 does not require dynamic relocations. */
70 #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
72 typedef struct bfd_hash_entry *(*new_hash_entry_func)
73 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
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. */
79 struct elfNN_ia64_dyn_sym_info
81 /* The addend for which this entry is relevant. */
82 bfd_vma addend;
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;
93 /* The symbol table entry, if any, that this was derived from. */
94 struct elf_link_hash_entry *h;
96 /* Used to count non-got, non-plt relocations for delayed sizing
97 of relocation sections. */
98 struct elfNN_ia64_dyn_reloc_entry
100 struct elfNN_ia64_dyn_reloc_entry *next;
101 asection *srel;
102 int type;
103 int count;
105 /* Is this reloc against readonly section? */
106 bfd_boolean reltext;
107 } *reloc_entries;
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;
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;
130 struct elfNN_ia64_local_hash_entry
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;
143 /* TRUE if this hash entry's addends was translated for
144 SHF_MERGE optimization. */
145 unsigned sec_merge_done : 1;
148 struct elfNN_ia64_link_hash_entry
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;
161 struct elfNN_ia64_link_hash_table
163 /* The main hash table. */
164 struct elf_link_hash_table root;
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 */
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 */
184 htab_t loc_hash_table;
185 void *loc_hash_memory;
188 struct elfNN_ia64_allocate_data
190 struct bfd_link_info *info;
191 bfd_size_type ofs;
192 bfd_boolean only_got;
195 #define elfNN_ia64_hash_table(p) \
196 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
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);
228 /* ia64-specific relocation. */
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)
238 if (output_bfd)
240 reloc->address += input_section->output_offset;
241 return bfd_reloc_ok;
244 if (input_section->flags & SEC_DEBUGGING)
245 return bfd_reloc_continue;
247 *error_message = "Unsupported call to elfNN_ia64_reloc";
248 return bfd_reloc_notsupported;
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)
255 /* This table has to be sorted according to increasing number of the
256 TYPE field. */
257 static reloc_howto_type ia64_howto_table[] =
259 IA64_HOWTO (R_IA64_NONE, "NONE", 0, FALSE, TRUE),
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),
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),
276 IA64_HOWTO (R_IA64_LTOFF22, "LTOFF22", 0, FALSE, TRUE),
277 IA64_HOWTO (R_IA64_LTOFF64I, "LTOFF64I", 0, FALSE, TRUE),
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),
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),
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),
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),
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),
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),
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),
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),
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),
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),
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),
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),
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),
357 static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
359 /* Given a BFD reloc type, return the matching HOWTO structure. */
361 static reloc_howto_type *
362 lookup_howto (unsigned int rtype)
364 static int inited = 0;
365 int i;
367 if (!inited)
369 inited = 1;
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;
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;
384 static reloc_howto_type*
385 elfNN_ia64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
386 bfd_reloc_code_real_type bfd_code)
388 unsigned int rtype;
390 switch (bfd_code)
392 case BFD_RELOC_NONE: rtype = R_IA64_NONE; break;
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;
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;
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;
410 case BFD_RELOC_IA64_LTOFF22: rtype = R_IA64_LTOFF22; break;
411 case BFD_RELOC_IA64_LTOFF64I: rtype = R_IA64_LTOFF64I; break;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
488 default: return 0;
490 return lookup_howto (rtype);
493 static reloc_howto_type *
494 elfNN_ia64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
495 const char *r_name)
497 unsigned int i;
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];
506 return NULL;
509 /* Given a ELF reloc, return the matching HOWTO structure. */
511 static void
512 elfNN_ia64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
513 arelent *bfd_reloc,
514 Elf_Internal_Rela *elf_reloc)
516 bfd_reloc->howto
517 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc->r_info));
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
525 static const bfd_byte plt_header[PLT_HEADER_SIZE] =
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;; */
538 static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
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>;; */
545 static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
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;; */
555 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
557 static const bfd_byte oor_brl[16] =
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
564 static const bfd_byte oor_ip[48] =
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;; */
577 static size_t oor_branch_size = sizeof (oor_brl);
579 void
580 bfd_elfNN_ia64_after_parse (int itanium)
582 oor_branch_size = itanium ? sizeof (oor_ip) : sizeof (oor_brl);
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
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)
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))
620 static bfd_boolean
621 elfNN_ia64_relax_br (bfd_byte *contents, bfd_vma off)
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;
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);
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)
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 ();
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;
687 /* Turn br into brl by setting bit 40. */
688 br_code |= 0x1LL << 40;
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;
697 if (template_val == 0x16)
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);
707 else
709 /* Keep the original instruction in slot 0. */
710 t0 &= 0x1ffffffffffLL << 5;
713 t0 |= mlx;
715 /* Put brl in slot 1. */
716 t1 = br_code << 23;
718 bfd_putl64 (t0, hit_addr);
719 bfd_putl64 (t1, hit_addr + 8);
720 return TRUE;
723 static void
724 elfNN_ia64_relax_brl (bfd_byte *contents, bfd_vma off)
726 int template_val;
727 bfd_byte *hit_addr;
728 bfd_vma t0, t1, i0, i1, i2;
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);
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;
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);
751 bfd_putl64 (t0, hit_addr);
752 bfd_putl64 (t1, hit_addr + 8);
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
761 /* These functions do relaxation for IA-64 ELF. */
763 static void
764 elfNN_ia64_update_short_info (asection *sec, bfd_vma offset,
765 struct elfNN_ia64_link_hash_table *ia64_info)
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;
772 if (!ia64_info->min_short_sec)
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;
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)
788 ia64_info->max_short_sec = sec;
789 ia64_info->max_short_offset = offset;
791 else if (sec->output_section->vma
792 < ia64_info->min_short_sec->vma)
794 ia64_info->min_short_sec = sec;
795 ia64_info->min_short_offset = offset;
799 static bfd_boolean
800 elfNN_ia64_relax_section (bfd *abfd, asection *sec,
801 struct bfd_link_info *link_info,
802 bfd_boolean *again)
804 struct one_fixup
806 struct one_fixup *next;
807 asection *tsec;
808 bfd_vma toff;
809 bfd_vma trampoff;
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;
826 /* Assume we're not going to change any sizes, and we'll only need
827 one pass. */
828 *again = FALSE;
830 if (link_info->relocatable)
831 (*link_info->callbacks->einfo)
832 (_("%P%F: --relax and -r may not be used together\n"));
834 /* Don't even try to relax for non-ELF outputs. */
835 if (!is_elf_hash_table (link_info->hash))
836 return FALSE;
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;
846 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
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;
855 ia64_info = elfNN_ia64_hash_table (link_info);
856 irelend = internal_relocs + sec->reloc_count;
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
863 if (!bfd_malloc_and_get_section (abfd, sec, &contents))
864 goto error_return;
867 for (irel = internal_relocs; irel < irelend; irel++)
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;
878 switch (r_type)
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;
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)
896 skip_relax_pass_1 = FALSE;
897 continue;
899 is_branch = TRUE;
900 break;
902 case R_IA64_GPREL22:
903 /* Update max_short_sec/min_short_sec. */
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)
911 skip_relax_pass_1 = FALSE;
912 continue;
914 is_branch = FALSE;
915 break;
917 default:
918 continue;
921 /* Get the value of the symbol referred to by the reloc. */
922 if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
924 /* A local symbol. */
925 Elf_Internal_Sym *isym;
927 /* Read this BFD's local symbols. */
928 if (isymbuf == NULL)
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;
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);
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);
955 else
957 unsigned long indx;
958 struct elf_link_hash_entry *h;
960 indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
961 h = elf_sym_hashes (abfd)[indx];
962 BFD_ASSERT (h != NULL);
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;
968 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, FALSE);
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)
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;
979 tsec = ia64_info->root.splt;
980 toff = dyn_i->plt2_offset;
981 BFD_ASSERT (irel->r_addend == 0);
984 /* Can't do anything else with dynamic symbols. */
985 else if (elfNN_ia64_dynamic_symbol_p (h, link_info, r_type))
986 continue;
988 else
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;
995 tsec = h->root.u.def.section;
996 toff = h->root.u.def.value;
999 symtype = h->type;
1002 if (tsec->sec_info_type == ELF_INFO_TYPE_MERGE)
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.)
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;
1023 toff = _bfd_merged_section_offset (abfd, &tsec,
1024 elf_section_data (tsec)->sec_info,
1025 toff);
1027 if (symtype != STT_SECTION)
1028 toff += irel->r_addend;
1030 else
1031 toff += irel->r_addend;
1033 symaddr = tsec->output_section->vma + tsec->output_offset + toff;
1035 roff = irel->r_offset;
1037 if (is_branch)
1039 bfd_signed_vma offset;
1041 reladdr = (sec->output_section->vma
1042 + sec->output_offset
1043 + roff) & (bfd_vma) -4;
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;
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)
1061 /* If the 60-bit branch is in 21-bit range, optimize it. */
1062 if (r_type == R_IA64_PCREL60B)
1064 elfNN_ia64_relax_brl (contents, roff);
1066 irel->r_info
1067 = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1068 R_IA64_PCREL21B);
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;
1076 continue;
1078 else if (r_type == R_IA64_PCREL60B)
1079 continue;
1080 else if (elfNN_ia64_relax_br (contents, roff))
1082 irel->r_info
1083 = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1084 R_IA64_PCREL60B);
1086 /* Make the relocation offset point to slot 1. */
1087 irel->r_offset = (irel->r_offset & ~((bfd_vma) 0x3)) + 1;
1088 continue;
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)
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;
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;
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;
1115 if (f == NULL)
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. */
1121 size_t size;
1123 if (tsec == ia64_info->root.splt)
1124 size = sizeof (plt_full_entry);
1125 else
1126 size = oor_branch_size;
1128 /* Resize the current section to make room for the new branch. */
1129 trampoff = (sec->size + 15) & (bfd_vma) -16;
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;
1137 amt = trampoff + size;
1138 contents = (bfd_byte *) bfd_realloc (contents, amt);
1139 if (contents == NULL)
1140 goto error_return;
1141 sec->size = amt;
1143 if (tsec == ia64_info->root.splt)
1145 memcpy (contents + trampoff, plt_full_entry, size);
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;
1152 else
1154 if (size == sizeof (oor_ip))
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;
1162 else
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;
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;
1181 else
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;
1189 /* Nop out the reloc, since we're finalizing things here. */
1190 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
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;
1198 changed_contents = TRUE;
1199 changed_relocs = TRUE;
1201 else
1203 /* Fetch the gp. */
1204 if (gp == 0)
1206 bfd *obfd = sec->output_section->owner;
1207 gp = _bfd_get_gp_value (obfd);
1208 if (gp == 0)
1210 if (!elfNN_ia64_choose_gp (obfd, link_info))
1211 goto error_return;
1212 gp = _bfd_get_gp_value (obfd);
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;
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)
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)
1232 dyn_i->want_gotx = 0;
1233 changed_got |= !dyn_i->want_got;
1236 elfNN_ia64_update_short_info (tsec->output_section,
1237 tsec->output_offset + toff,
1238 ia64_info);
1240 else
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;
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. */
1255 /* Clean up and go home. */
1256 while (fixups)
1258 struct one_fixup *f = fixups;
1259 fixups = fixups->next;
1260 free (f);
1263 if (isymbuf != NULL
1264 && symtab_hdr->contents != (unsigned char *) isymbuf)
1266 if (! link_info->keep_memory)
1267 free (isymbuf);
1268 else
1270 /* Cache the symbols for elf_link_input_bfd. */
1271 symtab_hdr->contents = (unsigned char *) isymbuf;
1275 if (contents != NULL
1276 && elf_section_data (sec)->this_hdr.contents != contents)
1278 if (!changed_contents && !link_info->keep_memory)
1279 free (contents);
1280 else
1282 /* Cache the section contents for elf_link_input_bfd. */
1283 elf_section_data (sec)->this_hdr.contents = contents;
1287 if (elf_section_data (sec)->relocs != internal_relocs)
1289 if (!changed_relocs)
1290 free (internal_relocs);
1291 else
1292 elf_section_data (sec)->relocs = internal_relocs;
1295 if (changed_got)
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;
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;
1307 if (ia64_info->root.dynamic_sections_created
1308 && ia64_info->root.srelgot != NULL)
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);
1321 if (link_info->relax_pass == 0)
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;
1328 *again = changed_contents || changed_relocs;
1329 return TRUE;
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;
1342 #undef skip_relax_pass_0
1343 #undef skip_relax_pass_1
1345 static void
1346 elfNN_ia64_relax_ldxmov (bfd_byte *contents, bfd_vma off)
1348 int shift, r1, r3;
1349 bfd_vma dword, insn;
1351 switch ((int)off & 0x3)
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 ();
1360 dword = bfd_getl64 (contents + off);
1361 insn = (dword >> shift) & 0x1ffffffffffLL;
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 */
1370 dword &= ~(0x1ffffffffffLL << shift);
1371 dword |= (insn << shift);
1372 bfd_putl64 (dword, contents + off);
1375 /* Return TRUE if NAME is an unwind table section name. */
1377 static inline bfd_boolean
1378 is_unwind_section_name (bfd *abfd, const char *name)
1380 if (elfNN_ia64_hpux_vec (abfd->xvec)
1381 && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
1382 return FALSE;
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));
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. */
1393 static bfd_boolean
1394 elfNN_ia64_section_from_shdr (bfd *abfd,
1395 Elf_Internal_Shdr *hdr,
1396 const char *name,
1397 int shindex)
1399 asection *newsect;
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)
1408 case SHT_IA_64_UNWIND:
1409 case SHT_IA_64_HP_OPT_ANOT:
1410 break;
1412 case SHT_IA_64_EXT:
1413 if (strcmp (name, ELF_STRING_ia64_archext) != 0)
1414 return FALSE;
1415 break;
1417 default:
1418 return FALSE;
1421 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
1422 return FALSE;
1423 newsect = hdr->bfd_section;
1425 return TRUE;
1428 /* Convert IA-64 specific section flags to bfd internal section flags. */
1430 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1431 flag. */
1433 static bfd_boolean
1434 elfNN_ia64_section_flags (flagword *flags,
1435 const Elf_Internal_Shdr *hdr)
1437 if (hdr->sh_flags & SHF_IA_64_SHORT)
1438 *flags |= SEC_SMALL_DATA;
1440 return TRUE;
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. */
1446 static bfd_boolean
1447 elfNN_ia64_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr,
1448 asection *sec)
1450 const char *name;
1452 name = bfd_get_section_name (abfd, sec);
1454 if (is_unwind_section_name (abfd, name))
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;
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;
1484 if (sec->flags & SEC_SMALL_DATA)
1485 hdr->sh_flags |= SHF_IA_64_SHORT;
1487 /* Some HP linkers look for the SHF_IA_64_HP_TLS flag instead of SHF_TLS. */
1489 if (elfNN_ia64_hpux_vec (abfd->xvec) && (sec->flags & SHF_TLS))
1490 hdr->sh_flags |= SHF_IA_64_HP_TLS;
1492 return TRUE;
1495 /* The final processing done just before writing out an IA-64 ELF
1496 object file. */
1498 static void
1499 elfNN_ia64_final_write_processing (bfd *abfd,
1500 bfd_boolean linker ATTRIBUTE_UNUSED)
1502 Elf_Internal_Shdr *hdr;
1503 asection *s;
1505 for (s = abfd->sections; s; s = s->next)
1507 hdr = &elf_section_data (s)->this_hdr;
1508 switch (hdr->sh_type)
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;
1520 if (! elf_flags_init (abfd))
1522 unsigned long flags = 0;
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;
1529 elf_elfheader(abfd)->e_flags = flags;
1530 elf_flags_init (abfd) = TRUE;
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. */
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)
1546 if (sym->st_shndx == SHN_COMMON
1547 && !info->relocatable
1548 && sym->st_size <= elf_gp_size (abfd))
1550 /* Common symbols less than or equal to -G nn bytes are
1551 automatically put into .sbss. */
1553 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1555 if (scomm == NULL)
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;
1565 *secp = scomm;
1566 *valp = sym->st_size;
1569 return TRUE;
1572 /* Return the number of additional phdrs we will need. */
1574 static int
1575 elfNN_ia64_additional_program_headers (bfd *abfd,
1576 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1578 asection *s;
1579 int ret = 0;
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;
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;
1591 return ret;
1594 static bfd_boolean
1595 elfNN_ia64_modify_segment_map (bfd *abfd,
1596 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1598 struct elf_segment_map *m, **pm;
1599 Elf_Internal_Shdr *hdr;
1600 asection *s;
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))
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)
1612 m = ((struct elf_segment_map *)
1613 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1614 if (m == NULL)
1615 return FALSE;
1617 m->p_type = PT_IA_64_ARCHEXT;
1618 m->count = 1;
1619 m->sections[0] = s;
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;
1628 m->next = *pm;
1629 *pm = m;
1633 /* Install PT_IA_64_UNWIND segments, if needed. */
1634 for (s = abfd->sections; s; s = s->next)
1636 hdr = &elf_section_data (s)->this_hdr;
1637 if (hdr->sh_type != SHT_IA_64_UNWIND)
1638 continue;
1640 if (s && (s->flags & SEC_LOAD))
1642 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1643 if (m->p_type == PT_IA_64_UNWIND)
1645 int i;
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;
1654 if (i >= 0)
1655 break;
1658 if (m == NULL)
1660 m = ((struct elf_segment_map *)
1661 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1662 if (m == NULL)
1663 return FALSE;
1665 m->p_type = PT_IA_64_UNWIND;
1666 m->count = 1;
1667 m->sections[0] = s;
1668 m->next = NULL;
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;
1679 return TRUE;
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. */
1686 static bfd_boolean
1687 elfNN_ia64_modify_program_headers (bfd *abfd,
1688 struct bfd_link_info *info ATTRIBUTE_UNUSED)
1690 struct elf_obj_tdata *tdata = elf_tdata (abfd);
1691 struct elf_segment_map *m;
1692 Elf_Internal_Phdr *p;
1694 for (p = tdata->phdr, m = tdata->segment_map; m != NULL; m = m->next, p++)
1695 if (m->p_type == PT_LOAD)
1697 int i;
1698 for (i = m->count - 1; i >= 0; --i)
1700 struct bfd_link_order *order = m->sections[i]->map_head.link_order;
1702 while (order != NULL)
1704 if (order->type == bfd_indirect_link_order)
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)
1710 p->p_flags |= PF_IA_64_NORECOV;
1711 goto found;
1714 order = order->next;
1717 found:;
1720 return TRUE;
1723 /* According to the Tahoe assembler spec, all labels starting with a
1724 '.' are local. */
1726 static bfd_boolean
1727 elfNN_ia64_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
1728 const char *name)
1730 return name[0] == '.';
1733 /* Should we do dynamic things to this symbol? */
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)
1739 bfd_boolean ignore_protected
1740 = ((r_type & 0xf8) == 0x40 /* FPTR relocs */
1741 || (r_type & 0xf8) == 0x50); /* LTOFF_FPTR relocs */
1743 return _bfd_elf_dynamic_symbol_p (h, info, ignore_protected);
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)
1751 struct elfNN_ia64_link_hash_entry *ret;
1752 ret = (struct elfNN_ia64_link_hash_entry *) entry;
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));
1759 if (!ret)
1760 return 0;
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));
1767 ret->info = NULL;
1768 ret->count = 0;
1769 ret->sorted_count = 0;
1770 ret->size = 0;
1771 return (struct bfd_hash_entry *) ret;
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)
1779 struct elfNN_ia64_link_hash_entry *dir, *ind;
1781 dir = (struct elfNN_ia64_link_hash_entry *) xdir;
1782 ind = (struct elfNN_ia64_link_hash_entry *) xind;
1784 /* Copy down any references that we may have already seen to the
1785 symbol which just became indirect. */
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;
1792 if (ind->root.root.type != bfd_link_hash_indirect)
1793 return;
1795 /* Copy over the got and plt data. This would have been done
1796 by check_relocs. */
1798 if (ind->info != NULL)
1800 struct elfNN_ia64_dyn_sym_info *dyn_i;
1801 unsigned int count;
1803 if (dir->info)
1804 free (dir->info);
1806 dir->info = ind->info;
1807 dir->count = ind->count;
1808 dir->sorted_count = ind->sorted_count;
1809 dir->size = ind->size;
1811 ind->info = NULL;
1812 ind->count = 0;
1813 ind->sorted_count = 0;
1814 ind->size = 0;
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;
1823 /* Copy over the dynindx. */
1825 if (ind->root.dynindx != -1)
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;
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)
1842 struct elfNN_ia64_link_hash_entry *h;
1843 struct elfNN_ia64_dyn_sym_info *dyn_i;
1844 unsigned int count;
1846 h = (struct elfNN_ia64_link_hash_entry *)xh;
1848 _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1850 for (count = h->count, dyn_i = h->info;
1851 count != 0;
1852 count--, dyn_i++)
1854 dyn_i->want_plt2 = 0;
1855 dyn_i->want_plt = 0;
1859 /* Compute a hash of a local hash entry. */
1861 static hashval_t
1862 elfNN_ia64_local_htab_hash (const void *ptr)
1864 struct elfNN_ia64_local_hash_entry *entry
1865 = (struct elfNN_ia64_local_hash_entry *) ptr;
1867 return ELF_LOCAL_SYMBOL_HASH (entry->id, entry->r_sym);
1870 /* Compare local hash entries. */
1872 static int
1873 elfNN_ia64_local_htab_eq (const void *ptr1, const void *ptr2)
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;
1880 return entry1->id == entry2->id && entry1->r_sym == entry2->r_sym;
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). */
1887 static struct bfd_link_hash_table*
1888 elfNN_ia64_hash_table_create (bfd *abfd)
1890 struct elfNN_ia64_link_hash_table *ret;
1892 ret = bfd_zmalloc ((bfd_size_type) sizeof (*ret));
1893 if (!ret)
1894 return 0;
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)))
1900 free (ret);
1901 return 0;
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)
1909 free (ret);
1910 return 0;
1913 return &ret->root.root;
1916 /* Free the global elfNN_ia64_dyn_sym_info array. */
1918 static bfd_boolean
1919 elfNN_ia64_global_dyn_info_free (void **xentry,
1920 PTR unused ATTRIBUTE_UNUSED)
1922 struct elfNN_ia64_link_hash_entry *entry
1923 = (struct elfNN_ia64_link_hash_entry *) xentry;
1925 if (entry->root.root.type == bfd_link_hash_warning)
1926 entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
1928 if (entry->info)
1930 free (entry->info);
1931 entry->info = NULL;
1932 entry->count = 0;
1933 entry->sorted_count = 0;
1934 entry->size = 0;
1937 return TRUE;
1940 /* Free the local elfNN_ia64_dyn_sym_info array. */
1942 static bfd_boolean
1943 elfNN_ia64_local_dyn_info_free (void **slot,
1944 PTR unused ATTRIBUTE_UNUSED)
1946 struct elfNN_ia64_local_hash_entry *entry
1947 = (struct elfNN_ia64_local_hash_entry *) *slot;
1949 if (entry->info)
1951 free (entry->info);
1952 entry->info = NULL;
1953 entry->count = 0;
1954 entry->sorted_count = 0;
1955 entry->size = 0;
1958 return TRUE;
1961 /* Destroy IA-64 linker hash table. */
1963 static void
1964 elfNN_ia64_hash_table_free (struct bfd_link_hash_table *hash)
1966 struct elfNN_ia64_link_hash_table *ia64_info
1967 = (struct elfNN_ia64_link_hash_table *) hash;
1968 if (ia64_info->loc_hash_table)
1970 htab_traverse (ia64_info->loc_hash_table,
1971 elfNN_ia64_local_dyn_info_free, NULL);
1972 htab_delete (ia64_info->loc_hash_table);
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);
1981 /* Traverse both local and global hash tables. */
1983 struct elfNN_ia64_dyn_sym_traverse_data
1985 bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR);
1986 PTR data;
1989 static bfd_boolean
1990 elfNN_ia64_global_dyn_sym_thunk (struct bfd_hash_entry *xentry,
1991 PTR xdata)
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;
2000 if (entry->root.root.type == bfd_link_hash_warning)
2001 entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
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;
2011 static bfd_boolean
2012 elfNN_ia64_local_dyn_sym_thunk (void **slot, PTR xdata)
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;
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;
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)
2034 struct elfNN_ia64_dyn_sym_traverse_data xdata;
2036 xdata.func = func;
2037 xdata.data = data;
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);
2045 static bfd_boolean
2046 elfNN_ia64_create_dynamic_sections (bfd *abfd,
2047 struct bfd_link_info *info)
2049 struct elfNN_ia64_link_hash_table *ia64_info;
2050 asection *s;
2052 if (! _bfd_elf_create_dynamic_sections (abfd, info))
2053 return FALSE;
2055 ia64_info = elfNN_ia64_hash_table (info);
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);
2065 if (!get_pltoff (abfd, info, ia64_info))
2066 return FALSE;
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;
2079 return TRUE;
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)
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;
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);
2099 if (!slot)
2100 return NULL;
2102 if (*slot)
2103 return (struct elfNN_ia64_local_hash_entry *) *slot;
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)
2110 memset (ret, 0, sizeof (*ret));
2111 ret->id = sec->id;
2112 ret->r_sym = ELFNN_R_SYM (rel->r_info);
2113 *slot = ret;
2115 return ret;
2118 /* Used to sort elfNN_ia64_dyn_sym_info array. */
2120 static int
2121 addend_compare (const void *xp, const void *yp)
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;
2128 return x->addend < y->addend ? -1 : x->addend > y->addend ? 1 : 0;
2131 /* Sort elfNN_ia64_dyn_sym_info array and remove duplicates. */
2133 static unsigned int
2134 sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info *info,
2135 unsigned int count)
2137 bfd_vma curr, prev, got_offset;
2138 unsigned int i, kept, dupes, diff, dest, src, len;
2140 qsort (info, count, sizeof (*info), addend_compare);
2142 /* Find the first duplicate. */
2143 prev = info [0].addend;
2144 got_offset = info [0].got_offset;
2145 for (i = 1; i < count; i++)
2147 curr = info [i].addend;
2148 if (curr == prev)
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;
2155 got_offset = info [i].got_offset;
2156 prev = curr;
2159 /* We may move a block of elements to here. */
2160 dest = i++;
2162 /* Remove duplicates. */
2163 if (i < count)
2165 while (i < count)
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;
2173 curr = info [i].addend;
2174 got_offset = info [i].got_offset;
2176 /* Move a block of elements whose first one is different from
2177 the previous. */
2178 if (curr == prev)
2180 for (src = i + 1; src < count; src++)
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;
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;
2194 else
2195 src = i;
2197 if (src >= count)
2198 break;
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 ++)
2205 curr = info [dupes].addend;
2206 if (curr == prev)
2208 /* Make sure that got_offset is valid. */
2209 if (got_offset == (bfd_vma) -1)
2210 got_offset = info [dupes].got_offset;
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;
2218 got_offset = info [dupes].got_offset;
2219 prev = curr;
2222 /* How much to move. */
2223 len = dupes - src;
2224 i = dupes + 1;
2226 if (len == 1 && dupes < count)
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++)
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;
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;
2246 if (diff < count)
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 ++)
2254 curr = info [dupes].addend;
2255 if (curr == prev)
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;
2263 got_offset = info [dupes].got_offset;
2264 prev = curr;
2265 diff++;
2268 len = diff - src + 1;
2269 i = diff + 1;
2273 memmove (&info [dest], &info [src], len * sizeof (*info));
2275 dest += len;
2278 count = dest;
2280 else
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)
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;
2294 return count;
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.
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. */
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)
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;
2324 if (h)
2326 struct elfNN_ia64_link_hash_entry *global_h;
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;
2334 else
2336 struct elfNN_ia64_local_hash_entry *loc_h;
2338 loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
2339 if (!loc_h)
2341 BFD_ASSERT (!create);
2342 return NULL;
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;
2351 count = *count_p;
2352 sorted_count = *sorted_count_p;
2353 size = *size_p;
2354 info = *info_p;
2355 if (create)
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)
2363 if (sorted_count)
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);
2370 if (dyn_i)
2372 return dyn_i;
2376 /* Do a quick check for the last inserted entry. */
2377 dyn_i = info + count - 1;
2378 if (dyn_i->addend == addend)
2380 return dyn_i;
2384 if (size == 0)
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);
2392 else if (size <= count)
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);
2400 else
2401 goto has_space;
2403 if (info == NULL)
2404 return NULL;
2405 *size_p = size;
2406 *info_p = info;
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;
2415 /* We increment count only since the new ones are unsorted and
2416 may have duplicate. */
2417 (*count_p)++;
2419 else
2421 /* It is a lookup without insertion. Sort array if part of the
2422 array isn't sorted. */
2423 if (count != sorted_count)
2425 count = sort_dyn_sym_info (info, count);
2426 *count_p = count;
2427 *sorted_count_p = count;
2430 /* Free unused memory. */
2431 if (size != count)
2433 amt = count * sizeof (*info);
2434 info = bfd_malloc (amt);
2435 if (info != NULL)
2437 memcpy (info, *info_p, amt);
2438 free (*info_p);
2439 *size_p = count;
2440 *info_p = info;
2444 key.addend = addend;
2445 dyn_i = bsearch (&key, info, count,
2446 sizeof (*info), addend_compare);
2449 return dyn_i;
2452 static asection *
2453 get_got (bfd *abfd, struct bfd_link_info *info,
2454 struct elfNN_ia64_link_hash_table *ia64_info)
2456 asection *got;
2457 bfd *dynobj;
2459 got = ia64_info->root.sgot;
2460 if (!got)
2462 flagword flags;
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;
2470 got = ia64_info->root.sgot;
2472 /* The .got section is always aligned at 8 bytes. */
2473 if (!bfd_set_section_alignment (abfd, got, 3))
2474 return 0;
2476 flags = bfd_get_section_flags (abfd, got);
2477 bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
2480 return got;
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. */
2488 static asection *
2489 get_fptr (bfd *abfd, struct bfd_link_info *info,
2490 struct elfNN_ia64_link_hash_table *ia64_info)
2492 asection *fptr;
2493 bfd *dynobj;
2495 fptr = ia64_info->fptr_sec;
2496 if (!fptr)
2498 dynobj = ia64_info->root.dynobj;
2499 if (!dynobj)
2500 ia64_info->root.dynobj = dynobj = abfd;
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))
2512 BFD_ASSERT (0);
2513 return NULL;
2516 ia64_info->fptr_sec = fptr;
2518 if (info->pie)
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))
2531 BFD_ASSERT (0);
2532 return NULL;
2535 ia64_info->rel_fptr_sec = fptr_rel;
2539 return fptr;
2542 static asection *
2543 get_pltoff (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED,
2544 struct elfNN_ia64_link_hash_table *ia64_info)
2546 asection *pltoff;
2547 bfd *dynobj;
2549 pltoff = ia64_info->pltoff_sec;
2550 if (!pltoff)
2552 dynobj = ia64_info->root.dynobj;
2553 if (!dynobj)
2554 ia64_info->root.dynobj = dynobj = abfd;
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))
2567 BFD_ASSERT (0);
2568 return NULL;
2571 ia64_info->pltoff_sec = pltoff;
2574 return pltoff;
2577 static asection *
2578 get_reloc_section (bfd *abfd,
2579 struct elfNN_ia64_link_hash_table *ia64_info,
2580 asection *sec, bfd_boolean create)
2582 const char *srel_name;
2583 asection *srel;
2584 bfd *dynobj;
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;
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));
2599 dynobj = ia64_info->root.dynobj;
2600 if (!dynobj)
2601 ia64_info->root.dynobj = dynobj = abfd;
2603 srel = bfd_get_section_by_name (dynobj, srel_name);
2604 if (srel == NULL && create)
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;
2618 return srel;
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)
2625 struct elfNN_ia64_dyn_reloc_entry *rent;
2627 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2628 if (rent->srel == srel && rent->type == type)
2629 break;
2631 if (!rent)
2633 rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2634 bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
2635 if (!rent)
2636 return FALSE;
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;
2644 rent->reltext = reltext;
2645 rent->count++;
2647 return TRUE;
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)
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
2673 int need_entry;
2674 struct elf_link_hash_entry *h;
2675 unsigned long r_symndx;
2676 bfd_boolean maybe_dynamic;
2678 if (info->relocatable)
2679 return TRUE;
2681 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2682 ia64_info = elfNN_ia64_hash_table (info);
2684 got = fptr = srel = pltoff = NULL;
2686 relend = relocs + sec->reloc_count;
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)
2693 r_symndx = ELFNN_R_SYM (rel->r_info);
2694 if (r_symndx >= symtab_hdr->sh_info)
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;
2702 else
2703 h = NULL;
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));
2715 need_entry = 0;
2716 switch (ELFNN_R_TYPE (rel->r_info))
2718 case R_IA64_TPREL64MSB:
2719 case R_IA64_TPREL64LSB:
2720 if (info->shared || maybe_dynamic)
2721 need_entry = NEED_DYNREL;
2722 break;
2724 case R_IA64_LTOFF_TPREL22:
2725 need_entry = NEED_TPREL;
2726 if (info->shared)
2727 info->flags |= DF_STATIC_TLS;
2728 break;
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;
2738 case R_IA64_LTOFF_DTPREL22:
2739 need_entry = NEED_DTPREL;
2740 break;
2742 case R_IA64_DTPMOD64MSB:
2743 case R_IA64_DTPMOD64LSB:
2744 if (info->shared || maybe_dynamic)
2745 need_entry = NEED_DYNREL;
2746 break;
2748 case R_IA64_LTOFF_DTPMOD22:
2749 need_entry = NEED_DTPMOD;
2750 break;
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;
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;
2772 case R_IA64_LTOFF22:
2773 case R_IA64_LTOFF64I:
2774 need_entry = NEED_GOT;
2775 break;
2777 case R_IA64_LTOFF22X:
2778 need_entry = NEED_GOTX;
2779 break;
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)
2788 if (maybe_dynamic)
2789 need_entry |= NEED_MIN_PLT;
2791 else
2793 (*info->callbacks->warning)
2794 (info, _("@pltoff reloc against local symbol"), 0,
2795 abfd, 0, (bfd_vma) 0);
2797 break;
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;
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;
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;
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;
2839 if (!need_entry)
2840 continue;
2842 if ((need_entry & NEED_FPTR) != 0
2843 && rel->r_addend)
2845 (*info->callbacks->warning)
2846 (info, _("non-zero addend in @fptr reloc"), 0,
2847 abfd, 0, (bfd_vma) 0);
2850 if (get_dyn_sym_info (ia64_info, h, abfd, rel, TRUE) == NULL)
2851 return FALSE;
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)
2858 struct elfNN_ia64_dyn_sym_info *dyn_i;
2859 int dynrel_type = R_IA64_NONE;
2861 r_symndx = ELFNN_R_SYM (rel->r_info);
2862 if (r_symndx >= symtab_hdr->sh_info)
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;
2872 h->ref_regular = 1;
2874 else
2875 h = NULL;
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));
2887 need_entry = 0;
2888 switch (ELFNN_R_TYPE (rel->r_info))
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;
2899 case R_IA64_LTOFF_TPREL22:
2900 need_entry = NEED_TPREL;
2901 if (info->shared)
2902 info->flags |= DF_STATIC_TLS;
2903 break;
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;
2914 case R_IA64_LTOFF_DTPREL22:
2915 need_entry = NEED_DTPREL;
2916 break;
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;
2925 case R_IA64_LTOFF_DTPMOD22:
2926 need_entry = NEED_DTPMOD;
2927 break;
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;
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;
2950 case R_IA64_LTOFF22:
2951 case R_IA64_LTOFF64I:
2952 need_entry = NEED_GOT;
2953 break;
2955 case R_IA64_LTOFF22X:
2956 need_entry = NEED_GOTX;
2957 break;
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)
2966 if (maybe_dynamic)
2967 need_entry |= NEED_MIN_PLT;
2969 break;
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;
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;
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;
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;
3014 if (!need_entry)
3015 continue;
3017 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, FALSE);
3019 /* Record whether or not this is a local symbol. */
3020 dyn_i->h = h;
3022 /* Create what's needed. */
3023 if (need_entry & (NEED_GOT | NEED_GOTX | NEED_TPREL
3024 | NEED_DTPMOD | NEED_DTPREL))
3026 if (!got)
3028 got = get_got (abfd, info, ia64_info);
3029 if (!got)
3030 return FALSE;
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;
3043 if (need_entry & NEED_FPTR)
3045 if (!fptr)
3047 fptr = get_fptr (abfd, info, ia64_info);
3048 if (!fptr)
3049 return FALSE;
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)
3057 if (! (bfd_elf_link_record_local_dynamic_symbol
3058 (info, abfd, (long) r_symndx)))
3059 return FALSE;
3062 dyn_i->want_fptr = 1;
3064 if (need_entry & NEED_LTOFF_FPTR)
3065 dyn_i->want_ltoff_fptr = 1;
3066 if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
3068 if (!ia64_info->root.dynobj)
3069 ia64_info->root.dynobj = abfd;
3070 h->needs_plt = 1;
3071 dyn_i->want_plt = 1;
3073 if (need_entry & NEED_FULL_PLT)
3074 dyn_i->want_plt2 = 1;
3075 if (need_entry & NEED_PLTOFF)
3077 /* This is needed here, in case @pltoff is used in a non-shared
3078 link. */
3079 if (!pltoff)
3081 pltoff = get_pltoff (abfd, info, ia64_info);
3082 if (!pltoff)
3083 return FALSE;
3086 dyn_i->want_pltoff = 1;
3088 if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
3090 if (!srel)
3092 srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
3093 if (!srel)
3094 return FALSE;
3096 if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type,
3097 (sec->flags & SEC_READONLY) != 0))
3098 return FALSE;
3102 return TRUE;
3105 /* For cleanliness, and potentially faster dynamic loading, allocate
3106 external GOT entries first. */
3108 static bfd_boolean
3109 allocate_global_data_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
3110 PTR data)
3112 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
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))
3118 dyn_i->got_offset = x->ofs;
3119 x->ofs += 8;
3121 if (dyn_i->want_tprel)
3123 dyn_i->tprel_offset = x->ofs;
3124 x->ofs += 8;
3126 if (dyn_i->want_dtpmod)
3128 if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
3130 dyn_i->dtpmod_offset = x->ofs;
3131 x->ofs += 8;
3133 else
3135 struct elfNN_ia64_link_hash_table *ia64_info;
3137 ia64_info = elfNN_ia64_hash_table (x->info);
3138 if (ia64_info->self_dtpmod_offset == (bfd_vma) -1)
3140 ia64_info->self_dtpmod_offset = x->ofs;
3141 x->ofs += 8;
3143 dyn_i->dtpmod_offset = ia64_info->self_dtpmod_offset;
3146 if (dyn_i->want_dtprel)
3148 dyn_i->dtprel_offset = x->ofs;
3149 x->ofs += 8;
3151 return TRUE;
3154 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
3156 static bfd_boolean
3157 allocate_global_fptr_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
3158 PTR data)
3160 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
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))
3166 dyn_i->got_offset = x->ofs;
3167 x->ofs += 8;
3169 return TRUE;
3172 /* Lastly, allocate all the GOT entries for local data. */
3174 static bfd_boolean
3175 allocate_local_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
3176 PTR data)
3178 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3180 if ((dyn_i->want_got || dyn_i->want_gotx)
3181 && !elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
3183 dyn_i->got_offset = x->ofs;
3184 x->ofs += 8;
3186 return TRUE;
3189 /* Search for the index of a global symbol in it's defining object file. */
3191 static long
3192 global_sym_index (struct elf_link_hash_entry *h)
3194 struct elf_link_hash_entry **p;
3195 bfd *obj;
3197 BFD_ASSERT (h->root.type == bfd_link_hash_defined
3198 || h->root.type == bfd_link_hash_defweak);
3200 obj = h->root.u.def.section->owner;
3201 for (p = elf_sym_hashes (obj); *p != h; ++p)
3202 continue;
3204 return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
3207 /* Allocate function descriptors. We can do these for every function
3208 in a main executable that is not exported. */
3210 static bfd_boolean
3211 allocate_fptr (struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data)
3213 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3215 if (dyn_i->want_fptr)
3217 struct elf_link_hash_entry *h = dyn_i->h;
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;
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)))
3230 if (h && h->dynindx == -1)
3232 BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
3233 || (h->root.type == bfd_link_hash_defweak));
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;
3241 dyn_i->want_fptr = 0;
3243 else if (h == NULL || h->dynindx == -1)
3245 dyn_i->fptr_offset = x->ofs;
3246 x->ofs += 16;
3248 else
3249 dyn_i->want_fptr = 0;
3251 return TRUE;
3254 /* Allocate all the minimal PLT entries. */
3256 static bfd_boolean
3257 allocate_plt_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
3258 PTR data)
3260 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3262 if (dyn_i->want_plt)
3264 struct elf_link_hash_entry *h = dyn_i->h;
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;
3271 /* ??? Versioned symbols seem to lose NEEDS_PLT. */
3272 if (elfNN_ia64_dynamic_symbol_p (h, x->info, 0))
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;
3280 dyn_i->want_pltoff = 1;
3282 else
3284 dyn_i->want_plt = 0;
3285 dyn_i->want_plt2 = 0;
3288 return TRUE;
3291 /* Allocate all the full PLT entries. */
3293 static bfd_boolean
3294 allocate_plt2_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
3295 PTR data)
3297 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3299 if (dyn_i->want_plt2)
3301 struct elf_link_hash_entry *h = dyn_i->h;
3302 bfd_size_type ofs = x->ofs;
3304 dyn_i->plt2_offset = ofs;
3305 x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
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;
3312 return TRUE;
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. */
3320 static bfd_boolean
3321 allocate_pltoff_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
3322 PTR data)
3324 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
3326 if (dyn_i->want_pltoff)
3328 dyn_i->pltoff_offset = x->ofs;
3329 x->ofs += 16;
3331 return TRUE;
3334 /* Allocate dynamic relocations for those symbols that turned out
3335 to be dynamic. */
3337 static bfd_boolean
3338 allocate_dynrel_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
3339 PTR data)
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;
3346 ia64_info = elfNN_ia64_hash_table (x->info);
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);
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);
3356 /* Take care of the GOT and PLT relocations. */
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))
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);
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);
3378 if (x->only_got)
3379 return TRUE;
3381 if (ia64_info->rel_fptr_sec && dyn_i->want_fptr)
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);
3387 if (!resolved_zero && dyn_i->want_pltoff)
3389 bfd_size_type t = 0;
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);
3399 ia64_info->rel_pltoff_sec->size += t;
3402 /* Take care of the normal data relocations. */
3404 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
3406 int count = rent->count;
3408 switch (rent->type)
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 ();
3445 if (rent->reltext)
3446 ia64_info->reltext = 1;
3447 rent->srel->size += sizeof (ElfNN_External_Rela) * count;
3450 return TRUE;
3453 static bfd_boolean
3454 elfNN_ia64_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
3455 struct elf_link_hash_entry *h)
3457 /* ??? Undefined symbols with PLT entries should be re-defined
3458 to be the PLT entry. */
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)
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;
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.
3476 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
3477 of hackery. */
3479 return TRUE;
3482 static bfd_boolean
3483 elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
3484 struct bfd_link_info *info)
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;
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;
3498 /* Set the contents of the .interp section to the interpreter. */
3499 if (ia64_info->root.dynamic_sections_created
3500 && info->executable)
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;
3508 /* Allocate the GOT entries. */
3510 if (ia64_info->root.sgot)
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;
3519 /* Allocate the FPTR entries. */
3521 if (ia64_info->fptr_sec)
3523 data.ofs = 0;
3524 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
3525 ia64_info->fptr_sec->size = data.ofs;
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. */
3533 data.ofs = 0;
3534 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
3536 ia64_info->minplt_entries = 0;
3537 if (data.ofs)
3539 ia64_info->minplt_entries
3540 = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
3543 /* Align the pointer for the plt2 entries. */
3544 data.ofs = (data.ofs + 31) & (bfd_vma) -32;
3546 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
3547 if (data.ofs != 0 || ia64_info->root.dynamic_sections_created)
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. */
3553 BFD_ASSERT (ia64_info->root.dynamic_sections_created);
3555 ia64_info->root.splt->size = data.ofs;
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;
3563 /* Allocate the PLTOFF entries. */
3565 if (ia64_info->pltoff_sec)
3567 data.ofs = 0;
3568 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
3569 ia64_info->pltoff_sec->size = data.ofs;
3572 if (ia64_info->root.dynamic_sections_created)
3574 /* Allocate space for the dynamic relocations that turned out to be
3575 required. */
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);
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)
3587 bfd_boolean strip;
3589 if (!(sec->flags & SEC_LINKER_CREATED))
3590 continue;
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. */
3600 strip = (sec->size == 0);
3602 if (sec == ia64_info->root.sgot)
3603 strip = FALSE;
3604 else if (sec == ia64_info->root.srelgot)
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;
3613 else if (sec == ia64_info->fptr_sec)
3615 if (strip)
3616 ia64_info->fptr_sec = NULL;
3618 else if (sec == ia64_info->rel_fptr_sec)
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;
3627 else if (sec == ia64_info->root.splt)
3629 if (strip)
3630 ia64_info->root.splt = NULL;
3632 else if (sec == ia64_info->pltoff_sec)
3634 if (strip)
3635 ia64_info->pltoff_sec = NULL;
3637 else if (sec == ia64_info->rel_pltoff_sec)
3639 if (strip)
3640 ia64_info->rel_pltoff_sec = NULL;
3641 else
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;
3649 else
3651 const char *name;
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);
3657 if (strcmp (name, ".got.plt") == 0)
3658 strip = FALSE;
3659 else if (CONST_STRNEQ (name, ".rel"))
3661 if (!strip)
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;
3668 else
3669 continue;
3672 if (strip)
3673 sec->flags |= SEC_EXCLUDE;
3674 else
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;
3683 if (elf_hash_table (info)->dynamic_sections_created)
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. */
3689 if (info->executable)
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)
3696 if (!add_dynamic_entry (DT_DEBUG, 0))
3697 return FALSE;
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;
3705 if (relplt)
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;
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;
3718 if (ia64_info->reltext)
3720 if (!add_dynamic_entry (DT_TEXTREL, 0))
3721 return FALSE;
3722 info->flags |= DF_TEXTREL;
3726 /* ??? Perhaps force __gp local. */
3728 return TRUE;
3731 static bfd_reloc_status_type
3732 elfNN_ia64_install_value (bfd_byte *hit_addr, bfd_vma v,
3733 unsigned int r_type)
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
3748 opnd = IA64_OPND_NIL;
3749 switch (r_type)
3751 case R_IA64_NONE:
3752 case R_IA64_LDXMOV:
3753 return bfd_reloc_ok;
3755 /* Instruction relocations. */
3757 case R_IA64_IMM14:
3758 case R_IA64_TPREL14:
3759 case R_IA64_DTPREL14:
3760 opnd = IA64_OPND_IMM14;
3761 break;
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;
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;
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;
3798 /* Data relocations. */
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;
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;
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;
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;
3854 /* Unsupported / Dynamic relocations. */
3855 default:
3856 return bfd_reloc_notsupported;
3859 switch (opnd)
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);
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 */
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));
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 */
3886 bfd_putl64 (t0, hit_addr);
3887 bfd_putl64 (t1, hit_addr + 8);
3888 break;
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);
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 */
3900 /* First, clear the bits that form the 64 bit constant. */
3901 t0 &= ~(0x3ffffLL << 46);
3902 t1 &= ~(0x7fffffLL
3903 | ((1LL << 36 | 0xfffffLL << 13) << 23));
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 */
3911 bfd_putl64 (t0, hit_addr);
3912 bfd_putl64 (t1, hit_addr + 8);
3913 break;
3915 default:
3916 switch ((long) hit_addr & 0x3)
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... */
3923 dword = bfd_getl64 (hit_addr);
3924 insn = (dword >> shift) & 0x1ffffffffffLL;
3926 op = elf64_ia64_operands + opnd;
3927 err = (*op->insert) (op, val, &insn);
3928 if (err)
3929 return bfd_reloc_overflow;
3931 dword &= ~(0x1ffffffffffLL << shift);
3932 dword |= (insn << shift);
3933 bfd_putl64 (dword, hit_addr);
3934 break;
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;
3951 return bfd_reloc_ok;
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)
3960 Elf_Internal_Rela outrel;
3961 bfd_byte *loc;
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)
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;
3975 else
3976 outrel.r_offset += sec->output_section->vma + sec->output_offset;
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);
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. */
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)
3993 struct elfNN_ia64_link_hash_table *ia64_info;
3994 asection *got_sec;
3995 bfd_boolean done;
3996 bfd_vma got_offset;
3998 ia64_info = elfNN_ia64_hash_table (info);
3999 got_sec = ia64_info->root.sgot;
4001 switch (dyn_r_type)
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)
4011 done = dyn_i->dtpmod_done;
4012 dyn_i->dtpmod_done = TRUE;
4014 else
4016 done = ia64_info->self_dtpmod_done;
4017 ia64_info->self_dtpmod_done = TRUE;
4018 dynindx = 0;
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;
4035 BFD_ASSERT ((got_offset & 7) == 0);
4037 if (! done)
4039 /* Store the target address in the linkage table entry. */
4040 bfd_put_64 (abfd, value, got_sec->contents + got_offset);
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))
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)
4064 dyn_r_type = R_IA64_RELNNLSB;
4065 dynindx = 0;
4066 addend = value;
4069 if (bfd_big_endian (abfd))
4071 switch (dyn_r_type)
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;
4109 elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
4110 ia64_info->root.srelgot,
4111 got_offset, dyn_r_type,
4112 dynindx, addend);
4116 /* Return the address of the linkage table entry. */
4117 value = (got_sec->output_section->vma
4118 + got_sec->output_offset
4119 + got_offset);
4121 return value;
4124 /* Fill in a function descriptor consisting of the function's code
4125 address and its global pointer. Return the descriptor's address. */
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)
4132 struct elfNN_ia64_link_hash_table *ia64_info;
4133 asection *fptr_sec;
4135 ia64_info = elfNN_ia64_hash_table (info);
4136 fptr_sec = ia64_info->fptr_sec;
4138 if (!dyn_i->fptr_done)
4140 dyn_i->fptr_done = 1;
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)
4148 Elf_Internal_Rela outrel;
4149 bfd_byte *loc;
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);
4166 /* Return the descriptor's address. */
4167 value = (fptr_sec->output_section->vma
4168 + fptr_sec->output_offset
4169 + dyn_i->fptr_offset);
4171 return value;
4174 /* Fill in a PLTOFF entry consisting of the function's code address
4175 and its global pointer. Return the descriptor's address. */
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)
4182 struct elfNN_ia64_link_hash_table *ia64_info;
4183 asection *pltoff_sec;
4185 ia64_info = elfNN_ia64_hash_table (info);
4186 pltoff_sec = ia64_info->pltoff_sec;
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)
4193 bfd_vma gp = _bfd_get_gp_value (abfd);
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);
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))
4206 unsigned int dyn_r_type;
4208 if (bfd_big_endian (abfd))
4209 dyn_r_type = R_IA64_RELNNMSB;
4210 else
4211 dyn_r_type = R_IA64_RELNNLSB;
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);
4223 dyn_i->pltoff_done = 1;
4226 /* Return the descriptor's address. */
4227 value = (pltoff_sec->output_section->vma
4228 + pltoff_sec->output_offset
4229 + dyn_i->pltoff_offset);
4231 return value;
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). */
4239 static bfd_vma
4240 elfNN_ia64_tprel_base (struct bfd_link_info *info)
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);
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. */
4251 static bfd_vma
4252 elfNN_ia64_dtprel_base (struct bfd_link_info *info)
4254 return elf_hash_table (info)->tls_sec->vma;
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. */
4261 static bfd *elfNN_ia64_unwind_entry_compare_bfd;
4263 static int
4264 elfNN_ia64_unwind_entry_compare (const PTR a, const PTR b)
4266 bfd_vma av, bv;
4268 av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
4269 bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
4271 return (av < bv ? -1 : av > bv ? 1 : 0);
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)
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;
4285 ia64_info = elfNN_ia64_hash_table (info);
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)
4291 bfd_vma lo, hi;
4293 if ((os->flags & SEC_ALLOC) == 0)
4294 continue;
4296 lo = os->vma;
4297 hi = os->vma + (os->rawsize ? os->rawsize : os->size);
4298 if (hi < lo)
4299 hi = (bfd_vma) -1;
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)
4307 if (min_short_vma > lo)
4308 min_short_vma = lo;
4309 if (max_short_vma < hi)
4310 max_short_vma = hi;
4314 if (ia64_info->min_short_sec)
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);
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);
4332 if (gp
4333 && (gp->root.type == bfd_link_hash_defined
4334 || gp->root.type == bfd_link_hash_defweak))
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);
4341 else
4343 /* Pick a sensible value. */
4345 if (ia64_info->min_short_sec)
4347 bfd_vma short_range = max_short_vma - min_short_vma;
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;
4355 else
4357 asection *got_sec = ia64_info->root.sgot;
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;
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)
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;
4382 /* If we're addressing stuff past the end, adjust back. */
4383 if (gp_val > max_vma)
4384 gp_val = max_vma - 0x200000 + 8;
4388 /* Validate whether all SHF_IA_64_SHORT sections are within
4389 range of the chosen GP. */
4391 if (max_short_vma != 0)
4393 if (max_short_vma - min_short_vma >= 0x400000)
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;
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))
4407 (*_bfd_error_handler)
4408 (_("%s: __gp does not cover short data segment"),
4409 bfd_get_filename (abfd));
4410 return FALSE;
4414 _bfd_set_gp_value (abfd, gp_val);
4416 return TRUE;
4419 static bfd_boolean
4420 elfNN_ia64_final_link (bfd *abfd, struct bfd_link_info *info)
4422 struct elfNN_ia64_link_hash_table *ia64_info;
4423 asection *unwind_output_sec;
4425 ia64_info = elfNN_ia64_hash_table (info);
4427 /* Make sure we've got ourselves a nice fat __gp value. */
4428 if (!info->relocatable)
4430 bfd_vma gp_val;
4431 struct elf_link_hash_entry *gp;
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);
4440 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
4441 FALSE, FALSE);
4442 if (gp)
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;
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)
4456 asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
4457 if (s)
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;
4467 /* Invoke the regular ELF backend linker to do all the work. */
4468 if (!bfd_elf_final_link (abfd, info))
4469 return FALSE;
4471 if (unwind_output_sec)
4473 elfNN_ia64_unwind_entry_compare_bfd = abfd;
4474 qsort (unwind_output_sec->contents,
4475 (size_t) (unwind_output_sec->size / 24),
4477 elfNN_ia64_unwind_entry_compare);
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;
4485 return TRUE;
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)
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;
4506 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
4507 ia64_info = elfNN_ia64_hash_table (info);
4509 /* Infect various flags from the input section to the output section. */
4510 if (info->relocatable)
4512 bfd_vma flags;
4514 flags = elf_section_data(input_section)->this_hdr.sh_flags;
4515 flags &= SHF_IA_64_NORECOV;
4517 elf_section_data(input_section->output_section)
4518 ->this_hdr.sh_flags |= flags;
4521 gp_val = _bfd_get_gp_value (output_bfd);
4522 srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
4524 rel = relocs;
4525 relend = relocs + input_section->reloc_count;
4526 for (; rel < relend; ++rel)
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;
4541 r_type = ELFNN_R_TYPE (rel->r_info);
4542 if (r_type > R_IA64_MAX_RELOC_CODE)
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;
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;
4559 if (r_symndx < symtab_hdr->sh_info)
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)
4572 struct elfNN_ia64_local_hash_entry *loc_h;
4574 loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
4575 if (loc_h && ! loc_h->sec_merge_done)
4577 struct elfNN_ia64_dyn_sym_info *dynent;
4578 unsigned int count;
4580 for (count = loc_h->count, dynent = loc_h->info;
4581 count != 0;
4582 count--, dynent++)
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;
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)
4603 loc_h->count = count;
4604 loc_h->sorted_count = count;
4607 loc_h->sec_merge_done = 1;
4611 else
4613 bfd_boolean unresolved_reloc;
4614 bfd_boolean warned;
4615 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
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);
4622 if (h->root.type == bfd_link_hash_undefweak)
4623 undef_weak_ref = TRUE;
4624 else if (warned)
4625 continue;
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))
4633 _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
4634 rel->r_info = 0;
4635 rel->r_addend = 0;
4636 continue;
4639 if (info->relocatable)
4640 continue;
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);
4646 switch (r_type)
4648 case R_IA64_NONE:
4649 case R_IA64_LDXMOV:
4650 continue;
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)
4664 unsigned int dyn_r_type;
4665 long dynindx;
4666 bfd_vma addend;
4668 BFD_ASSERT (srel != NULL);
4670 switch (r_type)
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;
4686 default:
4687 break;
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)
4695 dynindx = h->dynindx;
4696 addend = rel->r_addend;
4697 value = 0;
4699 else
4701 switch (r_type)
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;
4716 default:
4717 break;
4719 dynindx = 0;
4720 addend = value;
4723 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4724 srel, rel->r_offset, dyn_r_type,
4725 dynindx, addend);
4727 /* Fall through. */
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;
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)
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;
4753 value -= gp_val;
4754 r = elfNN_ia64_install_value (hit_addr, value, r_type);
4755 break;
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;
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;
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)
4785 if (!undef_weak_ref)
4786 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4788 if (!dyn_i->want_fptr || info->pie)
4790 long dynindx;
4791 unsigned int dyn_r_type = r_type;
4792 bfd_vma addend = rel->r_addend;
4794 /* Otherwise, we expect the dynamic linker to create
4795 the entry. */
4797 if (dyn_i->want_fptr)
4799 if (r_type == R_IA64_FPTR64I)
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;
4813 dynindx = 0;
4814 addend = value;
4815 dyn_r_type = r_type + R_IA64_RELNNLSB - R_IA64_FPTRNNLSB;
4817 else if (h)
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;
4827 else
4829 dynindx = (_bfd_elf_link_lookup_local_dynindx
4830 (info, input_bfd, (long) r_symndx));
4831 value = 0;
4834 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4835 srel, rel->r_offset, dyn_r_type,
4836 dynindx, addend);
4839 r = elfNN_ia64_install_value (hit_addr, value, r_type);
4840 break;
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:
4849 long dynindx;
4851 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4852 if (dyn_i->want_fptr)
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;
4859 else
4861 /* Otherwise, we expect the dynamic linker to create
4862 the entry. */
4863 if (h)
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)));
4872 else
4873 dynindx = (_bfd_elf_link_lookup_local_dynindx
4874 (info, input_bfd, (long) r_symndx));
4875 value = 0;
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);
4883 break;
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)
4892 BFD_ASSERT (srel != NULL);
4894 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4895 srel, rel->r_offset, r_type,
4896 h->dynindx, rel->r_addend);
4898 goto finish_pcrel;
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);
4907 if (dyn_i && dyn_i->want_plt2)
4909 /* Should have caught this earlier. */
4910 BFD_ASSERT (rel->r_addend == 0);
4912 value = (ia64_info->root.splt->output_section->vma
4913 + ia64_info->root.splt->output_offset
4914 + dyn_i->plt2_offset);
4916 else
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);
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;
4929 goto finish_pcrel;
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)
4942 const char *msg;
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;
4959 goto finish_pcrel;
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;
4969 case R_IA64_SEGREL32MSB:
4970 case R_IA64_SEGREL32LSB:
4971 case R_IA64_SEGREL64MSB:
4972 case R_IA64_SEGREL64LSB:
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);
4978 if (p == NULL)
4980 r = bfd_reloc_notsupported;
4982 else
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);
4992 break;
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;
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)
5012 BFD_ASSERT (srel != NULL);
5014 /* If we don't need dynamic symbol lookup, install two
5015 RELATIVE relocations. */
5016 if (!dynamic_symbol_p)
5018 unsigned int dyn_r_type;
5020 if (r_type == R_IA64_IPLTMSB)
5021 dyn_r_type = R_IA64_REL64MSB;
5022 else
5023 dyn_r_type = R_IA64_REL64LSB;
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);
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);
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;
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;
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;
5070 case R_IA64_LTOFF_TPREL22:
5071 case R_IA64_LTOFF_DTPMOD22:
5072 case R_IA64_LTOFF_DTPREL22:
5074 int got_r_type;
5075 long dynindx = h ? h->dynindx : -1;
5076 bfd_vma r_addend = rel->r_addend;
5078 switch (r_type)
5080 default:
5081 case R_IA64_LTOFF_TPREL22:
5082 if (!dynamic_symbol_p)
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
5090 r_addend += value - elfNN_ia64_dtprel_base (info);
5091 dynindx = 0;
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)
5104 if (elf_hash_table (info)->tls_sec == NULL)
5105 goto missing_tls_sec;
5106 value -= elfNN_ia64_dtprel_base (info);
5108 got_r_type = R_IA64_DTPRELNNLSB;
5109 break;
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);
5117 break;
5119 default:
5120 r = bfd_reloc_notsupported;
5121 break;
5124 switch (r)
5126 case bfd_reloc_ok:
5127 break;
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;
5137 case bfd_reloc_notsupported:
5139 const char *name;
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;
5152 break;
5154 case bfd_reloc_dangerous:
5155 case bfd_reloc_outofrange:
5156 case bfd_reloc_overflow:
5157 default:
5158 missing_tls_sec:
5160 const char *name;
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);
5168 switch (r_type)
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;
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))
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;
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;
5217 ret_val = FALSE;
5219 break;
5223 return ret_val;
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)
5232 struct elfNN_ia64_link_hash_table *ia64_info;
5233 struct elfNN_ia64_dyn_sym_info *dyn_i;
5235 ia64_info = elfNN_ia64_hash_table (info);
5236 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
5238 /* Fill in the PLT data, if required. */
5239 if (dyn_i && dyn_i->want_plt)
5241 Elf_Internal_Rela outrel;
5242 bfd_byte *loc;
5243 asection *plt_sec;
5244 bfd_vma plt_addr, pltoff_addr, gp_val, plt_index;
5246 gp_val = _bfd_get_gp_value (output_bfd);
5248 /* Initialize the minimal PLT entry. */
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;
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);
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);
5263 /* Initialize the FULL PLT entry, if needed. */
5264 if (dyn_i->want_plt2)
5266 loc = plt_sec->contents + dyn_i->plt2_offset;
5268 memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
5269 elfNN_ia64_install_value (loc, pltoff_addr - gp_val, R_IA64_IMM22);
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;
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;
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.
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. */
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);
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;
5311 return TRUE;
5314 static bfd_boolean
5315 elfNN_ia64_finish_dynamic_sections (bfd *abfd,
5316 struct bfd_link_info *info)
5318 struct elfNN_ia64_link_hash_table *ia64_info;
5319 bfd *dynobj;
5321 ia64_info = elfNN_ia64_hash_table (info);
5322 dynobj = ia64_info->root.dynobj;
5324 if (elf_hash_table (info)->dynamic_sections_created)
5326 ElfNN_External_Dyn *dyncon, *dynconend;
5327 asection *sdyn, *sgotplt;
5328 bfd_vma gp_val;
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);
5336 gp_val = _bfd_get_gp_value (abfd);
5338 for (; dyncon < dynconend; dyncon++)
5340 Elf_Internal_Dyn dyn;
5342 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
5344 switch (dyn.d_tag)
5346 case DT_PLTGOT:
5347 dyn.d_un.d_ptr = gp_val;
5348 break;
5350 case DT_PLTRELSZ:
5351 dyn.d_un.d_val = (ia64_info->minplt_entries
5352 * sizeof (ElfNN_External_Rela));
5353 break;
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;
5363 case DT_IA_64_PLT_RESERVE:
5364 dyn.d_un.d_ptr = (sgotplt->output_section->vma
5365 + sgotplt->output_offset);
5366 break;
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;
5376 bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
5379 /* Initialize the PLT0 entry. */
5380 if (ia64_info->root.splt)
5382 bfd_byte *loc = ia64_info->root.splt->contents;
5383 bfd_vma pltres;
5385 memcpy (loc, plt_header, PLT_HEADER_SIZE);
5387 pltres = (sgotplt->output_section->vma
5388 + sgotplt->output_offset
5389 - gp_val);
5391 elfNN_ia64_install_value (loc+1, pltres, R_IA64_GPREL22);
5395 return TRUE;
5398 /* ELF file flag handling: */
5400 /* Function to keep IA-64 specific file flags. */
5401 static bfd_boolean
5402 elfNN_ia64_set_private_flags (bfd *abfd, flagword flags)
5404 BFD_ASSERT (!elf_flags_init (abfd)
5405 || elf_elfheader (abfd)->e_flags == flags);
5407 elf_elfheader (abfd)->e_flags = flags;
5408 elf_flags_init (abfd) = TRUE;
5409 return TRUE;
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)
5417 flagword out_flags;
5418 flagword in_flags;
5419 bfd_boolean ok = TRUE;
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;
5426 in_flags = elf_elfheader (ibfd)->e_flags;
5427 out_flags = elf_elfheader (obfd)->e_flags;
5429 if (! elf_flags_init (obfd))
5431 elf_flags_init (obfd) = TRUE;
5432 elf_elfheader (obfd)->e_flags = in_flags;
5434 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
5435 && bfd_get_arch_info (obfd)->the_default)
5437 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
5438 bfd_get_mach (ibfd));
5441 return TRUE;
5444 /* Check flag compatibility. */
5445 if (in_flags == out_flags)
5446 return TRUE;
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;
5452 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
5454 (*_bfd_error_handler)
5455 (_("%B: linking trap-on-NULL-dereference with non-trapping files"),
5456 ibfd);
5458 bfd_set_error (bfd_error_bad_value);
5459 ok = FALSE;
5461 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
5463 (*_bfd_error_handler)
5464 (_("%B: linking big-endian files with little-endian files"),
5465 ibfd);
5467 bfd_set_error (bfd_error_bad_value);
5468 ok = FALSE;
5470 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
5472 (*_bfd_error_handler)
5473 (_("%B: linking 64-bit files with 32-bit files"),
5474 ibfd);
5476 bfd_set_error (bfd_error_bad_value);
5477 ok = FALSE;
5479 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
5481 (*_bfd_error_handler)
5482 (_("%B: linking constant-gp files with non-constant-gp files"),
5483 ibfd);
5485 bfd_set_error (bfd_error_bad_value);
5486 ok = FALSE;
5488 if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
5489 != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
5491 (*_bfd_error_handler)
5492 (_("%B: linking auto-pic files with non-auto-pic files"),
5493 ibfd);
5495 bfd_set_error (bfd_error_bad_value);
5496 ok = FALSE;
5499 return ok;
5502 static bfd_boolean
5503 elfNN_ia64_print_private_bfd_data (bfd *abfd, PTR ptr)
5505 FILE *file = (FILE *) ptr;
5506 flagword flags = elf_elfheader (abfd)->e_flags;
5508 BFD_ASSERT (abfd != NULL && ptr != NULL);
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");
5520 _bfd_elf_print_private_bfd_data (abfd, ptr);
5521 return TRUE;
5524 static enum elf_reloc_type_class
5525 elfNN_ia64_reloc_type_class (const Elf_Internal_Rela *rela)
5527 switch ((int) ELFNN_R_TYPE (rela->r_info))
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;
5544 static const struct bfd_elf_special_section elfNN_ia64_special_sections[] =
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 }
5551 static bfd_boolean
5552 elfNN_ia64_object_p (bfd *abfd)
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;
5561 if (abfd->flags & DYNAMIC)
5562 return TRUE;
5564 /* Flags for fake group section. */
5565 flags = (SEC_LINKER_CREATED | SEC_GROUP | SEC_LINK_ONCE
5566 | SEC_EXCLUDE);
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)
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."))
5577 name = sec->name + 16;
5579 amt = strlen (name) + sizeof (".gnu.linkonce.ia64unwi.");
5580 unwi_name = bfd_alloc (abfd, amt);
5581 if (!unwi_name)
5582 return FALSE;
5584 strcpy (stpcpy (unwi_name, ".gnu.linkonce.ia64unwi."), name);
5585 unwi = bfd_get_section_by_name (abfd, unwi_name);
5587 amt = strlen (name) + sizeof (".gnu.linkonce.ia64unw.");
5588 unw_name = bfd_alloc (abfd, amt);
5589 if (!unw_name)
5590 return FALSE;
5592 strcpy (stpcpy (unw_name, ".gnu.linkonce.ia64unw."), name);
5593 unw = bfd_get_section_by_name (abfd, unw_name);
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;
5602 /* Move the fake group section to the beginning. */
5603 bfd_section_list_remove (abfd, group);
5604 bfd_section_list_prepend (abfd, group);
5606 elf_next_in_group (group) = sec;
5608 elf_group_name (sec) = name;
5609 elf_next_in_group (sec) = sec;
5610 elf_sec_group (sec) = group;
5612 if (unwi)
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;
5620 if (unw)
5622 elf_group_name (unw) = name;
5623 if (unwi)
5625 elf_next_in_group (unw) = elf_next_in_group (unwi);
5626 elf_next_in_group (unwi) = unw;
5628 else
5630 elf_next_in_group (unw) = sec;
5631 elf_next_in_group (sec) = unw;
5633 elf_sec_group (unw) = group;
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;
5641 return TRUE;
5644 static bfd_boolean
5645 elfNN_ia64_hpux_vec (const bfd_target *vec)
5647 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
5648 return (vec == & bfd_elfNN_ia64_hpux_big_vec);
5651 static void
5652 elfNN_hpux_post_process_headers (bfd *abfd,
5653 struct bfd_link_info *info ATTRIBUTE_UNUSED)
5655 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
5657 i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
5658 i_ehdrp->e_ident[EI_ABIVERSION] = 1;
5661 static bfd_boolean
5662 elfNN_hpux_backend_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
5663 asection *sec, int *retval)
5665 if (bfd_is_com_section (sec))
5667 *retval = SHN_IA_64_ANSI_COMMON;
5668 return TRUE;
5670 return FALSE;
5673 static void
5674 elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
5675 asymbol *asym)
5677 elf_symbol_type *elfsym = (elf_symbol_type *) asym;
5679 switch (elfsym->internal_elf_sym.st_shndx)
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;
5689 static bfd_boolean
5690 elfNN_vms_section_from_shdr (bfd *abfd,
5691 Elf_Internal_Shdr *hdr,
5692 const char *name,
5693 int shindex)
5695 asection *newsect;
5697 switch (hdr->sh_type)
5699 case SHT_IA_64_VMS_TRACE:
5700 case SHT_IA_64_VMS_DEBUG:
5701 case SHT_IA_64_VMS_DEBUG_STR:
5702 break;
5704 default:
5705 return elfNN_ia64_section_from_shdr (abfd, hdr, name, shindex);
5708 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
5709 return FALSE;
5710 newsect = hdr->bfd_section;
5712 return TRUE;
5715 static bfd_boolean
5716 elfNN_vms_object_p (bfd *abfd)
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];
5726 if (!elfNN_ia64_object_p (abfd))
5727 return FALSE;
5729 for (i = 0; i < i_ehdrp->e_phnum; i++, i_phdr++)
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;
5735 if (i_phdr->p_type != PT_LOAD)
5736 continue;
5738 again:
5739 while (base_vma < limit_vma)
5741 bfd_vma next_vma = limit_vma;
5742 asection *nsec;
5743 asection *sec;
5744 flagword flags;
5745 char *nname = NULL;
5747 /* Find a section covering base_vma. */
5748 for (sec = abfd->sections; sec != NULL; sec = sec->next)
5750 if ((sec->flags & (SEC_ALLOC | SEC_LOAD)) == 0)
5751 continue;
5752 if (sec->vma <= base_vma && sec->vma + sec->size > base_vma)
5754 base_vma = sec->vma + sec->size;
5755 goto again;
5757 if (sec->vma < next_vma && sec->vma + sec->size >= base_vma)
5758 next_vma = sec->vma;
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)
5765 flags |= SEC_CODE;
5766 if (num_text++ == 0)
5767 nname = ".text";
5768 else
5769 sprintf (name, ".text$%u", num_text);
5771 else if ((i_phdr->p_flags & (PF_R | PF_W)) == PF_R)
5773 flags |= SEC_READONLY;
5774 sprintf (name, ".rodata$%u", num_rodata++);
5776 else
5778 flags |= SEC_DATA;
5779 sprintf (name, ".data$%u", num_data++);
5782 /* Allocate name. */
5783 if (nname == NULL)
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);
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);
5800 base_vma = next_vma;
5803 return TRUE;
5806 static void
5807 elfNN_vms_post_process_headers (bfd *abfd,
5808 struct bfd_link_info *info ATTRIBUTE_UNUSED)
5810 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
5812 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_OPENVMS;
5813 i_ehdrp->e_ident[EI_ABIVERSION] = 2;
5816 static bfd_boolean
5817 elfNN_vms_section_processing (bfd *abfd ATTRIBUTE_UNUSED,
5818 Elf_Internal_Shdr *hdr)
5820 if (hdr->bfd_section != NULL)
5822 const char *name = bfd_get_section_name (abfd, hdr->bfd_section);
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)
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;
5849 symcount = bfd_get_symcount (abfd);
5850 syms = bfd_get_outsymbols (abfd);
5851 for (idx = 0; idx < symcount; idx++)
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))
5859 demangler_sym_idx = sym->udata.i;
5860 break;
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;
5869 /* Find symtab index of demangler routine and stuff it in
5870 the second long word of section data. */
5872 if (demangler_sym_idx > -1)
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);
5883 return TRUE;
5886 /* The final processing done just before writing out a VMS IA-64 ELF
5887 object file. */
5889 static void
5890 elfNN_vms_final_write_processing (bfd *abfd,
5891 bfd_boolean linker ATTRIBUTE_UNUSED)
5893 Elf_Internal_Shdr *hdr;
5894 asection *s;
5895 int unwind_info_sect_idx = 0;
5897 for (s = abfd->sections; s; s = s->next)
5899 hdr = &elf_section_data (s)->this_hdr;
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;
5905 switch (hdr->sh_type)
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;
5914 if (! elf_flags_init (abfd))
5916 unsigned long flags = 0;
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;
5923 elf_elfheader(abfd)->e_flags = flags;
5924 elf_flags_init (abfd) = TRUE;
5928 static bfd_boolean
5929 elfNN_vms_close_and_cleanup (bfd *abfd)
5931 if (bfd_get_format (abfd) == bfd_object)
5933 long isize, irsize;
5935 if (elf_shstrtab (abfd) != NULL)
5936 _bfd_elf_strtab_free (elf_shstrtab (abfd));
5938 /* Pad to 8 byte boundary for IPF/VMS. */
5939 isize = bfd_get_size (abfd);
5940 if ((irsize = isize/8*8) < isize)
5942 int ishort = (irsize + 8) - isize;
5943 bfd_seek (abfd, isize, SEEK_SET);
5944 bfd_bwrite (bfd_zmalloc (ishort), ishort, abfd);
5948 return _bfd_generic_close_and_cleanup (abfd);
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 */
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
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
5990 #define elf_backend_object_p \
5991 elfNN_ia64_object_p
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
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
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
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
6048 #include "elfNN-target.h"
6050 /* HPUX-specific vectors. */
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"
6059 /* These are HP-UX specific functions. */
6061 #undef elf_backend_post_process_headers
6062 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
6064 #undef elf_backend_section_from_bfd_section
6065 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
6067 #undef elf_backend_symbol_processing
6068 #define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
6070 #undef elf_backend_want_p_paddr_set_to_zero
6071 #define elf_backend_want_p_paddr_set_to_zero 1
6073 #undef ELF_COMMONPAGESIZE
6074 #undef ELF_OSABI
6075 #define ELF_OSABI ELFOSABI_HPUX
6077 #undef elfNN_bed
6078 #define elfNN_bed elfNN_ia64_hpux_bed
6080 #include "elfNN-target.h"
6082 /* VMS-specific vectors. */
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
6091 /* These are VMS specific functions. */
6093 #undef elf_backend_object_p
6094 #define elf_backend_object_p elfNN_vms_object_p
6096 #undef elf_backend_section_from_shdr
6097 #define elf_backend_section_from_shdr elfNN_vms_section_from_shdr
6099 #undef elf_backend_post_process_headers
6100 #define elf_backend_post_process_headers elfNN_vms_post_process_headers
6102 #undef elf_backend_section_processing
6103 #define elf_backend_section_processing elfNN_vms_section_processing
6105 #undef elf_backend_final_write_processing
6106 #define elf_backend_final_write_processing elfNN_vms_final_write_processing
6108 #undef bfd_elfNN_close_and_cleanup
6109 #define bfd_elfNN_close_and_cleanup elfNN_vms_close_and_cleanup
6111 #undef elf_backend_section_from_bfd_section
6113 #undef elf_backend_symbol_processing
6115 #undef elf_backend_want_p_paddr_set_to_zero
6117 #undef ELF_OSABI
6118 #define ELF_OSABI ELFOSABI_OPENVMS
6120 #undef ELF_MAXPAGESIZE
6121 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
6123 #undef elfNN_bed
6124 #define elfNN_bed elfNN_ia64_vms_bed
6126 #include "elfNN-target.h"