OSDN Git Service

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