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