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