fc43f465de2812160f9a7ed663ed80b32d5c9aba
[deliverable/binutils-gdb.git] / bfd / elfxx-ia64.c
1 /* IA-64 support for 64-bit ELF
2 Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "elf-bfd.h"
25 #include "opcode/ia64.h"
26 #include "elf/ia64.h"
27
28 /* THE RULES for all the stuff the linker creates --
29
30 GOT Entries created in response to LTOFF or LTOFF_FPTR
31 relocations. Dynamic relocs created for dynamic
32 symbols in an application; REL relocs for locals
33 in a shared library.
34
35 FPTR The canonical function descriptor. Created for local
36 symbols in applications. Descriptors for dynamic symbols
37 and local symbols in shared libraries are created by
38 ld.so. Thus there are no dynamic relocs against these
39 objects. The FPTR relocs for such _are_ passed through
40 to the dynamic relocation tables.
41
42 FULL_PLT Created for a PCREL21B relocation against a dynamic symbol.
43 Requires the creation of a PLTOFF entry. This does not
44 require any dynamic relocations.
45
46 PLTOFF Created by PLTOFF relocations. For local symbols, this
47 is an alternate function descriptor, and in shared libraries
48 requires two REL relocations. Note that this cannot be
49 transformed into an FPTR relocation, since it must be in
50 range of the GP. For dynamic symbols, this is a function
51 descriptor for a MIN_PLT entry, and requires one IPLT reloc.
52
53 MIN_PLT Created by PLTOFF entries against dynamic symbols. This
54 does not reqire dynamic relocations. */
55
56 #define NELEMS(a) ((int) (sizeof (a) / sizeof ((a)[0])))
57
58 typedef struct bfd_hash_entry *(*new_hash_entry_func)
59 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
60
61 /* In dynamically (linker-) created sections, we generally need to keep track
62 of the place a symbol or expression got allocated to. This is done via hash
63 tables that store entries of the following type. */
64
65 struct elfNN_ia64_dyn_sym_info
66 {
67 /* The addend for which this entry is relevant. */
68 bfd_vma addend;
69
70 /* Next addend in the list. */
71 struct elfNN_ia64_dyn_sym_info *next;
72
73 bfd_vma got_offset;
74 bfd_vma fptr_offset;
75 bfd_vma pltoff_offset;
76 bfd_vma plt_offset;
77 bfd_vma plt2_offset;
78 bfd_vma tprel_offset;
79 bfd_vma dtpmod_offset;
80 bfd_vma dtprel_offset;
81
82 /* The symbol table entry, if any, that this was derrived from. */
83 struct elf_link_hash_entry *h;
84
85 /* Used to count non-got, non-plt relocations for delayed sizing
86 of relocation sections. */
87 struct elfNN_ia64_dyn_reloc_entry
88 {
89 struct elfNN_ia64_dyn_reloc_entry *next;
90 asection *srel;
91 int type;
92 int count;
93 } *reloc_entries;
94
95 /* TRUE when the section contents have been updated. */
96 unsigned got_done : 1;
97 unsigned fptr_done : 1;
98 unsigned pltoff_done : 1;
99 unsigned tprel_done : 1;
100 unsigned dtpmod_done : 1;
101 unsigned dtprel_done : 1;
102
103 /* TRUE for the different kinds of linker data we want created. */
104 unsigned want_got : 1;
105 unsigned want_gotx : 1;
106 unsigned want_fptr : 1;
107 unsigned want_ltoff_fptr : 1;
108 unsigned want_plt : 1;
109 unsigned want_plt2 : 1;
110 unsigned want_pltoff : 1;
111 unsigned want_tprel : 1;
112 unsigned want_dtpmod : 1;
113 unsigned want_dtprel : 1;
114 };
115
116 struct elfNN_ia64_local_hash_entry
117 {
118 struct bfd_hash_entry root;
119 struct elfNN_ia64_dyn_sym_info *info;
120
121 /* TRUE if this hash entry's addends was translated for
122 SHF_MERGE optimization. */
123 unsigned sec_merge_done : 1;
124 };
125
126 struct elfNN_ia64_local_hash_table
127 {
128 struct bfd_hash_table root;
129 /* No additional fields for now. */
130 };
131
132 struct elfNN_ia64_link_hash_entry
133 {
134 struct elf_link_hash_entry root;
135 struct elfNN_ia64_dyn_sym_info *info;
136 };
137
138 struct elfNN_ia64_link_hash_table
139 {
140 /* The main hash table. */
141 struct elf_link_hash_table root;
142
143 asection *got_sec; /* the linkage table section (or NULL) */
144 asection *rel_got_sec; /* dynamic relocation section for same */
145 asection *fptr_sec; /* function descriptor table (or NULL) */
146 asection *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, -1LL, 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 ((!info->executable && (!info->symbolic || info->allow_shlib_undefined))
1657 || ((h->elf_link_hash_flags
1658 & (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR))
1659 == (ELF_LINK_HASH_DEF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR)))
1660 return TRUE;
1661
1662 return FALSE;
1663 }
1664 \f
1665 static bfd_boolean
1666 elfNN_ia64_local_hash_table_init (ht, abfd, new)
1667 struct elfNN_ia64_local_hash_table *ht;
1668 bfd *abfd ATTRIBUTE_UNUSED;
1669 new_hash_entry_func new;
1670 {
1671 memset (ht, 0, sizeof (*ht));
1672 return bfd_hash_table_init (&ht->root, new);
1673 }
1674
1675 static struct bfd_hash_entry*
1676 elfNN_ia64_new_loc_hash_entry (entry, table, string)
1677 struct bfd_hash_entry *entry;
1678 struct bfd_hash_table *table;
1679 const char *string;
1680 {
1681 struct elfNN_ia64_local_hash_entry *ret;
1682 ret = (struct elfNN_ia64_local_hash_entry *) entry;
1683
1684 /* Allocate the structure if it has not already been allocated by a
1685 subclass. */
1686 if (!ret)
1687 ret = bfd_hash_allocate (table, sizeof (*ret));
1688
1689 if (!ret)
1690 return 0;
1691
1692 /* Initialize our local data. All zeros, and definitely easier
1693 than setting a handful of bit fields. */
1694 memset (ret, 0, sizeof (*ret));
1695
1696 /* Call the allocation method of the superclass. */
1697 ret = ((struct elfNN_ia64_local_hash_entry *)
1698 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
1699
1700 return (struct bfd_hash_entry *) ret;
1701 }
1702
1703 static struct bfd_hash_entry*
1704 elfNN_ia64_new_elf_hash_entry (entry, table, string)
1705 struct bfd_hash_entry *entry;
1706 struct bfd_hash_table *table;
1707 const char *string;
1708 {
1709 struct elfNN_ia64_link_hash_entry *ret;
1710 ret = (struct elfNN_ia64_link_hash_entry *) entry;
1711
1712 /* Allocate the structure if it has not already been allocated by a
1713 subclass. */
1714 if (!ret)
1715 ret = bfd_hash_allocate (table, sizeof (*ret));
1716
1717 if (!ret)
1718 return 0;
1719
1720 /* Initialize our local data. All zeros, and definitely easier
1721 than setting a handful of bit fields. */
1722 memset (ret, 0, sizeof (*ret));
1723
1724 /* Call the allocation method of the superclass. */
1725 ret = ((struct elfNN_ia64_link_hash_entry *)
1726 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
1727 table, string));
1728
1729 return (struct bfd_hash_entry *) ret;
1730 }
1731
1732 static void
1733 elfNN_ia64_hash_copy_indirect (bed, xdir, xind)
1734 struct elf_backend_data *bed ATTRIBUTE_UNUSED;
1735 struct elf_link_hash_entry *xdir, *xind;
1736 {
1737 struct elfNN_ia64_link_hash_entry *dir, *ind;
1738
1739 dir = (struct elfNN_ia64_link_hash_entry *) xdir;
1740 ind = (struct elfNN_ia64_link_hash_entry *) xind;
1741
1742 /* Copy down any references that we may have already seen to the
1743 symbol which just became indirect. */
1744
1745 dir->root.elf_link_hash_flags |=
1746 (ind->root.elf_link_hash_flags
1747 & (ELF_LINK_HASH_REF_DYNAMIC
1748 | ELF_LINK_HASH_REF_REGULAR
1749 | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
1750
1751 if (ind->root.root.type != bfd_link_hash_indirect)
1752 return;
1753
1754 /* Copy over the got and plt data. This would have been done
1755 by check_relocs. */
1756
1757 if (dir->info == NULL)
1758 {
1759 struct elfNN_ia64_dyn_sym_info *dyn_i;
1760
1761 dir->info = dyn_i = ind->info;
1762 ind->info = NULL;
1763
1764 /* Fix up the dyn_sym_info pointers to the global symbol. */
1765 for (; dyn_i; dyn_i = dyn_i->next)
1766 dyn_i->h = &dir->root;
1767 }
1768 BFD_ASSERT (ind->info == NULL);
1769
1770 /* Copy over the dynindx. */
1771
1772 if (dir->root.dynindx == -1)
1773 {
1774 dir->root.dynindx = ind->root.dynindx;
1775 dir->root.dynstr_index = ind->root.dynstr_index;
1776 ind->root.dynindx = -1;
1777 ind->root.dynstr_index = 0;
1778 }
1779 BFD_ASSERT (ind->root.dynindx == -1);
1780 }
1781
1782 static void
1783 elfNN_ia64_hash_hide_symbol (info, xh, force_local)
1784 struct bfd_link_info *info;
1785 struct elf_link_hash_entry *xh;
1786 bfd_boolean force_local;
1787 {
1788 struct elfNN_ia64_link_hash_entry *h;
1789 struct elfNN_ia64_dyn_sym_info *dyn_i;
1790
1791 h = (struct elfNN_ia64_link_hash_entry *)xh;
1792
1793 _bfd_elf_link_hash_hide_symbol (info, &h->root, force_local);
1794
1795 for (dyn_i = h->info; dyn_i; dyn_i = dyn_i->next)
1796 {
1797 dyn_i->want_plt2 = 0;
1798 dyn_i->want_plt = 0;
1799 }
1800 }
1801
1802 /* Create the derived linker hash table. The IA-64 ELF port uses this
1803 derived hash table to keep information specific to the IA-64 ElF
1804 linker (without using static variables). */
1805
1806 static struct bfd_link_hash_table*
1807 elfNN_ia64_hash_table_create (abfd)
1808 bfd *abfd;
1809 {
1810 struct elfNN_ia64_link_hash_table *ret;
1811
1812 ret = bfd_zmalloc ((bfd_size_type) sizeof (*ret));
1813 if (!ret)
1814 return 0;
1815
1816 if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
1817 elfNN_ia64_new_elf_hash_entry))
1818 {
1819 free (ret);
1820 return 0;
1821 }
1822
1823 if (!elfNN_ia64_local_hash_table_init (&ret->loc_hash_table, abfd,
1824 elfNN_ia64_new_loc_hash_entry))
1825 {
1826 free (ret);
1827 return 0;
1828 }
1829
1830 return &ret->root.root;
1831 }
1832
1833 /* Look up an entry in a Alpha ELF linker hash table. */
1834
1835 static INLINE struct elfNN_ia64_local_hash_entry *
1836 elfNN_ia64_local_hash_lookup(table, string, create, copy)
1837 struct elfNN_ia64_local_hash_table *table;
1838 const char *string;
1839 bfd_boolean create, copy;
1840 {
1841 return ((struct elfNN_ia64_local_hash_entry *)
1842 bfd_hash_lookup (&table->root, string, create, copy));
1843 }
1844
1845 /* Traverse both local and global hash tables. */
1846
1847 struct elfNN_ia64_dyn_sym_traverse_data
1848 {
1849 bfd_boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1850 PTR data;
1851 };
1852
1853 static bfd_boolean
1854 elfNN_ia64_global_dyn_sym_thunk (xentry, xdata)
1855 struct bfd_hash_entry *xentry;
1856 PTR xdata;
1857 {
1858 struct elfNN_ia64_link_hash_entry *entry
1859 = (struct elfNN_ia64_link_hash_entry *) xentry;
1860 struct elfNN_ia64_dyn_sym_traverse_data *data
1861 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1862 struct elfNN_ia64_dyn_sym_info *dyn_i;
1863
1864 if (entry->root.root.type == bfd_link_hash_warning)
1865 entry = (struct elfNN_ia64_link_hash_entry *) entry->root.root.u.i.link;
1866
1867 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1868 if (! (*data->func) (dyn_i, data->data))
1869 return FALSE;
1870 return TRUE;
1871 }
1872
1873 static bfd_boolean
1874 elfNN_ia64_local_dyn_sym_thunk (xentry, xdata)
1875 struct bfd_hash_entry *xentry;
1876 PTR xdata;
1877 {
1878 struct elfNN_ia64_local_hash_entry *entry
1879 = (struct elfNN_ia64_local_hash_entry *) xentry;
1880 struct elfNN_ia64_dyn_sym_traverse_data *data
1881 = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
1882 struct elfNN_ia64_dyn_sym_info *dyn_i;
1883
1884 for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
1885 if (! (*data->func) (dyn_i, data->data))
1886 return FALSE;
1887 return TRUE;
1888 }
1889
1890 static void
1891 elfNN_ia64_dyn_sym_traverse (ia64_info, func, data)
1892 struct elfNN_ia64_link_hash_table *ia64_info;
1893 bfd_boolean (*func) PARAMS ((struct elfNN_ia64_dyn_sym_info *, PTR));
1894 PTR data;
1895 {
1896 struct elfNN_ia64_dyn_sym_traverse_data xdata;
1897
1898 xdata.func = func;
1899 xdata.data = data;
1900
1901 elf_link_hash_traverse (&ia64_info->root,
1902 elfNN_ia64_global_dyn_sym_thunk, &xdata);
1903 bfd_hash_traverse (&ia64_info->loc_hash_table.root,
1904 elfNN_ia64_local_dyn_sym_thunk, &xdata);
1905 }
1906 \f
1907 static bfd_boolean
1908 elfNN_ia64_create_dynamic_sections (abfd, info)
1909 bfd *abfd;
1910 struct bfd_link_info *info;
1911 {
1912 struct elfNN_ia64_link_hash_table *ia64_info;
1913 asection *s;
1914
1915 if (! _bfd_elf_create_dynamic_sections (abfd, info))
1916 return FALSE;
1917
1918 ia64_info = elfNN_ia64_hash_table (info);
1919
1920 ia64_info->plt_sec = bfd_get_section_by_name (abfd, ".plt");
1921 ia64_info->got_sec = bfd_get_section_by_name (abfd, ".got");
1922
1923 {
1924 flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
1925 bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
1926 }
1927
1928 if (!get_pltoff (abfd, info, ia64_info))
1929 return FALSE;
1930
1931 s = bfd_make_section(abfd, ".rela.IA_64.pltoff");
1932 if (s == NULL
1933 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1934 | SEC_HAS_CONTENTS
1935 | SEC_IN_MEMORY
1936 | SEC_LINKER_CREATED
1937 | SEC_READONLY))
1938 || !bfd_set_section_alignment (abfd, s, 3))
1939 return FALSE;
1940 ia64_info->rel_pltoff_sec = s;
1941
1942 s = bfd_make_section(abfd, ".rela.got");
1943 if (s == NULL
1944 || !bfd_set_section_flags (abfd, s, (SEC_ALLOC | SEC_LOAD
1945 | SEC_HAS_CONTENTS
1946 | SEC_IN_MEMORY
1947 | SEC_LINKER_CREATED
1948 | SEC_READONLY))
1949 || !bfd_set_section_alignment (abfd, s, 3))
1950 return FALSE;
1951 ia64_info->rel_got_sec = s;
1952
1953 return TRUE;
1954 }
1955
1956 /* Find and/or create a hash entry for local symbol. */
1957 static struct elfNN_ia64_local_hash_entry *
1958 get_local_sym_hash (ia64_info, abfd, rel, create)
1959 struct elfNN_ia64_link_hash_table *ia64_info;
1960 bfd *abfd;
1961 const Elf_Internal_Rela *rel;
1962 bfd_boolean create;
1963 {
1964 struct elfNN_ia64_local_hash_entry *ret;
1965 asection *sec = abfd->sections;
1966 char addr_name [34];
1967
1968 BFD_ASSERT ((sizeof (sec->id)*2 + 1 + sizeof (unsigned long)*2 + 1) <= 34);
1969 BFD_ASSERT (sec);
1970
1971 /* Construct a string for use in the elfNN_ia64_local_hash_table.
1972 name describes what was once anonymous memory. */
1973
1974 sprintf (addr_name, "%x:%lx",
1975 sec->id, (unsigned long) ELFNN_R_SYM (rel->r_info));
1976
1977 /* Collect the canonical entry data for this address. */
1978 ret = elfNN_ia64_local_hash_lookup (&ia64_info->loc_hash_table,
1979 addr_name, create, create);
1980 return ret;
1981 }
1982
1983 /* Find and/or create a descriptor for dynamic symbol info. This will
1984 vary based on global or local symbol, and the addend to the reloc. */
1985
1986 static struct elfNN_ia64_dyn_sym_info *
1987 get_dyn_sym_info (ia64_info, h, abfd, rel, create)
1988 struct elfNN_ia64_link_hash_table *ia64_info;
1989 struct elf_link_hash_entry *h;
1990 bfd *abfd;
1991 const Elf_Internal_Rela *rel;
1992 bfd_boolean create;
1993 {
1994 struct elfNN_ia64_dyn_sym_info **pp;
1995 struct elfNN_ia64_dyn_sym_info *dyn_i;
1996 bfd_vma addend = rel ? rel->r_addend : 0;
1997
1998 if (h)
1999 pp = &((struct elfNN_ia64_link_hash_entry *)h)->info;
2000 else
2001 {
2002 struct elfNN_ia64_local_hash_entry *loc_h;
2003
2004 loc_h = get_local_sym_hash (ia64_info, abfd, rel, create);
2005 if (!loc_h)
2006 {
2007 BFD_ASSERT (!create);
2008 return NULL;
2009 }
2010
2011 pp = &loc_h->info;
2012 }
2013
2014 for (dyn_i = *pp; dyn_i && dyn_i->addend != addend; dyn_i = *pp)
2015 pp = &dyn_i->next;
2016
2017 if (dyn_i == NULL && create)
2018 {
2019 dyn_i = ((struct elfNN_ia64_dyn_sym_info *)
2020 bfd_zalloc (abfd, (bfd_size_type) sizeof *dyn_i));
2021 *pp = dyn_i;
2022 dyn_i->addend = addend;
2023 }
2024
2025 return dyn_i;
2026 }
2027
2028 static asection *
2029 get_got (abfd, info, ia64_info)
2030 bfd *abfd;
2031 struct bfd_link_info *info;
2032 struct elfNN_ia64_link_hash_table *ia64_info;
2033 {
2034 asection *got;
2035 bfd *dynobj;
2036
2037 got = ia64_info->got_sec;
2038 if (!got)
2039 {
2040 flagword flags;
2041
2042 dynobj = ia64_info->root.dynobj;
2043 if (!dynobj)
2044 ia64_info->root.dynobj = dynobj = abfd;
2045 if (!_bfd_elf_create_got_section (dynobj, info))
2046 return 0;
2047
2048 got = bfd_get_section_by_name (dynobj, ".got");
2049 BFD_ASSERT (got);
2050 ia64_info->got_sec = got;
2051
2052 flags = bfd_get_section_flags (abfd, got);
2053 bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
2054 }
2055
2056 return got;
2057 }
2058
2059 /* Create function descriptor section (.opd). This section is called .opd
2060 because it contains "official prodecure descriptors". The "official"
2061 refers to the fact that these descriptors are used when taking the address
2062 of a procedure, thus ensuring a unique address for each procedure. */
2063
2064 static asection *
2065 get_fptr (abfd, info, ia64_info)
2066 bfd *abfd;
2067 struct bfd_link_info *info;
2068 struct elfNN_ia64_link_hash_table *ia64_info;
2069 {
2070 asection *fptr;
2071 bfd *dynobj;
2072
2073 fptr = ia64_info->fptr_sec;
2074 if (!fptr)
2075 {
2076 dynobj = ia64_info->root.dynobj;
2077 if (!dynobj)
2078 ia64_info->root.dynobj = dynobj = abfd;
2079
2080 fptr = bfd_make_section (dynobj, ".opd");
2081 if (!fptr
2082 || !bfd_set_section_flags (dynobj, fptr,
2083 (SEC_ALLOC
2084 | SEC_LOAD
2085 | SEC_HAS_CONTENTS
2086 | SEC_IN_MEMORY
2087 | (info->pie ? 0 : SEC_READONLY)
2088 | SEC_LINKER_CREATED))
2089 || !bfd_set_section_alignment (abfd, fptr, 4))
2090 {
2091 BFD_ASSERT (0);
2092 return NULL;
2093 }
2094
2095 ia64_info->fptr_sec = fptr;
2096
2097 if (info->pie)
2098 {
2099 asection *fptr_rel;
2100 fptr_rel = bfd_make_section(abfd, ".rela.opd");
2101 if (fptr_rel == NULL
2102 || !bfd_set_section_flags (abfd, fptr_rel,
2103 (SEC_ALLOC | SEC_LOAD
2104 | SEC_HAS_CONTENTS
2105 | SEC_IN_MEMORY
2106 | SEC_LINKER_CREATED
2107 | SEC_READONLY))
2108 || !bfd_set_section_alignment (abfd, fptr_rel, 3))
2109 {
2110 BFD_ASSERT (0);
2111 return NULL;
2112 }
2113
2114 ia64_info->rel_fptr_sec = fptr_rel;
2115 }
2116 }
2117
2118 return fptr;
2119 }
2120
2121 static asection *
2122 get_pltoff (abfd, info, ia64_info)
2123 bfd *abfd;
2124 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2125 struct elfNN_ia64_link_hash_table *ia64_info;
2126 {
2127 asection *pltoff;
2128 bfd *dynobj;
2129
2130 pltoff = ia64_info->pltoff_sec;
2131 if (!pltoff)
2132 {
2133 dynobj = ia64_info->root.dynobj;
2134 if (!dynobj)
2135 ia64_info->root.dynobj = dynobj = abfd;
2136
2137 pltoff = bfd_make_section (dynobj, ELF_STRING_ia64_pltoff);
2138 if (!pltoff
2139 || !bfd_set_section_flags (dynobj, pltoff,
2140 (SEC_ALLOC
2141 | SEC_LOAD
2142 | SEC_HAS_CONTENTS
2143 | SEC_IN_MEMORY
2144 | SEC_SMALL_DATA
2145 | SEC_LINKER_CREATED))
2146 || !bfd_set_section_alignment (abfd, pltoff, 4))
2147 {
2148 BFD_ASSERT (0);
2149 return NULL;
2150 }
2151
2152 ia64_info->pltoff_sec = pltoff;
2153 }
2154
2155 return pltoff;
2156 }
2157
2158 static asection *
2159 get_reloc_section (abfd, ia64_info, sec, create)
2160 bfd *abfd;
2161 struct elfNN_ia64_link_hash_table *ia64_info;
2162 asection *sec;
2163 bfd_boolean create;
2164 {
2165 const char *srel_name;
2166 asection *srel;
2167 bfd *dynobj;
2168
2169 srel_name = (bfd_elf_string_from_elf_section
2170 (abfd, elf_elfheader(abfd)->e_shstrndx,
2171 elf_section_data(sec)->rel_hdr.sh_name));
2172 if (srel_name == NULL)
2173 return NULL;
2174
2175 BFD_ASSERT ((strncmp (srel_name, ".rela", 5) == 0
2176 && strcmp (bfd_get_section_name (abfd, sec),
2177 srel_name+5) == 0)
2178 || (strncmp (srel_name, ".rel", 4) == 0
2179 && strcmp (bfd_get_section_name (abfd, sec),
2180 srel_name+4) == 0));
2181
2182 dynobj = ia64_info->root.dynobj;
2183 if (!dynobj)
2184 ia64_info->root.dynobj = dynobj = abfd;
2185
2186 srel = bfd_get_section_by_name (dynobj, srel_name);
2187 if (srel == NULL && create)
2188 {
2189 srel = bfd_make_section (dynobj, srel_name);
2190 if (srel == NULL
2191 || !bfd_set_section_flags (dynobj, srel,
2192 (SEC_ALLOC
2193 | SEC_LOAD
2194 | SEC_HAS_CONTENTS
2195 | SEC_IN_MEMORY
2196 | SEC_LINKER_CREATED
2197 | SEC_READONLY))
2198 || !bfd_set_section_alignment (dynobj, srel, 3))
2199 return NULL;
2200 }
2201
2202 if (sec->flags & SEC_READONLY)
2203 ia64_info->reltext = 1;
2204
2205 return srel;
2206 }
2207
2208 static bfd_boolean
2209 count_dyn_reloc (abfd, dyn_i, srel, type)
2210 bfd *abfd;
2211 struct elfNN_ia64_dyn_sym_info *dyn_i;
2212 asection *srel;
2213 int type;
2214 {
2215 struct elfNN_ia64_dyn_reloc_entry *rent;
2216
2217 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2218 if (rent->srel == srel && rent->type == type)
2219 break;
2220
2221 if (!rent)
2222 {
2223 rent = ((struct elfNN_ia64_dyn_reloc_entry *)
2224 bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
2225 if (!rent)
2226 return FALSE;
2227
2228 rent->next = dyn_i->reloc_entries;
2229 rent->srel = srel;
2230 rent->type = type;
2231 rent->count = 0;
2232 dyn_i->reloc_entries = rent;
2233 }
2234 rent->count++;
2235
2236 return TRUE;
2237 }
2238
2239 static bfd_boolean
2240 elfNN_ia64_check_relocs (abfd, info, sec, relocs)
2241 bfd *abfd;
2242 struct bfd_link_info *info;
2243 asection *sec;
2244 const Elf_Internal_Rela *relocs;
2245 {
2246 struct elfNN_ia64_link_hash_table *ia64_info;
2247 const Elf_Internal_Rela *relend;
2248 Elf_Internal_Shdr *symtab_hdr;
2249 const Elf_Internal_Rela *rel;
2250 asection *got, *fptr, *srel;
2251
2252 if (info->relocatable)
2253 return TRUE;
2254
2255 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2256 ia64_info = elfNN_ia64_hash_table (info);
2257
2258 got = fptr = srel = NULL;
2259
2260 relend = relocs + sec->reloc_count;
2261 for (rel = relocs; rel < relend; ++rel)
2262 {
2263 enum {
2264 NEED_GOT = 1,
2265 NEED_GOTX = 2,
2266 NEED_FPTR = 4,
2267 NEED_PLTOFF = 8,
2268 NEED_MIN_PLT = 16,
2269 NEED_FULL_PLT = 32,
2270 NEED_DYNREL = 64,
2271 NEED_LTOFF_FPTR = 128,
2272 NEED_TPREL = 256,
2273 NEED_DTPMOD = 512,
2274 NEED_DTPREL = 1024
2275 };
2276
2277 struct elf_link_hash_entry *h = NULL;
2278 unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
2279 struct elfNN_ia64_dyn_sym_info *dyn_i;
2280 int need_entry;
2281 bfd_boolean maybe_dynamic;
2282 int dynrel_type = R_IA64_NONE;
2283
2284 if (r_symndx >= symtab_hdr->sh_info)
2285 {
2286 /* We're dealing with a global symbol -- find its hash entry
2287 and mark it as being referenced. */
2288 long indx = r_symndx - symtab_hdr->sh_info;
2289 h = elf_sym_hashes (abfd)[indx];
2290 while (h->root.type == bfd_link_hash_indirect
2291 || h->root.type == bfd_link_hash_warning)
2292 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2293
2294 h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
2295 }
2296
2297 /* We can only get preliminary data on whether a symbol is
2298 locally or externally defined, as not all of the input files
2299 have yet been processed. Do something with what we know, as
2300 this may help reduce memory usage and processing time later. */
2301 maybe_dynamic = FALSE;
2302 if (h && ((!info->executable
2303 && (!info->symbolic || info->allow_shlib_undefined))
2304 || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
2305 || h->root.type == bfd_link_hash_defweak
2306 || elfNN_ia64_aix_vec (abfd->xvec)))
2307 maybe_dynamic = TRUE;
2308
2309 need_entry = 0;
2310 switch (ELFNN_R_TYPE (rel->r_info))
2311 {
2312 case R_IA64_TPREL64MSB:
2313 case R_IA64_TPREL64LSB:
2314 if (info->shared || maybe_dynamic)
2315 need_entry = NEED_DYNREL;
2316 dynrel_type = R_IA64_TPREL64LSB;
2317 if (info->shared)
2318 info->flags |= DF_STATIC_TLS;
2319 break;
2320
2321 case R_IA64_LTOFF_TPREL22:
2322 need_entry = NEED_TPREL;
2323 if (info->shared)
2324 info->flags |= DF_STATIC_TLS;
2325 break;
2326
2327 case R_IA64_DTPREL64MSB:
2328 case R_IA64_DTPREL64LSB:
2329 if (info->shared || maybe_dynamic)
2330 need_entry = NEED_DYNREL;
2331 dynrel_type = R_IA64_DTPREL64LSB;
2332 break;
2333
2334 case R_IA64_LTOFF_DTPREL22:
2335 need_entry = NEED_DTPREL;
2336 break;
2337
2338 case R_IA64_DTPMOD64MSB:
2339 case R_IA64_DTPMOD64LSB:
2340 if (info->shared || maybe_dynamic)
2341 need_entry = NEED_DYNREL;
2342 dynrel_type = R_IA64_DTPMOD64LSB;
2343 break;
2344
2345 case R_IA64_LTOFF_DTPMOD22:
2346 need_entry = NEED_DTPMOD;
2347 break;
2348
2349 case R_IA64_LTOFF_FPTR22:
2350 case R_IA64_LTOFF_FPTR64I:
2351 case R_IA64_LTOFF_FPTR32MSB:
2352 case R_IA64_LTOFF_FPTR32LSB:
2353 case R_IA64_LTOFF_FPTR64MSB:
2354 case R_IA64_LTOFF_FPTR64LSB:
2355 need_entry = NEED_FPTR | NEED_GOT | NEED_LTOFF_FPTR;
2356 break;
2357
2358 case R_IA64_FPTR64I:
2359 case R_IA64_FPTR32MSB:
2360 case R_IA64_FPTR32LSB:
2361 case R_IA64_FPTR64MSB:
2362 case R_IA64_FPTR64LSB:
2363 if (info->shared || h || elfNN_ia64_aix_vec (abfd->xvec))
2364 need_entry = NEED_FPTR | NEED_DYNREL;
2365 else
2366 need_entry = NEED_FPTR;
2367 dynrel_type = R_IA64_FPTR64LSB;
2368 break;
2369
2370 case R_IA64_LTOFF22:
2371 case R_IA64_LTOFF64I:
2372 need_entry = NEED_GOT;
2373 break;
2374
2375 case R_IA64_LTOFF22X:
2376 need_entry = NEED_GOTX;
2377 break;
2378
2379 case R_IA64_PLTOFF22:
2380 case R_IA64_PLTOFF64I:
2381 case R_IA64_PLTOFF64MSB:
2382 case R_IA64_PLTOFF64LSB:
2383 need_entry = NEED_PLTOFF;
2384 if (h)
2385 {
2386 if (maybe_dynamic)
2387 need_entry |= NEED_MIN_PLT;
2388 }
2389 else
2390 {
2391 (*info->callbacks->warning)
2392 (info, _("@pltoff reloc against local symbol"), 0,
2393 abfd, 0, (bfd_vma) 0);
2394 }
2395 break;
2396
2397 case R_IA64_PCREL21B:
2398 case R_IA64_PCREL60B:
2399 /* Depending on where this symbol is defined, we may or may not
2400 need a full plt entry. Only skip if we know we'll not need
2401 the entry -- static or symbolic, and the symbol definition
2402 has already been seen. */
2403 if (maybe_dynamic && rel->r_addend == 0)
2404 need_entry = NEED_FULL_PLT;
2405 break;
2406
2407 case R_IA64_IMM14:
2408 case R_IA64_IMM22:
2409 case R_IA64_IMM64:
2410 case R_IA64_DIR32MSB:
2411 case R_IA64_DIR32LSB:
2412 case R_IA64_DIR64MSB:
2413 case R_IA64_DIR64LSB:
2414 /* Shared objects will always need at least a REL relocation. */
2415 if (info->shared || maybe_dynamic
2416 || (elfNN_ia64_aix_vec (abfd->xvec)
2417 && (!h || strcmp (h->root.root.string,
2418 "__GLOB_DATA_PTR") != 0)))
2419 need_entry = NEED_DYNREL;
2420 dynrel_type = R_IA64_DIR64LSB;
2421 break;
2422
2423 case R_IA64_IPLTMSB:
2424 case R_IA64_IPLTLSB:
2425 /* Shared objects will always need at least a REL relocation. */
2426 if (info->shared || maybe_dynamic)
2427 need_entry = NEED_DYNREL;
2428 dynrel_type = R_IA64_IPLTLSB;
2429 break;
2430
2431 case R_IA64_PCREL22:
2432 case R_IA64_PCREL64I:
2433 case R_IA64_PCREL32MSB:
2434 case R_IA64_PCREL32LSB:
2435 case R_IA64_PCREL64MSB:
2436 case R_IA64_PCREL64LSB:
2437 if (maybe_dynamic)
2438 need_entry = NEED_DYNREL;
2439 dynrel_type = R_IA64_PCREL64LSB;
2440 break;
2441 }
2442
2443 if (!need_entry)
2444 continue;
2445
2446 if ((need_entry & NEED_FPTR) != 0
2447 && rel->r_addend)
2448 {
2449 (*info->callbacks->warning)
2450 (info, _("non-zero addend in @fptr reloc"), 0,
2451 abfd, 0, (bfd_vma) 0);
2452 }
2453
2454 dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, TRUE);
2455
2456 /* Record whether or not this is a local symbol. */
2457 dyn_i->h = h;
2458
2459 /* Create what's needed. */
2460 if (need_entry & (NEED_GOT | NEED_GOTX | NEED_TPREL
2461 | NEED_DTPMOD | NEED_DTPREL))
2462 {
2463 if (!got)
2464 {
2465 got = get_got (abfd, info, ia64_info);
2466 if (!got)
2467 return FALSE;
2468 }
2469 if (need_entry & NEED_GOT)
2470 dyn_i->want_got = 1;
2471 if (need_entry & NEED_GOTX)
2472 dyn_i->want_gotx = 1;
2473 if (need_entry & NEED_TPREL)
2474 dyn_i->want_tprel = 1;
2475 if (need_entry & NEED_DTPMOD)
2476 dyn_i->want_dtpmod = 1;
2477 if (need_entry & NEED_DTPREL)
2478 dyn_i->want_dtprel = 1;
2479 }
2480 if (need_entry & NEED_FPTR)
2481 {
2482 if (!fptr)
2483 {
2484 fptr = get_fptr (abfd, info, ia64_info);
2485 if (!fptr)
2486 return FALSE;
2487 }
2488
2489 /* FPTRs for shared libraries are allocated by the dynamic
2490 linker. Make sure this local symbol will appear in the
2491 dynamic symbol table. */
2492 if (!h && (info->shared
2493 /* AIX also needs one */
2494 || elfNN_ia64_aix_vec (abfd->xvec)))
2495 {
2496 if (! (_bfd_elfNN_link_record_local_dynamic_symbol
2497 (info, abfd, (long) r_symndx)))
2498 return FALSE;
2499 }
2500
2501 dyn_i->want_fptr = 1;
2502 }
2503 if (need_entry & NEED_LTOFF_FPTR)
2504 dyn_i->want_ltoff_fptr = 1;
2505 if (need_entry & (NEED_MIN_PLT | NEED_FULL_PLT))
2506 {
2507 if (!ia64_info->root.dynobj)
2508 ia64_info->root.dynobj = abfd;
2509 h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
2510 dyn_i->want_plt = 1;
2511 }
2512 if (need_entry & NEED_FULL_PLT)
2513 dyn_i->want_plt2 = 1;
2514 if (need_entry & NEED_PLTOFF)
2515 dyn_i->want_pltoff = 1;
2516 if ((need_entry & NEED_DYNREL) && (sec->flags & SEC_ALLOC))
2517 {
2518 if (!srel)
2519 {
2520 srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
2521 if (!srel)
2522 return FALSE;
2523 }
2524 if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type))
2525 return FALSE;
2526 }
2527 }
2528
2529 return TRUE;
2530 }
2531
2532 /* For cleanliness, and potentially faster dynamic loading, allocate
2533 external GOT entries first. */
2534
2535 static bfd_boolean
2536 allocate_global_data_got (dyn_i, data)
2537 struct elfNN_ia64_dyn_sym_info *dyn_i;
2538 PTR data;
2539 {
2540 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2541
2542 if ((dyn_i->want_got || dyn_i->want_gotx)
2543 && ! dyn_i->want_fptr
2544 && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2545 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2546 && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2547 "__GLOB_DATA_PTR") != 0))))
2548 {
2549 dyn_i->got_offset = x->ofs;
2550 x->ofs += 8;
2551 }
2552 if (dyn_i->want_tprel)
2553 {
2554 dyn_i->tprel_offset = x->ofs;
2555 x->ofs += 8;
2556 }
2557 if (dyn_i->want_dtpmod)
2558 {
2559 if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
2560 {
2561 dyn_i->dtpmod_offset = x->ofs;
2562 x->ofs += 8;
2563 }
2564 else
2565 {
2566 struct elfNN_ia64_link_hash_table *ia64_info;
2567
2568 ia64_info = elfNN_ia64_hash_table (x->info);
2569 if (ia64_info->self_dtpmod_offset == (bfd_vma) -1)
2570 {
2571 ia64_info->self_dtpmod_offset = x->ofs;
2572 x->ofs += 8;
2573 }
2574 dyn_i->dtpmod_offset = ia64_info->self_dtpmod_offset;
2575 }
2576 }
2577 if (dyn_i->want_dtprel)
2578 {
2579 dyn_i->dtprel_offset = x->ofs;
2580 x->ofs += 8;
2581 }
2582 return TRUE;
2583 }
2584
2585 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs. */
2586
2587 static bfd_boolean
2588 allocate_global_fptr_got (dyn_i, data)
2589 struct elfNN_ia64_dyn_sym_info *dyn_i;
2590 PTR data;
2591 {
2592 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2593
2594 if (dyn_i->want_got
2595 && dyn_i->want_fptr
2596 && (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2597 || elfNN_ia64_aix_vec (x->info->hash->creator)))
2598 {
2599 dyn_i->got_offset = x->ofs;
2600 x->ofs += 8;
2601 }
2602 return TRUE;
2603 }
2604
2605 /* Lastly, allocate all the GOT entries for local data. */
2606
2607 static bfd_boolean
2608 allocate_local_got (dyn_i, data)
2609 struct elfNN_ia64_dyn_sym_info *dyn_i;
2610 PTR data;
2611 {
2612 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2613
2614 if ((dyn_i->want_got || dyn_i->want_gotx)
2615 && ! (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2616 || elfNN_ia64_aix_vec (x->info->hash->creator)))
2617 {
2618 dyn_i->got_offset = x->ofs;
2619 x->ofs += 8;
2620 }
2621 return TRUE;
2622 }
2623
2624 /* Search for the index of a global symbol in it's defining object file. */
2625
2626 static long
2627 global_sym_index (h)
2628 struct elf_link_hash_entry *h;
2629 {
2630 struct elf_link_hash_entry **p;
2631 bfd *obj;
2632
2633 BFD_ASSERT (h->root.type == bfd_link_hash_defined
2634 || h->root.type == bfd_link_hash_defweak);
2635
2636 obj = h->root.u.def.section->owner;
2637 for (p = elf_sym_hashes (obj); *p != h; ++p)
2638 continue;
2639
2640 return p - elf_sym_hashes (obj) + elf_tdata (obj)->symtab_hdr.sh_info;
2641 }
2642
2643 /* Allocate function descriptors. We can do these for every function
2644 in a main executable that is not exported. */
2645
2646 static bfd_boolean
2647 allocate_fptr (dyn_i, data)
2648 struct elfNN_ia64_dyn_sym_info *dyn_i;
2649 PTR data;
2650 {
2651 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2652
2653 if (dyn_i->want_fptr)
2654 {
2655 struct elf_link_hash_entry *h = dyn_i->h;
2656
2657 if (h)
2658 while (h->root.type == bfd_link_hash_indirect
2659 || h->root.type == bfd_link_hash_warning)
2660 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2661
2662 if ((!x->info->executable
2663 && (!h
2664 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
2665 || h->root.type != bfd_link_hash_undefweak))
2666 /* AIX needs an FPTR in this case. */
2667 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2668 && (!h
2669 || h->root.type == bfd_link_hash_defined
2670 || h->root.type == bfd_link_hash_defweak)))
2671 {
2672 if (h && h->dynindx == -1)
2673 {
2674 BFD_ASSERT ((h->root.type == bfd_link_hash_defined)
2675 || (h->root.type == bfd_link_hash_defweak));
2676
2677 if (!_bfd_elfNN_link_record_local_dynamic_symbol
2678 (x->info, h->root.u.def.section->owner,
2679 global_sym_index (h)))
2680 return FALSE;
2681 }
2682
2683 dyn_i->want_fptr = 0;
2684 }
2685 else if (h == NULL || h->dynindx == -1)
2686 {
2687 dyn_i->fptr_offset = x->ofs;
2688 x->ofs += 16;
2689 }
2690 else
2691 dyn_i->want_fptr = 0;
2692 }
2693 return TRUE;
2694 }
2695
2696 /* Allocate all the minimal PLT entries. */
2697
2698 static bfd_boolean
2699 allocate_plt_entries (dyn_i, data)
2700 struct elfNN_ia64_dyn_sym_info *dyn_i;
2701 PTR data;
2702 {
2703 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2704
2705 if (dyn_i->want_plt)
2706 {
2707 struct elf_link_hash_entry *h = dyn_i->h;
2708
2709 if (h)
2710 while (h->root.type == bfd_link_hash_indirect
2711 || h->root.type == bfd_link_hash_warning)
2712 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2713
2714 /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT. */
2715 if (elfNN_ia64_dynamic_symbol_p (h, x->info))
2716 {
2717 bfd_size_type offset = x->ofs;
2718 if (offset == 0)
2719 offset = PLT_HEADER_SIZE;
2720 dyn_i->plt_offset = offset;
2721 x->ofs = offset + PLT_MIN_ENTRY_SIZE;
2722
2723 dyn_i->want_pltoff = 1;
2724 }
2725 else
2726 {
2727 dyn_i->want_plt = 0;
2728 dyn_i->want_plt2 = 0;
2729 }
2730 }
2731 return TRUE;
2732 }
2733
2734 /* Allocate all the full PLT entries. */
2735
2736 static bfd_boolean
2737 allocate_plt2_entries (dyn_i, data)
2738 struct elfNN_ia64_dyn_sym_info *dyn_i;
2739 PTR data;
2740 {
2741 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2742
2743 if (dyn_i->want_plt2)
2744 {
2745 struct elf_link_hash_entry *h = dyn_i->h;
2746 bfd_size_type ofs = x->ofs;
2747
2748 dyn_i->plt2_offset = ofs;
2749 x->ofs = ofs + PLT_FULL_ENTRY_SIZE;
2750
2751 while (h->root.type == bfd_link_hash_indirect
2752 || h->root.type == bfd_link_hash_warning)
2753 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2754 dyn_i->h->plt.offset = ofs;
2755 }
2756 return TRUE;
2757 }
2758
2759 /* Allocate all the PLTOFF entries requested by relocations and
2760 plt entries. We can't share space with allocated FPTR entries,
2761 because the latter are not necessarily addressable by the GP.
2762 ??? Relaxation might be able to determine that they are. */
2763
2764 static bfd_boolean
2765 allocate_pltoff_entries (dyn_i, data)
2766 struct elfNN_ia64_dyn_sym_info *dyn_i;
2767 PTR data;
2768 {
2769 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2770
2771 if (dyn_i->want_pltoff)
2772 {
2773 dyn_i->pltoff_offset = x->ofs;
2774 x->ofs += 16;
2775 }
2776 return TRUE;
2777 }
2778
2779 /* Allocate dynamic relocations for those symbols that turned out
2780 to be dynamic. */
2781
2782 static bfd_boolean
2783 allocate_dynrel_entries (dyn_i, data)
2784 struct elfNN_ia64_dyn_sym_info *dyn_i;
2785 PTR data;
2786 {
2787 struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
2788 struct elfNN_ia64_link_hash_table *ia64_info;
2789 struct elfNN_ia64_dyn_reloc_entry *rent;
2790 bfd_boolean dynamic_symbol, shared, resolved_zero;
2791
2792 ia64_info = elfNN_ia64_hash_table (x->info);
2793 dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info)
2794 || (elfNN_ia64_aix_vec (x->info->hash->creator)
2795 /* Don't allocate an entry for __GLOB_DATA_PTR */
2796 && (!dyn_i->h || strcmp (dyn_i->h->root.root.string,
2797 "__GLOB_DATA_PTR") != 0));
2798 shared = x->info->shared;
2799 resolved_zero = (dyn_i->h
2800 && ELF_ST_VISIBILITY (dyn_i->h->other)
2801 && dyn_i->h->root.type == bfd_link_hash_undefweak);
2802
2803 /* Take care of the normal data relocations. */
2804
2805 for (rent = dyn_i->reloc_entries; rent; rent = rent->next)
2806 {
2807 int count = rent->count;
2808
2809 switch (rent->type)
2810 {
2811 case R_IA64_FPTR64LSB:
2812 /* Allocate one iff !want_fptr and not PIE, which by this point
2813 will be true only if we're actually allocating one statically
2814 in the main executable. Position independent executables
2815 need a relative reloc. */
2816 if (dyn_i->want_fptr && !x->info->pie)
2817 continue;
2818 break;
2819 case R_IA64_PCREL64LSB:
2820 if (!dynamic_symbol)
2821 continue;
2822 break;
2823 case R_IA64_DIR64LSB:
2824 if (!dynamic_symbol && !shared)
2825 continue;
2826 break;
2827 case R_IA64_IPLTLSB:
2828 if (!dynamic_symbol && !shared)
2829 continue;
2830 /* Use two REL relocations for IPLT relocations
2831 against local symbols. */
2832 if (!dynamic_symbol)
2833 count *= 2;
2834 break;
2835 case R_IA64_TPREL64LSB:
2836 case R_IA64_DTPREL64LSB:
2837 case R_IA64_DTPMOD64LSB:
2838 break;
2839 default:
2840 abort ();
2841 }
2842 rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * count;
2843 }
2844
2845 /* Take care of the GOT and PLT relocations. */
2846
2847 if ((!resolved_zero
2848 && (dynamic_symbol || shared)
2849 && (dyn_i->want_got || dyn_i->want_gotx))
2850 || (dyn_i->want_ltoff_fptr
2851 && dyn_i->h
2852 && dyn_i->h->dynindx != -1))
2853 {
2854 if (!dyn_i->want_ltoff_fptr
2855 || !x->info->pie
2856 || dyn_i->h == NULL
2857 || dyn_i->h->root.type != bfd_link_hash_undefweak)
2858 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2859 }
2860 if ((dynamic_symbol || shared) && dyn_i->want_tprel)
2861 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2862 if (dynamic_symbol && dyn_i->want_dtpmod)
2863 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2864 if (dynamic_symbol && dyn_i->want_dtprel)
2865 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
2866 if (ia64_info->rel_fptr_sec && dyn_i->want_fptr)
2867 {
2868 if (dyn_i->h == NULL || dyn_i->h->root.type != bfd_link_hash_undefweak)
2869 ia64_info->rel_fptr_sec->_raw_size += sizeof (ElfNN_External_Rela);
2870 }
2871
2872 if (!resolved_zero && dyn_i->want_pltoff)
2873 {
2874 bfd_size_type t = 0;
2875
2876 /* Dynamic symbols get one IPLT relocation. Local symbols in
2877 shared libraries get two REL relocations. Local symbols in
2878 main applications get nothing. */
2879 if (dynamic_symbol)
2880 t = sizeof (ElfNN_External_Rela);
2881 else if (shared)
2882 t = 2 * sizeof (ElfNN_External_Rela);
2883
2884 ia64_info->rel_pltoff_sec->_raw_size += t;
2885 }
2886
2887 return TRUE;
2888 }
2889
2890 static bfd_boolean
2891 elfNN_ia64_adjust_dynamic_symbol (info, h)
2892 struct bfd_link_info *info ATTRIBUTE_UNUSED;
2893 struct elf_link_hash_entry *h;
2894 {
2895 /* ??? Undefined symbols with PLT entries should be re-defined
2896 to be the PLT entry. */
2897
2898 /* If this is a weak symbol, and there is a real definition, the
2899 processor independent code will have arranged for us to see the
2900 real definition first, and we can just use the same value. */
2901 if (h->weakdef != NULL)
2902 {
2903 BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
2904 || h->weakdef->root.type == bfd_link_hash_defweak);
2905 h->root.u.def.section = h->weakdef->root.u.def.section;
2906 h->root.u.def.value = h->weakdef->root.u.def.value;
2907 return TRUE;
2908 }
2909
2910 /* If this is a reference to a symbol defined by a dynamic object which
2911 is not a function, we might allocate the symbol in our .dynbss section
2912 and allocate a COPY dynamic relocation.
2913
2914 But IA-64 code is canonically PIC, so as a rule we can avoid this sort
2915 of hackery. */
2916
2917 return TRUE;
2918 }
2919
2920 static bfd_boolean
2921 elfNN_ia64_size_dynamic_sections (output_bfd, info)
2922 bfd *output_bfd;
2923 struct bfd_link_info *info;
2924 {
2925 struct elfNN_ia64_allocate_data data;
2926 struct elfNN_ia64_link_hash_table *ia64_info;
2927 asection *sec;
2928 bfd *dynobj;
2929 bfd_boolean relplt = FALSE;
2930
2931 dynobj = elf_hash_table(info)->dynobj;
2932 ia64_info = elfNN_ia64_hash_table (info);
2933 ia64_info->self_dtpmod_offset = (bfd_vma) -1;
2934 BFD_ASSERT(dynobj != NULL);
2935 data.info = info;
2936
2937 /* Set the contents of the .interp section to the interpreter. */
2938 if (ia64_info->root.dynamic_sections_created
2939 && info->executable)
2940 {
2941 sec = bfd_get_section_by_name (dynobj, ".interp");
2942 BFD_ASSERT (sec != NULL);
2943 sec->contents = (bfd_byte *) DYNAMIC_INTERPRETER (output_bfd);
2944 sec->_raw_size = strlen (DYNAMIC_INTERPRETER (output_bfd)) + 1;
2945 }
2946
2947 /* Allocate the GOT entries. */
2948
2949 if (ia64_info->got_sec)
2950 {
2951 data.ofs = 0;
2952 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_data_got, &data);
2953 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_global_fptr_got, &data);
2954 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_local_got, &data);
2955 ia64_info->got_sec->_raw_size = data.ofs;
2956 }
2957
2958 /* Allocate the FPTR entries. */
2959
2960 if (ia64_info->fptr_sec)
2961 {
2962 data.ofs = 0;
2963 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_fptr, &data);
2964 ia64_info->fptr_sec->_raw_size = data.ofs;
2965 }
2966
2967 /* Now that we've seen all of the input files, we can decide which
2968 symbols need plt entries. Allocate the minimal PLT entries first.
2969 We do this even though dynamic_sections_created may be FALSE, because
2970 this has the side-effect of clearing want_plt and want_plt2. */
2971
2972 data.ofs = 0;
2973 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt_entries, &data);
2974
2975 ia64_info->minplt_entries = 0;
2976 if (data.ofs)
2977 {
2978 ia64_info->minplt_entries
2979 = (data.ofs - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
2980 }
2981
2982 /* Align the pointer for the plt2 entries. */
2983 data.ofs = (data.ofs + 31) & (bfd_vma) -32;
2984
2985 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
2986 if (data.ofs != 0)
2987 {
2988 BFD_ASSERT (ia64_info->root.dynamic_sections_created);
2989
2990 ia64_info->plt_sec->_raw_size = data.ofs;
2991
2992 /* If we've got a .plt, we need some extra memory for the dynamic
2993 linker. We stuff these in .got.plt. */
2994 sec = bfd_get_section_by_name (dynobj, ".got.plt");
2995 sec->_raw_size = 8 * PLT_RESERVED_WORDS;
2996 }
2997
2998 /* Allocate the PLTOFF entries. */
2999
3000 if (ia64_info->pltoff_sec)
3001 {
3002 data.ofs = 0;
3003 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_pltoff_entries, &data);
3004 ia64_info->pltoff_sec->_raw_size = data.ofs;
3005 }
3006
3007 if (ia64_info->root.dynamic_sections_created)
3008 {
3009 /* Allocate space for the dynamic relocations that turned out to be
3010 required. */
3011
3012 if (info->shared && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
3013 ia64_info->rel_got_sec->_raw_size += sizeof (ElfNN_External_Rela);
3014 elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
3015 }
3016
3017 /* We have now determined the sizes of the various dynamic sections.
3018 Allocate memory for them. */
3019 for (sec = dynobj->sections; sec != NULL; sec = sec->next)
3020 {
3021 bfd_boolean strip;
3022
3023 if (!(sec->flags & SEC_LINKER_CREATED))
3024 continue;
3025
3026 /* If we don't need this section, strip it from the output file.
3027 There were several sections primarily related to dynamic
3028 linking that must be create before the linker maps input
3029 sections to output sections. The linker does that before
3030 bfd_elf_size_dynamic_sections is called, and it is that
3031 function which decides whether anything needs to go into
3032 these sections. */
3033
3034 strip = (sec->_raw_size == 0);
3035
3036 if (sec == ia64_info->got_sec)
3037 strip = FALSE;
3038 else if (sec == ia64_info->rel_got_sec)
3039 {
3040 if (strip)
3041 ia64_info->rel_got_sec = NULL;
3042 else
3043 /* We use the reloc_count field as a counter if we need to
3044 copy relocs into the output file. */
3045 sec->reloc_count = 0;
3046 }
3047 else if (sec == ia64_info->fptr_sec)
3048 {
3049 if (strip)
3050 ia64_info->fptr_sec = NULL;
3051 }
3052 else if (sec == ia64_info->plt_sec)
3053 {
3054 if (strip)
3055 ia64_info->plt_sec = NULL;
3056 }
3057 else if (sec == ia64_info->pltoff_sec)
3058 {
3059 if (strip)
3060 ia64_info->pltoff_sec = NULL;
3061 }
3062 else if (sec == ia64_info->rel_pltoff_sec)
3063 {
3064 if (strip)
3065 ia64_info->rel_pltoff_sec = NULL;
3066 else
3067 {
3068 relplt = TRUE;
3069 /* We use the reloc_count field as a counter if we need to
3070 copy relocs into the output file. */
3071 sec->reloc_count = 0;
3072 }
3073 }
3074 else
3075 {
3076 const char *name;
3077
3078 /* It's OK to base decisions on the section name, because none
3079 of the dynobj section names depend upon the input files. */
3080 name = bfd_get_section_name (dynobj, sec);
3081
3082 if (strcmp (name, ".got.plt") == 0)
3083 strip = FALSE;
3084 else if (strncmp (name, ".rel", 4) == 0)
3085 {
3086 if (!strip)
3087 {
3088 /* We use the reloc_count field as a counter if we need to
3089 copy relocs into the output file. */
3090 sec->reloc_count = 0;
3091 }
3092 }
3093 else
3094 continue;
3095 }
3096
3097 if (strip)
3098 _bfd_strip_section_from_output (info, sec);
3099 else
3100 {
3101 /* Allocate memory for the section contents. */
3102 sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->_raw_size);
3103 if (sec->contents == NULL && sec->_raw_size != 0)
3104 return FALSE;
3105 }
3106 }
3107
3108 if (elf_hash_table (info)->dynamic_sections_created)
3109 {
3110 /* Add some entries to the .dynamic section. We fill in the values
3111 later (in finish_dynamic_sections) but we must add the entries now
3112 so that we get the correct size for the .dynamic section. */
3113
3114 if (info->executable)
3115 {
3116 /* The DT_DEBUG entry is filled in by the dynamic linker and used
3117 by the debugger. */
3118 #define add_dynamic_entry(TAG, VAL) \
3119 bfd_elfNN_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
3120
3121 if (!add_dynamic_entry (DT_DEBUG, 0))
3122 return FALSE;
3123 }
3124
3125 if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
3126 return FALSE;
3127 if (!add_dynamic_entry (DT_PLTGOT, 0))
3128 return FALSE;
3129
3130 if (relplt)
3131 {
3132 if (!add_dynamic_entry (DT_PLTRELSZ, 0)
3133 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3134 || !add_dynamic_entry (DT_JMPREL, 0))
3135 return FALSE;
3136 }
3137
3138 if (!add_dynamic_entry (DT_RELA, 0)
3139 || !add_dynamic_entry (DT_RELASZ, 0)
3140 || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
3141 return FALSE;
3142
3143 if (ia64_info->reltext)
3144 {
3145 if (!add_dynamic_entry (DT_TEXTREL, 0))
3146 return FALSE;
3147 info->flags |= DF_TEXTREL;
3148 }
3149 }
3150
3151 /* ??? Perhaps force __gp local. */
3152
3153 return TRUE;
3154 }
3155
3156 static bfd_reloc_status_type
3157 elfNN_ia64_install_value (abfd, hit_addr, v, r_type)
3158 bfd *abfd;
3159 bfd_byte *hit_addr;
3160 bfd_vma v;
3161 unsigned int r_type;
3162 {
3163 const struct ia64_operand *op;
3164 int bigendian = 0, shift = 0;
3165 bfd_vma t0, t1, insn, dword;
3166 enum ia64_opnd opnd;
3167 const char *err;
3168 size_t size = 8;
3169 #ifdef BFD_HOST_U_64_BIT
3170 BFD_HOST_U_64_BIT val = (BFD_HOST_U_64_BIT) v;
3171 #else
3172 bfd_vma val = v;
3173 #endif
3174
3175 opnd = IA64_OPND_NIL;
3176 switch (r_type)
3177 {
3178 case R_IA64_NONE:
3179 case R_IA64_LDXMOV:
3180 return bfd_reloc_ok;
3181
3182 /* Instruction relocations. */
3183
3184 case R_IA64_IMM14:
3185 case R_IA64_TPREL14:
3186 case R_IA64_DTPREL14:
3187 opnd = IA64_OPND_IMM14;
3188 break;
3189
3190 case R_IA64_PCREL21F: opnd = IA64_OPND_TGT25; break;
3191 case R_IA64_PCREL21M: opnd = IA64_OPND_TGT25b; break;
3192 case R_IA64_PCREL60B: opnd = IA64_OPND_TGT64; break;
3193 case R_IA64_PCREL21B:
3194 case R_IA64_PCREL21BI:
3195 opnd = IA64_OPND_TGT25c;
3196 break;
3197
3198 case R_IA64_IMM22:
3199 case R_IA64_GPREL22:
3200 case R_IA64_LTOFF22:
3201 case R_IA64_LTOFF22X:
3202 case R_IA64_PLTOFF22:
3203 case R_IA64_PCREL22:
3204 case R_IA64_LTOFF_FPTR22:
3205 case R_IA64_TPREL22:
3206 case R_IA64_DTPREL22:
3207 case R_IA64_LTOFF_TPREL22:
3208 case R_IA64_LTOFF_DTPMOD22:
3209 case R_IA64_LTOFF_DTPREL22:
3210 opnd = IA64_OPND_IMM22;
3211 break;
3212
3213 case R_IA64_IMM64:
3214 case R_IA64_GPREL64I:
3215 case R_IA64_LTOFF64I:
3216 case R_IA64_PLTOFF64I:
3217 case R_IA64_PCREL64I:
3218 case R_IA64_FPTR64I:
3219 case R_IA64_LTOFF_FPTR64I:
3220 case R_IA64_TPREL64I:
3221 case R_IA64_DTPREL64I:
3222 opnd = IA64_OPND_IMMU64;
3223 break;
3224
3225 /* Data relocations. */
3226
3227 case R_IA64_DIR32MSB:
3228 case R_IA64_GPREL32MSB:
3229 case R_IA64_FPTR32MSB:
3230 case R_IA64_PCREL32MSB:
3231 case R_IA64_LTOFF_FPTR32MSB:
3232 case R_IA64_SEGREL32MSB:
3233 case R_IA64_SECREL32MSB:
3234 case R_IA64_LTV32MSB:
3235 case R_IA64_DTPREL32MSB:
3236 size = 4; bigendian = 1;
3237 break;
3238
3239 case R_IA64_DIR32LSB:
3240 case R_IA64_GPREL32LSB:
3241 case R_IA64_FPTR32LSB:
3242 case R_IA64_PCREL32LSB:
3243 case R_IA64_LTOFF_FPTR32LSB:
3244 case R_IA64_SEGREL32LSB:
3245 case R_IA64_SECREL32LSB:
3246 case R_IA64_LTV32LSB:
3247 case R_IA64_DTPREL32LSB:
3248 size = 4; bigendian = 0;
3249 break;
3250
3251 case R_IA64_DIR64MSB:
3252 case R_IA64_GPREL64MSB:
3253 case R_IA64_PLTOFF64MSB:
3254 case R_IA64_FPTR64MSB:
3255 case R_IA64_PCREL64MSB:
3256 case R_IA64_LTOFF_FPTR64MSB:
3257 case R_IA64_SEGREL64MSB:
3258 case R_IA64_SECREL64MSB:
3259 case R_IA64_LTV64MSB:
3260 case R_IA64_TPREL64MSB:
3261 case R_IA64_DTPMOD64MSB:
3262 case R_IA64_DTPREL64MSB:
3263 size = 8; bigendian = 1;
3264 break;
3265
3266 case R_IA64_DIR64LSB:
3267 case R_IA64_GPREL64LSB:
3268 case R_IA64_PLTOFF64LSB:
3269 case R_IA64_FPTR64LSB:
3270 case R_IA64_PCREL64LSB:
3271 case R_IA64_LTOFF_FPTR64LSB:
3272 case R_IA64_SEGREL64LSB:
3273 case R_IA64_SECREL64LSB:
3274 case R_IA64_LTV64LSB:
3275 case R_IA64_TPREL64LSB:
3276 case R_IA64_DTPMOD64LSB:
3277 case R_IA64_DTPREL64LSB:
3278 size = 8; bigendian = 0;
3279 break;
3280
3281 /* Unsupported / Dynamic relocations. */
3282 default:
3283 return bfd_reloc_notsupported;
3284 }
3285
3286 switch (opnd)
3287 {
3288 case IA64_OPND_IMMU64:
3289 hit_addr -= (long) hit_addr & 0x3;
3290 t0 = bfd_get_64 (abfd, hit_addr);
3291 t1 = bfd_get_64 (abfd, hit_addr + 8);
3292
3293 /* tmpl/s: bits 0.. 5 in t0
3294 slot 0: bits 5..45 in t0
3295 slot 1: bits 46..63 in t0, bits 0..22 in t1
3296 slot 2: bits 23..63 in t1 */
3297
3298 /* First, clear the bits that form the 64 bit constant. */
3299 t0 &= ~(0x3ffffLL << 46);
3300 t1 &= ~(0x7fffffLL
3301 | (( (0x07fLL << 13) | (0x1ffLL << 27)
3302 | (0x01fLL << 22) | (0x001LL << 21)
3303 | (0x001LL << 36)) << 23));
3304
3305 t0 |= ((val >> 22) & 0x03ffffLL) << 46; /* 18 lsbs of imm41 */
3306 t1 |= ((val >> 40) & 0x7fffffLL) << 0; /* 23 msbs of imm41 */
3307 t1 |= ( (((val >> 0) & 0x07f) << 13) /* imm7b */
3308 | (((val >> 7) & 0x1ff) << 27) /* imm9d */
3309 | (((val >> 16) & 0x01f) << 22) /* imm5c */
3310 | (((val >> 21) & 0x001) << 21) /* ic */
3311 | (((val >> 63) & 0x001) << 36)) << 23; /* i */
3312
3313 bfd_put_64 (abfd, t0, hit_addr);
3314 bfd_put_64 (abfd, t1, hit_addr + 8);
3315 break;
3316
3317 case IA64_OPND_TGT64:
3318 hit_addr -= (long) hit_addr & 0x3;
3319 t0 = bfd_get_64 (abfd, hit_addr);
3320 t1 = bfd_get_64 (abfd, hit_addr + 8);
3321
3322 /* tmpl/s: bits 0.. 5 in t0
3323 slot 0: bits 5..45 in t0
3324 slot 1: bits 46..63 in t0, bits 0..22 in t1
3325 slot 2: bits 23..63 in t1 */
3326
3327 /* First, clear the bits that form the 64 bit constant. */
3328 t0 &= ~(0x3ffffLL << 46);
3329 t1 &= ~(0x7fffffLL
3330 | ((1LL << 36 | 0xfffffLL << 13) << 23));
3331
3332 val >>= 4;
3333 t0 |= ((val >> 20) & 0xffffLL) << 2 << 46; /* 16 lsbs of imm39 */
3334 t1 |= ((val >> 36) & 0x7fffffLL) << 0; /* 23 msbs of imm39 */
3335 t1 |= ((((val >> 0) & 0xfffffLL) << 13) /* imm20b */
3336 | (((val >> 59) & 0x1LL) << 36)) << 23; /* i */
3337
3338 bfd_put_64 (abfd, t0, hit_addr);
3339 bfd_put_64 (abfd, t1, hit_addr + 8);
3340 break;
3341
3342 default:
3343 switch ((long) hit_addr & 0x3)
3344 {
3345 case 0: shift = 5; break;
3346 case 1: shift = 14; hit_addr += 3; break;
3347 case 2: shift = 23; hit_addr += 6; break;
3348 case 3: return bfd_reloc_notsupported; /* shouldn't happen... */
3349 }
3350 dword = bfd_get_64 (abfd, hit_addr);
3351 insn = (dword >> shift) & 0x1ffffffffffLL;
3352
3353 op = elf64_ia64_operands + opnd;
3354 err = (*op->insert) (op, val, (ia64_insn *)& insn);
3355 if (err)
3356 return bfd_reloc_overflow;
3357
3358 dword &= ~(0x1ffffffffffLL << shift);
3359 dword |= (insn << shift);
3360 bfd_put_64 (abfd, dword, hit_addr);
3361 break;
3362
3363 case IA64_OPND_NIL:
3364 /* A data relocation. */
3365 if (bigendian)
3366 if (size == 4)
3367 bfd_putb32 (val, hit_addr);
3368 else
3369 bfd_putb64 (val, hit_addr);
3370 else
3371 if (size == 4)
3372 bfd_putl32 (val, hit_addr);
3373 else
3374 bfd_putl64 (val, hit_addr);
3375 break;
3376 }
3377
3378 return bfd_reloc_ok;
3379 }
3380
3381 static void
3382 elfNN_ia64_install_dyn_reloc (abfd, info, sec, srel, offset, type,
3383 dynindx, addend)
3384 bfd *abfd;
3385 struct bfd_link_info *info;
3386 asection *sec;
3387 asection *srel;
3388 bfd_vma offset;
3389 unsigned int type;
3390 long dynindx;
3391 bfd_vma addend;
3392 {
3393 Elf_Internal_Rela outrel;
3394 bfd_byte *loc;
3395
3396 BFD_ASSERT (dynindx != -1);
3397 outrel.r_info = ELFNN_R_INFO (dynindx, type);
3398 outrel.r_addend = addend;
3399 outrel.r_offset = _bfd_elf_section_offset (abfd, info, sec, offset);
3400 if (outrel.r_offset >= (bfd_vma) -2)
3401 {
3402 /* Run for the hills. We shouldn't be outputting a relocation
3403 for this. So do what everyone else does and output a no-op. */
3404 outrel.r_info = ELFNN_R_INFO (0, R_IA64_NONE);
3405 outrel.r_addend = 0;
3406 outrel.r_offset = 0;
3407 }
3408 else
3409 outrel.r_offset += sec->output_section->vma + sec->output_offset;
3410
3411 loc = srel->contents;
3412 loc += srel->reloc_count++ * sizeof (ElfNN_External_Rela);
3413 bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3414 BFD_ASSERT (sizeof (ElfNN_External_Rela) * srel->reloc_count
3415 <= srel->_cooked_size);
3416 }
3417
3418 /* Store an entry for target address TARGET_ADDR in the linkage table
3419 and return the gp-relative address of the linkage table entry. */
3420
3421 static bfd_vma
3422 set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
3423 bfd *abfd;
3424 struct bfd_link_info *info;
3425 struct elfNN_ia64_dyn_sym_info *dyn_i;
3426 long dynindx;
3427 bfd_vma addend;
3428 bfd_vma value;
3429 unsigned int dyn_r_type;
3430 {
3431 struct elfNN_ia64_link_hash_table *ia64_info;
3432 asection *got_sec;
3433 bfd_boolean done;
3434 bfd_vma got_offset;
3435
3436 ia64_info = elfNN_ia64_hash_table (info);
3437 got_sec = ia64_info->got_sec;
3438
3439 switch (dyn_r_type)
3440 {
3441 case R_IA64_TPREL64LSB:
3442 done = dyn_i->tprel_done;
3443 dyn_i->tprel_done = TRUE;
3444 got_offset = dyn_i->tprel_offset;
3445 break;
3446 case R_IA64_DTPMOD64LSB:
3447 if (dyn_i->dtpmod_offset != ia64_info->self_dtpmod_offset)
3448 {
3449 done = dyn_i->dtpmod_done;
3450 dyn_i->dtpmod_done = TRUE;
3451 }
3452 else
3453 {
3454 done = ia64_info->self_dtpmod_done;
3455 ia64_info->self_dtpmod_done = TRUE;
3456 dynindx = 0;
3457 }
3458 got_offset = dyn_i->dtpmod_offset;
3459 break;
3460 case R_IA64_DTPREL64LSB:
3461 done = dyn_i->dtprel_done;
3462 dyn_i->dtprel_done = TRUE;
3463 got_offset = dyn_i->dtprel_offset;
3464 break;
3465 default:
3466 done = dyn_i->got_done;
3467 dyn_i->got_done = TRUE;
3468 got_offset = dyn_i->got_offset;
3469 break;
3470 }
3471
3472 BFD_ASSERT ((got_offset & 7) == 0);
3473
3474 if (! done)
3475 {
3476 /* Store the target address in the linkage table entry. */
3477 bfd_put_64 (abfd, value, got_sec->contents + got_offset);
3478
3479 /* Install a dynamic relocation if needed. */
3480 if (((info->shared
3481 && (!dyn_i->h
3482 || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
3483 || dyn_i->h->root.type != bfd_link_hash_undefweak)
3484 && dyn_r_type != R_IA64_DTPREL64LSB)
3485 || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info)
3486 || elfNN_ia64_aix_vec (abfd->xvec)
3487 || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
3488 && (!dyn_i->want_ltoff_fptr
3489 || !info->pie
3490 || !dyn_i->h
3491 || dyn_i->h->root.type != bfd_link_hash_undefweak))
3492 {
3493 if (dynindx == -1
3494 && dyn_r_type != R_IA64_TPREL64LSB
3495 && dyn_r_type != R_IA64_DTPMOD64LSB
3496 && dyn_r_type != R_IA64_DTPREL64LSB)
3497 {
3498 dyn_r_type = R_IA64_REL64LSB;
3499 dynindx = 0;
3500 addend = value;
3501 }
3502
3503 if (bfd_big_endian (abfd))
3504 {
3505 switch (dyn_r_type)
3506 {
3507 case R_IA64_REL64LSB:
3508 dyn_r_type = R_IA64_REL64MSB;
3509 break;
3510 case R_IA64_DIR64LSB:
3511 dyn_r_type = R_IA64_DIR64MSB;
3512 break;
3513 case R_IA64_FPTR64LSB:
3514 dyn_r_type = R_IA64_FPTR64MSB;
3515 break;
3516 case R_IA64_TPREL64LSB:
3517 dyn_r_type = R_IA64_TPREL64MSB;
3518 break;
3519 case R_IA64_DTPMOD64LSB:
3520 dyn_r_type = R_IA64_DTPMOD64MSB;
3521 break;
3522 case R_IA64_DTPREL64LSB:
3523 dyn_r_type = R_IA64_DTPREL64MSB;
3524 break;
3525 default:
3526 BFD_ASSERT (FALSE);
3527 break;
3528 }
3529 }
3530
3531 elfNN_ia64_install_dyn_reloc (abfd, NULL, got_sec,
3532 ia64_info->rel_got_sec,
3533 got_offset, dyn_r_type,
3534 dynindx, addend);
3535 }
3536 }
3537
3538 /* Return the address of the linkage table entry. */
3539 value = (got_sec->output_section->vma
3540 + got_sec->output_offset
3541 + got_offset);
3542
3543 return value;
3544 }
3545
3546 /* Fill in a function descriptor consisting of the function's code
3547 address and its global pointer. Return the descriptor's address. */
3548
3549 static bfd_vma
3550 set_fptr_entry (abfd, info, dyn_i, value)
3551 bfd *abfd;
3552 struct bfd_link_info *info;
3553 struct elfNN_ia64_dyn_sym_info *dyn_i;
3554 bfd_vma value;
3555 {
3556 struct elfNN_ia64_link_hash_table *ia64_info;
3557 asection *fptr_sec;
3558
3559 ia64_info = elfNN_ia64_hash_table (info);
3560 fptr_sec = ia64_info->fptr_sec;
3561
3562 if (!dyn_i->fptr_done)
3563 {
3564 dyn_i->fptr_done = 1;
3565
3566 /* Fill in the function descriptor. */
3567 bfd_put_64 (abfd, value, fptr_sec->contents + dyn_i->fptr_offset);
3568 bfd_put_64 (abfd, _bfd_get_gp_value (abfd),
3569 fptr_sec->contents + dyn_i->fptr_offset + 8);
3570 if (ia64_info->rel_fptr_sec)
3571 {
3572 Elf_Internal_Rela outrel;
3573 bfd_byte *loc;
3574
3575 if (bfd_little_endian (abfd))
3576 outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTLSB);
3577 else
3578 outrel.r_info = ELFNN_R_INFO (0, R_IA64_IPLTMSB);
3579 outrel.r_addend = value;
3580 outrel.r_offset = (fptr_sec->output_section->vma
3581 + fptr_sec->output_offset
3582 + dyn_i->fptr_offset);
3583 loc = ia64_info->rel_fptr_sec->contents;
3584 loc += ia64_info->rel_fptr_sec->reloc_count++
3585 * sizeof (ElfNN_External_Rela);
3586 bfd_elfNN_swap_reloca_out (abfd, &outrel, loc);
3587 }
3588 }
3589
3590 /* Return the descriptor's address. */
3591 value = (fptr_sec->output_section->vma
3592 + fptr_sec->output_offset
3593 + dyn_i->fptr_offset);
3594
3595 return value;
3596 }
3597
3598 /* Fill in a PLTOFF entry consisting of the function's code address
3599 and its global pointer. Return the descriptor's address. */
3600
3601 static bfd_vma
3602 set_pltoff_entry (abfd, info, dyn_i, value, is_plt)
3603 bfd *abfd;
3604 struct bfd_link_info *info;
3605 struct elfNN_ia64_dyn_sym_info *dyn_i;
3606 bfd_vma value;
3607 bfd_boolean is_plt;
3608 {
3609 struct elfNN_ia64_link_hash_table *ia64_info;
3610 asection *pltoff_sec;
3611
3612 ia64_info = elfNN_ia64_hash_table (info);
3613 pltoff_sec = ia64_info->pltoff_sec;
3614
3615 /* Don't do anything if this symbol uses a real PLT entry. In
3616 that case, we'll fill this in during finish_dynamic_symbol. */
3617 if ((! dyn_i->want_plt || is_plt)
3618 && !dyn_i->pltoff_done)
3619 {
3620 bfd_vma gp = _bfd_get_gp_value (abfd);
3621
3622 /* Fill in the function descriptor. */
3623 bfd_put_64 (abfd, value, pltoff_sec->contents + dyn_i->pltoff_offset);
3624 bfd_put_64 (abfd, gp, pltoff_sec->contents + dyn_i->pltoff_offset + 8);
3625
3626 /* Install dynamic relocations if needed. */
3627 if (!is_plt
3628 && info->shared
3629 && (!dyn_i->h
3630 || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
3631 || dyn_i->h->root.type != bfd_link_hash_undefweak))
3632 {
3633 unsigned int dyn_r_type;
3634
3635 if (bfd_big_endian (abfd))
3636 dyn_r_type = R_IA64_REL64MSB;
3637 else
3638 dyn_r_type = R_IA64_REL64LSB;
3639
3640 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3641 ia64_info->rel_pltoff_sec,
3642 dyn_i->pltoff_offset,
3643 dyn_r_type, 0, value);
3644 elfNN_ia64_install_dyn_reloc (abfd, NULL, pltoff_sec,
3645 ia64_info->rel_pltoff_sec,
3646 dyn_i->pltoff_offset + 8,
3647 dyn_r_type, 0, gp);
3648 }
3649
3650 dyn_i->pltoff_done = 1;
3651 }
3652
3653 /* Return the descriptor's address. */
3654 value = (pltoff_sec->output_section->vma
3655 + pltoff_sec->output_offset
3656 + dyn_i->pltoff_offset);
3657
3658 return value;
3659 }
3660
3661 /* Return the base VMA address which should be subtracted from real addresses
3662 when resolving @tprel() relocation.
3663 Main program TLS (whose template starts at PT_TLS p_vaddr)
3664 is assigned offset round(16, PT_TLS p_align). */
3665
3666 static bfd_vma
3667 elfNN_ia64_tprel_base (info)
3668 struct bfd_link_info *info;
3669 {
3670 struct elf_link_tls_segment *tls_segment
3671 = elf_hash_table (info)->tls_segment;
3672
3673 BFD_ASSERT (tls_segment != NULL);
3674 return (tls_segment->start
3675 - align_power ((bfd_vma) 16, tls_segment->align));
3676 }
3677
3678 /* Return the base VMA address which should be subtracted from real addresses
3679 when resolving @dtprel() relocation.
3680 This is PT_TLS segment p_vaddr. */
3681
3682 static bfd_vma
3683 elfNN_ia64_dtprel_base (info)
3684 struct bfd_link_info *info;
3685 {
3686 BFD_ASSERT (elf_hash_table (info)->tls_segment != NULL);
3687 return elf_hash_table (info)->tls_segment->start;
3688 }
3689
3690 /* Called through qsort to sort the .IA_64.unwind section during a
3691 non-relocatable link. Set elfNN_ia64_unwind_entry_compare_bfd
3692 to the output bfd so we can do proper endianness frobbing. */
3693
3694 static bfd *elfNN_ia64_unwind_entry_compare_bfd;
3695
3696 static int
3697 elfNN_ia64_unwind_entry_compare (a, b)
3698 const PTR a;
3699 const PTR b;
3700 {
3701 bfd_vma av, bv;
3702
3703 av = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, a);
3704 bv = bfd_get_64 (elfNN_ia64_unwind_entry_compare_bfd, b);
3705
3706 return (av < bv ? -1 : av > bv ? 1 : 0);
3707 }
3708
3709 /* Make sure we've got ourselves a nice fat __gp value. */
3710 static bfd_boolean
3711 elfNN_ia64_choose_gp (abfd, info)
3712 bfd *abfd;
3713 struct bfd_link_info *info;
3714 {
3715 bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
3716 bfd_vma min_short_vma = min_vma, max_short_vma = 0;
3717 struct elf_link_hash_entry *gp;
3718 bfd_vma gp_val;
3719 asection *os;
3720 struct elfNN_ia64_link_hash_table *ia64_info;
3721
3722 ia64_info = elfNN_ia64_hash_table (info);
3723
3724 /* Find the min and max vma of all sections marked short. Also collect
3725 min and max vma of any type, for use in selecting a nice gp. */
3726 for (os = abfd->sections; os ; os = os->next)
3727 {
3728 bfd_vma lo, hi;
3729
3730 if ((os->flags & SEC_ALLOC) == 0)
3731 continue;
3732
3733 lo = os->vma;
3734 hi = os->vma + os->_raw_size;
3735 if (hi < lo)
3736 hi = (bfd_vma) -1;
3737
3738 if (min_vma > lo)
3739 min_vma = lo;
3740 if (max_vma < hi)
3741 max_vma = hi;
3742 if (os->flags & SEC_SMALL_DATA)
3743 {
3744 if (min_short_vma > lo)
3745 min_short_vma = lo;
3746 if (max_short_vma < hi)
3747 max_short_vma = hi;
3748 }
3749 }
3750
3751 /* See if the user wants to force a value. */
3752 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3753 FALSE, FALSE);
3754
3755 if (gp
3756 && (gp->root.type == bfd_link_hash_defined
3757 || gp->root.type == bfd_link_hash_defweak))
3758 {
3759 asection *gp_sec = gp->root.u.def.section;
3760 gp_val = (gp->root.u.def.value
3761 + gp_sec->output_section->vma
3762 + gp_sec->output_offset);
3763 }
3764 else
3765 {
3766 /* Pick a sensible value. */
3767
3768 asection *got_sec = ia64_info->got_sec;
3769
3770 /* Start with just the address of the .got. */
3771 if (got_sec)
3772 gp_val = got_sec->output_section->vma;
3773 else if (max_short_vma != 0)
3774 gp_val = min_short_vma;
3775 else
3776 gp_val = min_vma;
3777
3778 /* If it is possible to address the entire image, but we
3779 don't with the choice above, adjust. */
3780 if (max_vma - min_vma < 0x400000
3781 && max_vma - gp_val <= 0x200000
3782 && gp_val - min_vma > 0x200000)
3783 gp_val = min_vma + 0x200000;
3784 else if (max_short_vma != 0)
3785 {
3786 /* If we don't cover all the short data, adjust. */
3787 if (max_short_vma - gp_val >= 0x200000)
3788 gp_val = min_short_vma + 0x200000;
3789
3790 /* If we're addressing stuff past the end, adjust back. */
3791 if (gp_val > max_vma)
3792 gp_val = max_vma - 0x200000 + 8;
3793 }
3794 }
3795
3796 /* Validate whether all SHF_IA_64_SHORT sections are within
3797 range of the chosen GP. */
3798
3799 if (max_short_vma != 0)
3800 {
3801 if (max_short_vma - min_short_vma >= 0x400000)
3802 {
3803 (*_bfd_error_handler)
3804 (_("%s: short data segment overflowed (0x%lx >= 0x400000)"),
3805 bfd_get_filename (abfd),
3806 (unsigned long) (max_short_vma - min_short_vma));
3807 return FALSE;
3808 }
3809 else if ((gp_val > min_short_vma
3810 && gp_val - min_short_vma > 0x200000)
3811 || (gp_val < max_short_vma
3812 && max_short_vma - gp_val >= 0x200000))
3813 {
3814 (*_bfd_error_handler)
3815 (_("%s: __gp does not cover short data segment"),
3816 bfd_get_filename (abfd));
3817 return FALSE;
3818 }
3819 }
3820
3821 _bfd_set_gp_value (abfd, gp_val);
3822
3823 return TRUE;
3824 }
3825
3826 static bfd_boolean
3827 elfNN_ia64_final_link (abfd, info)
3828 bfd *abfd;
3829 struct bfd_link_info *info;
3830 {
3831 struct elfNN_ia64_link_hash_table *ia64_info;
3832 asection *unwind_output_sec;
3833
3834 ia64_info = elfNN_ia64_hash_table (info);
3835
3836 /* Make sure we've got ourselves a nice fat __gp value. */
3837 if (!info->relocatable)
3838 {
3839 bfd_vma gp_val = _bfd_get_gp_value (abfd);
3840 struct elf_link_hash_entry *gp;
3841
3842 if (gp_val == 0)
3843 {
3844 if (! elfNN_ia64_choose_gp (abfd, info))
3845 return FALSE;
3846 gp_val = _bfd_get_gp_value (abfd);
3847 }
3848
3849 gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
3850 FALSE, FALSE);
3851 if (gp)
3852 {
3853 gp->root.type = bfd_link_hash_defined;
3854 gp->root.u.def.value = gp_val;
3855 gp->root.u.def.section = bfd_abs_section_ptr;
3856 }
3857 }
3858
3859 /* If we're producing a final executable, we need to sort the contents
3860 of the .IA_64.unwind section. Force this section to be relocated
3861 into memory rather than written immediately to the output file. */
3862 unwind_output_sec = NULL;
3863 if (!info->relocatable)
3864 {
3865 asection *s = bfd_get_section_by_name (abfd, ELF_STRING_ia64_unwind);
3866 if (s)
3867 {
3868 unwind_output_sec = s->output_section;
3869 unwind_output_sec->contents
3870 = bfd_malloc (unwind_output_sec->_raw_size);
3871 if (unwind_output_sec->contents == NULL)
3872 return FALSE;
3873 }
3874 }
3875
3876 /* Invoke the regular ELF backend linker to do all the work. */
3877 if (!bfd_elfNN_bfd_final_link (abfd, info))
3878 return FALSE;
3879
3880 if (unwind_output_sec)
3881 {
3882 elfNN_ia64_unwind_entry_compare_bfd = abfd;
3883 qsort (unwind_output_sec->contents,
3884 (size_t) (unwind_output_sec->_raw_size / 24),
3885 24,
3886 elfNN_ia64_unwind_entry_compare);
3887
3888 if (! bfd_set_section_contents (abfd, unwind_output_sec,
3889 unwind_output_sec->contents, (bfd_vma) 0,
3890 unwind_output_sec->_raw_size))
3891 return FALSE;
3892 }
3893
3894 return TRUE;
3895 }
3896
3897 static bfd_boolean
3898 elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
3899 contents, relocs, local_syms, local_sections)
3900 bfd *output_bfd;
3901 struct bfd_link_info *info;
3902 bfd *input_bfd;
3903 asection *input_section;
3904 bfd_byte *contents;
3905 Elf_Internal_Rela *relocs;
3906 Elf_Internal_Sym *local_syms;
3907 asection **local_sections;
3908 {
3909 struct elfNN_ia64_link_hash_table *ia64_info;
3910 Elf_Internal_Shdr *symtab_hdr;
3911 Elf_Internal_Rela *rel;
3912 Elf_Internal_Rela *relend;
3913 asection *srel;
3914 bfd_boolean ret_val = TRUE; /* for non-fatal errors */
3915 bfd_vma gp_val;
3916
3917 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
3918 ia64_info = elfNN_ia64_hash_table (info);
3919
3920 /* Infect various flags from the input section to the output section. */
3921 if (info->relocatable)
3922 {
3923 bfd_vma flags;
3924
3925 flags = elf_section_data(input_section)->this_hdr.sh_flags;
3926 flags &= SHF_IA_64_NORECOV;
3927
3928 elf_section_data(input_section->output_section)
3929 ->this_hdr.sh_flags |= flags;
3930 return TRUE;
3931 }
3932
3933 gp_val = _bfd_get_gp_value (output_bfd);
3934 srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
3935
3936 rel = relocs;
3937 relend = relocs + input_section->reloc_count;
3938 for (; rel < relend; ++rel)
3939 {
3940 struct elf_link_hash_entry *h;
3941 struct elfNN_ia64_dyn_sym_info *dyn_i;
3942 bfd_reloc_status_type r;
3943 reloc_howto_type *howto;
3944 unsigned long r_symndx;
3945 Elf_Internal_Sym *sym;
3946 unsigned int r_type;
3947 bfd_vma value;
3948 asection *sym_sec;
3949 bfd_byte *hit_addr;
3950 bfd_boolean dynamic_symbol_p;
3951 bfd_boolean local_symbol_p;
3952 bfd_boolean undef_weak_ref;
3953
3954 r_type = ELFNN_R_TYPE (rel->r_info);
3955 if (r_type > R_IA64_MAX_RELOC_CODE)
3956 {
3957 (*_bfd_error_handler)
3958 (_("%s: unknown relocation type %d"),
3959 bfd_archive_filename (input_bfd), (int)r_type);
3960 bfd_set_error (bfd_error_bad_value);
3961 ret_val = FALSE;
3962 continue;
3963 }
3964
3965 howto = lookup_howto (r_type);
3966 r_symndx = ELFNN_R_SYM (rel->r_info);
3967 h = NULL;
3968 sym = NULL;
3969 sym_sec = NULL;
3970 undef_weak_ref = FALSE;
3971
3972 if (r_symndx < symtab_hdr->sh_info)
3973 {
3974 /* Reloc against local symbol. */
3975 sym = local_syms + r_symndx;
3976 sym_sec = local_sections[r_symndx];
3977 value = _bfd_elf_rela_local_sym (output_bfd, sym, sym_sec, rel);
3978 if ((sym_sec->flags & SEC_MERGE)
3979 && ELF_ST_TYPE (sym->st_info) == STT_SECTION
3980 && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
3981 {
3982 struct elfNN_ia64_local_hash_entry *loc_h;
3983
3984 loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
3985 if (loc_h && ! loc_h->sec_merge_done)
3986 {
3987 struct elfNN_ia64_dyn_sym_info *dynent;
3988 asection *msec;
3989
3990 for (dynent = loc_h->info; dynent; dynent = dynent->next)
3991 {
3992 msec = sym_sec;
3993 dynent->addend =
3994 _bfd_merged_section_offset (output_bfd, &msec,
3995 elf_section_data (msec)->
3996 sec_info,
3997 sym->st_value
3998 + dynent->addend,
3999 (bfd_vma) 0);
4000 dynent->addend -= sym->st_value;
4001 dynent->addend += msec->output_section->vma
4002 + msec->output_offset
4003 - sym_sec->output_section->vma
4004 - sym_sec->output_offset;
4005 }
4006 loc_h->sec_merge_done = 1;
4007 }
4008 }
4009 }
4010 else
4011 {
4012 long indx;
4013
4014 /* Reloc against global symbol. */
4015 indx = r_symndx - symtab_hdr->sh_info;
4016 h = elf_sym_hashes (input_bfd)[indx];
4017 while (h->root.type == bfd_link_hash_indirect
4018 || h->root.type == bfd_link_hash_warning)
4019 h = (struct elf_link_hash_entry *) h->root.u.i.link;
4020
4021 value = 0;
4022 if (h->root.type == bfd_link_hash_defined
4023 || h->root.type == bfd_link_hash_defweak)
4024 {
4025 sym_sec = h->root.u.def.section;
4026
4027 /* Detect the cases that sym_sec->output_section is
4028 expected to be NULL -- all cases in which the symbol
4029 is defined in another shared module. This includes
4030 PLT relocs for which we've created a PLT entry and
4031 other relocs for which we're prepared to create
4032 dynamic relocations. */
4033 /* ??? Just accept it NULL and continue. */
4034
4035 if (sym_sec->output_section != NULL)
4036 {
4037 value = (h->root.u.def.value
4038 + sym_sec->output_section->vma
4039 + sym_sec->output_offset);
4040 }
4041 }
4042 else if (h->root.type == bfd_link_hash_undefweak)
4043 undef_weak_ref = TRUE;
4044 else if (! info->executable
4045 && !info->no_undefined
4046 && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
4047 ;
4048 else
4049 {
4050 if (! ((*info->callbacks->undefined_symbol)
4051 (info, h->root.root.string, input_bfd,
4052 input_section, rel->r_offset,
4053 (!info->shared || info->no_undefined
4054 || ELF_ST_VISIBILITY (h->other)))))
4055 return FALSE;
4056 continue;
4057 }
4058 }
4059
4060 hit_addr = contents + rel->r_offset;
4061 value += rel->r_addend;
4062 dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info);
4063 /* Is this symbol locally defined? A protected symbol is locallly
4064 defined. But its function descriptor may not. Use it with
4065 caution. */
4066 local_symbol_p = (! dynamic_symbol_p
4067 || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT);
4068
4069 switch (r_type)
4070 {
4071 case R_IA64_NONE:
4072 case R_IA64_LDXMOV:
4073 continue;
4074
4075 case R_IA64_IMM14:
4076 case R_IA64_IMM22:
4077 case R_IA64_IMM64:
4078 case R_IA64_DIR32MSB:
4079 case R_IA64_DIR32LSB:
4080 case R_IA64_DIR64MSB:
4081 case R_IA64_DIR64LSB:
4082 /* Install a dynamic relocation for this reloc. */
4083 if ((dynamic_symbol_p || info->shared
4084 || (elfNN_ia64_aix_vec (info->hash->creator)
4085 /* Don't emit relocs for __GLOB_DATA_PTR on AIX. */
4086 && (!h || strcmp (h->root.root.string,
4087 "__GLOB_DATA_PTR") != 0)))
4088 && r_symndx != 0
4089 && (input_section->flags & SEC_ALLOC) != 0)
4090 {
4091 unsigned int dyn_r_type;
4092 long dynindx;
4093 bfd_vma addend;
4094
4095 BFD_ASSERT (srel != NULL);
4096
4097 /* If we don't need dynamic symbol lookup, find a
4098 matching RELATIVE relocation. */
4099 dyn_r_type = r_type;
4100 if (! local_symbol_p)
4101 {
4102 dynindx = h->dynindx;
4103 addend = rel->r_addend;
4104 value = 0;
4105 }
4106 else
4107 {
4108 switch (r_type)
4109 {
4110 case R_IA64_DIR32MSB:
4111 dyn_r_type = R_IA64_REL32MSB;
4112 break;
4113 case R_IA64_DIR32LSB:
4114 dyn_r_type = R_IA64_REL32LSB;
4115 break;
4116 case R_IA64_DIR64MSB:
4117 dyn_r_type = R_IA64_REL64MSB;
4118 break;
4119 case R_IA64_DIR64LSB:
4120 dyn_r_type = R_IA64_REL64LSB;
4121 break;
4122
4123 default:
4124 /* We can't represent this without a dynamic symbol.
4125 Adjust the relocation to be against an output
4126 section symbol, which are always present in the
4127 dynamic symbol table. */
4128 /* ??? People shouldn't be doing non-pic code in
4129 shared libraries. Hork. */
4130 (*_bfd_error_handler)
4131 (_("%s: linking non-pic code in a shared library"),
4132 bfd_archive_filename (input_bfd));
4133 ret_val = FALSE;
4134 continue;
4135 }
4136 dynindx = 0;
4137 addend = value;
4138 }
4139
4140 if (elfNN_ia64_aix_vec (info->hash->creator))
4141 rel->r_addend = value;
4142 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4143 srel, rel->r_offset, dyn_r_type,
4144 dynindx, addend);
4145 }
4146 /* Fall through. */
4147
4148 case R_IA64_LTV32MSB:
4149 case R_IA64_LTV32LSB:
4150 case R_IA64_LTV64MSB:
4151 case R_IA64_LTV64LSB:
4152 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4153 break;
4154
4155 case R_IA64_GPREL22:
4156 case R_IA64_GPREL64I:
4157 case R_IA64_GPREL32MSB:
4158 case R_IA64_GPREL32LSB:
4159 case R_IA64_GPREL64MSB:
4160 case R_IA64_GPREL64LSB:
4161 if (dynamic_symbol_p)
4162 {
4163 (*_bfd_error_handler)
4164 (_("%s: @gprel relocation against dynamic symbol %s"),
4165 bfd_archive_filename (input_bfd), h->root.root.string);
4166 ret_val = FALSE;
4167 continue;
4168 }
4169 value -= gp_val;
4170 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4171 break;
4172
4173 case R_IA64_LTOFF22:
4174 case R_IA64_LTOFF22X:
4175 case R_IA64_LTOFF64I:
4176 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4177 value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
4178 rel->r_addend, value, R_IA64_DIR64LSB);
4179 value -= gp_val;
4180 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4181 break;
4182
4183 case R_IA64_PLTOFF22:
4184 case R_IA64_PLTOFF64I:
4185 case R_IA64_PLTOFF64MSB:
4186 case R_IA64_PLTOFF64LSB:
4187 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4188 value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
4189 value -= gp_val;
4190 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4191 break;
4192
4193 case R_IA64_FPTR64I:
4194 case R_IA64_FPTR32MSB:
4195 case R_IA64_FPTR32LSB:
4196 case R_IA64_FPTR64MSB:
4197 case R_IA64_FPTR64LSB:
4198 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4199 if (dyn_i->want_fptr)
4200 {
4201 if (!undef_weak_ref)
4202 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4203 }
4204 if (!dyn_i->want_fptr || info->pie)
4205 {
4206 long dynindx;
4207 unsigned int dyn_r_type = r_type;
4208 bfd_vma addend = rel->r_addend;
4209
4210 /* Otherwise, we expect the dynamic linker to create
4211 the entry. */
4212
4213 if (dyn_i->want_fptr)
4214 {
4215 if (r_type == R_IA64_FPTR64I)
4216 {
4217 /* We can't represent this without a dynamic symbol.
4218 Adjust the relocation to be against an output
4219 section symbol, which are always present in the
4220 dynamic symbol table. */
4221 /* ??? People shouldn't be doing non-pic code in
4222 shared libraries. Hork. */
4223 (*_bfd_error_handler)
4224 (_("%s: linking non-pic code in a position independent executable"),
4225 bfd_archive_filename (input_bfd));
4226 ret_val = FALSE;
4227 continue;
4228 }
4229 dynindx = 0;
4230 addend = value;
4231 dyn_r_type = r_type + R_IA64_REL64LSB - R_IA64_FPTR64LSB;
4232 }
4233 else if (h)
4234 {
4235 if (h->dynindx != -1)
4236 dynindx = h->dynindx;
4237 else
4238 dynindx = (_bfd_elf_link_lookup_local_dynindx
4239 (info, h->root.u.def.section->owner,
4240 global_sym_index (h)));
4241 value = 0;
4242 }
4243 else
4244 {
4245 dynindx = (_bfd_elf_link_lookup_local_dynindx
4246 (info, input_bfd, (long) r_symndx));
4247 value = 0;
4248 }
4249
4250 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4251 srel, rel->r_offset, dyn_r_type,
4252 dynindx, addend);
4253 }
4254
4255 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4256 break;
4257
4258 case R_IA64_LTOFF_FPTR22:
4259 case R_IA64_LTOFF_FPTR64I:
4260 case R_IA64_LTOFF_FPTR32MSB:
4261 case R_IA64_LTOFF_FPTR32LSB:
4262 case R_IA64_LTOFF_FPTR64MSB:
4263 case R_IA64_LTOFF_FPTR64LSB:
4264 {
4265 long dynindx;
4266
4267 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4268 if (dyn_i->want_fptr)
4269 {
4270 BFD_ASSERT (h == NULL || h->dynindx == -1)
4271 if (!undef_weak_ref)
4272 value = set_fptr_entry (output_bfd, info, dyn_i, value);
4273 dynindx = -1;
4274 }
4275 else
4276 {
4277 /* Otherwise, we expect the dynamic linker to create
4278 the entry. */
4279 if (h)
4280 {
4281 if (h->dynindx != -1)
4282 dynindx = h->dynindx;
4283 else
4284 dynindx = (_bfd_elf_link_lookup_local_dynindx
4285 (info, h->root.u.def.section->owner,
4286 global_sym_index (h)));
4287 }
4288 else
4289 dynindx = (_bfd_elf_link_lookup_local_dynindx
4290 (info, input_bfd, (long) r_symndx));
4291 value = 0;
4292 }
4293
4294 value = set_got_entry (output_bfd, info, dyn_i, dynindx,
4295 rel->r_addend, value, R_IA64_FPTR64LSB);
4296 value -= gp_val;
4297 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4298 }
4299 break;
4300
4301 case R_IA64_PCREL32MSB:
4302 case R_IA64_PCREL32LSB:
4303 case R_IA64_PCREL64MSB:
4304 case R_IA64_PCREL64LSB:
4305 /* Install a dynamic relocation for this reloc. */
4306 if ((dynamic_symbol_p
4307 || elfNN_ia64_aix_vec (info->hash->creator))
4308 && r_symndx != 0)
4309 {
4310 BFD_ASSERT (srel != NULL);
4311
4312 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4313 srel, rel->r_offset, r_type,
4314 h->dynindx, rel->r_addend);
4315 }
4316 goto finish_pcrel;
4317
4318 case R_IA64_PCREL21B:
4319 case R_IA64_PCREL60B:
4320 /* We should have created a PLT entry for any dynamic symbol. */
4321 dyn_i = NULL;
4322 if (h)
4323 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4324
4325 if (dyn_i && dyn_i->want_plt2)
4326 {
4327 /* Should have caught this earlier. */
4328 BFD_ASSERT (rel->r_addend == 0);
4329
4330 value = (ia64_info->plt_sec->output_section->vma
4331 + ia64_info->plt_sec->output_offset
4332 + dyn_i->plt2_offset);
4333 }
4334 else
4335 {
4336 /* Since there's no PLT entry, Validate that this is
4337 locally defined. */
4338 BFD_ASSERT (undef_weak_ref || sym_sec->output_section != NULL);
4339
4340 /* If the symbol is undef_weak, we shouldn't be trying
4341 to call it. There's every chance that we'd wind up
4342 with an out-of-range fixup here. Don't bother setting
4343 any value at all. */
4344 if (undef_weak_ref)
4345 continue;
4346 }
4347 goto finish_pcrel;
4348
4349 case R_IA64_PCREL21BI:
4350 case R_IA64_PCREL21F:
4351 case R_IA64_PCREL21M:
4352 case R_IA64_PCREL22:
4353 case R_IA64_PCREL64I:
4354 /* The PCREL21BI reloc is specifically not intended for use with
4355 dynamic relocs. PCREL21F and PCREL21M are used for speculation
4356 fixup code, and thus probably ought not be dynamic. The
4357 PCREL22 and PCREL64I relocs aren't emitted as dynamic relocs. */
4358 if (dynamic_symbol_p)
4359 {
4360 const char *msg;
4361
4362 if (r_type == R_IA64_PCREL21BI)
4363 msg = _("%s: @internal branch to dynamic symbol %s");
4364 else if (r_type == R_IA64_PCREL21F || r_type == R_IA64_PCREL21M)
4365 msg = _("%s: speculation fixup to dynamic symbol %s");
4366 else
4367 msg = _("%s: @pcrel relocation against dynamic symbol %s");
4368 (*_bfd_error_handler) (msg, bfd_archive_filename (input_bfd),
4369 h->root.root.string);
4370 ret_val = FALSE;
4371 continue;
4372 }
4373 goto finish_pcrel;
4374
4375 finish_pcrel:
4376 /* Make pc-relative. */
4377 value -= (input_section->output_section->vma
4378 + input_section->output_offset
4379 + rel->r_offset) & ~ (bfd_vma) 0x3;
4380 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4381 break;
4382
4383 case R_IA64_SEGREL32MSB:
4384 case R_IA64_SEGREL32LSB:
4385 case R_IA64_SEGREL64MSB:
4386 case R_IA64_SEGREL64LSB:
4387 if (r_symndx == 0)
4388 {
4389 /* If the input section was discarded from the output, then
4390 do nothing. */
4391 r = bfd_reloc_ok;
4392 }
4393 else
4394 {
4395 struct elf_segment_map *m;
4396 Elf_Internal_Phdr *p;
4397
4398 /* Find the segment that contains the output_section. */
4399 for (m = elf_tdata (output_bfd)->segment_map,
4400 p = elf_tdata (output_bfd)->phdr;
4401 m != NULL;
4402 m = m->next, p++)
4403 {
4404 int i;
4405 for (i = m->count - 1; i >= 0; i--)
4406 if (m->sections[i] == input_section->output_section)
4407 break;
4408 if (i >= 0)
4409 break;
4410 }
4411
4412 if (m == NULL)
4413 {
4414 r = bfd_reloc_notsupported;
4415 }
4416 else
4417 {
4418 /* The VMA of the segment is the vaddr of the associated
4419 program header. */
4420 if (value > p->p_vaddr)
4421 value -= p->p_vaddr;
4422 else
4423 value = 0;
4424 r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
4425 r_type);
4426 }
4427 break;
4428 }
4429
4430 case R_IA64_SECREL32MSB:
4431 case R_IA64_SECREL32LSB:
4432 case R_IA64_SECREL64MSB:
4433 case R_IA64_SECREL64LSB:
4434 /* Make output-section relative. */
4435 if (value > input_section->output_section->vma)
4436 value -= input_section->output_section->vma;
4437 else
4438 value = 0;
4439 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4440 break;
4441
4442 case R_IA64_IPLTMSB:
4443 case R_IA64_IPLTLSB:
4444 /* Install a dynamic relocation for this reloc. */
4445 if ((dynamic_symbol_p || info->shared)
4446 && (input_section->flags & SEC_ALLOC) != 0)
4447 {
4448 BFD_ASSERT (srel != NULL);
4449
4450 /* If we don't need dynamic symbol lookup, install two
4451 RELATIVE relocations. */
4452 if (local_symbol_p)
4453 {
4454 unsigned int dyn_r_type;
4455
4456 if (r_type == R_IA64_IPLTMSB)
4457 dyn_r_type = R_IA64_REL64MSB;
4458 else
4459 dyn_r_type = R_IA64_REL64LSB;
4460
4461 elfNN_ia64_install_dyn_reloc (output_bfd, info,
4462 input_section,
4463 srel, rel->r_offset,
4464 dyn_r_type, 0, value);
4465 elfNN_ia64_install_dyn_reloc (output_bfd, info,
4466 input_section,
4467 srel, rel->r_offset + 8,
4468 dyn_r_type, 0, gp_val);
4469 }
4470 else
4471 elfNN_ia64_install_dyn_reloc (output_bfd, info, input_section,
4472 srel, rel->r_offset, r_type,
4473 h->dynindx, rel->r_addend);
4474 }
4475
4476 if (r_type == R_IA64_IPLTMSB)
4477 r_type = R_IA64_DIR64MSB;
4478 else
4479 r_type = R_IA64_DIR64LSB;
4480 elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4481 r = elfNN_ia64_install_value (output_bfd, hit_addr + 8, gp_val,
4482 r_type);
4483 break;
4484
4485 case R_IA64_TPREL14:
4486 case R_IA64_TPREL22:
4487 case R_IA64_TPREL64I:
4488 value -= elfNN_ia64_tprel_base (info);
4489 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4490 break;
4491
4492 case R_IA64_DTPREL14:
4493 case R_IA64_DTPREL22:
4494 case R_IA64_DTPREL64I:
4495 case R_IA64_DTPREL64LSB:
4496 case R_IA64_DTPREL64MSB:
4497 value -= elfNN_ia64_dtprel_base (info);
4498 r = elfNN_ia64_install_value (output_bfd, hit_addr, value, r_type);
4499 break;
4500
4501 case R_IA64_LTOFF_TPREL22:
4502 case R_IA64_LTOFF_DTPMOD22:
4503 case R_IA64_LTOFF_DTPREL22:
4504 {
4505 int got_r_type;
4506 long dynindx = h ? h->dynindx : -1;
4507 bfd_vma r_addend = rel->r_addend;
4508
4509 switch (r_type)
4510 {
4511 default:
4512 case R_IA64_LTOFF_TPREL22:
4513 if (!dynamic_symbol_p)
4514 {
4515 if (!info->shared)
4516 value -= elfNN_ia64_tprel_base (info);
4517 else
4518 {
4519 r_addend += value - elfNN_ia64_dtprel_base (info);
4520 dynindx = 0;
4521 }
4522 }
4523 got_r_type = R_IA64_TPREL64LSB;
4524 break;
4525 case R_IA64_LTOFF_DTPMOD22:
4526 if (!dynamic_symbol_p && !info->shared)
4527 value = 1;
4528 got_r_type = R_IA64_DTPMOD64LSB;
4529 break;
4530 case R_IA64_LTOFF_DTPREL22:
4531 if (!dynamic_symbol_p)
4532 value -= elfNN_ia64_dtprel_base (info);
4533 got_r_type = R_IA64_DTPREL64LSB;
4534 break;
4535 }
4536 dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
4537 value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
4538 value, got_r_type);
4539 value -= gp_val;
4540 r = elfNN_ia64_install_value (output_bfd, hit_addr, value,
4541 r_type);
4542 }
4543 break;
4544
4545 default:
4546 r = bfd_reloc_notsupported;
4547 break;
4548 }
4549
4550 switch (r)
4551 {
4552 case bfd_reloc_ok:
4553 break;
4554
4555 case bfd_reloc_undefined:
4556 /* This can happen for global table relative relocs if
4557 __gp is undefined. This is a panic situation so we
4558 don't try to continue. */
4559 (*info->callbacks->undefined_symbol)
4560 (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
4561 return FALSE;
4562
4563 case bfd_reloc_notsupported:
4564 {
4565 const char *name;
4566
4567 if (h)
4568 name = h->root.root.string;
4569 else
4570 {
4571 name = bfd_elf_string_from_elf_section (input_bfd,
4572 symtab_hdr->sh_link,
4573 sym->st_name);
4574 if (name == NULL)
4575 return FALSE;
4576 if (*name == '\0')
4577 name = bfd_section_name (input_bfd, input_section);
4578 }
4579 if (!(*info->callbacks->warning) (info, _("unsupported reloc"),
4580 name, input_bfd,
4581 input_section, rel->r_offset))
4582 return FALSE;
4583 ret_val = FALSE;
4584 }
4585 break;
4586
4587 case bfd_reloc_dangerous:
4588 case bfd_reloc_outofrange:
4589 case bfd_reloc_overflow:
4590 default:
4591 {
4592 const char *name;
4593
4594 if (h)
4595 name = h->root.root.string;
4596 else
4597 {
4598 name = bfd_elf_string_from_elf_section (input_bfd,
4599 symtab_hdr->sh_link,
4600 sym->st_name);
4601 if (name == NULL)
4602 return FALSE;
4603 if (*name == '\0')
4604 name = bfd_section_name (input_bfd, input_section);
4605 }
4606 if (!(*info->callbacks->reloc_overflow) (info, name,
4607 howto->name,
4608 (bfd_vma) 0,
4609 input_bfd,
4610 input_section,
4611 rel->r_offset))
4612 return FALSE;
4613 ret_val = FALSE;
4614 }
4615 break;
4616 }
4617 }
4618
4619 return ret_val;
4620 }
4621
4622 static bfd_boolean
4623 elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
4624 bfd *output_bfd;
4625 struct bfd_link_info *info;
4626 struct elf_link_hash_entry *h;
4627 Elf_Internal_Sym *sym;
4628 {
4629 struct elfNN_ia64_link_hash_table *ia64_info;
4630 struct elfNN_ia64_dyn_sym_info *dyn_i;
4631
4632 ia64_info = elfNN_ia64_hash_table (info);
4633 dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
4634
4635 /* Fill in the PLT data, if required. */
4636 if (dyn_i && dyn_i->want_plt)
4637 {
4638 Elf_Internal_Rela outrel;
4639 bfd_byte *loc;
4640 asection *plt_sec;
4641 bfd_vma plt_addr, pltoff_addr, gp_val, index;
4642
4643 gp_val = _bfd_get_gp_value (output_bfd);
4644
4645 /* Initialize the minimal PLT entry. */
4646
4647 index = (dyn_i->plt_offset - PLT_HEADER_SIZE) / PLT_MIN_ENTRY_SIZE;
4648 plt_sec = ia64_info->plt_sec;
4649 loc = plt_sec->contents + dyn_i->plt_offset;
4650
4651 memcpy (loc, plt_min_entry, PLT_MIN_ENTRY_SIZE);
4652 elfNN_ia64_install_value (output_bfd, loc, index, R_IA64_IMM22);
4653 elfNN_ia64_install_value (output_bfd, loc+2, -dyn_i->plt_offset,
4654 R_IA64_PCREL21B);
4655
4656 plt_addr = (plt_sec->output_section->vma
4657 + plt_sec->output_offset
4658 + dyn_i->plt_offset);
4659 pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
4660
4661 /* Initialize the FULL PLT entry, if needed. */
4662 if (dyn_i->want_plt2)
4663 {
4664 loc = plt_sec->contents + dyn_i->plt2_offset;
4665
4666 memcpy (loc, plt_full_entry, PLT_FULL_ENTRY_SIZE);
4667 elfNN_ia64_install_value (output_bfd, loc, pltoff_addr - gp_val,
4668 R_IA64_IMM22);
4669
4670 /* Mark the symbol as undefined, rather than as defined in the
4671 plt section. Leave the value alone. */
4672 /* ??? We didn't redefine it in adjust_dynamic_symbol in the
4673 first place. But perhaps elflink.h did some for us. */
4674 if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
4675 sym->st_shndx = SHN_UNDEF;
4676 }
4677
4678 /* Create the dynamic relocation. */
4679 outrel.r_offset = pltoff_addr;
4680 if (bfd_little_endian (output_bfd))
4681 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTLSB);
4682 else
4683 outrel.r_info = ELFNN_R_INFO (h->dynindx, R_IA64_IPLTMSB);
4684 outrel.r_addend = 0;
4685
4686 /* This is fun. In the .IA_64.pltoff section, we've got entries
4687 that correspond both to real PLT entries, and those that
4688 happened to resolve to local symbols but need to be created
4689 to satisfy @pltoff relocations. The .rela.IA_64.pltoff
4690 relocations for the real PLT should come at the end of the
4691 section, so that they can be indexed by plt entry at runtime.
4692
4693 We emitted all of the relocations for the non-PLT @pltoff
4694 entries during relocate_section. So we can consider the
4695 existing sec->reloc_count to be the base of the array of
4696 PLT relocations. */
4697
4698 loc = ia64_info->rel_pltoff_sec->contents;
4699 loc += ((ia64_info->rel_pltoff_sec->reloc_count + index)
4700 * sizeof (Elf64_External_Rela));
4701 bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
4702 }
4703
4704 /* Mark some specially defined symbols as absolute. */
4705 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
4706 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
4707 || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
4708 sym->st_shndx = SHN_ABS;
4709
4710 return TRUE;
4711 }
4712
4713 static bfd_boolean
4714 elfNN_ia64_finish_dynamic_sections (abfd, info)
4715 bfd *abfd;
4716 struct bfd_link_info *info;
4717 {
4718 struct elfNN_ia64_link_hash_table *ia64_info;
4719 bfd *dynobj;
4720
4721 ia64_info = elfNN_ia64_hash_table (info);
4722 dynobj = ia64_info->root.dynobj;
4723
4724 if (elf_hash_table (info)->dynamic_sections_created)
4725 {
4726 ElfNN_External_Dyn *dyncon, *dynconend;
4727 asection *sdyn, *sgotplt;
4728 bfd_vma gp_val;
4729
4730 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
4731 sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
4732 BFD_ASSERT (sdyn != NULL);
4733 dyncon = (ElfNN_External_Dyn *) sdyn->contents;
4734 dynconend = (ElfNN_External_Dyn *) (sdyn->contents + sdyn->_raw_size);
4735
4736 gp_val = _bfd_get_gp_value (abfd);
4737
4738 for (; dyncon < dynconend; dyncon++)
4739 {
4740 Elf_Internal_Dyn dyn;
4741
4742 bfd_elfNN_swap_dyn_in (dynobj, dyncon, &dyn);
4743
4744 switch (dyn.d_tag)
4745 {
4746 case DT_PLTGOT:
4747 dyn.d_un.d_ptr = gp_val;
4748 break;
4749
4750 case DT_PLTRELSZ:
4751 dyn.d_un.d_val = (ia64_info->minplt_entries
4752 * sizeof (ElfNN_External_Rela));
4753 break;
4754
4755 case DT_JMPREL:
4756 /* See the comment above in finish_dynamic_symbol. */
4757 dyn.d_un.d_ptr = (ia64_info->rel_pltoff_sec->output_section->vma
4758 + ia64_info->rel_pltoff_sec->output_offset
4759 + (ia64_info->rel_pltoff_sec->reloc_count
4760 * sizeof (ElfNN_External_Rela)));
4761 break;
4762
4763 case DT_IA_64_PLT_RESERVE:
4764 dyn.d_un.d_ptr = (sgotplt->output_section->vma
4765 + sgotplt->output_offset);
4766 break;
4767
4768 case DT_RELASZ:
4769 /* Do not have RELASZ include JMPREL. This makes things
4770 easier on ld.so. This is not what the rest of BFD set up. */
4771 dyn.d_un.d_val -= (ia64_info->minplt_entries
4772 * sizeof (ElfNN_External_Rela));
4773 break;
4774 }
4775
4776 bfd_elfNN_swap_dyn_out (abfd, &dyn, dyncon);
4777 }
4778
4779 /* Initialize the PLT0 entry. */
4780 if (ia64_info->plt_sec)
4781 {
4782 bfd_byte *loc = ia64_info->plt_sec->contents;
4783 bfd_vma pltres;
4784
4785 memcpy (loc, plt_header, PLT_HEADER_SIZE);
4786
4787 pltres = (sgotplt->output_section->vma
4788 + sgotplt->output_offset
4789 - gp_val);
4790
4791 elfNN_ia64_install_value (abfd, loc+1, pltres, R_IA64_GPREL22);
4792 }
4793 }
4794
4795 return TRUE;
4796 }
4797 \f
4798 /* ELF file flag handling: */
4799
4800 /* Function to keep IA-64 specific file flags. */
4801 static bfd_boolean
4802 elfNN_ia64_set_private_flags (abfd, flags)
4803 bfd *abfd;
4804 flagword flags;
4805 {
4806 BFD_ASSERT (!elf_flags_init (abfd)
4807 || elf_elfheader (abfd)->e_flags == flags);
4808
4809 elf_elfheader (abfd)->e_flags = flags;
4810 elf_flags_init (abfd) = TRUE;
4811 return TRUE;
4812 }
4813
4814 /* Merge backend specific data from an object file to the output
4815 object file when linking. */
4816 static bfd_boolean
4817 elfNN_ia64_merge_private_bfd_data (ibfd, obfd)
4818 bfd *ibfd, *obfd;
4819 {
4820 flagword out_flags;
4821 flagword in_flags;
4822 bfd_boolean ok = TRUE;
4823
4824 /* Don't even pretend to support mixed-format linking. */
4825 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
4826 || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
4827 return FALSE;
4828
4829 in_flags = elf_elfheader (ibfd)->e_flags;
4830 out_flags = elf_elfheader (obfd)->e_flags;
4831
4832 if (! elf_flags_init (obfd))
4833 {
4834 elf_flags_init (obfd) = TRUE;
4835 elf_elfheader (obfd)->e_flags = in_flags;
4836
4837 if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
4838 && bfd_get_arch_info (obfd)->the_default)
4839 {
4840 return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
4841 bfd_get_mach (ibfd));
4842 }
4843
4844 return TRUE;
4845 }
4846
4847 /* Check flag compatibility. */
4848 if (in_flags == out_flags)
4849 return TRUE;
4850
4851 /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set. */
4852 if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
4853 elf_elfheader (obfd)->e_flags &= ~EF_IA_64_REDUCEDFP;
4854
4855 if ((in_flags & EF_IA_64_TRAPNIL) != (out_flags & EF_IA_64_TRAPNIL))
4856 {
4857 (*_bfd_error_handler)
4858 (_("%s: linking trap-on-NULL-dereference with non-trapping files"),
4859 bfd_archive_filename (ibfd));
4860
4861 bfd_set_error (bfd_error_bad_value);
4862 ok = FALSE;
4863 }
4864 if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
4865 {
4866 (*_bfd_error_handler)
4867 (_("%s: linking big-endian files with little-endian files"),
4868 bfd_archive_filename (ibfd));
4869
4870 bfd_set_error (bfd_error_bad_value);
4871 ok = FALSE;
4872 }
4873 if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
4874 {
4875 (*_bfd_error_handler)
4876 (_("%s: linking 64-bit files with 32-bit files"),
4877 bfd_archive_filename (ibfd));
4878
4879 bfd_set_error (bfd_error_bad_value);
4880 ok = FALSE;
4881 }
4882 if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
4883 {
4884 (*_bfd_error_handler)
4885 (_("%s: linking constant-gp files with non-constant-gp files"),
4886 bfd_archive_filename (ibfd));
4887
4888 bfd_set_error (bfd_error_bad_value);
4889 ok = FALSE;
4890 }
4891 if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
4892 != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4893 {
4894 (*_bfd_error_handler)
4895 (_("%s: linking auto-pic files with non-auto-pic files"),
4896 bfd_archive_filename (ibfd));
4897
4898 bfd_set_error (bfd_error_bad_value);
4899 ok = FALSE;
4900 }
4901
4902 return ok;
4903 }
4904
4905 static bfd_boolean
4906 elfNN_ia64_print_private_bfd_data (abfd, ptr)
4907 bfd *abfd;
4908 PTR ptr;
4909 {
4910 FILE *file = (FILE *) ptr;
4911 flagword flags = elf_elfheader (abfd)->e_flags;
4912
4913 BFD_ASSERT (abfd != NULL && ptr != NULL);
4914
4915 fprintf (file, "private flags = %s%s%s%s%s%s%s%s\n",
4916 (flags & EF_IA_64_TRAPNIL) ? "TRAPNIL, " : "",
4917 (flags & EF_IA_64_EXT) ? "EXT, " : "",
4918 (flags & EF_IA_64_BE) ? "BE, " : "LE, ",
4919 (flags & EF_IA_64_REDUCEDFP) ? "REDUCEDFP, " : "",
4920 (flags & EF_IA_64_CONS_GP) ? "CONS_GP, " : "",
4921 (flags & EF_IA_64_NOFUNCDESC_CONS_GP) ? "NOFUNCDESC_CONS_GP, " : "",
4922 (flags & EF_IA_64_ABSOLUTE) ? "ABSOLUTE, " : "",
4923 (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
4924
4925 _bfd_elf_print_private_bfd_data (abfd, ptr);
4926 return TRUE;
4927 }
4928
4929 static enum elf_reloc_type_class
4930 elfNN_ia64_reloc_type_class (rela)
4931 const Elf_Internal_Rela *rela;
4932 {
4933 switch ((int) ELFNN_R_TYPE (rela->r_info))
4934 {
4935 case R_IA64_REL32MSB:
4936 case R_IA64_REL32LSB:
4937 case R_IA64_REL64MSB:
4938 case R_IA64_REL64LSB:
4939 return reloc_class_relative;
4940 case R_IA64_IPLTMSB:
4941 case R_IA64_IPLTLSB:
4942 return reloc_class_plt;
4943 case R_IA64_COPY:
4944 return reloc_class_copy;
4945 default:
4946 return reloc_class_normal;
4947 }
4948 }
4949
4950 static bfd_boolean
4951 elfNN_ia64_hpux_vec (const bfd_target *vec)
4952 {
4953 extern const bfd_target bfd_elfNN_ia64_hpux_big_vec;
4954 return (vec == & bfd_elfNN_ia64_hpux_big_vec);
4955 }
4956
4957 static void
4958 elfNN_hpux_post_process_headers (abfd, info)
4959 bfd *abfd;
4960 struct bfd_link_info *info ATTRIBUTE_UNUSED;
4961 {
4962 Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
4963
4964 i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_HPUX;
4965 i_ehdrp->e_ident[EI_ABIVERSION] = 1;
4966 }
4967
4968 bfd_boolean
4969 elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
4970 bfd *abfd ATTRIBUTE_UNUSED;
4971 asection *sec;
4972 int *retval;
4973 {
4974 if (bfd_is_com_section (sec))
4975 {
4976 *retval = SHN_IA_64_ANSI_COMMON;
4977 return TRUE;
4978 }
4979 return FALSE;
4980 }
4981 \f
4982 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_little_vec
4983 #define TARGET_LITTLE_NAME "elfNN-ia64-little"
4984 #define TARGET_BIG_SYM bfd_elfNN_ia64_big_vec
4985 #define TARGET_BIG_NAME "elfNN-ia64-big"
4986 #define ELF_ARCH bfd_arch_ia64
4987 #define ELF_MACHINE_CODE EM_IA_64
4988 #define ELF_MACHINE_ALT1 1999 /* EAS2.3 */
4989 #define ELF_MACHINE_ALT2 1998 /* EAS2.2 */
4990 #define ELF_MAXPAGESIZE 0x10000 /* 64KB */
4991
4992 #define elf_backend_section_from_shdr \
4993 elfNN_ia64_section_from_shdr
4994 #define elf_backend_section_flags \
4995 elfNN_ia64_section_flags
4996 #define elf_backend_fake_sections \
4997 elfNN_ia64_fake_sections
4998 #define elf_backend_final_write_processing \
4999 elfNN_ia64_final_write_processing
5000 #define elf_backend_add_symbol_hook \
5001 elfNN_ia64_add_symbol_hook
5002 #define elf_backend_additional_program_headers \
5003 elfNN_ia64_additional_program_headers
5004 #define elf_backend_modify_segment_map \
5005 elfNN_ia64_modify_segment_map
5006 #define elf_info_to_howto \
5007 elfNN_ia64_info_to_howto
5008
5009 #define bfd_elfNN_bfd_reloc_type_lookup \
5010 elfNN_ia64_reloc_type_lookup
5011 #define bfd_elfNN_bfd_is_local_label_name \
5012 elfNN_ia64_is_local_label_name
5013 #define bfd_elfNN_bfd_relax_section \
5014 elfNN_ia64_relax_section
5015
5016 /* Stuff for the BFD linker: */
5017 #define bfd_elfNN_bfd_link_hash_table_create \
5018 elfNN_ia64_hash_table_create
5019 #define elf_backend_create_dynamic_sections \
5020 elfNN_ia64_create_dynamic_sections
5021 #define elf_backend_check_relocs \
5022 elfNN_ia64_check_relocs
5023 #define elf_backend_adjust_dynamic_symbol \
5024 elfNN_ia64_adjust_dynamic_symbol
5025 #define elf_backend_size_dynamic_sections \
5026 elfNN_ia64_size_dynamic_sections
5027 #define elf_backend_relocate_section \
5028 elfNN_ia64_relocate_section
5029 #define elf_backend_finish_dynamic_symbol \
5030 elfNN_ia64_finish_dynamic_symbol
5031 #define elf_backend_finish_dynamic_sections \
5032 elfNN_ia64_finish_dynamic_sections
5033 #define bfd_elfNN_bfd_final_link \
5034 elfNN_ia64_final_link
5035
5036 #define bfd_elfNN_bfd_merge_private_bfd_data \
5037 elfNN_ia64_merge_private_bfd_data
5038 #define bfd_elfNN_bfd_set_private_flags \
5039 elfNN_ia64_set_private_flags
5040 #define bfd_elfNN_bfd_print_private_bfd_data \
5041 elfNN_ia64_print_private_bfd_data
5042
5043 #define elf_backend_plt_readonly 1
5044 #define elf_backend_want_plt_sym 0
5045 #define elf_backend_plt_alignment 5
5046 #define elf_backend_got_header_size 0
5047 #define elf_backend_plt_header_size PLT_HEADER_SIZE
5048 #define elf_backend_want_got_plt 1
5049 #define elf_backend_may_use_rel_p 1
5050 #define elf_backend_may_use_rela_p 1
5051 #define elf_backend_default_use_rela_p 1
5052 #define elf_backend_want_dynbss 0
5053 #define elf_backend_copy_indirect_symbol elfNN_ia64_hash_copy_indirect
5054 #define elf_backend_hide_symbol elfNN_ia64_hash_hide_symbol
5055 #define elf_backend_reloc_type_class elfNN_ia64_reloc_type_class
5056 #define elf_backend_rela_normal 1
5057
5058 #include "elfNN-target.h"
5059
5060 /* AIX-specific vectors. */
5061
5062 #undef TARGET_LITTLE_SYM
5063 #define TARGET_LITTLE_SYM bfd_elfNN_ia64_aix_little_vec
5064 #undef TARGET_LITTLE_NAME
5065 #define TARGET_LITTLE_NAME "elfNN-ia64-aix-little"
5066 #undef TARGET_BIG_SYM
5067 #define TARGET_BIG_SYM bfd_elfNN_ia64_aix_big_vec
5068 #undef TARGET_BIG_NAME
5069 #define TARGET_BIG_NAME "elfNN-ia64-aix-big"
5070
5071 #undef elf_backend_add_symbol_hook
5072 #define elf_backend_add_symbol_hook elfNN_ia64_aix_add_symbol_hook
5073
5074 #undef bfd_elfNN_bfd_link_add_symbols
5075 #define bfd_elfNN_bfd_link_add_symbols elfNN_ia64_aix_link_add_symbols
5076
5077 #define elfNN_bed elfNN_ia64_aix_bed
5078
5079 #include "elfNN-target.h"
5080
5081 /* HPUX-specific vectors. */
5082
5083 #undef TARGET_LITTLE_SYM
5084 #undef TARGET_LITTLE_NAME
5085 #undef TARGET_BIG_SYM
5086 #define TARGET_BIG_SYM bfd_elfNN_ia64_hpux_big_vec
5087 #undef TARGET_BIG_NAME
5088 #define TARGET_BIG_NAME "elfNN-ia64-hpux-big"
5089
5090 /* We need to undo the AIX specific functions. */
5091
5092 #undef elf_backend_add_symbol_hook
5093 #define elf_backend_add_symbol_hook elfNN_ia64_add_symbol_hook
5094
5095 #undef bfd_elfNN_bfd_link_add_symbols
5096 #define bfd_elfNN_bfd_link_add_symbols _bfd_generic_link_add_symbols
5097
5098 /* These are HP-UX specific functions. */
5099
5100 #undef elf_backend_post_process_headers
5101 #define elf_backend_post_process_headers elfNN_hpux_post_process_headers
5102
5103 #undef elf_backend_section_from_bfd_section
5104 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
5105
5106 #undef elf_backend_want_p_paddr_set_to_zero
5107 #define elf_backend_want_p_paddr_set_to_zero 1
5108
5109 #undef ELF_MAXPAGESIZE
5110 #define ELF_MAXPAGESIZE 0x1000 /* 1K */
5111
5112 #undef elfNN_bed
5113 #define elfNN_bed elfNN_ia64_hpux_bed
5114
5115 #include "elfNN-target.h"
5116
5117 #undef elf_backend_want_p_paddr_set_to_zero
This page took 0.140775 seconds and 4 git commands to generate.