OSDN Git Service

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