* elf-bfd.h (struct elf_reloc_cookie): Remove locsym_shndx,
[deliverable/binutils-gdb.git] / bfd / elfxx-ia64.c
1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4
5 This file is part of BFD, the Binary File Descriptor library.
6
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.
11
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.
16
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. */
20
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
28 /*
29 * THE RULES for all the stuff the linker creates --
30 *
31 * GOT Entries created in response to LTOFF or LTOFF_FPTR
32 * relocations. Dynamic relocs created for dynamic
33 * symbols in an application; REL relocs for locals
34 * in a shared library.
35 *
36 * FPTR The canonical function descriptor. Created for local
37 * symbols in applications. Descriptors for dynamic symbols
38 * and local symbols in shared libraries are created by
39 * ld.so. Thus there are no dynamic relocs against these
40 * objects. The FPTR relocs for such _are_ passed through
41 * to the dynamic relocation tables.
42 *
43 * FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
44 * Requires the creation of a PLTOFF entry. This does not
45 * require any dynamic relocations.
46 *
47 * PLTOFF Created by PLTOFF relocations. For local symbols, this
48 * is an alternate function descriptor, and in shared libraries
49 * requires two REL relocations. Note that this cannot be
50 * transformed into an FPTR relocation, since it must be in
51 * range of the GP. For dynamic symbols, this is a function
52 * descriptor for a MIN_PLT entry, and requires one IPLT reloc.
53 *
54 * MIN_PLT Created by PLTOFF entries against dynamic symbols. This
55 * does not reqire dynamic relocations.
56 */
57
58 #define USE_RELA /* we want RELA relocs, not REL */
59
60 #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
61
62 typedef struct bfd_hash_entry *(*new_hash_entry_func)
63 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
64
65 /* In dynamically (linker-) created sections, we generally need to keep track
66 of the place a symbol or expression got allocated to. This is done via hash
67 tables that store entries of the following type. */
68
69 struct elfNN_ia64_dyn_sym_info
70 {
71 /* The addend for which this entry is relevant. */
72 bfd_vma addend;
73
74 /* Next addend in the list. */
75 struct elfNN_ia64_dyn_sym_info *next;
76
77 bfd_vma got_offset;
78 bfd_vma fptr_offset;
79 bfd_vma pltoff_offset;
80 bfd_vma plt_offset;
81 bfd_vma plt2_offset;
82 bfd_vma tprel_offset;
83 bfd_vma dtpmod_offset;
84 bfd_vma dtprel_offset;
85
86 /* The symbol table entry, if any, that this was derrived from. */
87 struct elf_link_hash_entry *h;
88
89 /* Used to count non-got, non-plt relocations for delayed sizing
90 of relocation sections. */
91 struct elfNN_ia64_dyn_reloc_entry
92 {
93 struct elfNN_ia64_dyn_reloc_entry *next;
94 asection *srel;
95 int type;
96 int count;
97 } *reloc_entries;
98
99 /* True when the section contents have been updated. */
100 unsigned got_done : 1;
101 unsigned fptr_done : 1;
102 unsigned pltoff_done : 1;
103 unsigned tprel_done : 1;
104 unsigned dtpmod_done : 1;
105 unsigned dtprel_done : 1;
106
107 /* True for the different kinds of linker data we want created. */
108 unsigned want_got : 1;
109 unsigned want_fptr : 1;
110 unsigned want_ltoff_fptr : 1;
111 unsigned want_plt : 1;
112 unsigned want_plt2 : 1;
113 unsigned want_pltoff : 1;
114 unsigned want_tprel : 1;
115 unsigned want_dtpmod : 1;
116 unsigned want_dtprel : 1;
117 };
118
119 struct elfNN_ia64_local_hash_entry
120 {
121 struct bfd_hash_entry root;
122 struct elfNN_ia64_dyn_sym_info *info;
123
124 /* True if this hash entry's addends was translated for
125 SHF_MERGE optimization. */
126 unsigned sec_merge_done : 1;
127 };
128
129 struct elfNN_ia64_local_hash_table
130 {
131 struct bfd_hash_table root;
132 /* No additional fields for now. */
133 };
134
135 struct elfNN_ia64_link_hash_entry
136 {
137 struct elf_link_hash_entry root;
138 struct elfNN_ia64_dyn_sym_info *info;
139 };
140
141 struct elfNN_ia64_link_hash_table
142 {
143 /* The main hash table */
144 struct elf_link_hash_table root;
145
146 asection *got_sec; /* the linkage table section (or NULL) */
147 asection *rel_got_sec; /* dynamic relocation section for same */
148 asection *fptr_sec; /* function descriptor table (or NULL) */
149 asection *plt_sec; /* the primary plt section (or NULL) */
150 asection *pltoff_sec; /* private descriptors for plt (or NULL) */
151 asection *rel_pltoff_sec; /* dynamic relocation section for same */
152
153 bfd_size_type minplt_entries; /* number of minplt entries */
154 unsigned reltext : 1; /* are there relocs against readonly sections? */
155
156 struct elfNN_ia64_local_hash_table loc_hash_table;
157 };
158
159 #define elfNN_ia64_hash_table(p) \
160 ((struct elfNN_ia64_link_hash_table *) ((p)->hash))
161
162 static bfd_reloc_status_type elfNN_ia64_reloc
163 PARAMS ((bfd *abfd, arelent *reloc, asymbol *sym, PTR data,
164 asection *input_section, bfd *output_bfd, char **error_message));
165 static reloc_howto_type * lookup_howto
166 PARAMS ((unsigned int rtype));
167 static reloc_howto_type *elfNN_ia64_reloc_type_lookup
168 PARAMS ((bfd *abfd, bfd_reloc_code_real_type bfd_code));
169 static void elfNN_ia64_info_to_howto
170 PARAMS ((bfd *abfd, arelent *bfd_reloc, ElfNN_Internal_Rela *elf_reloc));
171 static boolean elfNN_ia64_relax_section
172 PARAMS((bfd *abfd, asection *sec, struct bfd_link_info *link_info,
173 boolean *again));
174 static boolean is_unwind_section_name
175 PARAMS ((bfd *abfd, const char *));
176 static boolean elfNN_ia64_section_from_shdr
177 PARAMS ((bfd *, ElfNN_Internal_Shdr *, const char *));
178 static boolean elfNN_ia64_section_flags
179 PARAMS ((flagword *, ElfNN_Internal_Shdr *));
180 static boolean elfNN_ia64_fake_sections
181 PARAMS ((bfd *abfd, ElfNN_Internal_Shdr *hdr, asection *sec));
182 static void elfNN_ia64_final_write_processing
183 PARAMS ((bfd *abfd, boolean linker));
184 static boolean elfNN_ia64_add_symbol_hook
185 PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
186 const char **namep, flagword *flagsp, asection **secp,
187 bfd_vma *valp));
188 static boolean elfNN_ia64_aix_vec
189 PARAMS ((const bfd_target *vec));
190 static boolean elfNN_ia64_aix_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 boolean elfNN_ia64_aix_link_add_symbols
195 PARAMS ((bfd *abfd, struct bfd_link_info *info));
196 static int elfNN_ia64_additional_program_headers
197 PARAMS ((bfd *abfd));
198 static boolean elfNN_ia64_modify_segment_map
199 PARAMS ((bfd *));
200 static boolean elfNN_ia64_is_local_label_name
201 PARAMS ((bfd *abfd, const char *name));
202 static boolean elfNN_ia64_dynamic_symbol_p
203 PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info));
204 static boolean elfNN_ia64_local_hash_table_init
205 PARAMS ((struct elfNN_ia64_local_hash_table *ht, bfd *abfd,
206 new_hash_entry_func new));
207 static struct bfd_hash_entry *elfNN_ia64_new_loc_hash_entry
208 PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
209 const char *string));
210 static struct bfd_hash_entry *elfNN_ia64_new_elf_hash_entry
211 PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
212 const char *string));
213 static void elfNN_ia64_hash_copy_indirect
214 PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *));
215 static void elfNN_ia64_hash_hide_symbol
216 PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, boolean));
217 static struct bfd_link_hash_table *elfNN_ia64_hash_table_create
218 PARAMS ((bfd *abfd));
219 static struct elfNN_ia64_local_hash_entry *elfNN_ia64_local_hash_lookup
220 PARAMS ((struct elfNN_ia64_local_hash_table *table, const char *string,
221 boolean create, boolean copy));
222 static boolean elfNN_ia64_global_dyn_sym_thunk
223 PARAMS ((struct bfd_hash_entry *, PTR));
224 static boolean elfNN_ia64_local_dyn_sym_thunk
225 PARAMS ((struct bfd_hash_entry *, PTR));
226 static void elfNN_ia64_dyn_sym_traverse
227 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
228 boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
229 PTR info));
230 static boolean elfNN_ia64_create_dynamic_sections
231 PARAMS ((bfd *abfd, struct bfd_link_info *info));
232 static struct elfNN_ia64_local_hash_entry * get_local_sym_hash
233 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
234 bfd *abfd, const Elf_Internal_Rela *rel, boolean create));
235 static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
236 PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
237 struct elf_link_hash_entry *h,
238 bfd *abfd, const Elf_Internal_Rela *rel, boolean create));
239 static asection *get_got
240 PARAMS ((bfd *abfd, struct bfd_link_info *info,
241 struct elfNN_ia64_link_hash_table *ia64_info));
242 static asection *get_fptr
243 PARAMS ((bfd *abfd, struct bfd_link_info *info,
244 struct elfNN_ia64_link_hash_table *ia64_info));
245 static asection *get_pltoff
246 PARAMS ((bfd *abfd, struct bfd_link_info *info,
247 struct elfNN_ia64_link_hash_table *ia64_info));
248 static asection *get_reloc_section
249 PARAMS ((bfd *abfd, struct elfNN_ia64_link_hash_table *ia64_info,
250 asection *sec, boolean create));
251 static boolean count_dyn_reloc
252 PARAMS ((bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
253 asection *srel, int type));
254 static boolean elfNN_ia64_check_relocs
255 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
256 const Elf_Internal_Rela *relocs));
257 static boolean elfNN_ia64_adjust_dynamic_symbol
258 PARAMS ((struct bfd_link_info *info, struct elf_link_hash_entry *h));
259 static long global_sym_index
260 PARAMS ((struct elf_link_hash_entry *h));
261 static boolean allocate_fptr
262 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
263 static boolean allocate_global_data_got
264 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
265 static boolean allocate_global_fptr_got
266 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
267 static boolean allocate_local_got
268 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
269 static boolean allocate_pltoff_entries
270 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
271 static boolean allocate_plt_entries
272 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
273 static boolean allocate_plt2_entries
274 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
275 static boolean allocate_dynrel_entries
276 PARAMS ((struct elfNN_ia64_dyn_sym_info *dyn_i, PTR data));
277 static boolean elfNN_ia64_size_dynamic_sections
278 PARAMS ((bfd *output_bfd, struct bfd_link_info *info));
279 static bfd_reloc_status_type elfNN_ia64_install_value
280 PARAMS ((bfd *abfd, bfd_byte *hit_addr, bfd_vma val, unsigned int r_type));
281 static void elfNN_ia64_install_dyn_reloc
282 PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
283 asection *srel, bfd_vma offset, unsigned int type,
284 long dynindx, bfd_vma addend));
285 static bfd_vma set_got_entry
286 PARAMS ((bfd *abfd, struct bfd_link_info *info,
287 struct elfNN_ia64_dyn_sym_info *dyn_i, long dynindx,
288 bfd_vma addend, bfd_vma value, unsigned int dyn_r_type));
289 static bfd_vma set_fptr_entry
290 PARAMS ((bfd *abfd, struct bfd_link_info *info,
291 struct elfNN_ia64_dyn_sym_info *dyn_i,
292 bfd_vma value));
293 static bfd_vma set_pltoff_entry
294 PARAMS ((bfd *abfd, struct bfd_link_info *info,
295 struct elfNN_ia64_dyn_sym_info *dyn_i,
296 bfd_vma value, boolean));
297 static bfd_vma elfNN_ia64_tprel_base
298 PARAMS ((struct bfd_link_info *info));
299 static bfd_vma elfNN_ia64_dtprel_base
300 PARAMS ((struct bfd_link_info *info));
301 static int elfNN_ia64_unwind_entry_compare
302 PARAMS ((const PTR, const PTR));
303 static boolean elfNN_ia64_final_link
304 PARAMS ((bfd *abfd, struct bfd_link_info *info));
305 static boolean elfNN_ia64_relocate_section
306 PARAMS ((bfd *output_bfd, struct bfd_link_info *info, bfd *input_bfd,
307 asection *input_section, bfd_byte *contents,
308 Elf_Internal_Rela *relocs, Elf_Internal_Sym *local_syms,
309 asection **local_sections));
310 static boolean elfNN_ia64_finish_dynamic_symbol
311 PARAMS ((bfd *output_bfd, struct bfd_link_info *info,
312 struct elf_link_hash_entry *h, Elf_Internal_Sym *sym));
313 static boolean elfNN_ia64_finish_dynamic_sections
314 PARAMS ((bfd *abfd, struct bfd_link_info *info));
315 static boolean elfNN_ia64_set_private_flags
316 PARAMS ((bfd *abfd, flagword flags));
317 static boolean elfNN_ia64_merge_private_bfd_data
318 PARAMS ((bfd *ibfd, bfd *obfd));
319 static boolean elfNN_ia64_print_private_bfd_data
320 PARAMS ((bfd *abfd, PTR ptr));
321 static enum elf_reloc_type_class elfNN_ia64_reloc_type_class
322 PARAMS ((const Elf_Internal_Rela *));
323 static boolean elfNN_ia64_hpux_vec
324 PARAMS ((const bfd_target *vec));
325 static void elfNN_hpux_post_process_headers
326 PARAMS ((bfd *abfd, struct bfd_link_info *info));
327 boolean elfNN_hpux_backend_section_from_bfd_section
328 PARAMS ((bfd *abfd, asection *sec, int *retval));
329 \f
330 /* ia64-specific relocation */
331
332 /* Perform a relocation. Not much to do here as all the hard work is
333 done in elfNN_ia64_final_link_relocate. */
334 static bfd_reloc_status_type
335 elfNN_ia64_reloc (abfd, reloc, sym, data, input_section,
336 output_bfd, error_message)
337 bfd *abfd ATTRIBUTE_UNUSED;
338 arelent *reloc;
339 asymbol *sym ATTRIBUTE_UNUSED;
340 PTR data ATTRIBUTE_UNUSED;
341 asection *input_section;
342 bfd *output_bfd;
343 char **error_message;
344 {
345 if (output_bfd)
346 {
347 reloc->address += input_section->output_offset;
348 return bfd_reloc_ok;
349 }
350 *error_message = "Unsupported call to elfNN_ia64_reloc";
351 return bfd_reloc_notsupported;
352 }
353
354 #define IA64_HOWTO(TYPE, NAME, SIZE, PCREL, IN) \
355 HOWTO (TYPE, 0, SIZE, 0, PCREL, 0, complain_overflow_signed, \
356 elfNN_ia64_reloc, NAME, false, 0, 0, IN)
357
358 /* This table has to be sorted according to increasing number of the
359 TYPE field. */
360 static reloc_howto_type ia64_howto_table[] =
361 {
362 IA64_HOWTO (R_IA64_NONE, "NONE", 0, false, true),
363
364 IA64_HOWTO (R_IA64_IMM14, "IMM14", 0, false, true),
365 IA64_HOWTO (R_IA64_IMM22, "IMM22", 0, false, true),
366 IA64_HOWTO (R_IA64_IMM64, "IMM64", 0, false, true),
367 IA64_HOWTO (R_IA64_DIR32MSB, "DIR32MSB", 2, false, true),
368 IA64_HOWTO (R_IA64_DIR32LSB, "DIR32LSB", 2, false, true),
369 IA64_HOWTO (R_IA64_DIR64MSB, "DIR64MSB", 4, false, true),
370 IA64_HOWTO (R_IA64_DIR64LSB, "DIR64LSB", 4, false, true),
371
372 IA64_HOWTO (R_IA64_GPREL22, "GPREL22", 0, false, true),
373 IA64_HOWTO (R_IA64_GPREL64I, "GPREL64I", 0, false, true),
374 IA64_HOWTO (R_IA64_GPREL32MSB, "GPREL32MSB", 2, false, true),
375 IA64_HOWTO (R_IA64_GPREL32LSB, "GPREL32LSB", 2, false, true),
376 IA64_HOWTO (R_IA64_GPREL64MSB, "GPREL64MSB", 4, false, true),
377 IA64_HOWTO (R_IA64_GPREL64LSB, "GPREL64LSB", 4, false, true),
378
379 IA64_HOWTO (R_IA64_LTOFF22, "LTOFF22", 0, false, true),
380 IA64_HOWTO (R_IA64_LTOFF64I, "LTOFF64I", 0, false, true),
381
382 IA64_HOWTO (R_IA64_PLTOFF22, "PLTOFF22", 0, false, true),
383 IA64_HOWTO (R_IA64_PLTOFF64I, "PLTOFF64I", 0, false, true),
384 IA64_HOWTO (R_IA64_PLTOFF64MSB, "PLTOFF64MSB", 4, false, true),
385 IA64_HOWTO (R_IA64_PLTOFF64LSB, "PLTOFF64LSB", 4, false, true),
386
387 IA64_HOWTO (R_IA64_FPTR64I, "FPTR64I", 0, false, true),
388 IA64_HOWTO (R_IA64_FPTR32MSB, "FPTR32MSB", 2, false, true),
389 IA64_HOWTO (R_IA64_FPTR32LSB, "FPTR32LSB", 2, false, true),
390 IA64_HOWTO (R_IA64_FPTR64MSB, "FPTR64MSB", 4, false, true),
391 IA64_HOWTO (R_IA64_FPTR64LSB, "FPTR64LSB", 4, false, true),
392
393 IA64_HOWTO (R_IA64_PCREL60B, "PCREL60B", 0, true, true),
394 IA64_HOWTO (R_IA64_PCREL21B, "PCREL21B", 0, true, true),
395 IA64_HOWTO (R_IA64_PCREL21M, "PCREL21M", 0, true, true),
396 IA64_HOWTO (R_IA64_PCREL21F, "PCREL21F", 0, true, true),
397 IA64_HOWTO (R_IA64_PCREL32MSB, "PCREL32MSB", 2, true, true),
398 IA64_HOWTO (R_IA64_PCREL32LSB, "PCREL32LSB", 2, true, true),
399 IA64_HOWTO (R_IA64_PCREL64MSB, "PCREL64MSB", 4, true, true),
400 IA64_HOWTO (R_IA64_PCREL64LSB, "PCREL64LSB", 4, true, true),
401
402 IA64_HOWTO (R_IA64_LTOFF_FPTR22, "LTOFF_FPTR22", 0, false, true),
403 IA64_HOWTO (R_IA64_LTOFF_FPTR64I, "LTOFF_FPTR64I", 0, false, true),
404 IA64_HOWTO (R_IA64_LTOFF_FPTR32MSB, "LTOFF_FPTR32MSB", 2, false, true),
405 IA64_HOWTO (R_IA64_LTOFF_FPTR32LSB, "LTOFF_FPTR32LSB", 2, false, true),
406 IA64_HOWTO (R_IA64_LTOFF_FPTR64MSB, "LTOFF_FPTR64MSB", 4, false, true),
407 IA64_HOWTO (R_IA64_LTOFF_FPTR64LSB, "LTOFF_FPTR64LSB", 4, false, true),
408
409 IA64_HOWTO (R_IA64_SEGREL32MSB, "SEGREL32MSB", 2, false, true),
410 IA64_HOWTO (R_IA64_SEGREL32LSB, "SEGREL32LSB", 2, false, true),
411 IA64_HOWTO (R_IA64_SEGREL64MSB, "SEGREL64MSB", 4, false, true),
412 IA64_HOWTO (R_IA64_SEGREL64LSB, "SEGREL64LSB", 4, false, true),
413
414 IA64_HOWTO (R_IA64_SECREL32MSB, "SECREL32MSB", 2, false, true),
415 IA64_HOWTO (R_IA64_SECREL32LSB, "SECREL32LSB", 2, false, true),
416 IA64_HOWTO (R_IA64_SECREL64MSB, "SECREL64MSB", 4, false, true),
417 IA64_HOWTO (R_IA64_SECREL64LSB, "SECREL64LSB", 4, false, true),
418
419 IA64_HOWTO (R_IA64_REL32MSB, "REL32MSB", 2, false, true),
420 IA64_HOWTO (R_IA64_REL32LSB, "REL32LSB", 2, false, true),
421 IA64_HOWTO (R_IA64_REL64MSB, "REL64MSB", 4, false, true),
422 IA64_HOWTO (R_IA64_REL64LSB, "REL64LSB", 4, false, true),
423
424 IA64_HOWTO (R_IA64_LTV32MSB, "LTV32MSB", 2, false, true),
425 IA64_HOWTO (R_IA64_LTV32LSB, "LTV32LSB", 2, false, true),
426 IA64_HOWTO (R_IA64_LTV64MSB, "LTV64MSB", 4, false, true),
427 IA64_HOWTO (R_IA64_LTV64LSB, "LTV64LSB", 4, false, true),
428
429 IA64_HOWTO (R_IA64_PCREL21BI, "PCREL21BI", 0, true, true),
430 IA64_HOWTO (R_IA64_PCREL22, "PCREL22", 0, true, true),
431 IA64_HOWTO (R_IA64_PCREL64I, "PCREL64I", 0, true, true),
432
433 IA64_HOWTO (R_IA64_IPLTMSB, "IPLTMSB", 4, false, true),
434 IA64_HOWTO (R_IA64_IPLTLSB, "IPLTLSB", 4, false, true),
435 IA64_HOWTO (R_IA64_COPY, "COPY", 4, false, true),
436 IA64_HOWTO (R_IA64_LTOFF22X, "LTOFF22X", 0, false, true),
437 IA64_HOWTO (R_IA64_LDXMOV, "LDXMOV", 0, false, true),
438
439 IA64_HOWTO (R_IA64_TPREL14, "TPREL14", 0, false, false),
440 IA64_HOWTO (R_IA64_TPREL22, "TPREL22", 0, false, false),
441 IA64_HOWTO (R_IA64_TPREL64I, "TPREL64I", 0, false, false),
442 IA64_HOWTO (R_IA64_TPREL64MSB, "TPREL64MSB", 8, false, false),
443 IA64_HOWTO (R_IA64_TPREL64LSB, "TPREL64LSB", 8, false, false),
444 IA64_HOWTO (R_IA64_LTOFF_TPREL22, "LTOFF_TPREL22", 0, false, false),
445
446 IA64_HOWTO (R_IA64_DTPMOD64MSB, "TPREL64MSB", 8, false, false),
447 IA64_HOWTO (R_IA64_DTPMOD64LSB, "TPREL64LSB", 8, false, false),
448 IA64_HOWTO (R_IA64_LTOFF_DTPMOD22, "LTOFF_DTPMOD22", 0, false, false),
449
450 IA64_HOWTO (R_IA64_DTPREL14, "DTPREL14", 0, false, false),
451 IA64_HOWTO (R_IA64_DTPREL22, "DTPREL22", 0, false, false),
452 IA64_HOWTO (R_IA64_DTPREL64I, "DTPREL64I", 0, false, false),
453 IA64_HOWTO (R_IA64_DTPREL32MSB, "DTPREL32MSB", 4, false, false),
454 IA64_HOWTO (R_IA64_DTPREL32LSB, "DTPREL32LSB", 4, false, false),
455 IA64_HOWTO (R_IA64_DTPREL64MSB, "DTPREL64MSB", 8, false, false),
456 IA64_HOWTO (R_IA64_DTPREL64LSB, "DTPREL64LSB", 8, false, false),
457 IA64_HOWTO (R_IA64_LTOFF_DTPREL22, "LTOFF_DTPREL22", 0, false, false),
458 };
459
460 static unsigned char elf_code_to_howto_index[R_IA64_MAX_RELOC_CODE + 1];
461
462 /* Given a BFD reloc type, return the matching HOWTO structure. */
463
464 static reloc_howto_type*
465 lookup_howto (rtype)
466 unsigned int rtype;
467 {
468 static int inited = 0;
469 int i;
470
471 if (!inited)
472 {
473 inited = 1;
474
475 memset (elf_code_to_howto_index, 0xff, sizeof (elf_code_to_howto_index));
476 for (i = 0; i < NELEMS (ia64_howto_table); ++i)
477 elf_code_to_howto_index[ia64_howto_table[i].type] = i;
478 }
479
480 BFD_ASSERT (rtype <= R_IA64_MAX_RELOC_CODE);
481 i = elf_code_to_howto_index[rtype];
482 if (i >= NELEMS (ia64_howto_table))
483 return 0;
484 return ia64_howto_table + i;
485 }
486
487 static reloc_howto_type*
488 elfNN_ia64_reloc_type_lookup (abfd, bfd_code)
489 bfd *abfd ATTRIBUTE_UNUSED;
490 bfd_reloc_code_real_type bfd_code;
491 {
492 unsigned int rtype;
493
494 switch (bfd_code)
495 {
496 case BFD_RELOC_NONE: rtype = R_IA64_NONE; break;
497
498 case BFD_RELOC_IA64_IMM14: rtype = R_IA64_IMM14; break;
499 case BFD_RELOC_IA64_IMM22: rtype = R_IA64_IMM22; break;
500 case BFD_RELOC_IA64_IMM64: rtype = R_IA64_IMM64; break;
501
502 case BFD_RELOC_IA64_DIR32MSB: rtype = R_IA64_DIR32MSB; break;
503 case BFD_RELOC_IA64_DIR32LSB: rtype = R_IA64_DIR32LSB; break;
504 case BFD_RELOC_IA64_DIR64MSB: rtype = R_IA64_DIR64MSB; break;
505 case BFD_RELOC_IA64_DIR64LSB: rtype = R_IA64_DIR64LSB; break;
506
507 case BFD_RELOC_IA64_GPREL22: rtype = R_IA64_GPREL22; break;
508 case BFD_RELOC_IA64_GPREL64I: rtype = R_IA64_GPREL64I; break;
509 case BFD_RELOC_IA64_GPREL32MSB: rtype = R_IA64_GPREL32MSB; break;
510 case BFD_RELOC_IA64_GPREL32LSB: rtype = R_IA64_GPREL32LSB; break;
511 case BFD_RELOC_IA64_GPREL64MSB: rtype = R_IA64_GPREL64MSB; break;
512 case BFD_RELOC_IA64_GPREL64LSB: rtype = R_IA64_GPREL64LSB; break;
513
514 case BFD_RELOC_IA64_LTOFF22: rtype = R_IA64_LTOFF22; break;
515 case BFD_RELOC_IA64_LTOFF64I: rtype = R_IA64_LTOFF64I; break;
516
517 case BFD_RELOC_IA64_PLTOFF22: rtype = R_IA64_PLTOFF22; break;
518 case BFD_RELOC_IA64_PLTOFF64I: rtype = R_IA64_PLTOFF64I; break;
519 case BFD_RELOC_IA64_PLTOFF64MSB: rtype = R_IA64_PLTOFF64MSB; break;
520 case BFD_RELOC_IA64_PLTOFF64LSB: rtype = R_IA64_PLTOFF64LSB; break;
521 case BFD_RELOC_IA64_FPTR64I: rtype = R_IA64_FPTR64I; break;
522 case BFD_RELOC_IA64_FPTR32MSB: rtype = R_IA64_FPTR32MSB; break;
523 case BFD_RELOC_IA64_FPTR32LSB: rtype = R_IA64_FPTR32LSB; break;
524 case BFD_RELOC_IA64_FPTR64MSB: rtype = R_IA64_FPTR64MSB; break;
525 case BFD_RELOC_IA64_FPTR64LSB: rtype = R_IA64_FPTR64LSB; break;
526
527 case BFD_RELOC_IA64_PCREL21B: rtype = R_IA64_PCREL21B; break;
528 case BFD_RELOC_IA64_PCREL21BI: rtype = R_IA64_PCREL21BI; break;
529 case BFD_RELOC_IA64_PCREL21M: rtype = R_IA64_PCREL21M; break;
530 case BFD_RELOC_IA64_PCREL21F: rtype = R_IA64_PCREL21F; break;
531 case BFD_RELOC_IA64_PCREL22: rtype = R_IA64_PCREL22; break;
532 case BFD_RELOC_IA64_PCREL60B: rtype = R_IA64_PCREL60B; break;
533 case BFD_RELOC_IA64_PCREL64I: rtype = R_IA64_PCREL64I; break;
534 case BFD_RELOC_IA64_PCREL32MSB: rtype = R_IA64_PCREL32MSB; break;
535 case BFD_RELOC_IA64_PCREL32LSB: rtype = R_IA64_PCREL32LSB; break;
536 case BFD_RELOC_IA64_PCREL64MSB: rtype = R_IA64_PCREL64MSB; break;
537 case BFD_RELOC_IA64_PCREL64LSB: rtype = R_IA64_PCREL64LSB; break;
538
539 case BFD_RELOC_IA64_LTOFF_FPTR22: rtype = R_IA64_LTOFF_FPTR22; break;
540 case BFD_RELOC_IA64_LTOFF_FPTR64I: rtype = R_IA64_LTOFF_FPTR64I; break;
541 case BFD_RELOC_IA64_LTOFF_FPTR32MSB: rtype = R_IA64_LTOFF_FPTR32MSB; break;
542 case BFD_RELOC_IA64_LTOFF_FPTR32LSB: rtype = R_IA64_LTOFF_FPTR32LSB; break;
543 case BFD_RELOC_IA64_LTOFF_FPTR64MSB: rtype = R_IA64_LTOFF_FPTR64MSB; break;
544 case BFD_RELOC_IA64_LTOFF_FPTR64LSB: rtype = R_IA64_LTOFF_FPTR64LSB; break;
545
546 case BFD_RELOC_IA64_SEGREL32MSB: rtype = R_IA64_SEGREL32MSB; break;
547 case BFD_RELOC_IA64_SEGREL32LSB: rtype = R_IA64_SEGREL32LSB; break;
548 case BFD_RELOC_IA64_SEGREL64MSB: rtype = R_IA64_SEGREL64MSB; break;
549 case BFD_RELOC_IA64_SEGREL64LSB: rtype = R_IA64_SEGREL64LSB; break;
550
551 case BFD_RELOC_IA64_SECREL32MSB: rtype = R_IA64_SECREL32MSB; break;
552 case BFD_RELOC_IA64_SECREL32LSB: rtype = R_IA64_SECREL32LSB; break;
553 case BFD_RELOC_IA64_SECREL64MSB: rtype = R_IA64_SECREL64MSB; break;
554 case BFD_RELOC_IA64_SECREL64LSB: rtype = R_IA64_SECREL64LSB; break;
555
556 case BFD_RELOC_IA64_REL32MSB: rtype = R_IA64_REL32MSB; break;
557 case BFD_RELOC_IA64_REL32LSB: rtype = R_IA64_REL32LSB; break;
558 case BFD_RELOC_IA64_REL64MSB: rtype = R_IA64_REL64MSB; break;
559 case BFD_RELOC_IA64_REL64LSB: rtype = R_IA64_REL64LSB; break;
560
561 case BFD_RELOC_IA64_LTV32MSB: rtype = R_IA64_LTV32MSB; break;
562 case BFD_RELOC_IA64_LTV32LSB: rtype = R_IA64_LTV32LSB; break;
563 case BFD_RELOC_IA64_LTV64MSB: rtype = R_IA64_LTV64MSB; break;
564 case BFD_RELOC_IA64_LTV64LSB: rtype = R_IA64_LTV64LSB; break;
565
566 case BFD_RELOC_IA64_IPLTMSB: rtype = R_IA64_IPLTMSB; break;
567 case BFD_RELOC_IA64_IPLTLSB: rtype = R_IA64_IPLTLSB; break;
568 case BFD_RELOC_IA64_COPY: rtype = R_IA64_COPY; break;
569 case BFD_RELOC_IA64_LTOFF22X: rtype = R_IA64_LTOFF22X; break;
570 case BFD_RELOC_IA64_LDXMOV: rtype = R_IA64_LDXMOV; break;
571
572 case BFD_RELOC_IA64_TPREL14: rtype = R_IA64_TPREL14; break;
573 case BFD_RELOC_IA64_TPREL22: rtype = R_IA64_TPREL22; break;
574 case BFD_RELOC_IA64_TPREL64I: rtype = R_IA64_TPREL64I; break;
575 case BFD_RELOC_IA64_TPREL64MSB: rtype = R_IA64_TPREL64MSB; break;
576 case BFD_RELOC_IA64_TPREL64LSB: rtype = R_IA64_TPREL64LSB; break;
577 case BFD_RELOC_IA64_LTOFF_TPREL22: rtype = R_IA64_LTOFF_TPREL22; break;
578
579 case BFD_RELOC_IA64_DTPMOD64MSB: rtype = R_IA64_DTPMOD64MSB; break;
580 case BFD_RELOC_IA64_DTPMOD64LSB: rtype = R_IA64_DTPMOD64LSB; break;
581 case BFD_RELOC_IA64_LTOFF_DTPMOD22: rtype = R_IA64_LTOFF_DTPMOD22; break;
582
583 case BFD_RELOC_IA64_DTPREL14: rtype = R_IA64_DTPREL14; break;
584 case BFD_RELOC_IA64_DTPREL22: rtype = R_IA64_DTPREL22; break;
585 case BFD_RELOC_IA64_DTPREL64I: rtype = R_IA64_DTPREL64I; break;
586 case BFD_RELOC_IA64_DTPREL32MSB: rtype = R_IA64_DTPREL32MSB; break;
587 case BFD_RELOC_IA64_DTPREL32LSB: rtype = R_IA64_DTPREL32LSB; break;
588 case BFD_RELOC_IA64_DTPREL64MSB: rtype = R_IA64_DTPREL64MSB; break;
589 case BFD_RELOC_IA64_DTPREL64LSB: rtype = R_IA64_DTPREL64LSB; break;
590 case BFD_RELOC_IA64_LTOFF_DTPREL22: rtype = R_IA64_LTOFF_DTPREL22; break;
591
592 default: return 0;
593 }
594 return lookup_howto (rtype);
595 }
596
597 /* Given a ELF reloc, return the matching HOWTO structure. */
598
599 static void
600 elfNN_ia64_info_to_howto (abfd, bfd_reloc, elf_reloc)
601 bfd *abfd ATTRIBUTE_UNUSED;
602 arelent *bfd_reloc;
603 ElfNN_Internal_Rela *elf_reloc;
604 {
605 bfd_reloc->howto
606 = lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc->r_info));
607 }
608 \f
609 #define PLT_HEADER_SIZE (3 * 16)
610 #define PLT_MIN_ENTRY_SIZE (1 * 16)
611 #define PLT_FULL_ENTRY_SIZE (2 * 16)
612 #define PLT_RESERVED_WORDS 3
613
614 static const bfd_byte plt_header[PLT_HEADER_SIZE] =
615 {
616 0x0b, 0x10, 0x00, 0x1c, 0x00, 0x21, /* [MMI] mov r2=r14;; */
617 0xe0, 0x00, 0x08, 0x00, 0x48, 0x00, /* addl r14=0,r2 */
618 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
619 0x0b, 0x80, 0x20, 0x1c, 0x18, 0x14, /* [MMI] ld8 r16=[r14],8;; */
620 0x10, 0x41, 0x38, 0x30, 0x28, 0x00, /* ld8 r17=[r14],8 */
621 0x00, 0x00, 0x04, 0x00, /* nop.i 0x0;; */
622 0x11, 0x08, 0x00, 0x1c, 0x18, 0x10, /* [MIB] ld8 r1=[r14] */
623 0x60, 0x88, 0x04, 0x80, 0x03, 0x00, /* mov b6=r17 */
624 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
625 };
626
627 static const bfd_byte plt_min_entry[PLT_MIN_ENTRY_SIZE] =
628 {
629 0x11, 0x78, 0x00, 0x00, 0x00, 0x24, /* [MIB] mov r15=0 */
630 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* nop.i 0x0 */
631 0x00, 0x00, 0x00, 0x40 /* br.few 0 <PLT0>;; */
632 };
633
634 static const bfd_byte plt_full_entry[PLT_FULL_ENTRY_SIZE] =
635 {
636 0x0b, 0x78, 0x00, 0x02, 0x00, 0x24, /* [MMI] addl r15=0,r1;; */
637 0x00, 0x41, 0x3c, 0x30, 0x28, 0xc0, /* ld8 r16=[r15],8 */
638 0x01, 0x08, 0x00, 0x84, /* mov r14=r1;; */
639 0x11, 0x08, 0x00, 0x1e, 0x18, 0x10, /* [MIB] ld8 r1=[r15] */
640 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
641 0x60, 0x00, 0x80, 0x00 /* br.few b6;; */
642 };
643
644 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/ld.so.1"
645 #define AIX_DYNAMIC_INTERPRETER "/usr/lib/ia64l64/libc.so.1"
646 #define DYNAMIC_INTERPRETER(abfd) \
647 (elfNN_ia64_aix_vec (abfd->xvec) ? AIX_DYNAMIC_INTERPRETER : ELF_DYNAMIC_INTERPRETER)
648
649 /* Select out of range branch fixup type. Note that Itanium does
650 not support brl, and so it gets emulated by the kernel. */
651 #undef USE_BRL
652
653 static const bfd_byte oor_brl[16] =
654 {
655 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
656 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* brl.sptk.few tgt;; */
657 0x00, 0x00, 0x00, 0xc0
658 };
659
660 static const bfd_byte oor_ip[48] =
661 {
662 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MLX] nop.m 0 */
663 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, /* movl r15=0 */
664 0x01, 0x00, 0x00, 0x60,
665 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MII] nop.m 0 */
666 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, /* mov r16=ip;; */
667 0xf2, 0x80, 0x00, 0x80, /* add r16=r15,r16;; */
668 0x11, 0x00, 0x00, 0x00, 0x01, 0x00, /* [MIB] nop.m 0 */
669 0x60, 0x80, 0x04, 0x80, 0x03, 0x00, /* mov b6=r16 */
670 0x60, 0x00, 0x80, 0x00 /* br b6;; */
671 };
672 \f
673 /* These functions do relaxation for IA-64 ELF.
674
675 This is primarily to support branches to targets out of range;
676 relaxation of R_IA64_LTOFF22X and R_IA64_LDXMOV not yet supported. */
677
678 static 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 boolean *again;
684 {
685 struct one_fixup
686 {
687 struct one_fixup *next;
688 asection *tsec;
689 bfd_vma toff;
690 bfd_vma trampoff;
691 };
692
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 boolean changed_contents = false;
701 boolean changed_relocs = false;
702
703 /* Assume we're not going to change any sizes, and we'll only need
704 one pass. */
705 *again = false;
706
707 /* Nothing to do if there are no relocations. */
708 if ((sec->flags & SEC_RELOC) == 0
709 || sec->reloc_count == 0)
710 return true;
711
712 /* If this is the first time we have been called for this section,
713 initialize the cooked size. */
714 if (sec->_cooked_size == 0)
715 sec->_cooked_size = sec->_raw_size;
716
717 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
718
719 /* Load the relocations for this section. */
720 internal_relocs = (_bfd_elfNN_link_read_relocs
721 (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
722 link_info->keep_memory));
723 if (internal_relocs == NULL)
724 return false;
725
726 ia64_info = elfNN_ia64_hash_table (link_info);
727 irelend = internal_relocs + sec->reloc_count;
728
729 for (irel = internal_relocs; irel < irelend; irel++)
730 if (ELFNN_R_TYPE (irel->r_info) == (int) R_IA64_PCREL21B)
731 break;
732
733 /* No branch-type relocations. */
734 if (irel == irelend)
735 {
736 if (elf_section_data (sec)->relocs != internal_relocs)
737 free (internal_relocs);
738 return true;
739 }
740
741 /* Get the section contents. */
742 if (elf_section_data (sec)->this_hdr.contents != NULL)
743 contents = elf_section_data (sec)->this_hdr.contents;
744 else
745 {
746 contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
747 if (contents == NULL)
748 goto error_return;
749
750 if (! bfd_get_section_contents (abfd, sec, contents,
751 (file_ptr) 0, sec->_raw_size))
752 goto error_return;
753 }
754
755 for (; irel < irelend; irel++)
756 {
757 bfd_vma symaddr, reladdr, trampoff, toff, roff;
758 asection *tsec;
759 struct one_fixup *f;
760 bfd_size_type amt;
761
762 if (ELFNN_R_TYPE (irel->r_info) != (int) R_IA64_PCREL21B)
763 continue;
764
765 /* Get the value of the symbol referred to by the reloc. */
766 if (ELFNN_R_SYM (irel->r_info) < symtab_hdr->sh_info)
767 {
768 /* A local symbol. */
769 Elf_Internal_Sym *isym;
770
771 /* Read this BFD's local symbols. */
772 if (isymbuf == NULL)
773 {
774 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
775 if (isymbuf == NULL)
776 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
777 symtab_hdr->sh_info, 0,
778 NULL, NULL, NULL);
779 if (isymbuf == 0)
780 goto error_return;
781 }
782
783 isym = isymbuf + ELF64_R_SYM (irel->r_info);
784 if (isym->st_shndx == SHN_UNDEF)
785 continue; /* We can't do anthing with undefined symbols. */
786 else if (isym->st_shndx == SHN_ABS)
787 tsec = bfd_abs_section_ptr;
788 else if (isym->st_shndx == SHN_COMMON)
789 tsec = bfd_com_section_ptr;
790 else if (isym->st_shndx == SHN_IA_64_ANSI_COMMON)
791 tsec = bfd_com_section_ptr;
792 else
793 tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
794
795 toff = isym->st_value;
796 }
797 else
798 {
799 unsigned long indx;
800 struct elf_link_hash_entry *h;
801 struct elfNN_ia64_dyn_sym_info *dyn_i;
802
803 indx = ELFNN_R_SYM (irel->r_info) - symtab_hdr->sh_info;
804 h = elf_sym_hashes (abfd)[indx];
805 BFD_ASSERT (h != NULL);
806
807 while (h->root.type == bfd_link_hash_indirect
808 || h->root.type == bfd_link_hash_warning)
809 h = (struct elf_link_hash_entry *) h->root.u.i.link;
810
811 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, false);
812
813 /* For branches to dynamic symbols, we're interested instead
814 in a branch to the PLT entry. */
815 if (dyn_i && dyn_i->want_plt2)
816 {
817 tsec = ia64_info->plt_sec;
818 toff = dyn_i->plt2_offset;
819 }
820 else
821 {
822 /* We can't do anthing with undefined symbols. */
823 if (h->root.type == bfd_link_hash_undefined
824 || h->root.type == bfd_link_hash_undefweak)
825 continue;
826
827 tsec = h->root.u.def.section;
828 toff = h->root.u.def.value;
829 }
830 }
831
832 symaddr = (tsec->output_section->vma
833 + tsec->output_offset
834 + toff
835 + irel->r_addend);
836
837 roff = irel->r_offset;
838 reladdr = (sec->output_section->vma
839 + sec->output_offset
840 + roff) & (bfd_vma) -4;
841
842 /* If the branch is in range, no need to do anything. */
843 if ((bfd_signed_vma) (symaddr - reladdr) >= -0x1000000
844 && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
845 continue;
846
847 /* If the branch and target are in the same section, you've
848 got one honking big section and we can't help you. You'll
849 get an error message later. */
850 if (tsec == sec)
851 continue;
852
853 /* Look for an existing fixup to this address. */
854 for (f = fixups; f ; f = f->next)
855 if (f->tsec == tsec && f->toff == toff)
856 break;
857
858 if (f == NULL)
859 {
860 /* Two alternatives: If it's a branch to a PLT entry, we can
861 make a copy of the FULL_PLT entry. Otherwise, we'll have
862 to use a `brl' insn to get where we're going. */
863
864 size_t size;
865
866 if (tsec == ia64_info->plt_sec)
867 size = sizeof (plt_full_entry);
868 else
869 {
870 #ifdef USE_BRL
871 size = sizeof (oor_brl);
872 #else
873 size = sizeof (oor_ip);
874 #endif
875 }
876
877 /* Resize the current section to make room for the new branch. */
878 trampoff = (sec->_cooked_size + 15) & (bfd_vma) -16;
879 amt = trampoff + size;
880 contents = (bfd_byte *) bfd_realloc (contents, amt);
881 if (contents == NULL)
882 goto error_return;
883 sec->_cooked_size = amt;
884
885 if (tsec == ia64_info->plt_sec)
886 {
887 memcpy (contents + trampoff, plt_full_entry, size);
888
889 /* Hijack the old relocation for use as the PLTOFF reloc. */
890 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
891 R_IA64_PLTOFF22);
892 irel->r_offset = trampoff;
893 }
894 else
895 {
896 #ifdef USE_BRL
897 memcpy (contents + trampoff, oor_brl, size);
898 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
899 R_IA64_PCREL60B);
900 irel->r_offset = trampoff + 2;
901 #else
902 memcpy (contents + trampoff, oor_ip, size);
903 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
904 R_IA64_PCREL64I);
905 irel->r_addend -= 16;
906 irel->r_offset = trampoff + 2;
907 #endif
908 }
909
910 /* Record the fixup so we don't do it again this section. */
911 f = (struct one_fixup *) bfd_malloc ((bfd_size_type) sizeof (*f));
912 f->next = fixups;
913 f->tsec = tsec;
914 f->toff = toff;
915 f->trampoff = trampoff;
916 fixups = f;
917 }
918 else
919 {
920 /* Nop out the reloc, since we're finalizing things here. */
921 irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
922 }
923
924 /* Fix up the existing branch to hit the trampoline. Hope like
925 hell this doesn't overflow too. */
926 if (elfNN_ia64_install_value (abfd, contents + roff,
927 f->trampoff - (roff & (bfd_vma) -4),
928 R_IA64_PCREL21B) != bfd_reloc_ok)
929 goto error_return;
930
931 changed_contents = true;
932 changed_relocs = true;
933 }
934
935 /* Clean up and go home. */
936 while (fixups)
937 {
938 struct one_fixup *f = fixups;
939 fixups = fixups->next;
940 free (f);
941 }
942
943 if (isymbuf != NULL
944 && symtab_hdr->contents != (unsigned char *) isymbuf)
945 {
946 if (! link_info->keep_memory)
947 free (isymbuf);
948 else
949 {
950 /* Cache the symbols for elf_link_input_bfd. */
951 symtab_hdr->contents = (unsigned char *) isymbuf;
952 }
953 }
954
955 if (contents != NULL
956 && elf_section_data (sec)->this_hdr.contents != contents)
957 {
958 if (!changed_contents && !link_info->keep_memory)
959 free (contents);
960 else
961 {
962 /* Cache the section contents for elf_link_input_bfd. */
963 elf_section_data (sec)->this_hdr.contents = contents;
964 }
965 }
966
967 if (elf_section_data (sec)->relocs != internal_relocs)
968 {
969 if (!changed_relocs)
970 free (internal_relocs);
971 else
972 elf_section_data (sec)->relocs = internal_relocs;
973 }
974
975 *again = changed_contents || changed_relocs;
976 return true;
977
978 error_return:
979 if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
980 free (isymbuf);
981 if (contents != NULL
982 && elf_section_data (sec)->this_hdr.contents != contents)
983 free (contents);
984 if (internal_relocs != NULL
985 && elf_section_data (sec)->relocs != internal_relocs)
986 free (internal_relocs);
987 return false;
988 }
989 \f
990 /* Return true if NAME is an unwind table section name. */
991
992 static inline boolean
993 is_unwind_section_name (abfd, name)
994 bfd *abfd;
995 const char *name;
996 {
997 size_t len1, len2, len3;
998
999 if (elfNN_ia64_hpux_vec (abfd->xvec)
1000 && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
1001 return false;
1002
1003 len1 = sizeof (ELF_STRING_ia64_unwind) - 1;
1004 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
1005 len3 = sizeof (ELF_STRING_ia64_unwind_once) - 1;
1006 return ((strncmp (name, ELF_STRING_ia64_unwind, len1) == 0
1007 && strncmp (name, ELF_STRING_ia64_unwind_info, len2) != 0)
1008 || strncmp (name, ELF_STRING_ia64_unwind_once, len3) == 0);
1009 }
1010
1011 /* Handle an IA-64 specific section when reading an object file. This
1012 is called when elfcode.h finds a section with an unknown type. */
1013
1014 static boolean
1015 elfNN_ia64_section_from_shdr (abfd, hdr, name)
1016 bfd *abfd;
1017 ElfNN_Internal_Shdr *hdr;
1018 const char *name;
1019 {
1020 asection *newsect;
1021
1022 /* There ought to be a place to keep ELF backend specific flags, but
1023 at the moment there isn't one. We just keep track of the
1024 sections by their name, instead. Fortunately, the ABI gives
1025 suggested names for all the MIPS specific sections, so we will
1026 probably get away with this. */
1027 switch (hdr->sh_type)
1028 {
1029 case SHT_IA_64_UNWIND:
1030 case SHT_IA_64_HP_OPT_ANOT:
1031 break;
1032
1033 case SHT_IA_64_EXT:
1034 if (strcmp (name, ELF_STRING_ia64_archext) != 0)
1035 return false;
1036 break;
1037
1038 default:
1039 return false;
1040 }
1041
1042 if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
1043 return false;
1044 newsect = hdr->bfd_section;
1045
1046 return true;
1047 }
1048
1049 /* Convert IA-64 specific section flags to bfd internal section flags. */
1050
1051 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
1052 flag. */
1053
1054 static boolean
1055 elfNN_ia64_section_flags (flags, hdr)
1056 flagword *flags;
1057 ElfNN_Internal_Shdr *hdr;
1058 {
1059 if (hdr->sh_flags & SHF_IA_64_SHORT)
1060 *flags |= SEC_SMALL_DATA;
1061
1062 return true;
1063 }
1064
1065 /* Set the correct type for an IA-64 ELF section. We do this by the
1066 section name, which is a hack, but ought to work. */
1067
1068 static boolean
1069 elfNN_ia64_fake_sections (abfd, hdr, sec)
1070 bfd *abfd ATTRIBUTE_UNUSED;
1071 ElfNN_Internal_Shdr *hdr;
1072 asection *sec;
1073 {
1074 register const char *name;
1075
1076 name = bfd_get_section_name (abfd, sec);
1077
1078 if (is_unwind_section_name (abfd, name))
1079 {
1080 /* We don't have the sections numbered at this point, so sh_info
1081 is set later, in elfNN_ia64_final_write_processing. */
1082 hdr->sh_type = SHT_IA_64_UNWIND;
1083 hdr->sh_flags |= SHF_LINK_ORDER;
1084 }
1085 else if (strcmp (name, ELF_STRING_ia64_archext) == 0)
1086 hdr->sh_type = SHT_IA_64_EXT;
1087 else if (strcmp (name, ".HP.opt_annot") == 0)
1088 hdr->sh_type = SHT_IA_64_HP_OPT_ANOT;
1089 else if (strcmp (name, ".reloc") == 0)
1090 /*
1091 * This is an ugly, but unfortunately necessary hack that is
1092 * needed when producing EFI binaries on IA-64. It tells
1093 * elf.c:elf_fake_sections() not to consider ".reloc" as a section
1094 * containing ELF relocation info. We need this hack in order to
1095 * be able to generate ELF binaries that can be translated into
1096 * EFI applications (which are essentially COFF objects). Those
1097 * files contain a COFF ".reloc" section inside an ELFNN object,
1098 * which would normally cause BFD to segfault because it would
1099 * attempt to interpret this section as containing relocation
1100 * entries for section "oc". With this hack enabled, ".reloc"
1101 * will be treated as a normal data section, which will avoid the
1102 * segfault. However, you won't be able to create an ELFNN binary
1103 * with a section named "oc" that needs relocations, but that's
1104 * the kind of ugly side-effects you get when detecting section
1105 * types based on their names... In practice, this limitation is
1106 * unlikely to bite.
1107 */
1108 hdr->sh_type = SHT_PROGBITS;
1109
1110 if (sec->flags & SEC_SMALL_DATA)
1111 hdr->sh_flags |= SHF_IA_64_SHORT;
1112
1113 return true;
1114 }
1115
1116 /* The final processing done just before writing out an IA-64 ELF
1117 object file. */
1118
1119 static void
1120 elfNN_ia64_final_write_processing (abfd, linker)
1121 bfd *abfd;
1122 boolean linker ATTRIBUTE_UNUSED;
1123 {
1124 Elf_Internal_Shdr *hdr;
1125 const char *sname;
1126 asection *text_sect, *s;
1127 size_t len;
1128
1129 for (s = abfd->sections; s; s = s->next)
1130 {
1131 hdr = &elf_section_data (s)->this_hdr;
1132 switch (hdr->sh_type)
1133 {
1134 case SHT_IA_64_UNWIND:
1135 /* See comments in gas/config/tc-ia64.c:dot_endp on why we
1136 have to do this. */
1137 sname = bfd_get_section_name (abfd, s);
1138 len = sizeof (ELF_STRING_ia64_unwind) - 1;
1139 if (sname && strncmp (sname, ELF_STRING_ia64_unwind, len) == 0)
1140 {
1141 sname += len;
1142
1143 if (sname[0] == '\0')
1144 /* .IA_64.unwind -> .text */
1145 text_sect = bfd_get_section_by_name (abfd, ".text");
1146 else
1147 /* .IA_64.unwindFOO -> FOO */
1148 text_sect = bfd_get_section_by_name (abfd, sname);
1149 }
1150 else if (sname
1151 && (len = sizeof (ELF_STRING_ia64_unwind_once) - 1,
1152 strncmp (sname, ELF_STRING_ia64_unwind_once, len)) == 0)
1153 {
1154 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.t.FOO */
1155 size_t len2 = sizeof (".gnu.linkonce.t.") - 1;
1156 char *once_name = bfd_malloc (len2 + strlen (sname + len) + 1);
1157
1158 if (once_name != NULL)
1159 {
1160 memcpy (once_name, ".gnu.linkonce.t.", len2);
1161 strcpy (once_name + len2, sname + len);
1162 text_sect = bfd_get_section_by_name (abfd, once_name);
1163 free (once_name);
1164 }
1165 else
1166 /* Should only happen if we run out of memory, in
1167 which case we're probably toast anyway. Try to
1168 cope by finding the section the slow way. */
1169 for (text_sect = abfd->sections;
1170 text_sect != NULL;
1171 text_sect = text_sect->next)
1172 {
1173 if (strncmp (bfd_section_name (abfd, text_sect),
1174 ".gnu.linkonce.t.", len2) == 0
1175 && strcmp (bfd_section_name (abfd, text_sect) + len2,
1176 sname + len) == 0)
1177 break;
1178 }
1179 }
1180 else
1181 /* last resort: fall back on .text */
1182 text_sect = bfd_get_section_by_name (abfd, ".text");
1183
1184 if (text_sect)
1185 {
1186 /* The IA-64 processor-specific ABI requires setting
1187 sh_link to the unwind section, whereas HP-UX requires
1188 sh_info to do so. For maximum compatibility, we'll
1189 set both for now... */
1190 hdr->sh_link = elf_section_data (text_sect)->this_idx;
1191 hdr->sh_info = elf_section_data (text_sect)->this_idx;
1192 }
1193 break;
1194 }
1195 }
1196 }
1197
1198 /* Hook called by the linker routine which adds symbols from an object
1199 file. We use it to put .comm items in .sbss, and not .bss. */
1200
1201 static boolean
1202 elfNN_ia64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1203 bfd *abfd;
1204 struct bfd_link_info *info;
1205 const Elf_Internal_Sym *sym;
1206 const char **namep ATTRIBUTE_UNUSED;
1207 flagword *flagsp ATTRIBUTE_UNUSED;
1208 asection **secp;
1209 bfd_vma *valp;
1210 {
1211 if (sym->st_shndx == SHN_COMMON
1212 && !info->relocateable
1213 && sym->st_size <= elf_gp_size (abfd))
1214 {
1215 /* Common symbols less than or equal to -G nn bytes are
1216 automatically put into .sbss. */
1217
1218 asection *scomm = bfd_get_section_by_name (abfd, ".scommon");
1219
1220 if (scomm == NULL)
1221 {
1222 scomm = bfd_make_section (abfd, ".scommon");
1223 if (scomm == NULL
1224 || !bfd_set_section_flags (abfd, scomm, (SEC_ALLOC
1225 | SEC_IS_COMMON
1226 | SEC_LINKER_CREATED)))
1227 return false;
1228 }
1229
1230 *secp = scomm;
1231 *valp = sym->st_size;
1232 }
1233
1234 return true;
1235 }
1236
1237 static boolean
1238 elfNN_ia64_aix_vec (const bfd_target *vec)
1239 {
1240 extern const bfd_target bfd_elfNN_ia64_aix_little_vec;
1241 extern const bfd_target bfd_elfNN_ia64_aix_big_vec;
1242
1243 return (/**/vec == & bfd_elfNN_ia64_aix_little_vec
1244 || vec == & bfd_elfNN_ia64_aix_big_vec);
1245 }
1246
1247 /* Hook called by the linker routine which adds symbols from an object
1248 file. We use it to handle OS-specific symbols. */
1249
1250 static boolean
1251 elfNN_ia64_aix_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
1252 bfd *abfd;
1253 struct bfd_link_info *info;
1254 const Elf_Internal_Sym *sym;
1255 const char **namep;
1256 flagword *flagsp;
1257 asection **secp;
1258 bfd_vma *valp;
1259 {
1260 if (strcmp (*namep, "__GLOB_DATA_PTR") == 0)
1261 {
1262 /* Define __GLOB_DATA_PTR when it is encountered. This is expected to
1263 be a linker-defined symbol by the Aix C runtime startup code. IBM sez
1264 no one else should use it b/c it is undocumented. */
1265 struct elf_link_hash_entry *h;
1266
1267 h = elf_link_hash_lookup (elf_hash_table (info), *namep,
1268 false, false, false);
1269 if (h == NULL)
1270 {
1271 struct elf_backend_data *bed;
1272 struct elfNN_ia64_link_hash_table *ia64_info;
1273
1274 bed = get_elf_backend_data (abfd);
1275 ia64_info = elfNN_ia64_hash_table (info);
1276
1277 if (!(_bfd_generic_link_add_one_symbol
1278 (info, abfd, *namep, BSF_GLOBAL,
1279 bfd_get_section_by_name (abfd, ".bss"),
1280 bed->got_symbol_offset, (const char *) NULL, false,
1281 bed->collect, (struct bfd_link_hash_entry **) &h)))
1282 return false;
1283
1284 h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
1285 h->type = STT_OBJECT;
1286
1287 if (! _bfd_elf_link_record_dynamic_symbol (info, h))
1288 return false;
1289 }
1290
1291 return true;
1292 }
1293 else if (sym->st_shndx == SHN_LOOS)
1294 {
1295 unsigned int i;
1296
1297 /* SHN_AIX_SYSCALL: Treat this as any other symbol. The special symbol
1298 is only relevant when compiling code for extended system calls.
1299 Replace the "special" section with .text, if possible.
1300 Note that these symbols are always assumed to be in .text. */
1301 for (i = 1; i < elf_numsections (abfd); i++)
1302 {
1303 asection * sec = bfd_section_from_elf_index (abfd, i);
1304
1305 if (sec && strcmp (sec->name, ".text") == 0)
1306 {
1307 *secp = sec;
1308 break;
1309 }
1310 }
1311
1312 if (*secp == NULL)
1313 *secp = bfd_abs_section_ptr;
1314
1315 *valp = sym->st_size;
1316
1317 return true;
1318 }
1319 else
1320 {
1321 return elfNN_ia64_add_symbol_hook (abfd, info, sym,
1322 namep, flagsp, secp, valp);
1323 }
1324 }
1325
1326 boolean
1327 elfNN_ia64_aix_link_add_symbols (abfd, info)
1328 bfd *abfd;
1329 struct bfd_link_info *info;
1330 {
1331 /* Make sure dynamic sections are always created. */
1332 if (! elf_hash_table (info)->dynamic_sections_created
1333 && abfd->xvec == info->hash->creator)
1334 {
1335 if (! bfd_elfNN_link_create_dynamic_sections (abfd, info))
1336 return false;
1337 }
1338
1339 /* Now do the standard call. */
1340 return bfd_elfNN_bfd_link_add_symbols (abfd, info);
1341 }
1342
1343 /* Return the number of additional phdrs we will need. */
1344
1345 static int
1346 elfNN_ia64_additional_program_headers (abfd)
1347 bfd *abfd;
1348 {
1349 asection *s;
1350 int ret = 0;
1351
1352 /* See if we need a PT_IA_64_ARCHEXT segment. */
1353 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1354 if (s && (s->flags & SEC_LOAD))
1355 ++ret;
1356
1357 /* Count how many PT_IA_64_UNWIND segments we need. */
1358 for (s = abfd->sections; s; s = s->next)
1359 if (is_unwind_section_name (abfd, s->name) && (s->flags & SEC_LOAD))
1360 ++ret;
1361
1362 return ret;
1363 }
1364
1365 static boolean
1366 elfNN_ia64_modify_segment_map (abfd)
1367 bfd *abfd;
1368 {
1369 struct elf_segment_map *m, **pm;
1370 Elf_Internal_Shdr *hdr;
1371 asection *s;
1372 boolean unwind_found;
1373 asection *unwind_sec;
1374
1375 /* If we need a PT_IA_64_ARCHEXT segment, it must come before
1376 all PT_LOAD segments. */
1377 s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_archext);
1378 if (s && (s->flags & SEC_LOAD))
1379 {
1380 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1381 if (m->p_type == PT_IA_64_ARCHEXT)
1382 break;
1383 if (m == NULL)
1384 {
1385 m = ((struct elf_segment_map *)
1386 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1387 if (m == NULL)
1388 return false;
1389
1390 m->p_type = PT_IA_64_ARCHEXT;
1391 m->count = 1;
1392 m->sections[0] = s;
1393
1394 /* We want to put it after the PHDR and INTERP segments. */
1395 pm = &elf_tdata (abfd)->segment_map;
1396 while (*pm != NULL
1397 && ((*pm)->p_type == PT_PHDR
1398 || (*pm)->p_type == PT_INTERP))
1399 pm = &(*pm)->next;
1400
1401 m->next = *pm;
1402 *pm = m;
1403 }
1404 }
1405
1406 /* Install PT_IA_64_UNWIND segments, if needed. */
1407 for (s = abfd->sections; s; s = s->next)
1408 {
1409 hdr = &elf_section_data (s)->this_hdr;
1410 if (hdr->sh_type != SHT_IA_64_UNWIND)
1411 continue;
1412
1413 if (s && (s->flags & SEC_LOAD))
1414 {
1415 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1416 if (m->p_type == PT_IA_64_UNWIND)
1417 {
1418 /* Look through all sections in the unwind segment
1419 for a match since there may be multiple sections
1420 to a segment. */
1421
1422 unwind_sec = m->sections[0];
1423 unwind_found = false;
1424 while (unwind_sec != NULL && !unwind_found)
1425 {
1426 if (unwind_sec == s)
1427 unwind_found = true;
1428 else
1429 unwind_sec = unwind_sec -> next;
1430 }
1431 if (unwind_found)
1432 break;
1433 }
1434
1435 if (m == NULL)
1436 {
1437 m = ((struct elf_segment_map *)
1438 bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
1439 if (m == NULL)
1440 return false;
1441
1442 m->p_type = PT_IA_64_UNWIND;
1443 m->count = 1;
1444 m->sections[0] = s;
1445 m->next = NULL;
1446
1447 /* We want to put it last. */
1448 pm = &elf_tdata (abfd)->segment_map;
1449 while (*pm != NULL)
1450 pm = &(*pm)->next;
1451 *pm = m;
1452 }
1453 }
1454 }
1455
1456 /* Turn on PF_IA_64_NORECOV if needed. This involves traversing all of
1457 the input sections for each output section in the segment and testing
1458 for SHF_IA_64_NORECOV on each. */
1459 for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
1460 if (m->p_type == PT_LOAD)
1461 {
1462 int i;
1463 for (i = m->count - 1; i >= 0; --i)
1464 {
1465 struct bfd_link_order *order = m->sections[i]->link_order_head;
1466 while (order)
1467 {
1468 if (order->type == bfd_indirect_link_order)
1469 {
1470 asection *is = order->u.indirect.section;
1471 bfd_vma flags = elf_section_data(is)->this_hdr.sh_flags;
1472 if (flags & SHF_IA_64_NORECOV)
1473 {
1474 m->p_flags |= PF_IA_64_NORECOV;
1475 goto found;
1476 }
1477 }
1478 order = order->next;
1479 }
1480 }
1481 found:;
1482 }
1483
1484 return true;
1485 }
1486
1487 /* According to the Tahoe assembler spec, all labels starting with a
1488 '.' are local. */
1489
1490 static boolean
1491 elfNN_ia64_is_local_label_name (abfd, name)
1492 bfd *abfd ATTRIBUTE_UNUSED;
1493 const char *name;
1494 {
1495 return name[0] == '.';
1496 }
1497
1498 /* Should we do dynamic things to this symbol? */
1499
1500 static boolean
1501 elfNN_ia64_dynamic_symbol_p (h, info)
1502 struct elf_link_hash_entry *h;
1503 struct bfd_link_info *info;
1504 {
1505 if (h == NULL)
1506 return false;
1507
1508 while (h->root.type == bfd_link_hash_indirect
1509 || h->root.type == bfd_link_hash_warning)
1510 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1511
1512 if (h->dynindx == -1)
1513 return false;
1514 switch (ELF_ST_VISIBILITY (h->other))
1515 {
1516 case STV_INTERNAL:
1517 case STV_HIDDEN:
1518 return false;
1519 }
1520
1521 if (h->root.type == bfd_link_hash_undefweak
1522 || h->root.type == bfd_link_hash_defweak)
1523 return true;
1524
1525 if ((info->shared && (!info->symbolic || info->allow_shlib_undefined))
1526 || ((h->elf_link_hash_flags
1527 & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR))
1528 == (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)))
1529 return true;
1530
1531 return false;
1532 }
1533 \f
1534 static boolean
1535 elfNN_ia64_local_hash_table_init (ht, abfd, new)
1536 struct elfNN_ia64_local_hash_table *ht;
1537 bfd *abfd ATTRIBUTE_UNUSED;
1538 new_hash_entry_func new;
1539 {
1540 memset (ht, 0, sizeof (*ht));
1541 return bfd_hash_table_init (&ht->root, new);
1542 }
1543
1544 static struct bfd_hash_entry*
1545 elfNN_ia64_new_loc_hash_entry (entry, table, string)
1546 struct bfd_hash_entry *entry;
1547 struct bfd_hash_table *table;
1548 const char *string;
1549 {
1550 struct elfNN_ia64_local_hash_entry *ret;
1551 ret = (struct elfNN_ia64_local_hash_entry *) entry;
1552
1553 /* Allocate the structure if it has not already been allocated by a
1554 subclass. */
1555 if (!ret)
1556 ret = bfd_hash_allocate (table, sizeof (*ret));
1557
1558 if (!ret)
1559 return 0;
1560
1561 /* Initialize our local data. All zeros, and definitely easier
1562 than setting a handful of bit fields. */
1563 memset (ret, 0, sizeof (*ret));
1564
1565 /* Call the allocation method of the superclass. */
1566 ret = ((struct elfNN_ia64_local_hash_entry *)
1567 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
1568
1569 return (struct bfd_hash_entry *) ret;
1570 }
1571
1572 static struct bfd_hash_entry*
1573 elfNN_ia64_new_elf_hash_entry (entry, table, string)
1574 struct bfd_hash_entry *entry;
1575 struct bfd_hash_table *table;
1576 const char *string;
1577 {
1578 struct elfNN_ia64_link_hash_entry *ret;
1579 ret = (struct elfNN_ia64_link_hash_entry *) entry;
1580
1581 /* Allocate the structure if it has not already been allocated by a
1582 subclass. */
1583 if (!ret)
1584 ret = bfd_hash_allocate (table, sizeof (*ret));
1585
1586 if (!ret)
1587 return 0;
1588
1589 /* Initialize our local data. All zeros, and definitely easier
1590 than setting a handful of bit fields. */
1591 memset (ret, 0, sizeof (*ret));
1592
1593 /* Call the allocation method of the superclass. */
1594 ret = ((struct elfNN_ia64_link_hash_entry *)
1595 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1596 table, string));
1597
1598 return (struct bfd_hash_entry *) ret;
1599 }
1600
1601 static void
1602 elfNN_ia64_hash_copy_indirect (xdir, xind)
1603 struct elf_link_hash_entry *xdir, *xind;
1604 {
1605 struct elfNN_ia64_link_hash_entry *dir, *ind;
1606
1607 dir = (struct elfNN_ia64_link_hash_entry *) xdir;
1608 ind = (struct elfNN_ia64_link_hash_entry *) xind;
1609
1610 /* Copy down any references that we may have already seen to the
1611 symbol which just became indirect. */
1612
1613 dir->root.elf_link_hash_flags |=
1614 (ind->root.elf_link_hash_flags
1615 & (ELF_LINK_HASH_REF_DYNAMIC
1616 | ELF_LINK_HASH_REF_REGULAR
1617 | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
1618
1619 if (ind->root.root.type != bfd_link_hash_indirect)
1620 return;
1621
1622 /* Copy over the got and plt data. This would have been done
1623 by check_relocs. */
1624
1625 if (dir->info == NULL)
1626 {
1627 struct elfNN_ia64_dyn_sym_info *dyn_i;
1628
1629 dir->info = dyn_i = ind->info;
1630 ind->info = NULL;
1631
1632 /* Fix up the dyn_sym_info pointers to the global symbol. */
1633 for (; dyn_i; dyn_i = dyn_i->next)
1634 dyn_i->h = &dir->root;
1635 }
1636 BFD_ASSERT (ind->info == NULL);
1637
1638 /* Copy over the dynindx. */
1639
1640 if (dir->root.dynindx == -1)
1641 {
1642 dir->root.dynindx = ind->root.dynindx;
1643 dir->root.dynstr_index = ind->root.dynstr_index;
1644 ind->root.dynindx = -1;
1645 ind->root.dynstr_index = 0;
1646 }
1647 BFD_ASSERT (ind->root.dynindx == -1);
1648 }
1649
1650 static void
1651 elfNN_ia64_hash_hide_symbol (info, xh, force_local)
1652 struct bfd_link_info *info;
1653 struct elf_link_hash_entry *xh;
1654 boolean force_local;
1655 {
1656 struct elfNN_ia64_link_hash_entry *h;
1657 struct elfNN_ia64_dyn_sym_info *dyn_i;
1658
1659 h = (struct elfNN_ia64_link_hash_entry *)xh;
1660
1661 _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1662
1663 for (dyn_i = h->info; dyn_i; dyn_i = dyn_i->next)
1664 dyn_i->want_plt2 = 0;
1665 }
1666
1667 /* Create the derived linker hash table. The IA-64 ELF port uses this
1668 derived hash table to keep information specific to the IA-64 ElF
1669 linker (without using static variables). */
1670
1671 static struct bfd_link_hash_table*
1672 elfNN_ia64_hash_table_create (abfd)
1673 bfd *abfd;
1674 {
1675 struct elfNN_ia64_link_hash_table *ret;
1676
1677 ret = bfd_zalloc (abfd, (bfd_size_type) sizeof (*ret));
1678 if (!ret)
1679 return 0;
1680 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1681 elfNN_ia64_new_elf_hash_entry))
1682 {
1683 bfd_release (abfd, ret);
1684 return 0;
1685 }
1686
1687 if (!elfNN_ia64_local_hash_table_init (&ret->loc_hash_table, abfd,
1688 elfNN_ia64_new_loc_hash_entry))
1689 return 0;
1690 return &ret->root.root;
1691 }
1692
1693 /* Look up an entry in a Alpha ELF linker hash table. */
1694
1695 static INLINE struct elfNN_ia64_local_hash_entry *
1696 elfNN_ia64_local_hash_lookup(table, string, create, copy)
1697 struct elfNN_ia64_local_hash_table *table;
1698 const char *string;
1699 boolean create, copy;
1700 {
1701 return ((struct elfNN_ia64_local_hash_entry *)
1702 bfd_hash_lookup (&table->root, string, create, copy));
1703 }
1704
1705 /* Traverse both local and global hash tables. */
1706
1707 struct elfNN_ia64_dyn_sym_traverse_data
1708 {
1709 boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1710 PTR data;
1711 };
1712
1713 static boolean
1714 elfNN_ia64_global_dyn_sym_thunk (xentry, xdata)
1715 struct bfd_hash_entry *xentry;
1716 PTR xdata;
1717 {
1718 struct elfNN_ia64_link_hash_entry *entry
1719 = (struct elfNN_ia64_link_hash_entry *) xentry;
1720 struct elfNN_ia64_dyn_sym_traverse_data *data
1721 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1722 struct elfNN_ia64_dyn_sym_info *dyn_i;
1723
1724 if (entry->root.root.type == bfd_link_hash_warning)
1725 entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
1726
1727 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1728 if (! (*data->func) (dyn_i, data->data))
1729 return false;
1730 return true;
1731 }
1732
1733 static boolean
1734 elfNN_ia64_local_dyn_sym_thunk (xentry, xdata)
1735 struct bfd_hash_entry *xentry;
1736 PTR xdata;
1737 {
1738 struct elfNN_ia64_local_hash_entry *entry
1739 = (struct elfNN_ia64_local_hash_entry *) xentry;
1740 struct elfNN_ia64_dyn_sym_traverse_data *data
1741 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1742 struct elfNN_ia64_dyn_sym_info *dyn_i;
1743
1744 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1745 if (! (*data->func) (dyn_i, data->data))
1746 return false;
1747 return true;
1748 }
1749
1750 static void
1751 elfNN_ia64_dyn_sym_traverse (ia64_info, func, data)
1752 struct elfNN_ia64_link_hash_table *ia64_info;
1753 boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1754 PTR data;
1755 {
1756 struct elfNN_ia64_dyn_sym_traverse_data xdata;
1757
1758 xdata.func = func;
1759 xdata.data = data;
1760
1761 elf_link_hash_traverse (&ia64_info->root,
1762 elfNN_ia64_global_dyn_sym_thunk, &xdata);
1763 bfd_hash_traverse (&ia64_info->loc_hash_table.root,
1764 elfNN_ia64_local_dyn_sym_thunk, &xdata);
1765 }
1766 \f
1767 static boolean
1768 elfNN_ia64_create_dynamic_sections (abfd, info)
1769 bfd *abfd;
1770 struct bfd_link_info *info;
1771 {
1772 struct elfNN_ia64_link_hash_table *ia64_info;
1773 asection *s;
1774
1775 if (! _bfd_elf_create_dynamic_sections (abfd, info))
1776 return false;
1777
1778 ia64_info = elfNN_ia64_hash_table (info);
1779
1780 ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
1781 ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
1782
1783 {
1784 flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
1785 bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
1786 }
1787
1788 if (!get_pltoff (abfd, info, ia64_info))
1789 return false;
1790
1791 s = bfd_make_section(abfd, ".rela.IA_64.pltoff");
1792 if (s == NULL
1793 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1794 | SEC_HAS_CONTENTS
1795 | SEC_IN_MEMORY
1796 | SEC_LINKER_CREATED
1797 | SEC_READONLY))
1798 || !bfd_set_section_alignment (abfd, s, 3))
1799 return false;
1800 ia64_info->rel_pltoff_sec = s;
1801
1802 s = bfd_make_section(abfd, ".rela.got");
1803 if (s == NULL
1804 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1805 | SEC_HAS_CONTENTS
1806 | SEC_IN_MEMORY
1807 | SEC_LINKER_CREATED
1808 | SEC_READONLY))
1809 || !bfd_set_section_alignment (abfd, s, 3))
1810 return false;
1811 ia64_info->rel_got_sec = s;
1812
1813 return true;
1814 }
1815
1816 /* Find and/or create a hash entry for local symbol. */
1817 static struct elfNN_ia64_local_hash_entry *
1818 get_local_sym_hash (ia64_info, abfd, rel, create)
1819 struct elfNN_ia64_link_hash_table *ia64_info;
1820 bfd *abfd;
1821 const Elf_Internal_Rela *rel;
1822 boolean create;
1823 {
1824 char *addr_name;
1825 size_t len;
1826 struct elfNN_ia64_local_hash_entry *ret;
1827
1828 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1829 name describes what was once anonymous memory. */
1830
1831 len = sizeof (void*)*2 + 1 + sizeof (bfd_vma)*4 + 1 + 1;
1832 len += 10; /* %p slop */
1833
1834 addr_name = bfd_malloc (len);
1835 if (addr_name == NULL)
1836 return 0;
1837 sprintf (addr_name, "%p:%lx",
1838 (void *) abfd, (unsigned long) ELFNN_R_SYM (rel->r_info));
1839
1840 /* Collect the canonical entry data for this address. */
1841 ret = elfNN_ia64_local_hash_lookup (&ia64_info->loc_hash_table,
1842 addr_name, create, create);
1843 free (addr_name);
1844 return ret;
1845 }
1846
1847 /* Find and/or create a descriptor for dynamic symbol info. This will
1848 vary based on global or local symbol, and the addend to the reloc. */
1849
1850 static struct elfNN_ia64_dyn_sym_info *
1851 get_dyn_sym_info (ia64_info, h, abfd, rel, create)
1852 struct elfNN_ia64_link_hash_table *ia64_info;
1853 struct elf_link_hash_entry *h;
1854 bfd *abfd;
1855 const Elf_Internal_Rela *rel;
1856 boolean create;
1857 {
1858 struct elfNN_ia64_dyn_sym_info **pp;
1859 struct elfNN_ia64_dyn_sym_info *dyn_i;
1860 bfd_vma addend = rel ? rel->r_addend : 0;
1861
1862 if (h)
1863 pp = &((struct elfNN_ia64_link_hash_entry *)h)->info;
1864 else
1865 {
1866 struct elfNN_ia64_local_hash_entry *loc_h;
1867
1868 loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
1869 BFD_ASSERT (loc_h);
1870
1871 pp = &loc_h->info;
1872 }
1873
1874 for (dyn_i = *pp; dyn_i && dyn_i->addend != addend; dyn_i = *pp)
1875 pp = &dyn_i->next;
1876
1877 if (dyn_i == NULL && create)
1878 {
1879 dyn_i = ((struct elfNN_ia64_dyn_sym_info *)
1880 bfd_zalloc (abfd, (bfd_size_type) sizeof *dyn_i));
1881 *pp = dyn_i;
1882 dyn_i->addend = addend;
1883 }
1884
1885 return dyn_i;
1886 }
1887
1888 static asection *
1889 get_got (abfd, info, ia64_info)
1890 bfd *abfd;
1891 struct bfd_link_info *info;
1892 struct elfNN_ia64_link_hash_table *ia64_info;
1893 {
1894 asection *got;
1895 bfd *dynobj;
1896
1897 got = ia64_info->got_sec;
1898 if (!got)
1899 {
1900 flagword flags;
1901
1902 dynobj = ia64_info->root.dynobj;
1903 if (!dynobj)
1904 ia64_info->root.dynobj = dynobj = abfd;
1905 if (!_bfd_elf_create_got_section (dynobj, info))
1906 return 0;
1907
1908 got = bfd_get_section_by_name (dynobj, ".got");
1909 BFD_ASSERT (got);
1910 ia64_info->got_sec = got;
1911
1912 flags = bfd_get_section_flags (abfd, got);
1913 bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
1914 }
1915
1916 return got;
1917 }
1918
1919 /* Create function descriptor section (.opd). This section is called .opd
1920 because it contains "official prodecure descriptors". The "official"
1921 refers to the fact that these descriptors are used when taking the address
1922 of a procedure, thus ensuring a unique address for each procedure. */
1923
1924 static asection *
1925 get_fptr (abfd, info, ia64_info)
1926 bfd *abfd;
1927 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1928 struct elfNN_ia64_link_hash_table *ia64_info;
1929 {
1930 asection *fptr;
1931 bfd *dynobj;
1932
1933 fptr = ia64_info->fptr_sec;
1934 if (!fptr)
1935 {
1936 dynobj = ia64_info->root.dynobj;
1937 if (!dynobj)
1938 ia64_info->root.dynobj = dynobj = abfd;
1939
1940 fptr = bfd_make_section (dynobj, ".opd");
1941 if (!fptr
1942 || !bfd_set_section_flags (dynobj, fptr,
1943 (SEC_ALLOC
1944 | SEC_LOAD
1945 | SEC_HAS_CONTENTS
1946 | SEC_IN_MEMORY
1947 | SEC_READONLY
1948 | SEC_LINKER_CREATED))
1949 || !bfd_set_section_alignment (abfd, fptr, 4))
1950 {
1951 BFD_ASSERT (0);
1952 return NULL;
1953 }
1954
1955 ia64_info->fptr_sec = fptr;
1956 }
1957
1958 return fptr;
1959 }
1960
1961 static asection *
1962 get_pltoff (abfd, info, ia64_info)
1963 bfd *abfd;
1964 struct bfd_link_info *info ATTRIBUTE_UNUSED;
1965 struct elfNN_ia64_link_hash_table *ia64_info;
1966 {
1967 asection *pltoff;
1968 bfd *dynobj;
1969
1970 pltoff = ia64_info->pltoff_sec;
1971 if (!pltoff)
1972 {
1973 dynobj = ia64_info->root.dynobj;
1974 if (!dynobj)
1975 ia64_info->root.dynobj = dynobj = abfd;
1976
1977 pltoff = bfd_make_section (dynobj, ELF_STRING_ia64_pltoff);
1978 if (!pltoff
1979 || !bfd_set_section_flags (dynobj, pltoff,
1980 (SEC_ALLOC
1981 | SEC_LOAD
1982 | SEC_HAS_CONTENTS
1983 | SEC_IN_MEMORY
1984 | SEC_SMALL_DATA
1985 | SEC_LINKER_CREATED))
1986 || !bfd_set_section_alignment (abfd, pltoff, 4))
1987 {
1988 BFD_ASSERT (0);
1989 return NULL;
1990 }
1991
1992 ia64_info->pltoff_sec = pltoff;
1993 }
1994
1995 return pltoff;
1996 }
1997
1998 static asection *
1999 get_reloc_section (abfd, ia64_info, sec, create)
2000 bfd *abfd;
2001 struct elfNN_ia64_link_hash_table *ia64_info;
2002 asection *sec;
2003 boolean create;
2004 {
2005 const char *srel_name;
2006 asection *srel;
2007 bfd *dynobj;
2008
2009 srel_name = (bfd_elf_string_from_elf_section
2010 (abfd, elf_elfheader(abfd)->e_shstrndx,
2011 elf_section_data(sec)->rel_hdr.sh_name));
2012 if (srel_name == NULL)
2013 return NULL;
2014
2015 BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0
2016 && strcmp (bfd_get_section_name (abfd, sec),
2017 srel_name+5) == 0)
2018 || (strncmp (srel_name, ".rel", 4) == 0
2019 && strcmp (bfd_get_section_name (abfd, sec),
2020 srel_name+4) == 0));
2021
2022 dynobj = ia64_info->root.dynobj;
2023 if (!dynobj)
2024 ia64_info->root.dynobj = dynobj = abfd;
2025
2026 srel = bfd_get_section_by_name (dynobj, srel_name);
2027 if (srel == NULL && create)
2028 {
2029 srel = bfd_make_section (dynobj, srel_name);
2030 if (srel == NULL
2031 || !bfd_set_section_flags (dynobj, srel,
2032 (SEC_ALLOC
2033 | SEC_LOAD
2034 | SEC_HAS_CONTENTS
2035 | SEC_IN_MEMORY
2036 | SEC_LINKER_CREATED
2037 | SEC_READONLY))
2038 || !bfd_set_section_alignment (dynobj, srel, 3))
2039 return NULL;
2040 }
2041
2042 if (sec->flags & SEC_READONLY)
2043 ia64_info->reltext = 1;
2044
2045 return srel;
2046 }
2047
2048 static boolean
2049 count_dyn_reloc (abfd, dyn_i, srel, type)
2050 bfd *abfd;
2051 struct elfNN_ia64_dyn_sym_info *dyn_i;
2052 asection *srel;
2053 int type;
2054 {
2055 struct elfNN_ia64_dyn_reloc_entry *rent;
2056
2057 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2058 if (rent->srel == srel && rent->type == type)
2059 break;
2060
2061 if (!rent)
2062 {
2063 rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2064 bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
2065 if (!rent)
2066 return false;
2067
2068 rent->next = dyn_i->reloc_entries;
2069 rent->srel = srel;
2070 rent->type = type;
2071 rent->count = 0;
2072 dyn_i->reloc_entries = rent;
2073 }
2074 rent->count++;
2075
2076 return true;
2077 }
2078
2079 static boolean
2080 elfNN_ia64_check_relocs (abfd, info, sec, relocs)
2081 bfd *abfd;
2082 struct bfd_link_info *info;
2083 asection *sec;
2084 const Elf_Internal_Rela *relocs;
2085 {
2086 struct elfNN_ia64_link_hash_table *ia64_info;
2087 const Elf_Internal_Rela *relend;
2088 Elf_Internal_Shdr *symtab_hdr;
2089 const Elf_Internal_Rela *rel;
2090 asection *got, *fptr, *srel;
2091
2092 if (info->relocateable)
2093 return true;
2094
2095 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2096 ia64_info = elfNN_ia64_hash_table (info);
2097
2098 got = fptr = srel = NULL;
2099
2100 relend = relocs + sec->reloc_count;
2101 for (rel = relocs; rel < relend; ++rel)
2102 {
2103 enum {
2104 NEED_GOT = 1,
2105 NEED_FPTR = 2,
2106 NEED_PLTOFF = 4,
2107 NEED_MIN_PLT = 8,
2108 NEED_FULL_PLT = 16,
2109 NEED_DYNREL = 32,
2110 NEED_LTOFF_FPTR = 64,
2111 NEED_TPREL = 128,
2112 NEED_DTPMOD = 256,
2113 NEED_DTPREL = 512
2114 };
2115
2116 struct elf_link_hash_entry *h = NULL;
2117 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
2118 struct elfNN_ia64_dyn_sym_info *dyn_i;
2119 int need_entry;
2120 boolean maybe_dynamic;
2121 int dynrel_type = R_IA64_NONE;
2122
2123 if (r_symndx >= symtab_hdr->sh_info)
2124 {
2125 /* We're dealing with a global symbol -- find its hash entry
2126 and mark it as being referenced. */
2127 long indx = r_symndx - symtab_hdr->sh_info;
2128 h = elf_sym_hashes (abfd)[indx];
2129 while (h->root.type == bfd_link_hash_indirect
2130 || h->root.type == bfd_link_hash_warning)
2131 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2132
2133 h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
2134 }
2135
2136 /* We can only get preliminary data on whether a symbol is
2137 locally or externally defined, as not all of the input files
2138 have yet been processed. Do something with what we know, as
2139 this may help reduce memory usage and processing time later. */
2140 maybe_dynamic = false;
2141 if (h && ((info->shared
2142 && (!info->symbolic || info->allow_shlib_undefined))
2143 || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
2144 || h->root.type == bfd_link_hash_defweak
2145 || elfNN_ia64_aix_vec (abfd->xvec)))
2146 maybe_dynamic = true;
2147
2148 need_entry = 0;
2149 switch (ELFNN_R_TYPE (rel->r_info))
2150 {
2151 case R_IA64_TPREL64MSB:
2152 case R_IA64_TPREL64LSB:
2153 if (info->shared || maybe_dynamic)
2154 need_entry = NEED_DYNREL;
2155 dynrel_type = R_IA64_TPREL64LSB;
2156 if (info->shared)
2157 info->flags |= DF_STATIC_TLS;
2158 break;
2159
2160 case R_IA64_LTOFF_TPREL22:
2161 need_entry = NEED_TPREL;
2162 if (info->shared)
2163 info->flags |= DF_STATIC_TLS;
2164 break;
2165
2166 case R_IA64_DTPREL64MSB:
2167 case R_IA64_DTPREL64LSB:
2168 if (info->shared || maybe_dynamic)
2169 need_entry = NEED_DYNREL;
2170 dynrel_type = R_IA64_DTPREL64LSB;
2171 break;
2172
2173 case R_IA64_LTOFF_DTPREL22:
2174 need_entry = NEED_DTPREL;
2175 break;
2176
2177 case R_IA64_DTPMOD64MSB:
2178 case R_IA64_DTPMOD64LSB:
2179 if (info->shared || maybe_dynamic)
2180 need_entry = NEED_DYNREL;
2181 dynrel_type = R_IA64_DTPMOD64LSB;
2182 break;
2183
2184 case R_IA64_LTOFF_DTPMOD22:
2185 need_entry = NEED_DTPMOD;
2186 break;
2187
2188 case R_IA64_LTOFF_FPTR22:
2189 case R_IA64_LTOFF_FPTR64I:
2190 case R_IA64_LTOFF_FPTR32MSB:
2191 case R_IA64_LTOFF_FPTR32LSB:
2192 case R_IA64_LTOFF_FPTR64MSB:
2193 case R_IA64_LTOFF_FPTR64LSB:
2194 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2195 break;
2196
2197 case R_IA64_FPTR64I:
2198 case R_IA64_FPTR32MSB:
2199 case R_IA64_FPTR32LSB:
2200 case R_IA64_FPTR64MSB:
2201 case R_IA64_FPTR64LSB:
2202 if (info->shared || h || elfNN_ia64_aix_vec (abfd->xvec))
2203 need_entry = NEED_FPTR | NEED_DYNREL;
2204 else
2205 need_entry = NEED_FPTR;
2206 dynrel_type = R_IA64_FPTR64LSB;
2207 break;
2208
2209 case R_IA64_LTOFF22:
2210 case R_IA64_LTOFF22X:
2211 case R_IA64_LTOFF64I:
2212 need_entry = NEED_GOT;
2213 break;
2214
2215 case R_IA64_PLTOFF22:
2216 case R_IA64_PLTOFF64I:
2217 case R_IA64_PLTOFF64MSB:
2218 case R_IA64_PLTOFF64LSB:
2219 need_entry = NEED_PLTOFF;
2220 if (h)
2221 {
2222 if (maybe_dynamic)
2223 need_entry |= NEED_MIN_PLT;
2224 }
2225 else
2226 {
2227 (*info->callbacks->warning)
2228 (info, _("@pltoff reloc against local symbol"), 0,
2229 abfd, 0, (bfd_vma) 0);
2230 }
2231 break;
2232
2233 case R_IA64_PCREL21B:
2234 case R_IA64_PCREL60B:
2235 /* Depending on where this symbol is defined, we may or may not
2236 need a full plt entry. Only skip if we know we'll not need
2237 the entry -- static or symbolic, and the symbol definition
2238 has already been seen. */
2239 if (maybe_dynamic && rel->r_addend == 0)
2240 need_entry = NEED_FULL_PLT;
2241 break;
2242
2243 case R_IA64_IMM14:
2244 case R_IA64_IMM22:
2245 case R_IA64_IMM64:
2246 case R_IA64_DIR32MSB:
2247 case R_IA64_DIR32LSB:
2248 case R_IA64_DIR64MSB:
2249 case R_IA64_DIR64LSB:
2250 /* Shared objects will always need at least a REL relocation. */
2251 if (info->shared || maybe_dynamic
2252 || (elfNN_ia64_aix_vec (abfd->xvec)
2253 && (!h || strcmp (h->root.root.string,
2254 "__GLOB_DATA_PTR") != 0)))
2255 need_entry = NEED_DYNREL;
2256 dynrel_type = R_IA64_DIR64LSB;
2257 break;
2258
2259 case R_IA64_IPLTMSB:
2260 case R_IA64_IPLTLSB:
2261 /* Shared objects will always need at least a REL relocation. */
2262 if (info->shared || maybe_dynamic)
2263 need_entry = NEED_DYNREL;
2264 dynrel_type = R_IA64_IPLTLSB;
2265 break;
2266
2267 case R_IA64_PCREL22:
2268 case R_IA64_PCREL64I:
2269 case R_IA64_PCREL32MSB:
2270 case R_IA64_PCREL32LSB:
2271 case R_IA64_PCREL64MSB:
2272 case R_IA64_PCREL64LSB:
2273 if (maybe_dynamic)
2274 need_entry = NEED_DYNREL;
2275 dynrel_type = R_IA64_PCREL64LSB;
2276 break;
2277 }
2278
2279 if (!need_entry)
2280 continue;
2281
2282 if ((need_entry & NEED_FPTR) != 0
2283 && rel->r_addend)
2284 {
2285 (*info->callbacks->warning)
2286 (info, _("non-zero addend in @fptr reloc"), 0,
2287 abfd, 0, (bfd_vma) 0);
2288 }
2289
2290 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, true);
2291
2292 /* Record whether or not this is a local symbol. */
2293 dyn_i->h = h;
2294
2295 /* Create what's needed. */
2296 if (need_entry & (NEED_GOT | NEED_TPREL | NEED_DTPMOD | NEED_DTPREL))
2297 {
2298 if (!got)
2299 {
2300 got = get_got (abfd, info, ia64_info);
2301 if (!got)
2302 return false;
2303 }
2304 if (need_entry & NEED_GOT)
2305 dyn_i->want_got = 1;
2306 if (need_entry & NEED_TPREL)
2307 dyn_i->want_tprel = 1;
2308 if (need_entry & NEED_DTPMOD)
2309 dyn_i->want_dtpmod = 1;
2310 if (need_entry & NEED_DTPREL)
2311 dyn_i->want_dtprel = 1;
2312 }
2313 if (need_entry & NEED_FPTR)
2314 {
2315 if (!fptr)
2316 {
2317 fptr = get_fptr (abfd, info, ia64_info);
2318 if (!fptr)
2319 return false;
2320 }
2321
2322 /* FPTRs for shared libraries are allocated by the dynamic
2323 linker. Make sure this local symbol will appear in the
2324 dynamic symbol table. */
2325 if (!h && (info->shared
2326 /* AIX also needs one */
2327 || elfNN_ia64_aix_vec (abfd->xvec)))
2328 {
2329 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2330 (info, abfd, (long) r_symndx)))
2331 return false;
2332 }
2333
2334 dyn_i->want_fptr = 1;
2335 }
2336 if (need_entry & NEED_LTOFF_FPTR)
2337 dyn_i->want_ltoff_fptr = 1;
2338 if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
2339 {
2340 if (!ia64_info->root.dynobj)
2341 ia64_info->root.dynobj = abfd;
2342 h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
2343 dyn_i->want_plt = 1;
2344 }
2345 if (need_entry & NEED_FULL_PLT)
2346 dyn_i->want_plt2 = 1;
2347 if (need_entry & NEED_PLTOFF)
2348 dyn_i->want_pltoff = 1;
2349 if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
2350 {
2351 if (!srel)
2352 {
2353 srel = get_reloc_section (abfd, ia64_info, sec, true);
2354 if (!srel)
2355 return false;
2356 }
2357 if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type))
2358 return false;
2359 }
2360 }
2361
2362 return true;
2363 }
2364
2365 struct elfNN_ia64_allocate_data
2366 {
2367 struct bfd_link_info *info;
2368 bfd_size_type ofs;
2369 };
2370
2371 /* For cleanliness, and potentially faster dynamic loading, allocate
2372 external GOT entries first. */
2373
2374 static boolean
2375 allocate_global_data_got (dyn_i, data)
2376 struct elfNN_ia64_dyn_sym_info *dyn_i;
2377 PTR data;
2378 {
2379 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2380
2381 if (dyn_i->want_got
2382 && ! dyn_i->want_fptr
2383 && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2384 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2385 && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2386 "__GLOB_DATA_PTR") != 0))))
2387 {
2388 dyn_i->got_offset = x->ofs;
2389 x->ofs += 8;
2390 }
2391 if (dyn_i->want_tprel)
2392 {
2393 dyn_i->tprel_offset = x->ofs;
2394 x->ofs += 8;
2395 }
2396 if (dyn_i->want_dtpmod)
2397 {
2398 dyn_i->dtpmod_offset = x->ofs;
2399 x->ofs += 8;
2400 }
2401 if (dyn_i->want_dtprel)
2402 {
2403 dyn_i->dtprel_offset = x->ofs;
2404 x->ofs += 8;
2405 }
2406 return true;
2407 }
2408
2409 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2410
2411 static boolean
2412 allocate_global_fptr_got (dyn_i, data)
2413 struct elfNN_ia64_dyn_sym_info *dyn_i;
2414 PTR data;
2415 {
2416 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2417
2418 if (dyn_i->want_got
2419 && dyn_i->want_fptr
2420 && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2421 || elfNN_ia64_aix_vec (x->info->hash->creator)))
2422 {
2423 dyn_i->got_offset = x->ofs;
2424 x->ofs += 8;
2425 }
2426 return true;
2427 }
2428
2429 /* Lastly, allocate all the GOT entries for local data. */
2430
2431 static boolean
2432 allocate_local_got (dyn_i, data)
2433 struct elfNN_ia64_dyn_sym_info *dyn_i;
2434 PTR data;
2435 {
2436 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2437
2438 if (dyn_i->want_got
2439 && ! (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2440 || elfNN_ia64_aix_vec (x->info->hash->creator)))
2441 {
2442 dyn_i->got_offset = x->ofs;
2443 x->ofs += 8;
2444 }
2445 return true;
2446 }
2447
2448 /* Search for the index of a global symbol in it's defining object file. */
2449
2450 static long
2451 global_sym_index (h)
2452 struct elf_link_hash_entry *h;
2453 {
2454 struct elf_link_hash_entry **p;
2455 bfd *obj;
2456
2457 BFD_ASSERT (h->root.type == bfd_link_hash_defined
2458 || h->root.type == bfd_link_hash_defweak);
2459
2460 obj = h->root.u.def.section->owner;
2461 for (p = elf_sym_hashes (obj); *p != h; ++p)
2462 continue;
2463
2464 return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2465 }
2466
2467 /* Allocate function descriptors. We can do these for every function
2468 in a main executable that is not exported. */
2469
2470 static boolean
2471 allocate_fptr (dyn_i, data)
2472 struct elfNN_ia64_dyn_sym_info *dyn_i;
2473 PTR data;
2474 {
2475 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2476
2477 if (dyn_i->want_fptr)
2478 {
2479 struct elf_link_hash_entry *h = dyn_i->h;
2480
2481 if (h)
2482 while (h->root.type == bfd_link_hash_indirect
2483 || h->root.type == bfd_link_hash_warning)
2484 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2485
2486 if (x->info->shared
2487 /* AIX needs an FPTR in this case. */
2488 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2489 && (!h
2490 || h->root.type == bfd_link_hash_defined
2491 || h->root.type == bfd_link_hash_defweak)))
2492 {
2493 if (h && h->dynindx == -1)
2494 {
2495 BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2496 || (h->root.type == bfd_link_hash_defweak));
2497
2498 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2499 (x->info, h->root.u.def.section->owner,
2500 global_sym_index (h)))
2501 return false;
2502 }
2503
2504 dyn_i->want_fptr = 0;
2505 }
2506 else if (h == NULL || h->dynindx == -1)
2507 {
2508 dyn_i->fptr_offset = x->ofs;
2509 x->ofs += 16;
2510 }
2511 else
2512 dyn_i->want_fptr = 0;
2513 }
2514 return true;
2515 }
2516
2517 /* Allocate all the minimal PLT entries. */
2518
2519 static boolean
2520 allocate_plt_entries (dyn_i, data)
2521 struct elfNN_ia64_dyn_sym_info *dyn_i;
2522 PTR data;
2523 {
2524 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2525
2526 if (dyn_i->want_plt)
2527 {
2528 struct elf_link_hash_entry *h = dyn_i->h;
2529
2530 if (h)
2531 while (h->root.type == bfd_link_hash_indirect
2532 || h->root.type == bfd_link_hash_warning)
2533 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2534
2535 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2536 if (elfNN_ia64_dynamic_symbol_p (h, x->info))
2537 {
2538 bfd_size_type offset = x->ofs;
2539 if (offset == 0)
2540 offset = PLT_HEADER_SIZE;
2541 dyn_i->plt_offset = offset;
2542 x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2543
2544 dyn_i->want_pltoff = 1;
2545 }
2546 else
2547 {
2548 dyn_i->want_plt = 0;
2549 dyn_i->want_plt2 = 0;
2550 }
2551 }
2552 return true;
2553 }
2554
2555 /* Allocate all the full PLT entries. */
2556
2557 static boolean
2558 allocate_plt2_entries (dyn_i, data)
2559 struct elfNN_ia64_dyn_sym_info *dyn_i;
2560 PTR data;
2561 {
2562 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2563
2564 if (dyn_i->want_plt2)
2565 {
2566 struct elf_link_hash_entry *h = dyn_i->h;
2567 bfd_size_type ofs = x->ofs;
2568
2569 dyn_i->plt2_offset = ofs;
2570 x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2571
2572 while (h->root.type == bfd_link_hash_indirect
2573 || h->root.type == bfd_link_hash_warning)
2574 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2575 dyn_i->h->plt.offset = ofs;
2576 }
2577 return true;
2578 }
2579
2580 /* Allocate all the PLTOFF entries requested by relocations and
2581 plt entries. We can't share space with allocated FPTR entries,
2582 because the latter are not necessarily addressable by the GP.
2583 ??? Relaxation might be able to determine that they are. */
2584
2585 static boolean
2586 allocate_pltoff_entries (dyn_i, data)
2587 struct elfNN_ia64_dyn_sym_info *dyn_i;
2588 PTR data;
2589 {
2590 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2591
2592 if (dyn_i->want_pltoff)
2593 {
2594 dyn_i->pltoff_offset = x->ofs;
2595 x->ofs += 16;
2596 }
2597 return true;
2598 }
2599
2600 /* Allocate dynamic relocations for those symbols that turned out
2601 to be dynamic. */
2602
2603 static boolean
2604 allocate_dynrel_entries (dyn_i, data)
2605 struct elfNN_ia64_dyn_sym_info *dyn_i;
2606 PTR data;
2607 {
2608 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2609 struct elfNN_ia64_link_hash_table *ia64_info;
2610 struct elfNN_ia64_dyn_reloc_entry *rent;
2611 boolean dynamic_symbol, shared;
2612
2613 ia64_info = elfNN_ia64_hash_table (x->info);
2614 dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2615 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2616 /* Don't allocate an entry for __GLOB_DATA_PTR */
2617 && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2618 "__GLOB_DATA_PTR") != 0));
2619 shared = x->info->shared;
2620
2621 /* Take care of the normal data relocations. */
2622
2623 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2624 {
2625 int count = rent->count;
2626
2627 switch (rent->type)
2628 {
2629 case R_IA64_FPTR64LSB:
2630 /* Allocate one iff !want_fptr, which by this point will
2631 be true only if we're actually allocating one statically
2632 in the main executable. */
2633 if (dyn_i->want_fptr)
2634 continue;
2635 break;
2636 case R_IA64_PCREL64LSB:
2637 if (!dynamic_symbol)
2638 continue;
2639 break;
2640 case R_IA64_DIR64LSB:
2641 if (!dynamic_symbol && !shared)
2642 continue;
2643 break;
2644 case R_IA64_IPLTLSB:
2645 if (!dynamic_symbol && !shared)
2646 continue;
2647 /* Use two REL relocations for IPLT relocations
2648 against local symbols. */
2649 if (!dynamic_symbol)
2650 count *= 2;
2651 break;
2652 case R_IA64_TPREL64LSB:
2653 case R_IA64_DTPREL64LSB:
2654 case R_IA64_DTPMOD64LSB:
2655 break;
2656 default:
2657 abort ();
2658 }
2659 rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * count;
2660 }
2661
2662 /* Take care of the GOT and PLT relocations. */
2663
2664 if (((dynamic_symbol || shared) && dyn_i->want_got)
2665 || (dyn_i->want_ltoff_fptr && dyn_i->h && dyn_i->h->dynindx != -1))
2666 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2667 if ((dynamic_symbol || shared) && dyn_i->want_tprel)
2668 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2669 if ((dynamic_symbol || shared) && dyn_i->want_dtpmod)
2670 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2671 if (dynamic_symbol && dyn_i->want_dtprel)
2672 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2673
2674 if (dyn_i->want_pltoff)
2675 {
2676 bfd_size_type t = 0;
2677
2678 /* Dynamic symbols get one IPLT relocation. Local symbols in
2679 shared libraries get two REL relocations. Local symbols in
2680 main applications get nothing. */
2681 if (dynamic_symbol)
2682 t = sizeof (ElfNN_External_Rela);
2683 else if (shared)
2684 t = 2 * sizeof (ElfNN_External_Rela);
2685
2686 ia64_info->rel_pltoff_sec->_raw_size += t;
2687 }
2688
2689 return true;
2690 }
2691
2692 static boolean
2693 elfNN_ia64_adjust_dynamic_symbol (info, h)
2694 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2695 struct elf_link_hash_entry *h;
2696 {
2697 /* ??? Undefined symbols with PLT entries should be re-defined
2698 to be the PLT entry. */
2699
2700 /* If this is a weak symbol, and there is a real definition, the
2701 processor independent code will have arranged for us to see the
2702 real definition first, and we can just use the same value. */
2703 if (h->weakdef != NULL)
2704 {
2705 BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
2706 || h->weakdef->root.type == bfd_link_hash_defweak);
2707 h->root.u.def.section = h->weakdef->root.u.def.section;
2708 h->root.u.def.value = h->weakdef->root.u.def.value;
2709 return true;
2710 }
2711
2712 /* If this is a reference to a symbol defined by a dynamic object which
2713 is not a function, we might allocate the symbol in our .dynbss section
2714 and allocate a COPY dynamic relocation.
2715
2716 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2717 of hackery. */
2718
2719 return true;
2720 }
2721
2722 static boolean
2723 elfNN_ia64_size_dynamic_sections (output_bfd, info)
2724 bfd *output_bfd;
2725 struct bfd_link_info *info;
2726 {
2727 struct elfNN_ia64_allocate_data data;
2728 struct elfNN_ia64_link_hash_table *ia64_info;
2729 asection *sec;
2730 bfd *dynobj;
2731 boolean relplt = false;
2732
2733 dynobj = elf_hash_table(info)->dynobj;
2734 ia64_info = elfNN_ia64_hash_table (info);
2735 BFD_ASSERT(dynobj != NULL);
2736 data.info = info;
2737
2738 /* Set the contents of the .interp section to the interpreter. */
2739 if (ia64_info->root.dynamic_sections_created
2740 && !info->shared)
2741 {
2742 sec = bfd_get_section_by_name (dynobj, ".interp");
2743 BFD_ASSERT (sec != NULL);
2744 sec->contents = (bfd_byte *) DYNAMIC_INTERPRETER (output_bfd);
2745 sec->_raw_size = strlen (DYNAMIC_INTERPRETER (output_bfd)) + 1;
2746 }
2747
2748 /* Allocate the GOT entries. */
2749
2750 if (ia64_info->got_sec)
2751 {
2752 data.ofs = 0;
2753 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
2754 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
2755 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
2756 ia64_info->got_sec->_raw_size = data.ofs;
2757 }
2758
2759 /* Allocate the FPTR entries. */
2760
2761 if (ia64_info->fptr_sec)
2762 {
2763 data.ofs = 0;
2764 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
2765 ia64_info->fptr_sec->_raw_size = data.ofs;
2766 }
2767
2768 /* Now that we've seen all of the input files, we can decide which
2769 symbols need plt entries. Allocate the minimal PLT entries first.
2770 We do this even though dynamic_sections_created may be false, because
2771 this has the side-effect of clearing want_plt and want_plt2. */
2772
2773 data.ofs = 0;
2774 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
2775
2776 ia64_info->minplt_entries = 0;
2777 if (data.ofs)
2778 {
2779 ia64_info->minplt_entries
2780 = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
2781 }
2782
2783 /* Align the pointer for the plt2 entries. */
2784 data.ofs = (data.ofs + 31) & (bfd_vma) -32;
2785
2786 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
2787 if (data.ofs != 0)
2788 {
2789 BFD_ASSERT (ia64_info->root.dynamic_sections_created);
2790
2791 ia64_info->plt_sec->_raw_size = data.ofs;
2792
2793 /* If we've got a .plt, we need some extra memory for the dynamic
2794 linker. We stuff these in .got.plt. */
2795 sec = bfd_get_section_by_name (dynobj, ".got.plt");
2796 sec->_raw_size = 8 * PLT_RESERVED_WORDS;
2797 }
2798
2799 /* Allocate the PLTOFF entries. */
2800
2801 if (ia64_info->pltoff_sec)
2802 {
2803 data.ofs = 0;
2804 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
2805 ia64_info->pltoff_sec->_raw_size = data.ofs;
2806 }
2807
2808 if (ia64_info->root.dynamic_sections_created)
2809 {
2810 /* Allocate space for the dynamic relocations that turned out to be
2811 required. */
2812
2813 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
2814 }
2815
2816 /* We have now determined the sizes of the various dynamic sections.
2817 Allocate memory for them. */
2818 for (sec = dynobj->sections; sec != NULL; sec = sec->next)
2819 {
2820 boolean strip;
2821
2822 if (!(sec->flags & SEC_LINKER_CREATED))
2823 continue;
2824
2825 /* If we don't need this section, strip it from the output file.
2826 There were several sections primarily related to dynamic
2827 linking that must be create before the linker maps input
2828 sections to output sections. The linker does that before
2829 bfd_elf_size_dynamic_sections is called, and it is that
2830 function which decides whether anything needs to go into
2831 these sections. */
2832
2833 strip = (sec->_raw_size == 0);
2834
2835 if (sec == ia64_info->got_sec)
2836 strip = false;
2837 else if (sec == ia64_info->rel_got_sec)
2838 {
2839 if (strip)
2840 ia64_info->rel_got_sec = NULL;
2841 else
2842 /* We use the reloc_count field as a counter if we need to
2843 copy relocs into the output file. */
2844 sec->reloc_count = 0;
2845 }
2846 else if (sec == ia64_info->fptr_sec)
2847 {
2848 if (strip)
2849 ia64_info->fptr_sec = NULL;
2850 }
2851 else if (sec == ia64_info->plt_sec)
2852 {
2853 if (strip)
2854 ia64_info->plt_sec = NULL;
2855 }
2856 else if (sec == ia64_info->pltoff_sec)
2857 {
2858 if (strip)
2859 ia64_info->pltoff_sec = NULL;
2860 }
2861 else if (sec == ia64_info->rel_pltoff_sec)
2862 {
2863 if (strip)
2864 ia64_info->rel_pltoff_sec = NULL;
2865 else
2866 {
2867 relplt = true;
2868 /* We use the reloc_count field as a counter if we need to
2869 copy relocs into the output file. */
2870 sec->reloc_count = 0;
2871 }
2872 }
2873 else
2874 {
2875 const char *name;
2876
2877 /* It's OK to base decisions on the section name, because none
2878 of the dynobj section names depend upon the input files. */
2879 name = bfd_get_section_name (dynobj, sec);
2880
2881 if (strcmp (name, ".got.plt") == 0)
2882 strip = false;
2883 else if (strncmp (name, ".rel", 4) == 0)
2884 {
2885 if (!strip)
2886 {
2887 /* We use the reloc_count field as a counter if we need to
2888 copy relocs into the output file. */
2889 sec->reloc_count = 0;
2890 }
2891 }
2892 else
2893 continue;
2894 }
2895
2896 if (strip)
2897 _bfd_strip_section_from_output (info, sec);
2898 else
2899 {
2900 /* Allocate memory for the section contents. */
2901 sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->_raw_size);
2902 if (sec->contents == NULL && sec->_raw_size != 0)
2903 return false;
2904 }
2905 }
2906
2907 if (elf_hash_table (info)->dynamic_sections_created)
2908 {
2909 /* Add some entries to the .dynamic section. We fill in the values
2910 later (in finish_dynamic_sections) but we must add the entries now
2911 so that we get the correct size for the .dynamic section. */
2912
2913 if (!info->shared)
2914 {
2915 /* The DT_DEBUG entry is filled in by the dynamic linker and used
2916 by the debugger. */
2917 #define add_dynamic_entry(TAG, VAL) \
2918 bfd_elfNN_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
2919
2920 if (!add_dynamic_entry (DT_DEBUG, 0))
2921 return false;
2922 }
2923
2924 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
2925 return false;
2926 if (!add_dynamic_entry (DT_PLTGOT, 0))
2927 return false;
2928
2929 if (relplt)
2930 {
2931 if (!add_dynamic_entry (DT_PLTRELSZ, 0)
2932 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
2933 || !add_dynamic_entry (DT_JMPREL, 0))
2934 return false;
2935 }
2936
2937 if (!add_dynamic_entry (DT_RELA, 0)
2938 || !add_dynamic_entry (DT_RELASZ, 0)
2939 || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
2940 return false;
2941
2942 if (ia64_info->reltext)
2943 {
2944 if (!add_dynamic_entry (DT_TEXTREL, 0))
2945 return false;
2946 info->flags |= DF_TEXTREL;
2947 }
2948 }
2949
2950 /* ??? Perhaps force __gp local. */
2951
2952 return true;
2953 }
2954
2955 static bfd_reloc_status_type
2956 elfNN_ia64_install_value (abfd, hit_addr, v, r_type)
2957 bfd *abfd;
2958 bfd_byte *hit_addr;
2959 bfd_vma v;
2960 unsigned int r_type;
2961 {
2962 const struct ia64_operand *op;
2963 int bigendian = 0, shift = 0;
2964 bfd_vma t0, t1, insn, dword;
2965 enum ia64_opnd opnd;
2966 const char *err;
2967 size_t size = 8;
2968 #ifdef BFD_HOST_U_64_BIT
2969 BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
2970 #else
2971 bfd_vma val = v;
2972 #endif
2973
2974 opnd = IA64_OPND_NIL;
2975 switch (r_type)
2976 {
2977 case R_IA64_NONE:
2978 case R_IA64_LDXMOV:
2979 return bfd_reloc_ok;
2980
2981 /* Instruction relocations. */
2982
2983 case R_IA64_IMM14:
2984 case R_IA64_TPREL14:
2985 case R_IA64_DTPREL14:
2986 opnd = IA64_OPND_IMM14;
2987 break;
2988
2989 case R_IA64_PCREL21F: opnd = IA64_OPND_TGT25; break;
2990 case R_IA64_PCREL21M: opnd = IA64_OPND_TGT25b; break;
2991 case R_IA64_PCREL60B: opnd = IA64_OPND_TGT64; break;
2992 case R_IA64_PCREL21B:
2993 case R_IA64_PCREL21BI:
2994 opnd = IA64_OPND_TGT25c;
2995 break;
2996
2997 case R_IA64_IMM22:
2998 case R_IA64_GPREL22:
2999 case R_IA64_LTOFF22:
3000 case R_IA64_LTOFF22X:
3001 case R_IA64_PLTOFF22:
3002 case R_IA64_PCREL22:
3003 case R_IA64_LTOFF_FPTR22:
3004 case R_IA64_TPREL22:
3005 case R_IA64_DTPREL22:
3006 case R_IA64_LTOFF_TPREL22:
3007 case R_IA64_LTOFF_DTPMOD22:
3008 case R_IA64_LTOFF_DTPREL22:
3009 opnd = IA64_OPND_IMM22;
3010 break;
3011
3012 case R_IA64_IMM64:
3013 case R_IA64_GPREL64I:
3014 case R_IA64_LTOFF64I:
3015 case R_IA64_PLTOFF64I:
3016 case R_IA64_PCREL64I:
3017 case R_IA64_FPTR64I:
3018 case R_IA64_LTOFF_FPTR64I:
3019 case R_IA64_TPREL64I:
3020 case R_IA64_DTPREL64I:
3021 opnd = IA64_OPND_IMMU64;
3022 break;
3023
3024 /* Data relocations. */
3025
3026 case R_IA64_DIR32MSB:
3027 case R_IA64_GPREL32MSB:
3028 case R_IA64_FPTR32MSB:
3029 case R_IA64_PCREL32MSB:
3030 case R_IA64_LTOFF_FPTR32MSB:
3031 case R_IA64_SEGREL32MSB:
3032 case R_IA64_SECREL32MSB:
3033 case R_IA64_LTV32MSB:
3034 case R_IA64_DTPREL32MSB:
3035 size = 4; bigendian = 1;
3036 break;
3037
3038 case R_IA64_DIR32LSB:
3039 case R_IA64_GPREL32LSB:
3040 case R_IA64_FPTR32LSB:
3041 case R_IA64_PCREL32LSB:
3042 case R_IA64_LTOFF_FPTR32LSB:
3043 case R_IA64_SEGREL32LSB:
3044 case R_IA64_SECREL32LSB:
3045 case R_IA64_LTV32LSB:
3046 case R_IA64_DTPREL32LSB:
3047 size = 4; bigendian = 0;
3048 break;
3049
3050 case R_IA64_DIR64MSB:
3051 case R_IA64_GPREL64MSB:
3052 case R_IA64_PLTOFF64MSB:
3053 case R_IA64_FPTR64MSB:
3054 case R_IA64_PCREL64MSB:
3055 case R_IA64_LTOFF_FPTR64MSB:
3056 case R_IA64_SEGREL64MSB:
3057 case R_IA64_SECREL64MSB:
3058 case R_IA64_LTV64MSB:
3059 case R_IA64_TPREL64MSB:
3060 case R_IA64_DTPMOD64MSB:
3061 case R_IA64_DTPREL64MSB:
3062 size = 8; bigendian = 1;
3063 break;
3064
3065 case R_IA64_DIR64LSB:
3066 case R_IA64_GPREL64LSB:
3067 case R_IA64_PLTOFF64LSB:
3068 case R_IA64_FPTR64LSB:
3069 case R_IA64_PCREL64LSB:
3070 case R_IA64_LTOFF_FPTR64LSB:
3071 case R_IA64_SEGREL64LSB:
3072 case R_IA64_SECREL64LSB:
3073 case R_IA64_LTV64LSB:
3074 case R_IA64_TPREL64LSB:
3075 case R_IA64_DTPMOD64LSB:
3076 case R_IA64_DTPREL64LSB:
3077 size = 8; bigendian = 0;
3078 break;
3079
3080 /* Unsupported / Dynamic relocations. */
3081 default:
3082 return bfd_reloc_notsupported;
3083 }
3084
3085 switch (opnd)
3086 {
3087 case IA64_OPND_IMMU64:
3088 hit_addr -= (long) hit_addr & 0x3;
3089 t0 = bfd_get_64 (abfd, hit_addr);
3090 t1 = bfd_get_64 (abfd, hit_addr + 8);
3091
3092 /* tmpl/s: bits 0.. 5 in t0
3093 slot 0: bits 5..45 in t0
3094 slot 1: bits 46..63 in t0, bits 0..22 in t1
3095 slot 2: bits 23..63 in t1 */
3096
3097 /* First, clear the bits that form the 64 bit constant. */
3098 t0 &= ~(0x3ffffLL << 46);
3099 t1 &= ~(0x7fffffLL
3100 | (( (0x07fLL << 13) | (0x1ffLL << 27)
3101 | (0x01fLL << 22) | (0x001LL << 21)
3102 | (0x001LL << 36)) << 23));
3103
3104 t0 |= ((val >> 22) & 0x03ffffLL) << 46; /* 18 lsbs of imm41 */
3105 t1 |= ((val >> 40) & 0x7fffffLL) << 0; /* 23 msbs of imm41 */
3106 t1 |= ( (((val >> 0) & 0x07f) << 13) /* imm7b */
3107 | (((val >> 7) & 0x1ff) << 27) /* imm9d */
3108 | (((val >> 16) & 0x01f) << 22) /* imm5c */
3109 | (((val >> 21) & 0x001) << 21) /* ic */
3110 | (((val >> 63) & 0x001) << 36)) << 23; /* i */
3111
3112 bfd_put_64 (abfd, t0, hit_addr);
3113 bfd_put_64 (abfd, t1, hit_addr + 8);
3114 break;
3115
3116 case IA64_OPND_TGT64:
3117 hit_addr -= (long) hit_addr & 0x3;
3118 t0 = bfd_get_64 (abfd, hit_addr);
3119 t1 = bfd_get_64 (abfd, hit_addr + 8);
3120
3121 /* tmpl/s: bits 0.. 5 in t0
3122 slot 0: bits 5..45 in t0
3123 slot 1: bits 46..63 in t0, bits 0..22 in t1
3124 slot 2: bits 23..63 in t1 */
3125
3126 /* First, clear the bits that form the 64 bit constant. */
3127 t0 &= ~(0x3ffffLL << 46);
3128 t1 &= ~(0x7fffffLL
3129 | ((1LL << 36 | 0xfffffLL << 13) << 23));
3130
3131 val >>= 4;
3132 t0 |= ((val >> 20) & 0xffffLL) << 2 << 46; /* 16 lsbs of imm39 */
3133 t1 |= ((val >> 36) & 0x7fffffLL) << 0; /* 23 msbs of imm39 */
3134 t1 |= ((((val >> 0) & 0xfffffLL) << 13) /* imm20b */
3135 | (((val >> 59) & 0x1LL) << 36)) << 23; /* i */
3136
3137 bfd_put_64 (abfd, t0, hit_addr);
3138 bfd_put_64 (abfd, t1, hit_addr + 8);
3139 break;
3140
3141 default:
3142 switch ((long) hit_addr & 0x3)
3143 {
3144 case 0: shift = 5; break;
3145 case 1: shift = 14; hit_addr += 3; break;
3146 case 2: shift = 23; hit_addr += 6; break;
3147 case 3: return bfd_reloc_notsupported; /* shouldn't happen... */
3148 }
3149 dword = bfd_get_64 (abfd, hit_addr);
3150 insn = (dword >> shift) & 0x1ffffffffffLL;
3151
3152 op = elf64_ia64_operands + opnd;
3153 err = (*op->insert) (op, val, (ia64_insn *)& insn);
3154 if (err)
3155 return bfd_reloc_overflow;
3156
3157 dword &= ~(0x1ffffffffffLL << shift);
3158 dword |= (insn << shift);
3159 bfd_put_64 (abfd, dword, hit_addr);
3160 break;
3161
3162 case IA64_OPND_NIL:
3163 /* A data relocation. */
3164 if (bigendian)
3165 if (size == 4)
3166 bfd_putb32 (val, hit_addr);
3167 else
3168 bfd_putb64 (val, hit_addr);
3169 else
3170 if (size == 4)
3171 bfd_putl32 (val, hit_addr);
3172 else
3173 bfd_putl64 (val, hit_addr);
3174 break;
3175 }
3176
3177 return bfd_reloc_ok;
3178 }
3179
3180 static void
3181 elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
3182 dynindx, addend)
3183 bfd *abfd;
3184 struct bfd_link_info *info;
3185 asection *sec;
3186 asection *srel;
3187 bfd_vma offset;
3188 unsigned int type;
3189 long dynindx;
3190 bfd_vma addend;
3191 {
3192 Elf_Internal_Rela outrel;
3193
3194 offset += sec->output_section->vma + sec->output_offset;
3195
3196 BFD_ASSERT (dynindx != -1);
3197 outrel.r_info = ELFNN_R_INFO (dynindx, type);
3198 outrel.r_addend = addend;
3199 outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
3200 if ((outrel.r_offset | 1) == (bfd_vma) -1)
3201 {
3202 /* Run for the hills. We shouldn't be outputting a relocation
3203 for this. So do what everyone else does and output a no-op. */
3204 outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
3205 outrel.r_addend = 0;
3206 outrel.r_offset = 0;
3207 }
3208
3209 bfd_elfNN_swap_reloca_out (abfd, &outrel,
3210 ((ElfNN_External_Rela *) srel->contents
3211 + srel->reloc_count++));
3212 BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count
3213 <= srel->_cooked_size);
3214 }
3215
3216 /* Store an entry for target address TARGET_ADDR in the linkage table
3217 and return the gp-relative address of the linkage table entry. */
3218
3219 static bfd_vma
3220 set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
3221 bfd *abfd;
3222 struct bfd_link_info *info;
3223 struct elfNN_ia64_dyn_sym_info *dyn_i;
3224 long dynindx;
3225 bfd_vma addend;
3226 bfd_vma value;
3227 unsigned int dyn_r_type;
3228 {
3229 struct elfNN_ia64_link_hash_table *ia64_info;
3230 asection *got_sec;
3231 boolean done;
3232 bfd_vma got_offset;
3233
3234 ia64_info = elfNN_ia64_hash_table (info);
3235 got_sec = ia64_info->got_sec;
3236
3237 switch (dyn_r_type)
3238 {
3239 case R_IA64_TPREL64LSB:
3240 done = dyn_i->tprel_done;
3241 dyn_i->tprel_done = true;
3242 got_offset = dyn_i->tprel_offset;
3243 break;
3244 case R_IA64_DTPMOD64LSB:
3245 done = dyn_i->dtpmod_done;
3246 dyn_i->dtpmod_done = true;
3247 got_offset = dyn_i->dtpmod_offset;
3248 break;
3249 case R_IA64_DTPREL64LSB:
3250 done = dyn_i->dtprel_done;
3251 dyn_i->dtprel_done = true;
3252 got_offset = dyn_i->dtprel_offset;
3253 break;
3254 default:
3255 done = dyn_i->got_done;
3256 dyn_i->got_done = true;
3257 got_offset = dyn_i->got_offset;
3258 break;
3259 }
3260
3261 BFD_ASSERT ((got_offset & 7) == 0);
3262
3263 if (! done)
3264 {
3265 /* Store the target address in the linkage table entry. */
3266 bfd_put_64 (abfd, value, got_sec->contents + got_offset);
3267
3268 /* Install a dynamic relocation if needed. */
3269 if ((info->shared && dyn_r_type != R_IA64_DTPREL64LSB)
3270 || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info)
3271 || elfNN_ia64_aix_vec (abfd->xvec)
3272 || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
3273 {
3274 if (dynindx == -1
3275 && dyn_r_type != R_IA64_TPREL64LSB
3276 && dyn_r_type != R_IA64_DTPMOD64LSB
3277 && dyn_r_type != R_IA64_DTPREL64LSB)
3278 {
3279 dyn_r_type = R_IA64_REL64LSB;
3280 dynindx = 0;
3281 addend = value;
3282 }
3283
3284 if (bfd_big_endian (abfd))
3285 {
3286 switch (dyn_r_type)
3287 {
3288 case R_IA64_REL64LSB:
3289 dyn_r_type = R_IA64_REL64MSB;
3290 break;
3291 case R_IA64_DIR64LSB:
3292 dyn_r_type = R_IA64_DIR64MSB;
3293 break;
3294 case R_IA64_FPTR64LSB:
3295 dyn_r_type = R_IA64_FPTR64MSB;
3296 break;
3297 case R_IA64_TPREL64LSB:
3298 dyn_r_type = R_IA64_TPREL64MSB;
3299 break;
3300 case R_IA64_DTPMOD64LSB:
3301 dyn_r_type = R_IA64_DTPMOD64MSB;
3302 break;
3303 case R_IA64_DTPREL64LSB:
3304 dyn_r_type = R_IA64_DTPREL64MSB;
3305 break;
3306 default:
3307 BFD_ASSERT (false);
3308 break;
3309 }
3310 }
3311
3312 elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
3313 ia64_info->rel_got_sec,
3314 got_offset, dyn_r_type,
3315 dynindx, addend);
3316 }
3317 }
3318
3319 /* Return the address of the linkage table entry. */
3320 value = (got_sec->output_section->vma
3321 + got_sec->output_offset
3322 + got_offset);
3323
3324 return value;
3325 }
3326
3327 /* Fill in a function descriptor consisting of the function's code
3328 address and its global pointer. Return the descriptor's address. */
3329
3330 static bfd_vma
3331 set_fptr_entry (abfd, info, dyn_i, value)
3332 bfd *abfd;
3333 struct bfd_link_info *info;
3334 struct elfNN_ia64_dyn_sym_info *dyn_i;
3335 bfd_vma value;
3336 {
3337 struct elfNN_ia64_link_hash_table *ia64_info;
3338 asection *fptr_sec;
3339
3340 ia64_info = elfNN_ia64_hash_table (info);
3341 fptr_sec = ia64_info->fptr_sec;
3342
3343 if (!dyn_i->fptr_done)
3344 {
3345 dyn_i->fptr_done = 1;
3346
3347 /* Fill in the function descriptor. */
3348 bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
3349 bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
3350 fptr_sec->contents + dyn_i->fptr_offset + 8);
3351 }
3352
3353 /* Return the descriptor's address. */
3354 value = (fptr_sec->output_section->vma
3355 + fptr_sec->output_offset
3356 + dyn_i->fptr_offset);
3357
3358 return value;
3359 }
3360
3361 /* Fill in a PLTOFF entry consisting of the function's code address
3362 and its global pointer. Return the descriptor's address. */
3363
3364 static bfd_vma
3365 set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
3366 bfd *abfd;
3367 struct bfd_link_info *info;
3368 struct elfNN_ia64_dyn_sym_info *dyn_i;
3369 bfd_vma value;
3370 boolean is_plt;
3371 {
3372 struct elfNN_ia64_link_hash_table *ia64_info;
3373 asection *pltoff_sec;
3374
3375 ia64_info = elfNN_ia64_hash_table (info);
3376 pltoff_sec = ia64_info->pltoff_sec;
3377
3378 /* Don't do anything if this symbol uses a real PLT entry. In
3379 that case, we'll fill this in during finish_dynamic_symbol. */
3380 if ((! dyn_i->want_plt || is_plt)
3381 && !dyn_i->pltoff_done)
3382 {
3383 bfd_vma gp = _bfd_get_gp_value (abfd);
3384
3385 /* Fill in the function descriptor. */
3386 bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
3387 bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
3388
3389 /* Install dynamic relocations if needed. */
3390 if (!is_plt && info->shared)
3391 {
3392 unsigned int dyn_r_type;
3393
3394 if (bfd_big_endian (abfd))
3395 dyn_r_type = R_IA64_REL64MSB;
3396 else
3397 dyn_r_type = R_IA64_REL64LSB;
3398
3399 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3400 ia64_info->rel_pltoff_sec,
3401 dyn_i->pltoff_offset,
3402 dyn_r_type, 0, value);
3403 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3404 ia64_info->rel_pltoff_sec,
3405 dyn_i->pltoff_offset + 8,
3406 dyn_r_type, 0, gp);
3407 }
3408
3409 dyn_i->pltoff_done = 1;
3410 }
3411
3412 /* Return the descriptor's address. */
3413 value = (pltoff_sec->output_section->vma
3414 + pltoff_sec->output_offset
3415 + dyn_i->pltoff_offset);
3416
3417 return value;
3418 }
3419
3420 /* Return the base VMA address which should be subtracted from real addresses
3421 when resolving @tprel() relocation.
3422 Main program TLS (whose template starts at PT_TLS p_vaddr)
3423 is assigned offset round(16, PT_TLS p_align). */
3424
3425 static bfd_vma
3426 elfNN_ia64_tprel_base (info)
3427 struct bfd_link_info *info;
3428 {
3429 struct elf_link_tls_segment *tls_segment
3430 = elf_hash_table (info)->tls_segment;
3431
3432 BFD_ASSERT (tls_segment != NULL);
3433 return (tls_segment->start
3434 - align_power ((bfd_vma) 16, tls_segment->align));
3435 }
3436
3437 /* Return the base VMA address which should be subtracted from real addresses
3438 when resolving @dtprel() relocation.
3439 This is PT_TLS segment p_vaddr. */
3440
3441 static bfd_vma
3442 elfNN_ia64_dtprel_base (info)
3443 struct bfd_link_info *info;
3444 {
3445 BFD_ASSERT (elf_hash_table (info)->tls_segment != NULL);
3446 return elf_hash_table (info)->tls_segment->start;
3447 }
3448
3449 /* Called through qsort to sort the .IA_64.unwind section during a
3450 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3451 to the output bfd so we can do proper endianness frobbing. */
3452
3453 static bfd *elfNN_ia64_unwind_entry_compare_bfd;
3454
3455 static int
3456 elfNN_ia64_unwind_entry_compare (a, b)
3457 const PTR a;
3458 const PTR b;
3459 {
3460 bfd_vma av, bv;
3461
3462 av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
3463 bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
3464
3465 return (av < bv ? -1 : av > bv ? 1 : 0);
3466 }
3467
3468 static boolean
3469 elfNN_ia64_final_link (abfd, info)
3470 bfd *abfd;
3471 struct bfd_link_info *info;
3472 {
3473 struct elfNN_ia64_link_hash_table *ia64_info;
3474 asection *unwind_output_sec;
3475
3476 ia64_info = elfNN_ia64_hash_table (info);
3477
3478 /* Make sure we've got ourselves a nice fat __gp value. */
3479 if (!info->relocateable)
3480 {
3481 bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
3482 bfd_vma min_short_vma = min_vma, max_short_vma = 0;
3483 struct elf_link_hash_entry *gp;
3484 bfd_vma gp_val;
3485 asection *os;
3486
3487 /* Find the min and max vma of all sections marked short. Also
3488 collect min and max vma of any type, for use in selecting a
3489 nice gp. */
3490 for (os = abfd->sections; os ; os = os->next)
3491 {
3492 bfd_vma lo, hi;
3493
3494 if ((os->flags & SEC_ALLOC) == 0)
3495 continue;
3496
3497 lo = os->vma;
3498 hi = os->vma + os->_raw_size;
3499 if (hi < lo)
3500 hi = (bfd_vma) -1;
3501
3502 if (min_vma > lo)
3503 min_vma = lo;
3504 if (max_vma < hi)
3505 max_vma = hi;
3506 if (os->flags & SEC_SMALL_DATA)
3507 {
3508 if (min_short_vma > lo)
3509 min_short_vma = lo;
3510 if (max_short_vma < hi)
3511 max_short_vma = hi;
3512 }
3513 }
3514
3515 /* See if the user wants to force a value. */
3516 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", false,
3517 false, false);
3518
3519 if (gp
3520 && (gp->root.type == bfd_link_hash_defined
3521 || gp->root.type == bfd_link_hash_defweak))
3522 {
3523 asection *gp_sec = gp->root.u.def.section;
3524 gp_val = (gp->root.u.def.value
3525 + gp_sec->output_section->vma
3526 + gp_sec->output_offset);
3527 }
3528 else
3529 {
3530 /* Pick a sensible value. */
3531
3532 asection *got_sec = ia64_info->got_sec;
3533
3534 /* Start with just the address of the .got. */
3535 if (got_sec)
3536 gp_val = got_sec->output_section->vma;
3537 else if (max_short_vma != 0)
3538 gp_val = min_short_vma;
3539 else
3540 gp_val = min_vma;
3541
3542 /* If it is possible to address the entire image, but we
3543 don't with the choice above, adjust. */
3544 if (max_vma - min_vma < 0x400000
3545 && max_vma - gp_val <= 0x200000
3546 && gp_val - min_vma > 0x200000)
3547 gp_val = min_vma + 0x200000;
3548 else if (max_short_vma != 0)
3549 {
3550 /* If we don't cover all the short data, adjust. */
3551 if (max_short_vma - gp_val >= 0x200000)
3552 gp_val = min_short_vma + 0x200000;
3553
3554 /* If we're addressing stuff past the end, adjust back. */
3555 if (gp_val > max_vma)
3556 gp_val = max_vma - 0x200000 + 8;
3557 }
3558 }
3559
3560 /* Validate whether all SHF_IA_64_SHORT sections are within
3561 range of the chosen GP. */
3562
3563 if (max_short_vma != 0)
3564 {
3565 if (max_short_vma - min_short_vma >= 0x400000)
3566 {
3567 (*_bfd_error_handler)
3568 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3569 bfd_get_filename (abfd),
3570 (unsigned long) (max_short_vma - min_short_vma));
3571 return false;
3572 }
3573 else if ((gp_val > min_short_vma
3574 && gp_val - min_short_vma > 0x200000)
3575 || (gp_val < max_short_vma
3576 && max_short_vma - gp_val >= 0x200000))
3577 {
3578 (*_bfd_error_handler)
3579 (_("%s: __gp does not cover short data segment"),
3580 bfd_get_filename (abfd));
3581 return false;
3582 }
3583 }
3584
3585 _bfd_set_gp_value (abfd, gp_val);
3586
3587 if (gp)
3588 {
3589 gp->root.type = bfd_link_hash_defined;
3590 gp->root.u.def.value = gp_val;
3591 gp->root.u.def.section = bfd_abs_section_ptr;
3592 }
3593 }
3594
3595 /* If we're producing a final executable, we need to sort the contents
3596 of the .IA_64.unwind section. Force this section to be relocated
3597 into memory rather than written immediately to the output file. */
3598 unwind_output_sec = NULL;
3599 if (!info->relocateable)
3600 {
3601 asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3602 if (s)
3603 {
3604 unwind_output_sec = s->output_section;
3605 unwind_output_sec->contents
3606 = bfd_malloc (unwind_output_sec->_raw_size);
3607 if (unwind_output_sec->contents == NULL)
3608 return false;
3609 }
3610 }
3611
3612 /* Invoke the regular ELF backend linker to do all the work. */
3613 if (!bfd_elfNN_bfd_final_link (abfd, info))
3614 return false;
3615
3616 if (unwind_output_sec)
3617 {
3618 elfNN_ia64_unwind_entry_compare_bfd = abfd;
3619 qsort (unwind_output_sec->contents,
3620 (size_t) (unwind_output_sec->_raw_size / 24),
3621 24,
3622 elfNN_ia64_unwind_entry_compare);
3623
3624 if (! bfd_set_section_contents (abfd, unwind_output_sec,
3625 unwind_output_sec->contents, (bfd_vma) 0,
3626 unwind_output_sec->_raw_size))
3627 return false;
3628 }
3629
3630 return true;
3631 }
3632
3633 static boolean
3634 elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
3635 contents, relocs, local_syms, local_sections)
3636 bfd *output_bfd;
3637 struct bfd_link_info *info;
3638 bfd *input_bfd;
3639 asection *input_section;
3640 bfd_byte *contents;
3641 Elf_Internal_Rela *relocs;
3642 Elf_Internal_Sym *local_syms;
3643 asection **local_sections;
3644 {
3645 struct elfNN_ia64_link_hash_table *ia64_info;
3646 Elf_Internal_Shdr *symtab_hdr;
3647 Elf_Internal_Rela *rel;
3648 Elf_Internal_Rela *relend;
3649 asection *srel;
3650 boolean ret_val = true; /* for non-fatal errors */
3651 bfd_vma gp_val;
3652
3653 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3654 ia64_info = elfNN_ia64_hash_table (info);
3655
3656 /* Infect various flags from the input section to the output section. */
3657 if (info->relocateable)
3658 {
3659 bfd_vma flags;
3660
3661 flags = elf_section_data(input_section)->this_hdr.sh_flags;
3662 flags &= SHF_IA_64_NORECOV;
3663
3664 elf_section_data(input_section->output_section)
3665 ->this_hdr.sh_flags |= flags;
3666 return true;
3667 }
3668
3669 gp_val = _bfd_get_gp_value (output_bfd);
3670 srel = get_reloc_section (input_bfd, ia64_info, input_section, false);
3671
3672 rel = relocs;
3673 relend = relocs + input_section->reloc_count;
3674 for (; rel < relend; ++rel)
3675 {
3676 struct elf_link_hash_entry *h;
3677 struct elfNN_ia64_dyn_sym_info *dyn_i;
3678 bfd_reloc_status_type r;
3679 reloc_howto_type *howto;
3680 unsigned long r_symndx;
3681 Elf_Internal_Sym *sym;
3682 unsigned int r_type;
3683 bfd_vma value;
3684 asection *sym_sec;
3685 bfd_byte *hit_addr;
3686 boolean dynamic_symbol_p;
3687 boolean undef_weak_ref;
3688
3689 r_type = ELFNN_R_TYPE (rel->r_info);
3690 if (r_type > R_IA64_MAX_RELOC_CODE)
3691 {
3692 (*_bfd_error_handler)
3693 (_("%s: unknown relocation type %d"),
3694 bfd_archive_filename (input_bfd), (int)r_type);
3695 bfd_set_error (bfd_error_bad_value);
3696 ret_val = false;
3697 continue;
3698 }
3699
3700 howto = lookup_howto (r_type);
3701 r_symndx = ELFNN_R_SYM (rel->r_info);
3702 h = NULL;
3703 sym = NULL;
3704 sym_sec = NULL;
3705 undef_weak_ref = false;
3706
3707 if (r_symndx < symtab_hdr->sh_info)
3708 {
3709 /* Reloc against local symbol. */
3710 sym = local_syms + r_symndx;
3711 sym_sec = local_sections[r_symndx];
3712 value = _bfd_elf_rela_local_sym (output_bfd, sym, sym_sec, rel);
3713 if ((sym_sec->flags & SEC_MERGE)
3714 && ELF_ST_TYPE (sym->st_info) == STT_SECTION
3715 && (elf_section_data (sym_sec)->sec_info_type
3716 == ELF_INFO_TYPE_MERGE))
3717 {
3718 struct elfNN_ia64_local_hash_entry *loc_h;
3719
3720 loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, false);
3721 if (loc_h && ! loc_h->sec_merge_done)
3722 {
3723 struct elfNN_ia64_dyn_sym_info *dynent;
3724 asection *msec;
3725
3726 for (dynent = loc_h->info; dynent; dynent = dynent->next)
3727 {
3728 msec = sym_sec;
3729 dynent->addend =
3730 _bfd_merged_section_offset (output_bfd, &msec,
3731 elf_section_data (msec)->
3732 sec_info,
3733 sym->st_value
3734 + dynent->addend,
3735 (bfd_vma) 0);
3736 dynent->addend -= sym->st_value;
3737 dynent->addend += msec->output_section->vma
3738 + msec->output_offset
3739 - sym_sec->output_section->vma
3740 - sym_sec->output_offset;
3741 }
3742 loc_h->sec_merge_done = 1;
3743 }
3744 }
3745 }
3746 else
3747 {
3748 long indx;
3749
3750 /* Reloc against global symbol. */
3751 indx = r_symndx - symtab_hdr->sh_info;
3752 h = elf_sym_hashes (input_bfd)[indx];
3753 while (h->root.type == bfd_link_hash_indirect
3754 || h->root.type == bfd_link_hash_warning)
3755 h = (struct elf_link_hash_entry *) h->root.u.i.link;
3756
3757 value = 0;
3758 if (h->root.type == bfd_link_hash_defined
3759 || h->root.type == bfd_link_hash_defweak)
3760 {
3761 sym_sec = h->root.u.def.section;
3762
3763 /* Detect the cases that sym_sec->output_section is
3764 expected to be NULL -- all cases in which the symbol
3765 is defined in another shared module. This includes
3766 PLT relocs for which we've created a PLT entry and
3767 other relocs for which we're prepared to create
3768 dynamic relocations. */
3769 /* ??? Just accept it NULL and continue. */
3770
3771 if (sym_sec->output_section != NULL)
3772 {
3773 value = (h->root.u.def.value
3774 + sym_sec->output_section->vma
3775 + sym_sec->output_offset);
3776 }
3777 }
3778 else if (h->root.type == bfd_link_hash_undefweak)
3779 undef_weak_ref = true;
3780 else if (info->shared
3781 && (!info->symbolic || info->allow_shlib_undefined)
3782 && !info->no_undefined
3783 && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
3784 ;
3785 else
3786 {
3787 if (! ((*info->callbacks->undefined_symbol)
3788 (info, h->root.root.string, input_bfd,
3789 input_section, rel->r_offset,
3790 (!info->shared || info->no_undefined
3791 || ELF_ST_VISIBILITY (h->other)))))
3792 return false;
3793 ret_val = false;
3794 continue;
3795 }
3796 }
3797
3798 hit_addr = contents + rel->r_offset;
3799 value += rel->r_addend;
3800 dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info);
3801
3802 switch (r_type)
3803 {
3804 case R_IA64_NONE:
3805 case R_IA64_LDXMOV:
3806 continue;
3807
3808 case R_IA64_IMM14:
3809 case R_IA64_IMM22:
3810 case R_IA64_IMM64:
3811 case R_IA64_DIR32MSB:
3812 case R_IA64_DIR32LSB:
3813 case R_IA64_DIR64MSB:
3814 case R_IA64_DIR64LSB:
3815 /* Install a dynamic relocation for this reloc. */
3816 if ((dynamic_symbol_p || info->shared
3817 || (elfNN_ia64_aix_vec (info->hash->creator)
3818 /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
3819 && (!h || strcmp (h->root.root.string,
3820 "__GLOB_DATA_PTR") != 0)))
3821 && r_symndx != 0
3822 && (input_section->flags & SEC_ALLOC) != 0)
3823 {
3824 unsigned int dyn_r_type;
3825 long dynindx;
3826 bfd_vma addend;
3827
3828 BFD_ASSERT (srel != NULL);
3829
3830 /* If we don't need dynamic symbol lookup, find a
3831 matching RELATIVE relocation. */
3832 dyn_r_type = r_type;
3833 if (dynamic_symbol_p)
3834 {
3835 dynindx = h->dynindx;
3836 addend = rel->r_addend;
3837 value = 0;
3838 }
3839 else
3840 {
3841 switch (r_type)
3842 {
3843 case R_IA64_DIR32MSB:
3844 dyn_r_type = R_IA64_REL32MSB;
3845 break;
3846 case R_IA64_DIR32LSB:
3847 dyn_r_type = R_IA64_REL32LSB;
3848 break;
3849 case R_IA64_DIR64MSB:
3850 dyn_r_type = R_IA64_REL64MSB;
3851 break;
3852 case R_IA64_DIR64LSB:
3853 dyn_r_type = R_IA64_REL64LSB;
3854 break;
3855
3856 default:
3857 /* We can't represent this without a dynamic symbol.
3858 Adjust the relocation to be against an output
3859 section symbol, which are always present in the
3860 dynamic symbol table. */
3861 /* ??? People shouldn't be doing non-pic code in
3862 shared libraries. Hork. */
3863 (*_bfd_error_handler)
3864 (_("%s: linking non-pic code in a shared library"),
3865 bfd_archive_filename (input_bfd));
3866 ret_val = false;
3867 continue;
3868 }
3869 dynindx = 0;
3870 addend = value;
3871 }
3872
3873 if (elfNN_ia64_aix_vec (info->hash->creator))
3874 rel->r_addend = value;
3875 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3876 srel, rel->r_offset, dyn_r_type,
3877 dynindx, addend);
3878 }
3879 /* FALLTHRU */
3880
3881 case R_IA64_LTV32MSB:
3882 case R_IA64_LTV32LSB:
3883 case R_IA64_LTV64MSB:
3884 case R_IA64_LTV64LSB:
3885 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3886 break;
3887
3888 case R_IA64_GPREL22:
3889 case R_IA64_GPREL64I:
3890 case R_IA64_GPREL32MSB:
3891 case R_IA64_GPREL32LSB:
3892 case R_IA64_GPREL64MSB:
3893 case R_IA64_GPREL64LSB:
3894 if (dynamic_symbol_p)
3895 {
3896 (*_bfd_error_handler)
3897 (_("%s: @gprel relocation against dynamic symbol %s"),
3898 bfd_archive_filename (input_bfd), h->root.root.string);
3899 ret_val = false;
3900 continue;
3901 }
3902 value -= gp_val;
3903 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3904 break;
3905
3906 case R_IA64_LTOFF22:
3907 case R_IA64_LTOFF22X:
3908 case R_IA64_LTOFF64I:
3909 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3910 value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
3911 rel->r_addend, value, R_IA64_DIR64LSB);
3912 value -= gp_val;
3913 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3914 break;
3915
3916 case R_IA64_PLTOFF22:
3917 case R_IA64_PLTOFF64I:
3918 case R_IA64_PLTOFF64MSB:
3919 case R_IA64_PLTOFF64LSB:
3920 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3921 value = set_pltoff_entry (output_bfd, info, dyn_i, value, false);
3922 value -= gp_val;
3923 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3924 break;
3925
3926 case R_IA64_FPTR64I:
3927 case R_IA64_FPTR32MSB:
3928 case R_IA64_FPTR32LSB:
3929 case R_IA64_FPTR64MSB:
3930 case R_IA64_FPTR64LSB:
3931 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3932 if (dyn_i->want_fptr)
3933 {
3934 if (!undef_weak_ref)
3935 value = set_fptr_entry (output_bfd, info, dyn_i, value);
3936 }
3937 else
3938 {
3939 long dynindx;
3940
3941 /* Otherwise, we expect the dynamic linker to create
3942 the entry. */
3943
3944 if (h)
3945 {
3946 if (h->dynindx != -1)
3947 dynindx = h->dynindx;
3948 else
3949 dynindx = (_bfd_elf_link_lookup_local_dynindx
3950 (info, h->root.u.def.section->owner,
3951 global_sym_index (h)));
3952 }
3953 else
3954 {
3955 dynindx = (_bfd_elf_link_lookup_local_dynindx
3956 (info, input_bfd, (long) r_symndx));
3957 }
3958
3959 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
3960 srel, rel->r_offset, r_type,
3961 dynindx, rel->r_addend);
3962 value = 0;
3963 }
3964
3965 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
3966 break;
3967
3968 case R_IA64_LTOFF_FPTR22:
3969 case R_IA64_LTOFF_FPTR64I:
3970 case R_IA64_LTOFF_FPTR32MSB:
3971 case R_IA64_LTOFF_FPTR32LSB:
3972 case R_IA64_LTOFF_FPTR64MSB:
3973 case R_IA64_LTOFF_FPTR64LSB:
3974 {
3975 long dynindx;
3976
3977 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
3978 if (dyn_i->want_fptr)
3979 {
3980 BFD_ASSERT (h == NULL || h->dynindx == -1)
3981 if (!undef_weak_ref)
3982 value = set_fptr_entry (output_bfd, info, dyn_i, value);
3983 dynindx = -1;
3984 }
3985 else
3986 {
3987 /* Otherwise, we expect the dynamic linker to create
3988 the entry. */
3989 if (h)
3990 {
3991 if (h->dynindx != -1)
3992 dynindx = h->dynindx;
3993 else
3994 dynindx = (_bfd_elf_link_lookup_local_dynindx
3995 (info, h->root.u.def.section->owner,
3996 global_sym_index (h)));
3997 }
3998 else
3999 dynindx = (_bfd_elf_link_lookup_local_dynindx
4000 (info, input_bfd, (long) r_symndx));
4001 value = 0;
4002 }
4003
4004 value = set_got_entry (output_bfd, info, dyn_i, dynindx,
4005 rel->r_addend, value, R_IA64_FPTR64LSB);
4006 value -= gp_val;
4007 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4008 }
4009 break;
4010
4011 case R_IA64_PCREL32MSB:
4012 case R_IA64_PCREL32LSB:
4013 case R_IA64_PCREL64MSB:
4014 case R_IA64_PCREL64LSB:
4015 /* Install a dynamic relocation for this reloc. */
4016 if ((dynamic_symbol_p
4017 || elfNN_ia64_aix_vec (info->hash->creator))
4018 && r_symndx != 0)
4019 {
4020 BFD_ASSERT (srel != NULL);
4021
4022 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4023 srel, rel->r_offset, r_type,
4024 h->dynindx, rel->r_addend);
4025 }
4026 goto finish_pcrel;
4027
4028 case R_IA64_PCREL21BI:
4029 case R_IA64_PCREL21F:
4030 case R_IA64_PCREL21M:
4031 /* ??? These two are only used for speculation fixup code.
4032 They should never be dynamic. */
4033 if (dynamic_symbol_p)
4034 {
4035 (*_bfd_error_handler)
4036 (_("%s: dynamic relocation against speculation fixup"),
4037 bfd_archive_filename (input_bfd));
4038 ret_val = false;
4039 continue;
4040 }
4041 if (undef_weak_ref)
4042 {
4043 (*_bfd_error_handler)
4044 (_("%s: speculation fixup against undefined weak symbol"),
4045 bfd_archive_filename (input_bfd));
4046 ret_val = false;
4047 continue;
4048 }
4049 goto finish_pcrel;
4050
4051 case R_IA64_PCREL21B:
4052 case R_IA64_PCREL60B:
4053 /* We should have created a PLT entry for any dynamic symbol. */
4054 dyn_i = NULL;
4055 if (h)
4056 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
4057
4058 if (dyn_i && dyn_i->want_plt2)
4059 {
4060 /* Should have caught this earlier. */
4061 BFD_ASSERT (rel->r_addend == 0);
4062
4063 value = (ia64_info->plt_sec->output_section->vma
4064 + ia64_info->plt_sec->output_offset
4065 + dyn_i->plt2_offset);
4066 }
4067 else
4068 {
4069 /* Since there's no PLT entry, Validate that this is
4070 locally defined. */
4071 BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
4072
4073 /* If the symbol is undef_weak, we shouldn't be trying
4074 to call it. There's every chance that we'd wind up
4075 with an out-of-range fixup here. Don't bother setting
4076 any value at all. */
4077 if (undef_weak_ref)
4078 continue;
4079 }
4080 goto finish_pcrel;
4081
4082 case R_IA64_PCREL22:
4083 case R_IA64_PCREL64I:
4084 finish_pcrel:
4085 /* Make pc-relative. */
4086 value -= (input_section->output_section->vma
4087 + input_section->output_offset
4088 + rel->r_offset) & ~ (bfd_vma) 0x3;
4089 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4090 break;
4091
4092 case R_IA64_SEGREL32MSB:
4093 case R_IA64_SEGREL32LSB:
4094 case R_IA64_SEGREL64MSB:
4095 case R_IA64_SEGREL64LSB:
4096 if (r_symndx == 0)
4097 {
4098 /* If the input section was discarded from the output, then
4099 do nothing. */
4100 r = bfd_reloc_ok;
4101 }
4102 else
4103 {
4104 struct elf_segment_map *m;
4105 Elf_Internal_Phdr *p;
4106
4107 /* Find the segment that contains the output_section. */
4108 for (m = elf_tdata (output_bfd)->segment_map,
4109 p = elf_tdata (output_bfd)->phdr;
4110 m != NULL;
4111 m = m->next, p++)
4112 {
4113 int i;
4114 for (i = m->count - 1; i >= 0; i--)
4115 if (m->sections[i] == sym_sec->output_section)
4116 break;
4117 if (i >= 0)
4118 break;
4119 }
4120
4121 if (m == NULL)
4122 {
4123 r = bfd_reloc_notsupported;
4124 }
4125 else
4126 {
4127 /* The VMA of the segment is the vaddr of the associated
4128 program header. */
4129 if (value > p->p_vaddr)
4130 value -= p->p_vaddr;
4131 else
4132 value = 0;
4133 r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
4134 r_type);
4135 }
4136 break;
4137 }
4138
4139 case R_IA64_SECREL32MSB:
4140 case R_IA64_SECREL32LSB:
4141 case R_IA64_SECREL64MSB:
4142 case R_IA64_SECREL64LSB:
4143 /* Make output-section relative. */
4144 if (value > input_section->output_section->vma)
4145 value -= input_section->output_section->vma;
4146 else
4147 value = 0;
4148 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4149 break;
4150
4151 case R_IA64_IPLTMSB:
4152 case R_IA64_IPLTLSB:
4153 /* Install a dynamic relocation for this reloc. */
4154 if ((dynamic_symbol_p || info->shared)
4155 && (input_section->flags & SEC_ALLOC) != 0)
4156 {
4157 BFD_ASSERT (srel != NULL);
4158
4159 /* If we don't need dynamic symbol lookup, install two
4160 RELATIVE relocations. */
4161 if (! dynamic_symbol_p)
4162 {
4163 unsigned int dyn_r_type;
4164
4165 if (r_type == R_IA64_IPLTMSB)
4166 dyn_r_type = R_IA64_REL64MSB;
4167 else
4168 dyn_r_type = R_IA64_REL64LSB;
4169
4170 elfNN_ia64_install_dyn_reloc (output_bfd, info,
4171 input_section,
4172 srel, rel->r_offset,
4173 dyn_r_type, 0, value);
4174 elfNN_ia64_install_dyn_reloc (output_bfd, info,
4175 input_section,
4176 srel, rel->r_offset + 8,
4177 dyn_r_type, 0, gp_val);
4178 }
4179 else
4180 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4181 srel, rel->r_offset, r_type,
4182 h->dynindx, rel->r_addend);
4183 }
4184
4185 if (r_type == R_IA64_IPLTMSB)
4186 r_type = R_IA64_DIR64MSB;
4187 else
4188 r_type = R_IA64_DIR64LSB;
4189 elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4190 r = elfNN_ia64_install_value (output_bfd, hit_addr + 8, gp_val,
4191 r_type);
4192 break;
4193
4194 case R_IA64_TPREL14:
4195 case R_IA64_TPREL22:
4196 case R_IA64_TPREL64I:
4197 value -= elfNN_ia64_tprel_base (info);
4198 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4199 break;
4200
4201 case R_IA64_DTPREL14:
4202 case R_IA64_DTPREL22:
4203 case R_IA64_DTPREL64I:
4204 value -= elfNN_ia64_dtprel_base (info);
4205 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4206 break;
4207
4208 case R_IA64_LTOFF_TPREL22:
4209 case R_IA64_LTOFF_DTPMOD22:
4210 case R_IA64_LTOFF_DTPREL22:
4211 {
4212 int got_r_type;
4213
4214 switch (r_type)
4215 {
4216 default:
4217 case R_IA64_LTOFF_TPREL22:
4218 if (!dynamic_symbol_p && !info->shared)
4219 value -= elfNN_ia64_tprel_base (info);
4220 got_r_type = R_IA64_TPREL64LSB;
4221 break;
4222 case R_IA64_LTOFF_DTPMOD22:
4223 if (!dynamic_symbol_p && !info->shared)
4224 value = 1;
4225 got_r_type = R_IA64_DTPMOD64LSB;
4226 break;
4227 case R_IA64_LTOFF_DTPREL22:
4228 if (!dynamic_symbol_p)
4229 value -= elfNN_ia64_dtprel_base (info);
4230 got_r_type = R_IA64_DTPREL64LSB;
4231 break;
4232 }
4233 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
4234 value = set_got_entry (input_bfd, info, dyn_i,
4235 (h ? h->dynindx : -1), rel->r_addend,
4236 value, got_r_type);
4237 value -= gp_val;
4238 r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
4239 r_type);
4240 }
4241 break;
4242
4243 default:
4244 r = bfd_reloc_notsupported;
4245 break;
4246 }
4247
4248 switch (r)
4249 {
4250 case bfd_reloc_ok:
4251 break;
4252
4253 case bfd_reloc_undefined:
4254 /* This can happen for global table relative relocs if
4255 __gp is undefined. This is a panic situation so we
4256 don't try to continue. */
4257 (*info->callbacks->undefined_symbol)
4258 (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
4259 return false;
4260
4261 case bfd_reloc_notsupported:
4262 {
4263 const char *name;
4264
4265 if (h)
4266 name = h->root.root.string;
4267 else
4268 {
4269 name = bfd_elf_string_from_elf_section (input_bfd,
4270 symtab_hdr->sh_link,
4271 sym->st_name);
4272 if (name == NULL)
4273 return false;
4274 if (*name == '\0')
4275 name = bfd_section_name (input_bfd, input_section);
4276 }
4277 if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
4278 name, input_bfd,
4279 input_section, rel->r_offset))
4280 return false;
4281 ret_val = false;
4282 }
4283 break;
4284
4285 case bfd_reloc_dangerous:
4286 case bfd_reloc_outofrange:
4287 case bfd_reloc_overflow:
4288 default:
4289 {
4290 const char *name;
4291
4292 if (h)
4293 name = h->root.root.string;
4294 else
4295 {
4296 name = bfd_elf_string_from_elf_section (input_bfd,
4297 symtab_hdr->sh_link,
4298 sym->st_name);
4299 if (name == NULL)
4300 return false;
4301 if (*name == '\0')
4302 name = bfd_section_name (input_bfd, input_section);
4303 }
4304 if (!(*info->callbacks->reloc_overflow) (info, name,
4305 howto->name,
4306 (bfd_vma) 0,
4307 input_bfd,
4308 input_section,
4309 rel->r_offset))
4310 return false;
4311 ret_val = false;
4312 }
4313 break;
4314 }
4315 }
4316
4317 return ret_val;
4318 }
4319
4320 static boolean
4321 elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
4322 bfd *output_bfd;
4323 struct bfd_link_info *info;
4324 struct elf_link_hash_entry *h;
4325 Elf_Internal_Sym *sym;
4326 {
4327 struct elfNN_ia64_link_hash_table *ia64_info;
4328 struct elfNN_ia64_dyn_sym_info *dyn_i;
4329
4330 ia64_info = elfNN_ia64_hash_table (info);
4331 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
4332
4333 /* Fill in the PLT data, if required. */
4334 if (dyn_i && dyn_i->want_plt)
4335 {
4336 Elf_Internal_Rela outrel;
4337 bfd_byte *loc;
4338 asection *plt_sec;
4339 bfd_vma plt_addr, pltoff_addr, gp_val, index;
4340 ElfNN_External_Rela *rel;
4341
4342 gp_val = _bfd_get_gp_value (output_bfd);
4343
4344 /* Initialize the minimal PLT entry. */
4345
4346 index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
4347 plt_sec = ia64_info->plt_sec;
4348 loc = plt_sec->contents + dyn_i->plt_offset;
4349
4350 memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
4351 elfNN_ia64_install_value (output_bfd, loc, index, R_IA64_IMM22);
4352 elfNN_ia64_install_value (output_bfd, loc+2, -dyn_i->plt_offset,
4353 R_IA64_PCREL21B);
4354
4355 plt_addr = (plt_sec->output_section->vma
4356 + plt_sec->output_offset
4357 + dyn_i->plt_offset);
4358 pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, true);
4359
4360 /* Initialize the FULL PLT entry, if needed. */
4361 if (dyn_i->want_plt2)
4362 {
4363 loc = plt_sec->contents + dyn_i->plt2_offset;
4364
4365 memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
4366 elfNN_ia64_install_value (output_bfd, loc, pltoff_addr - gp_val,
4367 R_IA64_IMM22);
4368
4369 /* Mark the symbol as undefined, rather than as defined in the
4370 plt section. Leave the value alone. */
4371 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4372 first place. But perhaps elflink.h did some for us. */
4373 if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
4374 sym->st_shndx = SHN_UNDEF;
4375 }
4376
4377 /* Create the dynamic relocation. */
4378 outrel.r_offset = pltoff_addr;
4379 if (bfd_little_endian (output_bfd))
4380 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
4381 else
4382 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
4383 outrel.r_addend = 0;
4384
4385 /* This is fun. In the .IA_64.pltoff section, we've got entries
4386 that correspond both to real PLT entries, and those that
4387 happened to resolve to local symbols but need to be created
4388 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4389 relocations for the real PLT should come at the end of the
4390 section, so that they can be indexed by plt entry at runtime.
4391
4392 We emitted all of the relocations for the non-PLT @pltoff
4393 entries during relocate_section. So we can consider the
4394 existing sec->reloc_count to be the base of the array of
4395 PLT relocations. */
4396
4397 rel = (ElfNN_External_Rela *)ia64_info->rel_pltoff_sec->contents;
4398 rel += ia64_info->rel_pltoff_sec->reloc_count;
4399
4400 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, rel + index);
4401 }
4402
4403 /* Mark some specially defined symbols as absolute. */
4404 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4405 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
4406 || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4407 sym->st_shndx = SHN_ABS;
4408
4409 return true;
4410 }
4411
4412 static boolean
4413 elfNN_ia64_finish_dynamic_sections (abfd, info)
4414 bfd *abfd;
4415 struct bfd_link_info *info;
4416 {
4417 struct elfNN_ia64_link_hash_table *ia64_info;
4418 bfd *dynobj;
4419
4420 ia64_info = elfNN_ia64_hash_table (info);
4421 dynobj = ia64_info->root.dynobj;
4422
4423 if (elf_hash_table (info)->dynamic_sections_created)
4424 {
4425 ElfNN_External_Dyn *dyncon, *dynconend;
4426 asection *sdyn, *sgotplt;
4427 bfd_vma gp_val;
4428
4429 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4430 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
4431 BFD_ASSERT (sdyn != NULL);
4432 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
4433 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
4434
4435 gp_val = _bfd_get_gp_value (abfd);
4436
4437 for (; dyncon < dynconend; dyncon++)
4438 {
4439 Elf_Internal_Dyn dyn;
4440
4441 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
4442
4443 switch (dyn.d_tag)
4444 {
4445 case DT_PLTGOT:
4446 dyn.d_un.d_ptr = gp_val;
4447 break;
4448
4449 case DT_PLTRELSZ:
4450 dyn.d_un.d_val = (ia64_info->minplt_entries
4451 * sizeof (ElfNN_External_Rela));
4452 break;
4453
4454 case DT_JMPREL:
4455 /* See the comment above in finish_dynamic_symbol. */
4456 dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
4457 + ia64_info->rel_pltoff_sec->output_offset
4458 + (ia64_info->rel_pltoff_sec->reloc_count
4459 * sizeof (ElfNN_External_Rela)));
4460 break;
4461
4462 case DT_IA_64_PLT_RESERVE:
4463 dyn.d_un.d_ptr = (sgotplt->output_section->vma
4464 + sgotplt->output_offset);
4465 break;
4466
4467 case DT_RELASZ:
4468 /* Do not have RELASZ include JMPREL. This makes things
4469 easier on ld.so. This is not what the rest of BFD set up. */
4470 dyn.d_un.d_val -= (ia64_info->minplt_entries
4471 * sizeof (ElfNN_External_Rela));
4472 break;
4473 }
4474
4475 bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
4476 }
4477
4478 /* Initialize the PLT0 entry */
4479 if (ia64_info->plt_sec)
4480 {
4481 bfd_byte *loc = ia64_info->plt_sec->contents;
4482 bfd_vma pltres;
4483
4484 memcpy (loc, plt_header, PLT_HEADER_SIZE);
4485
4486 pltres = (sgotplt->output_section->vma
4487 + sgotplt->output_offset
4488 - gp_val);
4489
4490 elfNN_ia64_install_value (abfd, loc+1, pltres, R_IA64_GPREL22);
4491 }
4492 }
4493
4494 return true;
4495 }
4496 \f
4497 /* ELF file flag handling: */
4498
4499 /* Function to keep IA-64 specific file flags. */
4500 static boolean
4501 elfNN_ia64_set_private_flags (abfd, flags)
4502 bfd *abfd;
4503 flagword flags;
4504 {
4505 BFD_ASSERT (!elf_flags_init (abfd)
4506 || elf_elfheader (abfd)->e_flags == flags);
4507
4508 elf_elfheader (abfd)->e_flags = flags;
4509 elf_flags_init (abfd) = true;
4510 return true;
4511 }
4512
4513 /* Merge backend specific data from an object file to the output
4514 object file when linking. */
4515 static boolean
4516 elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
4517 bfd *ibfd, *obfd;
4518 {
4519 flagword out_flags;
4520 flagword in_flags;
4521 boolean ok = true;
4522
4523 /* Don't even pretend to support mixed-format linking. */
4524 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4525 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4526 return false;
4527
4528 in_flags = elf_elfheader (ibfd)->e_flags;
4529 out_flags = elf_elfheader (obfd)->e_flags;
4530
4531 if (! elf_flags_init (obfd))
4532 {
4533 elf_flags_init (obfd) = true;
4534 elf_elfheader (obfd)->e_flags = in_flags;
4535
4536 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4537 && bfd_get_arch_info (obfd)->the_default)
4538 {
4539 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4540 bfd_get_mach (ibfd));
4541 }
4542
4543 return true;
4544 }
4545
4546 /* Check flag compatibility. */
4547 if (in_flags == out_flags)
4548 return true;
4549
4550 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4551 if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
4552 elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
4553
4554 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
4555 {
4556 (*_bfd_error_handler)
4557 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4558 bfd_archive_filename (ibfd));
4559
4560 bfd_set_error (bfd_error_bad_value);
4561 ok = false;
4562 }
4563 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
4564 {
4565 (*_bfd_error_handler)
4566 (_("%s: linking big-endian files with little-endian files"),
4567 bfd_archive_filename (ibfd));
4568
4569 bfd_set_error (bfd_error_bad_value);
4570 ok = false;
4571 }
4572 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4573 {
4574 (*_bfd_error_handler)
4575 (_("%s: linking 64-bit files with 32-bit files"),
4576 bfd_archive_filename (ibfd));
4577
4578 bfd_set_error (bfd_error_bad_value);
4579 ok = false;
4580 }
4581 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4582 {
4583 (*_bfd_error_handler)
4584 (_("%s: linking constant-gp files with non-constant-gp files"),
4585 bfd_archive_filename (ibfd));
4586
4587 bfd_set_error (bfd_error_bad_value);
4588 ok = false;
4589 }
4590 if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4591 != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4592 {
4593 (*_bfd_error_handler)
4594 (_("%s: linking auto-pic files with non-auto-pic files"),
4595 bfd_archive_filename (ibfd));
4596
4597 bfd_set_error (bfd_error_bad_value);
4598 ok = false;
4599 }
4600
4601 return ok;
4602 }
4603
4604 static boolean
4605 elfNN_ia64_print_private_bfd_data (abfd, ptr)
4606 bfd *abfd;
4607 PTR ptr;
4608 {
4609 FILE *file = (FILE *) ptr;
4610 flagword flags = elf_elfheader (abfd)->e_flags;
4611
4612 BFD_ASSERT (abfd != NULL && ptr != NULL);
4613
4614 fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4615 (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4616 (flags & EF_IA_64_EXT) ? "EXT, " : "",
4617 (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4618 (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4619 (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4620 (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4621 (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4622 (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4623
4624 _bfd_elf_print_private_bfd_data (abfd, ptr);
4625 return true;
4626 }
4627
4628 static enum elf_reloc_type_class
4629 elfNN_ia64_reloc_type_class (rela)
4630 const Elf_Internal_Rela *rela;
4631 {
4632 switch ((int) ELFNN_R_TYPE (rela->r_info))
4633 {
4634 case R_IA64_REL32MSB:
4635 case R_IA64_REL32LSB:
4636 case R_IA64_REL64MSB:
4637 case R_IA64_REL64LSB:
4638 return reloc_class_relative;
4639 case R_IA64_IPLTMSB:
4640 case R_IA64_IPLTLSB:
4641 return reloc_class_plt;
4642 case R_IA64_COPY:
4643 return reloc_class_copy;
4644 default:
4645 return reloc_class_normal;
4646 }
4647 }
4648
4649 static boolean
4650 elfNN_ia64_hpux_vec (const bfd_target *vec)
4651 {
4652 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
4653 return (vec == & bfd_elfNN_ia64_hpux_big_vec);
4654 }
4655
4656 static void
4657 elfNN_hpux_post_process_headers (abfd, info)
4658 bfd *abfd;
4659 struct bfd_link_info *info ATTRIBUTE_UNUSED;
4660 {
4661 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
4662
4663 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_HPUX;
4664 i_ehdrp->e_ident[EI_ABIVERSION] = 1;
4665 }
4666
4667 boolean
4668 elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
4669 bfd *abfd ATTRIBUTE_UNUSED;
4670 asection *sec;
4671 int *retval;
4672 {
4673 if (bfd_is_com_section (sec))
4674 {
4675 *retval = SHN_IA_64_ANSI_COMMON;
4676 return true;
4677 }
4678 return false;
4679 }
4680 \f
4681 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4682 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4683 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4684 #define TARGET_BIG_NAME "elfNN-ia64-big"
4685 #define ELF_ARCH bfd_arch_ia64
4686 #define ELF_MACHINE_CODE EM_IA_64
4687 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4688 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4689 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4690
4691 #define elf_backend_section_from_shdr \
4692 elfNN_ia64_section_from_shdr
4693 #define elf_backend_section_flags \
4694 elfNN_ia64_section_flags
4695 #define elf_backend_fake_sections \
4696 elfNN_ia64_fake_sections
4697 #define elf_backend_final_write_processing \
4698 elfNN_ia64_final_write_processing
4699 #define elf_backend_add_symbol_hook \
4700 elfNN_ia64_add_symbol_hook
4701 #define elf_backend_additional_program_headers \
4702 elfNN_ia64_additional_program_headers
4703 #define elf_backend_modify_segment_map \
4704 elfNN_ia64_modify_segment_map
4705 #define elf_info_to_howto \
4706 elfNN_ia64_info_to_howto
4707
4708 #define bfd_elfNN_bfd_reloc_type_lookup \
4709 elfNN_ia64_reloc_type_lookup
4710 #define bfd_elfNN_bfd_is_local_label_name \
4711 elfNN_ia64_is_local_label_name
4712 #define bfd_elfNN_bfd_relax_section \
4713 elfNN_ia64_relax_section
4714
4715 /* Stuff for the BFD linker: */
4716 #define bfd_elfNN_bfd_link_hash_table_create \
4717 elfNN_ia64_hash_table_create
4718 #define elf_backend_create_dynamic_sections \
4719 elfNN_ia64_create_dynamic_sections
4720 #define elf_backend_check_relocs \
4721 elfNN_ia64_check_relocs
4722 #define elf_backend_adjust_dynamic_symbol \
4723 elfNN_ia64_adjust_dynamic_symbol
4724 #define elf_backend_size_dynamic_sections \
4725 elfNN_ia64_size_dynamic_sections
4726 #define elf_backend_relocate_section \
4727 elfNN_ia64_relocate_section
4728 #define elf_backend_finish_dynamic_symbol \
4729 elfNN_ia64_finish_dynamic_symbol
4730 #define elf_backend_finish_dynamic_sections \
4731 elfNN_ia64_finish_dynamic_sections
4732 #define bfd_elfNN_bfd_final_link \
4733 elfNN_ia64_final_link
4734
4735 #define bfd_elfNN_bfd_merge_private_bfd_data \
4736 elfNN_ia64_merge_private_bfd_data
4737 #define bfd_elfNN_bfd_set_private_flags \
4738 elfNN_ia64_set_private_flags
4739 #define bfd_elfNN_bfd_print_private_bfd_data \
4740 elfNN_ia64_print_private_bfd_data
4741
4742 #define elf_backend_plt_readonly 1
4743 #define elf_backend_want_plt_sym 0
4744 #define elf_backend_plt_alignment 5
4745 #define elf_backend_got_header_size 0
4746 #define elf_backend_plt_header_size PLT_HEADER_SIZE
4747 #define elf_backend_want_got_plt 1
4748 #define elf_backend_may_use_rel_p 1
4749 #define elf_backend_may_use_rela_p 1
4750 #define elf_backend_default_use_rela_p 1
4751 #define elf_backend_want_dynbss 0
4752 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
4753 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
4754 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
4755 #define elf_backend_rela_normal 1
4756
4757 #include "elfNN-target.h"
4758
4759 /* AIX-specific vectors. */
4760
4761 #undef TARGET_LITTLE_SYM
4762 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec
4763 #undef TARGET_LITTLE_NAME
4764 #define TARGET_LITTLE_NAME "elfNN-ia64-aix-little"
4765 #undef TARGET_BIG_SYM
4766 #define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec
4767 #undef TARGET_BIG_NAME
4768 #define TARGET_BIG_NAME "elfNN-ia64-aix-big"
4769
4770 #undef elf_backend_add_symbol_hook
4771 #define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
4772
4773 #undef bfd_elfNN_bfd_link_add_symbols
4774 #define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
4775
4776 #define elfNN_bed elfNN_ia64_aix_bed
4777
4778 #include "elfNN-target.h"
4779
4780 /* HPUX-specific vectors. */
4781
4782 #undef TARGET_LITTLE_SYM
4783 #undef TARGET_LITTLE_NAME
4784 #undef TARGET_BIG_SYM
4785 #define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
4786 #undef TARGET_BIG_NAME
4787 #define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
4788
4789 /* We need to undo the AIX specific functions. */
4790
4791 #undef elf_backend_add_symbol_hook
4792 #define elf_backend_add_symbol_hook elfNN_ia64_add_symbol_hook
4793
4794 #undef bfd_elfNN_bfd_link_add_symbols
4795 #define bfd_elfNN_bfd_link_add_symbols _bfd_generic_link_add_symbols
4796
4797 /* These are HP-UX specific functions. */
4798
4799 #undef elf_backend_post_process_headers
4800 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
4801
4802 #undef elf_backend_section_from_bfd_section
4803 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
4804
4805 #undef ELF_MAXPAGESIZE
4806 #define ELF_MAXPAGESIZE 0x1000 /* 1K */
4807
4808 #undef elfNN_bed
4809 #define elfNN_bed elfNN_ia64_hpux_bed
4810
4811 #include "elfNN-target.h"
This page took 0.163493 seconds and 4 git commands to generate.