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