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