OSDN Git Service

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