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