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