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