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