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