* gas/config/tc-arm.c (do_vfp_reg2_from_sp2): Rename from
[binutils.git] / bfd / elfxx-ia64.c
blobc699922154dd5aebac4928128587b8723b3ee1b3
1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "elf-bfd.h"
25 #include "opcode/ia64.h"
26 #include "elf/ia64.h"
27 #include "objalloc.h"
28 #include "hashtab.h"
30 /* THE RULES for all the stuff the linker creates --
32 GOT Entries created in response to LTOFF or LTOFF_FPTR
33 relocations. Dynamic relocs created for dynamic
34 symbols in an application; REL relocs for locals
35 in a shared library.
37 FPTR The canonical function descriptor. Created for local
38 symbols in applications. Descriptors for dynamic symbols
39 and local symbols in shared libraries are created by
40 ld.so. Thus there are no dynamic relocs against these
41 objects. The FPTR relocs for such _are_ passed through
42 to the dynamic relocation tables.
44 FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
45 Requires the creation of a PLTOFF entry. This does not
46 require any dynamic relocations.
48 PLTOFF Created by PLTOFF relocations. For local symbols, this
49 is an alternate function descriptor, and in shared libraries
50 requires two REL relocations. Note that this cannot be
51 transformed into an FPTR relocation, since it must be in
52 range of the GP. For dynamic symbols, this is a function
53 descriptor for a MIN_PLT entry, and requires one IPLT reloc.
55 MIN_PLT Created by PLTOFF entries against dynamic symbols. This
56 does not require dynamic relocations. */
58 #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
60 typedef struct bfd_hash_entry *(*new_hash_entry_func)
61 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
63 /* In dynamically (linker-) created sections, we generally need to keep track
64 of the place a symbol or expression got allocated to. This is done via hash
65 tables that store entries of the following type. */
67 struct elfNN_ia64_dyn_sym_info
69 /* The addend for which this entry is relevant. */
70 bfd_vma addend;
72 /* Next addend in the list. */
73 struct elfNN_ia64_dyn_sym_info *next;
75 bfd_vma got_offset;
76 bfd_vma fptr_offset;
77 bfd_vma pltoff_offset;
78 bfd_vma plt_offset;
79 bfd_vma plt2_offset;
80 bfd_vma tprel_offset;
81 bfd_vma dtpmod_offset;
82 bfd_vma dtprel_offset;
84 /* The symbol table entry, if any, that this was derived from. */
85 struct elf_link_hash_entry *h;
87 /* Used to count non-got, non-plt relocations for delayed sizing
88 of relocation sections. */
89 struct elfNN_ia64_dyn_reloc_entry
91 struct elfNN_ia64_dyn_reloc_entry *next;
92 asection *srel;
93 int type;
94 int count;
95 } *reloc_entries;
97 /* TRUE when the section contents have been updated. */
98 unsigned got_done : 1;
99 unsigned fptr_done : 1;
100 unsigned pltoff_done : 1;
101 unsigned tprel_done : 1;
102 unsigned dtpmod_done : 1;
103 unsigned dtprel_done : 1;
105 /* TRUE for the different kinds of linker data we want created. */
106 unsigned want_got : 1;
107 unsigned want_gotx : 1;
108 unsigned want_fptr : 1;
109 unsigned want_ltoff_fptr : 1;
110 unsigned want_plt : 1;
111 unsigned want_plt2 : 1;
112 unsigned want_pltoff : 1;
113 unsigned want_tprel : 1;
114 unsigned want_dtpmod : 1;
115 unsigned want_dtprel : 1;
118 struct elfNN_ia64_local_hash_entry
120 int id;
121 unsigned int r_sym;
122 struct elfNN_ia64_dyn_sym_info *info;
124 /* TRUE if this hash entry's addends was translated for
125 SHF_MERGE optimization. */
126 unsigned sec_merge_done : 1;
129 struct elfNN_ia64_link_hash_entry
131 struct elf_link_hash_entry root;
132 struct elfNN_ia64_dyn_sym_info *info;
135 struct elfNN_ia64_link_hash_table
137 /* The main hash table. */
138 struct elf_link_hash_table root;
140 asection *got_sec; /* the linkage table section (or NULL) */
141 asection *rel_got_sec; /* dynamic relocation section for same */
142 asection *fptr_sec; /* function descriptor table (or NULL) */
143 asection *rel_fptr_sec; /* dynamic relocation section for same */
144 asection *plt_sec; /* the primary plt section (or NULL) */
145 asection *pltoff_sec; /* private descriptors for plt (or NULL) */
146 asection *rel_pltoff_sec; /* dynamic relocation section for same */
148 bfd_size_type minplt_entries; /* number of minplt entries */
149 unsigned reltext : 1; /* are there relocs against readonly sections? */
150 unsigned self_dtpmod_done : 1;/* has self DTPMOD entry been finished? */
151 bfd_vma self_dtpmod_offset; /* .got offset to self DTPMOD entry */
153 htab_t loc_hash_table;
154 void *loc_hash_memory;
157 struct elfNN_ia64_allocate_data
159 struct bfd_link_info *info;
160 bfd_size_type ofs;
163 #define elfNN_ia64_hash_table(p) \
164 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
166 static bfd_reloc_status_type elfNN_ia64_reloc
167 PARAMS ((bfd *abfd, arelent *reloc, asymbol *sym, PTR data,
168 asection *input_section, bfd *output_bfd, char **error_message));
169 static reloc_howto_type * lookup_howto
170 PARAMS ((unsigned int rtype));
171 static reloc_howto_type *elfNN_ia64_reloc_type_lookup
172 PARAMS ((bfd *abfd, bfd_reloc_code_real_type bfd_code));
173 static void elfNN_ia64_info_to_howto
174 PARAMS ((bfd *abfd, arelent *bfd_reloc, Elf_Internal_Rela *elf_reloc));
175 static bfd_boolean elfNN_ia64_relax_section
176 PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
177 bfd_boolean *again));
178 static void elfNN_ia64_relax_ldxmov
179 PARAMS((bfd *abfd, bfd_byte *contents, bfd_vma off));
180 static bfd_boolean is_unwind_section_name
181 PARAMS ((bfd *abfd, const char *));
182 static bfd_boolean elfNN_ia64_section_from_shdr
183 PARAMS ((bfd *, Elf_Internal_Shdr *, const char *));
184 static bfd_boolean elfNN_ia64_section_flags
185 PARAMS ((flagword *, Elf_Internal_Shdr *));
186 static bfd_boolean elfNN_ia64_fake_sections
187 PARAMS ((bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec));
188 static void elfNN_ia64_final_write_processing
189 PARAMS ((bfd *abfd, bfd_boolean linker));
190 static bfd_boolean elfNN_ia64_add_symbol_hook
191 PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
192 const char **namep, flagword *flagsp, asection **secp,
193 bfd_vma *valp));
194 static int elfNN_ia64_additional_program_headers
195 PARAMS ((bfd *abfd));
196 static bfd_boolean elfNN_ia64_modify_segment_map
197 PARAMS ((bfd *, struct bfd_link_info *));
198 static bfd_boolean elfNN_ia64_is_local_label_name
199 PARAMS ((bfd *abfd, const char *name));
200 static bfd_boolean elfNN_ia64_dynamic_symbol_p
201 PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info, int));
202 static struct bfd_hash_entry *elfNN_ia64_new_elf_hash_entry
203 PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
204 const char *string));
205 static void elfNN_ia64_hash_copy_indirect
206 PARAMS ((const struct elf_backend_data *, struct elf_link_hash_entry *,
207 struct elf_link_hash_entry *));
208 static void elfNN_ia64_hash_hide_symbol
209 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean));
210 static hashval_t elfNN_ia64_local_htab_hash PARAMS ((const void *));
211 static int elfNN_ia64_local_htab_eq PARAMS ((const void *ptr1,
212 const void *ptr2));
213 static struct bfd_link_hash_table *elfNN_ia64_hash_table_create
214 PARAMS ((bfd *abfd));
215 static void elfNN_ia64_hash_table_free
216 PARAMS ((struct bfd_link_hash_table *hash));
217 static bfd_boolean elfNN_ia64_global_dyn_sym_thunk
218 PARAMS ((struct bfd_hash_entry *, PTR));
219 static int elfNN_ia64_local_dyn_sym_thunk
220 PARAMS ((void **, PTR));
221 static void elfNN_ia64_dyn_sym_traverse
222 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
223 bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
224 PTR info));
225 static bfd_boolean elfNN_ia64_create_dynamic_sections
226 PARAMS ((bfd *abfd, struct bfd_link_info *info));
227 static struct elfNN_ia64_local_hash_entry * get_local_sym_hash
228 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
229 bfd *abfd, const Elf_Internal_Rela *rel, bfd_boolean create));
230 static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
231 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
232 struct elf_link_hash_entry *h,
233 bfd *abfd, const Elf_Internal_Rela *rel, bfd_boolean create));
234 static asection *get_got
235 PARAMS ((bfd *abfd, struct bfd_link_info *info,
236 struct elfNN_ia64_link_hash_table *ia64_info));
237 static asection *get_fptr
238 PARAMS ((bfd *abfd, struct bfd_link_info *info,
239 struct elfNN_ia64_link_hash_table *ia64_info));
240 static asection *get_pltoff
241 PARAMS ((bfd *abfd, struct bfd_link_info *info,
242 struct elfNN_ia64_link_hash_table *ia64_info));
243 static asection *get_reloc_section
244 PARAMS ((bfd *abfd, struct elfNN_ia64_link_hash_table *ia64_info,
245 asection *sec, bfd_boolean create));
246 static bfd_boolean count_dyn_reloc
247 PARAMS ((bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
248 asection *srel, int type));
249 static bfd_boolean elfNN_ia64_check_relocs
250 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
251 const Elf_Internal_Rela *relocs));
252 static bfd_boolean elfNN_ia64_adjust_dynamic_symbol
253 PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
254 static long global_sym_index
255 PARAMS ((struct elf_link_hash_entry *h));
256 static bfd_boolean allocate_fptr
257 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
258 static bfd_boolean allocate_global_data_got
259 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
260 static bfd_boolean allocate_global_fptr_got
261 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
262 static bfd_boolean allocate_local_got
263 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
264 static bfd_boolean allocate_pltoff_entries
265 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
266 static bfd_boolean allocate_plt_entries
267 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
268 static bfd_boolean allocate_plt2_entries
269 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
270 static bfd_boolean allocate_dynrel_entries
271 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
272 static bfd_boolean elfNN_ia64_size_dynamic_sections
273 PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
274 static bfd_reloc_status_type elfNN_ia64_install_value
275 PARAMS ((bfd *abfd, bfd_byte *hit_addr, bfd_vma val, unsigned int r_type));
276 static void elfNN_ia64_install_dyn_reloc
277 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
278 asection *srel, bfd_vma offset, unsigned int type,
279 long dynindx, bfd_vma addend));
280 static bfd_vma set_got_entry
281 PARAMS ((bfd *abfd, struct bfd_link_info *info,
282 struct elfNN_ia64_dyn_sym_info *dyn_i, long dynindx,
283 bfd_vma addend, bfd_vma value, unsigned int dyn_r_type));
284 static bfd_vma set_fptr_entry
285 PARAMS ((bfd *abfd, struct bfd_link_info *info,
286 struct elfNN_ia64_dyn_sym_info *dyn_i,
287 bfd_vma value));
288 static bfd_vma set_pltoff_entry
289 PARAMS ((bfd *abfd, struct bfd_link_info *info,
290 struct elfNN_ia64_dyn_sym_info *dyn_i,
291 bfd_vma value, bfd_boolean));
292 static bfd_vma elfNN_ia64_tprel_base
293 PARAMS ((struct bfd_link_info *info));
294 static bfd_vma elfNN_ia64_dtprel_base
295 PARAMS ((struct bfd_link_info *info));
296 static int elfNN_ia64_unwind_entry_compare
297 PARAMS ((const PTR, const PTR));
298 static bfd_boolean elfNN_ia64_choose_gp
299 PARAMS ((bfd *abfd, struct bfd_link_info *info));
300 static bfd_boolean elfNN_ia64_final_link
301 PARAMS ((bfd *abfd, struct bfd_link_info *info));
302 static bfd_boolean elfNN_ia64_relocate_section
303 PARAMS ((bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
304 asection *input_section, bfd_byte *contents,
305 Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms,
306 asection **local_sections));
307 static bfd_boolean elfNN_ia64_finish_dynamic_symbol
308 PARAMS ((bfd *output_bfd, struct bfd_link_info *info,
309 struct elf_link_hash_entry *h, Elf_Internal_Sym *sym));
310 static bfd_boolean elfNN_ia64_finish_dynamic_sections
311 PARAMS ((bfd *abfd, struct bfd_link_info *info));
312 static bfd_boolean elfNN_ia64_set_private_flags
313 PARAMS ((bfd *abfd, flagword flags));
314 static bfd_boolean elfNN_ia64_merge_private_bfd_data
315 PARAMS ((bfd *ibfd, bfd *obfd));
316 static bfd_boolean elfNN_ia64_print_private_bfd_data
317 PARAMS ((bfd *abfd, PTR ptr));
318 static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
319 PARAMS ((const Elf_Internal_Rela *));
320 static bfd_boolean elfNN_ia64_hpux_vec
321 PARAMS ((const bfd_target *vec));
322 static void elfNN_hpux_post_process_headers
323 PARAMS ((bfd *abfd, struct bfd_link_info *info));
324 bfd_boolean elfNN_hpux_backend_section_from_bfd_section
325 PARAMS ((bfd *abfd, asection *sec, int *retval));
327 /* ia64-specific relocation. */
329 /* Perform a relocation. Not much to do here as all the hard work is
330 done in elfNN_ia64_final_link_relocate. */
331 static bfd_reloc_status_type
332 elfNN_ia64_reloc (abfd, reloc, sym, data, input_section,
333 output_bfd, error_message)
334 bfd *abfd ATTRIBUTE_UNUSED;
335 arelent *reloc;
336 asymbol *sym ATTRIBUTE_UNUSED;
337 PTR data ATTRIBUTE_UNUSED;
338 asection *input_section;
339 bfd *output_bfd;
340 char **error_message;
342 if (output_bfd)
344 reloc->address += input_section->output_offset;
345 return bfd_reloc_ok;
348 if (input_section->flags & SEC_DEBUGGING)
349 return bfd_reloc_continue;
351 *error_message = "Unsupported call to elfNN_ia64_reloc";
352 return bfd_reloc_notsupported;
355 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
356 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
357 elfNN_ia64_reloc, NAME, FALSE, 0, -1, IN)
359 /* This table has to be sorted according to increasing number of the
360 TYPE field. */
361 static reloc_howto_type ia64_howto_table[] =
363 IA64_HOWTO (R_IA64_NONE, "NONE", 0, FALSE, TRUE),
365 IA64_HOWTO (R_IA64_IMM14, "IMM14", 0, FALSE, TRUE),
366 IA64_HOWTO (R_IA64_IMM22, "IMM22", 0, FALSE, TRUE),
367 IA64_HOWTO (R_IA64_IMM64, "IMM64", 0, FALSE, TRUE),
368 IA64_HOWTO (R_IA64_DIR32MSB, "DIR32MSB", 2, FALSE, TRUE),
369 IA64_HOWTO (R_IA64_DIR32LSB, "DIR32LSB", 2, FALSE, TRUE),
370 IA64_HOWTO (R_IA64_DIR64MSB, "DIR64MSB", 4, FALSE, TRUE),
371 IA64_HOWTO (R_IA64_DIR64LSB, "DIR64LSB", 4, FALSE, TRUE),
373 IA64_HOWTO (R_IA64_GPREL22, "GPREL22", 0, FALSE, TRUE),
374 IA64_HOWTO (R_IA64_GPREL64I, "GPREL64I", 0, FALSE, TRUE),
375 IA64_HOWTO (R_IA64_GPREL32MSB, "GPREL32MSB", 2, FALSE, TRUE),
376 IA64_HOWTO (R_IA64_GPREL32LSB, "GPREL32LSB", 2, FALSE, TRUE),
377 IA64_HOWTO (R_IA64_GPREL64MSB, "GPREL64MSB", 4, FALSE, TRUE),
378 IA64_HOWTO (R_IA64_GPREL64LSB, "GPREL64LSB", 4, FALSE, TRUE),
380 IA64_HOWTO (R_IA64_LTOFF22, "LTOFF22", 0, FALSE, TRUE),
381 IA64_HOWTO (R_IA64_LTOFF64I, "LTOFF64I", 0, FALSE, TRUE),
383 IA64_HOWTO (R_IA64_PLTOFF22, "PLTOFF22", 0, FALSE, TRUE),
384 IA64_HOWTO (R_IA64_PLTOFF64I, "PLTOFF64I", 0, FALSE, TRUE),
385 IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, FALSE, TRUE),
386 IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, FALSE, TRUE),
388 IA64_HOWTO (R_IA64_FPTR64I, "FPTR64I", 0, FALSE, TRUE),
389 IA64_HOWTO (R_IA64_FPTR32MSB, "FPTR32MSB", 2, FALSE, TRUE),
390 IA64_HOWTO (R_IA64_FPTR32LSB, "FPTR32LSB", 2, FALSE, TRUE),
391 IA64_HOWTO (R_IA64_FPTR64MSB, "FPTR64MSB", 4, FALSE, TRUE),
392 IA64_HOWTO (R_IA64_FPTR64LSB, "FPTR64LSB", 4, FALSE, TRUE),
394 IA64_HOWTO (R_IA64_PCREL60B, "PCREL60B", 0, TRUE, TRUE),
395 IA64_HOWTO (R_IA64_PCREL21B, "PCREL21B", 0, TRUE, TRUE),
396 IA64_HOWTO (R_IA64_PCREL21M, "PCREL21M", 0, TRUE, TRUE),
397 IA64_HOWTO (R_IA64_PCREL21F, "PCREL21F", 0, TRUE, TRUE),
398 IA64_HOWTO (R_IA64_PCREL32MSB, "PCREL32MSB", 2, TRUE, TRUE),
399 IA64_HOWTO (R_IA64_PCREL32LSB, "PCREL32LSB", 2, TRUE, TRUE),
400 IA64_HOWTO (R_IA64_PCREL64MSB, "PCREL64MSB", 4, TRUE, TRUE),
401 IA64_HOWTO (R_IA64_PCREL64LSB, "PCREL64LSB", 4, TRUE, TRUE),
403 IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, FALSE, TRUE),
404 IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, FALSE, TRUE),
405 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB, "LTOFF_FPTR32MSB", 2, FALSE, TRUE),
406 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB, "LTOFF_FPTR32LSB", 2, FALSE, TRUE),
407 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, FALSE, TRUE),
408 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, FALSE, TRUE),
410 IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, FALSE, TRUE),
411 IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, FALSE, TRUE),
412 IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, FALSE, TRUE),
413 IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, FALSE, TRUE),
415 IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, FALSE, TRUE),
416 IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, FALSE, TRUE),
417 IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, FALSE, TRUE),
418 IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, FALSE, TRUE),
420 IA64_HOWTO (R_IA64_REL32MSB, "REL32MSB", 2, FALSE, TRUE),
421 IA64_HOWTO (R_IA64_REL32LSB, "REL32LSB", 2, FALSE, TRUE),
422 IA64_HOWTO (R_IA64_REL64MSB, "REL64MSB", 4, FALSE, TRUE),
423 IA64_HOWTO (R_IA64_REL64LSB, "REL64LSB", 4, FALSE, TRUE),
425 IA64_HOWTO (R_IA64_LTV32MSB, "LTV32MSB", 2, FALSE, TRUE),
426 IA64_HOWTO (R_IA64_LTV32LSB, "LTV32LSB", 2, FALSE, TRUE),
427 IA64_HOWTO (R_IA64_LTV64MSB, "LTV64MSB", 4, FALSE, TRUE),
428 IA64_HOWTO (R_IA64_LTV64LSB, "LTV64LSB", 4, FALSE, TRUE),
430 IA64_HOWTO (R_IA64_PCREL21BI, "PCREL21BI", 0, TRUE, TRUE),
431 IA64_HOWTO (R_IA64_PCREL22, "PCREL22", 0, TRUE, TRUE),
432 IA64_HOWTO (R_IA64_PCREL64I, "PCREL64I", 0, TRUE, TRUE),
434 IA64_HOWTO (R_IA64_IPLTMSB, "IPLTMSB", 4, FALSE, TRUE),
435 IA64_HOWTO (R_IA64_IPLTLSB, "IPLTLSB", 4, FALSE, TRUE),
436 IA64_HOWTO (R_IA64_COPY, "COPY", 4, FALSE, TRUE),
437 IA64_HOWTO (R_IA64_LTOFF22X, "LTOFF22X", 0, FALSE, TRUE),
438 IA64_HOWTO (R_IA64_LDXMOV, "LDXMOV", 0, FALSE, TRUE),
440 IA64_HOWTO (R_IA64_TPREL14, "TPREL14", 0, FALSE, FALSE),
441 IA64_HOWTO (R_IA64_TPREL22, "TPREL22", 0, FALSE, FALSE),
442 IA64_HOWTO (R_IA64_TPREL64I, "TPREL64I", 0, FALSE, FALSE),
443 IA64_HOWTO (R_IA64_TPREL64MSB, "TPREL64MSB", 4, FALSE, FALSE),
444 IA64_HOWTO (R_IA64_TPREL64LSB, "TPREL64LSB", 4, FALSE, FALSE),
445 IA64_HOWTO (R_IA64_LTOFF_TPREL22, "LTOFF_TPREL22", 0, FALSE, FALSE),
447 IA64_HOWTO (R_IA64_DTPMOD64MSB, "TPREL64MSB", 4, FALSE, FALSE),
448 IA64_HOWTO (R_IA64_DTPMOD64LSB, "TPREL64LSB", 4, FALSE, FALSE),
449 IA64_HOWTO (R_IA64_LTOFF_DTPMOD22, "LTOFF_DTPMOD22", 0, FALSE, FALSE),
451 IA64_HOWTO (R_IA64_DTPREL14, "DTPREL14", 0, FALSE, FALSE),
452 IA64_HOWTO (R_IA64_DTPREL22, "DTPREL22", 0, FALSE, FALSE),
453 IA64_HOWTO (R_IA64_DTPREL64I, "DTPREL64I", 0, FALSE, FALSE),
454 IA64_HOWTO (R_IA64_DTPREL32MSB, "DTPREL32MSB", 2, FALSE, FALSE),
455 IA64_HOWTO (R_IA64_DTPREL32LSB, "DTPREL32LSB", 2, FALSE, FALSE),
456 IA64_HOWTO (R_IA64_DTPREL64MSB, "DTPREL64MSB", 4, FALSE, FALSE),
457 IA64_HOWTO (R_IA64_DTPREL64LSB, "DTPREL64LSB", 4, FALSE, FALSE),
458 IA64_HOWTO (R_IA64_LTOFF_DTPREL22, "LTOFF_DTPREL22", 0, FALSE, FALSE),
461 static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
463 /* Given a BFD reloc type, return the matching HOWTO structure. */
465 static reloc_howto_type *
466 lookup_howto (rtype)
467 unsigned int rtype;
469 static int inited = 0;
470 int i;
472 if (!inited)
474 inited = 1;
476 memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
477 for (i = 0; i < NELEMS (ia64_howto_table); ++i)
478 elf_code_to_howto_index[ia64_howto_table[i].type] = i;
481 BFD_ASSERT (rtype <= R_IA64_MAX_RELOC_CODE);
482 i = elf_code_to_howto_index[rtype];
483 if (i >= NELEMS (ia64_howto_table))
484 return 0;
485 return ia64_howto_table + i;
488 static reloc_howto_type*
489 elfNN_ia64_reloc_type_lookup (abfd, bfd_code)
490 bfd *abfd ATTRIBUTE_UNUSED;
491 bfd_reloc_code_real_type bfd_code;
493 unsigned int rtype;
495 switch (bfd_code)
497 case BFD_RELOC_NONE: rtype = R_IA64_NONE; break;
499 case BFD_RELOC_IA64_IMM14: rtype = R_IA64_IMM14; break;
500 case BFD_RELOC_IA64_IMM22: rtype = R_IA64_IMM22; break;
501 case BFD_RELOC_IA64_IMM64: rtype = R_IA64_IMM64; break;
503 case BFD_RELOC_IA64_DIR32MSB: rtype = R_IA64_DIR32MSB; break;
504 case BFD_RELOC_IA64_DIR32LSB: rtype = R_IA64_DIR32LSB; break;
505 case BFD_RELOC_IA64_DIR64MSB: rtype = R_IA64_DIR64MSB; break;
506 case BFD_RELOC_IA64_DIR64LSB: rtype = R_IA64_DIR64LSB; break;
508 case BFD_RELOC_IA64_GPREL22: rtype = R_IA64_GPREL22; break;
509 case BFD_RELOC_IA64_GPREL64I: rtype = R_IA64_GPREL64I; break;
510 case BFD_RELOC_IA64_GPREL32MSB: rtype = R_IA64_GPREL32MSB; break;
511 case BFD_RELOC_IA64_GPREL32LSB: rtype = R_IA64_GPREL32LSB; break;
512 case BFD_RELOC_IA64_GPREL64MSB: rtype = R_IA64_GPREL64MSB; break;
513 case BFD_RELOC_IA64_GPREL64LSB: rtype = R_IA64_GPREL64LSB; break;
515 case BFD_RELOC_IA64_LTOFF22: rtype = R_IA64_LTOFF22; break;
516 case BFD_RELOC_IA64_LTOFF64I: rtype = R_IA64_LTOFF64I; break;
518 case BFD_RELOC_IA64_PLTOFF22: rtype = R_IA64_PLTOFF22; break;
519 case BFD_RELOC_IA64_PLTOFF64I: rtype = R_IA64_PLTOFF64I; break;
520 case BFD_RELOC_IA64_PLTOFF64MSB: rtype = R_IA64_PLTOFF64MSB; break;
521 case BFD_RELOC_IA64_PLTOFF64LSB: rtype = R_IA64_PLTOFF64LSB; break;
522 case BFD_RELOC_IA64_FPTR64I: rtype = R_IA64_FPTR64I; break;
523 case BFD_RELOC_IA64_FPTR32MSB: rtype = R_IA64_FPTR32MSB; break;
524 case BFD_RELOC_IA64_FPTR32LSB: rtype = R_IA64_FPTR32LSB; break;
525 case BFD_RELOC_IA64_FPTR64MSB: rtype = R_IA64_FPTR64MSB; break;
526 case BFD_RELOC_IA64_FPTR64LSB: rtype = R_IA64_FPTR64LSB; break;
528 case BFD_RELOC_IA64_PCREL21B: rtype = R_IA64_PCREL21B; break;
529 case BFD_RELOC_IA64_PCREL21BI: rtype = R_IA64_PCREL21BI; break;
530 case BFD_RELOC_IA64_PCREL21M: rtype = R_IA64_PCREL21M; break;
531 case BFD_RELOC_IA64_PCREL21F: rtype = R_IA64_PCREL21F; break;
532 case BFD_RELOC_IA64_PCREL22: rtype = R_IA64_PCREL22; break;
533 case BFD_RELOC_IA64_PCREL60B: rtype = R_IA64_PCREL60B; break;
534 case BFD_RELOC_IA64_PCREL64I: rtype = R_IA64_PCREL64I; break;
535 case BFD_RELOC_IA64_PCREL32MSB: rtype = R_IA64_PCREL32MSB; break;
536 case BFD_RELOC_IA64_PCREL32LSB: rtype = R_IA64_PCREL32LSB; break;
537 case BFD_RELOC_IA64_PCREL64MSB: rtype = R_IA64_PCREL64MSB; break;
538 case BFD_RELOC_IA64_PCREL64LSB: rtype = R_IA64_PCREL64LSB; break;
540 case BFD_RELOC_IA64_LTOFF_FPTR22: rtype = R_IA64_LTOFF_FPTR22; break;
541 case BFD_RELOC_IA64_LTOFF_FPTR64I: rtype = R_IA64_LTOFF_FPTR64I; break;
542 case BFD_RELOC_IA64_LTOFF_FPTR32MSB: rtype = R_IA64_LTOFF_FPTR32MSB; break;
543 case BFD_RELOC_IA64_LTOFF_FPTR32LSB: rtype = R_IA64_LTOFF_FPTR32LSB; break;
544 case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
545 case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
547 case BFD_RELOC_IA64_SEGREL32MSB: rtype = R_IA64_SEGREL32MSB; break;
548 case BFD_RELOC_IA64_SEGREL32LSB: rtype = R_IA64_SEGREL32LSB; break;
549 case BFD_RELOC_IA64_SEGREL64MSB: rtype = R_IA64_SEGREL64MSB; break;
550 case BFD_RELOC_IA64_SEGREL64LSB: rtype = R_IA64_SEGREL64LSB; break;
552 case BFD_RELOC_IA64_SECREL32MSB: rtype = R_IA64_SECREL32MSB; break;
553 case BFD_RELOC_IA64_SECREL32LSB: rtype = R_IA64_SECREL32LSB; break;
554 case BFD_RELOC_IA64_SECREL64MSB: rtype = R_IA64_SECREL64MSB; break;
555 case BFD_RELOC_IA64_SECREL64LSB: rtype = R_IA64_SECREL64LSB; break;
557 case BFD_RELOC_IA64_REL32MSB: rtype = R_IA64_REL32MSB; break;
558 case BFD_RELOC_IA64_REL32LSB: rtype = R_IA64_REL32LSB; break;
559 case BFD_RELOC_IA64_REL64MSB: rtype = R_IA64_REL64MSB; break;
560 case BFD_RELOC_IA64_REL64LSB: rtype = R_IA64_REL64LSB; break;
562 case BFD_RELOC_IA64_LTV32MSB: rtype = R_IA64_LTV32MSB; break;
563 case BFD_RELOC_IA64_LTV32LSB: rtype = R_IA64_LTV32LSB; break;
564 case BFD_RELOC_IA64_LTV64MSB: rtype = R_IA64_LTV64MSB; break;
565 case BFD_RELOC_IA64_LTV64LSB: rtype = R_IA64_LTV64LSB; break;
567 case BFD_RELOC_IA64_IPLTMSB: rtype = R_IA64_IPLTMSB; break;
568 case BFD_RELOC_IA64_IPLTLSB: rtype = R_IA64_IPLTLSB; break;
569 case BFD_RELOC_IA64_COPY: rtype = R_IA64_COPY; break;
570 case BFD_RELOC_IA64_LTOFF22X: rtype = R_IA64_LTOFF22X; break;
571 case BFD_RELOC_IA64_LDXMOV: rtype = R_IA64_LDXMOV; break;
573 case BFD_RELOC_IA64_TPREL14: rtype = R_IA64_TPREL14; break;
574 case BFD_RELOC_IA64_TPREL22: rtype = R_IA64_TPREL22; break;
575 case BFD_RELOC_IA64_TPREL64I: rtype = R_IA64_TPREL64I; break;
576 case BFD_RELOC_IA64_TPREL64MSB: rtype = R_IA64_TPREL64MSB; break;
577 case BFD_RELOC_IA64_TPREL64LSB: rtype = R_IA64_TPREL64LSB; break;
578 case BFD_RELOC_IA64_LTOFF_TPREL22: rtype = R_IA64_LTOFF_TPREL22; break;
580 case BFD_RELOC_IA64_DTPMOD64MSB: rtype = R_IA64_DTPMOD64MSB; break;
581 case BFD_RELOC_IA64_DTPMOD64LSB: rtype = R_IA64_DTPMOD64LSB; break;
582 case BFD_RELOC_IA64_LTOFF_DTPMOD22: rtype = R_IA64_LTOFF_DTPMOD22; break;
584 case BFD_RELOC_IA64_DTPREL14: rtype = R_IA64_DTPREL14; break;
585 case BFD_RELOC_IA64_DTPREL22: rtype = R_IA64_DTPREL22; break;
586 case BFD_RELOC_IA64_DTPREL64I: rtype = R_IA64_DTPREL64I; break;
587 case BFD_RELOC_IA64_DTPREL32MSB: rtype = R_IA64_DTPREL32MSB; break;
588 case BFD_RELOC_IA64_DTPREL32LSB: rtype = R_IA64_DTPREL32LSB; break;
589 case BFD_RELOC_IA64_DTPREL64MSB: rtype = R_IA64_DTPREL64MSB; break;
590 case BFD_RELOC_IA64_DTPREL64LSB: rtype = R_IA64_DTPREL64LSB; break;
591 case BFD_RELOC_IA64_LTOFF_DTPREL22: rtype = R_IA64_LTOFF_DTPREL22; break;
593 default: return 0;
595 return lookup_howto (rtype);
598 /* Given a ELF reloc, return the matching HOWTO structure. */
600 static void
601 elfNN_ia64_info_to_howto (abfd, bfd_reloc, elf_reloc)
602 bfd *abfd ATTRIBUTE_UNUSED;
603 arelent *bfd_reloc;
604 Elf_Internal_Rela *elf_reloc;
606 bfd_reloc->howto
607 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc->r_info));
610 #define PLT_HEADER_SIZE (3 * 16)
611 #define PLT_MIN_ENTRY_SIZE (1 * 16)
612 #define PLT_FULL_ENTRY_SIZE (2 * 16)
613 #define PLT_RESERVED_WORDS 3
615 static const bfd_byte plt_header[PLT_HEADER_SIZE] =
617 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
618 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
619 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
620 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
621 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
622 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
623 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
624 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
625 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
628 static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
630 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
631 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
632 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
635 static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
637 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
638 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
639 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
640 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
641 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
642 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
645 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
647 static const bfd_byte oor_brl[16] =
649 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
650 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
651 0x00, 0x00, 0x00, 0xc0
654 static const bfd_byte oor_ip[48] =
656 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
657 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
658 0x01, 0x00, 0x00, 0x60,
659 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
660 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
661 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
662 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
663 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
664 0x60, 0x00, 0x80, 0x00 /* br b6;; */
667 static size_t oor_branch_size = sizeof (oor_brl);
669 void
670 bfd_elfNN_ia64_after_parse (int itanium)
672 oor_branch_size = itanium ? sizeof (oor_ip) : sizeof (oor_brl);
676 /* These functions do relaxation for IA-64 ELF. */
678 static bfd_boolean
679 elfNN_ia64_relax_section (abfd, sec, link_info, again)
680 bfd *abfd;
681 asection *sec;
682 struct bfd_link_info *link_info;
683 bfd_boolean *again;
685 struct one_fixup
687 struct one_fixup *next;
688 asection *tsec;
689 bfd_vma toff;
690 bfd_vma trampoff;
693 Elf_Internal_Shdr *symtab_hdr;
694 Elf_Internal_Rela *internal_relocs;
695 Elf_Internal_Rela *irel, *irelend;
696 bfd_byte *contents;
697 Elf_Internal_Sym *isymbuf = NULL;
698 struct elfNN_ia64_link_hash_table *ia64_info;
699 struct one_fixup *fixups = NULL;
700 bfd_boolean changed_contents = FALSE;
701 bfd_boolean changed_relocs = FALSE;
702 bfd_boolean changed_got = FALSE;
703 bfd_vma gp = 0;
705 /* Assume we're not going to change any sizes, and we'll only need
706 one pass. */
707 *again = FALSE;
709 /* Don't even try to relax for non-ELF outputs. */
710 if (!is_elf_hash_table (link_info->hash))
711 return FALSE;
713 /* Nothing to do if there are no relocations or there is no need for
714 the relax finalize pass. */
715 if ((sec->flags & SEC_RELOC) == 0
716 || sec->reloc_count == 0
717 || (!link_info->need_relax_finalize
718 && sec->need_finalize_relax == 0))
719 return TRUE;
721 /* If this is the first time we have been called for this section,
722 initialize the cooked size. */
723 if (sec->_cooked_size == 0)
724 sec->_cooked_size = sec->_raw_size;
726 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
728 /* Load the relocations for this section. */
729 internal_relocs = (_bfd_elf_link_read_relocs
730 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
731 link_info->keep_memory));
732 if (internal_relocs == NULL)
733 return FALSE;
735 ia64_info = elfNN_ia64_hash_table (link_info);
736 irelend = internal_relocs + sec->reloc_count;
738 /* Get the section contents. */
739 if (elf_section_data (sec)->this_hdr.contents != NULL)
740 contents = elf_section_data (sec)->this_hdr.contents;
741 else
743 contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
744 if (contents == NULL)
745 goto error_return;
747 if (! bfd_get_section_contents (abfd, sec, contents,
748 (file_ptr) 0, sec->_raw_size))
749 goto error_return;
752 for (irel = internal_relocs; irel < irelend; irel++)
754 unsigned long r_type = ELFNN_R_TYPE (irel->r_info);
755 bfd_vma symaddr, reladdr, trampoff, toff, roff;
756 asection *tsec;
757 struct one_fixup *f;
758 bfd_size_type amt;
759 bfd_boolean is_branch;
760 struct elfNN_ia64_dyn_sym_info *dyn_i;
762 switch (r_type)
764 case R_IA64_PCREL21B:
765 case R_IA64_PCREL21BI:
766 case R_IA64_PCREL21M:
767 case R_IA64_PCREL21F:
768 if (!link_info->need_relax_finalize)
769 continue;
770 is_branch = TRUE;
771 break;
773 case R_IA64_LTOFF22X:
774 case R_IA64_LDXMOV:
775 if (link_info->need_relax_finalize)
777 sec->need_finalize_relax = 1;
778 continue;
780 is_branch = FALSE;
781 break;
783 default:
784 continue;
787 /* Get the value of the symbol referred to by the reloc. */
788 if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
790 /* A local symbol. */
791 Elf_Internal_Sym *isym;
793 /* Read this BFD's local symbols. */
794 if (isymbuf == NULL)
796 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
797 if (isymbuf == NULL)
798 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
799 symtab_hdr->sh_info, 0,
800 NULL, NULL, NULL);
801 if (isymbuf == 0)
802 goto error_return;
805 isym = isymbuf + ELFNN_R_SYM (irel->r_info);
806 if (isym->st_shndx == SHN_UNDEF)
807 continue; /* We can't do anything with undefined symbols. */
808 else if (isym->st_shndx == SHN_ABS)
809 tsec = bfd_abs_section_ptr;
810 else if (isym->st_shndx == SHN_COMMON)
811 tsec = bfd_com_section_ptr;
812 else if (isym->st_shndx == SHN_IA_64_ANSI_COMMON)
813 tsec = bfd_com_section_ptr;
814 else
815 tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
817 toff = isym->st_value;
818 dyn_i = get_dyn_sym_info (ia64_info, NULL, abfd, irel, FALSE);
820 else
822 unsigned long indx;
823 struct elf_link_hash_entry *h;
825 indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
826 h = elf_sym_hashes (abfd)[indx];
827 BFD_ASSERT (h != NULL);
829 while (h->root.type == bfd_link_hash_indirect
830 || h->root.type == bfd_link_hash_warning)
831 h = (struct elf_link_hash_entry *) h->root.u.i.link;
833 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, FALSE);
835 /* For branches to dynamic symbols, we're interested instead
836 in a branch to the PLT entry. */
837 if (is_branch && dyn_i && dyn_i->want_plt2)
839 /* Internal branches shouldn't be sent to the PLT.
840 Leave this for now and we'll give an error later. */
841 if (r_type != R_IA64_PCREL21B)
842 continue;
844 tsec = ia64_info->plt_sec;
845 toff = dyn_i->plt2_offset;
846 BFD_ASSERT (irel->r_addend == 0);
849 /* Can't do anything else with dynamic symbols. */
850 else if (elfNN_ia64_dynamic_symbol_p (h, link_info, r_type))
851 continue;
853 else
855 /* We can't do anything with undefined symbols. */
856 if (h->root.type == bfd_link_hash_undefined
857 || h->root.type == bfd_link_hash_undefweak)
858 continue;
860 tsec = h->root.u.def.section;
861 toff = h->root.u.def.value;
865 if (tsec->sec_info_type == ELF_INFO_TYPE_MERGE)
866 toff = _bfd_merged_section_offset (abfd, &tsec,
867 elf_section_data (tsec)->sec_info,
868 toff + irel->r_addend,
869 (bfd_vma) 0);
870 else
871 toff += irel->r_addend;
873 symaddr = tsec->output_section->vma + tsec->output_offset + toff;
875 roff = irel->r_offset;
877 if (is_branch)
879 bfd_signed_vma offset;
881 reladdr = (sec->output_section->vma
882 + sec->output_offset
883 + roff) & (bfd_vma) -4;
885 /* If the branch is in range, no need to do anything. */
886 if ((bfd_signed_vma) (symaddr - reladdr) >= -0x1000000
887 && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
888 continue;
890 /* If the branch and target are in the same section, you've
891 got one honking big section and we can't help you. You'll
892 get an error message later. */
893 if (tsec == sec)
894 continue;
896 /* Look for an existing fixup to this address. */
897 for (f = fixups; f ; f = f->next)
898 if (f->tsec == tsec && f->toff == toff)
899 break;
901 if (f == NULL)
903 /* Two alternatives: If it's a branch to a PLT entry, we can
904 make a copy of the FULL_PLT entry. Otherwise, we'll have
905 to use a `brl' insn to get where we're going. */
907 size_t size;
909 if (tsec == ia64_info->plt_sec)
910 size = sizeof (plt_full_entry);
911 else
912 size = oor_branch_size;
914 /* Resize the current section to make room for the new branch. */
915 trampoff = (sec->_cooked_size + 15) & (bfd_vma) -16;
917 /* If trampoline is out of range, there is nothing we
918 can do. */
919 offset = trampoff - (roff & (bfd_vma) -4);
920 if (offset < -0x1000000 || offset > 0x0FFFFF0)
921 continue;
923 amt = trampoff + size;
924 contents = (bfd_byte *) bfd_realloc (contents, amt);
925 if (contents == NULL)
926 goto error_return;
927 sec->_cooked_size = amt;
929 if (tsec == ia64_info->plt_sec)
931 memcpy (contents + trampoff, plt_full_entry, size);
933 /* Hijack the old relocation for use as the PLTOFF reloc. */
934 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
935 R_IA64_PLTOFF22);
936 irel->r_offset = trampoff;
938 else
940 if (size == sizeof (oor_ip))
942 memcpy (contents + trampoff, oor_ip, size);
943 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
944 R_IA64_PCREL64I);
945 irel->r_addend -= 16;
946 irel->r_offset = trampoff + 2;
948 else
950 memcpy (contents + trampoff, oor_brl, size);
951 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
952 R_IA64_PCREL60B);
953 irel->r_offset = trampoff + 2;
958 /* Record the fixup so we don't do it again this section. */
959 f = (struct one_fixup *)
960 bfd_malloc ((bfd_size_type) sizeof (*f));
961 f->next = fixups;
962 f->tsec = tsec;
963 f->toff = toff;
964 f->trampoff = trampoff;
965 fixups = f;
967 else
969 /* If trampoline is out of range, there is nothing we
970 can do. */
971 offset = f->trampoff - (roff & (bfd_vma) -4);
972 if (offset < -0x1000000 || offset > 0x0FFFFF0)
973 continue;
975 /* Nop out the reloc, since we're finalizing things here. */
976 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
979 /* Fix up the existing branch to hit the trampoline. */
980 if (elfNN_ia64_install_value (abfd, contents + roff, offset,
981 r_type) != bfd_reloc_ok)
982 goto error_return;
984 changed_contents = TRUE;
985 changed_relocs = TRUE;
987 else
989 /* Fetch the gp. */
990 if (gp == 0)
992 bfd *obfd = sec->output_section->owner;
993 gp = _bfd_get_gp_value (obfd);
994 if (gp == 0)
996 if (!elfNN_ia64_choose_gp (obfd, link_info))
997 goto error_return;
998 gp = _bfd_get_gp_value (obfd);
1002 /* If the data is out of range, do nothing. */
1003 if ((bfd_signed_vma) (symaddr - gp) >= 0x200000
1004 ||(bfd_signed_vma) (symaddr - gp) < -0x200000)
1005 continue;
1007 if (r_type == R_IA64_LTOFF22X)
1009 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
1010 R_IA64_GPREL22);
1011 changed_relocs = TRUE;
1012 if (dyn_i->want_gotx)
1014 dyn_i->want_gotx = 0;
1015 changed_got |= !dyn_i->want_got;
1018 else
1020 elfNN_ia64_relax_ldxmov (abfd, contents, roff);
1021 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
1022 changed_contents = TRUE;
1023 changed_relocs = TRUE;
1028 /* ??? If we created fixups, this may push the code segment large
1029 enough that the data segment moves, which will change the GP.
1030 Reset the GP so that we re-calculate next round. We need to
1031 do this at the _beginning_ of the next round; now will not do. */
1033 /* Clean up and go home. */
1034 while (fixups)
1036 struct one_fixup *f = fixups;
1037 fixups = fixups->next;
1038 free (f);
1041 if (isymbuf != NULL
1042 && symtab_hdr->contents != (unsigned char *) isymbuf)
1044 if (! link_info->keep_memory)
1045 free (isymbuf);
1046 else
1048 /* Cache the symbols for elf_link_input_bfd. */
1049 symtab_hdr->contents = (unsigned char *) isymbuf;
1053 if (contents != NULL
1054 && elf_section_data (sec)->this_hdr.contents != contents)
1056 if (!changed_contents && !link_info->keep_memory)
1057 free (contents);
1058 else
1060 /* Cache the section contents for elf_link_input_bfd. */
1061 elf_section_data (sec)->this_hdr.contents = contents;
1065 if (elf_section_data (sec)->relocs != internal_relocs)
1067 if (!changed_relocs)
1068 free (internal_relocs);
1069 else
1070 elf_section_data (sec)->relocs = internal_relocs;
1073 if (changed_got)
1075 struct elfNN_ia64_allocate_data data;
1076 data.info = link_info;
1077 data.ofs = 0;
1078 ia64_info->self_dtpmod_offset = (bfd_vma) -1;
1080 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
1081 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
1082 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
1083 ia64_info->got_sec->_raw_size = data.ofs;
1084 ia64_info->got_sec->_cooked_size = data.ofs;
1086 /* ??? Resize .rela.got too. */
1089 if (!link_info->need_relax_finalize)
1090 sec->need_finalize_relax = 0;
1092 *again = changed_contents || changed_relocs;
1093 return TRUE;
1095 error_return:
1096 if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
1097 free (isymbuf);
1098 if (contents != NULL
1099 && elf_section_data (sec)->this_hdr.contents != contents)
1100 free (contents);
1101 if (internal_relocs != NULL
1102 && elf_section_data (sec)->relocs != internal_relocs)
1103 free (internal_relocs);
1104 return FALSE;
1107 static void
1108 elfNN_ia64_relax_ldxmov (abfd, contents, off)
1109 bfd *abfd;
1110 bfd_byte *contents;
1111 bfd_vma off;
1113 int shift, r1, r3;
1114 bfd_vma dword, insn;
1116 switch ((int)off & 0x3)
1118 case 0: shift = 5; break;
1119 case 1: shift = 14; off += 3; break;
1120 case 2: shift = 23; off += 6; break;
1121 default:
1122 abort ();
1125 dword = bfd_get_64 (abfd, contents + off);
1126 insn = (dword >> shift) & 0x1ffffffffffLL;
1128 r1 = (insn >> 6) & 127;
1129 r3 = (insn >> 20) & 127;
1130 if (r1 == r3)
1131 insn = 0x8000000; /* nop */
1132 else
1133 insn = (insn & 0x7f01fff) | 0x10800000000LL; /* (qp) mov r1 = r3 */
1135 dword &= ~(0x1ffffffffffLL << shift);
1136 dword |= (insn << shift);
1137 bfd_put_64 (abfd, dword, contents + off);
1140 /* Return TRUE if NAME is an unwind table section name. */
1142 static inline bfd_boolean
1143 is_unwind_section_name (abfd, name)
1144 bfd *abfd;
1145 const char *name;
1147 size_t len1, len2, len3;
1149 if (elfNN_ia64_hpux_vec (abfd->xvec)
1150 && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
1151 return FALSE;
1153 len1 = sizeof (ELF_STRING_ia64_unwind) - 1;
1154 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
1155 len3 = sizeof (ELF_STRING_ia64_unwind_once) - 1;
1156 return ((strncmp (name, ELF_STRING_ia64_unwind, len1) == 0
1157 && strncmp (name, ELF_STRING_ia64_unwind_info, len2) != 0)
1158 || strncmp (name, ELF_STRING_ia64_unwind_once, len3) == 0);
1161 /* Handle an IA-64 specific section when reading an object file. This
1162 is called when elfcode.h finds a section with an unknown type. */
1164 static bfd_boolean
1165 elfNN_ia64_section_from_shdr (abfd, hdr, name)
1166 bfd *abfd;
1167 Elf_Internal_Shdr *hdr;
1168 const char *name;
1170 asection *newsect;
1172 /* There ought to be a place to keep ELF backend specific flags, but
1173 at the moment there isn't one. We just keep track of the
1174 sections by their name, instead. Fortunately, the ABI gives
1175 suggested names for all the MIPS specific sections, so we will
1176 probably get away with this. */
1177 switch (hdr->sh_type)
1179 case SHT_IA_64_UNWIND:
1180 case SHT_IA_64_HP_OPT_ANOT:
1181 break;
1183 case SHT_IA_64_EXT:
1184 if (strcmp (name, ELF_STRING_ia64_archext) != 0)
1185 return FALSE;
1186 break;
1188 default:
1189 return FALSE;
1192 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
1193 return FALSE;
1194 newsect = hdr->bfd_section;
1196 return TRUE;
1199 /* Convert IA-64 specific section flags to bfd internal section flags. */
1201 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1202 flag. */
1204 static bfd_boolean
1205 elfNN_ia64_section_flags (flags, hdr)
1206 flagword *flags;
1207 Elf_Internal_Shdr *hdr;
1209 if (hdr->sh_flags & SHF_IA_64_SHORT)
1210 *flags |= SEC_SMALL_DATA;
1212 return TRUE;
1215 /* Set the correct type for an IA-64 ELF section. We do this by the
1216 section name, which is a hack, but ought to work. */
1218 static bfd_boolean
1219 elfNN_ia64_fake_sections (abfd, hdr, sec)
1220 bfd *abfd ATTRIBUTE_UNUSED;
1221 Elf_Internal_Shdr *hdr;
1222 asection *sec;
1224 register const char *name;
1226 name = bfd_get_section_name (abfd, sec);
1228 if (is_unwind_section_name (abfd, name))
1230 /* We don't have the sections numbered at this point, so sh_info
1231 is set later, in elfNN_ia64_final_write_processing. */
1232 hdr->sh_type = SHT_IA_64_UNWIND;
1233 hdr->sh_flags |= SHF_LINK_ORDER;
1235 else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
1236 hdr->sh_type = SHT_IA_64_EXT;
1237 else if (strcmp (name, ".HP.opt_annot") == 0)
1238 hdr->sh_type = SHT_IA_64_HP_OPT_ANOT;
1239 else if (strcmp (name, ".reloc") == 0)
1240 /* This is an ugly, but unfortunately necessary hack that is
1241 needed when producing EFI binaries on IA-64. It tells
1242 elf.c:elf_fake_sections() not to consider ".reloc" as a section
1243 containing ELF relocation info. We need this hack in order to
1244 be able to generate ELF binaries that can be translated into
1245 EFI applications (which are essentially COFF objects). Those
1246 files contain a COFF ".reloc" section inside an ELFNN object,
1247 which would normally cause BFD to segfault because it would
1248 attempt to interpret this section as containing relocation
1249 entries for section "oc". With this hack enabled, ".reloc"
1250 will be treated as a normal data section, which will avoid the
1251 segfault. However, you won't be able to create an ELFNN binary
1252 with a section named "oc" that needs relocations, but that's
1253 the kind of ugly side-effects you get when detecting section
1254 types based on their names... In practice, this limitation is
1255 unlikely to bite. */
1256 hdr->sh_type = SHT_PROGBITS;
1258 if (sec->flags & SEC_SMALL_DATA)
1259 hdr->sh_flags |= SHF_IA_64_SHORT;
1261 return TRUE;
1264 /* The final processing done just before writing out an IA-64 ELF
1265 object file. */
1267 static void
1268 elfNN_ia64_final_write_processing (abfd, linker)
1269 bfd *abfd;
1270 bfd_boolean linker ATTRIBUTE_UNUSED;
1272 Elf_Internal_Shdr *hdr;
1273 const char *sname;
1274 asection *text_sect, *s;
1275 size_t len;
1277 for (s = abfd->sections; s; s = s->next)
1279 hdr = &elf_section_data (s)->this_hdr;
1280 switch (hdr->sh_type)
1282 case SHT_IA_64_UNWIND:
1283 /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1284 have to do this. */
1285 sname = bfd_get_section_name (abfd, s);
1286 len = sizeof (ELF_STRING_ia64_unwind) - 1;
1287 if (sname && strncmp (sname, ELF_STRING_ia64_unwind, len) == 0)
1289 sname += len;
1291 if (sname[0] == '\0')
1292 /* .IA_64.unwind -> .text */
1293 text_sect = bfd_get_section_by_name (abfd, ".text");
1294 else
1295 /* .IA_64.unwindFOO -> FOO */
1296 text_sect = bfd_get_section_by_name (abfd, sname);
1298 else if (sname
1299 && (len = sizeof (ELF_STRING_ia64_unwind_once) - 1,
1300 strncmp (sname, ELF_STRING_ia64_unwind_once, len)) == 0)
1302 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
1303 size_t len2 = sizeof (".gnu.linkonce.t.") - 1;
1304 char *once_name = bfd_malloc (len2 + strlen (sname + len) + 1);
1306 if (once_name != NULL)
1308 memcpy (once_name, ".gnu.linkonce.t.", len2);
1309 strcpy (once_name + len2, sname + len);
1310 text_sect = bfd_get_section_by_name (abfd, once_name);
1311 free (once_name);
1313 else
1314 /* Should only happen if we run out of memory, in
1315 which case we're probably toast anyway. Try to
1316 cope by finding the section the slow way. */
1317 for (text_sect = abfd->sections;
1318 text_sect != NULL;
1319 text_sect = text_sect->next)
1321 if (strncmp (bfd_section_name (abfd, text_sect),
1322 ".gnu.linkonce.t.", len2) == 0
1323 && strcmp (bfd_section_name (abfd, text_sect) + len2,
1324 sname + len) == 0)
1325 break;
1328 else
1329 /* last resort: fall back on .text */
1330 text_sect = bfd_get_section_by_name (abfd, ".text");
1332 if (text_sect)
1334 /* The IA-64 processor-specific ABI requires setting
1335 sh_link to the unwind section, whereas HP-UX requires
1336 sh_info to do so. For maximum compatibility, we'll
1337 set both for now... */
1338 hdr->sh_link = elf_section_data (text_sect)->this_idx;
1339 hdr->sh_info = elf_section_data (text_sect)->this_idx;
1341 break;
1345 if (! elf_flags_init (abfd))
1347 unsigned long flags = 0;
1349 if (abfd->xvec->byteorder == BFD_ENDIAN_BIG)
1350 flags |= EF_IA_64_BE;
1351 if (bfd_get_mach (abfd) == bfd_mach_ia64_elf64)
1352 flags |= EF_IA_64_ABI64;
1354 elf_elfheader(abfd)->e_flags = flags;
1355 elf_flags_init (abfd) = TRUE;
1359 /* Hook called by the linker routine which adds symbols from an object
1360 file. We use it to put .comm items in .sbss, and not .bss. */
1362 static bfd_boolean
1363 elfNN_ia64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1364 bfd *abfd;
1365 struct bfd_link_info *info;
1366 const Elf_Internal_Sym *sym;
1367 const char **namep ATTRIBUTE_UNUSED;
1368 flagword *flagsp ATTRIBUTE_UNUSED;
1369 asection **secp;
1370 bfd_vma *valp;
1372 if (sym->st_shndx == SHN_COMMON
1373 && !info->relocatable
1374 && sym->st_size <= elf_gp_size (abfd))
1376 /* Common symbols less than or equal to -G nn bytes are
1377 automatically put into .sbss. */
1379 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1381 if (scomm == NULL)
1383 scomm = bfd_make_section (abfd, ".scommon");
1384 if (scomm == NULL
1385 || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
1386 | SEC_IS_COMMON
1387 | SEC_LINKER_CREATED)))
1388 return FALSE;
1391 *secp = scomm;
1392 *valp = sym->st_size;
1395 return TRUE;
1398 /* Return the number of additional phdrs we will need. */
1400 static int
1401 elfNN_ia64_additional_program_headers (abfd)
1402 bfd *abfd;
1404 asection *s;
1405 int ret = 0;
1407 /* See if we need a PT_IA_64_ARCHEXT segment. */
1408 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1409 if (s && (s->flags & SEC_LOAD))
1410 ++ret;
1412 /* Count how many PT_IA_64_UNWIND segments we need. */
1413 for (s = abfd->sections; s; s = s->next)
1414 if (is_unwind_section_name (abfd, s->name) && (s->flags & SEC_LOAD))
1415 ++ret;
1417 return ret;
1420 static bfd_boolean
1421 elfNN_ia64_modify_segment_map (abfd, info)
1422 bfd *abfd;
1423 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1425 struct elf_segment_map *m, **pm;
1426 Elf_Internal_Shdr *hdr;
1427 asection *s;
1429 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1430 all PT_LOAD segments. */
1431 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1432 if (s && (s->flags & SEC_LOAD))
1434 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1435 if (m->p_type == PT_IA_64_ARCHEXT)
1436 break;
1437 if (m == NULL)
1439 m = ((struct elf_segment_map *)
1440 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1441 if (m == NULL)
1442 return FALSE;
1444 m->p_type = PT_IA_64_ARCHEXT;
1445 m->count = 1;
1446 m->sections[0] = s;
1448 /* We want to put it after the PHDR and INTERP segments. */
1449 pm = &elf_tdata (abfd)->segment_map;
1450 while (*pm != NULL
1451 && ((*pm)->p_type == PT_PHDR
1452 || (*pm)->p_type == PT_INTERP))
1453 pm = &(*pm)->next;
1455 m->next = *pm;
1456 *pm = m;
1460 /* Install PT_IA_64_UNWIND segments, if needed. */
1461 for (s = abfd->sections; s; s = s->next)
1463 hdr = &elf_section_data (s)->this_hdr;
1464 if (hdr->sh_type != SHT_IA_64_UNWIND)
1465 continue;
1467 if (s && (s->flags & SEC_LOAD))
1469 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1470 if (m->p_type == PT_IA_64_UNWIND)
1472 int i;
1474 /* Look through all sections in the unwind segment
1475 for a match since there may be multiple sections
1476 to a segment. */
1477 for (i = m->count - 1; i >= 0; --i)
1478 if (m->sections[i] == s)
1479 break;
1481 if (i >= 0)
1482 break;
1485 if (m == NULL)
1487 m = ((struct elf_segment_map *)
1488 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1489 if (m == NULL)
1490 return FALSE;
1492 m->p_type = PT_IA_64_UNWIND;
1493 m->count = 1;
1494 m->sections[0] = s;
1495 m->next = NULL;
1497 /* We want to put it last. */
1498 pm = &elf_tdata (abfd)->segment_map;
1499 while (*pm != NULL)
1500 pm = &(*pm)->next;
1501 *pm = m;
1506 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1507 the input sections for each output section in the segment and testing
1508 for SHF_IA_64_NORECOV on each. */
1509 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1510 if (m->p_type == PT_LOAD)
1512 int i;
1513 for (i = m->count - 1; i >= 0; --i)
1515 struct bfd_link_order *order = m->sections[i]->link_order_head;
1516 while (order)
1518 if (order->type == bfd_indirect_link_order)
1520 asection *is = order->u.indirect.section;
1521 bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
1522 if (flags & SHF_IA_64_NORECOV)
1524 m->p_flags |= PF_IA_64_NORECOV;
1525 goto found;
1528 order = order->next;
1531 found:;
1534 return TRUE;
1537 /* According to the Tahoe assembler spec, all labels starting with a
1538 '.' are local. */
1540 static bfd_boolean
1541 elfNN_ia64_is_local_label_name (abfd, name)
1542 bfd *abfd ATTRIBUTE_UNUSED;
1543 const char *name;
1545 return name[0] == '.';
1548 /* Should we do dynamic things to this symbol? */
1550 static bfd_boolean
1551 elfNN_ia64_dynamic_symbol_p (h, info, r_type)
1552 struct elf_link_hash_entry *h;
1553 struct bfd_link_info *info;
1554 int r_type;
1556 bfd_boolean ignore_protected
1557 = ((r_type & 0xf8) == 0x40 /* FPTR relocs */
1558 || (r_type & 0xf8) == 0x50); /* LTOFF_FPTR relocs */
1560 return _bfd_elf_dynamic_symbol_p (h, info, ignore_protected);
1563 static struct bfd_hash_entry*
1564 elfNN_ia64_new_elf_hash_entry (entry, table, string)
1565 struct bfd_hash_entry *entry;
1566 struct bfd_hash_table *table;
1567 const char *string;
1569 struct elfNN_ia64_link_hash_entry *ret;
1570 ret = (struct elfNN_ia64_link_hash_entry *) entry;
1572 /* Allocate the structure if it has not already been allocated by a
1573 subclass. */
1574 if (!ret)
1575 ret = bfd_hash_allocate (table, sizeof (*ret));
1577 if (!ret)
1578 return 0;
1580 /* Initialize our local data. All zeros, and definitely easier
1581 than setting a handful of bit fields. */
1582 memset (ret, 0, sizeof (*ret));
1584 /* Call the allocation method of the superclass. */
1585 ret = ((struct elfNN_ia64_link_hash_entry *)
1586 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1587 table, string));
1589 return (struct bfd_hash_entry *) ret;
1592 static void
1593 elfNN_ia64_hash_copy_indirect (bed, xdir, xind)
1594 const struct elf_backend_data *bed ATTRIBUTE_UNUSED;
1595 struct elf_link_hash_entry *xdir, *xind;
1597 struct elfNN_ia64_link_hash_entry *dir, *ind;
1599 dir = (struct elfNN_ia64_link_hash_entry *) xdir;
1600 ind = (struct elfNN_ia64_link_hash_entry *) xind;
1602 /* Copy down any references that we may have already seen to the
1603 symbol which just became indirect. */
1605 dir->root.elf_link_hash_flags |=
1606 (ind->root.elf_link_hash_flags
1607 & (ELF_LINK_HASH_REF_DYNAMIC
1608 | ELF_LINK_HASH_REF_REGULAR
1609 | ELF_LINK_HASH_REF_REGULAR_NONWEAK
1610 | ELF_LINK_HASH_NEEDS_PLT));
1612 if (ind->root.root.type != bfd_link_hash_indirect)
1613 return;
1615 /* Copy over the got and plt data. This would have been done
1616 by check_relocs. */
1618 if (dir->info == NULL)
1620 struct elfNN_ia64_dyn_sym_info *dyn_i;
1622 dir->info = dyn_i = ind->info;
1623 ind->info = NULL;
1625 /* Fix up the dyn_sym_info pointers to the global symbol. */
1626 for (; dyn_i; dyn_i = dyn_i->next)
1627 dyn_i->h = &dir->root;
1629 BFD_ASSERT (ind->info == NULL);
1631 /* Copy over the dynindx. */
1633 if (dir->root.dynindx == -1)
1635 dir->root.dynindx = ind->root.dynindx;
1636 dir->root.dynstr_index = ind->root.dynstr_index;
1637 ind->root.dynindx = -1;
1638 ind->root.dynstr_index = 0;
1640 BFD_ASSERT (ind->root.dynindx == -1);
1643 static void
1644 elfNN_ia64_hash_hide_symbol (info, xh, force_local)
1645 struct bfd_link_info *info;
1646 struct elf_link_hash_entry *xh;
1647 bfd_boolean force_local;
1649 struct elfNN_ia64_link_hash_entry *h;
1650 struct elfNN_ia64_dyn_sym_info *dyn_i;
1652 h = (struct elfNN_ia64_link_hash_entry *)xh;
1654 _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1656 for (dyn_i = h->info; dyn_i; dyn_i = dyn_i->next)
1658 dyn_i->want_plt2 = 0;
1659 dyn_i->want_plt = 0;
1663 /* Compute a hash of a local hash entry. */
1665 static hashval_t
1666 elfNN_ia64_local_htab_hash (ptr)
1667 const void *ptr;
1669 struct elfNN_ia64_local_hash_entry *entry
1670 = (struct elfNN_ia64_local_hash_entry *) ptr;
1672 return (((entry->id & 0xff) << 24) | ((entry->id & 0xff00) << 8))
1673 ^ entry->r_sym ^ (entry->id >> 16);
1676 /* Compare local hash entries. */
1678 static int
1679 elfNN_ia64_local_htab_eq (ptr1, ptr2)
1680 const void *ptr1, *ptr2;
1682 struct elfNN_ia64_local_hash_entry *entry1
1683 = (struct elfNN_ia64_local_hash_entry *) ptr1;
1684 struct elfNN_ia64_local_hash_entry *entry2
1685 = (struct elfNN_ia64_local_hash_entry *) ptr2;
1687 return entry1->id == entry2->id && entry1->r_sym == entry2->r_sym;
1690 /* Create the derived linker hash table. The IA-64 ELF port uses this
1691 derived hash table to keep information specific to the IA-64 ElF
1692 linker (without using static variables). */
1694 static struct bfd_link_hash_table*
1695 elfNN_ia64_hash_table_create (abfd)
1696 bfd *abfd;
1698 struct elfNN_ia64_link_hash_table *ret;
1700 ret = bfd_zmalloc ((bfd_size_type) sizeof (*ret));
1701 if (!ret)
1702 return 0;
1704 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1705 elfNN_ia64_new_elf_hash_entry))
1707 free (ret);
1708 return 0;
1711 ret->loc_hash_table = htab_try_create (1024, elfNN_ia64_local_htab_hash,
1712 elfNN_ia64_local_htab_eq, NULL);
1713 ret->loc_hash_memory = objalloc_create ();
1714 if (!ret->loc_hash_table || !ret->loc_hash_memory)
1716 free (ret);
1717 return 0;
1720 return &ret->root.root;
1723 /* Destroy IA-64 linker hash table. */
1725 static void
1726 elfNN_ia64_hash_table_free (hash)
1727 struct bfd_link_hash_table *hash;
1729 struct elfNN_ia64_link_hash_table *ia64_info
1730 = (struct elfNN_ia64_link_hash_table *) hash;
1731 if (ia64_info->loc_hash_table)
1732 htab_delete (ia64_info->loc_hash_table);
1733 if (ia64_info->loc_hash_memory)
1734 objalloc_free ((struct objalloc *) ia64_info->loc_hash_memory);
1735 _bfd_generic_link_hash_table_free (hash);
1738 /* Traverse both local and global hash tables. */
1740 struct elfNN_ia64_dyn_sym_traverse_data
1742 bfd_boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1743 PTR data;
1746 static bfd_boolean
1747 elfNN_ia64_global_dyn_sym_thunk (xentry, xdata)
1748 struct bfd_hash_entry *xentry;
1749 PTR xdata;
1751 struct elfNN_ia64_link_hash_entry *entry
1752 = (struct elfNN_ia64_link_hash_entry *) xentry;
1753 struct elfNN_ia64_dyn_sym_traverse_data *data
1754 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1755 struct elfNN_ia64_dyn_sym_info *dyn_i;
1757 if (entry->root.root.type == bfd_link_hash_warning)
1758 entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
1760 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1761 if (! (*data->func) (dyn_i, data->data))
1762 return FALSE;
1763 return TRUE;
1766 static bfd_boolean
1767 elfNN_ia64_local_dyn_sym_thunk (slot, xdata)
1768 void **slot;
1769 PTR xdata;
1771 struct elfNN_ia64_local_hash_entry *entry
1772 = (struct elfNN_ia64_local_hash_entry *) *slot;
1773 struct elfNN_ia64_dyn_sym_traverse_data *data
1774 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1775 struct elfNN_ia64_dyn_sym_info *dyn_i;
1777 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1778 if (! (*data->func) (dyn_i, data->data))
1779 return 0;
1780 return 1;
1783 static void
1784 elfNN_ia64_dyn_sym_traverse (ia64_info, func, data)
1785 struct elfNN_ia64_link_hash_table *ia64_info;
1786 bfd_boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1787 PTR data;
1789 struct elfNN_ia64_dyn_sym_traverse_data xdata;
1791 xdata.func = func;
1792 xdata.data = data;
1794 elf_link_hash_traverse (&ia64_info->root,
1795 elfNN_ia64_global_dyn_sym_thunk, &xdata);
1796 htab_traverse (ia64_info->loc_hash_table,
1797 elfNN_ia64_local_dyn_sym_thunk, &xdata);
1800 static bfd_boolean
1801 elfNN_ia64_create_dynamic_sections (abfd, info)
1802 bfd *abfd;
1803 struct bfd_link_info *info;
1805 struct elfNN_ia64_link_hash_table *ia64_info;
1806 asection *s;
1808 if (! _bfd_elf_create_dynamic_sections (abfd, info))
1809 return FALSE;
1811 ia64_info = elfNN_ia64_hash_table (info);
1813 ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
1814 ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
1817 flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
1818 bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
1819 /* The .got section is always aligned at 8 bytes. */
1820 bfd_set_section_alignment (abfd, ia64_info->got_sec, 3);
1823 if (!get_pltoff (abfd, info, ia64_info))
1824 return FALSE;
1826 s = bfd_make_section(abfd, ".rela.IA_64.pltoff");
1827 if (s == NULL
1828 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1829 | SEC_HAS_CONTENTS
1830 | SEC_IN_MEMORY
1831 | SEC_LINKER_CREATED
1832 | SEC_READONLY))
1833 || !bfd_set_section_alignment (abfd, s, 3))
1834 return FALSE;
1835 ia64_info->rel_pltoff_sec = s;
1837 s = bfd_make_section(abfd, ".rela.got");
1838 if (s == NULL
1839 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1840 | SEC_HAS_CONTENTS
1841 | SEC_IN_MEMORY
1842 | SEC_LINKER_CREATED
1843 | SEC_READONLY))
1844 || !bfd_set_section_alignment (abfd, s, 3))
1845 return FALSE;
1846 ia64_info->rel_got_sec = s;
1848 return TRUE;
1851 /* Find and/or create a hash entry for local symbol. */
1852 static struct elfNN_ia64_local_hash_entry *
1853 get_local_sym_hash (ia64_info, abfd, rel, create)
1854 struct elfNN_ia64_link_hash_table *ia64_info;
1855 bfd *abfd;
1856 const Elf_Internal_Rela *rel;
1857 bfd_boolean create;
1859 struct elfNN_ia64_local_hash_entry e, *ret;
1860 asection *sec = abfd->sections;
1861 hashval_t h = (((sec->id & 0xff) << 24) | ((sec->id & 0xff00) << 8))
1862 ^ ELFNN_R_SYM (rel->r_info) ^ (sec->id >> 16);
1863 void **slot;
1865 e.id = sec->id;
1866 e.r_sym = ELFNN_R_SYM (rel->r_info);
1867 slot = htab_find_slot_with_hash (ia64_info->loc_hash_table, &e, h,
1868 create ? INSERT : NO_INSERT);
1870 if (!slot)
1871 return NULL;
1873 if (*slot)
1874 return (struct elfNN_ia64_local_hash_entry *) *slot;
1876 ret = (struct elfNN_ia64_local_hash_entry *)
1877 objalloc_alloc ((struct objalloc *) ia64_info->loc_hash_memory,
1878 sizeof (struct elfNN_ia64_local_hash_entry));
1879 if (ret)
1881 memset (ret, 0, sizeof (*ret));
1882 ret->id = sec->id;
1883 ret->r_sym = ELFNN_R_SYM (rel->r_info);
1884 *slot = ret;
1886 return ret;
1889 /* Find and/or create a descriptor for dynamic symbol info. This will
1890 vary based on global or local symbol, and the addend to the reloc. */
1892 static struct elfNN_ia64_dyn_sym_info *
1893 get_dyn_sym_info (ia64_info, h, abfd, rel, create)
1894 struct elfNN_ia64_link_hash_table *ia64_info;
1895 struct elf_link_hash_entry *h;
1896 bfd *abfd;
1897 const Elf_Internal_Rela *rel;
1898 bfd_boolean create;
1900 struct elfNN_ia64_dyn_sym_info **pp;
1901 struct elfNN_ia64_dyn_sym_info *dyn_i;
1902 bfd_vma addend = rel ? rel->r_addend : 0;
1904 if (h)
1905 pp = &((struct elfNN_ia64_link_hash_entry *)h)->info;
1906 else
1908 struct elfNN_ia64_local_hash_entry *loc_h;
1910 loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
1911 if (!loc_h)
1913 BFD_ASSERT (!create);
1914 return NULL;
1917 pp = &loc_h->info;
1920 for (dyn_i = *pp; dyn_i && dyn_i->addend != addend; dyn_i = *pp)
1921 pp = &dyn_i->next;
1923 if (dyn_i == NULL && create)
1925 dyn_i = ((struct elfNN_ia64_dyn_sym_info *)
1926 bfd_zalloc (abfd, (bfd_size_type) sizeof *dyn_i));
1927 *pp = dyn_i;
1928 dyn_i->addend = addend;
1931 return dyn_i;
1934 static asection *
1935 get_got (abfd, info, ia64_info)
1936 bfd *abfd;
1937 struct bfd_link_info *info;
1938 struct elfNN_ia64_link_hash_table *ia64_info;
1940 asection *got;
1941 bfd *dynobj;
1943 got = ia64_info->got_sec;
1944 if (!got)
1946 flagword flags;
1948 dynobj = ia64_info->root.dynobj;
1949 if (!dynobj)
1950 ia64_info->root.dynobj = dynobj = abfd;
1951 if (!_bfd_elf_create_got_section (dynobj, info))
1952 return 0;
1954 got = bfd_get_section_by_name (dynobj, ".got");
1955 BFD_ASSERT (got);
1956 ia64_info->got_sec = got;
1958 /* The .got section is always aligned at 8 bytes. */
1959 if (!bfd_set_section_alignment (abfd, got, 3))
1960 return 0;
1962 flags = bfd_get_section_flags (abfd, got);
1963 bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
1966 return got;
1969 /* Create function descriptor section (.opd). This section is called .opd
1970 because it contains "official procedure descriptors". The "official"
1971 refers to the fact that these descriptors are used when taking the address
1972 of a procedure, thus ensuring a unique address for each procedure. */
1974 static asection *
1975 get_fptr (abfd, info, ia64_info)
1976 bfd *abfd;
1977 struct bfd_link_info *info;
1978 struct elfNN_ia64_link_hash_table *ia64_info;
1980 asection *fptr;
1981 bfd *dynobj;
1983 fptr = ia64_info->fptr_sec;
1984 if (!fptr)
1986 dynobj = ia64_info->root.dynobj;
1987 if (!dynobj)
1988 ia64_info->root.dynobj = dynobj = abfd;
1990 fptr = bfd_make_section (dynobj, ".opd");
1991 if (!fptr
1992 || !bfd_set_section_flags (dynobj, fptr,
1993 (SEC_ALLOC
1994 | SEC_LOAD
1995 | SEC_HAS_CONTENTS
1996 | SEC_IN_MEMORY
1997 | (info->pie ? 0 : SEC_READONLY)
1998 | SEC_LINKER_CREATED))
1999 || !bfd_set_section_alignment (abfd, fptr, 4))
2001 BFD_ASSERT (0);
2002 return NULL;
2005 ia64_info->fptr_sec = fptr;
2007 if (info->pie)
2009 asection *fptr_rel;
2010 fptr_rel = bfd_make_section(dynobj, ".rela.opd");
2011 if (fptr_rel == NULL
2012 || !bfd_set_section_flags (dynobj, fptr_rel,
2013 (SEC_ALLOC | SEC_LOAD
2014 | SEC_HAS_CONTENTS
2015 | SEC_IN_MEMORY
2016 | SEC_LINKER_CREATED
2017 | SEC_READONLY))
2018 || !bfd_set_section_alignment (abfd, fptr_rel, 3))
2020 BFD_ASSERT (0);
2021 return NULL;
2024 ia64_info->rel_fptr_sec = fptr_rel;
2028 return fptr;
2031 static asection *
2032 get_pltoff (abfd, info, ia64_info)
2033 bfd *abfd;
2034 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2035 struct elfNN_ia64_link_hash_table *ia64_info;
2037 asection *pltoff;
2038 bfd *dynobj;
2040 pltoff = ia64_info->pltoff_sec;
2041 if (!pltoff)
2043 dynobj = ia64_info->root.dynobj;
2044 if (!dynobj)
2045 ia64_info->root.dynobj = dynobj = abfd;
2047 pltoff = bfd_make_section (dynobj, ELF_STRING_ia64_pltoff);
2048 if (!pltoff
2049 || !bfd_set_section_flags (dynobj, pltoff,
2050 (SEC_ALLOC
2051 | SEC_LOAD
2052 | SEC_HAS_CONTENTS
2053 | SEC_IN_MEMORY
2054 | SEC_SMALL_DATA
2055 | SEC_LINKER_CREATED))
2056 || !bfd_set_section_alignment (abfd, pltoff, 4))
2058 BFD_ASSERT (0);
2059 return NULL;
2062 ia64_info->pltoff_sec = pltoff;
2065 return pltoff;
2068 static asection *
2069 get_reloc_section (abfd, ia64_info, sec, create)
2070 bfd *abfd;
2071 struct elfNN_ia64_link_hash_table *ia64_info;
2072 asection *sec;
2073 bfd_boolean create;
2075 const char *srel_name;
2076 asection *srel;
2077 bfd *dynobj;
2079 srel_name = (bfd_elf_string_from_elf_section
2080 (abfd, elf_elfheader(abfd)->e_shstrndx,
2081 elf_section_data(sec)->rel_hdr.sh_name));
2082 if (srel_name == NULL)
2083 return NULL;
2085 BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0
2086 && strcmp (bfd_get_section_name (abfd, sec),
2087 srel_name+5) == 0)
2088 || (strncmp (srel_name, ".rel", 4) == 0
2089 && strcmp (bfd_get_section_name (abfd, sec),
2090 srel_name+4) == 0));
2092 dynobj = ia64_info->root.dynobj;
2093 if (!dynobj)
2094 ia64_info->root.dynobj = dynobj = abfd;
2096 srel = bfd_get_section_by_name (dynobj, srel_name);
2097 if (srel == NULL && create)
2099 srel = bfd_make_section (dynobj, srel_name);
2100 if (srel == NULL
2101 || !bfd_set_section_flags (dynobj, srel,
2102 (SEC_ALLOC
2103 | SEC_LOAD
2104 | SEC_HAS_CONTENTS
2105 | SEC_IN_MEMORY
2106 | SEC_LINKER_CREATED
2107 | SEC_READONLY))
2108 || !bfd_set_section_alignment (dynobj, srel, 3))
2109 return NULL;
2112 if (sec->flags & SEC_READONLY)
2113 ia64_info->reltext = 1;
2115 return srel;
2118 static bfd_boolean
2119 count_dyn_reloc (abfd, dyn_i, srel, type)
2120 bfd *abfd;
2121 struct elfNN_ia64_dyn_sym_info *dyn_i;
2122 asection *srel;
2123 int type;
2125 struct elfNN_ia64_dyn_reloc_entry *rent;
2127 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2128 if (rent->srel == srel && rent->type == type)
2129 break;
2131 if (!rent)
2133 rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2134 bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
2135 if (!rent)
2136 return FALSE;
2138 rent->next = dyn_i->reloc_entries;
2139 rent->srel = srel;
2140 rent->type = type;
2141 rent->count = 0;
2142 dyn_i->reloc_entries = rent;
2144 rent->count++;
2146 return TRUE;
2149 static bfd_boolean
2150 elfNN_ia64_check_relocs (abfd, info, sec, relocs)
2151 bfd *abfd;
2152 struct bfd_link_info *info;
2153 asection *sec;
2154 const Elf_Internal_Rela *relocs;
2156 struct elfNN_ia64_link_hash_table *ia64_info;
2157 const Elf_Internal_Rela *relend;
2158 Elf_Internal_Shdr *symtab_hdr;
2159 const Elf_Internal_Rela *rel;
2160 asection *got, *fptr, *srel;
2162 if (info->relocatable)
2163 return TRUE;
2165 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2166 ia64_info = elfNN_ia64_hash_table (info);
2168 got = fptr = srel = NULL;
2170 relend = relocs + sec->reloc_count;
2171 for (rel = relocs; rel < relend; ++rel)
2173 enum {
2174 NEED_GOT = 1,
2175 NEED_GOTX = 2,
2176 NEED_FPTR = 4,
2177 NEED_PLTOFF = 8,
2178 NEED_MIN_PLT = 16,
2179 NEED_FULL_PLT = 32,
2180 NEED_DYNREL = 64,
2181 NEED_LTOFF_FPTR = 128,
2182 NEED_TPREL = 256,
2183 NEED_DTPMOD = 512,
2184 NEED_DTPREL = 1024
2187 struct elf_link_hash_entry *h = NULL;
2188 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
2189 struct elfNN_ia64_dyn_sym_info *dyn_i;
2190 int need_entry;
2191 bfd_boolean maybe_dynamic;
2192 int dynrel_type = R_IA64_NONE;
2194 if (r_symndx >= symtab_hdr->sh_info)
2196 /* We're dealing with a global symbol -- find its hash entry
2197 and mark it as being referenced. */
2198 long indx = r_symndx - symtab_hdr->sh_info;
2199 h = elf_sym_hashes (abfd)[indx];
2200 while (h->root.type == bfd_link_hash_indirect
2201 || h->root.type == bfd_link_hash_warning)
2202 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2204 h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
2207 /* We can only get preliminary data on whether a symbol is
2208 locally or externally defined, as not all of the input files
2209 have yet been processed. Do something with what we know, as
2210 this may help reduce memory usage and processing time later. */
2211 maybe_dynamic = FALSE;
2212 if (h && ((!info->executable
2213 && (!info->symbolic || info->unresolved_syms_in_shared_libs == RM_IGNORE))
2214 || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
2215 || h->root.type == bfd_link_hash_defweak))
2216 maybe_dynamic = TRUE;
2218 need_entry = 0;
2219 switch (ELFNN_R_TYPE (rel->r_info))
2221 case R_IA64_TPREL64MSB:
2222 case R_IA64_TPREL64LSB:
2223 if (info->shared || maybe_dynamic)
2224 need_entry = NEED_DYNREL;
2225 dynrel_type = R_IA64_TPREL64LSB;
2226 if (info->shared)
2227 info->flags |= DF_STATIC_TLS;
2228 break;
2230 case R_IA64_LTOFF_TPREL22:
2231 need_entry = NEED_TPREL;
2232 if (info->shared)
2233 info->flags |= DF_STATIC_TLS;
2234 break;
2236 case R_IA64_DTPREL64MSB:
2237 case R_IA64_DTPREL64LSB:
2238 if (info->shared || maybe_dynamic)
2239 need_entry = NEED_DYNREL;
2240 dynrel_type = R_IA64_DTPREL64LSB;
2241 break;
2243 case R_IA64_LTOFF_DTPREL22:
2244 need_entry = NEED_DTPREL;
2245 break;
2247 case R_IA64_DTPMOD64MSB:
2248 case R_IA64_DTPMOD64LSB:
2249 if (info->shared || maybe_dynamic)
2250 need_entry = NEED_DYNREL;
2251 dynrel_type = R_IA64_DTPMOD64LSB;
2252 break;
2254 case R_IA64_LTOFF_DTPMOD22:
2255 need_entry = NEED_DTPMOD;
2256 break;
2258 case R_IA64_LTOFF_FPTR22:
2259 case R_IA64_LTOFF_FPTR64I:
2260 case R_IA64_LTOFF_FPTR32MSB:
2261 case R_IA64_LTOFF_FPTR32LSB:
2262 case R_IA64_LTOFF_FPTR64MSB:
2263 case R_IA64_LTOFF_FPTR64LSB:
2264 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2265 break;
2267 case R_IA64_FPTR64I:
2268 case R_IA64_FPTR32MSB:
2269 case R_IA64_FPTR32LSB:
2270 case R_IA64_FPTR64MSB:
2271 case R_IA64_FPTR64LSB:
2272 if (info->shared || h)
2273 need_entry = NEED_FPTR | NEED_DYNREL;
2274 else
2275 need_entry = NEED_FPTR;
2276 dynrel_type = R_IA64_FPTR64LSB;
2277 break;
2279 case R_IA64_LTOFF22:
2280 case R_IA64_LTOFF64I:
2281 need_entry = NEED_GOT;
2282 break;
2284 case R_IA64_LTOFF22X:
2285 need_entry = NEED_GOTX;
2286 break;
2288 case R_IA64_PLTOFF22:
2289 case R_IA64_PLTOFF64I:
2290 case R_IA64_PLTOFF64MSB:
2291 case R_IA64_PLTOFF64LSB:
2292 need_entry = NEED_PLTOFF;
2293 if (h)
2295 if (maybe_dynamic)
2296 need_entry |= NEED_MIN_PLT;
2298 else
2300 (*info->callbacks->warning)
2301 (info, _("@pltoff reloc against local symbol"), 0,
2302 abfd, 0, (bfd_vma) 0);
2304 break;
2306 case R_IA64_PCREL21B:
2307 case R_IA64_PCREL60B:
2308 /* Depending on where this symbol is defined, we may or may not
2309 need a full plt entry. Only skip if we know we'll not need
2310 the entry -- static or symbolic, and the symbol definition
2311 has already been seen. */
2312 if (maybe_dynamic && rel->r_addend == 0)
2313 need_entry = NEED_FULL_PLT;
2314 break;
2316 case R_IA64_IMM14:
2317 case R_IA64_IMM22:
2318 case R_IA64_IMM64:
2319 case R_IA64_DIR32MSB:
2320 case R_IA64_DIR32LSB:
2321 case R_IA64_DIR64MSB:
2322 case R_IA64_DIR64LSB:
2323 /* Shared objects will always need at least a REL relocation. */
2324 if (info->shared || maybe_dynamic)
2325 need_entry = NEED_DYNREL;
2326 dynrel_type = R_IA64_DIR64LSB;
2327 break;
2329 case R_IA64_IPLTMSB:
2330 case R_IA64_IPLTLSB:
2331 /* Shared objects will always need at least a REL relocation. */
2332 if (info->shared || maybe_dynamic)
2333 need_entry = NEED_DYNREL;
2334 dynrel_type = R_IA64_IPLTLSB;
2335 break;
2337 case R_IA64_PCREL22:
2338 case R_IA64_PCREL64I:
2339 case R_IA64_PCREL32MSB:
2340 case R_IA64_PCREL32LSB:
2341 case R_IA64_PCREL64MSB:
2342 case R_IA64_PCREL64LSB:
2343 if (maybe_dynamic)
2344 need_entry = NEED_DYNREL;
2345 dynrel_type = R_IA64_PCREL64LSB;
2346 break;
2349 if (!need_entry)
2350 continue;
2352 if ((need_entry & NEED_FPTR) != 0
2353 && rel->r_addend)
2355 (*info->callbacks->warning)
2356 (info, _("non-zero addend in @fptr reloc"), 0,
2357 abfd, 0, (bfd_vma) 0);
2360 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, TRUE);
2362 /* Record whether or not this is a local symbol. */
2363 dyn_i->h = h;
2365 /* Create what's needed. */
2366 if (need_entry & (NEED_GOT | NEED_GOTX | NEED_TPREL
2367 | NEED_DTPMOD | NEED_DTPREL))
2369 if (!got)
2371 got = get_got (abfd, info, ia64_info);
2372 if (!got)
2373 return FALSE;
2375 if (need_entry & NEED_GOT)
2376 dyn_i->want_got = 1;
2377 if (need_entry & NEED_GOTX)
2378 dyn_i->want_gotx = 1;
2379 if (need_entry & NEED_TPREL)
2380 dyn_i->want_tprel = 1;
2381 if (need_entry & NEED_DTPMOD)
2382 dyn_i->want_dtpmod = 1;
2383 if (need_entry & NEED_DTPREL)
2384 dyn_i->want_dtprel = 1;
2386 if (need_entry & NEED_FPTR)
2388 if (!fptr)
2390 fptr = get_fptr (abfd, info, ia64_info);
2391 if (!fptr)
2392 return FALSE;
2395 /* FPTRs for shared libraries are allocated by the dynamic
2396 linker. Make sure this local symbol will appear in the
2397 dynamic symbol table. */
2398 if (!h && info->shared)
2400 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2401 (info, abfd, (long) r_symndx)))
2402 return FALSE;
2405 dyn_i->want_fptr = 1;
2407 if (need_entry & NEED_LTOFF_FPTR)
2408 dyn_i->want_ltoff_fptr = 1;
2409 if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
2411 if (!ia64_info->root.dynobj)
2412 ia64_info->root.dynobj = abfd;
2413 h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
2414 dyn_i->want_plt = 1;
2416 if (need_entry & NEED_FULL_PLT)
2417 dyn_i->want_plt2 = 1;
2418 if (need_entry & NEED_PLTOFF)
2419 dyn_i->want_pltoff = 1;
2420 if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
2422 if (!srel)
2424 srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
2425 if (!srel)
2426 return FALSE;
2428 if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type))
2429 return FALSE;
2433 return TRUE;
2436 /* For cleanliness, and potentially faster dynamic loading, allocate
2437 external GOT entries first. */
2439 static bfd_boolean
2440 allocate_global_data_got (dyn_i, data)
2441 struct elfNN_ia64_dyn_sym_info *dyn_i;
2442 PTR data;
2444 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2446 if ((dyn_i->want_got || dyn_i->want_gotx)
2447 && ! dyn_i->want_fptr
2448 && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
2450 dyn_i->got_offset = x->ofs;
2451 x->ofs += 8;
2453 if (dyn_i->want_tprel)
2455 dyn_i->tprel_offset = x->ofs;
2456 x->ofs += 8;
2458 if (dyn_i->want_dtpmod)
2460 if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
2462 dyn_i->dtpmod_offset = x->ofs;
2463 x->ofs += 8;
2465 else
2467 struct elfNN_ia64_link_hash_table *ia64_info;
2469 ia64_info = elfNN_ia64_hash_table (x->info);
2470 if (ia64_info->self_dtpmod_offset == (bfd_vma) -1)
2472 ia64_info->self_dtpmod_offset = x->ofs;
2473 x->ofs += 8;
2475 dyn_i->dtpmod_offset = ia64_info->self_dtpmod_offset;
2478 if (dyn_i->want_dtprel)
2480 dyn_i->dtprel_offset = x->ofs;
2481 x->ofs += 8;
2483 return TRUE;
2486 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2488 static bfd_boolean
2489 allocate_global_fptr_got (dyn_i, data)
2490 struct elfNN_ia64_dyn_sym_info *dyn_i;
2491 PTR data;
2493 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2495 if (dyn_i->want_got
2496 && dyn_i->want_fptr
2497 && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, R_IA64_FPTR64LSB))
2499 dyn_i->got_offset = x->ofs;
2500 x->ofs += 8;
2502 return TRUE;
2505 /* Lastly, allocate all the GOT entries for local data. */
2507 static bfd_boolean
2508 allocate_local_got (dyn_i, data)
2509 struct elfNN_ia64_dyn_sym_info *dyn_i;
2510 PTR data;
2512 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2514 if ((dyn_i->want_got || dyn_i->want_gotx)
2515 && !elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
2517 dyn_i->got_offset = x->ofs;
2518 x->ofs += 8;
2520 return TRUE;
2523 /* Search for the index of a global symbol in it's defining object file. */
2525 static long
2526 global_sym_index (h)
2527 struct elf_link_hash_entry *h;
2529 struct elf_link_hash_entry **p;
2530 bfd *obj;
2532 BFD_ASSERT (h->root.type == bfd_link_hash_defined
2533 || h->root.type == bfd_link_hash_defweak);
2535 obj = h->root.u.def.section->owner;
2536 for (p = elf_sym_hashes (obj); *p != h; ++p)
2537 continue;
2539 return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2542 /* Allocate function descriptors. We can do these for every function
2543 in a main executable that is not exported. */
2545 static bfd_boolean
2546 allocate_fptr (dyn_i, data)
2547 struct elfNN_ia64_dyn_sym_info *dyn_i;
2548 PTR data;
2550 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2552 if (dyn_i->want_fptr)
2554 struct elf_link_hash_entry *h = dyn_i->h;
2556 if (h)
2557 while (h->root.type == bfd_link_hash_indirect
2558 || h->root.type == bfd_link_hash_warning)
2559 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2561 if (!x->info->executable
2562 && (!h
2563 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
2564 || h->root.type != bfd_link_hash_undefweak))
2566 if (h && h->dynindx == -1)
2568 BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2569 || (h->root.type == bfd_link_hash_defweak));
2571 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2572 (x->info, h->root.u.def.section->owner,
2573 global_sym_index (h)))
2574 return FALSE;
2577 dyn_i->want_fptr = 0;
2579 else if (h == NULL || h->dynindx == -1)
2581 dyn_i->fptr_offset = x->ofs;
2582 x->ofs += 16;
2584 else
2585 dyn_i->want_fptr = 0;
2587 return TRUE;
2590 /* Allocate all the minimal PLT entries. */
2592 static bfd_boolean
2593 allocate_plt_entries (dyn_i, data)
2594 struct elfNN_ia64_dyn_sym_info *dyn_i;
2595 PTR data;
2597 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2599 if (dyn_i->want_plt)
2601 struct elf_link_hash_entry *h = dyn_i->h;
2603 if (h)
2604 while (h->root.type == bfd_link_hash_indirect
2605 || h->root.type == bfd_link_hash_warning)
2606 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2608 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2609 if (elfNN_ia64_dynamic_symbol_p (h, x->info, 0))
2611 bfd_size_type offset = x->ofs;
2612 if (offset == 0)
2613 offset = PLT_HEADER_SIZE;
2614 dyn_i->plt_offset = offset;
2615 x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2617 dyn_i->want_pltoff = 1;
2619 else
2621 dyn_i->want_plt = 0;
2622 dyn_i->want_plt2 = 0;
2625 return TRUE;
2628 /* Allocate all the full PLT entries. */
2630 static bfd_boolean
2631 allocate_plt2_entries (dyn_i, data)
2632 struct elfNN_ia64_dyn_sym_info *dyn_i;
2633 PTR data;
2635 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2637 if (dyn_i->want_plt2)
2639 struct elf_link_hash_entry *h = dyn_i->h;
2640 bfd_size_type ofs = x->ofs;
2642 dyn_i->plt2_offset = ofs;
2643 x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2645 while (h->root.type == bfd_link_hash_indirect
2646 || h->root.type == bfd_link_hash_warning)
2647 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2648 dyn_i->h->plt.offset = ofs;
2650 return TRUE;
2653 /* Allocate all the PLTOFF entries requested by relocations and
2654 plt entries. We can't share space with allocated FPTR entries,
2655 because the latter are not necessarily addressable by the GP.
2656 ??? Relaxation might be able to determine that they are. */
2658 static bfd_boolean
2659 allocate_pltoff_entries (dyn_i, data)
2660 struct elfNN_ia64_dyn_sym_info *dyn_i;
2661 PTR data;
2663 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2665 if (dyn_i->want_pltoff)
2667 dyn_i->pltoff_offset = x->ofs;
2668 x->ofs += 16;
2670 return TRUE;
2673 /* Allocate dynamic relocations for those symbols that turned out
2674 to be dynamic. */
2676 static bfd_boolean
2677 allocate_dynrel_entries (dyn_i, data)
2678 struct elfNN_ia64_dyn_sym_info *dyn_i;
2679 PTR data;
2681 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2682 struct elfNN_ia64_link_hash_table *ia64_info;
2683 struct elfNN_ia64_dyn_reloc_entry *rent;
2684 bfd_boolean dynamic_symbol, shared, resolved_zero;
2686 ia64_info = elfNN_ia64_hash_table (x->info);
2688 /* Note that this can't be used in relation to FPTR relocs below. */
2689 dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0);
2691 shared = x->info->shared;
2692 resolved_zero = (dyn_i->h
2693 && ELF_ST_VISIBILITY (dyn_i->h->other)
2694 && dyn_i->h->root.type == bfd_link_hash_undefweak);
2696 /* Take care of the normal data relocations. */
2698 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2700 int count = rent->count;
2702 switch (rent->type)
2704 case R_IA64_FPTR64LSB:
2705 /* Allocate one iff !want_fptr and not PIE, which by this point
2706 will be true only if we're actually allocating one statically
2707 in the main executable. Position independent executables
2708 need a relative reloc. */
2709 if (dyn_i->want_fptr && !x->info->pie)
2710 continue;
2711 break;
2712 case R_IA64_PCREL64LSB:
2713 if (!dynamic_symbol)
2714 continue;
2715 break;
2716 case R_IA64_DIR64LSB:
2717 if (!dynamic_symbol && !shared)
2718 continue;
2719 break;
2720 case R_IA64_IPLTLSB:
2721 if (!dynamic_symbol && !shared)
2722 continue;
2723 /* Use two REL relocations for IPLT relocations
2724 against local symbols. */
2725 if (!dynamic_symbol)
2726 count *= 2;
2727 break;
2728 case R_IA64_TPREL64LSB:
2729 case R_IA64_DTPREL64LSB:
2730 case R_IA64_DTPMOD64LSB:
2731 break;
2732 default:
2733 abort ();
2735 rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * count;
2738 /* Take care of the GOT and PLT relocations. */
2740 if ((!resolved_zero
2741 && (dynamic_symbol || shared)
2742 && (dyn_i->want_got || dyn_i->want_gotx))
2743 || (dyn_i->want_ltoff_fptr
2744 && dyn_i->h
2745 && dyn_i->h->dynindx != -1))
2747 if (!dyn_i->want_ltoff_fptr
2748 || !x->info->pie
2749 || dyn_i->h == NULL
2750 || dyn_i->h->root.type != bfd_link_hash_undefweak)
2751 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2753 if ((dynamic_symbol || shared) && dyn_i->want_tprel)
2754 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2755 if (dynamic_symbol && dyn_i->want_dtpmod)
2756 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2757 if (dynamic_symbol && dyn_i->want_dtprel)
2758 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2759 if (ia64_info->rel_fptr_sec && dyn_i->want_fptr)
2761 if (dyn_i->h == NULL || dyn_i->h->root.type != bfd_link_hash_undefweak)
2762 ia64_info->rel_fptr_sec->_raw_size += sizeof (ElfNN_External_Rela);
2765 if (!resolved_zero && dyn_i->want_pltoff)
2767 bfd_size_type t = 0;
2769 /* Dynamic symbols get one IPLT relocation. Local symbols in
2770 shared libraries get two REL relocations. Local symbols in
2771 main applications get nothing. */
2772 if (dynamic_symbol)
2773 t = sizeof (ElfNN_External_Rela);
2774 else if (shared)
2775 t = 2 * sizeof (ElfNN_External_Rela);
2777 ia64_info->rel_pltoff_sec->_raw_size += t;
2780 return TRUE;
2783 static bfd_boolean
2784 elfNN_ia64_adjust_dynamic_symbol (info, h)
2785 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2786 struct elf_link_hash_entry *h;
2788 /* ??? Undefined symbols with PLT entries should be re-defined
2789 to be the PLT entry. */
2791 /* If this is a weak symbol, and there is a real definition, the
2792 processor independent code will have arranged for us to see the
2793 real definition first, and we can just use the same value. */
2794 if (h->weakdef != NULL)
2796 BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
2797 || h->weakdef->root.type == bfd_link_hash_defweak);
2798 h->root.u.def.section = h->weakdef->root.u.def.section;
2799 h->root.u.def.value = h->weakdef->root.u.def.value;
2800 return TRUE;
2803 /* If this is a reference to a symbol defined by a dynamic object which
2804 is not a function, we might allocate the symbol in our .dynbss section
2805 and allocate a COPY dynamic relocation.
2807 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2808 of hackery. */
2810 return TRUE;
2813 static bfd_boolean
2814 elfNN_ia64_size_dynamic_sections (output_bfd, info)
2815 bfd *output_bfd ATTRIBUTE_UNUSED;
2816 struct bfd_link_info *info;
2818 struct elfNN_ia64_allocate_data data;
2819 struct elfNN_ia64_link_hash_table *ia64_info;
2820 asection *sec;
2821 bfd *dynobj;
2822 bfd_boolean relplt = FALSE;
2824 dynobj = elf_hash_table(info)->dynobj;
2825 ia64_info = elfNN_ia64_hash_table (info);
2826 ia64_info->self_dtpmod_offset = (bfd_vma) -1;
2827 BFD_ASSERT(dynobj != NULL);
2828 data.info = info;
2830 /* Set the contents of the .interp section to the interpreter. */
2831 if (ia64_info->root.dynamic_sections_created
2832 && info->executable)
2834 sec = bfd_get_section_by_name (dynobj, ".interp");
2835 BFD_ASSERT (sec != NULL);
2836 sec->contents = (bfd_byte *) ELF_DYNAMIC_INTERPRETER;
2837 sec->_raw_size = strlen (ELF_DYNAMIC_INTERPRETER) + 1;
2840 /* Allocate the GOT entries. */
2842 if (ia64_info->got_sec)
2844 data.ofs = 0;
2845 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
2846 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
2847 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
2848 ia64_info->got_sec->_raw_size = data.ofs;
2851 /* Allocate the FPTR entries. */
2853 if (ia64_info->fptr_sec)
2855 data.ofs = 0;
2856 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
2857 ia64_info->fptr_sec->_raw_size = data.ofs;
2860 /* Now that we've seen all of the input files, we can decide which
2861 symbols need plt entries. Allocate the minimal PLT entries first.
2862 We do this even though dynamic_sections_created may be FALSE, because
2863 this has the side-effect of clearing want_plt and want_plt2. */
2865 data.ofs = 0;
2866 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
2868 ia64_info->minplt_entries = 0;
2869 if (data.ofs)
2871 ia64_info->minplt_entries
2872 = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
2875 /* Align the pointer for the plt2 entries. */
2876 data.ofs = (data.ofs + 31) & (bfd_vma) -32;
2878 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
2879 if (data.ofs != 0)
2881 BFD_ASSERT (ia64_info->root.dynamic_sections_created);
2883 ia64_info->plt_sec->_raw_size = data.ofs;
2885 /* If we've got a .plt, we need some extra memory for the dynamic
2886 linker. We stuff these in .got.plt. */
2887 sec = bfd_get_section_by_name (dynobj, ".got.plt");
2888 sec->_raw_size = 8 * PLT_RESERVED_WORDS;
2891 /* Allocate the PLTOFF entries. */
2893 if (ia64_info->pltoff_sec)
2895 data.ofs = 0;
2896 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
2897 ia64_info->pltoff_sec->_raw_size = data.ofs;
2900 if (ia64_info->root.dynamic_sections_created)
2902 /* Allocate space for the dynamic relocations that turned out to be
2903 required. */
2905 if (info->shared && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
2906 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2907 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
2910 /* We have now determined the sizes of the various dynamic sections.
2911 Allocate memory for them. */
2912 for (sec = dynobj->sections; sec != NULL; sec = sec->next)
2914 bfd_boolean strip;
2916 if (!(sec->flags & SEC_LINKER_CREATED))
2917 continue;
2919 /* If we don't need this section, strip it from the output file.
2920 There were several sections primarily related to dynamic
2921 linking that must be create before the linker maps input
2922 sections to output sections. The linker does that before
2923 bfd_elf_size_dynamic_sections is called, and it is that
2924 function which decides whether anything needs to go into
2925 these sections. */
2927 strip = (sec->_raw_size == 0);
2929 if (sec == ia64_info->got_sec)
2930 strip = FALSE;
2931 else if (sec == ia64_info->rel_got_sec)
2933 if (strip)
2934 ia64_info->rel_got_sec = NULL;
2935 else
2936 /* We use the reloc_count field as a counter if we need to
2937 copy relocs into the output file. */
2938 sec->reloc_count = 0;
2940 else if (sec == ia64_info->fptr_sec)
2942 if (strip)
2943 ia64_info->fptr_sec = NULL;
2945 else if (sec == ia64_info->rel_fptr_sec)
2947 if (strip)
2948 ia64_info->rel_fptr_sec = NULL;
2949 else
2950 /* We use the reloc_count field as a counter if we need to
2951 copy relocs into the output file. */
2952 sec->reloc_count = 0;
2954 else if (sec == ia64_info->plt_sec)
2956 if (strip)
2957 ia64_info->plt_sec = NULL;
2959 else if (sec == ia64_info->pltoff_sec)
2961 if (strip)
2962 ia64_info->pltoff_sec = NULL;
2964 else if (sec == ia64_info->rel_pltoff_sec)
2966 if (strip)
2967 ia64_info->rel_pltoff_sec = NULL;
2968 else
2970 relplt = TRUE;
2971 /* We use the reloc_count field as a counter if we need to
2972 copy relocs into the output file. */
2973 sec->reloc_count = 0;
2976 else
2978 const char *name;
2980 /* It's OK to base decisions on the section name, because none
2981 of the dynobj section names depend upon the input files. */
2982 name = bfd_get_section_name (dynobj, sec);
2984 if (strcmp (name, ".got.plt") == 0)
2985 strip = FALSE;
2986 else if (strncmp (name, ".rel", 4) == 0)
2988 if (!strip)
2990 /* We use the reloc_count field as a counter if we need to
2991 copy relocs into the output file. */
2992 sec->reloc_count = 0;
2995 else
2996 continue;
2999 if (strip)
3000 _bfd_strip_section_from_output (info, sec);
3001 else
3003 /* Allocate memory for the section contents. */
3004 sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->_raw_size);
3005 if (sec->contents == NULL && sec->_raw_size != 0)
3006 return FALSE;
3010 if (elf_hash_table (info)->dynamic_sections_created)
3012 /* Add some entries to the .dynamic section. We fill in the values
3013 later (in finish_dynamic_sections) but we must add the entries now
3014 so that we get the correct size for the .dynamic section. */
3016 if (info->executable)
3018 /* The DT_DEBUG entry is filled in by the dynamic linker and used
3019 by the debugger. */
3020 #define add_dynamic_entry(TAG, VAL) \
3021 bfd_elfNN_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
3023 if (!add_dynamic_entry (DT_DEBUG, 0))
3024 return FALSE;
3027 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
3028 return FALSE;
3029 if (!add_dynamic_entry (DT_PLTGOT, 0))
3030 return FALSE;
3032 if (relplt)
3034 if (!add_dynamic_entry (DT_PLTRELSZ, 0)
3035 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3036 || !add_dynamic_entry (DT_JMPREL, 0))
3037 return FALSE;
3040 if (!add_dynamic_entry (DT_RELA, 0)
3041 || !add_dynamic_entry (DT_RELASZ, 0)
3042 || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
3043 return FALSE;
3045 if (ia64_info->reltext)
3047 if (!add_dynamic_entry (DT_TEXTREL, 0))
3048 return FALSE;
3049 info->flags |= DF_TEXTREL;
3053 /* ??? Perhaps force __gp local. */
3055 return TRUE;
3058 static bfd_reloc_status_type
3059 elfNN_ia64_install_value (abfd, hit_addr, v, r_type)
3060 bfd *abfd;
3061 bfd_byte *hit_addr;
3062 bfd_vma v;
3063 unsigned int r_type;
3065 const struct ia64_operand *op;
3066 int bigendian = 0, shift = 0;
3067 bfd_vma t0, t1, insn, dword;
3068 enum ia64_opnd opnd;
3069 const char *err;
3070 size_t size = 8;
3071 #ifdef BFD_HOST_U_64_BIT
3072 BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
3073 #else
3074 bfd_vma val = v;
3075 #endif
3077 opnd = IA64_OPND_NIL;
3078 switch (r_type)
3080 case R_IA64_NONE:
3081 case R_IA64_LDXMOV:
3082 return bfd_reloc_ok;
3084 /* Instruction relocations. */
3086 case R_IA64_IMM14:
3087 case R_IA64_TPREL14:
3088 case R_IA64_DTPREL14:
3089 opnd = IA64_OPND_IMM14;
3090 break;
3092 case R_IA64_PCREL21F: opnd = IA64_OPND_TGT25; break;
3093 case R_IA64_PCREL21M: opnd = IA64_OPND_TGT25b; break;
3094 case R_IA64_PCREL60B: opnd = IA64_OPND_TGT64; break;
3095 case R_IA64_PCREL21B:
3096 case R_IA64_PCREL21BI:
3097 opnd = IA64_OPND_TGT25c;
3098 break;
3100 case R_IA64_IMM22:
3101 case R_IA64_GPREL22:
3102 case R_IA64_LTOFF22:
3103 case R_IA64_LTOFF22X:
3104 case R_IA64_PLTOFF22:
3105 case R_IA64_PCREL22:
3106 case R_IA64_LTOFF_FPTR22:
3107 case R_IA64_TPREL22:
3108 case R_IA64_DTPREL22:
3109 case R_IA64_LTOFF_TPREL22:
3110 case R_IA64_LTOFF_DTPMOD22:
3111 case R_IA64_LTOFF_DTPREL22:
3112 opnd = IA64_OPND_IMM22;
3113 break;
3115 case R_IA64_IMM64:
3116 case R_IA64_GPREL64I:
3117 case R_IA64_LTOFF64I:
3118 case R_IA64_PLTOFF64I:
3119 case R_IA64_PCREL64I:
3120 case R_IA64_FPTR64I:
3121 case R_IA64_LTOFF_FPTR64I:
3122 case R_IA64_TPREL64I:
3123 case R_IA64_DTPREL64I:
3124 opnd = IA64_OPND_IMMU64;
3125 break;
3127 /* Data relocations. */
3129 case R_IA64_DIR32MSB:
3130 case R_IA64_GPREL32MSB:
3131 case R_IA64_FPTR32MSB:
3132 case R_IA64_PCREL32MSB:
3133 case R_IA64_LTOFF_FPTR32MSB:
3134 case R_IA64_SEGREL32MSB:
3135 case R_IA64_SECREL32MSB:
3136 case R_IA64_LTV32MSB:
3137 case R_IA64_DTPREL32MSB:
3138 size = 4; bigendian = 1;
3139 break;
3141 case R_IA64_DIR32LSB:
3142 case R_IA64_GPREL32LSB:
3143 case R_IA64_FPTR32LSB:
3144 case R_IA64_PCREL32LSB:
3145 case R_IA64_LTOFF_FPTR32LSB:
3146 case R_IA64_SEGREL32LSB:
3147 case R_IA64_SECREL32LSB:
3148 case R_IA64_LTV32LSB:
3149 case R_IA64_DTPREL32LSB:
3150 size = 4; bigendian = 0;
3151 break;
3153 case R_IA64_DIR64MSB:
3154 case R_IA64_GPREL64MSB:
3155 case R_IA64_PLTOFF64MSB:
3156 case R_IA64_FPTR64MSB:
3157 case R_IA64_PCREL64MSB:
3158 case R_IA64_LTOFF_FPTR64MSB:
3159 case R_IA64_SEGREL64MSB:
3160 case R_IA64_SECREL64MSB:
3161 case R_IA64_LTV64MSB:
3162 case R_IA64_TPREL64MSB:
3163 case R_IA64_DTPMOD64MSB:
3164 case R_IA64_DTPREL64MSB:
3165 size = 8; bigendian = 1;
3166 break;
3168 case R_IA64_DIR64LSB:
3169 case R_IA64_GPREL64LSB:
3170 case R_IA64_PLTOFF64LSB:
3171 case R_IA64_FPTR64LSB:
3172 case R_IA64_PCREL64LSB:
3173 case R_IA64_LTOFF_FPTR64LSB:
3174 case R_IA64_SEGREL64LSB:
3175 case R_IA64_SECREL64LSB:
3176 case R_IA64_LTV64LSB:
3177 case R_IA64_TPREL64LSB:
3178 case R_IA64_DTPMOD64LSB:
3179 case R_IA64_DTPREL64LSB:
3180 size = 8; bigendian = 0;
3181 break;
3183 /* Unsupported / Dynamic relocations. */
3184 default:
3185 return bfd_reloc_notsupported;
3188 switch (opnd)
3190 case IA64_OPND_IMMU64:
3191 hit_addr -= (long) hit_addr & 0x3;
3192 t0 = bfd_get_64 (abfd, hit_addr);
3193 t1 = bfd_get_64 (abfd, hit_addr + 8);
3195 /* tmpl/s: bits 0.. 5 in t0
3196 slot 0: bits 5..45 in t0
3197 slot 1: bits 46..63 in t0, bits 0..22 in t1
3198 slot 2: bits 23..63 in t1 */
3200 /* First, clear the bits that form the 64 bit constant. */
3201 t0 &= ~(0x3ffffLL << 46);
3202 t1 &= ~(0x7fffffLL
3203 | (( (0x07fLL << 13) | (0x1ffLL << 27)
3204 | (0x01fLL << 22) | (0x001LL << 21)
3205 | (0x001LL << 36)) << 23));
3207 t0 |= ((val >> 22) & 0x03ffffLL) << 46; /* 18 lsbs of imm41 */
3208 t1 |= ((val >> 40) & 0x7fffffLL) << 0; /* 23 msbs of imm41 */
3209 t1 |= ( (((val >> 0) & 0x07f) << 13) /* imm7b */
3210 | (((val >> 7) & 0x1ff) << 27) /* imm9d */
3211 | (((val >> 16) & 0x01f) << 22) /* imm5c */
3212 | (((val >> 21) & 0x001) << 21) /* ic */
3213 | (((val >> 63) & 0x001) << 36)) << 23; /* i */
3215 bfd_put_64 (abfd, t0, hit_addr);
3216 bfd_put_64 (abfd, t1, hit_addr + 8);
3217 break;
3219 case IA64_OPND_TGT64:
3220 hit_addr -= (long) hit_addr & 0x3;
3221 t0 = bfd_get_64 (abfd, hit_addr);
3222 t1 = bfd_get_64 (abfd, hit_addr + 8);
3224 /* tmpl/s: bits 0.. 5 in t0
3225 slot 0: bits 5..45 in t0
3226 slot 1: bits 46..63 in t0, bits 0..22 in t1
3227 slot 2: bits 23..63 in t1 */
3229 /* First, clear the bits that form the 64 bit constant. */
3230 t0 &= ~(0x3ffffLL << 46);
3231 t1 &= ~(0x7fffffLL
3232 | ((1LL << 36 | 0xfffffLL << 13) << 23));
3234 val >>= 4;
3235 t0 |= ((val >> 20) & 0xffffLL) << 2 << 46; /* 16 lsbs of imm39 */
3236 t1 |= ((val >> 36) & 0x7fffffLL) << 0; /* 23 msbs of imm39 */
3237 t1 |= ((((val >> 0) & 0xfffffLL) << 13) /* imm20b */
3238 | (((val >> 59) & 0x1LL) << 36)) << 23; /* i */
3240 bfd_put_64 (abfd, t0, hit_addr);
3241 bfd_put_64 (abfd, t1, hit_addr + 8);
3242 break;
3244 default:
3245 switch ((long) hit_addr & 0x3)
3247 case 0: shift = 5; break;
3248 case 1: shift = 14; hit_addr += 3; break;
3249 case 2: shift = 23; hit_addr += 6; break;
3250 case 3: return bfd_reloc_notsupported; /* shouldn't happen... */
3252 dword = bfd_get_64 (abfd, hit_addr);
3253 insn = (dword >> shift) & 0x1ffffffffffLL;
3255 op = elf64_ia64_operands + opnd;
3256 err = (*op->insert) (op, val, (ia64_insn *)& insn);
3257 if (err)
3258 return bfd_reloc_overflow;
3260 dword &= ~(0x1ffffffffffLL << shift);
3261 dword |= (insn << shift);
3262 bfd_put_64 (abfd, dword, hit_addr);
3263 break;
3265 case IA64_OPND_NIL:
3266 /* A data relocation. */
3267 if (bigendian)
3268 if (size == 4)
3269 bfd_putb32 (val, hit_addr);
3270 else
3271 bfd_putb64 (val, hit_addr);
3272 else
3273 if (size == 4)
3274 bfd_putl32 (val, hit_addr);
3275 else
3276 bfd_putl64 (val, hit_addr);
3277 break;
3280 return bfd_reloc_ok;
3283 static void
3284 elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
3285 dynindx, addend)
3286 bfd *abfd;
3287 struct bfd_link_info *info;
3288 asection *sec;
3289 asection *srel;
3290 bfd_vma offset;
3291 unsigned int type;
3292 long dynindx;
3293 bfd_vma addend;
3295 Elf_Internal_Rela outrel;
3296 bfd_byte *loc;
3298 BFD_ASSERT (dynindx != -1);
3299 outrel.r_info = ELFNN_R_INFO (dynindx, type);
3300 outrel.r_addend = addend;
3301 outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
3302 if (outrel.r_offset >= (bfd_vma) -2)
3304 /* Run for the hills. We shouldn't be outputting a relocation
3305 for this. So do what everyone else does and output a no-op. */
3306 outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
3307 outrel.r_addend = 0;
3308 outrel.r_offset = 0;
3310 else
3311 outrel.r_offset += sec->output_section->vma + sec->output_offset;
3313 loc = srel->contents;
3314 loc += srel->reloc_count++ * sizeof (ElfNN_External_Rela);
3315 bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3316 BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count
3317 <= srel->_cooked_size);
3320 /* Store an entry for target address TARGET_ADDR in the linkage table
3321 and return the gp-relative address of the linkage table entry. */
3323 static bfd_vma
3324 set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
3325 bfd *abfd;
3326 struct bfd_link_info *info;
3327 struct elfNN_ia64_dyn_sym_info *dyn_i;
3328 long dynindx;
3329 bfd_vma addend;
3330 bfd_vma value;
3331 unsigned int dyn_r_type;
3333 struct elfNN_ia64_link_hash_table *ia64_info;
3334 asection *got_sec;
3335 bfd_boolean done;
3336 bfd_vma got_offset;
3338 ia64_info = elfNN_ia64_hash_table (info);
3339 got_sec = ia64_info->got_sec;
3341 switch (dyn_r_type)
3343 case R_IA64_TPREL64LSB:
3344 done = dyn_i->tprel_done;
3345 dyn_i->tprel_done = TRUE;
3346 got_offset = dyn_i->tprel_offset;
3347 break;
3348 case R_IA64_DTPMOD64LSB:
3349 if (dyn_i->dtpmod_offset != ia64_info->self_dtpmod_offset)
3351 done = dyn_i->dtpmod_done;
3352 dyn_i->dtpmod_done = TRUE;
3354 else
3356 done = ia64_info->self_dtpmod_done;
3357 ia64_info->self_dtpmod_done = TRUE;
3358 dynindx = 0;
3360 got_offset = dyn_i->dtpmod_offset;
3361 break;
3362 case R_IA64_DTPREL64LSB:
3363 done = dyn_i->dtprel_done;
3364 dyn_i->dtprel_done = TRUE;
3365 got_offset = dyn_i->dtprel_offset;
3366 break;
3367 default:
3368 done = dyn_i->got_done;
3369 dyn_i->got_done = TRUE;
3370 got_offset = dyn_i->got_offset;
3371 break;
3374 BFD_ASSERT ((got_offset & 7) == 0);
3376 if (! done)
3378 /* Store the target address in the linkage table entry. */
3379 bfd_put_64 (abfd, value, got_sec->contents + got_offset);
3381 /* Install a dynamic relocation if needed. */
3382 if (((info->shared
3383 && (!dyn_i->h
3384 || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
3385 || dyn_i->h->root.type != bfd_link_hash_undefweak)
3386 && dyn_r_type != R_IA64_DTPREL64LSB)
3387 || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info, dyn_r_type)
3388 || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
3389 && (!dyn_i->want_ltoff_fptr
3390 || !info->pie
3391 || !dyn_i->h
3392 || dyn_i->h->root.type != bfd_link_hash_undefweak))
3394 if (dynindx == -1
3395 && dyn_r_type != R_IA64_TPREL64LSB
3396 && dyn_r_type != R_IA64_DTPMOD64LSB
3397 && dyn_r_type != R_IA64_DTPREL64LSB)
3399 dyn_r_type = R_IA64_REL64LSB;
3400 dynindx = 0;
3401 addend = value;
3404 if (bfd_big_endian (abfd))
3406 switch (dyn_r_type)
3408 case R_IA64_REL64LSB:
3409 dyn_r_type = R_IA64_REL64MSB;
3410 break;
3411 case R_IA64_DIR64LSB:
3412 dyn_r_type = R_IA64_DIR64MSB;
3413 break;
3414 case R_IA64_FPTR64LSB:
3415 dyn_r_type = R_IA64_FPTR64MSB;
3416 break;
3417 case R_IA64_TPREL64LSB:
3418 dyn_r_type = R_IA64_TPREL64MSB;
3419 break;
3420 case R_IA64_DTPMOD64LSB:
3421 dyn_r_type = R_IA64_DTPMOD64MSB;
3422 break;
3423 case R_IA64_DTPREL64LSB:
3424 dyn_r_type = R_IA64_DTPREL64MSB;
3425 break;
3426 default:
3427 BFD_ASSERT (FALSE);
3428 break;
3432 elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
3433 ia64_info->rel_got_sec,
3434 got_offset, dyn_r_type,
3435 dynindx, addend);
3439 /* Return the address of the linkage table entry. */
3440 value = (got_sec->output_section->vma
3441 + got_sec->output_offset
3442 + got_offset);
3444 return value;
3447 /* Fill in a function descriptor consisting of the function's code
3448 address and its global pointer. Return the descriptor's address. */
3450 static bfd_vma
3451 set_fptr_entry (abfd, info, dyn_i, value)
3452 bfd *abfd;
3453 struct bfd_link_info *info;
3454 struct elfNN_ia64_dyn_sym_info *dyn_i;
3455 bfd_vma value;
3457 struct elfNN_ia64_link_hash_table *ia64_info;
3458 asection *fptr_sec;
3460 ia64_info = elfNN_ia64_hash_table (info);
3461 fptr_sec = ia64_info->fptr_sec;
3463 if (!dyn_i->fptr_done)
3465 dyn_i->fptr_done = 1;
3467 /* Fill in the function descriptor. */
3468 bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
3469 bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
3470 fptr_sec->contents + dyn_i->fptr_offset + 8);
3471 if (ia64_info->rel_fptr_sec)
3473 Elf_Internal_Rela outrel;
3474 bfd_byte *loc;
3476 if (bfd_little_endian (abfd))
3477 outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTLSB);
3478 else
3479 outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTMSB);
3480 outrel.r_addend = value;
3481 outrel.r_offset = (fptr_sec->output_section->vma
3482 + fptr_sec->output_offset
3483 + dyn_i->fptr_offset);
3484 loc = ia64_info->rel_fptr_sec->contents;
3485 loc += ia64_info->rel_fptr_sec->reloc_count++
3486 * sizeof (ElfNN_External_Rela);
3487 bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3491 /* Return the descriptor's address. */
3492 value = (fptr_sec->output_section->vma
3493 + fptr_sec->output_offset
3494 + dyn_i->fptr_offset);
3496 return value;
3499 /* Fill in a PLTOFF entry consisting of the function's code address
3500 and its global pointer. Return the descriptor's address. */
3502 static bfd_vma
3503 set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
3504 bfd *abfd;
3505 struct bfd_link_info *info;
3506 struct elfNN_ia64_dyn_sym_info *dyn_i;
3507 bfd_vma value;
3508 bfd_boolean is_plt;
3510 struct elfNN_ia64_link_hash_table *ia64_info;
3511 asection *pltoff_sec;
3513 ia64_info = elfNN_ia64_hash_table (info);
3514 pltoff_sec = ia64_info->pltoff_sec;
3516 /* Don't do anything if this symbol uses a real PLT entry. In
3517 that case, we'll fill this in during finish_dynamic_symbol. */
3518 if ((! dyn_i->want_plt || is_plt)
3519 && !dyn_i->pltoff_done)
3521 bfd_vma gp = _bfd_get_gp_value (abfd);
3523 /* Fill in the function descriptor. */
3524 bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
3525 bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
3527 /* Install dynamic relocations if needed. */
3528 if (!is_plt
3529 && info->shared
3530 && (!dyn_i->h
3531 || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
3532 || dyn_i->h->root.type != bfd_link_hash_undefweak))
3534 unsigned int dyn_r_type;
3536 if (bfd_big_endian (abfd))
3537 dyn_r_type = R_IA64_REL64MSB;
3538 else
3539 dyn_r_type = R_IA64_REL64LSB;
3541 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3542 ia64_info->rel_pltoff_sec,
3543 dyn_i->pltoff_offset,
3544 dyn_r_type, 0, value);
3545 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3546 ia64_info->rel_pltoff_sec,
3547 dyn_i->pltoff_offset + 8,
3548 dyn_r_type, 0, gp);
3551 dyn_i->pltoff_done = 1;
3554 /* Return the descriptor's address. */
3555 value = (pltoff_sec->output_section->vma
3556 + pltoff_sec->output_offset
3557 + dyn_i->pltoff_offset);
3559 return value;
3562 /* Return the base VMA address which should be subtracted from real addresses
3563 when resolving @tprel() relocation.
3564 Main program TLS (whose template starts at PT_TLS p_vaddr)
3565 is assigned offset round(16, PT_TLS p_align). */
3567 static bfd_vma
3568 elfNN_ia64_tprel_base (info)
3569 struct bfd_link_info *info;
3571 asection *tls_sec = elf_hash_table (info)->tls_sec;
3573 BFD_ASSERT (tls_sec != NULL);
3574 return tls_sec->vma - align_power ((bfd_vma) 16, tls_sec->alignment_power);
3577 /* Return the base VMA address which should be subtracted from real addresses
3578 when resolving @dtprel() relocation.
3579 This is PT_TLS segment p_vaddr. */
3581 static bfd_vma
3582 elfNN_ia64_dtprel_base (info)
3583 struct bfd_link_info *info;
3585 BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
3586 return elf_hash_table (info)->tls_sec->vma;
3589 /* Called through qsort to sort the .IA_64.unwind section during a
3590 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3591 to the output bfd so we can do proper endianness frobbing. */
3593 static bfd *elfNN_ia64_unwind_entry_compare_bfd;
3595 static int
3596 elfNN_ia64_unwind_entry_compare (a, b)
3597 const PTR a;
3598 const PTR b;
3600 bfd_vma av, bv;
3602 av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
3603 bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
3605 return (av < bv ? -1 : av > bv ? 1 : 0);
3608 /* Make sure we've got ourselves a nice fat __gp value. */
3609 static bfd_boolean
3610 elfNN_ia64_choose_gp (abfd, info)
3611 bfd *abfd;
3612 struct bfd_link_info *info;
3614 bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
3615 bfd_vma min_short_vma = min_vma, max_short_vma = 0;
3616 struct elf_link_hash_entry *gp;
3617 bfd_vma gp_val;
3618 asection *os;
3619 struct elfNN_ia64_link_hash_table *ia64_info;
3621 ia64_info = elfNN_ia64_hash_table (info);
3623 /* Find the min and max vma of all sections marked short. Also collect
3624 min and max vma of any type, for use in selecting a nice gp. */
3625 for (os = abfd->sections; os ; os = os->next)
3627 bfd_vma lo, hi;
3629 if ((os->flags & SEC_ALLOC) == 0)
3630 continue;
3632 lo = os->vma;
3633 hi = os->vma + os->_raw_size;
3634 if (hi < lo)
3635 hi = (bfd_vma) -1;
3637 if (min_vma > lo)
3638 min_vma = lo;
3639 if (max_vma < hi)
3640 max_vma = hi;
3641 if (os->flags & SEC_SMALL_DATA)
3643 if (min_short_vma > lo)
3644 min_short_vma = lo;
3645 if (max_short_vma < hi)
3646 max_short_vma = hi;
3650 /* See if the user wants to force a value. */
3651 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3652 FALSE, FALSE);
3654 if (gp
3655 && (gp->root.type == bfd_link_hash_defined
3656 || gp->root.type == bfd_link_hash_defweak))
3658 asection *gp_sec = gp->root.u.def.section;
3659 gp_val = (gp->root.u.def.value
3660 + gp_sec->output_section->vma
3661 + gp_sec->output_offset);
3663 else
3665 /* Pick a sensible value. */
3667 asection *got_sec = ia64_info->got_sec;
3669 /* Start with just the address of the .got. */
3670 if (got_sec)
3671 gp_val = got_sec->output_section->vma;
3672 else if (max_short_vma != 0)
3673 gp_val = min_short_vma;
3674 else
3675 gp_val = min_vma;
3677 /* If it is possible to address the entire image, but we
3678 don't with the choice above, adjust. */
3679 if (max_vma - min_vma < 0x400000
3680 && max_vma - gp_val <= 0x200000
3681 && gp_val - min_vma > 0x200000)
3682 gp_val = min_vma + 0x200000;
3683 else if (max_short_vma != 0)
3685 /* If we don't cover all the short data, adjust. */
3686 if (max_short_vma - gp_val >= 0x200000)
3687 gp_val = min_short_vma + 0x200000;
3689 /* If we're addressing stuff past the end, adjust back. */
3690 if (gp_val > max_vma)
3691 gp_val = max_vma - 0x200000 + 8;
3695 /* Validate whether all SHF_IA_64_SHORT sections are within
3696 range of the chosen GP. */
3698 if (max_short_vma != 0)
3700 if (max_short_vma - min_short_vma >= 0x400000)
3702 (*_bfd_error_handler)
3703 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3704 bfd_get_filename (abfd),
3705 (unsigned long) (max_short_vma - min_short_vma));
3706 return FALSE;
3708 else if ((gp_val > min_short_vma
3709 && gp_val - min_short_vma > 0x200000)
3710 || (gp_val < max_short_vma
3711 && max_short_vma - gp_val >= 0x200000))
3713 (*_bfd_error_handler)
3714 (_("%s: __gp does not cover short data segment"),
3715 bfd_get_filename (abfd));
3716 return FALSE;
3720 _bfd_set_gp_value (abfd, gp_val);
3722 return TRUE;
3725 static bfd_boolean
3726 elfNN_ia64_final_link (abfd, info)
3727 bfd *abfd;
3728 struct bfd_link_info *info;
3730 struct elfNN_ia64_link_hash_table *ia64_info;
3731 asection *unwind_output_sec;
3733 ia64_info = elfNN_ia64_hash_table (info);
3735 /* Make sure we've got ourselves a nice fat __gp value. */
3736 if (!info->relocatable)
3738 bfd_vma gp_val = _bfd_get_gp_value (abfd);
3739 struct elf_link_hash_entry *gp;
3741 if (gp_val == 0)
3743 if (! elfNN_ia64_choose_gp (abfd, info))
3744 return FALSE;
3745 gp_val = _bfd_get_gp_value (abfd);
3748 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3749 FALSE, FALSE);
3750 if (gp)
3752 gp->root.type = bfd_link_hash_defined;
3753 gp->root.u.def.value = gp_val;
3754 gp->root.u.def.section = bfd_abs_section_ptr;
3758 /* If we're producing a final executable, we need to sort the contents
3759 of the .IA_64.unwind section. Force this section to be relocated
3760 into memory rather than written immediately to the output file. */
3761 unwind_output_sec = NULL;
3762 if (!info->relocatable)
3764 asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3765 if (s)
3767 unwind_output_sec = s->output_section;
3768 unwind_output_sec->contents
3769 = bfd_malloc (unwind_output_sec->_raw_size);
3770 if (unwind_output_sec->contents == NULL)
3771 return FALSE;
3775 /* Invoke the regular ELF backend linker to do all the work. */
3776 if (!bfd_elfNN_bfd_final_link (abfd, info))
3777 return FALSE;
3779 if (unwind_output_sec)
3781 elfNN_ia64_unwind_entry_compare_bfd = abfd;
3782 qsort (unwind_output_sec->contents,
3783 (size_t) (unwind_output_sec->_raw_size / 24),
3785 elfNN_ia64_unwind_entry_compare);
3787 if (! bfd_set_section_contents (abfd, unwind_output_sec,
3788 unwind_output_sec->contents, (bfd_vma) 0,
3789 unwind_output_sec->_raw_size))
3790 return FALSE;
3793 return TRUE;
3796 static bfd_boolean
3797 elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
3798 contents, relocs, local_syms, local_sections)
3799 bfd *output_bfd;
3800 struct bfd_link_info *info;
3801 bfd *input_bfd;
3802 asection *input_section;
3803 bfd_byte *contents;
3804 Elf_Internal_Rela *relocs;
3805 Elf_Internal_Sym *local_syms;
3806 asection **local_sections;
3808 struct elfNN_ia64_link_hash_table *ia64_info;
3809 Elf_Internal_Shdr *symtab_hdr;
3810 Elf_Internal_Rela *rel;
3811 Elf_Internal_Rela *relend;
3812 asection *srel;
3813 bfd_boolean ret_val = TRUE; /* for non-fatal errors */
3814 bfd_vma gp_val;
3816 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3817 ia64_info = elfNN_ia64_hash_table (info);
3819 /* Infect various flags from the input section to the output section. */
3820 if (info->relocatable)
3822 bfd_vma flags;
3824 flags = elf_section_data(input_section)->this_hdr.sh_flags;
3825 flags &= SHF_IA_64_NORECOV;
3827 elf_section_data(input_section->output_section)
3828 ->this_hdr.sh_flags |= flags;
3829 return TRUE;
3832 gp_val = _bfd_get_gp_value (output_bfd);
3833 srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
3835 rel = relocs;
3836 relend = relocs + input_section->reloc_count;
3837 for (; rel < relend; ++rel)
3839 struct elf_link_hash_entry *h;
3840 struct elfNN_ia64_dyn_sym_info *dyn_i;
3841 bfd_reloc_status_type r;
3842 reloc_howto_type *howto;
3843 unsigned long r_symndx;
3844 Elf_Internal_Sym *sym;
3845 unsigned int r_type;
3846 bfd_vma value;
3847 asection *sym_sec;
3848 bfd_byte *hit_addr;
3849 bfd_boolean dynamic_symbol_p;
3850 bfd_boolean undef_weak_ref;
3852 r_type = ELFNN_R_TYPE (rel->r_info);
3853 if (r_type > R_IA64_MAX_RELOC_CODE)
3855 (*_bfd_error_handler)
3856 (_("%s: unknown relocation type %d"),
3857 bfd_archive_filename (input_bfd), (int)r_type);
3858 bfd_set_error (bfd_error_bad_value);
3859 ret_val = FALSE;
3860 continue;
3863 howto = lookup_howto (r_type);
3864 r_symndx = ELFNN_R_SYM (rel->r_info);
3865 h = NULL;
3866 sym = NULL;
3867 sym_sec = NULL;
3868 undef_weak_ref = FALSE;
3870 if (r_symndx < symtab_hdr->sh_info)
3872 /* Reloc against local symbol. */
3873 asection *msec;
3874 sym = local_syms + r_symndx;
3875 sym_sec = local_sections[r_symndx];
3876 msec = sym_sec;
3877 value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
3878 if ((sym_sec->flags & SEC_MERGE)
3879 && ELF_ST_TYPE (sym->st_info) == STT_SECTION
3880 && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
3882 struct elfNN_ia64_local_hash_entry *loc_h;
3884 loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
3885 if (loc_h && ! loc_h->sec_merge_done)
3887 struct elfNN_ia64_dyn_sym_info *dynent;
3889 for (dynent = loc_h->info; dynent; dynent = dynent->next)
3891 msec = sym_sec;
3892 dynent->addend =
3893 _bfd_merged_section_offset (output_bfd, &msec,
3894 elf_section_data (msec)->
3895 sec_info,
3896 sym->st_value
3897 + dynent->addend,
3898 (bfd_vma) 0);
3899 dynent->addend -= sym->st_value;
3900 dynent->addend += msec->output_section->vma
3901 + msec->output_offset
3902 - sym_sec->output_section->vma
3903 - sym_sec->output_offset;
3905 loc_h->sec_merge_done = 1;
3909 else
3911 bfd_boolean unresolved_reloc;
3912 bfd_boolean warned;
3914 RELOC_FOR_GLOBAL_SYMBOL (h, elf_sym_hashes (input_bfd),
3915 r_symndx,
3916 symtab_hdr, value, sym_sec,
3917 unresolved_reloc, info,
3918 warned);
3920 if (h->root.type == bfd_link_hash_undefweak)
3921 undef_weak_ref = TRUE;
3922 else if (warned)
3923 continue;
3926 hit_addr = contents + rel->r_offset;
3927 value += rel->r_addend;
3928 dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type);
3930 switch (r_type)
3932 case R_IA64_NONE:
3933 case R_IA64_LDXMOV:
3934 continue;
3936 case R_IA64_IMM14:
3937 case R_IA64_IMM22:
3938 case R_IA64_IMM64:
3939 case R_IA64_DIR32MSB:
3940 case R_IA64_DIR32LSB:
3941 case R_IA64_DIR64MSB:
3942 case R_IA64_DIR64LSB:
3943 /* Install a dynamic relocation for this reloc. */
3944 if ((dynamic_symbol_p || info->shared)
3945 && r_symndx != 0
3946 && (input_section->flags & SEC_ALLOC) != 0)
3948 unsigned int dyn_r_type;
3949 long dynindx;
3950 bfd_vma addend;
3952 BFD_ASSERT (srel != NULL);
3954 /* If we don't need dynamic symbol lookup, find a
3955 matching RELATIVE relocation. */
3956 dyn_r_type = r_type;
3957 if (dynamic_symbol_p)
3959 dynindx = h->dynindx;
3960 addend = rel->r_addend;
3961 value = 0;
3963 else
3965 switch (r_type)
3967 case R_IA64_DIR32MSB:
3968 dyn_r_type = R_IA64_REL32MSB;
3969 break;
3970 case R_IA64_DIR32LSB:
3971 dyn_r_type = R_IA64_REL32LSB;
3972 break;
3973 case R_IA64_DIR64MSB:
3974 dyn_r_type = R_IA64_REL64MSB;
3975 break;
3976 case R_IA64_DIR64LSB:
3977 dyn_r_type = R_IA64_REL64LSB;
3978 break;
3980 default:
3981 /* We can't represent this without a dynamic symbol.
3982 Adjust the relocation to be against an output
3983 section symbol, which are always present in the
3984 dynamic symbol table. */
3985 /* ??? People shouldn't be doing non-pic code in
3986 shared libraries. Hork. */
3987 (*_bfd_error_handler)
3988 (_("%s: linking non-pic code in a shared library"),
3989 bfd_archive_filename (input_bfd));
3990 ret_val = FALSE;
3991 continue;
3993 dynindx = 0;
3994 addend = value;
3997 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3998 srel, rel->r_offset, dyn_r_type,
3999 dynindx, addend);
4001 /* Fall through. */
4003 case R_IA64_LTV32MSB:
4004 case R_IA64_LTV32LSB:
4005 case R_IA64_LTV64MSB:
4006 case R_IA64_LTV64LSB:
4007 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4008 break;
4010 case R_IA64_GPREL22:
4011 case R_IA64_GPREL64I:
4012 case R_IA64_GPREL32MSB:
4013 case R_IA64_GPREL32LSB:
4014 case R_IA64_GPREL64MSB:
4015 case R_IA64_GPREL64LSB:
4016 if (dynamic_symbol_p)
4018 (*_bfd_error_handler)
4019 (_("%s: @gprel relocation against dynamic symbol %s"),
4020 bfd_archive_filename (input_bfd), h->root.root.string);
4021 ret_val = FALSE;
4022 continue;
4024 value -= gp_val;
4025 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4026 break;
4028 case R_IA64_LTOFF22:
4029 case R_IA64_LTOFF22X:
4030 case R_IA64_LTOFF64I:
4031 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4032 value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
4033 rel->r_addend, value, R_IA64_DIR64LSB);
4034 value -= gp_val;
4035 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4036 break;
4038 case R_IA64_PLTOFF22:
4039 case R_IA64_PLTOFF64I:
4040 case R_IA64_PLTOFF64MSB:
4041 case R_IA64_PLTOFF64LSB:
4042 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4043 value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
4044 value -= gp_val;
4045 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4046 break;
4048 case R_IA64_FPTR64I:
4049 case R_IA64_FPTR32MSB:
4050 case R_IA64_FPTR32LSB:
4051 case R_IA64_FPTR64MSB:
4052 case R_IA64_FPTR64LSB:
4053 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4054 if (dyn_i->want_fptr)
4056 if (!undef_weak_ref)
4057 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4059 if (!dyn_i->want_fptr || info->pie)
4061 long dynindx;
4062 unsigned int dyn_r_type = r_type;
4063 bfd_vma addend = rel->r_addend;
4065 /* Otherwise, we expect the dynamic linker to create
4066 the entry. */
4068 if (dyn_i->want_fptr)
4070 if (r_type == R_IA64_FPTR64I)
4072 /* We can't represent this without a dynamic symbol.
4073 Adjust the relocation to be against an output
4074 section symbol, which are always present in the
4075 dynamic symbol table. */
4076 /* ??? People shouldn't be doing non-pic code in
4077 shared libraries. Hork. */
4078 (*_bfd_error_handler)
4079 (_("%s: linking non-pic code in a position independent executable"),
4080 bfd_archive_filename (input_bfd));
4081 ret_val = FALSE;
4082 continue;
4084 dynindx = 0;
4085 addend = value;
4086 dyn_r_type = r_type + R_IA64_REL64LSB - R_IA64_FPTR64LSB;
4088 else if (h)
4090 if (h->dynindx != -1)
4091 dynindx = h->dynindx;
4092 else
4093 dynindx = (_bfd_elf_link_lookup_local_dynindx
4094 (info, h->root.u.def.section->owner,
4095 global_sym_index (h)));
4096 value = 0;
4098 else
4100 dynindx = (_bfd_elf_link_lookup_local_dynindx
4101 (info, input_bfd, (long) r_symndx));
4102 value = 0;
4105 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4106 srel, rel->r_offset, dyn_r_type,
4107 dynindx, addend);
4110 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4111 break;
4113 case R_IA64_LTOFF_FPTR22:
4114 case R_IA64_LTOFF_FPTR64I:
4115 case R_IA64_LTOFF_FPTR32MSB:
4116 case R_IA64_LTOFF_FPTR32LSB:
4117 case R_IA64_LTOFF_FPTR64MSB:
4118 case R_IA64_LTOFF_FPTR64LSB:
4120 long dynindx;
4122 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4123 if (dyn_i->want_fptr)
4125 BFD_ASSERT (h == NULL || h->dynindx == -1)
4126 if (!undef_weak_ref)
4127 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4128 dynindx = -1;
4130 else
4132 /* Otherwise, we expect the dynamic linker to create
4133 the entry. */
4134 if (h)
4136 if (h->dynindx != -1)
4137 dynindx = h->dynindx;
4138 else
4139 dynindx = (_bfd_elf_link_lookup_local_dynindx
4140 (info, h->root.u.def.section->owner,
4141 global_sym_index (h)));
4143 else
4144 dynindx = (_bfd_elf_link_lookup_local_dynindx
4145 (info, input_bfd, (long) r_symndx));
4146 value = 0;
4149 value = set_got_entry (output_bfd, info, dyn_i, dynindx,
4150 rel->r_addend, value, R_IA64_FPTR64LSB);
4151 value -= gp_val;
4152 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4154 break;
4156 case R_IA64_PCREL32MSB:
4157 case R_IA64_PCREL32LSB:
4158 case R_IA64_PCREL64MSB:
4159 case R_IA64_PCREL64LSB:
4160 /* Install a dynamic relocation for this reloc. */
4161 if (dynamic_symbol_p && r_symndx != 0)
4163 BFD_ASSERT (srel != NULL);
4165 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4166 srel, rel->r_offset, r_type,
4167 h->dynindx, rel->r_addend);
4169 goto finish_pcrel;
4171 case R_IA64_PCREL21B:
4172 case R_IA64_PCREL60B:
4173 /* We should have created a PLT entry for any dynamic symbol. */
4174 dyn_i = NULL;
4175 if (h)
4176 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4178 if (dyn_i && dyn_i->want_plt2)
4180 /* Should have caught this earlier. */
4181 BFD_ASSERT (rel->r_addend == 0);
4183 value = (ia64_info->plt_sec->output_section->vma
4184 + ia64_info->plt_sec->output_offset
4185 + dyn_i->plt2_offset);
4187 else
4189 /* Since there's no PLT entry, Validate that this is
4190 locally defined. */
4191 BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
4193 /* If the symbol is undef_weak, we shouldn't be trying
4194 to call it. There's every chance that we'd wind up
4195 with an out-of-range fixup here. Don't bother setting
4196 any value at all. */
4197 if (undef_weak_ref)
4198 continue;
4200 goto finish_pcrel;
4202 case R_IA64_PCREL21BI:
4203 case R_IA64_PCREL21F:
4204 case R_IA64_PCREL21M:
4205 case R_IA64_PCREL22:
4206 case R_IA64_PCREL64I:
4207 /* The PCREL21BI reloc is specifically not intended for use with
4208 dynamic relocs. PCREL21F and PCREL21M are used for speculation
4209 fixup code, and thus probably ought not be dynamic. The
4210 PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
4211 if (dynamic_symbol_p)
4213 const char *msg;
4215 if (r_type == R_IA64_PCREL21BI)
4216 msg = _("%s: @internal branch to dynamic symbol %s");
4217 else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
4218 msg = _("%s: speculation fixup to dynamic symbol %s");
4219 else
4220 msg = _("%s: @pcrel relocation against dynamic symbol %s");
4221 (*_bfd_error_handler) (msg, bfd_archive_filename (input_bfd),
4222 h->root.root.string);
4223 ret_val = FALSE;
4224 continue;
4226 goto finish_pcrel;
4228 finish_pcrel:
4229 /* Make pc-relative. */
4230 value -= (input_section->output_section->vma
4231 + input_section->output_offset
4232 + rel->r_offset) & ~ (bfd_vma) 0x3;
4233 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4234 break;
4236 case R_IA64_SEGREL32MSB:
4237 case R_IA64_SEGREL32LSB:
4238 case R_IA64_SEGREL64MSB:
4239 case R_IA64_SEGREL64LSB:
4240 if (r_symndx == 0)
4242 /* If the input section was discarded from the output, then
4243 do nothing. */
4244 r = bfd_reloc_ok;
4246 else
4248 struct elf_segment_map *m;
4249 Elf_Internal_Phdr *p;
4251 /* Find the segment that contains the output_section. */
4252 for (m = elf_tdata (output_bfd)->segment_map,
4253 p = elf_tdata (output_bfd)->phdr;
4254 m != NULL;
4255 m = m->next, p++)
4257 int i;
4258 for (i = m->count - 1; i >= 0; i--)
4259 if (m->sections[i] == input_section->output_section)
4260 break;
4261 if (i >= 0)
4262 break;
4265 if (m == NULL)
4267 r = bfd_reloc_notsupported;
4269 else
4271 /* The VMA of the segment is the vaddr of the associated
4272 program header. */
4273 if (value > p->p_vaddr)
4274 value -= p->p_vaddr;
4275 else
4276 value = 0;
4277 r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
4278 r_type);
4280 break;
4283 case R_IA64_SECREL32MSB:
4284 case R_IA64_SECREL32LSB:
4285 case R_IA64_SECREL64MSB:
4286 case R_IA64_SECREL64LSB:
4287 /* Make output-section relative. */
4288 if (value > input_section->output_section->vma)
4289 value -= input_section->output_section->vma;
4290 else
4291 value = 0;
4292 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4293 break;
4295 case R_IA64_IPLTMSB:
4296 case R_IA64_IPLTLSB:
4297 /* Install a dynamic relocation for this reloc. */
4298 if ((dynamic_symbol_p || info->shared)
4299 && (input_section->flags & SEC_ALLOC) != 0)
4301 BFD_ASSERT (srel != NULL);
4303 /* If we don't need dynamic symbol lookup, install two
4304 RELATIVE relocations. */
4305 if (!dynamic_symbol_p)
4307 unsigned int dyn_r_type;
4309 if (r_type == R_IA64_IPLTMSB)
4310 dyn_r_type = R_IA64_REL64MSB;
4311 else
4312 dyn_r_type = R_IA64_REL64LSB;
4314 elfNN_ia64_install_dyn_reloc (output_bfd, info,
4315 input_section,
4316 srel, rel->r_offset,
4317 dyn_r_type, 0, value);
4318 elfNN_ia64_install_dyn_reloc (output_bfd, info,
4319 input_section,
4320 srel, rel->r_offset + 8,
4321 dyn_r_type, 0, gp_val);
4323 else
4324 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4325 srel, rel->r_offset, r_type,
4326 h->dynindx, rel->r_addend);
4329 if (r_type == R_IA64_IPLTMSB)
4330 r_type = R_IA64_DIR64MSB;
4331 else
4332 r_type = R_IA64_DIR64LSB;
4333 elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4334 r = elfNN_ia64_install_value (output_bfd, hit_addr + 8, gp_val,
4335 r_type);
4336 break;
4338 case R_IA64_TPREL14:
4339 case R_IA64_TPREL22:
4340 case R_IA64_TPREL64I:
4341 value -= elfNN_ia64_tprel_base (info);
4342 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4343 break;
4345 case R_IA64_DTPREL14:
4346 case R_IA64_DTPREL22:
4347 case R_IA64_DTPREL64I:
4348 case R_IA64_DTPREL64LSB:
4349 case R_IA64_DTPREL64MSB:
4350 value -= elfNN_ia64_dtprel_base (info);
4351 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4352 break;
4354 case R_IA64_LTOFF_TPREL22:
4355 case R_IA64_LTOFF_DTPMOD22:
4356 case R_IA64_LTOFF_DTPREL22:
4358 int got_r_type;
4359 long dynindx = h ? h->dynindx : -1;
4360 bfd_vma r_addend = rel->r_addend;
4362 switch (r_type)
4364 default:
4365 case R_IA64_LTOFF_TPREL22:
4366 if (!dynamic_symbol_p)
4368 if (!info->shared)
4369 value -= elfNN_ia64_tprel_base (info);
4370 else
4372 r_addend += value - elfNN_ia64_dtprel_base (info);
4373 dynindx = 0;
4376 got_r_type = R_IA64_TPREL64LSB;
4377 break;
4378 case R_IA64_LTOFF_DTPMOD22:
4379 if (!dynamic_symbol_p && !info->shared)
4380 value = 1;
4381 got_r_type = R_IA64_DTPMOD64LSB;
4382 break;
4383 case R_IA64_LTOFF_DTPREL22:
4384 if (!dynamic_symbol_p)
4385 value -= elfNN_ia64_dtprel_base (info);
4386 got_r_type = R_IA64_DTPREL64LSB;
4387 break;
4389 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4390 value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
4391 value, got_r_type);
4392 value -= gp_val;
4393 r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
4394 r_type);
4396 break;
4398 default:
4399 r = bfd_reloc_notsupported;
4400 break;
4403 switch (r)
4405 case bfd_reloc_ok:
4406 break;
4408 case bfd_reloc_undefined:
4409 /* This can happen for global table relative relocs if
4410 __gp is undefined. This is a panic situation so we
4411 don't try to continue. */
4412 (*info->callbacks->undefined_symbol)
4413 (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
4414 return FALSE;
4416 case bfd_reloc_notsupported:
4418 const char *name;
4420 if (h)
4421 name = h->root.root.string;
4422 else
4424 name = bfd_elf_string_from_elf_section (input_bfd,
4425 symtab_hdr->sh_link,
4426 sym->st_name);
4427 if (name == NULL)
4428 return FALSE;
4429 if (*name == '\0')
4430 name = bfd_section_name (input_bfd, input_section);
4432 if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
4433 name, input_bfd,
4434 input_section, rel->r_offset))
4435 return FALSE;
4436 ret_val = FALSE;
4438 break;
4440 case bfd_reloc_dangerous:
4441 case bfd_reloc_outofrange:
4442 case bfd_reloc_overflow:
4443 default:
4445 const char *name;
4447 if (h)
4448 name = h->root.root.string;
4449 else
4451 name = bfd_elf_string_from_elf_section (input_bfd,
4452 symtab_hdr->sh_link,
4453 sym->st_name);
4454 if (name == NULL)
4455 return FALSE;
4456 if (*name == '\0')
4457 name = bfd_section_name (input_bfd, input_section);
4459 if (!(*info->callbacks->reloc_overflow) (info, name,
4460 howto->name,
4461 (bfd_vma) 0,
4462 input_bfd,
4463 input_section,
4464 rel->r_offset))
4465 return FALSE;
4466 ret_val = FALSE;
4468 break;
4472 return ret_val;
4475 static bfd_boolean
4476 elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
4477 bfd *output_bfd;
4478 struct bfd_link_info *info;
4479 struct elf_link_hash_entry *h;
4480 Elf_Internal_Sym *sym;
4482 struct elfNN_ia64_link_hash_table *ia64_info;
4483 struct elfNN_ia64_dyn_sym_info *dyn_i;
4485 ia64_info = elfNN_ia64_hash_table (info);
4486 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4488 /* Fill in the PLT data, if required. */
4489 if (dyn_i && dyn_i->want_plt)
4491 Elf_Internal_Rela outrel;
4492 bfd_byte *loc;
4493 asection *plt_sec;
4494 bfd_vma plt_addr, pltoff_addr, gp_val, index;
4496 gp_val = _bfd_get_gp_value (output_bfd);
4498 /* Initialize the minimal PLT entry. */
4500 index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
4501 plt_sec = ia64_info->plt_sec;
4502 loc = plt_sec->contents + dyn_i->plt_offset;
4504 memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
4505 elfNN_ia64_install_value (output_bfd, loc, index, R_IA64_IMM22);
4506 elfNN_ia64_install_value (output_bfd, loc+2, -dyn_i->plt_offset,
4507 R_IA64_PCREL21B);
4509 plt_addr = (plt_sec->output_section->vma
4510 + plt_sec->output_offset
4511 + dyn_i->plt_offset);
4512 pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
4514 /* Initialize the FULL PLT entry, if needed. */
4515 if (dyn_i->want_plt2)
4517 loc = plt_sec->contents + dyn_i->plt2_offset;
4519 memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
4520 elfNN_ia64_install_value (output_bfd, loc, pltoff_addr - gp_val,
4521 R_IA64_IMM22);
4523 /* Mark the symbol as undefined, rather than as defined in the
4524 plt section. Leave the value alone. */
4525 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4526 first place. But perhaps elflink.h did some for us. */
4527 if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
4528 sym->st_shndx = SHN_UNDEF;
4531 /* Create the dynamic relocation. */
4532 outrel.r_offset = pltoff_addr;
4533 if (bfd_little_endian (output_bfd))
4534 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
4535 else
4536 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
4537 outrel.r_addend = 0;
4539 /* This is fun. In the .IA_64.pltoff section, we've got entries
4540 that correspond both to real PLT entries, and those that
4541 happened to resolve to local symbols but need to be created
4542 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4543 relocations for the real PLT should come at the end of the
4544 section, so that they can be indexed by plt entry at runtime.
4546 We emitted all of the relocations for the non-PLT @pltoff
4547 entries during relocate_section. So we can consider the
4548 existing sec->reloc_count to be the base of the array of
4549 PLT relocations. */
4551 loc = ia64_info->rel_pltoff_sec->contents;
4552 loc += ((ia64_info->rel_pltoff_sec->reloc_count + index)
4553 * sizeof (ElfNN_External_Rela));
4554 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
4557 /* Mark some specially defined symbols as absolute. */
4558 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4559 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
4560 || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4561 sym->st_shndx = SHN_ABS;
4563 return TRUE;
4566 static bfd_boolean
4567 elfNN_ia64_finish_dynamic_sections (abfd, info)
4568 bfd *abfd;
4569 struct bfd_link_info *info;
4571 struct elfNN_ia64_link_hash_table *ia64_info;
4572 bfd *dynobj;
4574 ia64_info = elfNN_ia64_hash_table (info);
4575 dynobj = ia64_info->root.dynobj;
4577 if (elf_hash_table (info)->dynamic_sections_created)
4579 ElfNN_External_Dyn *dyncon, *dynconend;
4580 asection *sdyn, *sgotplt;
4581 bfd_vma gp_val;
4583 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4584 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
4585 BFD_ASSERT (sdyn != NULL);
4586 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
4587 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
4589 gp_val = _bfd_get_gp_value (abfd);
4591 for (; dyncon < dynconend; dyncon++)
4593 Elf_Internal_Dyn dyn;
4595 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
4597 switch (dyn.d_tag)
4599 case DT_PLTGOT:
4600 dyn.d_un.d_ptr = gp_val;
4601 break;
4603 case DT_PLTRELSZ:
4604 dyn.d_un.d_val = (ia64_info->minplt_entries
4605 * sizeof (ElfNN_External_Rela));
4606 break;
4608 case DT_JMPREL:
4609 /* See the comment above in finish_dynamic_symbol. */
4610 dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
4611 + ia64_info->rel_pltoff_sec->output_offset
4612 + (ia64_info->rel_pltoff_sec->reloc_count
4613 * sizeof (ElfNN_External_Rela)));
4614 break;
4616 case DT_IA_64_PLT_RESERVE:
4617 dyn.d_un.d_ptr = (sgotplt->output_section->vma
4618 + sgotplt->output_offset);
4619 break;
4621 case DT_RELASZ:
4622 /* Do not have RELASZ include JMPREL. This makes things
4623 easier on ld.so. This is not what the rest of BFD set up. */
4624 dyn.d_un.d_val -= (ia64_info->minplt_entries
4625 * sizeof (ElfNN_External_Rela));
4626 break;
4629 bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
4632 /* Initialize the PLT0 entry. */
4633 if (ia64_info->plt_sec)
4635 bfd_byte *loc = ia64_info->plt_sec->contents;
4636 bfd_vma pltres;
4638 memcpy (loc, plt_header, PLT_HEADER_SIZE);
4640 pltres = (sgotplt->output_section->vma
4641 + sgotplt->output_offset
4642 - gp_val);
4644 elfNN_ia64_install_value (abfd, loc+1, pltres, R_IA64_GPREL22);
4648 return TRUE;
4651 /* ELF file flag handling: */
4653 /* Function to keep IA-64 specific file flags. */
4654 static bfd_boolean
4655 elfNN_ia64_set_private_flags (abfd, flags)
4656 bfd *abfd;
4657 flagword flags;
4659 BFD_ASSERT (!elf_flags_init (abfd)
4660 || elf_elfheader (abfd)->e_flags == flags);
4662 elf_elfheader (abfd)->e_flags = flags;
4663 elf_flags_init (abfd) = TRUE;
4664 return TRUE;
4667 /* Merge backend specific data from an object file to the output
4668 object file when linking. */
4669 static bfd_boolean
4670 elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
4671 bfd *ibfd, *obfd;
4673 flagword out_flags;
4674 flagword in_flags;
4675 bfd_boolean ok = TRUE;
4677 /* Don't even pretend to support mixed-format linking. */
4678 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4679 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4680 return FALSE;
4682 in_flags = elf_elfheader (ibfd)->e_flags;
4683 out_flags = elf_elfheader (obfd)->e_flags;
4685 if (! elf_flags_init (obfd))
4687 elf_flags_init (obfd) = TRUE;
4688 elf_elfheader (obfd)->e_flags = in_flags;
4690 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4691 && bfd_get_arch_info (obfd)->the_default)
4693 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4694 bfd_get_mach (ibfd));
4697 return TRUE;
4700 /* Check flag compatibility. */
4701 if (in_flags == out_flags)
4702 return TRUE;
4704 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4705 if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
4706 elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
4708 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
4710 (*_bfd_error_handler)
4711 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4712 bfd_archive_filename (ibfd));
4714 bfd_set_error (bfd_error_bad_value);
4715 ok = FALSE;
4717 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
4719 (*_bfd_error_handler)
4720 (_("%s: linking big-endian files with little-endian files"),
4721 bfd_archive_filename (ibfd));
4723 bfd_set_error (bfd_error_bad_value);
4724 ok = FALSE;
4726 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4728 (*_bfd_error_handler)
4729 (_("%s: linking 64-bit files with 32-bit files"),
4730 bfd_archive_filename (ibfd));
4732 bfd_set_error (bfd_error_bad_value);
4733 ok = FALSE;
4735 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4737 (*_bfd_error_handler)
4738 (_("%s: linking constant-gp files with non-constant-gp files"),
4739 bfd_archive_filename (ibfd));
4741 bfd_set_error (bfd_error_bad_value);
4742 ok = FALSE;
4744 if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4745 != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4747 (*_bfd_error_handler)
4748 (_("%s: linking auto-pic files with non-auto-pic files"),
4749 bfd_archive_filename (ibfd));
4751 bfd_set_error (bfd_error_bad_value);
4752 ok = FALSE;
4755 return ok;
4758 static bfd_boolean
4759 elfNN_ia64_print_private_bfd_data (abfd, ptr)
4760 bfd *abfd;
4761 PTR ptr;
4763 FILE *file = (FILE *) ptr;
4764 flagword flags = elf_elfheader (abfd)->e_flags;
4766 BFD_ASSERT (abfd != NULL && ptr != NULL);
4768 fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4769 (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4770 (flags & EF_IA_64_EXT) ? "EXT, " : "",
4771 (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4772 (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4773 (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4774 (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4775 (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4776 (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4778 _bfd_elf_print_private_bfd_data (abfd, ptr);
4779 return TRUE;
4782 static enum elf_reloc_type_class
4783 elfNN_ia64_reloc_type_class (rela)
4784 const Elf_Internal_Rela *rela;
4786 switch ((int) ELFNN_R_TYPE (rela->r_info))
4788 case R_IA64_REL32MSB:
4789 case R_IA64_REL32LSB:
4790 case R_IA64_REL64MSB:
4791 case R_IA64_REL64LSB:
4792 return reloc_class_relative;
4793 case R_IA64_IPLTMSB:
4794 case R_IA64_IPLTLSB:
4795 return reloc_class_plt;
4796 case R_IA64_COPY:
4797 return reloc_class_copy;
4798 default:
4799 return reloc_class_normal;
4803 static struct bfd_elf_special_section const elfNN_ia64_special_sections[]=
4805 { ".sbss", 5, -1, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
4806 { ".sdata", 6, -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
4807 { NULL, 0, 0, 0, 0 }
4810 static bfd_boolean
4811 elfNN_ia64_hpux_vec (const bfd_target *vec)
4813 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
4814 return (vec == & bfd_elfNN_ia64_hpux_big_vec);
4817 static void
4818 elfNN_hpux_post_process_headers (abfd, info)
4819 bfd *abfd;
4820 struct bfd_link_info *info ATTRIBUTE_UNUSED;
4822 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
4824 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_HPUX;
4825 i_ehdrp->e_ident[EI_ABIVERSION] = 1;
4828 bfd_boolean
4829 elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
4830 bfd *abfd ATTRIBUTE_UNUSED;
4831 asection *sec;
4832 int *retval;
4834 if (bfd_is_com_section (sec))
4836 *retval = SHN_IA_64_ANSI_COMMON;
4837 return TRUE;
4839 return FALSE;
4842 static void
4843 elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
4844 asymbol *asym)
4846 elf_symbol_type *elfsym = (elf_symbol_type *) asym;;
4848 switch (elfsym->internal_elf_sym.st_shndx)
4850 case SHN_IA_64_ANSI_COMMON:
4851 asym->section = bfd_com_section_ptr;
4852 asym->value = elfsym->internal_elf_sym.st_size;
4853 asym->flags &= ~BSF_GLOBAL;
4854 break;
4859 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4860 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4861 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4862 #define TARGET_BIG_NAME "elfNN-ia64-big"
4863 #define ELF_ARCH bfd_arch_ia64
4864 #define ELF_MACHINE_CODE EM_IA_64
4865 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4866 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4867 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4869 #define elf_backend_section_from_shdr \
4870 elfNN_ia64_section_from_shdr
4871 #define elf_backend_section_flags \
4872 elfNN_ia64_section_flags
4873 #define elf_backend_fake_sections \
4874 elfNN_ia64_fake_sections
4875 #define elf_backend_final_write_processing \
4876 elfNN_ia64_final_write_processing
4877 #define elf_backend_add_symbol_hook \
4878 elfNN_ia64_add_symbol_hook
4879 #define elf_backend_additional_program_headers \
4880 elfNN_ia64_additional_program_headers
4881 #define elf_backend_modify_segment_map \
4882 elfNN_ia64_modify_segment_map
4883 #define elf_info_to_howto \
4884 elfNN_ia64_info_to_howto
4886 #define bfd_elfNN_bfd_reloc_type_lookup \
4887 elfNN_ia64_reloc_type_lookup
4888 #define bfd_elfNN_bfd_is_local_label_name \
4889 elfNN_ia64_is_local_label_name
4890 #define bfd_elfNN_bfd_relax_section \
4891 elfNN_ia64_relax_section
4893 /* Stuff for the BFD linker: */
4894 #define bfd_elfNN_bfd_link_hash_table_create \
4895 elfNN_ia64_hash_table_create
4896 #define bfd_elfNN_bfd_link_hash_table_free \
4897 elfNN_ia64_hash_table_free
4898 #define elf_backend_create_dynamic_sections \
4899 elfNN_ia64_create_dynamic_sections
4900 #define elf_backend_check_relocs \
4901 elfNN_ia64_check_relocs
4902 #define elf_backend_adjust_dynamic_symbol \
4903 elfNN_ia64_adjust_dynamic_symbol
4904 #define elf_backend_size_dynamic_sections \
4905 elfNN_ia64_size_dynamic_sections
4906 #define elf_backend_relocate_section \
4907 elfNN_ia64_relocate_section
4908 #define elf_backend_finish_dynamic_symbol \
4909 elfNN_ia64_finish_dynamic_symbol
4910 #define elf_backend_finish_dynamic_sections \
4911 elfNN_ia64_finish_dynamic_sections
4912 #define bfd_elfNN_bfd_final_link \
4913 elfNN_ia64_final_link
4915 #define bfd_elfNN_bfd_merge_private_bfd_data \
4916 elfNN_ia64_merge_private_bfd_data
4917 #define bfd_elfNN_bfd_set_private_flags \
4918 elfNN_ia64_set_private_flags
4919 #define bfd_elfNN_bfd_print_private_bfd_data \
4920 elfNN_ia64_print_private_bfd_data
4922 #define elf_backend_plt_readonly 1
4923 #define elf_backend_want_plt_sym 0
4924 #define elf_backend_plt_alignment 5
4925 #define elf_backend_got_header_size 0
4926 #define elf_backend_want_got_plt 1
4927 #define elf_backend_may_use_rel_p 1
4928 #define elf_backend_may_use_rela_p 1
4929 #define elf_backend_default_use_rela_p 1
4930 #define elf_backend_want_dynbss 0
4931 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4932 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4933 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
4934 #define elf_backend_rela_normal 1
4935 #define elf_backend_special_sections elfNN_ia64_special_sections
4937 #include "elfNN-target.h"
4939 /* HPUX-specific vectors. */
4941 #undef TARGET_LITTLE_SYM
4942 #undef TARGET_LITTLE_NAME
4943 #undef TARGET_BIG_SYM
4944 #define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
4945 #undef TARGET_BIG_NAME
4946 #define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
4948 /* These are HP-UX specific functions. */
4950 #undef elf_backend_post_process_headers
4951 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
4953 #undef elf_backend_section_from_bfd_section
4954 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
4956 #undef elf_backend_symbol_processing
4957 #define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
4959 #undef elf_backend_want_p_paddr_set_to_zero
4960 #define elf_backend_want_p_paddr_set_to_zero 1
4962 #undef ELF_MAXPAGESIZE
4963 #define ELF_MAXPAGESIZE 0x1000 /* 1K */
4965 #undef elfNN_bed
4966 #define elfNN_bed elfNN_ia64_hpux_bed
4968 #include "elfNN-target.h"
4970 #undef elf_backend_want_p_paddr_set_to_zero