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