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