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